From 90d1578878da6f62bdb8459d214b5ec88b19f9eb Mon Sep 17 00:00:00 2001 From: kbinani Date: Thu, 25 Jun 2009 14:16:22 +0000 Subject: [PATCH] git-svn-id: http://svn.sourceforge.jp/svnroot/lipsync@6 b1f601f4-4f45-0410-8980-aecacb008692 --- trunk/Boare.Lib.AppUtil/AuthorListEntry.cs | 50 + .../Boare.Lib.AppUtil/BHScrollBar.Designer.cs | 66 + trunk/Boare.Lib.AppUtil/BHScrollBar.cs | 86 + trunk/Boare.Lib.AppUtil/BSplitContainer.cs | 506 + trunk/Boare.Lib.AppUtil/BSplitterPanel.cs | 96 + trunk/Boare.Lib.AppUtil/BTrackBar.cs | 289 + .../Boare.Lib.AppUtil/BVScrollBar.Designer.cs | 67 + trunk/Boare.Lib.AppUtil/BVScrollBar.cs | 86 + trunk/Boare.Lib.AppUtil/BitmapEx.cs | 159 + .../Boare.Lib.AppUtil.csproj | 126 + trunk/Boare.Lib.AppUtil/ColorBar.cs | 1118 ++ trunk/Boare.Lib.AppUtil/CubicSpline.cs | 275 + trunk/Boare.Lib.AppUtil/ISO639.cs | 29 + trunk/Boare.Lib.AppUtil/InputBox.Designer.cs | 113 + trunk/Boare.Lib.AppUtil/InputBox.cs | 37 + trunk/Boare.Lib.AppUtil/MathEx.cs | 21 + trunk/Boare.Lib.AppUtil/MessageBody.cs | 162 + trunk/Boare.Lib.AppUtil/Messaging.cs | 107 + trunk/Boare.Lib.AppUtil/Misc.cs | 325 + .../Properties/AssemblyInfo.cs | 29 + .../Boare.Lib.AppUtil/VersionInfo.Designer.cs | 136 + trunk/Boare.Lib.AppUtil/VersionInfo.cs | 262 + .../XmlSerializeWithDescription.cs | 215 + .../XmlStaticMemberSerializer.cs | 209 + trunk/Boare.Lib.AppUtil/makefile | 17 + trunk/Boare.Lib.Media/AviReader.cs | 359 + trunk/Boare.Lib.Media/AviWriterVcm.cs | 550 + trunk/Boare.Lib.Media/AviWriterVfw.cs | 496 + trunk/Boare.Lib.Media/Boare.Lib.Media.csproj | 92 + trunk/Boare.Lib.Media/IAviWriter.cs | 34 + trunk/Boare.Lib.Media/MediaPlayer.cs | 416 + trunk/Boare.Lib.Media/MidiInDevice.cs | 164 + trunk/Boare.Lib.Media/PipedAviWriter.cs | 251 + .../Properties/AssemblyInfo.cs | 29 + trunk/Boare.Lib.Media/RawAvi2Writer.cs | 542 + trunk/Boare.Lib.Media/Util.cs | 222 + trunk/Boare.Lib.Media/VCM.cs | 238 + trunk/Boare.Lib.Media/VFW.cs | 384 + trunk/Boare.Lib.Media/Wave.cs | 1317 +++ trunk/Boare.Lib.Media/WavePlay.cs | 626 ++ trunk/Boare.Lib.Media/WaveReader.cs | 283 + trunk/Boare.Lib.Media/WaveWriter.cs | 384 + trunk/Boare.Lib.Media/makefile | 17 + trunk/Boare.Lib.Swf/Boare.Lib.Swf.csproj | 59 + .../Boare.Lib.Swf/Properties/AssemblyInfo.cs | 36 + trunk/Boare.Lib.Swf/RECT.cs | 63 + trunk/Boare.Lib.Swf/SB.cs | 54 + trunk/Boare.Lib.Swf/SwfWriter.cs | 81 + trunk/Boare.Lib.Swf/Util.cs | 22 + trunk/Boare.Lib.Swf/makefile | 8 + trunk/Boare.Lib.Vsq/BPPair.cs | 47 + trunk/Boare.Lib.Vsq/Boare.Lib.Vsq.csproj | 114 + trunk/Boare.Lib.Vsq/NRPN.cs | 249 + trunk/Boare.Lib.Vsq/NrpnData.cs | 36 + trunk/Boare.Lib.Vsq/PortUtil.cs | 55 + .../Boare.Lib.Vsq/Properties/AssemblyInfo.cs | 29 + trunk/Boare.Lib.Vsq/SMF/MidiFile.cs | 316 + trunk/Boare.Lib.Vsq/SingerConfig.cs | 244 + trunk/Boare.Lib.Vsq/SymbolTable.cs | 676 ++ trunk/Boare.Lib.Vsq/TempoTableEntry.cs | 48 + trunk/Boare.Lib.Vsq/TextMemoryStream.cs | 127 + trunk/Boare.Lib.Vsq/TimeSigTableEntry.cs | 61 + trunk/Boare.Lib.Vsq/UstEvent.cs | 74 + trunk/Boare.Lib.Vsq/UstFile.cs | 259 + trunk/Boare.Lib.Vsq/UstTrack.cs | 60 + trunk/Boare.Lib.Vsq/VibratoBPList.cs | 62 + trunk/Boare.Lib.Vsq/VibratoBPPair.cs | 38 + trunk/Boare.Lib.Vsq/VibratoType.cs | 351 + trunk/Boare.Lib.Vsq/VsqBPList.cs | 228 + trunk/Boare.Lib.Vsq/VsqBarLineType.cs | 54 + trunk/Boare.Lib.Vsq/VsqCommand.cs | 498 + trunk/Boare.Lib.Vsq/VsqCommandType.cs | 50 + trunk/Boare.Lib.Vsq/VsqEvent.cs | 70 + trunk/Boare.Lib.Vsq/VsqEventList.cs | 90 + trunk/Boare.Lib.Vsq/VsqFile.cs | 2459 +++++ trunk/Boare.Lib.Vsq/VsqMetaText/Common.cs | 149 + trunk/Boare.Lib.Vsq/VsqMetaText/Common.java | 151 + trunk/Boare.Lib.Vsq/VsqMetaText/Handle.cs | 448 + trunk/Boare.Lib.Vsq/VsqMetaText/ID.cs | 272 + trunk/Boare.Lib.Vsq/VsqMetaText/Lyric.cs | 210 + trunk/Boare.Lib.Vsq/VsqMetaText/Master.cs | 100 + trunk/Boare.Lib.Vsq/VsqMetaText/Mixer.cs | 266 + .../Boare.Lib.Vsq/VsqMetaText/VsqMetaText.cs | 811 ++ trunk/Boare.Lib.Vsq/VsqNote.cs | 236 + trunk/Boare.Lib.Vsq/VsqNrpn.cs | 116 + trunk/Boare.Lib.Vsq/VsqPhoneticSymbol.cs | 153 + trunk/Boare.Lib.Vsq/VsqTrack.cs | 413 + trunk/Boare.Lib.Vsq/VsqUtil.cs | 390 + trunk/Boare.Lib.Vsq/comhdr.h | 173 + trunk/Boare.Lib.Vsq/common.h | 46 + trunk/Boare.Lib.Vsq/makefile | 21 + .../Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.sln | 20 + .../port_cpp/Boare.Lib.Vsq.vcproj | 187 + trunk/Boare.Lib.Vsq/port_cpp/cp932.cpp | 9579 ++++++++++++++++ trunk/Boare.Lib.Vsq/port_cpp/cp932.h | 13 + trunk/Boare.Lib.Vsq/port_cpp/libvsq.cpp | 2 + trunk/Boare.Lib.Vsq/port_cpp/libvsq.h | 1184 ++ trunk/Boare.Lib.Vsq/port_cpp/main.cpp | 17 + trunk/LipSync/Background/Background.cs | 239 + trunk/LipSync/Background/Background.csproj | 77 + .../Background/Properties/AssemblyInfo.cs | 35 + .../Background/entry_config.Designer.cs | 289 + trunk/LipSync/Background/entry_config.cs | 74 + trunk/LipSync/Background/entry_config.resx | 123 + trunk/LipSync/Background/makefile | 10 + trunk/LipSync/DevUtl/DevUtl.csproj | 65 + trunk/LipSync/DevUtl/Program.cs | 139 + .../LipSync/DevUtl/Properties/AssemblyInfo.cs | 36 + trunk/LipSync/IPlugin/AviReader.cs | 483 + trunk/LipSync/IPlugin/IPlugin.cs | 129 + trunk/LipSync/IPlugin/IPlugin.csproj | 74 + trunk/LipSync/IPlugin/ISO639.cs | 29 + trunk/LipSync/IPlugin/InputBox.cs | 44 + trunk/LipSync/IPlugin/InputBox.designer.cs | 111 + trunk/LipSync/IPlugin/InputBox.resx | 120 + .../IPlugin/Properties/AssemblyInfo.cs | 35 + trunk/LipSync/IPlugin/makefile | 10 + trunk/LipSync/JVsq/build.xml | 69 + trunk/LipSync/JVsq/nbproject/build-impl.xml | 629 ++ .../JVsq/nbproject/genfiles.properties | 8 + .../LipSync/JVsq/nbproject/project.properties | 57 + trunk/LipSync/JVsq/nbproject/project.xml | 16 + .../jp/sourceforge/lipsync/bocoree/cp932.java | 130 + .../sourceforge/lipsync/bocoree/cp932_a.java | 3093 ++++++ .../sourceforge/lipsync/bocoree/cp932_b.java | 3093 ++++++ .../sourceforge/lipsync/bocoree/cp932_c.java | 3433 ++++++ .../jp/sourceforge/lipsync/bocoree/math.java | 340 + .../jp/sourceforge/lipsync/vsq/BPPair.java | 58 + .../sourceforge/lipsync/vsq/IconHandle.java | 88 + .../sourceforge/lipsync/vsq/KeyValuePair.java | 28 + .../src/jp/sourceforge/lipsync/vsq/Lyric.java | 365 + .../sourceforge/lipsync/vsq/LyricHandle.java | 47 + .../jp/sourceforge/lipsync/vsq/MidiEvent.java | 122 + .../lipsync/vsq/MidiEventType.java | 71 + .../jp/sourceforge/lipsync/vsq/MidiFile.java | 1636 +++ .../jp/sourceforge/lipsync/vsq/NrpnData.java | 49 + .../jp/sourceforge/lipsync/vsq/SMFReader.java | 50 + .../sourceforge/lipsync/vsq/SingerConfig.java | 327 + .../lipsync/vsq/TempoTableEntry.java | 70 + .../lipsync/vsq/TextMemoryStream.java | 112 + .../sourceforge/lipsync/vsq/TextResult.java | 43 + .../lipsync/vsq/TimeSigTableEntry.java | 90 + .../lipsync/vsq/VibratoHandle.java | 156 + .../sourceforge/lipsync/vsq/VibratoType.java | 33 + .../lipsync/vsq/VibratoTypeUtil.java | 253 + .../jp/sourceforge/lipsync/vsq/VsqBPList.java | 203 + .../lipsync/vsq/VsqBarLineEnumeration.java | 126 + .../lipsync/vsq/VsqBarLineType.java | 56 + .../sourceforge/lipsync/vsq/VsqCommand.java | 44 + .../lipsync/vsq/VsqCommandType.java | 45 + .../jp/sourceforge/lipsync/vsq/VsqCommon.java | 103 + .../sourceforge/lipsync/vsq/VsqCurveType.java | 60 + .../jp/sourceforge/lipsync/vsq/VsqEvent.java | 110 + .../lipsync/vsq/VsqEventIterator.java | 84 + .../lipsync/vsq/VsqEventIteratorMode.java | 24 + .../sourceforge/lipsync/vsq/VsqEventList.java | 97 + .../jp/sourceforge/lipsync/vsq/VsqFile.java | 2584 +++++ .../jp/sourceforge/lipsync/vsq/VsqHandle.java | 391 + .../lipsync/vsq/VsqHandleType.java | 24 + .../src/jp/sourceforge/lipsync/vsq/VsqID.java | 209 + .../jp/sourceforge/lipsync/vsq/VsqIDType.java | 24 + .../jp/sourceforge/lipsync/vsq/VsqMaster.java | 69 + .../sourceforge/lipsync/vsq/VsqMetaText.java | 911 ++ .../jp/sourceforge/lipsync/vsq/VsqMixer.java | 219 + .../lipsync/vsq/VsqMixerEntry.java | 40 + .../jp/sourceforge/lipsync/vsq/VsqNote.java | 239 + .../jp/sourceforge/lipsync/vsq/VsqNrpn.java | 143 + .../lipsync/vsq/VsqPhoneticSymbol.java | 146 + .../jp/sourceforge/lipsync/vsq/VsqTrack.java | 307 + .../jp/sourceforge/lipsync/vsq/VsqUtil.java | 326 + .../lipsync/vsq/VsqVoiceLanguage.java | 29 + trunk/LipSync/LipSync.sln | 86 + trunk/LipSync/LipSync/Common/AviutlPlugin.cs | 45 + trunk/LipSync/LipSync/Common/Common.cs | 264 + trunk/LipSync/LipSync/Common/CurveEditor.cs | 2653 +++++ .../LipSync/Common/CurveEditor.designer.cs | 68 + trunk/LipSync/LipSync/Common/NativeMethods.cs | 290 + .../Common/NumericUpDownEx.Designer.cs | 45 + .../LipSync/LipSync/Common/NumericUpDownEx.cs | 44 + .../LipSync/LipSync/Common/OpenFileDialog.cs | 506 + trunk/LipSync/LipSync/EditResx.pl | 14 + trunk/LipSync/LipSync/Editor/AppManager.cs | 468 + trunk/LipSync/LipSync/Editor/AviOutput.cs | 220 + .../LipSync/Editor/AviOutput.designer.cs | 378 + .../LipSync/Editor/AviOutputArguments.cs | 32 + trunk/LipSync/LipSync/Editor/AviReaderEx.cs | 47 + trunk/LipSync/LipSync/Editor/BarLineType.cs | 28 + .../LipSync/Editor/BugReport.Designer.cs | 75 + trunk/LipSync/LipSync/Editor/BugReport.cs | 84 + trunk/LipSync/LipSync/Editor/Character.cs | 300 + trunk/LipSync/LipSync/Editor/Character3.cs | 739 ++ .../Editor/CharacterConfigCollection.cs | 136 + .../Editor/CharacterConfigSpecifier.cs | 95 + trunk/LipSync/LipSync/Editor/ColorSet.cs | 95 + trunk/LipSync/LipSync/Editor/Command.cs | 316 + trunk/LipSync/LipSync/Editor/CommandType.cs | 44 + .../LipSync/Editor/DisplacementControl.cs | 235 + .../Editor/DisplacementControl.designer.cs | 194 + .../LipSync/Editor/EditEntry.Designer.cs | 207 + trunk/LipSync/LipSync/Editor/EditEntry.cs | 178 + trunk/LipSync/LipSync/Editor/EditMode.cs | 43 + trunk/LipSync/LipSync/Editor/EditingBounds.cs | 76 + .../Editor/EnvConfiguration.Designer.cs | 871 ++ .../LipSync/Editor/EnvConfiguration.cs | 412 + trunk/LipSync/LipSync/Editor/EnvSettings.cs | 351 + trunk/LipSync/LipSync/Editor/FontConfig.cs | 89 + trunk/LipSync/LipSync/Editor/Form1.cs | 3727 +++++++ .../LipSync/LipSync/Editor/Form1.designer.cs | 1294 +++ trunk/LipSync/LipSync/Editor/Form1Util.cs | 2228 ++++ .../LipSync/Editor/Form1_EventHandler.cs | 1183 ++ .../Editor/FormCommandHistory.Designer.cs | 113 + .../LipSync/Editor/FormCommandHistory.cs | 154 + .../LipSync/Editor/FormObjectList.Designer.cs | 64 + .../LipSync/LipSync/Editor/FormObjectList.cs | 55 + .../LipSync/Editor/FormPreview.Designer.cs | 55 + trunk/LipSync/LipSync/Editor/FormPreview.cs | 87 + .../Editor/FormSeriesImage.Designer.cs | 293 + .../LipSync/LipSync/Editor/FormSeriesImage.cs | 207 + .../Editor/FormSetFrameRate.Designer.cs | 197 + .../LipSync/Editor/FormSetFrameRate.cs | 188 + .../LipSync/Editor/FormVocalomark.Designer.cs | 729 ++ .../LipSync/LipSync/Editor/FormVocalomark.cs | 198 + .../LipSync/Editor/GenerateCharacter.cs | 931 ++ .../Editor/GenerateCharacter.designer.cs | 641 ++ trunk/LipSync/LipSync/Editor/IDrawObject.cs | 49 + .../LipSync/Editor/IMultiLanguageControl.cs | 24 + trunk/LipSync/LipSync/Editor/ImageEntry.cs | 196 + trunk/LipSync/LipSync/Editor/InputBox.cs | 53 + .../LipSync/Editor/InputBox.designer.cs | 113 + trunk/LipSync/LipSync/Editor/Item.cs | 35 + .../LipSync/Editor/MListView.Designer.cs | 97 + trunk/LipSync/LipSync/Editor/MListView.cs | 71 + .../Editor/PasteModeDialog.Designer.cs | 114 + .../LipSync/LipSync/Editor/PasteModeDialog.cs | 77 + trunk/LipSync/LipSync/Editor/PluginConfig.cs | 39 + trunk/LipSync/LipSync/Editor/PluginInfo.cs | 142 + trunk/LipSync/LipSync/Editor/Position.cs | 47 + .../LipSync/Editor/PositionConverter.cs | 67 + .../LipSync/Editor/Previewer.Designer.cs | 328 + trunk/LipSync/LipSync/Editor/Previewer.cs | 318 + .../LipSync/Editor/Property.Designer.cs | 273 + trunk/LipSync/LipSync/Editor/Property.cs | 389 + trunk/LipSync/LipSync/Editor/QuantizeMode.cs | 28 + .../LipSync/Editor/RipSync/RsiImporter.cs | 28 + .../LipSync/Editor/RipSync/RsiReader.cs | 162 + .../LipSync/Editor/RipSync/RsiWriter.cs | 530 + .../LipSync/Editor/RipSync/RspImporter.cs | 692 ++ trunk/LipSync/LipSync/Editor/ScoreUnit.cs | 52 + .../LipSync/LipSync/Editor/SelectCharacter.cs | 132 + .../Editor/SelectCharacter.designer.cs | 219 + trunk/LipSync/LipSync/Editor/SetSize.cs | 133 + .../LipSync/Editor/SetSize.designer.cs | 136 + trunk/LipSync/LipSync/Editor/Settings.cs | 214 + trunk/LipSync/LipSync/Editor/SettingsEx.cs | 1115 ++ .../LipSync/LipSync/Editor/TagForTreeNode.cs | 45 + trunk/LipSync/LipSync/Editor/Telop.cs | 444 + trunk/LipSync/LipSync/Editor/TimeSig.cs | 50 + trunk/LipSync/LipSync/Editor/TimeSigType.cs | 27 + .../LipSync/Editor/TimeTable/TimeTable.cs | 538 + .../Editor/TimeTable/TimeTableEntry.cs | 70 + .../Editor/TimeTable/TimeTableGroup.cs | 1087 ++ .../LipSync/Editor/TimeTable/TimeTableType.cs | 27 + trunk/LipSync/LipSync/Editor/TrackSelecter.cs | 98 + .../LipSync/Editor/TrackSelecter.designer.cs | 139 + trunk/LipSync/LipSync/Editor/VersionBox.cs | 44 + .../LipSync/Editor/VersionBox.designer.cs | 89 + trunk/LipSync/LipSync/Editor/VowelType.cs | 552 + .../LipSync/LipSync/Editor/Winker.Designer.cs | 266 + trunk/LipSync/LipSync/Editor/Winker.cs | 197 + .../LipSync/LipSync/Editor/ZOrder.Designer.cs | 150 + trunk/LipSync/LipSync/Editor/ZOrder.cs | 117 + trunk/LipSync/LipSync/Editor/ZorderItem.cs | 75 + trunk/LipSync/LipSync/LipSync.csproj | 444 + .../LipSync/Properties/AssemblyInfo.cs | 33 + .../LipSync/Properties/Resources.Designer.cs | 448 + .../LipSync/LipSync/Properties/Resources.resx | 286 + .../LipSync/Properties/Settings.Designer.cs | 26 + .../LipSync/LipSync/Resources/author_list.png | Bin 0 -> 8610 bytes trunk/LipSync/LipSync/Resources/closed.png | Bin 0 -> 178 bytes trunk/LipSync/LipSync/Resources/cursor.cur | Bin 0 -> 766 bytes trunk/LipSync/LipSync/Resources/opened.png | Bin 0 -> 168 bytes .../Resources/sanari_len/b_len100_a.png | Bin 0 -> 1788 bytes .../Resources/sanari_len/b_len100_aa.png | Bin 0 -> 1852 bytes .../Resources/sanari_len/b_len100_base.png | Bin 0 -> 57574 bytes .../Resources/sanari_len/b_len100_e.png | Bin 0 -> 1782 bytes .../sanari_len/b_len100_eyeclose.png | Bin 0 -> 4739 bytes .../Resources/sanari_len/b_len100_eyethin.png | Bin 0 -> 5713 bytes .../Resources/sanari_len/b_len100_i.png | Bin 0 -> 1759 bytes .../Resources/sanari_len/b_len100_kisisi.png | Bin 0 -> 1722 bytes .../Resources/sanari_len/b_len100_nn.png | Bin 0 -> 1649 bytes .../Resources/sanari_len/b_len100_o.png | Bin 0 -> 1747 bytes .../Resources/sanari_len/b_len100_shakin.png | Bin 0 -> 5825 bytes .../Resources/sanari_len/b_len100_smile.png | Bin 0 -> 4746 bytes .../Resources/sanari_len/b_len100_u.png | Bin 0 -> 1718 bytes .../sanari_len/b_len100_winkleft.png | Bin 0 -> 5334 bytes .../sanari_len/b_len100_winkright.png | Bin 0 -> 5273 bytes .../Resources/sanari_len/b_len100_xo.png | Bin 0 -> 1662 bytes .../Resources/sanari_miku/b_miku175_a.png | Bin 0 -> 4228 bytes .../Resources/sanari_miku/b_miku175_aa.png | Bin 0 -> 4290 bytes .../Resources/sanari_miku/b_miku175_base.png | Bin 0 -> 91575 bytes .../Resources/sanari_miku/b_miku175_bee.png | Bin 0 -> 4223 bytes .../Resources/sanari_miku/b_miku175_e.png | Bin 0 -> 4231 bytes .../sanari_miku/b_miku175_eyeclose.png | Bin 0 -> 9392 bytes .../sanari_miku/b_miku175_eyethin.png | Bin 0 -> 9987 bytes .../Resources/sanari_miku/b_miku175_i.png | Bin 0 -> 4200 bytes .../sanari_miku/b_miku175_konata.png | Bin 0 -> 9445 bytes .../Resources/sanari_miku/b_miku175_kudo.png | Bin 0 -> 9532 bytes .../Resources/sanari_miku/b_miku175_neko.png | Bin 0 -> 4102 bytes .../Resources/sanari_miku/b_miku175_nn.png | Bin 0 -> 4077 bytes .../Resources/sanari_miku/b_miku175_o.png | Bin 0 -> 4196 bytes .../Resources/sanari_miku/b_miku175_smile.png | Bin 0 -> 9346 bytes .../Resources/sanari_miku/b_miku175_u.png | Bin 0 -> 4171 bytes .../sanari_miku/b_miku175_winkleft.png | Bin 0 -> 9813 bytes .../sanari_miku/b_miku175_winkright.png | Bin 0 -> 9632 bytes .../Resources/sanari_miku/b_miku175_xo.png | Bin 0 -> 4118 bytes .../Resources/sanari_rin/b_rin100_a.png | Bin 0 -> 1678 bytes .../Resources/sanari_rin/b_rin100_aa.png | Bin 0 -> 1726 bytes .../Resources/sanari_rin/b_rin100_base.png | Bin 0 -> 60137 bytes .../Resources/sanari_rin/b_rin100_bee.png | Bin 0 -> 1663 bytes .../Resources/sanari_rin/b_rin100_e.png | Bin 0 -> 1687 bytes .../sanari_rin/b_rin100_eyeclose.png | Bin 0 -> 6939 bytes .../Resources/sanari_rin/b_rin100_eyethin.png | Bin 0 -> 7847 bytes .../Resources/sanari_rin/b_rin100_i.png | Bin 0 -> 1662 bytes .../Resources/sanari_rin/b_rin100_kisisi.png | Bin 0 -> 1686 bytes .../Resources/sanari_rin/b_rin100_kudo.png | Bin 0 -> 7080 bytes .../Resources/sanari_rin/b_rin100_neko.png | Bin 0 -> 1582 bytes .../Resources/sanari_rin/b_rin100_nn.png | Bin 0 -> 1559 bytes .../Resources/sanari_rin/b_rin100_o.png | Bin 0 -> 1665 bytes .../Resources/sanari_rin/b_rin100_smile.png | Bin 0 -> 7031 bytes .../Resources/sanari_rin/b_rin100_u.png | Bin 0 -> 1630 bytes .../sanari_rin/b_rin100_winkleft.png | Bin 0 -> 7517 bytes .../sanari_rin/b_rin100_winkright.png | Bin 0 -> 7503 bytes .../Resources/sanari_rin/b_rin100_xo.png | Bin 0 -> 1601 bytes .../LipSync/SearchUsageOfMessageIDEx.pl | 71 + trunk/LipSync/LipSync/de.po | 1033 ++ trunk/LipSync/LipSync/en.lang | 246 + trunk/LipSync/LipSync/ja.po | 1301 +++ trunk/LipSync/LipSync/makefile | 17 + trunk/LipSync/LipSync/readme_ja.txt | 31 + trunk/LipSync/LipSync/zh-CN.po | 1270 +++ trunk/LipSync/LipSync/zh-TW.po | 1268 +++ trunk/LipSync/NicoComment/Config.Designer.cs | 41 + trunk/LipSync/NicoComment/Config.cs | 15 + trunk/LipSync/NicoComment/Config.resx | 120 + trunk/LipSync/NicoComment/FConfig.Designer.cs | 116 + trunk/LipSync/NicoComment/FConfig.cs | 45 + trunk/LipSync/NicoComment/FConfig.resx | 123 + trunk/LipSync/NicoComment/Form1.Designer.cs | 100 + trunk/LipSync/NicoComment/Form1.cs | 25 + trunk/LipSync/NicoComment/Form1.resx | 120 + trunk/LipSync/NicoComment/NicoComment.cs | 508 + trunk/LipSync/NicoComment/NicoComment.csproj | 92 + trunk/LipSync/NicoComment/Program.cs | 30 + .../NicoComment/Properties/AssemblyInfo.cs | 35 + trunk/LipSync/NicoComment/makefile | 11 + .../LipSync/VFlip/Properties/AssemblyInfo.cs | 35 + trunk/LipSync/lang2po/Program.cs | 79 + .../lang2po/Properties/AssemblyInfo.cs | 36 + trunk/LipSync/lang2po/lang2po.csproj | 70 + trunk/LipSync/lang2po/template.po | 1076 ++ trunk/LipSync/makefile | 64 + trunk/bocoree/Properties/AssemblyInfo.cs | 25 + trunk/bocoree/bocoree.csproj | 75 + trunk/bocoree/cp932.cs | 9716 +++++++++++++++++ trunk/bocoree/cp932reader.cs | 110 + trunk/bocoree/cp932writer.cs | 60 + trunk/bocoree/fft.cs | 3255 ++++++ trunk/bocoree/makefile | 8 + trunk/bocoree/math.cs | 273 + trunk/bocoree/misc.cs | 145 + trunk/bocoree/windows.cs | 171 + trunk/bocoree/wingdi.cs | 118 + trunk/bocoree/winmm.cs | 405 + 373 files changed, 111302 insertions(+) create mode 100644 trunk/Boare.Lib.AppUtil/AuthorListEntry.cs create mode 100644 trunk/Boare.Lib.AppUtil/BHScrollBar.Designer.cs create mode 100644 trunk/Boare.Lib.AppUtil/BHScrollBar.cs create mode 100644 trunk/Boare.Lib.AppUtil/BSplitContainer.cs create mode 100644 trunk/Boare.Lib.AppUtil/BSplitterPanel.cs create mode 100644 trunk/Boare.Lib.AppUtil/BTrackBar.cs create mode 100644 trunk/Boare.Lib.AppUtil/BVScrollBar.Designer.cs create mode 100644 trunk/Boare.Lib.AppUtil/BVScrollBar.cs create mode 100644 trunk/Boare.Lib.AppUtil/BitmapEx.cs create mode 100644 trunk/Boare.Lib.AppUtil/Boare.Lib.AppUtil.csproj create mode 100644 trunk/Boare.Lib.AppUtil/ColorBar.cs create mode 100644 trunk/Boare.Lib.AppUtil/CubicSpline.cs create mode 100644 trunk/Boare.Lib.AppUtil/ISO639.cs create mode 100644 trunk/Boare.Lib.AppUtil/InputBox.Designer.cs create mode 100644 trunk/Boare.Lib.AppUtil/InputBox.cs create mode 100644 trunk/Boare.Lib.AppUtil/MathEx.cs create mode 100644 trunk/Boare.Lib.AppUtil/MessageBody.cs create mode 100644 trunk/Boare.Lib.AppUtil/Messaging.cs create mode 100644 trunk/Boare.Lib.AppUtil/Misc.cs create mode 100644 trunk/Boare.Lib.AppUtil/Properties/AssemblyInfo.cs create mode 100644 trunk/Boare.Lib.AppUtil/VersionInfo.Designer.cs create mode 100644 trunk/Boare.Lib.AppUtil/VersionInfo.cs create mode 100644 trunk/Boare.Lib.AppUtil/XmlSerializeWithDescription.cs create mode 100644 trunk/Boare.Lib.AppUtil/XmlStaticMemberSerializer.cs create mode 100644 trunk/Boare.Lib.AppUtil/makefile create mode 100644 trunk/Boare.Lib.Media/AviReader.cs create mode 100644 trunk/Boare.Lib.Media/AviWriterVcm.cs create mode 100644 trunk/Boare.Lib.Media/AviWriterVfw.cs create mode 100644 trunk/Boare.Lib.Media/Boare.Lib.Media.csproj create mode 100644 trunk/Boare.Lib.Media/IAviWriter.cs create mode 100644 trunk/Boare.Lib.Media/MediaPlayer.cs create mode 100644 trunk/Boare.Lib.Media/MidiInDevice.cs create mode 100644 trunk/Boare.Lib.Media/PipedAviWriter.cs create mode 100644 trunk/Boare.Lib.Media/Properties/AssemblyInfo.cs create mode 100644 trunk/Boare.Lib.Media/RawAvi2Writer.cs create mode 100644 trunk/Boare.Lib.Media/Util.cs create mode 100644 trunk/Boare.Lib.Media/VCM.cs create mode 100644 trunk/Boare.Lib.Media/VFW.cs create mode 100644 trunk/Boare.Lib.Media/Wave.cs create mode 100644 trunk/Boare.Lib.Media/WavePlay.cs create mode 100644 trunk/Boare.Lib.Media/WaveReader.cs create mode 100644 trunk/Boare.Lib.Media/WaveWriter.cs create mode 100644 trunk/Boare.Lib.Media/makefile create mode 100644 trunk/Boare.Lib.Swf/Boare.Lib.Swf.csproj create mode 100644 trunk/Boare.Lib.Swf/Properties/AssemblyInfo.cs create mode 100644 trunk/Boare.Lib.Swf/RECT.cs create mode 100644 trunk/Boare.Lib.Swf/SB.cs create mode 100644 trunk/Boare.Lib.Swf/SwfWriter.cs create mode 100644 trunk/Boare.Lib.Swf/Util.cs create mode 100644 trunk/Boare.Lib.Swf/makefile create mode 100644 trunk/Boare.Lib.Vsq/BPPair.cs create mode 100644 trunk/Boare.Lib.Vsq/Boare.Lib.Vsq.csproj create mode 100644 trunk/Boare.Lib.Vsq/NRPN.cs create mode 100644 trunk/Boare.Lib.Vsq/NrpnData.cs create mode 100644 trunk/Boare.Lib.Vsq/PortUtil.cs create mode 100644 trunk/Boare.Lib.Vsq/Properties/AssemblyInfo.cs create mode 100644 trunk/Boare.Lib.Vsq/SMF/MidiFile.cs create mode 100644 trunk/Boare.Lib.Vsq/SingerConfig.cs create mode 100644 trunk/Boare.Lib.Vsq/SymbolTable.cs create mode 100644 trunk/Boare.Lib.Vsq/TempoTableEntry.cs create mode 100644 trunk/Boare.Lib.Vsq/TextMemoryStream.cs create mode 100644 trunk/Boare.Lib.Vsq/TimeSigTableEntry.cs create mode 100644 trunk/Boare.Lib.Vsq/UstEvent.cs create mode 100644 trunk/Boare.Lib.Vsq/UstFile.cs create mode 100644 trunk/Boare.Lib.Vsq/UstTrack.cs create mode 100644 trunk/Boare.Lib.Vsq/VibratoBPList.cs create mode 100644 trunk/Boare.Lib.Vsq/VibratoBPPair.cs create mode 100644 trunk/Boare.Lib.Vsq/VibratoType.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqBPList.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqBarLineType.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqCommand.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqCommandType.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqEvent.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqEventList.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqFile.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Common.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Common.java create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Handle.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/ID.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Lyric.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Master.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/Mixer.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqMetaText/VsqMetaText.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqNote.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqNrpn.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqPhoneticSymbol.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqTrack.cs create mode 100644 trunk/Boare.Lib.Vsq/VsqUtil.cs create mode 100644 trunk/Boare.Lib.Vsq/comhdr.h create mode 100644 trunk/Boare.Lib.Vsq/common.h create mode 100644 trunk/Boare.Lib.Vsq/makefile create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.sln create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.vcproj create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/cp932.cpp create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/cp932.h create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/libvsq.cpp create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/libvsq.h create mode 100644 trunk/Boare.Lib.Vsq/port_cpp/main.cpp create mode 100644 trunk/LipSync/Background/Background.cs create mode 100644 trunk/LipSync/Background/Background.csproj create mode 100644 trunk/LipSync/Background/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/Background/entry_config.Designer.cs create mode 100644 trunk/LipSync/Background/entry_config.cs create mode 100644 trunk/LipSync/Background/entry_config.resx create mode 100644 trunk/LipSync/Background/makefile create mode 100644 trunk/LipSync/DevUtl/DevUtl.csproj create mode 100644 trunk/LipSync/DevUtl/Program.cs create mode 100644 trunk/LipSync/DevUtl/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/IPlugin/AviReader.cs create mode 100644 trunk/LipSync/IPlugin/IPlugin.cs create mode 100644 trunk/LipSync/IPlugin/IPlugin.csproj create mode 100644 trunk/LipSync/IPlugin/ISO639.cs create mode 100644 trunk/LipSync/IPlugin/InputBox.cs create mode 100644 trunk/LipSync/IPlugin/InputBox.designer.cs create mode 100644 trunk/LipSync/IPlugin/InputBox.resx create mode 100644 trunk/LipSync/IPlugin/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/IPlugin/makefile create mode 100644 trunk/LipSync/JVsq/build.xml create mode 100644 trunk/LipSync/JVsq/nbproject/build-impl.xml create mode 100644 trunk/LipSync/JVsq/nbproject/genfiles.properties create mode 100644 trunk/LipSync/JVsq/nbproject/project.properties create mode 100644 trunk/LipSync/JVsq/nbproject/project.xml create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_a.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_b.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_c.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/math.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/BPPair.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/IconHandle.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/KeyValuePair.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/Lyric.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/LyricHandle.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEvent.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEventType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiFile.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/NrpnData.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SMFReader.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SingerConfig.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TempoTableEntry.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextMemoryStream.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextResult.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TimeSigTableEntry.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoHandle.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoTypeUtil.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBPList.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineEnumeration.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommand.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommandType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommon.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCurveType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEvent.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIterator.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIteratorMode.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventList.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqFile.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandle.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandleType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqID.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqIDType.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMaster.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMetaText.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixer.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixerEntry.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNote.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNrpn.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqPhoneticSymbol.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqTrack.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqUtil.java create mode 100644 trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqVoiceLanguage.java create mode 100644 trunk/LipSync/LipSync.sln create mode 100644 trunk/LipSync/LipSync/Common/AviutlPlugin.cs create mode 100644 trunk/LipSync/LipSync/Common/Common.cs create mode 100644 trunk/LipSync/LipSync/Common/CurveEditor.cs create mode 100644 trunk/LipSync/LipSync/Common/CurveEditor.designer.cs create mode 100644 trunk/LipSync/LipSync/Common/NativeMethods.cs create mode 100644 trunk/LipSync/LipSync/Common/NumericUpDownEx.Designer.cs create mode 100644 trunk/LipSync/LipSync/Common/NumericUpDownEx.cs create mode 100644 trunk/LipSync/LipSync/Common/OpenFileDialog.cs create mode 100644 trunk/LipSync/LipSync/EditResx.pl create mode 100644 trunk/LipSync/LipSync/Editor/AppManager.cs create mode 100644 trunk/LipSync/LipSync/Editor/AviOutput.cs create mode 100644 trunk/LipSync/LipSync/Editor/AviOutput.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/AviOutputArguments.cs create mode 100644 trunk/LipSync/LipSync/Editor/AviReaderEx.cs create mode 100644 trunk/LipSync/LipSync/Editor/BarLineType.cs create mode 100644 trunk/LipSync/LipSync/Editor/BugReport.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/BugReport.cs create mode 100644 trunk/LipSync/LipSync/Editor/Character.cs create mode 100644 trunk/LipSync/LipSync/Editor/Character3.cs create mode 100644 trunk/LipSync/LipSync/Editor/CharacterConfigCollection.cs create mode 100644 trunk/LipSync/LipSync/Editor/CharacterConfigSpecifier.cs create mode 100644 trunk/LipSync/LipSync/Editor/ColorSet.cs create mode 100644 trunk/LipSync/LipSync/Editor/Command.cs create mode 100644 trunk/LipSync/LipSync/Editor/CommandType.cs create mode 100644 trunk/LipSync/LipSync/Editor/DisplacementControl.cs create mode 100644 trunk/LipSync/LipSync/Editor/DisplacementControl.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/EditEntry.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/EditEntry.cs create mode 100644 trunk/LipSync/LipSync/Editor/EditMode.cs create mode 100644 trunk/LipSync/LipSync/Editor/EditingBounds.cs create mode 100644 trunk/LipSync/LipSync/Editor/EnvConfiguration.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/EnvConfiguration.cs create mode 100644 trunk/LipSync/LipSync/Editor/EnvSettings.cs create mode 100644 trunk/LipSync/LipSync/Editor/FontConfig.cs create mode 100644 trunk/LipSync/LipSync/Editor/Form1.cs create mode 100644 trunk/LipSync/LipSync/Editor/Form1.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Form1Util.cs create mode 100644 trunk/LipSync/LipSync/Editor/Form1_EventHandler.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormCommandHistory.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormCommandHistory.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormObjectList.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormObjectList.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormPreview.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormPreview.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormSeriesImage.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormSeriesImage.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormSetFrameRate.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormSetFrameRate.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormVocalomark.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/FormVocalomark.cs create mode 100644 trunk/LipSync/LipSync/Editor/GenerateCharacter.cs create mode 100644 trunk/LipSync/LipSync/Editor/GenerateCharacter.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/IDrawObject.cs create mode 100644 trunk/LipSync/LipSync/Editor/IMultiLanguageControl.cs create mode 100644 trunk/LipSync/LipSync/Editor/ImageEntry.cs create mode 100644 trunk/LipSync/LipSync/Editor/InputBox.cs create mode 100644 trunk/LipSync/LipSync/Editor/InputBox.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Item.cs create mode 100644 trunk/LipSync/LipSync/Editor/MListView.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/MListView.cs create mode 100644 trunk/LipSync/LipSync/Editor/PasteModeDialog.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/PasteModeDialog.cs create mode 100644 trunk/LipSync/LipSync/Editor/PluginConfig.cs create mode 100644 trunk/LipSync/LipSync/Editor/PluginInfo.cs create mode 100644 trunk/LipSync/LipSync/Editor/Position.cs create mode 100644 trunk/LipSync/LipSync/Editor/PositionConverter.cs create mode 100644 trunk/LipSync/LipSync/Editor/Previewer.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Previewer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Property.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Property.cs create mode 100644 trunk/LipSync/LipSync/Editor/QuantizeMode.cs create mode 100644 trunk/LipSync/LipSync/Editor/RipSync/RsiImporter.cs create mode 100644 trunk/LipSync/LipSync/Editor/RipSync/RsiReader.cs create mode 100644 trunk/LipSync/LipSync/Editor/RipSync/RsiWriter.cs create mode 100644 trunk/LipSync/LipSync/Editor/RipSync/RspImporter.cs create mode 100644 trunk/LipSync/LipSync/Editor/ScoreUnit.cs create mode 100644 trunk/LipSync/LipSync/Editor/SelectCharacter.cs create mode 100644 trunk/LipSync/LipSync/Editor/SelectCharacter.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/SetSize.cs create mode 100644 trunk/LipSync/LipSync/Editor/SetSize.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Settings.cs create mode 100644 trunk/LipSync/LipSync/Editor/SettingsEx.cs create mode 100644 trunk/LipSync/LipSync/Editor/TagForTreeNode.cs create mode 100644 trunk/LipSync/LipSync/Editor/Telop.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeSig.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeSigType.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeTable/TimeTable.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeTable/TimeTableEntry.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeTable/TimeTableGroup.cs create mode 100644 trunk/LipSync/LipSync/Editor/TimeTable/TimeTableType.cs create mode 100644 trunk/LipSync/LipSync/Editor/TrackSelecter.cs create mode 100644 trunk/LipSync/LipSync/Editor/TrackSelecter.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/VersionBox.cs create mode 100644 trunk/LipSync/LipSync/Editor/VersionBox.designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/VowelType.cs create mode 100644 trunk/LipSync/LipSync/Editor/Winker.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/Winker.cs create mode 100644 trunk/LipSync/LipSync/Editor/ZOrder.Designer.cs create mode 100644 trunk/LipSync/LipSync/Editor/ZOrder.cs create mode 100644 trunk/LipSync/LipSync/Editor/ZorderItem.cs create mode 100644 trunk/LipSync/LipSync/LipSync.csproj create mode 100644 trunk/LipSync/LipSync/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/LipSync/Properties/Resources.Designer.cs create mode 100644 trunk/LipSync/LipSync/Properties/Resources.resx create mode 100644 trunk/LipSync/LipSync/Properties/Settings.Designer.cs create mode 100644 trunk/LipSync/LipSync/Resources/author_list.png create mode 100644 trunk/LipSync/LipSync/Resources/closed.png create mode 100644 trunk/LipSync/LipSync/Resources/cursor.cur create mode 100644 trunk/LipSync/LipSync/Resources/opened.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_a.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_aa.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_base.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_e.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_eyeclose.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_eyethin.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_i.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_kisisi.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_nn.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_o.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_shakin.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_smile.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_u.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkleft.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkright.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_len/b_len100_xo.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_a.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_aa.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_base.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_bee.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_e.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_eyeclose.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_eyethin.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_i.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_konata.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_kudo.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_neko.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_nn.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_o.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_smile.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_u.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkleft.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkright.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_xo.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_a.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_aa.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_base.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_bee.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_e.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_eyeclose.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_eyethin.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_i.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_kisisi.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_kudo.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_neko.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_nn.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_o.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_smile.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_u.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_winkleft.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_winkright.png create mode 100644 trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_xo.png create mode 100644 trunk/LipSync/LipSync/SearchUsageOfMessageIDEx.pl create mode 100644 trunk/LipSync/LipSync/de.po create mode 100644 trunk/LipSync/LipSync/en.lang create mode 100644 trunk/LipSync/LipSync/ja.po create mode 100644 trunk/LipSync/LipSync/makefile create mode 100644 trunk/LipSync/LipSync/readme_ja.txt create mode 100644 trunk/LipSync/LipSync/zh-CN.po create mode 100644 trunk/LipSync/LipSync/zh-TW.po create mode 100644 trunk/LipSync/NicoComment/Config.Designer.cs create mode 100644 trunk/LipSync/NicoComment/Config.cs create mode 100644 trunk/LipSync/NicoComment/Config.resx create mode 100644 trunk/LipSync/NicoComment/FConfig.Designer.cs create mode 100644 trunk/LipSync/NicoComment/FConfig.cs create mode 100644 trunk/LipSync/NicoComment/FConfig.resx create mode 100644 trunk/LipSync/NicoComment/Form1.Designer.cs create mode 100644 trunk/LipSync/NicoComment/Form1.cs create mode 100644 trunk/LipSync/NicoComment/Form1.resx create mode 100644 trunk/LipSync/NicoComment/NicoComment.cs create mode 100644 trunk/LipSync/NicoComment/NicoComment.csproj create mode 100644 trunk/LipSync/NicoComment/Program.cs create mode 100644 trunk/LipSync/NicoComment/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/NicoComment/makefile create mode 100644 trunk/LipSync/VFlip/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/lang2po/Program.cs create mode 100644 trunk/LipSync/lang2po/Properties/AssemblyInfo.cs create mode 100644 trunk/LipSync/lang2po/lang2po.csproj create mode 100644 trunk/LipSync/lang2po/template.po create mode 100644 trunk/LipSync/makefile create mode 100644 trunk/bocoree/Properties/AssemblyInfo.cs create mode 100644 trunk/bocoree/bocoree.csproj create mode 100644 trunk/bocoree/cp932.cs create mode 100644 trunk/bocoree/cp932reader.cs create mode 100644 trunk/bocoree/cp932writer.cs create mode 100644 trunk/bocoree/fft.cs create mode 100644 trunk/bocoree/makefile create mode 100644 trunk/bocoree/math.cs create mode 100644 trunk/bocoree/misc.cs create mode 100644 trunk/bocoree/windows.cs create mode 100644 trunk/bocoree/wingdi.cs create mode 100644 trunk/bocoree/winmm.cs diff --git a/trunk/Boare.Lib.AppUtil/AuthorListEntry.cs b/trunk/Boare.Lib.AppUtil/AuthorListEntry.cs new file mode 100644 index 0000000..8b75b3c --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/AuthorListEntry.cs @@ -0,0 +1,50 @@ +/* + * AuthorListEntry.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Drawing; + +namespace Boare.Lib.AppUtil { + + public class AuthorListEntry { + string m_name; + FontStyle m_style; + + public AuthorListEntry( string name, FontStyle style ) + : this( name ) { + m_style = style; + } + + public AuthorListEntry( string name ) { + m_name = name; + m_style = FontStyle.Regular; + } + + public AuthorListEntry() { + m_name = ""; + m_style = FontStyle.Regular; + } + + public string Name { + get { + return m_name; + } + } + + public FontStyle Style { + get { + return m_style; + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BHScrollBar.Designer.cs b/trunk/Boare.Lib.AppUtil/BHScrollBar.Designer.cs new file mode 100644 index 0000000..9564606 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BHScrollBar.Designer.cs @@ -0,0 +1,66 @@ +/* + * BHScrollBar.Designer.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.AppUtil { + partial class BHScrollBar { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.hScroll = new System.Windows.Forms.HScrollBar(); + this.SuspendLayout(); + // + // hScroll + // + this.hScroll.Dock = System.Windows.Forms.DockStyle.Fill; + this.hScroll.Location = new System.Drawing.Point( 0, 0 ); + this.hScroll.Name = "hScroll"; + this.hScroll.Size = new System.Drawing.Size( 333, 16 ); + this.hScroll.TabIndex = 0; + this.hScroll.ValueChanged += new System.EventHandler( this.hScroll_ValueChanged ); + // + // BHScrollBar + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add( this.hScroll ); + this.Name = "BHScrollBar"; + this.Size = new System.Drawing.Size( 333, 16 ); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.HScrollBar hScroll; + } +} diff --git a/trunk/Boare.Lib.AppUtil/BHScrollBar.cs b/trunk/Boare.Lib.AppUtil/BHScrollBar.cs new file mode 100644 index 0000000..0831ec9 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BHScrollBar.cs @@ -0,0 +1,86 @@ +/* + * BHScrollBar.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + + /// + /// Valueの値が正しくMinimumからMaximumの間を動くスクロールバー + /// + public partial class BHScrollBar : UserControl { + int m_max = 100; + int m_min = 0; + + public event EventHandler ValueChanged; + + public BHScrollBar() { + InitializeComponent(); + } + + public int Value { + get { + return hScroll.Value; + } + set { + hScroll.Value = value; + } + } + + public int LargeChange { + get { + return hScroll.LargeChange; + } + set { + hScroll.LargeChange = value; + hScroll.Maximum = m_max + value; + } + } + + public int SmallChange { + get { + return hScroll.SmallChange; + } + set { + hScroll.SmallChange = value; + } + } + + public int Maximum { + get { + return m_max; + } + set { + m_max = value; + hScroll.Maximum = m_max + hScroll.LargeChange; + } + } + + public int Minimum { + get { + return m_min; + } + set { + m_min = value; + } + } + + private void hScroll_ValueChanged( object sender, EventArgs e ) { + if ( ValueChanged != null ) { + ValueChanged( this, e ); + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BSplitContainer.cs b/trunk/Boare.Lib.AppUtil/BSplitContainer.cs new file mode 100644 index 0000000..d943296 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BSplitContainer.cs @@ -0,0 +1,506 @@ +/* + * BSplitContainer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + + [Serializable] + public partial class BSplitContainer : ContainerControl { + private Orientation m_orientation = Orientation.Horizontal; + private int m_splitter_distance = 50; + private int m_panel1_min = 25; + private int m_panel2_min = 25; + private int m_splitter_width = 4; + private bool m_splitter_moving = false; + private int m_splitter_distance_draft = 50; + private BSplitterPanel m_panel1; + private BSplitterPanel m_panel2; + private System.ComponentModel.IContainer components = null; + private bool m_splitter_fixed = false; + private Pen m_panel1_border = null; + private Pen m_panel2_border = null; + private System.Windows.Forms.FixedPanel m_fixed_panel; + private PictureBox m_lbl_splitter; + private int m_panel2_distance = 1; + private double m_distance_rate = 0.5; + + public event SplitterEventHandler SplitterMoved; + [Browsable(false)] + public event ControlEventHandler ControlAdded; + + public BSplitContainer() { + InitializeComponent(); + if ( m_orientation == Orientation.Horizontal ) { + m_lbl_splitter.Cursor = Cursors.VSplit; + } else { + m_lbl_splitter.Cursor = Cursors.HSplit; + } + if ( m_orientation == Orientation.Horizontal ) { + m_panel2_distance = this.Width - m_splitter_distance; + } else { + m_panel2_distance = this.Height - m_splitter_distance; + } + m_distance_rate = m_splitter_distance / (double)(m_splitter_distance + m_panel2_distance); + } + + public System.Windows.Forms.FixedPanel FixedPanel { + get { + return m_fixed_panel; + } + set { + System.Windows.Forms.FixedPanel old = m_fixed_panel; + m_fixed_panel = value; + if ( m_fixed_panel != FixedPanel.None && m_fixed_panel != old ) { + if ( m_fixed_panel == FixedPanel.Panel1 ) { + m_panel2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + if ( m_orientation == Orientation.Vertical ) { + m_panel1.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + } else { + m_panel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left; + } + } else { + m_panel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + if ( m_orientation == Orientation.Vertical ) { + m_panel2.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + } else { + m_panel2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; + } + } + } + } + } + + public bool IsSplitterFixed { + get { + return m_splitter_fixed; + } + set { + m_splitter_fixed = value; + if ( m_splitter_fixed ) { + m_lbl_splitter.Cursor = Cursors.Default; + } else { + if ( m_orientation == Orientation.Horizontal ) { + m_lbl_splitter.Cursor = Cursors.VSplit; + } else { + m_lbl_splitter.Cursor = Cursors.HSplit; + } + } + } + } + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.m_lbl_splitter = new System.Windows.Forms.PictureBox(); + this.m_panel2 = new Boare.Lib.AppUtil.BSplitterPanel(); + this.m_panel1 = new Boare.Lib.AppUtil.BSplitterPanel(); + ((System.ComponentModel.ISupportInitialize)(this.m_lbl_splitter)).BeginInit(); + this.SuspendLayout(); + // + // m_lbl_splitter + // + this.m_lbl_splitter.BackColor = System.Drawing.Color.Transparent; + this.m_lbl_splitter.Location = new System.Drawing.Point( 0, 0 ); + this.m_lbl_splitter.Name = "m_lbl_splitter"; + this.m_lbl_splitter.Size = new System.Drawing.Size( 100, 50 ); + this.m_lbl_splitter.TabIndex = 0; + this.m_lbl_splitter.TabStop = false; + this.m_lbl_splitter.MouseMove += new System.Windows.Forms.MouseEventHandler( this.m_lbl_splitter_MouseMove ); + this.m_lbl_splitter.MouseDown += new System.Windows.Forms.MouseEventHandler( this.m_lbl_splitter_MouseDown ); + this.m_lbl_splitter.MouseUp += new System.Windows.Forms.MouseEventHandler( this.m_lbl_splitter_MouseUp ); + // + // m_panel2 + // + this.m_panel2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.m_panel2.BorderColor = System.Drawing.Color.Black; + this.m_panel2.Location = new System.Drawing.Point( 0, 103 ); + this.m_panel2.Margin = new System.Windows.Forms.Padding( 0 ); + this.m_panel2.Name = "m_panel2"; + this.m_panel2.Size = new System.Drawing.Size( 441, 245 ); + this.m_panel2.TabIndex = 1; + this.m_panel2.BorderStyleChanged += new System.EventHandler( this.m_panel2_BorderStyleChanged ); + this.m_panel2.SizeChanged += new System.EventHandler( this.m_panel2_SizeChanged ); + // + // m_panel1 + // + this.m_panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.m_panel1.BorderColor = System.Drawing.Color.Black; + this.m_panel1.Location = new System.Drawing.Point( 0, 0 ); + this.m_panel1.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 4 ); + this.m_panel1.Name = "m_panel1"; + this.m_panel1.Size = new System.Drawing.Size( 441, 99 ); + this.m_panel1.TabIndex = 0; + this.m_panel1.BorderStyleChanged += new System.EventHandler( this.m_panel1_BorderStyleChanged ); + this.m_panel1.SizeChanged += new System.EventHandler( this.m_panel1_SizeChanged ); + // + // SplitContainerEx + // + this.Controls.Add( this.m_panel2 ); + this.Controls.Add( this.m_panel1 ); + this.Controls.Add( this.m_lbl_splitter ); + this.Size = new System.Drawing.Size( 441, 348 ); + this.Paint += new System.Windows.Forms.PaintEventHandler( this.SplitContainerEx_Paint ); + ((System.ComponentModel.ISupportInitialize)(this.m_lbl_splitter)).EndInit(); + this.ResumeLayout( false ); + } + + private void SplitContainerEx_Paint( object sender, PaintEventArgs e ) { + bool panel1_visible = true; + if ( Orientation == Orientation.Horizontal ) { + if ( m_panel1.Width == 0 ) { + panel1_visible = false; + } + } else { + if ( m_panel1.Height == 0 ) { + panel1_visible = false; + } + } + if ( m_panel1.BorderStyle == BorderStyle.FixedSingle && panel1_visible ) { + if ( m_panel1_border == null ) { + m_panel1_border = new Pen( m_panel1.BorderColor ); + } else { + if ( !m_panel1.BorderColor.Equals( m_panel1_border.Color ) ) { + m_panel1_border = new Pen( m_panel1.BorderColor ); + } + } + e.Graphics.DrawRectangle( m_panel1_border, + new Rectangle( m_panel1.Left - 1, m_panel1.Top - 1, m_panel1.Width + 1, m_panel1.Height + 1) ); + } + + bool panel2_visible = true; + if ( Orientation == Orientation.Horizontal ) { + if ( m_panel2.Width == 0 ) { + panel2_visible = false; + } + } else { + if ( m_panel2.Height == 0 ) { + panel2_visible = false; + } + } + if ( m_panel2.BorderStyle == BorderStyle.FixedSingle && panel2_visible ) { + if ( m_panel2_border == null ) { + m_panel2_border = new Pen( m_panel2.BorderColor ); + } else { + if ( !m_panel2.BorderColor.Equals( m_panel2_border.Color ) ) { + m_panel2_border = new Pen( m_panel2.BorderColor ); + } + } + e.Graphics.DrawRectangle( m_panel2_border, + new Rectangle( m_panel2.Left - 1, m_panel2.Top - 1, m_panel2.Width + 1, m_panel2.Height + 1 ) ); + } + } + + private void m_panel2_BorderStyleChanged( object sender, EventArgs e ) { + UpdateLayout( m_splitter_distance, m_splitter_width, m_panel1_min, m_panel2_min, false ); + } + + private void m_panel1_BorderStyleChanged( object sender, EventArgs e ) { + UpdateLayout( m_splitter_distance, m_splitter_width, m_panel1_min, m_panel2_min, false ); + } + + private void m_panel2_SizeChanged( object sender, EventArgs e ) { + m_panel2.Invalidate( true ); + } + + private void m_panel1_SizeChanged( object sender, EventArgs e ) { + m_panel1.Invalidate( true ); + } + + public int Panel1MinSize { + get { + return m_panel1_min; + } + set { + int min_splitter_distance = value; + if ( m_splitter_distance < min_splitter_distance && min_splitter_distance > 0 ) { + m_splitter_distance = min_splitter_distance; + } + UpdateLayout( m_splitter_distance, m_splitter_width, value, m_panel2_min, false ); + } + } + + public int Panel2MinSize { + get { + return m_panel2_min; + } + set { + int max_splitter_distance = (m_orientation == Orientation.Horizontal) ? + this.Width - m_splitter_width - value : + this.Height - m_splitter_width - value; + if ( m_splitter_distance > max_splitter_distance && max_splitter_distance > 0 ) { + m_splitter_distance = max_splitter_distance; + } + UpdateLayout( m_splitter_distance, m_splitter_width, m_panel1_min, value, false ); + } + } + + public int SplitterWidth { + get { + return m_splitter_width; + } + set { + if ( value < 1 ) { + value = 1; + } + UpdateLayout( m_splitter_distance, value, m_panel1_min, m_panel2_min, false ); + } + } + + private bool UpdateLayout( int splitter_distance, int splitter_width, int panel1_min, int panel2_min, bool check_only ) { + Point mouse = this.PointToClient( Control.MousePosition ); + int pad1 = (m_panel1.BorderStyle == BorderStyle.FixedSingle) ? 1 : 0; + int pad2 = (m_panel2.BorderStyle == BorderStyle.FixedSingle) ? 1 : 0; + if ( m_orientation == Orientation.Horizontal ) { + int p1 = splitter_distance; + if ( p1 < 0 ) { + p1 = 0; + } else if ( this.Width < p1 + splitter_width ) { + p1 = this.Width - splitter_width; + } + int p2 = this.Width - p1 - splitter_width; + if ( check_only ) { + if ( p1 < panel1_min || p2 < panel2_min ) { + return false; + } + } else { + if ( p1 < panel1_min ) { + p1 = panel1_min; + } + p2 = this.Width - p1 - splitter_width; + if ( p2 < panel2_min ) { + p2 = panel2_min; + //return false; + } + } + if ( !check_only ) { + m_panel1.Left = pad1; + m_panel1.Top = pad1; + m_panel1.Width = (p1 - 2 * pad1 >= 0) ? (p1 - 2 * pad1) : 0; + m_panel1.Height = (this.Height - 2 * pad1 >= 0) ? (this.Height - 2 * pad1) : 0; + + m_panel2.Left = p1 + splitter_width + pad2; + m_panel2.Top = pad2; + m_panel2.Width = (p2 - 2 * pad2 >= 0) ? (p2 - 2 * pad2) : 0; + m_panel2.Height = (this.Height - 2 * pad2 >= 0) ? (this.Height - 2 * pad2) : 0; + + m_splitter_distance = p1; + m_panel2_distance = this.Width - m_splitter_distance; + m_distance_rate = m_splitter_distance / (double)(m_splitter_distance + m_panel2_distance); + if ( SplitterMoved != null ) { + SplitterMoved( this, new SplitterEventArgs( mouse.X, mouse.Y, p1, 0 ) ); + } + m_splitter_width = splitter_width; + m_panel1_min = panel1_min; + m_panel2_min = panel2_min; + + m_lbl_splitter.Left = p1; + m_lbl_splitter.Top = 0; + m_lbl_splitter.Width = splitter_width; + m_lbl_splitter.Height = this.Height; + } + return true; + } else { + int p1 = splitter_distance; + if ( p1 < 0 ) { + p1 = 0; + } else if ( this.Height < p1 + splitter_width ) { + p1 = this.Height - splitter_width; + } + int p2 = this.Height - p1 - splitter_width; + if ( check_only ) { + if ( p1 < panel1_min || p2 < panel2_min ) { + return false; + } + } else { + if ( p1 < panel1_min ) { + p1 = panel1_min; + } + p2 = this.Height - p1 - splitter_width; + if ( p2 < panel2_min ) { + p2 = panel2_min; + //return false; + } + } + if ( !check_only ) { + m_panel1.Left = pad1; + m_panel1.Top = pad1; + m_panel1.Width = (this.Width - 2 * pad1 >= 0) ? (this.Width - 2 * pad1) : 0; + m_panel1.Height = (p1 - 2 * pad1 >= 0) ? (p1 - 2 * pad1) : 0; + + m_panel2.Left = pad2; + m_panel2.Top = p1 + splitter_width + pad2; + m_panel2.Width = (this.Width - 2 * pad2 >= 0) ? (this.Width - 2 * pad2) : 0; + m_panel2.Height = (p2 - 2 * pad2 >= 0) ? (p2 - 2 * pad2) : 0; + + m_splitter_distance = p1; + m_panel2_distance = this.Height - m_splitter_distance; + m_distance_rate = m_splitter_distance / (double)(m_splitter_distance + m_panel2_distance); + if ( SplitterMoved != null ) { + SplitterMoved( this, new SplitterEventArgs( mouse.X, mouse.Y, 0, p1 ) ); + } + m_splitter_width = splitter_width; + m_panel1_min = panel1_min; + m_panel2_min = panel2_min; + + m_lbl_splitter.Left = 0; + m_lbl_splitter.Top = p1; + m_lbl_splitter.Width = this.Width; + m_lbl_splitter.Height = splitter_width; + } + return true; + } + } + + public int SplitterDistance { + get { + return m_splitter_distance; + } + set { + UpdateLayout( value, m_splitter_width, m_panel1_min, m_panel2_min, false ); + if ( m_orientation == Orientation.Horizontal ) { + m_panel2_distance = this.Width - m_splitter_distance; + } else { + m_panel2_distance = this.Height - m_splitter_distance; + } + } + } + + public Orientation Orientation { + get { + return m_orientation; + } + set { + if ( m_orientation != value ) { + m_orientation = value; + UpdateLayout( m_splitter_distance, m_splitter_width, m_panel1_min, m_panel2_min, false ); + if ( m_orientation == Orientation.Horizontal ) { + m_lbl_splitter.Cursor = Cursors.VSplit; + } else { + m_lbl_splitter.Cursor = Cursors.HSplit; + } + } + } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public BSplitterPanel Panel1 { + get { + return m_panel1; + } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + public BSplitterPanel Panel2 { + get { + return m_panel2; + } + } + + protected override void OnSizeChanged( EventArgs e ) { +#if DEBUG + Console.WriteLine( "BSplitContainer+OnSizeChanged" ); + //Console.WriteLine( " FixedPanel=" + FixedPanel ); + //Console.WriteLine( " m_splitter_distance=" + m_splitter_distance ); + Console.WriteLine( " Width=" + Width ); + Console.WriteLine( " Height=" + Height ); + //Console.WriteLine( " m_panel2_distance=" + m_panel2_distance ); +#endif + base.OnSizeChanged( e ); + if ( Width <= 0 || Height <= 0 ) { + return; + } + if ( m_fixed_panel == FixedPanel.Panel2 ) { + if ( m_orientation == Orientation.Horizontal ) { + m_splitter_distance = this.Width - m_panel2_distance; + } else { + m_splitter_distance = this.Height - m_panel2_distance; + } + } else if ( m_fixed_panel == FixedPanel.None ) { +#if DEBUG + //Console.WriteLine( " m_distance_rate=" + m_distance_rate ); +#endif + if ( m_orientation == Orientation.Horizontal ) { + m_splitter_distance = (int)(this.Width * m_distance_rate); + } else { + m_splitter_distance = (int)(this.Height * m_distance_rate); + } + } + UpdateLayout( m_splitter_distance, m_splitter_width, m_panel1_min, m_panel2_min, false ); + } + + private void m_lbl_splitter_MouseDown( object sender, MouseEventArgs e ) { + if ( !m_splitter_fixed ) { + m_splitter_moving = true; + m_splitter_distance_draft = m_splitter_distance; + this.Cursor = (m_orientation == Orientation.Horizontal) ? Cursors.VSplit : Cursors.HSplit; + m_lbl_splitter.BackColor = SystemColors.ControlDark; + m_lbl_splitter.BringToFront(); + } + } + + private void m_lbl_splitter_MouseUp( object sender, MouseEventArgs e ) { + if ( m_splitter_moving ) { + m_splitter_moving = false; + UpdateLayout( m_splitter_distance_draft, m_splitter_width, m_panel1_min, m_panel2_min, false ); + this.Cursor = Cursors.Default; + m_lbl_splitter.BackColor = SystemColors.Control; + } + } + + private void m_lbl_splitter_MouseMove( object sender, MouseEventArgs e ) { + base.OnMouseMove( e ); + if ( m_splitter_fixed ) { + return; + } + Point mouse_local = this.PointToClient( Control.MousePosition ); + if ( m_splitter_moving ) { + int new_distance = m_splitter_distance; + if ( m_orientation == Orientation.Horizontal ) { + new_distance = mouse_local.X; + } else { + new_distance = mouse_local.Y; + } + if ( UpdateLayout( new_distance, m_splitter_width, m_panel1_min, m_panel2_min, true ) ) { + m_splitter_distance_draft = new_distance; + if ( m_orientation == Orientation.Horizontal ) { + m_lbl_splitter.Left = m_splitter_distance_draft; + } else { + m_lbl_splitter.Top = m_splitter_distance_draft; + } + } + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BSplitterPanel.cs b/trunk/Boare.Lib.AppUtil/BSplitterPanel.cs new file mode 100644 index 0000000..e886e8d --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BSplitterPanel.cs @@ -0,0 +1,96 @@ +/* + * BSplitterPanel.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.ComponentModel; +using System.Windows.Forms; +using System.Drawing; + +namespace Boare.Lib.AppUtil { + + public class BSplitterPanel : Panel { + private BorderStyle m_border_style = BorderStyle.None; + private Color m_border_color = Color.Black; + + public event EventHandler BorderStyleChanged; + + public BSplitterPanel() + : base() { + base.AutoScroll = false; + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public Color BorderColor { + get { + return m_border_color; + } + set { + m_border_color = value; + } + } + + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] + public new BorderStyle BorderStyle { + get { + return m_border_style; + } + set { + BorderStyle old = m_border_style; + m_border_style = value; + if ( m_border_style == BorderStyle.Fixed3D ) { + base.BorderStyle = BorderStyle.Fixed3D; + } else if ( m_border_style == BorderStyle.FixedSingle ) { + base.BorderStyle = BorderStyle.None; + base.Padding = new Padding( 1 ); + } else { + base.Padding = new Padding( 0 ); + base.BorderStyle = BorderStyle.None; + } + if ( old != m_border_style && BorderStyleChanged != null ) { + BorderStyleChanged( this, new EventArgs() ); + } + } + } + + [Browsable(false)] + public new int Width { + get { + return base.Width; + } + internal set { + base.Width = value; + } + } + + [Browsable(false)] + public new int Height { + get { + return base.Height; + } + internal set { + base.Height = value; + } + } + + [Browsable(false)] + public new Rectangle Bounds { + get { + return base.Bounds; + } + internal set { + base.Bounds = value; + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BTrackBar.cs b/trunk/Boare.Lib.AppUtil/BTrackBar.cs new file mode 100644 index 0000000..afd4b16 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BTrackBar.cs @@ -0,0 +1,289 @@ +/* + * BTrackBar.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +//#define BENCH +using System; +using System.Windows.Forms; +using System.Reflection; + +namespace Boare.Lib.AppUtil { + + /// + /// Valueの型を変えられるTrackBar + /// + public class BTrackBar : UserControl where T : struct, IComparable { + const int _MAX = 10000; + private T m_value; + private T m_min; + private T m_max; + private T m_tick_frequency; + private MethodInfo m_parser = null; + private ValueType m_value_type = ValueType.int_; + private TrackBarEx m_track_bar; + private Type m_type = typeof( int ); + + private enum ValueType { + sbyte_, + byte_, + shoft_, + ushort_, + int_, + uint_, + long_, + ulong_, + } + + public event EventHandler ValueChanged; + + private static void test() { + System.Windows.Forms.TrackBar tb = new System.Windows.Forms.TrackBar(); + BTrackBar tb2 = new BTrackBar(); + } + + public BTrackBar() { + InitializeComponent(); + T value_type = new T(); + if ( value_type is byte ) { + m_value_type = BTrackBar.ValueType.byte_; + } else if ( value_type is sbyte ) { + m_value_type = BTrackBar.ValueType.sbyte_; + } else if ( value_type is short ) { + m_value_type = BTrackBar.ValueType.shoft_; + } else if ( value_type is ushort ) { + m_value_type = BTrackBar.ValueType.ushort_; + } else if ( value_type is int ) { + m_value_type = BTrackBar.ValueType.int_; + } else if ( value_type is uint ) { + m_value_type = BTrackBar.ValueType.uint_; + } else if ( value_type is long ) { + m_value_type = BTrackBar.ValueType.long_; + } else if ( value_type is ulong ) { + m_value_type = BTrackBar.ValueType.ulong_; + } else { + throw new NotSupportedException( "generic type T must be byte, sbyte, short, ushort, int, uint, long or ulong" ); + } + m_type = value_type.GetType(); + m_parser = typeof( T ).GetMethod( "Parse", new Type[] { typeof( string ) } ); + if ( m_parser == null ) { + throw new ApplicationException( "this error never occurs; m_type=" + m_value_type ); + } +#if BENCH + // Benchmark1: string parser + int _COUNT = 100000; + MethodInfo parser_double = typeof( double ).GetMethod( "Parse", new Type[] { typeof( string ) } ); + Console.WriteLine( "parsed \"123.456\" = " + ((double)parser_double.Invoke( typeof( double ), new object[] { "123.456" } )) ); + DateTime start = DateTime.Now; + for ( int i = 0; i < _COUNT; i++ ) { + double v = (double)parser_double.Invoke( typeof( double ), new object[] { "123.456" } ); + } + Console.WriteLine( "Benchmark1; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); + + // Benchmark2: BinaryFormatter + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); + System.IO.MemoryStream ms = new System.IO.MemoryStream( 64 ); + const double cdbbl = 123.456; + bf.Serialize( ms, cdbbl ); + _COUNT = 10000; + ms.Seek( 0, System.IO.SeekOrigin.Begin ); + Console.WriteLine( "deserilized = " + ((double)bf.Deserialize( ms )) ); + start = DateTime.Now; + for ( int i = 0; i < _COUNT; i++ ) { + ms.Seek( 0, System.IO.SeekOrigin.Begin ); + double v = (double)bf.Deserialize( ms ); + } + Console.WriteLine( "Benchmark2; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); + + // Benchmark3: Convert class + object obj = cdbbl; + Console.WriteLine( "Converted = " + Convert.ToDouble( obj ) ); + _COUNT = 100000; + start = DateTime.Now; + for ( int i = 0; i < _COUNT; i++ ) { + double v = Convert.ToDouble( obj ); + } + Console.WriteLine( "Benchmark3; " + DateTime.Now.Subtract( start ).TotalMilliseconds / (double)_COUNT + "ms" ); +#endif + } + + public T Maximum { + get { + return m_max; + } + set { + if ( value.CompareTo( m_min ) < 0 ) { + throw new ArgumentOutOfRangeException( "Maximum" ); + } + m_max = value; + if ( m_max.CompareTo( m_value ) < 0 ) { + Value = m_max; + } + } + } + + public T Minimum { + get { + return m_min; + } + set { + if ( value.CompareTo( m_max ) > 0 ) { + throw new ArgumentOutOfRangeException( "Minimum" ); + } + m_min = value; + if ( m_min.CompareTo( m_value ) > 0 ) { + Value = m_min; + } + } + } + + public TickStyle TickStyle { + get { + return m_track_bar.TickStyle; + } + set { + m_track_bar.TickStyle = value; + } + } + + public T TickFrequency { + get { + return m_tick_frequency; + } + set { + m_tick_frequency = value; + double max = asDouble( m_max ); + double min = asDouble( m_min ); + double stride = asDouble( m_tick_frequency ); + double rate = (max - min) / stride; + Console.WriteLine( "BTrackBar+set__TickFrequency" ); + Console.WriteLine( " rate=" + rate ); + int freq = (int)(_MAX / rate); + Console.WriteLine( " freq=" + freq ); + Console.WriteLine( " m_track_bar.Maximum=" + m_track_bar.Maximum ); + m_track_bar.TickFrequency = freq; + } + } + + public T Value { + get { + return m_value; + } + set { + if ( value.CompareTo( m_max ) > 0 ) { + throw new ArgumentOutOfRangeException( "Value" ); + } + if ( value.CompareTo( m_min ) < 0 ) { + throw new ArgumentOutOfRangeException( "Value" ); + } + T old = m_value; + m_value = value; + if ( old.CompareTo( m_value ) != 0 && ValueChanged != null ) { + ValueChanged( this, new EventArgs() ); + } + } + } + + private double asDouble( T value ) { + object o = value; + return Convert.ToDouble( o ); + } + + private T add( T value1, T value2 ) { + object o1 = value1; + object o2 = value2; + switch ( m_value_type ) { + case BTrackBar.ValueType.sbyte_: + sbyte sb1 = Convert.ToSByte( o1 ); + sbyte sb2 = Convert.ToSByte( o2 ); + object sb_r = (sb1 + sb2); + return (T)sb_r; + case BTrackBar.ValueType.byte_: + byte b1 = Convert.ToByte( o1 ); + byte b2 = Convert.ToByte( o2 ); + object b_r = (b1 + b2); + return (T)b_r; + case BTrackBar.ValueType.shoft_: + short s1 = Convert.ToInt16( o1 ); + short s2 = Convert.ToInt16( o2 ); + object s_r = (s1 + s2); + return (T)s_r; + case BTrackBar.ValueType.ushort_: + ushort us1 = Convert.ToUInt16( o1 ); + ushort us2 = Convert.ToUInt16( o2 ); + object us_r = (us1 + us2); + return (T)us_r; + case BTrackBar.ValueType.int_: + int i1 = Convert.ToInt32( o1 ); + int i2 = Convert.ToInt32( o2 ); + object i_r = (i1 + i2); + return (T)i_r; + case BTrackBar.ValueType.uint_: + uint ui1 = Convert.ToUInt32( o1 ); + uint ui2 = Convert.ToUInt32( o2 ); + object ui_r = ui1 + ui2; + return (T)ui_r; + case BTrackBar.ValueType.long_: + long l1 = Convert.ToInt64( o1 ); + long l2 = Convert.ToInt64( o2 ); + object l_r = l1 + l2; + return (T)l_r; + case BTrackBar.ValueType.ulong_: + ulong ul1 = Convert.ToUInt64( o1 ); + ulong ul2 = Convert.ToUInt64( o2 ); + object ul_r = ul1 + ul2; + return (T)ul_r; + } + return new T(); + } + + private void InitializeComponent() { + this.m_track_bar = new TrackBarEx(); + ((System.ComponentModel.ISupportInitialize)(this.m_track_bar)).BeginInit(); + this.SuspendLayout(); + // + // trackBar + // + this.m_track_bar.Dock = System.Windows.Forms.DockStyle.Fill; + this.m_track_bar.Location = new System.Drawing.Point( 0, 0 ); + this.m_track_bar.Name = "trackBar"; + this.m_track_bar.Size = new System.Drawing.Size( 286, 55 ); + this.m_track_bar.TabIndex = 0; + this.m_track_bar.Maximum = _MAX; + this.m_track_bar.Minimum = 0; + this.m_track_bar.TickFrequency = 1; + this.m_track_bar.SmallChange = 1; + this.m_track_bar.m_wheel_direction = false; + // + // BTrackBar + // + this.Controls.Add( this.m_track_bar ); + this.Name = "BTrackBar"; + this.Size = new System.Drawing.Size( 286, 55 ); + ((System.ComponentModel.ISupportInitialize)(this.m_track_bar)).EndInit(); + this.ResumeLayout( false ); + this.PerformLayout(); + } + } + + internal class TrackBarEx : TrackBar { + public bool m_wheel_direction = true; + + protected override void OnMouseWheel( MouseEventArgs e ) { + if ( m_wheel_direction ) { + base.OnMouseWheel( new MouseEventArgs( e.Button, e.Clicks, e.X, e.Y, e.Delta ) ); + } else { + base.OnMouseWheel( new MouseEventArgs( e.Button, e.Clicks, e.X, e.Y, -e.Delta ) ); + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BVScrollBar.Designer.cs b/trunk/Boare.Lib.AppUtil/BVScrollBar.Designer.cs new file mode 100644 index 0000000..83939a7 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BVScrollBar.Designer.cs @@ -0,0 +1,67 @@ +/* + * BHScrollBar.Designer.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.AppUtil { + partial class BVScrollBar { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.vScroll = new System.Windows.Forms.VScrollBar(); + this.SuspendLayout(); + // + // hScroll + // + this.vScroll.Dock = System.Windows.Forms.DockStyle.Fill; + this.vScroll.Location = new System.Drawing.Point( 0, 0 ); + this.vScroll.Name = "hScroll"; + this.vScroll.Size = new System.Drawing.Size( 16, 205 ); + this.vScroll.TabIndex = 0; + this.vScroll.ValueChanged += new System.EventHandler( this.vScroll_ValueChanged ); + // + // BHScrollBar + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add( this.vScroll ); + this.Name = "BHScrollBar"; + this.Size = new System.Drawing.Size( 16, 205 ); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.VScrollBar vScroll; + + } +} diff --git a/trunk/Boare.Lib.AppUtil/BVScrollBar.cs b/trunk/Boare.Lib.AppUtil/BVScrollBar.cs new file mode 100644 index 0000000..1a43c4d --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BVScrollBar.cs @@ -0,0 +1,86 @@ +/* + * BVScrollBar.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + + /// + /// Valueの値が正しくMinimumからMaximumの間を動くスクロールバー + /// + public partial class BVScrollBar : UserControl { + int m_max = 100; + int m_min = 0; + + public event EventHandler ValueChanged; + + public BVScrollBar() { + InitializeComponent(); + } + + public int Value { + get { + return vScroll.Value; + } + set { + vScroll.Value = value; + } + } + + public int LargeChange { + get { + return vScroll.LargeChange; + } + set { + vScroll.LargeChange = value; + vScroll.Maximum = m_max + value; + } + } + + public int SmallChange { + get { + return vScroll.SmallChange; + } + set { + vScroll.SmallChange = value; + } + } + + public int Maximum { + get { + return m_max; + } + set { + m_max = value; + vScroll.Maximum = m_max + vScroll.LargeChange; + } + } + + public int Minimum { + get { + return m_min; + } + set { + m_min = value; + } + } + + private void vScroll_ValueChanged( object sender, EventArgs e ) { + if ( ValueChanged != null ) { + ValueChanged( this, e ); + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/BitmapEx.cs b/trunk/Boare.Lib.AppUtil/BitmapEx.cs new file mode 100644 index 0000000..4a22791 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/BitmapEx.cs @@ -0,0 +1,159 @@ +/* + * BitmapEx.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; + +namespace Boare.Lib.AppUtil { + + public unsafe class BitmapEx : IDisposable { + private Bitmap m_base; + private bool m_locked = false; + private BitmapData m_bd; + private int m_stride; + private int m_byte_per_pixel; + + public int Width { + get { + return m_base.Width; + } + } + + public int Height { + get { + return m_base.Height; + } + } + + public void Dispose() { + EndLock(); + m_base.Dispose(); + } + + public void EndLock() { + if ( m_locked ) { + m_base.UnlockBits( m_bd ); + m_locked = false; + } + } + + public Bitmap GetBitmap() { + return (Bitmap)m_base.Clone(); + } + + public Color GetPixel( int x, int y ) { + if ( !m_locked ) { + BeginLock(); + } + int location = y * m_stride + m_byte_per_pixel * x; + byte* dat = (byte*)m_bd.Scan0; + byte b = dat[location]; + byte g = dat[location + 1]; + byte r = dat[location + 2]; + byte a = 255; + if ( m_base.PixelFormat == PixelFormat.Format32bppArgb ) { + a = dat[location + 3]; + } + return Color.FromArgb( a, r, g, b ); + } + + public void SetPixel( int x, int y, Color color ) { + if ( !m_locked ) { + BeginLock(); + } + int location = y * m_stride + m_byte_per_pixel * x; + byte* dat = (byte*)m_bd.Scan0; + dat[location] = (byte)color.B; + dat[location + 1] = (byte)color.G; + dat[location + 2] = (byte)color.R; + if ( m_base.PixelFormat == PixelFormat.Format32bppArgb ) { + dat[location + 3] = (byte)color.A; + } + } + + public void BeginLock(){ + if ( !m_locked ) { + m_bd = m_base.LockBits( new Rectangle( 0, 0, m_base.Width, m_base.Height ), + ImageLockMode.ReadWrite, + m_base.PixelFormat ); + m_stride = m_bd.Stride; + switch ( m_base.PixelFormat ) { + case PixelFormat.Format24bppRgb: + m_byte_per_pixel = 3; + break; + case PixelFormat.Format32bppArgb: + m_byte_per_pixel = 4; + break; + default: + throw new Exception( "unsuported pixel format" ); + } + m_locked = true; + } + } + + ~BitmapEx() { + m_base.Dispose(); + } + + public BitmapEx( Image original ) { + m_base = new Bitmap( original ); + } + + public BitmapEx( string filename ) { + m_base = new Bitmap( filename ); + } + + public BitmapEx( Stream stream ) { + m_base = new Bitmap( stream ); + } + + public BitmapEx( Image original, Size newSize ) { + m_base = new Bitmap( original, newSize ); + } + + public BitmapEx( int width, int height ) { + m_base = new Bitmap( width, height ); + } + + public BitmapEx( Stream stream, bool useIcm ) { + m_base = new Bitmap( stream, useIcm ); + } + + public BitmapEx( string filename, bool useIcm ) { + m_base = new Bitmap( filename, useIcm ); + } + + public BitmapEx( Type type, string resource ) { + m_base = new Bitmap( type, resource ); + } + + public BitmapEx( Image original, int width, int height ) { + m_base = new Bitmap( original, width, height ); + } + + public BitmapEx( int width, int height, Graphics g ) { + m_base = new Bitmap( width, height, g ); + } + + public BitmapEx( int width, int height, PixelFormat format ) { + m_base = new Bitmap( width, height, format ); + } + + public BitmapEx( int width, int height, int stride, PixelFormat format, IntPtr scan0 ) { + m_base = new Bitmap( width, height, stride, format, scan0 ); + } + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.AppUtil/Boare.Lib.AppUtil.csproj b/trunk/Boare.Lib.AppUtil/Boare.Lib.AppUtil.csproj new file mode 100644 index 0000000..ee00d4c --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/Boare.Lib.AppUtil.csproj @@ -0,0 +1,126 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {0C58B068-272F-4390-A14F-3D72AFCF3DFB} + Library + Properties + Boare.Lib.AppUtil + Boare.Lib.AppUtil + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + Boare.Lib.AppUtil.xml + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + Boare.Lib.AppUtil.xml + true + + + x86 + bin\x86\Debug\ + true + DEBUG + bin\x86\Debug\Boare.Lib.AppUtil.XML + + + x86 + bin\x86\Release\ + true + bin\x86\Release\Boare.Lib.AppUtil.XML + + + + + 3.5 + + + + + 3.5 + + + 3.5 + + + + + + + + UserControl + + + BHScrollBar.cs + + + + + + Form + + + InputBox.cs + + + + + + + + Component + + + Component + + + UserControl + + + Form + + + VersionInfo.cs + + + UserControl + + + BVScrollBar.cs + + + + + + + {C8AAE632-9C6C-4372-8175-811528A66742} + bocoree + + + + + \ No newline at end of file diff --git a/trunk/Boare.Lib.AppUtil/ColorBar.cs b/trunk/Boare.Lib.AppUtil/ColorBar.cs new file mode 100644 index 0000000..d0464f2 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/ColorBar.cs @@ -0,0 +1,1118 @@ +/* + * ColorBar.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace Boare.Lib.AppUtil { + + public enum ColorBarType { + apricot = 1, + carnation = 2, + ether = 3, + grayscale_banded = 4, + hot_metal = 5, + hotmetal = 5, + lava_waves = 6, + lavawaves = 6, + malachite = 7, + morning_glory = 8, + peanut_butter_and_jerry = 9, + purple_haze = 10, + rainbow = 11, + rainbow_banded = 12, + rainbow_striped = 13, + rose = 14, + saturn = 15, + seismic = 16, + space = 17, + supernova = 18, + cyclic = 19, + rflow_rainbow = 20, + } + + public static partial class Misc { + const double OPORT_OP_PI = 3.141592653589793238462643383279502884197169399; + const double OPORT_OP_PI2 = 3.141592653589793238462643383279502884197169399 * 2.0; + const double OPORT_OP_1P9 = 1.0 / 9.0; + const double OPORT_OP_3P9 = 3.0 / 9.0; + const double OPORT_OP_5P9 = 5.0 / 9.0; + const double OPORT_OP_7P9 = 7.0 / 9.0; + + public static Color ColorBar( double x, double xmax, double xmin, ColorBarType bartype ) { + int red = 0; + int green = 0; + int blue = 0; + double y, h, s, v, r, g, b; + y = (x - xmin) / (xmax - xmin); + switch ( bartype ) { + case ColorBarType.apricot: + red = oport_colorbar_apricot_red( y ); + green = oport_colorbar_apricot_green( y ); + blue = oport_colorbar_apricot_blue( y ); + break; + case ColorBarType.carnation: + red = oport_colorbar_carnation_red( y ); + green = oport_colorbar_carnation_green( y ); + blue = oport_colorbar_carnation_blue( y ); + break; + case ColorBarType.ether: + red = oport_colorbar_ether_red( y ); + green = oport_colorbar_ether_green( y ); + blue = oport_colorbar_ether_blue( y ); + break; + case ColorBarType.grayscale_banded: + red = oport_colorbar_grayscale_banded_rgb( y ); + green = red; + blue = red; + break; + case ColorBarType.hot_metal: + red = (int)oport_colorbar_hotmetal_red( y ); + green = (int)oport_colorbar_hotmetal_green( y ); + blue = (int)oport_colorbar_hotmetal_blue( y ); + break; + case ColorBarType.lava_waves: + red = oport_colorbar_lava_waves_red( y ); + green = oport_colorbar_lava_waves_green( y ); + blue = oport_colorbar_lava_waves_blue( y ); + break; + case ColorBarType.malachite: + red = oport_colorbar_malachite_red( y ); + green = oport_colorbar_malachite_green( y ); + blue = oport_colorbar_malachite_blue( y ); + break; + case ColorBarType.morning_glory: + red = oport_colorbar_morning_glory_red( y ); + green = oport_colorbar_morning_glory_green( y ); + blue = oport_colorbar_morning_glory_blue( y ); + break; + case ColorBarType.peanut_butter_and_jerry: + red = oport_colorbar_peanut_butter_and_jerry_red( y ); + green = oport_colorbar_peanut_butter_and_jerry_green( y ); + blue = oport_colorbar_peanut_butter_and_jerry_blue( y ); + break; + case ColorBarType.purple_haze: + red = oport_colorbar_purple_haze_red( y ); + green = oport_colorbar_purple_haze_green( y ); + blue = oport_colorbar_purple_haze_blue( y ); + break; + case ColorBarType.rainbow: + red = (int)oport_colorbar_rainbow_red( y ); + green = (int)oport_colorbar_rainbow_green( y ); + blue = (int)oport_colorbar_rainbow_blue( y ); + break; + case ColorBarType.rainbow_banded: + if ( y < 0.0 ) { + red = 44; + green = 6; + blue = 65; + } else if ( y <= 1.0 ) { + h = oport_colorbar_rainbow_banded_h( y ); + s = oport_colorbar_rainbow_banded_s( y ); + v = oport_colorbar_rainbow_banded_v( y ); + HsvToRgb( h, s, v, out r, out g, out b ); + red = (int)(r * 255.0); + green = (int)(g * 255.0); + blue = (int)(b * 255.0); + } else { + red = 167; + green = 18; + blue = 15; + } + break; + case ColorBarType.rainbow_striped: + if ( y < 0.0 ) { + red = 150; + green = 0; + blue = 144; + } else if ( y <= 1.0 ) { + h = oport_colorbar_rainbow_striped_h( y ); + s = oport_colorbar_rainbow_striped_s( y ); + v = oport_colorbar_rainbow_striped_v( y ); + HsvToRgb( h, s, v, out r, out g, out b ); + red = (int)(r * 255.0); + green = (int)(g * 255.0); + blue = (int)(b * 255.0); + } else { + red = 255; + green = 0; + blue = 0; + } + break; + case ColorBarType.rose: + red = oport_colorbar_rose_red( y ); + green = oport_colorbar_rose_green( y ); + blue = oport_colorbar_rose_blue( y ); + break; + case ColorBarType.saturn: + red = oport_colorbar_saturn_red( y ); + green = oport_colorbar_saturn_green( y ); + blue = oport_colorbar_saturn_blue( y ); + break; + case ColorBarType.seismic: + red = oport_colorbar_seismic_red( y ); + green = oport_colorbar_seismic_green( y ); + blue = oport_colorbar_seismic_blue( y ); + break; + case ColorBarType.space: + red = oport_colorbar_space_red( y ); + green = oport_colorbar_space_green( y ); + blue = oport_colorbar_space_blue( y ); + break; + case ColorBarType.supernova: + red = oport_colorbar_supernova_red( y ); + green = oport_colorbar_supernova_green( y ); + blue = oport_colorbar_supernova_blue( y ); + break; + case ColorBarType.cyclic: + blue = (int)(100.0 * Math.Cos( OPORT_OP_PI2 * (y + 2.0 / 3.0) )) + 100; + green = (int)(100.0 * Math.Cos( OPORT_OP_PI2 * (y + 1.0 / 3.0) )) + 100; + red = (int)(100.0 * Math.Cos( OPORT_OP_PI2 * y )) + 100; + break; + case ColorBarType.rflow_rainbow: + red = oport_colorbar_rflow_rainbow_red( y ); + green = oport_colorbar_rflow_rainbow_green( y ); + blue = oport_colorbar_rflow_rainbow_blue( y ); + break; + } + return Color.FromArgb( red, green, blue ); + } + + static int oport_colorbar_rgb2col( int red, int green, int blue ) { + int res = (blue * 256 + green) * 256 + red; + return res; + } + + /// APRICOT [No.1]; + private static int oport_colorbar_apricot_blue( double x ) { + double x255; + int res; + x255 = x * 256.0; + if ( x255 < 0.0 ) { + res = 241; + } else if ( x255 < 66.82 ) { + res = (int)(oport_colorbar_apricot_f( x255 - 32.0, -27.0 )); + if ( x255 > 32.0 && res > 225 ) { + res = res - 10; + } + } else if ( x255 < 126.67 ) { + res = (int)(oport_colorbar_apricot_f( x255 - 97.0, 30.0 )); + } else if ( x255 < 195.83 ) { + res = (int)(oport_colorbar_apricot_f( x255 - 161.0, -27.0 )); + if ( x255 > 161.0 && res > 225 ) { + res = res - 10; + } + } else if ( x255 < 256.0 ) { + res = (int)(oport_colorbar_apricot_f( x255 - 226.0, 30.0 )); + } else { + res = 251; + } + if ( res > 255 ) { + res = 255; + } + return res; + } + private static int oport_colorbar_apricot_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 1.0 ) { + res = (int)(109.0 * x + 25.0 * Math.Sin( 9.92 * OPORT_OP_PI * x ) * x); + } else { + res = 102; + } + return res; + } + private static int oport_colorbar_apricot_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 1.0 ) { + res = oport_colorbar_apricot_f2( x ); + if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 255; + } + return res; + } + private static double oport_colorbar_apricot_f( double x, double c ) { + double res; + res = Math.Abs( -5.563d - 5 * (x * x * x * x) + 3.331d - 16 * (x * x * x) + 3.045d - 1 * (x * x) + 4.396d - 12 * x + c ); + return res; + } + private static int oport_colorbar_apricot_f2( double x ) { + int res; + // oport_colorbar_apricot_f2 = (int)(262.0 * x + 12.0 * x * Math.Sin(66.0 * OPORT_OP_PI * x - 8.0 * x**2 + x**3)); + res = (int)(262.0 * x + 12.0 * x * Math.Sin( ((x - 8.0) * x + 66.0 * OPORT_OP_PI) * x )); + return res; + } + /// CARNATION [No.2]; + private static int oport_colorbar_carnation_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 11; + } else if ( x < 0.16531216481302 ) { + res = (int)(-1635.0 * (x * x) + 1789.0 * x + 3.938); + } else if ( x < 0.50663669203696 ) { + res = 255; + } else if ( x < 0.67502056695956 ) { + res = (int)(1.28932e3 * (x * x * x) - 7.74147e2 * (x * x) - 9.47634e2 * x + 7.65071e2); + } else if ( x < 1.0 ) { + res = oport_colorbar_carnation_f( x ); + } else { + res = 251; + } + return res; + } + private static int oport_colorbar_carnation_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 0.33807590140751 ) { + res = oport_colorbar_carnation_f( x ); + } else if ( x < 0.50663669203696 ) { + res = (int)(-5.83014e2 * (x * x * x) - 8.38523e2 * (x * x) + 2.03823e3 * x - 4.86592e2); + } else if ( x < 0.84702285244773 ) { + res = 255; + } else if ( x < 1.0 ) { + res = (int)(-5.03306e2 * (x * x * x) + 2.95545e3 * (x * x) - 4.19210e3 * x + 1.99128e3); + } else { + res = 251; + } + return res; + } + private static int oport_colorbar_carnation_red( double x ) { + int res; + if ( x < 0.16531216481302 ) { + res = 255; + } else if ( x < 0.33807590140751 ) { + res = (int)(-5.15164e3 * (x * x * x) + 5.30564e3 * (x * x) - 2.65098e3 * x + 5.70771e2); + } else if ( x < 0.67502056695956 ) { + res = oport_colorbar_carnation_f( x ); + } else if ( x < 0.84702285244773 ) { + res = (int)(3.34136e3 * (x * x * x) - 9.01976e3 * (x * x) + 8.39740e3 * x - 2.41682e3); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_carnation_f( double x ) { + int res = (int)(-9.93427 * (x * x * x) + 1.56301e1 * (x * x) + 2.44663e2 * x); + return res; + } + + /// ETHER [No.3]; + private static int oport_colorbar_ether_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 246; + } else if ( x < 0.25 ) { + res = oport_colorbar_ether_f( x - 32.0 / 256.0, 65.0 ); + } else if ( x < 130.0 / 256.0 ) { + res = oport_colorbar_ether_f2( x - 97.0 / 256.0, 190.0 ); + } else if ( x < 193.0 / 256.0 ) { + res = oport_colorbar_ether_f( x - 161.0 / 256.0, 65.0 ); + } else if ( x < 1.0 ) { + res = oport_colorbar_ether_f2( x - 226.0 / 256.0, 190.0 ); + } else { + res = 18; + } + return res; + } + private static int oport_colorbar_ether_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 0.20615790927912 ) { + res = (int)((((-3.81619e4 * x - 2.94574e3) * x + 2.61347e3) * x - 7.92183e1) * x); + } else if ( x < 0.54757171958025 ) { + res = (int)(((((2.65271e5 * x - 4.14808e5) * x + 2.26118e5) * x - 5.16491e4) * x + 5.06893e3) * x - 1.80630e2); + } else if ( x < 0.71235558668792 ) { + res = (int)((((1.77058e5 * x - 4.62571e5) * x + 4.39628e5) * x - 1.80143e5) * x + 2.68555e4); + } else if ( x < 1.0 ) { + res = (int)((((1.70556e5 * x - 6.20429e5) * x + 8.28331e5) * x - 4.80913e5) * x + 1.02608e5); + if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 154; + } + return res; + } + private static int oport_colorbar_ether_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 2; + } else if ( x < 1.0 ) { + res = (int)(2.83088e2 * x + 8.17847d - 1); + if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 226; + } + return res; + } + private static int oport_colorbar_ether_f( double x, double b ) { + int res = (int)(-1.89814e5 * (x * x * x * x) + 1.50967e4 * (x * x) + b); + return res; + } + private static int oport_colorbar_ether_f2( double x, double b ) { + int res = (int)(1.88330e5 * (x * x * x * x) - 1.50839e4 * (x * x) + b); + return res; + } + + /// GRAYSCALE_BANDED [No.4]; + private static int oport_colorbar_grayscale_banded_rgb( double x ) { + int res; + res = (int)(Math.Cos( 133.0 * x ) * 28.0 + 230.0 * x + 27.0); + if ( res > 255 ) { + res = 255 - res; + } + return res; + } + + /// HOT_METAL [No.5]; + private static double oport_colorbar_hotmetal_blue( double x ) { + int res; + res = 0; + return res; + } + private static double oport_colorbar_hotmetal_green( double x ) { + int res; + if ( x < 0.6 ) { + res = 0; + } else if ( x <= 0.95 ) { + res = (int)((x - 0.6) * 728.57); + } else { + res = 255; + } + return res; + } + private static double oport_colorbar_hotmetal_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x <= 0.57147 ) { + res = (int)(446.22 * x); + } else { + res = 255; + } + return res; + } + + /// LAVA_WAVES [No.6]; + private static int oport_colorbar_lava_waves_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 124; + } else if ( x <= 1.0 ) { + res = (int)(128.0 * Math.Sin( 6.25 * (x + 0.5) ) + 128.0); + } else { + res = 134; + } + return res; + } + private static int oport_colorbar_lava_waves_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 121; + } else if ( x <= 1.0 ) { + res = (int)(63.0 * Math.Sin( x * 99.72 ) + 97.0); + } else { + res = 52; + } + return res; + } + private static int oport_colorbar_lava_waves_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 131; + } else if ( x <= 1.0 ) { + res = (int)(128.0 * Math.Sin( 6.23 * x ) + 128.0); + } else { + res = 121; + } + return res; + } + + /// MALACHITE [No.7]; + private static int oport_colorbar_malachite_blue( double x ) { + int res; + if ( x < 248.25 / 1066.8 ) { + res = 0; + } else if ( x < 384.25 / 1066.8 ) { + res = (int)(1066.8 * x - 248.25); + } else if ( x < 0.5 ) { + res = 136; + } else if ( x < 595.14 / 1037.9 ) { + res = (int)(-1037.9 * x + 595.14); + } else if ( x < 666.68 / 913.22 ) { + res = 0; + } else if ( x <= 1.0 ) { + res = (int)(913.22 * x - 666.68); + } else { + res = 246; + } + return res; + } + private static int oport_colorbar_malachite_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 253; + } else if ( x < 248.25 / 1066.8 ) { + res = (int)(-545.75 * x + 253.36); + } else if ( x < 384.25 / 1066.8 ) { + res = (int)(426.18 * x + 19335217.0 / 711200.0); + } else if ( x < 0.5 ) { + res = (int)(-385524981.0 / 298300.0 * x + 385524981.0 / 596600.0); + } else if ( x < 666.68 / 913.22 ) { + res = (int)(3065810.0 / 3001.0 * x - 1532906.0 / 3001.0); + } else { + res = 0; + } + return res; + } + private static int oport_colorbar_malachite_red( double x ) { + int res; + if ( x < 384.25 / 1066.8 ) { + res = 0; + } else if ( x < 0.5 ) { + res = (int)(1092.0 * x - 99905.0 / 254.0); + } else if ( x < 259.3 / 454.5 ) { + res = (int)(1091.9 * x - 478.18); + } else if ( x < 34188.3 / 51989.0 ) { + res = (int)(819.2 * x - 322.6); + } else if ( x < 666.68 / 913.22 ) { + res = (int)(299.31 * x + 19.283); + } else { + res = 0; + } + return res; + } + + /// MORNING_GLORY [No.8]; + private static int oport_colorbar_morning_glory_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x <= 1.0 ) { + res = (int)(270.9 * x + 0.7703); + if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 239; + } + return res; + } + private static int oport_colorbar_morning_glory_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 124; + } else if ( x <= 1.0 ) { + res = (int)(180.0 * Math.Sin( x * 3.97 + 9.46 ) + 131.0); + if ( res < 0 ) { + res = Math.Abs( res ); + } else if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 242; + } + return res; + } + private static int oport_colorbar_morning_glory_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 78; + } else if ( x <= 1.0 ) { + res = (int)(95.0 * Math.Sin( (x - 0.041) * 7.46 ) + 106.9); + } else { + res = 179; + } + return res; + } + + /// PEANUT_BUTTER_AND_JERRY [No.9]; + private static int oport_colorbar_peanut_butter_and_jerry_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 1; + } else if ( x <= 1.0 ) { + res = (int)(407.92 * x + 1.3181); + if ( res > 255 ) { + res = 510 - res; + } + } else { + res = 100; + } + return res; + } + private static int oport_colorbar_peanut_butter_and_jerry_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x <= 1.0 ) { + res = (int)(128.7 * x + 0.2089); + } else { + res = 128; + } + return res; + } + private static int oport_colorbar_peanut_butter_and_jerry_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 73; + } else if ( x <= 1.0 ) { + res = (int)(63.0 * Math.Sin( x * 6.21 - 0.3 ) + 92.0); + } else { + res = 69; + } + return res; + } + + /// PURPLE_HAZE [No.10]; + private static int oport_colorbar_purple_haze_red( double x ) { + int res; + double e; + e = Math.Exp( 1.0 ); + if ( x < 0.0 ) { + res = 13; + } else if ( x < e * 0.1 ) { + res = (int)(706.48 * x + 13.06); + } else if ( x < e * 0.1 + 149.0 / 510.0 ) { + res = (int)(166.35 * x + 28.3); + } else if ( x < e * 0.1 + 298.0 / 510.0 ) { + res = (int)(313.65 * x - 47.179); + } else if ( x < e * 0.05 + 202.0 / 255.0 ) { + res = (int)(557.93 * x - 310.05); + } else if ( x <= 1.0 ) { + res = (int)(319.64 * x + 439093 / 34000 * e - 1030939 / 8500); + } else { + res = 249; + } + return res; + } + private static int oport_colorbar_purple_haze_green( double x ) { + int res; + double e; + e = Math.Exp( 1.0 ); + if ( x < e * 0.1 ) { + res = 0; + } else if ( x < e * 0.1 + 149.0 / 510.0 ) { + res = (int)((3166.59 / 14.9 * e + 2098.7 / 74.5) * x - (316.659 / 14.9 * e + 209.87 / 74.5) * e); + } else if ( x < e * 0.1 + 298.0 / 510.0 ) { + res = (int)(725.0 * x - 394.35); + } else if ( x <= 1.0 ) { + res = (int)(-716.23 * x + 721.38); + } else { + res = 5; + } + return res; + } + private static int oport_colorbar_purple_haze_blue( double x ) { + int res; + double e; + e = Math.Exp( 1.0 ); + if ( x < 0.0 ) { + res = 16; + } else if ( x < e * 0.1 ) { + res = (int)(878.72 * x + 16.389); + } else if ( x < e * 0.1 + 149.0 / 510.0 ) { + res = (int)(-166.35 * x + 227.7); + } else if ( x < e * 0.1 + 298.0 / 510.0 ) { + res = (int)(-317.2 * x + 305.21); + } else if ( x < 1.0 ) { + res = (int)((1530.0 / (212.0 - 51.0 * e)) * x + (153.0 * e + 894.0) / (51.0 * e - 212.0)); + } else { + res = 2; + } + return res; + } + + /// RAINBOW [No.11]; + private static double oport_colorbar_rainbow_red( double x ) { + int res; + if ( x < 0 ) { + res = 127; + } else if ( x <= OPORT_OP_1P9 ) { + res = (int)(1147.5 * (OPORT_OP_1P9 - x)); + } else if ( x <= OPORT_OP_5P9 ) { + res = 0; + } else if ( x <= OPORT_OP_7P9 ) { + res = (int)(1147.5 * (x - OPORT_OP_5P9)); + } else { + res = 255; + } + return res; + } + private static double oport_colorbar_rainbow_green( double x ) { + int res; + if ( x <= OPORT_OP_1P9 ) { + res = 0; + } else if ( x <= OPORT_OP_3P9 ) { + res = (int)(1147.5 * (x - OPORT_OP_1P9)); + } else if ( x <= OPORT_OP_7P9 ) { + res = 255; + } else if ( x <= 1.0 ) { + res = 255 - (int)(1147.5 * (x - OPORT_OP_7P9)); + } else { + res = 0; + } + return res; + } + private static double oport_colorbar_rainbow_blue( double x ) { + int res; + if ( x <= OPORT_OP_3P9 ) { + res = 255; + } else if ( x <= OPORT_OP_5P9 ) { + res = 255 - (int)(1147.5 * (x - OPORT_OP_3P9)); + } else { + res = 0; + } + return res; + } + + /// RAINBOW_BANDED [No.12]; + private static double oport_colorbar_rainbow_banded_h( double x ) { + int res; + res = (int)(-277.34 * x + 278.69); + res = (int)(res / 360.0); + return res; + } + private static double oport_colorbar_rainbow_banded_s( double x ) { + int res; + res = (int)(0.908306127594742); + return res; + } + private static double oport_colorbar_rainbow_banded_v( double x ) { + int res; + res = (int)(0.293 * Math.Sin( x * 79.7 - 1.53 ) + 0.55); + return res; + } + + /// RAINBOW_STRIPED [No.13]; + private static double oport_colorbar_rainbow_striped_h( double x ) { + int res; + if ( x < 1303 / 3817 ) { + res = (int)((171.99 * x - 241.35) * x + 302.44); + } else if ( x < 21321 / 25489 ) { + res = (int)(-364.593271477158 * x + 364.553562528411); + } else if ( x < 44617 / 48806 ) { + res = (int)((-1385.4 * x + 1948.5) * x - 600.94); + } else { + res = (int)(-262.518169057616 * x + 262.518169057616); + } + res = (int)(res / 360.0); + return res; + } + private static double oport_colorbar_rainbow_striped_s( double x ) { + int res; + if ( x < 21321 / 25489 ) { + res = (int)(1.0); + } else if ( x < 44617 / 48806 ) { + res = (int)(-2.5489 * x + 3.1321); + } else { + res = (int)(2.3317 * x - 1.3296); + } + return res; + } + private static double oport_colorbar_rainbow_striped_v( double x ) { + int res; + double xx; + xx = x % 10.0 / 255.0; + if ( xx < 2 / 256 ) { + if ( x < 1303 / 3817 ) { + res = (int)(0.6067 * x + 0.5921); + } else { + res = (int)(0.8); + } + } else { + if ( x < 1303 / 3817 ) { + res = (int)(0.7634 * x + 0.7394); + } else { + res = (int)(1.0); + } + } + return res; + } + + /// ROSE [No.14]; + private static int oport_colorbar_rose_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 54; + } else if ( x < 20049 / 82979 ) { + res = (int)(829.79 * x + 54.51); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_rose_green( double x ) { + int res; + if ( x < 20049 / 82979 ) { + res = 0; + } else if ( x < 327013 / 810990 ) { + res = (int)(8546482679670 / 10875673217 * x - 2064961390770 / 10875673217); + } else if ( x <= 1.0 ) { + res = (int)(103806720 / 483977 * x + 19607415 / 483977); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_rose_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 54; + } else if ( x < 7249 / 82979 ) { + res = (int)(829.79 * x + 54.51); + } else if ( x < 20049 / 82979 ) { + res = 127; + } else if ( x < 327013 / 810990 ) { + res = (int)(792.02249341361393720147485376583 * x - 64.364790735602331034989206222672); + } else { + res = 255; + } + return res; + } + + /// SATURN [No.15]; + private static int oport_colorbar_saturn_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 255; + } else if ( x < 10873 / 94585 ) { + res = (int)(oport_colorbar_saturn_II( x )); + if ( res > 255 ) { + res = 510 - res; + } + } else if ( x < 0.5 ) { + res = 255; + } else if ( x < 146169 / 251000 ) { + res = (int)(oport_colorbar_saturn_IV( x )); + } else if ( x < 197169 / 251000 ) { + res = (int)(oport_colorbar_saturn_V( x )); + } else { + res = 0; + } + return res; + } + private static int oport_colorbar_saturn_green( double x ) { + int res; + if ( x < 10873 / 94585 ) { + res = 255; + } else if ( x < 36373 / 94585 ) { + res = (int)(oport_colorbar_saturn_II( x )); + } else if ( x < 0.5 ) { + res = (int)(oport_colorbar_saturn_I( x )); + } else if ( x < 197169 / 251000 ) { + res = 0; + } else if ( x <= 1.0 ) { + res = (int)(Math.Abs( oport_colorbar_saturn_V( x ) )); + } else { + res = 0; + } + return res; + } + private static int oport_colorbar_saturn_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 36373 / 94585 ) { + res = (int)(oport_colorbar_saturn_I( x )); + } else if ( x < 146169 / 251000 ) { + res = (int)(oport_colorbar_saturn_III( x )); + } else if ( x <= 1.0 ) { + res = (int)(oport_colorbar_saturn_IV( x )); + } else { + res = 0; + } + return res; + } + private static double oport_colorbar_saturn_I( double x ) { + int res; + res = (int)(-510.0 * x + 255.0); + return res; + } + private static double oport_colorbar_saturn_II( double x ) { + int res; + res = (int)((-1891.7 * x + 217.46) * x + 255.0); + return res; + } + private static double oport_colorbar_saturn_III( double x ) { + int res; + res = (int)(9.26643676359015e1 * Math.Sin( (x - 4.83450094847127d - 1) * 9.93 ) + 1.35940451627965e2); + return res; + } + private static double oport_colorbar_saturn_IV( double x ) { + int res; + res = (int)(-510.0 * x + 510.0); + return res; + } + private static double oport_colorbar_saturn_V( double x ) { + int res; + double xx; + xx = x - 197169 / 251000; + res = (int)((2510.0 * xx - 538.31) * xx); + return res; + } + + /// SEISMIC [No.16]; + private static int oport_colorbar_seismic_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 3; + } else if ( x < 0.238 ) { + res = (int)((-1810 * x + 414.49) * x + 3.87702); + } else if ( x < 51611 / 108060 ) { + res = (int)(344441250 / 323659 * x - 23422005 / 92474); + } else if ( x < 25851 / 34402 ) { + res = 255; + } else if ( x <= 1.0 ) { + res = (int)(-688.04 * x + 772.02); + } else { + res = 83; + } + return res; + } + private static int oport_colorbar_seismic_green( double x ) { + int res; + double xx; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 0.238 ) { + res = 0; + } else if ( x < 51611 / 108060 ) { + res = (int)(oport_colorbar_seismic_I( x )); + } else if ( x < 0.739376978894039 ) { + xx = x - 51611 / 108060; + res = (int)((-914.74 * xx - 734.72) * xx + 255); + } else { + res = 0; + } + return res; + } + private static int oport_colorbar_seismic_blue( double x ) { + int res; + double xx; + if ( x < 0.0 ) { + res = 19; + } else if ( x < 0.238 ) { + xx = x - 0.238; + res = (int)(((1624.6 * xx + 1191.4) * xx + 1180.2) * xx + 255); + } else if ( x < 51611 / 108060 ) { + res = 255; + } else if ( x < 174.5 / 256 ) { + res = (int)(-951.67322673866 * x + 709.532730938451); + } else if ( x < 0.745745353439206 ) { + res = (int)(-705.250074130877 * x + 559.620050530617); + } else if ( x <= 1.0 ) { + res = (int)((-399.29 * x + 655.71) * x - 233.25); + } else { + res = 23; + } + return res; + } + private static double oport_colorbar_seismic_I( double x ) { + int res; + res = (int)((-2010 * x + 36469683133498 / 14572746475) * x - 40117786837711 / 83272837000); + return res; + } + + /// SPACE [No.17]; + private static int oport_colorbar_space_red( double x ) { + int res; + double xx; + if ( x < 37067 / 158860 ) { + res = 0; + } else if ( x < 85181 / 230350 ) { + xx = x - 37067 / 158860; + res = (int)((780.25 * xx + 319.71) * xx); + } else if ( x < (Math.Sqrt( 3196965649 ) + 83129) / 310480 ) { + res = (int)((1035.33580904442 * x - 82.5380748768798) * x - 52.8985266363330); + } else if ( x < 231408 / 362695 ) { + res = (int)(339.41 * x - 33.194); + } else if ( x < 152073 / 222340 ) { + res = (int)(1064.8 * x - 496.01); + } else if ( x < 294791 / 397780 ) { + res = (int)(397.78 * x - 39.791); + } else if ( x < 491189 / 550980 ) { + res = 255; + } else if ( x < 1.0 ) { + xx = x - 1.0; + res = (int)((5509.8 * xx + 597.91) * xx); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_space_green( double x ) { + int res; + double xx; + if ( x < 0.0 ) { + res = 0; + } else if ( x < (-Math.Sqrt( 166317494 ) + 39104) / 183830 ) { + res = (int)((-1838.3 * x + 464.36) * x); + } else if ( x < 37067 / 158860 ) { + res = (int)(-317.72 * x + 74.134); + } else if ( x < (3.0 * Math.Sqrt( 220297369 ) + 58535) / 155240 ) { + res = 0; + } else if ( x < 294791 / 397780 ) { + xx = x - (3.0 * Math.Sqrt( 220297369 ) + 58535) / 155240; + res = (int)((-1945 * xx + 1430.2) * xx); + } else if ( x < 491189 / 550980 ) { + res = (int)((-1770 * x + 3.92813840044638e3) * x - 1.84017494792245e3); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_space_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 51987 / 349730 ) { + res = (int)(458.79 * x); + } else if ( x < 85181 / 230350 ) { + res = (int)(109.06 * x + 51.987); + } else if ( x < (Math.Sqrt( 3196965649 ) + 83129) / 310480 ) { + res = (int)(339.41 * x - 33.194); + } else if ( x < (3.0 * Math.Sqrt( 220297369 ) + 58535) / 155240 ) { + res = (int)((-1552.4 * x + 1170.7) * x - 92.996); + } else if ( x < 27568 / 38629 ) { + res = 0; + } else if ( x < 81692 / 96241 ) { + res = (int)(386.29 * x - 275.68); + } else if ( x <= 1.0 ) { + res = (int)(1348.7 * x - 1092.6); + } else { + res = 255; + } + return res; + } + + /// SUPERNOVA [No.18]; + private static int oport_colorbar_supernova_red( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 0.136721748106749 ) { + res = (int)(oport_colorbar_supernova_II( x )); + } else if ( x < 0.23422409711017 ) { + res = (int)(1789.6 * x - 226.52); + } else if ( x < 0.498842730309711 ) { + res = (int)(oport_colorbar_supernova_I( x )); + } else if ( x < 0.549121259378134 ) { + res = (int)(-654.951781800243 * x + 562.838873112072); + } else if ( x < 1.0 ) { + res = (int)((3.6897 * x + 11.125) * x + 223.15); + } else { + res = 237; + } + return res; + } + private static int oport_colorbar_supernova_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 154; + } else if ( x < 3.888853260731947d - 2 ) { + res = (int)(oport_colorbar_supernova_I( x )); + } else if ( x < 0.136721748106749 ) { + res = (int)(-1455.86353067466 * x + 217.205447330541); + } else if ( x < 0.330799131955394 ) { + res = (int)(oport_colorbar_supernova_II( x )); + } else if ( x < 0.498842730309711 ) { + res = (int)(1096.6 * x - 310.91); + } else if ( x < 0.549121259378134 ) { + res = (int)(oport_colorbar_supernova_I( x )); + } else { + res = 244; + } + return res; + } + private static int oport_colorbar_supernova_blue( double x ) { + int res; + if ( x < 0.0 ) { + res = 93; + } else if ( x < 3.888853260731947d - 2 ) { + res = (int)(1734.6 * x + 93.133); + } else if ( x < 0.234224097110170 ) { + res = (int)(oport_colorbar_supernova_I( x )); + } else if ( x < 0.330799131955394 ) { + res = (int)(-1457.96598791534 * x + 534.138211325166); + } else if ( x < 0.549121259378134 ) { + res = (int)(oport_colorbar_supernova_II( x )); + } else if ( x < 1.0 ) { + res = (int)((3.8931 * x + 176.32) * x + 3.1505); + } else { + res = 183; + } + return res; + } + private static double oport_colorbar_supernova_I( double x ) { + int res; + res = (int)((0.3647 * x + 164.02) * x + 154.21); + return res; + } + private static double oport_colorbar_supernova_II( double x ) { + int res; + res = (int)((126.68 * x + 114.35) * x + 0.1551); + return res; + } + + /// rflow%rainbow [No.20]; + private static int oport_colorbar_rflow_rainbow_red( double x ) { + int res; + if ( x < 0.5 ) { + res = 0; + } else if ( x < 0.75 ) { + res = (int)(1020 * x - 510); + } else { + res = 255; + } + return res; + } + private static int oport_colorbar_rflow_rainbow_green( double x ) { + int res; + if ( x < 0.0 ) { + res = 0; + } else if ( x < 0.25 ) { + res = (int)(1020 * x); + } else if ( x < 0.75 ) { + res = 255; + } else if ( x < 1.0 ) { + res = (int)(-1020 * x + 1020); + } else { + res = 0; + } + return res; + } + private static int oport_colorbar_rflow_rainbow_blue( double x ) { + int res; + if ( x < 0.25 ) { + res = 255; + } else if ( x < 0.5 ) { + res = (int)(-1020 * x + 510); + } else { + res = 0; + } + return res; + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/CubicSpline.cs b/trunk/Boare.Lib.AppUtil/CubicSpline.cs new file mode 100644 index 0000000..bf0f59e --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/CubicSpline.cs @@ -0,0 +1,275 @@ +/* + * CubicSpline.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.AppUtil { + + public class CubicSpline : ICloneable, IDisposable { + int m_num_key; + public double[] m_key, m_sp3_a, m_sp3_b, m_sp3_c, m_sp3_d; + double m_default; + + public void Dispose() { + m_key = null; + m_sp3_a = null; + m_sp3_b = null; + m_sp3_c = null; + m_sp3_d = null; + GC.Collect(); + m_num_key = 0; + } + + public object Clone() { + CubicSpline ret = new CubicSpline( m_key, m_sp3_d ); + ret.DefaultValue = m_default; + return ret; + } + + public double DefaultValue { + get { + return m_default; + } + set { + m_default = value; + } + } + + public double GetValue( double x ) { + int status; + + double a, b, c, d, xx; + int i, index; + + status = 0; + if ( this.m_num_key == -1 ) { + status = -2; + return 0.0; + } + + if ( x < this.m_key[0] || this.m_key[this.m_num_key] < x ) { + status = -1; + return 0.0; + }//end if + + index = -1; + for ( i = 0; i < this.m_num_key; i++ ) {// do i = 0, sp3%noOfKey - 1 + if ( this.m_key[i] <= x && x <= this.m_key[i + 1] ) {// if(sp3%key(i) <= x .and. x <= sp3%key(i + 1))then + index = i; + break;// exit + }//end if + }//end do + + xx = x - this.m_key[index];// xx = x - sp3%key(index) + a = this.m_sp3_a[index];// a = sp3%a(index) + b = this.m_sp3_b[index];// b = sp3%b(index) + c = this.m_sp3_c[index];// c = sp3%c(index) + d = this.m_sp3_d[index];// d = sp3%d(index) + return ((a * xx + b) * xx + c) * xx + d;// ans = ((a * xx + b) * xx + c) * xx + d + }//end subroutine spline3_val + + /// 配列の形で与えられるデータ点から,3次のスプライン補間で用いる各区域のxの多項式の係数を計算します + /// データ点のx座標を格納した配列 + /// データ点のy座標を格納した配列 + public CubicSpline( double[] x, double[] y ) { + //integer, intent(in) :: n + //real(8), intent(in) :: x(0:n), y(0:n) + //integer, intent(out) :: status + int n = x.Length - 1; + int status; + m_num_key = -1; + m_default = 0.0; + double[] h, v, a, b, c, u, tmp, xx, yy;//real(8), allocatable :: h(:), v(:), a(:), b(:), c(:), u(:), tmp(:), xx(:), yy(:) + double buff1, buff2;//real(8) buff1, buff2 + int i, iostatus, nn, j;//integer i, iostatus, nn, j + + status = 0; + nn = n; + + xx = new double[n + 1]; + yy = new double[n + 1];//allocate(xx(0:n), yy(0:n)) + + xx = x; + yy = y;//yy(0:n) = y(0:n) + + //nullify(sp3%a) + //nullify(sp3%b) + //nullify(sp3%c) + //nullify(sp3%d) + //nullify(sp3%key) + + while ( true ) {//do + iostatus = 0; + for ( i = 1; i <= nn - 1; i++ ) {// do i = 1, nn - 1 + if ( xx[i + 1] - x[i] == 0.0 ) {// if(xx(i + 1) - xx(i) == 0.0d0)then + for ( j = i; j <= nn - 2; j++ ) {// do j = i, nn - 2 + xx[j] = xx[j + 1];// xx(j) = xx(j + 1) + yy[j] = yy[j + 1];// yy(j) = yy(j + 1) + }// end do + iostatus = -1; + + // create the copy of xx + //if(allocated(tmp))then + //deallocate(tmp) + //end if + tmp = new double[nn];// allocate(tmp(0:nn - 1)) + for ( int k = 0; k < nn; k++ ) { + tmp[k] = xx[k]; + }// tmp(0:nn - 1) = xx(0:nn - 1) + // deallocate(xx) + xx = new double[nn];// allocate(xx(0:nn - 1)) + for ( int k = 0; k < nn; k++ ) { + xx[k] = tmp[k]; + }// xx(0:nn - 1) = tmp(0:nn - 1) + + // create the copy of yy + for ( int k = 0; k < nn; k++ ) { + tmp[k] = yy[k]; + }// tmp(0:nn - 1) = yy(0:nn - 1) + //deallocate(yy) + yy = new double[nn];// allocate(yy(0:nn - 1)) + for ( int k = 0; k < nn; k++ ) { + yy[k] = tmp[k]; + }// yy(0:nn - 1) = tmp(0:nn - 1) + break;// exit + }//end if + }//end do + if ( iostatus == 0 ) {// if(iostatus == 0)then + break;// exit + } else {// else + nn = nn - 1;// nn = nn - 1 + }// end if + }// end do + + //allocate(h(0:nn - 1), v(1:nn - 1), a(1:nn - 1), b(1:nn - 1), c(1:nn - 1), u(1:nn - 1)) + h = new double[nn]; + v = new double[nn - 1]; + a = new double[nn - 1]; + b = new double[nn - 1]; + c = new double[nn - 1]; + u = new double[nn - 1]; + + // executed in debug mode ****************************************************************************************************** + //if(spline_debug_flag == 1)then ! ** + //open(unit = 26, file = 'spline_debug.txt') ! ** + //end if ! ** + // ***************************************************************************************************************************** + + // calculate h_j + for ( i = 0; i < nn; i++ ) {// do i = 0, nn - 1 + h[i] = xx[i + 1] - xx[i];// h(i) = xx(i + 1) - xx(i) + if ( h[i] <= 0.0 ) {// if(h(i) <= 0.0d0)then + this.m_key = new double[1]; + this.m_sp3_a = new double[1]; + this.m_sp3_b = new double[1]; + this.m_sp3_c = new double[1]; + this.m_sp3_d = new double[1]; + return; + } + } + + // calculate v_j + for ( i = 1; i < nn; i++ ) {// do i = 1, nn - 1 + buff1 = yy[i + 1] - yy[i];// buff1 = yy(i + 1) - yy(i) + buff2 = yy[i] - y[i - 1];// buff2 = yy(i) - yy(i - 1) + if ( buff1 == 0.0 ) {// if(buff1 == 0.0d0)then + if ( buff2 == 0.0 ) {// if(buff2 == 0.0d0)then + v[i - 1] = 0;// v(i) = 0.0d0 + } else {// else + v[i - 1] = 6.0 * (-(yy[i] - yy[i - 1]) / h[i - 1]);// v(i) = 6.0d0 * (- (yy(i) - yy(i - 1)) / h(i - 1)) + }// end if + } else {// else + if ( buff2 == 0.0 ) {// if(buff2 == 0.0d0)then + v[i - 1] = 6.0 * ((yy[i + 1] - yy[i]) / h[i]);// v(i) = 6.0d0 * ((yy(i + 1) - yy(i)) / h(i)) + } else {// else + v[i - 1] = 6.0 * ((yy[i + 1] - yy[i]) / h[i] - (yy[i] - yy[i - 1]) / h[i - 1]);// v(i) = 6.0d0 * ((yy(i + 1) - yy(i)) / h(i) - (yy(i) - yy(i - 1)) / h(i - 1)) + }// end if + }// end if + }//end do + + for ( i = 1; i < nn; i++ ) {// do i = 1, nn - 1 + a[i - 1] = 2.0 * (h[i - 1] + h[i]);// a(i) = 2.0d0 * (h(i - 1) + h(i)) + b[i - 1] = h[i - 1];// b(i) = h(i - 1) + c[i - 1] = h[i];// c(i) = h(i) + }// end do + + LUDecTDM( nn - 1, a, b, c, v, out u );// call LUDecTDM(nn - 1, a, b, c, v, u) + + m_num_key = nn;// sp3%noOfKey = nn + this.m_sp3_a = new double[nn];// allocate(sp3%a(0:nn - 1)) + this.m_sp3_b = new double[nn];// allocate(sp3%b(0:nn - 1)) + this.m_sp3_c = new double[nn];// allocate(sp3%c(0:nn - 1)) + this.m_sp3_d = new double[nn];// allocate(sp3%d(0:nn - 1)) + this.m_key = new double[nn + 1];// allocate(sp3%key(0:nn)) + + this.m_sp3_a[0] = u[0] / (6.0 * h[0]);// sp3%a(0) = u(1) / (6.0d0 * h(0)) + this.m_sp3_b[0] = 0.0;// sp3%b(0) = 0.0d0 + this.m_sp3_c[0] = (yy[1] - yy[0]) / h[0] - h[0] * u[0] / 6.0;// sp3%c(0) = (yy(1) - yy(0)) / h(0) - h(0) * u(1) / 6.0d0 + this.m_sp3_a[nn - 1] = -u[nn - 2] / (6.0 * h[nn - 1]);// sp3%a(nn - 1) = -u(nn - 1) / (6.0d0 * h(nn - 1)) + this.m_sp3_b[nn - 1] = u[nn - 2] * 0.5;// sp3%b(nn - 1) = u(nn - 1) * 0.5d0 + this.m_sp3_c[nn - 1] = (yy[nn] - yy[nn - 1]) / h[nn - 1] - h[nn - 1] * u[nn - 2] / 3.0;// sp3%c(nn - 1) = (yy(nn) - yy(nn - 1)) / h(nn - 1) - h(nn - 1) * u(nn - 1) / 3.0d0 + for ( i = 1; i <= nn - 2; i++ ) {// do i = 1, nn - 2 + this.m_sp3_a[i] = (u[i] - u[i - 1]) / (6.0 * h[i]);// sp3%a(i) = (u(i + 1) - u(i)) / (6.0d0 * h(i)) + this.m_sp3_b[i] = u[i - 1] * 0.5;// sp3%b(i) = u(i) * 0.5d0 + this.m_sp3_c[i] = (yy[i + 1] - yy[i]) / h[i] - h[i] * (2.0 * u[i - 1] + u[i]) / 6.0;// sp3%c(i) = (yy(i + 1) - yy(i)) / h(i) - h(i) * (2.0d0 * u(i) + u(i + 1)) / 6.0d0 + }//end do + this.m_key = xx; + // sp3%key(0:nn) = xx(0:nn) + for ( int k = 0; k < nn; k++ ) { + this.m_sp3_d[k] = yy[k]; + }// sp3%d(0:nn - 1) = yy(0:nn - 1) + } + + /// + /// This subroutine solves system of linear equation(only for + /// tridiagonal matrix system) by LU decompression method. + /// Meanings of variables are defined below. + /// ( a1 c1 0 ) ( x1 ) ( y1 ) + /// ( b2 a2 c2 ) ( x2 ) ( y2 ) + /// ( b3 a3 c3 ) ( x3 ) ( y3 ) + /// ( ... ) ( ...) = ( ...) + /// ( bN-1 aN-1 cN-1 ) (xN-1) (yN-1) + /// ( 0 bN aN ) ( xN ) ( yN ) + /// + /// + /// + /// + /// + /// + /// + private static void LUDecTDM( int N, double[] a, double[] b, double[] c, double[] y, out double[] x ) { + double[] d = new double[N]; + double[] z = new double[N]; + double[] l = new double[N]; + int i; + x = new double[N]; + + d[0] = a[0];// d(1) = a(1) + for ( i = 1; i < N; i++ ) {// do i = 2, N + l[i] = b[i] / d[i - 1];// l(i) = b(i) / d(i - 1) + d[i] = a[i] - l[i] * c[i - 1];// d(i) = a(i) - l(i) * c(i - 1) + }// end do + + z[0] = y[0];// z(1) = y(1) + for ( i = 1; i < N; i++ ) {// do i = 2, N + z[i] = y[i] - l[i] * z[i - 1];// z(i) = y(i) - l(i) * z(i - 1) + }// end do + + x[N - 1] = z[N - 1] / d[N - 1];// x(N) = z(N) / d(N) + for ( i = N - 2; i >= 0; i-- ) {// do i = N - 1, 1, -1 + x[i] = (z[i] - c[i] * x[i + 1]) / d[i];// x(i) = (z(i) - c(i) * x(i + 1)) / d(i) + }// end do + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/ISO639.cs b/trunk/Boare.Lib.AppUtil/ISO639.cs new file mode 100644 index 0000000..601b2fa --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/ISO639.cs @@ -0,0 +1,29 @@ +/* + * ISO639.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Globalization; + +namespace Boare.Lib.AppUtil { + + internal class iso639 { + public static bool CheckValidity( string code_string ) { + try { + CultureInfo c = CultureInfo.CreateSpecificCulture( code_string ); + } catch { + return false; + } + return true; + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/InputBox.Designer.cs b/trunk/Boare.Lib.AppUtil/InputBox.Designer.cs new file mode 100644 index 0000000..23c6272 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/InputBox.Designer.cs @@ -0,0 +1,113 @@ +/* + * InputBox.Designer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.AppUtil { + partial class InputBox { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.txtInput = new System.Windows.Forms.TextBox(); + this.btnOk = new System.Windows.Forms.Button(); + this.lblMessage = new System.Windows.Forms.Label(); + this.btnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // txtInput + // + this.txtInput.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtInput.Location = new System.Drawing.Point( 12, 24 ); + this.txtInput.Name = "txtInput"; + this.txtInput.Size = new System.Drawing.Size( 309, 19 ); + this.txtInput.TabIndex = 0; + // + // btnOk + // + this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnOk.Location = new System.Drawing.Point( 246, 49 ); + this.btnOk.Name = "btnOk"; + this.btnOk.Size = new System.Drawing.Size( 75, 23 ); + this.btnOk.TabIndex = 1; + this.btnOk.Text = "OK"; + this.btnOk.UseVisualStyleBackColor = true; + this.btnOk.Click += new System.EventHandler( this.btnOk_Click ); + // + // lblMessage + // + this.lblMessage.AutoSize = true; + this.lblMessage.Location = new System.Drawing.Point( 12, 9 ); + this.lblMessage.Name = "lblMessage"; + this.lblMessage.Size = new System.Drawing.Size( 0, 12 ); + this.lblMessage.TabIndex = 2; + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( -100, 49 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 3; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // InputBox + // + this.AcceptButton = this.btnOk; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 333, 82 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.lblMessage ); + this.Controls.Add( this.btnOk ); + this.Controls.Add( this.txtInput ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InputBox"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "InputBox"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtInput; + private System.Windows.Forms.Button btnOk; + private System.Windows.Forms.Label lblMessage; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/trunk/Boare.Lib.AppUtil/InputBox.cs b/trunk/Boare.Lib.AppUtil/InputBox.cs new file mode 100644 index 0000000..db2ea7e --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/InputBox.cs @@ -0,0 +1,37 @@ +/* + * InputBox.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + public partial class InputBox : Form { + public InputBox( string message ) { + InitializeComponent(); + lblMessage.Text = message; + } + + public string Result { + get { + return txtInput.Text; + } + set { + txtInput.Text = value; + } + } + + private void btnOk_Click( object sender, EventArgs e ) { + DialogResult = DialogResult.OK; + } + } +} diff --git a/trunk/Boare.Lib.AppUtil/MathEx.cs b/trunk/Boare.Lib.AppUtil/MathEx.cs new file mode 100644 index 0000000..6d26602 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/MathEx.cs @@ -0,0 +1,21 @@ +/* + * MathEx.cs + * Copyright (c) 2008 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Boare.Lib.AppUtil { + + +} diff --git a/trunk/Boare.Lib.AppUtil/MessageBody.cs b/trunk/Boare.Lib.AppUtil/MessageBody.cs new file mode 100644 index 0000000..c8bc0f5 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/MessageBody.cs @@ -0,0 +1,162 @@ +/* + * MessageBody.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.AppUtil { + + public class MessageBody { + public string lang; + public string po_header = ""; + public Dictionary list = new Dictionary(); + + public MessageBody( string lang_ ) { + lang = lang_; + } + + public MessageBody( string lang, string[] ids, string[] messages ) { + this.lang = lang; + list = new Dictionary(); + for( int i = 0; i < ids.Length; i++ ) { + list.Add( ids[i], messages[i] ); + } + } + + public MessageBody( string lang_, string file ) { + lang = lang_; + //Dictionary list = new Dictionary(); + po_header = ""; + using ( StreamReader sr = new StreamReader( file ) ) { + while ( sr.Peek() >= 0 ) { + string msgid; + string first_line = sr.ReadLine(); + string last_line = ReadTillMessageEnd( sr, first_line, "msgid", out msgid ); + string msgstr; + last_line = ReadTillMessageEnd( sr, last_line, "msgstr", out msgstr ); + //if ( msgid.Length > 0 && msgstr.Length > 0 ) { + if ( msgid.Length > 0 ) { + if ( list.ContainsKey( msgid ) ) { + list[msgid] = msgstr; + } else { + list.Add( msgid, msgstr ); + } + } else { + po_header = msgstr; + } + } + } + string[] ids = new string[list.Keys.Count]; + string[] msgs = new string[ids.Length]; + int i = -1; + foreach ( string id in list.Keys ) { + i++; + ids[i] = id; + msgs[i] = list[ids[i]]; + } + } + + public string GetMessage( string id ) { + if ( list.ContainsKey( id ) ) { + string ret = list[id]; + if ( ret == "" ) { + return id; + } else { + return list[id]; + } + } + return id; + } + + public void Write( string file ) { + using ( StreamWriter sw = new StreamWriter( file ) ) { + if ( po_header != "" ) { + sw.WriteLine( "msgid \"\"" ); + sw.WriteLine( "msgstr \"\"" ); + sw.WriteLine( po_header ); + sw.WriteLine(); + } else { + sw.WriteLine( "msgid \"\"" ); + sw.WriteLine( "msgstr \"\"" ); + sw.WriteLine( "\"Content-Type: text/plain; charset=UTF-8\\n\"" ); + sw.WriteLine( "\"Content-Transfer-Encoding: 8bit\\n\"" ); + sw.WriteLine(); + } + foreach ( string key in list.Keys ) { + string skey = key.Replace( "\n", "\\n\"\n\"" ); + sw.WriteLine( "msgid \"" + skey + "\"" ); + string s = list[key]; + s = s.Replace( "\n", "\\n\"\n\"" ); + sw.WriteLine( "msgstr \"" + s + "\"" ); + sw.WriteLine(); + } + } + } + + private static void SeparateEntryAndMessage( string source, out string entry, out string message ) { + string line = source.Trim(); + entry = ""; + message = ""; + if ( line.Length <= 0 ) { + return; + } + int index_space = line.IndexOf( ' ' ); + int index_dquoter = line.IndexOf( '"' ); + int index = Math.Min( index_dquoter, index_space ); + entry = line.Substring( 0, index ); + message = line.Substring( index_dquoter + 1 ); + message = message.Substring( 0, message.Length - 1 ); + } + + private static string ReadTillMessageEnd( StreamReader sr, string first_line, string entry, out string msg ) { + msg = ""; + string line = first_line; + bool entry_found = false; + if ( line.StartsWith( entry ) ) { + string dum, dum2; + SeparateEntryAndMessage( line, out dum, out dum2 ); + msg += dum2; + } else { + while ( sr.Peek() >= 0 ) { + line = sr.ReadLine(); + if ( line.StartsWith( "#" ) ) { + continue; + } + if ( line.StartsWith( entry ) ) { + string dum, dum2; + SeparateEntryAndMessage( line, out dum, out dum2 ); + msg += dum2; + break; + } + } + } + string ret = ""; + while ( sr.Peek() >= 0 ) { + line = sr.ReadLine(); + if ( !line.StartsWith( "\"" ) ) { + msg = msg.Replace( "\\\"", "\"" ); + msg = msg.Replace( "\\n", "\n" ); + return line; + } + int index = line.LastIndexOf( "\"" ); + msg += line.Substring( 1, index - 1 ); + } + msg = msg.Replace( "\\\"", "\"" ); + msg = msg.Replace( "\\n", "\n" ); + return line; + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/Messaging.cs b/trunk/Boare.Lib.AppUtil/Messaging.cs new file mode 100644 index 0000000..30eb1f7 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/Messaging.cs @@ -0,0 +1,107 @@ +/* + * Messaging.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + + public static class Messaging { + private static string s_lang = ""; + private static List s_messages = new List(); + + public static string[] GetKeys( string lang ) { + foreach ( MessageBody dict in s_messages ) { + if ( lang == dict.lang ) { + List list = new List(); + foreach ( string key in dict.list.Keys ) { + list.Add( key ); + } + return list.ToArray(); + } + } + return null; + } + + public static string[] GetRegisteredLanguage() { + List res = new List(); + foreach ( MessageBody dict in s_messages ) { + res.Add( dict.lang ); + } + return res.ToArray(); + } + + public static string Language { + get { + if ( s_lang != "" ) { + return s_lang; + } else { + s_lang = "en"; + return s_lang; + } + } + set { + if ( value != "" ) { + s_lang = value; + } else { + s_lang = "en"; + } + } + } + + /// + /// 現在の実行ディレクトリにある言語設定ファイルを全て読込み、メッセージリストに追加します + /// + public static void LoadMessages() { + LoadMessages( Application.StartupPath ); + } + + /// + /// 指定されたディレクトリにある言語設定ファイルを全て読込み、メッセージリストに追加します + /// + /// + public static void LoadMessages( string directory ) { + DirectoryInfo current = new DirectoryInfo( directory ); + s_messages.Clear(); +#if DEBUG + Console.WriteLine( "Messaging+LoadMessages()" ); +#endif + foreach ( FileInfo fi in current.GetFiles( "*.po" ) ) { + string fname = fi.FullName; +#if DEBUG + Console.WriteLine( " fname=" + fname ); +#endif + AppendFromFile( fname ); + } + } + + public static void AppendFromFile( string file ) { + s_messages.Add( new MessageBody( Path.GetFileNameWithoutExtension( file ), file ) ); + } + + public static string GetMessage( string id ) { + if ( s_lang.Length <= 0 ) { + s_lang = "en"; + } + foreach ( MessageBody mb in s_messages ) { + if ( mb.lang == s_lang ) { + return mb.GetMessage( id ); + } + } + return id; + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/Misc.cs b/trunk/Boare.Lib.AppUtil/Misc.cs new file mode 100644 index 0000000..56ea996 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/Misc.cs @@ -0,0 +1,325 @@ +/* + * Misc.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Windows.Forms; +using System.Drawing.Imaging; +using System.Reflection; +using System.IO; + +namespace Boare.Lib.AppUtil { + + public static partial class Misc { + /// + /// 指定したディレクトリに作成可能な、一時ファイル名を取得します + /// + /// ディレクトリ + /// + public static string GetTempFileNameIn( string directory ) { + for ( uint i = uint.MinValue; i <= uint.MaxValue; i++ ) { + string file = Path.Combine( directory, "temp" + i ); + if ( !File.Exists( file ) ) { + return file; + } + } + return ""; + } + + /// + /// 指定したディレクトリに作成可能な、一時ファイル名を取得します + /// + /// ディレクトリ + /// 拡張子(ex. ".txt") + /// + public static string GetTempFileNameIn( string directory, string extention ){ + for ( uint i = uint.MinValue; i <= uint.MaxValue; i++ ) { + string file = Path.Combine( directory, "temp" + i + extention ); + if ( !File.Exists( file ) ) { + return file; + } + } + return ""; + } + + /// + /// 指定した画像ファイルから新しいBitmapオブジェクトを作成します + /// + /// + /// + public static Bitmap BitmapFromStream( string file ) { + if ( !File.Exists( file ) ) { + return null; + } + FileStream fs = new FileStream( file, FileMode.Open ); + Bitmap ret = new Bitmap( fs ); + fs.Close(); + return ret; + } + + /// + /// 指定した画像ファイルから新しいImageオブジェクトを作成します + /// + /// + /// + public static Image ImageFromStream( string file ) { + if ( !File.Exists( file ) ) { + return null; + } + FileStream fs = new FileStream( file, FileMode.Open ); + Image ret = Image.FromStream( fs ); + fs.Close(); + return ret; + } + + /// + /// ImageFormatから,デフォルトの拡張子を取得します + /// + /// + /// + public static string GetExtensionFromImageFormat( ImageFormat format ) { + switch ( format.ToString().ToLower() ) { + case "bmp": + return "bmp"; + case "emf": + return "emf"; + case "gif": + return "gif"; + case "jpeg": + return "jpg"; + case "png": + return "png"; + case "tiff": + return "tiff"; + case "wmf": + return "wmf"; + default: + return ""; + + } + } + + /// + /// System.Drawimg.Imaging.ImageFormatで使用可能なフォーマットの一覧を取得します + /// + /// + public static ImageFormat[] GetImageFormats() { +#if DEBUG + Console.WriteLine( "GetImageFormats()" ); +#endif + PropertyInfo[] properties = typeof( System.Drawing.Imaging.ImageFormat ).GetProperties(); + List ret = new List(); + foreach ( PropertyInfo pi in properties ) { + if ( pi.PropertyType.Equals( typeof( System.Drawing.Imaging.ImageFormat ) ) ) { + ImageFormat ifmt = (System.Drawing.Imaging.ImageFormat)pi.GetValue( null, null ); +#if DEBUG + Console.WriteLine( ifmt.ToString() ); +#endif + ret.Add( ifmt ); + } + } + return ret.ToArray(); + } + + public static void RgbToHsv( int r, int g, int b, out double h, out double s, out double v ) { + RgbToHsv( r / 255.0, g / 255.0, b / 255.0, out h, out s, out v ); + } + + public static void RgbToHsv( double r, double g, double b, out double h, out double s, out double v ) { + double tmph, imax, imin; + const double sqrt3 = 1.7320508075688772935274463415059; + imax = Math.Max( r, Math.Max( g, b ) ); + imin = Math.Min( r, Math.Min( g, b ) ); + if ( imax == 0.0 ) { + h = 0; + s = 0; + v = 0; + return; + } else if ( imax == imin ) { + tmph = 0; + } else { + if ( r == imax ) { + tmph = 60.0 * (g - b) / (imax - imin); + } else if ( g == imax ) { + tmph = 60.0 * (b - r) / (imax - imin) + 120.0; + } else { + tmph = 60.0 * (r - g) / (imax - imin) + 240.0; + } + } + while ( tmph < 0.0 ) { + tmph = tmph + 360.0; + } + while ( tmph >= 360.0 ) { + tmph = tmph - 360.0; + } + h = tmph / 360.0; + s = (imax - imin) / imax; + v = imax; + } + + /*public static void RgbToHsv( double r, double g, double b, out double h, out double s, out double v ) { + double tmph, imax, imin; + const double sqrt3 = 1.7320508075688772935274463415059; + const double deg2rad = 180.0 / Math.PI; + imax = Math.Max( r, Math.Max( g, b ) ); + imin = Math.Min( r, Math.Min( g, b ) ); + if ( imax == 0.0 ) { + h = 0; + s = 0; + v = 0; + return; + } else if ( imax == imin ) { + tmph = 0; + } else { + double x = 2.0 * r - g - b; + double y = sqrt3 * (g - b); + if ( x == 0.0 ) { + if ( y > 0.0 ) { + tmph = 90.0; + } else { + tmph = 270.0; + } + } else { + tmph = Math.Atan2( y, x ); + tmph = tmph * deg2rad; + } + } + while ( tmph < 0.0 ) { + tmph = tmph + 360.0; + } + while ( tmph >= 360.0 ) { + tmph = tmph - 360.0; + } + h = tmph / 360.0; + s = (imax - imin) / imax; + v = imax; + }*/ + + public static Color HsvToColor( double h, double s, double v ) { + double dr, dg, db; + HsvToRgb( h, s, v, out dr, out dg, out db ); + return Color.FromArgb( (int)(dr * 255), (int)(dg * 255), (int)(db * 255) ); + } + + public static void HsvToRgb( double h, double s, double v, out byte r, out byte g, out byte b ) { + double dr, dg, db; + HsvToRgb( h, s, v, out dr, out dg, out db ); + r = (byte)(dr * 255); + g = (byte)(dg * 255); + b = (byte)(db * 255); + } + + public static void HsvToRgb( double h, double s, double v, out double r, out double g, out double b ) { + double f, p, q, t, hh; + int hi; + r = g = b = 0.0; + if ( s == 0 ) { + r = v; + g = v; + b = v; + } else { + hh = h * 360.0; + hi = (int)(hh / 60.0) % 6; + f = hh / 60.0 - (double)(hi); + p = v * (1.0 - s); + q = v * (1.0 - f * s); + t = v * (1.0 - (1.0 - f) * s); + switch ( hi ) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + } + } + + /// + /// 指定された文字列を指定されたフォントで描画したときのサイズを計測します。 + /// + /// + /// + /// + public static Size MeasureString( string text, Font font ) { + using ( Bitmap dumy = new Bitmap( 1, 1 ) ) + using ( Graphics g = Graphics.FromImage( dumy ) ) { + SizeF tmp = g.MeasureString( text, font ); + return new Size( (int)tmp.Width, (int)tmp.Height ); + } + } + + /// + /// 指定したコントロールと、その子コントロールのフォントを変更します + /// + /// + /// + public static void ApplyFontRecurse( Control c, Font font ) { + c.Font = font; + for ( int i = 0; i < c.Controls.Count; i++ ) { + ApplyFontRecurse( c.Controls[i], font ); + } + } + + /// + /// + /// + /// + /// + /// + /// + /// + public static bool IsOverwrapped( double start1, double end1, double start2, double end2 ) { + if ( start2 <= start1 && start1 < end2 ) { + return true; + } else if ( start2 < end1 && end1 < end2 ) { + return true; + } else { + if ( start1 <= start2 && start2 < end1 ) { + return true; + } else if ( start1 < end2 && end2 < end1 ) { + return true; + } else { + return false; + } + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/Properties/AssemblyInfo.cs b/trunk/Boare.Lib.AppUtil/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6c14cd1 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +/* + * AssemblyInfo.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Cadencii is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle( "Boare.Lib.AppUtil" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "Boare.Lib.AppUtil" )] +[assembly: AssemblyCopyright( "Copyright © 2008-2009" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] +[assembly: ComVisible( false )] +[assembly: Guid( "1d456f8c-100a-4f4b-b53f-d09a32ce6bfc" )] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.1" )] diff --git a/trunk/Boare.Lib.AppUtil/VersionInfo.Designer.cs b/trunk/Boare.Lib.AppUtil/VersionInfo.Designer.cs new file mode 100644 index 0000000..dcd0c91 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/VersionInfo.Designer.cs @@ -0,0 +1,136 @@ +/* + * VersionInfo.Designer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace Boare.Lib.AppUtil { + + partial class VersionInfo { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.btnFlip = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.timer = new System.Windows.Forms.Timer( this.components ); + this.btnSaveAuthorList = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // btnFlip + // + this.btnFlip.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnFlip.Location = new System.Drawing.Point( 13, 391 ); + this.btnFlip.Name = "btnFlip"; + this.btnFlip.Size = new System.Drawing.Size( 75, 21 ); + this.btnFlip.TabIndex = 2; + this.btnFlip.Text = "クレジット"; + this.btnFlip.UseVisualStyleBackColor = true; + this.btnFlip.Click += new System.EventHandler( this.btnFlip_Click ); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Location = new System.Drawing.Point( 211, 391 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 21 ); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // timer + // + this.timer.Interval = 30; + this.timer.Tick += new System.EventHandler( this.timer_Tick ); + // + // btnSaveAuthorList + // + this.btnSaveAuthorList.Location = new System.Drawing.Point( 123, 391 ); + this.btnSaveAuthorList.Name = "btnSaveAuthorList"; + this.btnSaveAuthorList.Size = new System.Drawing.Size( 43, 21 ); + this.btnSaveAuthorList.TabIndex = 3; + this.btnSaveAuthorList.Text = "button1"; + this.btnSaveAuthorList.UseVisualStyleBackColor = true; + this.btnSaveAuthorList.Visible = false; + // + // VersionInfoEx + // + this.AcceptButton = this.btnOK; + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.ClientSize = new System.Drawing.Size( 300, 426 ); + this.Controls.Add( this.btnSaveAuthorList ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnFlip ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.KeyPreview = true; + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size( 306, 451 ); + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size( 306, 451 ); + this.Name = "VersionInfoEx"; + this.ShowIcon = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "VersionInfoEx"; + this.Paint += new System.Windows.Forms.PaintEventHandler( this.VersionInfoEx_Paint ); + this.KeyDown += new System.Windows.Forms.KeyEventHandler( this.VersionInfoEx_KeyDown ); + this.FontChanged += new System.EventHandler( this.VersionInfoEx_FontChanged ); + this.ResumeLayout( false ); + + } + + #endregion + + public void ApplyLanguage() { + string about = string.Format( _( "About {0}" ), m_app_name ); + string credit = _( "Credit" ); + Size size1 = Misc.MeasureString( about, btnFlip.Font ); + Size size2 = Misc.MeasureString( credit, btnFlip.Font ); + m_button_width_about = Math.Max( 75, (int)(size1.Width * 1.3) ); + m_button_width_credit = Math.Max( 75, (int)(size2.Width * 1.3) ); + if( m_credit_mode ) { + btnFlip.Width = m_button_width_about; + btnFlip.Text = about; + } else { + btnFlip.Width = m_button_width_credit; + btnFlip.Text = credit; + } + this.Text = about; + } + private System.Windows.Forms.Button btnFlip; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Timer timer; + private System.Windows.Forms.Button btnSaveAuthorList; + } +} \ No newline at end of file diff --git a/trunk/Boare.Lib.AppUtil/VersionInfo.cs b/trunk/Boare.Lib.AppUtil/VersionInfo.cs new file mode 100644 index 0000000..aef1bc4 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/VersionInfo.cs @@ -0,0 +1,262 @@ +/* + * VersionInfo.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace Boare.Lib.AppUtil { + + public partial class VersionInfo : Form { + DateTime m_scroll_started; + private AuthorListEntry[] m_credit; + const float m_speed = 35f; + string m_version; + bool m_credit_mode = false; + float m_last_t = 0f; + float m_last_speed = 0f; + float m_shift = 0f; + int m_button_width_about = 75; + int m_button_width_credit = 75; + Bitmap m_scroll; + const int m_height = 380; + readonly Color m_background = Color.White; + private string m_app_name = ""; + private Color m_app_name_color = Color.Black; + private Color m_version_color = Color.FromArgb( 105, 105, 105 ); + private bool m_shadow_enablde = true; + + public VersionInfo( string app_name, string version ) { + m_version = version; + m_app_name = app_name; + InitializeComponent(); + ApplyLanguage(); + + this.SetStyle( ControlStyles.DoubleBuffer, true ); + this.SetStyle( ControlStyles.UserPaint, true ); + this.SetStyle( ControlStyles.AllPaintingInWmPaint, true ); + + m_credit = new AuthorListEntry[] { }; + btnSaveAuthorList.Visible = false; +#if DEBUG + GenerateAuthorList(); + btnSaveAuthorList.Visible = true; + btnSaveAuthorList.Click += new EventHandler( btnSaveAuthorList_Click ); +#endif + } + + public bool SaveAuthorListVisible { + set { + btnSaveAuthorList.Visible = value; + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + /// + /// バージョン番号表示の文字色を取得または設定します + /// + public Color VersionColor { + get { + return m_version_color; + } + set { + m_version_color = value; + } + } + + /// + /// アプリケーション名表示の文字色を取得または設定します + /// + public Color AppNameColor { + get { + return m_app_name_color; + } + set { + m_app_name_color = value; + } + } + + public Bitmap Credit { + set { + m_scroll = value; + } + } + + public string AppName { + get { + return m_app_name; + } + set { + m_app_name = value; + } + } + + public AuthorListEntry[] AuthorList { + set { + m_credit = value; +#if DEBUG + GenerateAuthorList(); +#endif + } + } + + private void GenerateAuthorList() { + const float shadow_shift = 2f; + const string font_name = "Arial"; + const int font_size = 10; + Font font = new Font( font_name, font_size ); + Size size = Boare.Lib.AppUtil.Misc.MeasureString( "Qjqp", font ); + float width = this.Width; + float height = size.Height; + StringFormat sf = new StringFormat(); + m_scroll = new Bitmap( (int)width, (int)(40f + m_credit.Length * height * 1.1f) ); + using ( Graphics g = Graphics.FromImage( m_scroll ) ) { + sf.Alignment = StringAlignment.Center; + if ( m_shadow_enablde ) { + g.DrawString( m_app_name, + new Font( font_name, (int)(font_size * 1.1f), FontStyle.Bold ), + new SolidBrush( Color.FromArgb( 40, Color.Black ) ), + new RectangleF( shadow_shift, shadow_shift, width, height ), + sf ); + } + g.DrawString( m_app_name, + new Font( font_name, (int)(font_size * 1.1f), FontStyle.Bold ), + Brushes.Black, + new RectangleF( 0f, 0f, width, height ), + sf ); + for ( int i = 0; i < m_credit.Length; i++ ) { + if ( m_shadow_enablde ) { + g.DrawString( m_credit[i].Name, + new Font( font_name, font_size, m_credit[i].Style ), + new SolidBrush( Color.FromArgb( 40, Color.Black ) ), + new RectangleF( 0f + shadow_shift, 40f + i * height * 1.1f + shadow_shift, width, height ), + sf ); + } + g.DrawString( m_credit[i].Name, + new Font( font_name, font_size, m_credit[i].Style ), + Brushes.Black, + new RectangleF( 0f, 40f + i * height * 1.1f, width, height ), + sf ); + } + } + } + + void btnSaveAuthorList_Click( object sender, EventArgs e ) { +#if DEBUG + using ( SaveFileDialog dlg = new SaveFileDialog() ){ + if( dlg.ShowDialog() == DialogResult.OK ){ + m_scroll.Save( dlg.FileName, System.Drawing.Imaging.ImageFormat.Png ); + } + } +#endif + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnFlip_Click( object sender, EventArgs e ) { + m_credit_mode = !m_credit_mode; + if ( m_credit_mode ) { + btnFlip.Width = m_button_width_about; + btnFlip.Text = string.Format( _( "About {0}" ), m_app_name ); + m_scroll_started = DateTime.Now; + m_last_speed = 0f; + m_last_t = 0f; + m_shift = 0f; + timer.Enabled = true; + } else { + timer.Enabled = false; + btnFlip.Width = m_button_width_credit; + btnFlip.Text = _( "Credit" ); + } + this.Invalidate(); + } + + private void timer_Tick( object sender, EventArgs e ) { + this.Invalidate(); + } + + private void VersionInfoEx_Paint( object sender, PaintEventArgs e ) { + try { + Graphics g = e.Graphics; + g.Clip = new Region( new Rectangle( 0, 0, this.Width, m_height ) ); + g.Clear( m_background ); + if ( m_credit_mode ) { + float times = (float)(((DateTime.Now).Subtract( m_scroll_started )).TotalSeconds) - 3f; + float speed = (float)((2.0 - bocoree.math.erfcc( times * 0.8 )) / 2.0) * m_speed; + float dt = times - m_last_t; + m_shift += (speed + m_last_speed) * dt / 2f; + m_last_t = times; + m_last_speed = speed; + float dx = (this.Width - m_scroll.Width) * 0.5f; + if ( m_scroll != null ) { + g.DrawImage( m_scroll, + dx, 90f - m_shift, + m_scroll.Width, m_scroll.Height ); + if ( 90f - m_shift + m_scroll.Height < 0 ) { + m_shift = -m_height * 1.5f; + } + } + int grad_height = 60; + Rectangle top = new Rectangle( 0, 0, this.Width, grad_height ); + using ( LinearGradientBrush lgb = new LinearGradientBrush( top, Color.White, Color.Transparent, LinearGradientMode.Vertical ) ) { + g.FillRectangle( lgb, top ); + } + Rectangle bottom = new Rectangle( 0, m_height - grad_height, this.Width, grad_height ); + g.Clip = new Region( new Rectangle( 0, m_height - grad_height + 1, this.Width, grad_height - 1 ) ); + using ( LinearGradientBrush lgb = new LinearGradientBrush( bottom, Color.Transparent, Color.White, LinearGradientMode.Vertical ) ) { + g.FillRectangle( lgb, bottom ); + } + g.ResetClip(); + } else { + g.DrawString( + m_app_name, + new Font( "Century Gorhic", 24, FontStyle.Bold ), + new SolidBrush( m_app_name_color ), + new PointF( 20, 110 ) ); + g.DrawString( + "version " + m_version, + new Font( "Arial", 10 ), + new SolidBrush( m_version_color ), + new PointF( 25, 150 ) ); + } + } catch ( Exception ex ) { +#if DEBUG + Console.WriteLine( "VersionInfoEx_Paint" ); + Console.WriteLine( ex.StackTrace ); +#endif + } + } + + private void VersionInfoEx_KeyDown( object sender, KeyEventArgs e ) { + if ( (e.KeyCode & Keys.Escape) == Keys.Escape ) { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + } + + private void VersionInfoEx_FontChanged( object sender, EventArgs e ) { + Font font = this.Font; + for ( int i = 0; i < this.Controls.Count; i++ ) { + Misc.ApplyFontRecurse( this.Controls[i], font ); + } + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/XmlSerializeWithDescription.cs b/trunk/Boare.Lib.AppUtil/XmlSerializeWithDescription.cs new file mode 100644 index 0000000..c2d9966 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/XmlSerializeWithDescription.cs @@ -0,0 +1,215 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Xml; +using System.Reflection; +using System.IO; + +namespace Boare.Lib.AppUtil { + + /// + /// フィールド、またはプロパティの概要を格納するattribute + /// + [AttributeUsage( AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false )] + public class XmlItemDescription : Attribute { + private string m_value = ""; + private string m_attribute_name = "description"; + + public XmlItemDescription( string Value ) { + m_value = Value; + } + + public XmlItemDescription( string AttributeName, string Value ) { + m_value = Value; + m_attribute_name = AttributeName; + } + + public string AttributeName { + get { + return m_attribute_name; + } + } + + public string Value { + get { + return m_value; + } + } + } + + /// + /// フィールドおよびプロパティを、XmlItemDescription属性の文字列を付加しながらXmlシリアライズする + /// + public class XmlSerializeWithDescription { + [XmlItemDescription( "mio" )] + private string foo; + + private XmlTextWriter m_writer; + private Type m_type; + + public XmlSerializeWithDescription() { + } + + public void Serialize( Stream stream, object obj ) { + m_writer = new XmlTextWriter( stream, null ); + m_writer.Formatting = Formatting.Indented; + m_writer.Indentation = 4; + m_writer.IndentChar = ' '; + m_writer.WriteStartDocument(); + m_writer.WriteStartElement( obj.GetType().Name ); + PrintItemRecurse( obj ); + m_writer.WriteEndElement(); + m_writer.WriteEndDocument(); + m_writer.Flush(); + } + + private void PrintItemRecurse( object obj ) { + Type t = obj.GetType(); + if ( !TryWriteValueType( obj ) ){ + if ( t.IsGenericType ) { + List f = new List(); + Type list_type = f.GetType().GetGenericTypeDefinition(); +#if DEBUG + Console.WriteLine( "t.GetGenericTypeDefinition().Equals( list_type )=" + t.GetGenericTypeDefinition().Equals( list_type ) ); +#endif + if ( t.GetGenericTypeDefinition().Equals( list_type ) ) { + Type[] gen = t.GetGenericArguments(); +#if DEBUG + Console.WriteLine( "gen.Length=" + gen.Length ); +#endif + if ( gen.Length == 1 ) { + PropertyInfo count_property = t.GetProperty( "Count", typeof( int ) ); + int count = (int)count_property.GetValue( obj, new object[] { } ); +#if DEBUG + Console.WriteLine( "count=" + count ); + Console.WriteLine( "Properties" ); + foreach ( PropertyInfo pi in t.GetProperties() ) { + Console.WriteLine( " " + pi ); + } + Console.WriteLine( "Methods" ); + foreach ( MethodInfo mi in t.GetMethods() ) { + Console.WriteLine( " " + mi ); + } +#endif + Type returntype = gen[0]; + MethodInfo indexer = t.GetMethod( "get_Item", new Type[] { typeof( int ) } ); + string name = ""; + if ( returntype.Equals( typeof( Boolean ) ) ) { + name = "boolean"; + } else if ( returntype.Equals( typeof( DateTime ) ) ) { + name = "dateTime"; + } else if ( returntype.Equals( typeof( Decimal ) ) ) { + name = "decimal"; + } else if ( returntype.Equals( typeof( Double ) ) ) { + name = "double"; + } else if ( returntype.Equals( typeof( Int32 ) ) ) { + name = "int"; + } else if ( returntype.Equals( typeof( Int64 ) ) ) { + name = "long"; + } else if ( returntype.Equals( typeof( Single ) ) ) { + name = "float"; + } else if ( returntype.Equals( typeof( String ) ) ) { + name = "string"; + } else if ( returntype.IsEnum ) { + name = returntype.Name; + } + if ( indexer != null && name != "" ) { + for ( int i = 0; i < count; i++ ) { + object value = indexer.Invoke( obj, new object[] { i } ); + m_writer.WriteStartElement( name ); + TryWriteValueType( value ); + m_writer.WriteEndElement(); + } + } + } + } + } else { + foreach ( FieldInfo fi in t.GetFields() ) { + if ( fi.IsPrivate || fi.IsStatic ) { + continue; + } + object[] attr = fi.GetCustomAttributes( typeof( XmlItemDescription ), false ); + XmlItemDescription xid = null; + if ( attr.Length > 0 ) { + xid = (XmlItemDescription)attr[0]; + } + WriteContents( fi.Name, fi.GetValue( obj ), xid ); +#if DEBUG + m_writer.Flush(); +#endif + } + foreach ( PropertyInfo pi in t.GetProperties() ) { + if ( !pi.CanRead | !pi.CanWrite ) { + continue; + } + if ( !pi.GetSetMethod().IsPublic | !pi.GetGetMethod().IsPublic ) { + continue; + } + if ( pi.GetSetMethod().IsStatic | pi.GetGetMethod().IsStatic ) { + continue; + } + object[] attr = pi.GetCustomAttributes( typeof( XmlItemDescription ), false ); + XmlItemDescription xid = null; + if ( attr.Length > 0 ) { + xid = (XmlItemDescription)attr[0]; + } + WriteContents( pi.Name, pi.GetValue( obj, new object[] { } ), xid ); +#if DEBUG + m_writer.Flush(); +#endif + } + } + } + } + + private bool TryWriteValueType( object obj ) { + Type t = obj.GetType(); + if ( t.Equals( typeof( Boolean ) ) ) { + m_writer.WriteValue( (Boolean)obj ); + return true; + } else if ( t.Equals( typeof( DateTime ) ) ) { + m_writer.WriteValue( (DateTime)obj ); + return true; + } else if ( t.Equals( typeof( Decimal ) ) ) { + m_writer.WriteValue( (Decimal)obj ); + return true; + } else if ( t.Equals( typeof( Double ) ) ) { + m_writer.WriteValue( (Double)obj ); + return true; + } else if ( t.Equals( typeof( Int32 ) ) ) { + m_writer.WriteValue( (Int32)obj ); + return true; + } else if ( t.Equals( typeof( Int64 ) ) ) { + m_writer.WriteValue( (Int64)obj ); + return true; + } else if ( t.Equals( typeof( Single ) ) ) { + m_writer.WriteValue( (Single)obj ); + return true; + } else if ( t.Equals( typeof( String ) ) ) { + m_writer.WriteString( (String)obj ); + return true; + } else if ( t.IsEnum ) { + string val = Enum.GetName( t, obj ); + m_writer.WriteString( val ); + return true; + } else { + return false; + } + } + + private void WriteContents( string name, object next_obj, XmlItemDescription xid ) { + m_writer.WriteStartElement( name ); + if ( xid != null ) { + m_writer.WriteAttributeString( xid.AttributeName, xid.Value ); + } + PrintItemRecurse( next_obj ); + m_writer.WriteEndElement(); + } + + private void test() { + System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer( typeof( int ) ); + } + + } + +} diff --git a/trunk/Boare.Lib.AppUtil/XmlStaticMemberSerializer.cs b/trunk/Boare.Lib.AppUtil/XmlStaticMemberSerializer.cs new file mode 100644 index 0000000..08ffb75 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/XmlStaticMemberSerializer.cs @@ -0,0 +1,209 @@ +/* + * XmlStaticMemberSerializer.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.AppUtil. + * + * Boare.Lib.AppUtil is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.AppUtil is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Xml.Serialization; + +using Microsoft.CSharp; + +namespace Boare.Lib.AppUtil { + + /// + /// クラスのstaticメンバーのxmlシリアライズ/デシリアライズを行うclass + /// + public class XmlStaticMemberSerializer { + /// + /// ターゲットとなるクラスから,シリアライズするメンバーを抽出する時に使用 + /// + private class MemberEntry { + /// + /// プロパティ/フィールドの名前 + /// + public string Name; + /// + /// プロパティ/フィールドの型 + /// + public Type Type; + /// + /// プロパティ/フィールドのデフォルト値 + /// + public object Default; + + public MemberEntry( string name, Type type, object default_ ) { + Name = name; + Type = type; + Default = default_; + } + } + + /// + /// シリアライズする対象の型.staticメンバーだけなので,インスタンスではなく型を保持 + /// + private Type m_item; + /// + /// シリアライズ/デシリアライズするための内部型 + /// + private Type m_config_type = null; + /// + /// m_config_typeで初期化されたシリアライザ + /// + private XmlSerializer m_xs = null; + + private XmlStaticMemberSerializer() { + } + + /// + /// 指定された型をシリアライズするための初期化を行います + /// + /// + public XmlStaticMemberSerializer( Type item ) { + m_item = item; + } + + /// + /// シリアライズを行い,ストリームに書き込みます + /// + /// + public void Serialize( Stream stream ) { + if ( m_config_type == null ) { + GenerateConfigType(); + } + ConstructorInfo ci = m_config_type.GetConstructor( new Type[]{} ); + object config = ci.Invoke( new object[]{} ); + foreach ( FieldInfo target in m_config_type.GetFields() ) { + foreach ( PropertyInfo pi in m_item.GetProperties( BindingFlags.Public | BindingFlags.Static ) ) { + if ( target.Name == pi.Name && target.FieldType.Equals( pi.PropertyType ) && pi.CanRead && pi.CanWrite ) { + target.SetValue( config, pi.GetValue( m_item, new object[] { } ) ); + break; + } + } + foreach ( FieldInfo fi in m_item.GetFields( BindingFlags.Public | BindingFlags.Static ) ) { + if ( target.Name == fi.Name && target.FieldType.Equals( fi.FieldType ) ) { + target.SetValue( config, fi.GetValue( m_item ) ); + break; + } + } + } + m_xs.Serialize( stream, config ); + } + + /// + /// 指定したストリームを使って,デシリアライズを行います + /// + /// + public void Deserialize( Stream stream ) { + if ( m_config_type == null ) { + GenerateConfigType(); + } + object config = m_xs.Deserialize( stream ); + if ( config == null ) { + throw new ApplicationException( "failed serializing internal config object" ); + } + foreach ( FieldInfo target in m_config_type.GetFields() ) { + foreach ( PropertyInfo pi in m_item.GetProperties( BindingFlags.Public | BindingFlags.Static ) ) { + if ( target.Name == pi.Name && target.FieldType.Equals( pi.PropertyType ) && pi.CanRead && pi.CanWrite ) { + pi.SetValue( m_item, target.GetValue( config ), new object[] { } ); + break; + } + } + foreach ( FieldInfo fi in m_item.GetFields( BindingFlags.Public | BindingFlags.Static ) ) { + if ( target.Name == fi.Name && target.FieldType.Equals( fi.FieldType ) ) { + fi.SetValue( m_item, target.GetValue( config ) ); + break; + } + } + } + } + + /// + /// シリアライズ用の内部型をコンパイルし,m_xsが使用できるようにします + /// + private void GenerateConfigType() { + List config_names = CollectScriptConfigEntries( m_item ); + string code = GenerateClassCodeForXmlSerialization( config_names, m_item ); + CSharpCodeProvider provider = new CSharpCodeProvider(); + CompilerParameters parameters = new CompilerParameters(); + parameters.ReferencedAssemblies.Add( "System.Windows.Forms.dll" ); + parameters.ReferencedAssemblies.Add( "System.dll" ); + parameters.ReferencedAssemblies.Add( "System.Drawing.dll" ); + parameters.ReferencedAssemblies.Add( "System.Xml.dll" ); + parameters.GenerateInMemory = true; + parameters.GenerateExecutable = false; + parameters.IncludeDebugInformation = true; + CompilerResults results = provider.CompileAssemblyFromSource( parameters, code ); + Assembly asm = results.CompiledAssembly; + if ( asm.GetTypes().Length <= 0 ) { + m_config_type = null; + m_xs = null; + throw new ApplicationException( "failed generating internal xml serizlizer" ); + } else { + m_config_type = (asm.GetTypes())[0]; + m_xs = new XmlSerializer( m_config_type ); + } + } + + /// + /// 設定ファイルから読込むための型情報を蒐集 + /// + /// + /// + private static List CollectScriptConfigEntries( Type item ) { + List config_names = new List(); + foreach ( PropertyInfo pi in item.GetProperties( BindingFlags.Static | BindingFlags.Public ) ) { + object[] attrs = pi.GetCustomAttributes( true ); + foreach ( object obj in attrs ) { + if ( obj.GetType().Equals( typeof( System.Xml.Serialization.XmlIgnoreAttribute ) ) ) { + continue; + } + } + if ( pi.CanRead && pi.CanWrite ) { + config_names.Add( new MemberEntry( pi.Name, pi.PropertyType, pi.GetValue( item, new object[] { } ) ) ); + } + } + foreach ( FieldInfo fi in item.GetFields( BindingFlags.Static | BindingFlags.Public ) ) { + object[] attrs = fi.GetCustomAttributes( true ); + foreach ( object obj in attrs ) { + if ( obj.GetType().Equals( typeof( System.Xml.Serialization.XmlIgnoreAttribute ) ) ) { + continue; + } + } + config_names.Add( new MemberEntry( fi.Name, fi.FieldType, fi.GetValue( item ) ) ); + } + return config_names; + } + + /// + /// 指定した型から、Reflectionを使ってxmlシリアライズ用のクラスをコンパイルするためのC#コードを作成します + /// + /// + /// + private static string GenerateClassCodeForXmlSerialization( List config_names, Type item ) { + // XmlSerialization用の型を作成 + string code = ""; + code += "using System;\n"; + code += "namespace Boare.Lib.AppUtil{\n"; + code += " public class StaticMembersOf" + item.Name + "{\n"; + foreach ( MemberEntry entry in config_names ) { + code += " public " + entry.Type.ToString() + " " + entry.Name + ";\n"; + } + code += " }\n"; + code += "}\n"; + return code; + } + } + +} diff --git a/trunk/Boare.Lib.AppUtil/makefile b/trunk/Boare.Lib.AppUtil/makefile new file mode 100644 index 0000000..0087be8 --- /dev/null +++ b/trunk/Boare.Lib.AppUtil/makefile @@ -0,0 +1,17 @@ +OPT= +CP=cp +RM=rm + +Boare.Lib.AppUtil.dll: *.cs bocoree.dll + gmcs $(OPT) -recurse:*.cs -unsafe+ -target:library -out:Boare.Lib.AppUtil.dll \ + -r:bocoree.dll,System.Drawing,System.Windows.Forms + +bocoree.dll: ../bocoree/bocoree.dll + cp ../bocoree/bocoree.dll bocoree.dll + +../bocoree/bocoree.dll: + cd ../bocoree/ && $(MAKE) OPT=$(OPT) + +clean: + $(RM) Boare.Lib.AppUtil.dll + $(RM) bocoree.dll diff --git a/trunk/Boare.Lib.Media/AviReader.cs b/trunk/Boare.Lib.Media/AviReader.cs new file mode 100644 index 0000000..05312a6 --- /dev/null +++ b/trunk/Boare.Lib.Media/AviReader.cs @@ -0,0 +1,359 @@ +/* + * AviReader.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.IO; +using System.Windows.Forms; + +using bocoree; + +namespace Boare.Lib.Media { + + /// + /// Extract bitmaps from AVI files + /// + public class AviReader { + private int firstFrame = 0, countFrames = 0; + private int aviFile = 0; + private int getFrameObject; + private IntPtr aviStream; + private bool m_opened = false; + private AVISTREAMINFOW streamInfo; + private string m_fileName = ""; + + public string FileName { + get { + return m_fileName; + } + } + + public int CountFrames { + get { + return countFrames; + } + } + + public uint dwRate { + get { + return streamInfo.dwRate; + } + } + + public uint dwScale { + get { + return streamInfo.dwScale; + } + } + + [Obsolete] + public float FrameRate { + get { + return (float)streamInfo.dwRate / (float)streamInfo.dwScale; + } + } + + public Size BitmapSize { + get { + return new Size( (int)streamInfo.rect_right, (int)streamInfo.rect_bottom ); + } + } + + /// + /// Opens an AVI file and creates a GetFrame object + /// + /// Name of the AVI file + public void Open( string fileName ) { + //Intitialize AVI library + VFW.AVIFileInit(); + + //Open the file + int result = VFW.AVIFileOpenW( + ref aviFile, fileName, + (int)windows.OF_SHARE_DENY_WRITE, 0 ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIFileOpen: " + result.ToString() ); + } + + //Get the video stream + result = VFW.AVIFileGetStream( + aviFile, + out aviStream, + (int)VFW.streamtypeVIDEO, 0 ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIFileGetStream: " + result.ToString() ); + } + + firstFrame = VFW.AVIStreamStart( aviStream.ToInt32() ); + countFrames = VFW.AVIStreamLength( aviStream.ToInt32() ); + + streamInfo = new AVISTREAMINFOW(); + result = VFW.AVIStreamInfo( aviStream.ToInt32(), ref streamInfo, Marshal.SizeOf( streamInfo ) ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIStreamInfo: " + result.ToString() ); + } + + //Open frames + + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih.biBitCount = 24; + bih.biClrImportant = 0; + bih.biClrUsed = 0; + bih.biCompression = 0; //BI_RGB; + bih.biHeight = (Int32)streamInfo.rect_bottom; + bih.biWidth = (Int32)streamInfo.rect_right; + bih.biPlanes = 1; + bih.biSize = (UInt32)Marshal.SizeOf( bih ); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + + getFrameObject = VFW.AVIStreamGetFrameOpen( aviStream, ref bih ); //force function to return 24bit DIBS + //getFrameObject = Avi.AVIStreamGetFrameOpen(aviStream, 0); //return any bitmaps + if ( getFrameObject == 0 ) { + throw new Exception( "Exception in AVIStreamGetFrameOpen!" ); + } + m_opened = true; + m_fileName = fileName; + } + + /// Closes all streams, files and libraries + public void Close() { + if ( getFrameObject != 0 ) { + VFW.AVIStreamGetFrameClose( getFrameObject ); + getFrameObject = 0; + } + if ( aviStream != IntPtr.Zero ) { + VFW.AVIStreamRelease( aviStream ); + aviStream = IntPtr.Zero; + } + if ( aviFile != 0 ) { + VFW.AVIFileRelease( aviFile ); + aviFile = 0; + } + VFW.AVIFileExit(); + m_opened = false; + m_fileName = ""; + } + + + private void dispTime( string message, DateTime start ) { + DateTime current = DateTime.Now; + TimeSpan ts = current.Subtract( start ); + System.Diagnostics.Debug.WriteLine( message + "; " + ts.TotalSeconds + "s" ); + } + + + public bool Opened { + get { + return m_opened; + } + } + + + public void ExportToArray( int position, out byte[] bitmapData, out int width, out int height, out int bit_count ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + //Decompress the frame and return a pointer to the DIB + int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + //Copy the bitmap header into a managed struct + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + + //Copy the image + bitmapData = new byte[bih.biSizeImage]; + int address = pDib + Marshal.SizeOf( bih ); + Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); + width = bih.biWidth; + height = bih.biHeight; + bit_count = bih.biBitCount; + } + + + public Bitmap Export( int position ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + //Decompress the frame and return a pointer to the DIB + int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + if ( pDib == 0 ) { + //throw new Exception( "AVIStreamGetFrame; failed" ); + return null; + } + //Copy the bitmap header into a managed struct + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + Bitmap result = new Bitmap( bih.biWidth, bih.biHeight ); + BitmapData dat = result.LockBits( + new Rectangle( 0, 0, bih.biWidth, bih.biHeight ), + ImageLockMode.ReadWrite, + PixelFormat.Format24bppRgb ); + //Copy the image + int address = pDib + Marshal.SizeOf( bih ); + int length = dat.Stride * dat.Height; + byte[] target = new byte[length]; + Marshal.Copy( new IntPtr( address ), target, 0, length ); + Marshal.Copy( target, 0, dat.Scan0, length ); + result.UnlockBits( dat ); + result.RotateFlip( RotateFlipType.RotateNoneFlipY ); + return result; + } + + + public unsafe void ExportEx( Bitmap bmp, int position ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + //Decompress the frame and return a pointer to the DIB + int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + if ( pDib == 0 ) { + //throw new Exception( "AVIStreamGetFrame; failed" ); + return; + } + //Copy the bitmap header into a managed struct + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + BitmapData dat = bmp.LockBits( + new Rectangle( 0, 0, bih.biWidth, bih.biHeight ), + ImageLockMode.ReadWrite, + PixelFormat.Format24bppRgb ); + //Copy the image + int address = pDib + Marshal.SizeOf( bih ); + int length = dat.Stride * dat.Height; + CopyMemory( dat.Scan0, new IntPtr( address ), length ); + //Marshal.Copy( new IntPtr( address ), target, 0, length ); + //Marshal.Copy( target, 0, dat.Scan0, length ); + bmp.UnlockBits( dat ); + bmp.RotateFlip( RotateFlipType.RotateNoneFlipY ); + } + + + [DllImport( "kernel32.dll" )] + private static extern void CopyMemory( + IntPtr destination, IntPtr source, int length ); + + public unsafe void Export( Bitmap bmp, int position ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + //Decompress the frame and return a pointer to the DIB + int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + if ( pDib == 0 ) { + //throw new Exception( "AVIStreamGetFrame; failed" ); + return; + } + //Copy the bitmap header into a managed struct + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + BitmapData dat = bmp.LockBits( + new Rectangle( 0, 0, bih.biWidth, bih.biHeight ), + ImageLockMode.WriteOnly, + bmp.PixelFormat ); + //Copy the image + int address = pDib + Marshal.SizeOf( bih ); + int length = dat.Stride * dat.Height; + byte[] target = new byte[length]; + Marshal.Copy( new IntPtr( address ), target, 0, length ); + Marshal.Copy( target, 0, dat.Scan0, length ); + bmp.UnlockBits( dat ); + bmp.RotateFlip( RotateFlipType.RotateNoneFlipY ); + } + + + + /// Exports a frame into a bitmap file + /// Position of the frame + /// Name ofthe file to store the bitmap + public void ExportBitmap( int position, String dstFileName ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + + //Decompress the frame and return a pointer to the DIB + int pDib = VFW.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + //Copy the bitmap header into a managed struct + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih = (BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + + /*if(bih.biBitCount < 24){ + throw new Exception("Not enough colors! DIB color depth is less than 24 bit."); + }else */ + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + + //Copy the image + byte[] bitmapData = new byte[bih.biSizeImage]; + int address = pDib + Marshal.SizeOf( bih ); + for ( int offset = 0; offset < bitmapData.Length; offset++ ) { + bitmapData[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Copy bitmap info + byte[] bitmapInfo = new byte[Marshal.SizeOf( bih )]; + IntPtr ptr; + ptr = Marshal.AllocHGlobal( bitmapInfo.Length ); + Marshal.StructureToPtr( bih, ptr, false ); + address = ptr.ToInt32(); + for ( int offset = 0; offset < bitmapInfo.Length; offset++ ) { + bitmapInfo[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Create file header + BITMAPFILEHEADER bfh = new BITMAPFILEHEADER(); + bfh.bfType = Util.BMP_MAGIC_COOKIE; + bfh.bfSize = (Int32)(55 + bih.biSizeImage); //size of file as written to disk + bfh.bfReserved1 = 0; + bfh.bfReserved2 = 0; + bfh.bfOffBits = Marshal.SizeOf( bih ) + Marshal.SizeOf( bfh ); + + //Create or overwrite the destination file + FileStream fs = new FileStream( dstFileName, System.IO.FileMode.Create ); + BinaryWriter bw = new BinaryWriter( fs ); + + //Write header + bw.Write( bfh.bfType ); + bw.Write( bfh.bfSize ); + bw.Write( bfh.bfReserved1 ); + bw.Write( bfh.bfReserved2 ); + bw.Write( bfh.bfOffBits ); + //Write bitmap info + bw.Write( bitmapInfo ); + //Write bitmap data + bw.Write( bitmapData ); + bw.Close(); + fs.Close(); + } + } + +} diff --git a/trunk/Boare.Lib.Media/AviWriterVcm.cs b/trunk/Boare.Lib.Media/AviWriterVcm.cs new file mode 100644 index 0000000..4e4278c --- /dev/null +++ b/trunk/Boare.Lib.Media/AviWriterVcm.cs @@ -0,0 +1,550 @@ +/* + * AviWriter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; + +using bocoree; + +namespace Boare.Lib.Media { + + public unsafe class AviWriterVcm : IAviWriter { + private const long _THRESHOLD = 1000000000L; //AVIXリストの最大サイズ(byte) + private MainAVIHeader m_main_header; + private AVIStreamHeader m_stream_header; + private BinaryWriter m_stream; + private int m_current_chunk = 0; + private long m_position_in_chunk = 0L; + private long m_split_sreshold = 160000000L; //AVIリストの最大サイズ(byte) + private AVISTDINDEX m_std_index; + private AVISUPERINDEX m_super_index; + private int m_linesize;//bitmapの1行分のデータサイズ(byte) + private bool m_is_first = true; + private long m_riff_position;//"RIFF*"の*が記入されているファイルの絶対位置。RIFF-AVI のときは必ず4。RIFF-AVIXの時は変化する + private long m_movi_position; + private long m_next_framedata_position;//次に00dbデータを記入するべき場所 + private long m_avix_position; + private int m_junk_length; + private uint m_scale; + private uint m_rate; + private bool m_compressed = false; + private IntPtr m_hwnd = IntPtr.Zero; + private uint m_stream_fcc_handler = 808810089; + private string m_file; + //private int m_addr_compvar; + //private COMPVARS m_compvar; + private COMPVARS* m_compvar; + private BITMAPINFO* m_bitmapinfo_in; + private BITMAPINFO* m_bitmapinfo_out; + private IntPtr m_p_compvar; + private IntPtr m_p_bitmapinfo_in; + private IntPtr m_p_bitmapinfo_out; + private uint m_bih_compression = 0; + private long m_super_index_position; + private bool m_closed = false; + private bool m_opened = false; + private bool m_is_transparent = false; + /// + /// 現在記入中のmoviチャンクのサイズ + /// + private long m_this_movi_size = 0; + + private static bool s_vfw_bug_compati = false; + + public Size Size { + get { + return new Size( (int)m_main_header.dwWidth, (int)m_main_header.dwHeight ); + } + } + + public uint Scale { + get { + return m_scale; + } + } + + public uint Rate { + get { + return m_rate; + } + } + + /// + /// Video For Windows APIとバグコンパチブルな動作をするかどうかを表す値を取得または設定します + /// + public static bool VfwBugCompatible { + get { + return s_vfw_bug_compati; + } + set { + s_vfw_bug_compati = value; + } + } + + internal float frameRate { + get { + return (float)m_rate / (float)m_scale; + } + } + + /// + /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に, + /// ファイルにヘッダー情報を書き込みます. + /// + /// 書き込み対象のファイル + /// + /// + /// + public unsafe bool Open( string file, uint scale, uint rate, int width, int height, bool compressed, bool transparent, IntPtr hWnd ) { +#if DEBUG + Console.WriteLine( "AviWriterEx.Open(string,uint,uint,bool,IntPtr)" ); +#endif + m_stream = new BinaryWriter( new FileStream( file, FileMode.Create, FileAccess.Write ) ); + float fps = (float)rate / (float)scale; + m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);// ! 1秒は10^6μ秒 + m_main_header.dwReserved1 = 0; + m_main_header.dwFlags = 2064; + m_main_header.dwInitialFrames = 0; + m_main_header.dwStreams = 0; + m_main_header.dwScale = scale; + m_main_header.dwRate = rate; + m_main_header.dwStart = 0; + m_main_header.dwLength = 0; + m_rate = rate; + m_scale = scale; + Util.fwrite( "RIFF", m_stream ); + Util.WriteDWORD( 0, m_stream ); + Util.fwrite( "AVI ", m_stream ); + Util.fwrite( "LIST", m_stream ); + Util.WriteDWORD( 0x9cc, m_stream ); + Util.fwrite( "hdrl", m_stream ); + m_current_chunk = 0; + m_position_in_chunk = 0L; + m_std_index = new AVISTDINDEX( 0L ); + m_super_index = new AVISUPERINDEX( 0 ); + m_riff_position = 0x4; + m_compressed = compressed; + m_is_transparent = transparent; + m_stream_fcc_handler = 0; + m_hwnd = hWnd; + m_file = file; + m_opened = true; + if ( m_is_first ) { + int stride = 0; + using ( Bitmap b = new Bitmap( width, height, m_is_transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb ) ) { + BitmapData bd = b.LockBits( new Rectangle( 0, 0, width, height ), + ImageLockMode.ReadOnly, + b.PixelFormat ); + stride = bd.Stride; + b.UnlockBits( bd ); + } + m_is_first = false; + m_main_header.dwWidth = (uint)width; + m_main_header.dwHeight = (uint)height; + m_main_header.dwMaxBytesPerSec = (uint)(stride * height * frameRate); + m_main_header.dwStreams = 1; + m_main_header.dwSuggestedBufferSize = (uint)(stride * height); + m_linesize = stride; + + m_stream_header.fccType = Util.mmioFOURCC( "vids" ); + m_stream_header.fccHandler = 0; + m_stream_header.dwFlags = 0; + m_stream_header.dwReserved1 = 0; + m_stream_header.dwInitialFrames = 0; + m_stream_header.dwScale = m_scale; + m_stream_header.dwRate = m_rate; + m_stream_header.dwStart = 0; + m_stream_header.dwSuggestedBufferSize = m_main_header.dwSuggestedBufferSize; + m_stream_header.dwQuality = 0; + m_stream_header.dwSampleSize = 0; + + Util.aviWriteMainHeader( m_main_header, m_stream ); + + Util.fwrite( "LIST", m_stream ); + Util.WriteDWORD( 0x874, m_stream ); + Util.fwrite( "strl", m_stream ); + + Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream ); + + Util.fwrite( "strf", m_stream ); + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); + bih.biSize = (uint)(Marshal.SizeOf( bih )); + bih.biWidth = width; + bih.biHeight = height; + bih.biPlanes = 1; + bih.biBitCount = m_is_transparent ? (short)32 : (short)24; + bih.biCompression = 0;//BI_RGB + bih.biSizeImage = (uint)(stride * height); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + if ( m_compressed ) { + m_p_compvar = Marshal.AllocHGlobal( sizeof( COMPVARS ) ); + m_compvar = (COMPVARS*)m_p_compvar.ToPointer(); + byte[] buf = new byte[sizeof( COMPVARS )]; + for ( int i = 0; i < buf.Length; i++ ) { + buf[i] = 0x0; + } + Marshal.Copy( buf, 0, m_p_compvar, buf.Length ); + m_compvar->cbSize = sizeof( COMPVARS ); + int ret = VCM.ICCompressorChoose( m_hwnd, 0, IntPtr.Zero, IntPtr.Zero, m_compvar, "Select Video Compressor" ); + if ( ret == 0 ) { + m_opened = false; + Marshal.FreeHGlobal( m_p_compvar ); + m_stream.Close(); + return false; + } + if ( m_compvar->hic != 0 ) { + m_p_bitmapinfo_in = Marshal.AllocHGlobal( sizeof( BITMAPINFO ) ); + m_bitmapinfo_in = (BITMAPINFO*)m_p_bitmapinfo_in.ToPointer(); + buf = new byte[sizeof( BITMAPINFO )]; + for ( int i = 0; i < buf.Length; i++ ) { + buf[i] = 0x0; + } + Marshal.Copy( buf, 0, m_p_bitmapinfo_in, buf.Length ); + m_bitmapinfo_in->bmiHeader = bih; + uint dwSize = VCM.ICCompressGetFormatSize( m_compvar->hic, m_bitmapinfo_in ); +#if DEBUG + Console.WriteLine( "m_compvar->hic=" + m_compvar->hic ); + Console.WriteLine( "ICCompressGetFormatSize=" + dwSize ); +#endif + m_p_bitmapinfo_out = Marshal.AllocHGlobal( (int)dwSize ); + m_bitmapinfo_out = (BITMAPINFO*)m_p_bitmapinfo_out.ToPointer(); + buf = new byte[dwSize]; + for ( int i = 0; i < buf.Length; i++ ) { + buf[i] = 0x0; + } + Marshal.Copy( buf, 0, m_p_bitmapinfo_out, buf.Length ); + VCM.ICCompressGetFormat( m_compvar->hic, m_bitmapinfo_in, m_bitmapinfo_out ); + m_bih_compression = m_bitmapinfo_out->bmiHeader.biCompression; +#if DEBUG + Console.WriteLine( "AddFrame(Bitmap)" ); + Console.WriteLine( " biout.biSize=" + m_bitmapinfo_out->bmiHeader.biSize ); +#endif + VCM.ICSeqCompressFrameStart( m_compvar, m_bitmapinfo_in ); + bih = m_bitmapinfo_out->bmiHeader; + Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ + m_bitmapinfo_out->Write( m_stream ); + } else { + m_compressed = false; + Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ + bih.Write( m_stream ); + } + } else { + Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ + bih.Write( m_stream ); + } + + m_super_index_position = m_stream.BaseStream.Position; + Util.fwrite( "indx", m_stream ); //fcc + Util.WriteDWORD( 0x7f8, m_stream ); // cb + Util.WriteWORD( (byte)0x4, m_stream ); // wLongsPerEntry + Util.WriteBYTE( 0x0, m_stream ); // bIndexSubType + Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, m_stream );// bIndexType + Util.WriteDWORD( 0x0, m_stream ); // nEntriesInUse + Util.fwrite( "00db", m_stream ); // dwChunkId + Util.WriteDWORD( 0x0, m_stream ); + Util.WriteDWORD( 0x0, m_stream ); + Util.WriteDWORD( 0x0, m_stream ); + for ( int ii = 1; ii <= 126; ii++ ) { + Util.WriteQWORD( 0x0, m_stream ); + Util.WriteDWORD( 0x0, m_stream ); + Util.WriteDWORD( 0x0, m_stream ); + } + + Util.fwrite( "LIST", m_stream ); + Util.WriteDWORD( 0x104, m_stream ); + Util.fwrite( "odml", m_stream ); + Util.fwrite( "dmlh", m_stream ); + Util.WriteDWORD( 0xf8, m_stream ); + Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき + for ( int ii = 1; ii <= 61; ii++ ) { + Util.WriteDWORD( 0x0, m_stream ); + } + + Util.fwrite( "JUNK", m_stream ); + Util.WriteDWORD( 0x60c, m_stream ); + Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので + string msg = "This file was generated by AviWriter@Boare.Lib.Media;VfwBugCompatible=" + VfwBugCompatible; + const int tlen = 1544; + int remain = tlen - msg.Length; + Util.fwrite( msg, m_stream ); + for ( int i = 1; i <= remain; i++ ) { + m_stream.Write( (byte)0 ); + } + m_junk_length = 0xff4; + + Util.fwrite( "LIST", m_stream ); + m_movi_position = m_stream.BaseStream.Position; + Util.WriteDWORD( 0, m_stream );// call bmpQWordWrite( 0, avi%fp ) !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も + Util.fwrite( "movi", m_stream ); + m_next_framedata_position = m_stream.BaseStream.Position; + + m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); + m_super_index.nEntriesInUse++; + } + return true; + } + + public bool Open( string file, uint scale, uint rate, int width, int height, IntPtr hwnd ) { + return Open( file, scale, rate, width, height, false, false, hwnd ); + } + + //todo: AVIMainHeader.dwTotalFramesに、ファイル全体のフレーム数を入れる(仕様違反) + //todo: AVIStreamHeader.dwLengthに、ファイル全体のフレーム数を入れる(仕様違反) + /// + /// 全てのインデックスを更新し、ファイルが(動画ファイルとして)使用できる状態にします + /// この関数を読んだあとでも,さらにaviAddFrame関数を使うことでフレームを追加することが出来ます. + /// + public void UpdateIndex() { + _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk]; + entry.qwOffset = (ulong)m_stream.BaseStream.Position; + entry.dwSize = m_std_index.cb; + m_super_index.aIndex[m_current_chunk] = entry; + if ( m_stream.BaseStream.Position != m_next_framedata_position ) { + m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin ); + } + m_std_index.Write( m_stream ); + int frames = (int)m_super_index.aIndex[m_current_chunk].dwDuration; + m_avix_position = m_stream.BaseStream.Position; + + if ( m_current_chunk == 0 ) { + uint i, step, number; + step = m_main_header.dwSuggestedBufferSize + 8; + + Util.fwrite( "idx1", m_stream ); + Util.WriteDWORD( (uint)(16 * frames), m_stream ); + for ( i = 1; i <= frames; i++ ) { + Util.fwrite( "00db", m_stream ); + Util.WriteDWORD( Util.AVIF_HASINDEX, m_stream ); + Util.WriteDWORD( (uint)(4 + (i - 1) * step), m_stream ); + Util.WriteDWORD( m_main_header.dwSuggestedBufferSize, m_stream ); + } + m_avix_position = m_stream.BaseStream.Position; + + number = (uint)frames; + m_stream.Seek( 0x30, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + m_stream.Seek( 0x8c, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + + //odml dlmhのdwTotalFrames + m_stream.Seek( 0x8e8, SeekOrigin.Begin ); + Util.WriteDWORD( (uint)frames, m_stream ); + + // LIST****moviの****の数値を計算 + number = 4;//"movi" + number += (uint)(m_this_movi_size + 8 * frames);// (uint)(frames * (m_linesize * m_main_header.dwHeight + 8));//フレーム数*(フレームのサイズ+"00db"+00dbチャンクのサイズ) + number += 4 + 4 + (uint)m_std_index.cb; //ix00のサイズ + m_stream.BaseStream.Seek( m_movi_position, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + + //number = 4096 + (this.mainHeader.dwSuggestedBufferSize + 24) * this.noOfFrame; + //avi_writeIsolate( this.fp, number, 4 ); // RIFF****AVI の ****部分 + number = (uint)m_junk_length/* 0xff4*/; //JUNKの終わりまでのサイズ。これは固定 + number += 4;//"movi" + number += (uint)(m_this_movi_size + 8 * frames);//00db...の合計サイズ + number += 4 + 4 + (uint)m_std_index.cb; + number += (uint)(4 + 4 + 16 * frames);//idx1のサイズ + m_stream.BaseStream.Seek( m_riff_position, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + UpdateIndexOfIndex(); + } else { + // LIST****moviの****を更新 + uint number = 4; + number += (uint)(m_this_movi_size + frames * 8); + number += 8 + (uint)m_std_index.cb; + m_stream.BaseStream.Seek( m_movi_position, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + + // odml dlmhのdwTotalFrames + uint frames2 = 0; + for ( int j = 0; j <= m_current_chunk; j++ ) { + frames2 += (uint)m_super_index.aIndex[j].dwDuration; + } + m_stream.BaseStream.Seek( 0x8e8, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + m_stream.Seek( 48, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + m_stream.Seek( 140, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + //RIFF****AVIXの****を更新 + long num2 = m_junk_length + number; + m_stream.BaseStream.Seek( m_riff_position, SeekOrigin.Begin ); + Util.WriteDWORD( (uint)num2, m_stream ); + UpdateIndexOfIndex(); + } + } + + /// + /// aviファイルを閉じます + /// + public unsafe void Close() { + UpdateIndex(); + m_stream.Close(); + if ( m_compressed ) { + m_stream_fcc_handler = m_compvar->fccHandler; + VCM.ICSeqCompressFrameEnd( m_compvar ); + VCM.ICCompressorFree( m_compvar ); + using ( FileStream fs = new FileStream( m_file, FileMode.Open ) ) { + fs.Seek( 0x70, SeekOrigin.Begin ); + { + byte ch3 = (byte)(m_stream_fcc_handler >> 24); + uint b = (uint)(m_stream_fcc_handler - (ch3 << 24)); + byte ch2 = (byte)(b >> 16); + b = (uint)(b - (ch2 << 16)); + byte ch1 = (byte)(b >> 8); + byte ch0 = (byte)(b - (ch1 << 8)); + fs.Write( new byte[] { ch0, ch1, ch2, ch3 }, 0, 4 ); + } + fs.Seek( 0xbc, SeekOrigin.Begin ); + { + byte ch3 = (byte)(m_bih_compression >> 24); + uint b = (uint)(m_bih_compression - (ch3 << 24)); + byte ch2 = (byte)(b >> 16); + b = (uint)(b - (ch2 << 16)); + byte ch1 = (byte)(b >> 8); + byte ch0 = (byte)(b - (ch1 << 8)); + fs.Write( new byte[] { ch0, ch1, ch2, ch3 }, 0, 4 ); + } + } + } + m_closed = true; + } + + ~AviWriterVcm() { + if ( m_opened && !m_closed ) { + Close(); + } + } + + /// + /// 最初の[AVI :AVI[LIST:hdrl[LIST:strl]]]に書き込まれているsuper indexチャンク[indx]を更新します + /// + private void UpdateIndexOfIndex() { + m_stream.Seek( (int)m_super_index_position, SeekOrigin.Begin ); + m_super_index.Write( m_stream ); + } + + + /// + /// aviファイルにフレームを1つ追加します. + /// + /// + public unsafe void AddFrame( Bitmap bmp ) { + int width, height, lineSize; + BitmapData bmpDat; + if ( m_is_transparent ) { + bmpDat = bmp.LockBits( new Rectangle( 0, 0, bmp.Width, bmp.Height ), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb ); + } else { + bmpDat = bmp.LockBits( new Rectangle( 0, 0, (int)bmp.Width, (int)bmp.Height ), + ImageLockMode.ReadOnly, + PixelFormat.Format24bppRgb ); + } + + if ( m_next_framedata_position != m_stream.BaseStream.Position ) { + m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin ); + } + + long chunk_size = m_next_framedata_position - m_riff_position; + if ( (m_current_chunk == 0 && chunk_size > m_split_sreshold) || + (m_current_chunk > 0 && chunk_size > _THRESHOLD) ) { + // AVIXリストへの書き込みに移行 + UpdateIndex(); + m_stream.BaseStream.Seek( m_avix_position, SeekOrigin.Begin ); + Util.fwrite( "RIFF", m_stream ); + m_riff_position = m_stream.BaseStream.Position; + Util.WriteDWORD( 0, m_stream ); + Util.fwrite( "AVIX", m_stream ); + long current = m_stream.BaseStream.Position; + if ( (current + 12) % 0x800 != 0 ) { + long additional = (current + 20) % 0x800; + additional = 0x800 - ((current + 20) % 0x800); + m_junk_length = (int)additional + 20; + Util.fwrite( "JUNK", m_stream ); + Util.WriteDWORD( (uint)additional, m_stream ); + for ( long ii = 0; ii < additional; ii++ ) { + Util.WriteBYTE( (byte)0, m_stream ); + } + } else { + m_junk_length = 0; + } + m_junk_length = 0; + + Util.fwrite( "LIST", m_stream ); + m_movi_position = m_stream.BaseStream.Position; + Util.WriteDWORD( 0, m_stream );//後で更新するべき + Util.fwrite( "movi", m_stream ); + m_next_framedata_position = m_stream.BaseStream.Position; + m_std_index.aIndex.Clear(); + m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); + m_current_chunk++; + m_super_index.nEntriesInUse++; + } + + // フレームを書き込む処理 + width = (int)m_main_header.dwWidth; + height = (int)m_main_header.dwHeight; + if ( width != bmpDat.Width ) { + return; + } + if ( height != bmpDat.Height ) { + return; + } + lineSize = bmpDat.Stride; + + if ( m_compressed ) { + int is_key_frame = 0; + int size = bmpDat.Stride * bmpDat.Height; + try { + IntPtr dat = VCM.ICSeqCompressFrame( m_compvar, 0, bmpDat.Scan0, &is_key_frame, &size ); + if ( !dat.Equals( IntPtr.Zero ) ) { + byte[] ndat = new byte[size]; + Marshal.Copy( dat, ndat, 0, size ); + m_std_index.AddIndex( (uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)size ); + Util.fwrite( "00db", m_stream ); + Util.WriteDWORD( (uint)size, m_stream ); + m_stream.Write( ndat, 0, size ); + m_this_movi_size += size; + } + } catch { + } + } else { + m_std_index.AddIndex( (uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)(lineSize * height) ); + Util.fwrite( "00db", m_stream ); + int address = bmpDat.Scan0.ToInt32(); + byte[] bitmapData = new byte[bmpDat.Stride * bmpDat.Height]; + Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); + Util.WriteDWORD( m_main_header.dwSuggestedBufferSize, m_stream ); + m_stream.Write( bitmapData ); + m_this_movi_size += bitmapData.Length; + } + m_next_framedata_position = m_stream.BaseStream.Position; + _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk]; + entry.dwDuration++; + m_super_index.aIndex[m_current_chunk] = entry; + m_stream.Flush(); + bmp.UnlockBits( bmpDat ); + } + } +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Media/AviWriterVfw.cs b/trunk/Boare.Lib.Media/AviWriterVfw.cs new file mode 100644 index 0000000..6834316 --- /dev/null +++ b/trunk/Boare.Lib.Media/AviWriterVfw.cs @@ -0,0 +1,496 @@ +/* + * VfwAviWriter.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.IO; + +namespace Boare.Lib.Media { + + public class AviWriterVfw : IAviWriter { + private int m_file_handle = 0; + private IntPtr m_video = new IntPtr( 0 ); + private IntPtr m_video_compressed = new IntPtr( 0 ); + private IntPtr m_audio = new IntPtr( 0 ); + private IntPtr m_audio_compressed = new IntPtr( 0 ); + private uint m_scale; + private uint m_rate; + private int m_count = 0; + private UInt32 m_width = 0; + private UInt32 m_stride = 0; + private UInt32 m_height = 0; + private static readonly UInt32 _STREAM_TYPE_VIDEO = (UInt32)mmioFOURCC( 'v', 'i', 'd', 's' ); + private static readonly UInt32 _STREAM_TYPE_AUDIO = (UInt32)mmioFOURCC( 'a', 'u', 'd', 's' ); + private uint m_strh_fcc = 0; + private string m_file = ""; + + private const int OF_READ = 0; + private const int OF_READWRITE = 2; + private const int OF_WRITE = 1; + private const int OF_SHARE_COMPAT = 0; + private const int OF_SHARE_DENY_NONE = 64; + private const int OF_SHARE_DENY_READ = 48; + private const int OF_SHARE_DENY_WRITE = 32; + private const int OF_SHARE_EXCLUSIVE = 16; + private const int OF_CREATE = 4096; + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + private struct AVISTREAMINFOW { + public UInt32 fccType, fccHandler, dwFlags, dwCaps; + + public UInt16 wPriority, wLanguage; + + public UInt32 dwScale, dwRate, + dwStart, dwLength, dwInitialFrames, dwSuggestedBufferSize, + dwQuality, dwSampleSize, rect_left, rect_top, + rect_right, rect_bottom, dwEditCount, dwFormatChangeCount; + public UInt16 szName0, szName1, szName2, szName3, szName4, szName5, + szName6, szName7, szName8, szName9, szName10, szName11, + szName12, szName13, szName14, szName15, szName16, szName17, + szName18, szName19, szName20, szName21, szName22, szName23, + szName24, szName25, szName26, szName27, szName28, szName29, + szName30, szName31, szName32, szName33, szName34, szName35, + szName36, szName37, szName38, szName39, szName40, szName41, + szName42, szName43, szName44, szName45, szName46, szName47, + szName48, szName49, szName50, szName51, szName52, szName53, + szName54, szName55, szName56, szName57, szName58, szName59, + szName60, szName61, szName62, szName63; + } + + // vfw.h + [Serializable] + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct AVICOMPRESSOPTIONS { + public UInt32 fccType; + public UInt32 fccHandler; + public UInt32 dwKeyFrameEvery; // only used with AVICOMRPESSF_KEYFRAMES + public UInt32 dwQuality; + public UInt32 dwBytesPerSecond; // only used with AVICOMPRESSF_DATARATE + public UInt32 dwFlags; + public IntPtr lpFormat; + public UInt32 cbFormat; + public IntPtr lpParms; + public UInt32 cbParms; + public UInt32 dwInterleaveEvery; + public override string ToString() { + return "fccType=" + fccType + "\n" + + "fccHandler=" + fccHandler + "\n" + + "dwKeyFrameEvery=" + dwKeyFrameEvery + "\n" + + "dwQuality=" + dwQuality + "\n" + + "dwBytesPerSecond=" + dwBytesPerSecond + "\n" + + "dwFlags=" + dwFlags + "\n" + + "lpFormat=" + lpFormat + "\n" + + "cbFormat=" + cbFormat + "\n" + + "lpParms=" + lpParms + "\n" + + "cbParms=" + cbParms + "\n" + + "dwInterleaveEvery=" + dwInterleaveEvery; + } + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct BITMAPINFOHEADER { + public UInt32 biSize; + public Int32 biWidth; + public Int32 biHeight; + public Int16 biPlanes; + public Int16 biBitCount; + public UInt32 biCompression; + public UInt32 biSizeImage; + public Int32 biXPelsPerMeter; + public Int32 biYPelsPerMeter; + public UInt32 biClrUsed; + public UInt32 biClrImportant; + } + + public Size Size { + get { + return new Size( (int)m_width, (int)m_height ); + } + } + + public uint Scale { + get { + return m_scale; + } + } + + public uint Rate { + get { + return m_rate; + } + } + + public class AviException : ApplicationException { + public AviException( string s ) + : base( s ) { + } + public AviException( string s, Int32 hr ) + : base( s ) { + + if ( hr == AVIERR_BADPARAM ) { + err_msg = "AVIERR_BADPARAM"; + } else { + err_msg = "unknown"; + } + } + + public string ErrMsg() { + return err_msg; + } + private const Int32 AVIERR_BADPARAM = -2147205018; + private string err_msg; + } + + public bool Open( string file_name, uint scale, uint rate, int width, int height, IntPtr hwnd ) { + m_file = file_name; + this.m_scale = scale; + this.m_rate = rate; + this.m_width = (UInt32)width; + this.m_height = (UInt32)height; + using ( Bitmap bmp = new Bitmap( width, height, PixelFormat.Format24bppRgb ) ) { + BitmapData bmpDat = bmp.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb ); + this.m_stride = (UInt32)bmpDat.Stride; + bmp.UnlockBits( bmpDat ); + } + AVIFileInit(); + int hr = AVIFileOpenW( ref m_file_handle, file_name, OF_WRITE | OF_CREATE, 0 ); + if ( hr != 0 ) { + throw new AviException( "error for AVIFileOpenW" ); + } + + CreateStream(); + return SetOptions( hwnd ); + } + + public void AddFrame( Bitmap bmp ) { + BitmapData bmpDat = bmp.LockBits( new Rectangle( 0, 0, (int)m_width, (int)m_height ), + ImageLockMode.ReadOnly, + PixelFormat.Format24bppRgb ); + + int hr = AVIStreamWrite( m_video_compressed, m_count, 1, + bmpDat.Scan0, + (Int32)(m_stride * m_height), + 0, + 0, + 0 ); + + if ( hr != 0 ) { + throw new AviException( "AVIStreamWrite" ); + } + + bmp.UnlockBits( bmpDat ); + + m_count++; + } + + unsafe public static AVICOMPRESSOPTIONS RequireVideoCompressOption( AVICOMPRESSOPTIONS current_option ) { + AviWriterVfw temp = new AviWriterVfw(); + temp.m_scale = 1000; + temp.m_rate = 30 * temp.m_scale; + int width = 10, height = 10; + temp.m_width = (UInt32)width; + temp.m_height = (UInt32)height; + using ( Bitmap bmp = new Bitmap( width, height, PixelFormat.Format24bppRgb ) ) { + BitmapData bmpDat = bmp.LockBits( new Rectangle( 0, 0, width, height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb ); + temp.m_stride = (UInt32)bmpDat.Stride; + bmp.UnlockBits( bmpDat ); + } + AVIFileInit(); + string temp_file = Path.GetTempFileName() + ".avi";// .aviを付けないと、AVIFileOpenWが失敗する + int hr = AVIFileOpenW( ref temp.m_file_handle, temp_file, OF_WRITE | OF_CREATE, 0 ); + if ( hr != 0 ) { + throw new AviException( "error for AVIFileOpenW" ); + } + + temp.CreateStream(); + + AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); + opts.fccType = 0; //fccType_; + opts.fccHandler = 0;//fccHandler_; + opts.dwKeyFrameEvery = 0; + opts.dwQuality = 0; // 0 .. 10000 + opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 + opts.dwBytesPerSecond = 0; + opts.lpFormat = new IntPtr( 0 ); + opts.cbFormat = 0; + opts.lpParms = new IntPtr( 0 ); + opts.cbParms = 0; + opts.dwInterleaveEvery = 0; + + opts = current_option; + AVICOMPRESSOPTIONS* p = &opts; + AVICOMPRESSOPTIONS** pp = &p; + IntPtr x = temp.m_video; + IntPtr* ptr_ps = &x; + AVISaveOptions( IntPtr.Zero, 0, 1, ptr_ps, pp ); + //MessageBox.Show( "AVISaveOptions ok" ); + AVICOMPRESSOPTIONS copied = new AVICOMPRESSOPTIONS(); + copied = opts; + AVIStreamRelease( temp.m_video ); + //MessageBox.Show( "AVIStreamRelease(temp.m_video) ok" ); + + AVIFileRelease( temp.m_file_handle ); + //MessageBox.Show( "AVIFileRelease ok" ); + AVIFileExit(); + //MessageBox.Show( "AVIFileExit ok" ); + File.Delete( temp_file ); + //MessageBox.Show( "File.Delete(fileName) ok" ); + return copied; + } + + /// + /// オーディオ圧縮の設定ダイアログを表示し、オーディオ圧縮の設定を取得します + /// + /// + unsafe public static AVICOMPRESSOPTIONS RequireAudioCompressOption() { + string temp_file = Path.GetTempFileName(); + byte[] buf = new byte[] { + 82, 73, 70, 70, 94, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, + 0, 1, 0, 64, 31, 0, 0, 64, 31, 0, 0, 1, 0, 8, 0, 100, 97, 116, 97, 58, 0, 0, 0, + 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, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + }; + using ( FileStream fs = new FileStream( temp_file, FileMode.Create ) ) { + fs.Write( buf, 0, buf.Length ); + } + + AVIFileInit(); + //MessageBox.Show( "AVIFileInit ok" ); + IntPtr audio; + int hr = AVIStreamOpenFromFileW( out audio, temp_file, _STREAM_TYPE_AUDIO, 0, OF_READ, 0 ); + //MessageBox.Show( "AVIStreamOpenFromFileW ok" ); + + AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); + opts.fccType = _STREAM_TYPE_AUDIO; //fccType_; + opts.fccHandler = 0;//fccHandler_; + opts.dwKeyFrameEvery = 0; + opts.dwQuality = 0; // 0 .. 10000 + opts.dwFlags = 0; // AVICOMRPESSF_KEYFRAMES = 4 + opts.dwBytesPerSecond = 0; + opts.lpFormat = new IntPtr( 0 ); + opts.cbFormat = 0; + opts.lpParms = new IntPtr( 0 ); + opts.cbParms = 0; + opts.dwInterleaveEvery = 0; + AVICOMPRESSOPTIONS* p = &opts; + AVICOMPRESSOPTIONS** pp = &p; + IntPtr x = audio; + IntPtr* ptr_ps = &x; + AVISaveOptions( IntPtr.Zero, 0, 1, ptr_ps, pp ); + //MessageBox.Show( "AVISaveOptions ok" ); + AVICOMPRESSOPTIONS copied = new AVICOMPRESSOPTIONS(); + copied = opts; + AVIStreamRelease( audio ); + //MessageBox.Show( "AVIStreamRelease(audio) ok" ); + + AVIFileExit(); + //MessageBox.Show( "AVIFileExit ok" ); + File.Delete( temp_file ); + return copied; + } + + public void Close() { + AVIStreamRelease( m_video ); + AVIStreamRelease( m_video_compressed ); + AVIFileRelease( m_file_handle ); + AVIFileExit(); + using ( FileStream fs = new FileStream( m_file, FileMode.Open ) ) { + fs.Seek( 0x70, SeekOrigin.Begin ); + byte ch3 = (byte)(m_strh_fcc >> 24); + uint b = (uint)(m_strh_fcc - (ch3 << 24)); + byte ch2 = (byte)(b >> 16); + b = (uint)(b - (ch2 << 16)); + byte ch1 = (byte)(b >> 8); + byte ch0 = (byte)(b - (ch1 << 8)); + fs.Write( new byte[] { ch0, ch1, ch2, ch3 }, 0, 4 ); + } + } + + private void CreateStream() { + // video stream + AVISTREAMINFOW strhdr = new AVISTREAMINFOW(); + strhdr.fccType = _STREAM_TYPE_VIDEO; + strhdr.fccHandler = 0;// fccHandler_; + strhdr.dwFlags = 0; + strhdr.dwCaps = 0; + strhdr.wPriority = 0; + strhdr.wLanguage = 0; + strhdr.dwScale = m_scale; + strhdr.dwRate = m_rate; + strhdr.dwStart = 0; + strhdr.dwLength = 0; + strhdr.dwInitialFrames = 0; + strhdr.dwSuggestedBufferSize = m_height * m_stride; + strhdr.dwQuality = 0xffffffff; + strhdr.dwSampleSize = 0; + strhdr.rect_top = 0; + strhdr.rect_left = 0; + strhdr.rect_bottom = m_height; + strhdr.rect_right = m_width; + strhdr.dwEditCount = 0; + strhdr.dwFormatChangeCount = 0; + strhdr.szName0 = 0; + strhdr.szName1 = 0; + int hr = AVIFileCreateStream( m_file_handle, out m_video, ref strhdr ); + if ( hr != 0 ) { + throw new AviException( "AVIFileCreateStream; Video" ); + } +#if DEBUG + Console.WriteLine( "AviWrierVfw+CreateStream" ); + Console.WriteLine( " strhdr.fccHandler=" + strhdr.fccHandler ); +#endif + } + + internal static void CalcScaleAndRate( decimal fps, out uint scale, out uint rate ) { + scale = 100; + rate = (uint)(fps * 1000m); + int max = (int)(Math.Log10( uint.MaxValue )); + for ( int i = 0; i <= max; i++ ) { + scale = (uint)pow10( i ); + rate = (uint)(fps * scale); + decimal t_fps = (decimal)rate / (decimal)scale; + if ( t_fps == fps ) { + return; + } + } + } + + private static int pow10( int x ) { + int result = 1; + for ( int i = 1; i <= x; i++ ) { + result = result * 10; + } + return result; + } + + unsafe private bool SetOptions( IntPtr hwnd ) { + // VIDEO + AVICOMPRESSOPTIONS opts = new AVICOMPRESSOPTIONS(); + opts.fccType = 0; + opts.fccHandler = 0; + opts.dwKeyFrameEvery = 0; + opts.dwQuality = 0; + opts.dwFlags = 0; + opts.dwBytesPerSecond = 0; + opts.lpFormat = new IntPtr( 0 ); + opts.cbFormat = 0; + opts.lpParms = new IntPtr( 0 ); + opts.cbParms = 0; + opts.dwInterleaveEvery = 0; + + AVICOMPRESSOPTIONS* p = &opts; + AVICOMPRESSOPTIONS** pp; + pp = &p; + IntPtr x = m_video; + IntPtr* ptr_ps; + ptr_ps = &x; + if ( AVISaveOptions( hwnd, 0, 1, ptr_ps, pp ) == 0 ) { + return false; + } + int hr = AVIMakeCompressedStream( out m_video_compressed, m_video, ref opts, 0 ); + if ( hr != 0 ) { + throw new AviException( "AVIMakeCompressedStream; Video" ); + } + m_strh_fcc = opts.fccHandler; +#if DEBUG + Console.WriteLine( "AviWriterVfw+SetOptions" ); + Console.WriteLine( " opts.fccHandler=" + opts.fccHandler ); +#endif + + // TODO: AVISaveOptionsFree(...) + BITMAPINFO bi = new BITMAPINFO(); + bi.bmiHeader.biSize = 40; + bi.bmiHeader.biWidth = (Int32)m_width; + bi.bmiHeader.biHeight = (Int32)m_height; + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 24; + bi.bmiHeader.biCompression = 0; + bi.bmiHeader.biSizeImage = m_stride * m_height; + bi.bmiHeader.biXPelsPerMeter = 0; + bi.bmiHeader.biYPelsPerMeter = 0; + bi.bmiHeader.biClrUsed = 0; + bi.bmiHeader.biClrImportant = 0; + + hr = AVIStreamSetFormat( m_video_compressed, 0, ref bi, sizeof( BITMAPINFO ) ); + if ( hr != 0 ) { + throw new AviException( "AVIStreamSetFormat", hr ); + } +#if DEBUG + Console.WriteLine( " bi.bmiHeader.biCompression=" + bi.bmiHeader.biCompression ); +#endif + return true; + } + + [DllImport( "avifil32.dll" )] + private static extern int AVIStreamOpenFromFileW( out IntPtr ppavi, + [MarshalAs( UnmanagedType.LPWStr )]string szfile, + uint fccType, + int lParam, + int mode, + int dumy ); + + [DllImport( "avifil32.dll" )] + private static extern void AVIFileInit(); + + [DllImport( "avifil32.dll" )] + private static extern int AVIFileOpenW( ref int ptr_pfile, + [MarshalAs( UnmanagedType.LPWStr )]string fileName, + int flags, + int dummy ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIFileCreateStream( + int ptr_pfile, out IntPtr ptr_ptr_avi, ref AVISTREAMINFOW ptr_streaminfo ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIMakeCompressedStream( + out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS ao, int dummy ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIStreamSetFormat( + IntPtr aviStream, Int32 lPos, ref BITMAPINFO lpFormat, Int32 cbFormat ); + + [DllImport( "avifil32.dll" )] + unsafe private static extern int AVISaveOptions( + IntPtr hwnd, UInt32 flags, int nStreams, IntPtr* ptr_ptr_avi, AVICOMPRESSOPTIONS** ao ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIStreamWrite( IntPtr aviStream, + Int32 lStart, + Int32 lSamples, + IntPtr lpBuffer, + Int32 cbBuffer, + Int32 dwFlags, + Int32 dummy1, + Int32 dummy2 ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIStreamRelease( IntPtr aviStream ); + + [DllImport( "avifil32.dll" )] + private static extern int AVIFileRelease( int pfile ); + + [DllImport( "avifil32.dll" )] + private static extern void AVIFileExit(); + + public static Int32 mmioFOURCC( char ch0, char ch1, char ch2, char ch3 ) { + return ((Int32)(byte)(ch0) | ((byte)(ch1) << 8) | ((byte)(ch2) << 16) | ((byte)(ch3) << 24)); + } + } + +} diff --git a/trunk/Boare.Lib.Media/Boare.Lib.Media.csproj b/trunk/Boare.Lib.Media/Boare.Lib.Media.csproj new file mode 100644 index 0000000..e9938f6 --- /dev/null +++ b/trunk/Boare.Lib.Media/Boare.Lib.Media.csproj @@ -0,0 +1,92 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452} + Library + Properties + Boare.Lib.Media + Boare.Lib.Media + + + 2.0 + v2.0 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + Boare.Lib.Media.xml + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + Boare.Lib.Media.xml + + + x86 + bin\x86\Debug\ + true + DEBUG + bin\x86\Debug\Boare.Lib.Media.XML + + + x86 + bin\x86\Release\ + true + bin\x86\Release\Boare.Lib.Media.XML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {C8AAE632-9C6C-4372-8175-811528A66742} + bocoree + + + + + \ No newline at end of file diff --git a/trunk/Boare.Lib.Media/IAviWriter.cs b/trunk/Boare.Lib.Media/IAviWriter.cs new file mode 100644 index 0000000..906549e --- /dev/null +++ b/trunk/Boare.Lib.Media/IAviWriter.cs @@ -0,0 +1,34 @@ +/* + * IAviWriter.cs + * Copyright (c) 2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace Boare.Lib.Media { + + public interface IAviWriter { + void AddFrame( Bitmap frame ); + void Close(); + bool Open( string file, uint scale, uint rate, int width, int height, IntPtr hwnd ); + Size Size { + get; + } + uint Scale { + get; + } + uint Rate { + get; + } + } + +} diff --git a/trunk/Boare.Lib.Media/MediaPlayer.cs b/trunk/Boare.Lib.Media/MediaPlayer.cs new file mode 100644 index 0000000..fd20f96 --- /dev/null +++ b/trunk/Boare.Lib.Media/MediaPlayer.cs @@ -0,0 +1,416 @@ +/* + * MediaPlayer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace Boare.Lib.Media { + + /// + /// Sound player using mciSendSring command operation + /// + public class MediaPlayer : IDisposable { + private string m_filename = ""; + const int FALSE = 0; + const int TRUE = 1; + bool pausing = false; + int m_volume = 1000; + bool mute = false; + string m_alias = ""; + bool m_loaded = false; + float m_speed = 1.0f; + bool m_playing = false; + /// + /// the number of Load failure + /// + int m_load_failed = 0; + + ~MediaPlayer() { + Dispose(); + } + + public void Dispose() { + if ( m_loaded ) { + Close(); + } + m_playing = false; + } + + /// + /// Gets or Sets the speed + /// + public float Speed { + get { + return m_speed; + } + set { + m_speed = value; + SetSpeed( m_speed ); + } + } + + /// + /// Sets the speed + /// + /// the value of speed to set + private void SetSpeed( float speed ) { + w_mciSendString( "set " + m_alias + " speed " + (int)(speed * 1000.0f) ); + } + + /// + /// Gets or Sets the volume (0 >= volume >= 1000) + /// + public int Volume { + get { + if ( mute ) { + return 0; + } else { + return m_volume; + } + } + set { + m_volume = value; + SetVolume( m_volume ); + } + } + + /// + /// Sets the volume (0 >= volume >= 1000) + /// + /// + private void SetVolume( int value ) { + ReLoad(); + w_mciSendString( "setaudio " + m_alias + " volume to " + value ); + } + + /// + /// Gets the volume (0 <= volume <= 1000) + /// + /// + private int GetVolume() { + ReLoad(); + string str; + bool ret = w_mciSendString( "status " + m_alias + " volume", out str ); + int v = m_volume; + if ( ret ) { + int v1; + if ( int.TryParse( str, out v1 ) ) { + v = v1; + } + } +#if DEBUG + Console.WriteLine( "MediaPlayer+GetVolume()" ); + Console.WriteLine( " str=" + str ); + Console.WriteLine( " volume=" + v ); +#endif + return v; + } + + /// + /// Gets or Sets whether sound is muted or not + /// + public bool IsMuted { + get { + return mute; + } + set { + bool old = mute; + mute = value; + if ( old != mute ) { + if ( mute ) { + SetVolume( 0 ); + } else { + SetVolume( m_volume ); + } + } + } + } + + /// + /// Gets the pass of the sound file + /// + public string SoundLocation { + get { + return m_filename; + } + } + + /// + /// external declaration of mciSendString + /// + /// Command String + /// Return String + /// Return String Size + /// Callback Hwnd + /// true when successed, false if not + [DllImport( "winmm.dll" )] + extern static int mciSendString( string s1, StringBuilder s2, int i1, int i2 ); + + /// + /// mciSendString wrapper with exception handling + /// + /// command sending to MCI + /// returned string of mciSendString + /// command successedd or not + static bool w_mciSendString( string command, out string result ) { + StringBuilder sb = new StringBuilder( 32 ); + int io_status = 0; + result = ""; + try { + io_status = mciSendString( command, sb, sb.Capacity, 0 ); + result = sb.ToString(); + } catch { + return false; + } + if ( io_status == 0 ) { + return true; + } else { + return false; + } + } + + static bool w_mciSendString( string command ) { + string ret; + return w_mciSendString( command, out ret ); + } + + /// + /// Closes sound file temporary + /// + /// + public void UnLoad() { + if ( m_filename != "" ) { + Stop(); + w_mciSendString( "close " + m_alias ); + m_loaded = false; + } + } + + /// + /// Opens sound file which was closed with "UnLoad" method + /// + /// + public void ReLoad() { + if ( m_filename != "" && !m_loaded && m_load_failed < 10 ) { + if ( Load( m_filename ) ) { + m_loaded = true; + if ( mute ) { + SetVolume( 0 ); + } else { + SetVolume( m_volume ); + } + } + } + } + + /// + /// Opens sound file + /// + /// Path of sound file to open + /// successed opening the file or not + public bool Load( string filename ) { +#if DEBUG + Console.WriteLine( "MediaPlayer+Load(String)" ); + Console.WriteLine( " filename=" + filename ); +#endif + if ( m_filename != "" ) { + Close(); + } + this.m_filename = filename; + m_alias = bocoree.misc.getmd5( m_filename ); +#if DEBUG + Console.WriteLine( " m_alias=" + m_alias ); +#endif + bool ret = w_mciSendString( "open \"" + filename + "\" type MPEGVIDEO2 alias " + m_alias ); + if ( !ret ) { + ret = w_mciSendString( "open \"" + filename + "\" type MPEGVIDEO alias " + m_alias ); + if ( !ret ) { + ret = w_mciSendString( "open \"" + filename + "\" alias " + m_alias ); + } + } +#if DEBUG + Console.WriteLine( " w_mciSendString result=" + ret ); +#endif + if ( ret ) { + m_loaded = true; + } else { + m_load_failed++; + } +#if DEBUG + m_volume = GetVolume(); + Console.WriteLine( " m_volume=" + m_volume ); +#endif + SetVolume( m_volume ); + return ret; + } + + /// + /// Plays sound from specified second + /// + /// Sound position start to play + /// true if play command successed + public bool PlayFrom( double time ) { + if ( m_filename == "" ) { + return false; + } + long position = (long)(time * 1000); + if ( !m_loaded ) { + ReLoad(); + } + /*if ( mute ) { + EnterMute(); + } else { + ExitMute(); + }*/ + SetSpeed( m_speed ); + m_playing = true; + return w_mciSendString( "play " + m_alias + " from " + position.ToString() ); + } + + /// + /// Closes sound file + /// + /// true if successed closing sound file + public bool Close() { + if ( m_filename == "" ) { + return false; + } + Stop(); + m_filename = ""; + m_loaded = false; + return w_mciSendString( "close " + m_alias ); + } + + /// + /// Plays sound from time 0 second + /// + /// true if successed to play + public bool Play() { + if ( m_filename == "" ) { + return false; + } + if ( !m_loaded ) { + ReLoad(); + } + /*if ( mute ) { + EnterMute(); + } else { + ExitMute(); + }*/ + SetSpeed( m_speed ); + m_playing = true; + if ( pausing ) { + //return w_mciSendString( "resume \"" + m_filename + "\"", null, 0, 0 ); + return w_mciSendString( "resume " + m_alias ); + } else { + //return w_mciSendString( "play \"" + m_filename + "\"", null, 0, 0 ); + return w_mciSendString( "play " + m_alias ); + } + } + + /// + /// Seeks to specified position + /// + /// position to seek in second + /// true if successed to seek + public bool Seek( double pos_second ) { + if ( m_filename == "" ) { + return false; + } + if ( !m_loaded ) { + ReLoad(); + } + long position = (long)(pos_second * 1000.0); + bool ret = w_mciSendString( "seek " + m_alias + " to " + position ); + return ret; + } + + /// + /// Pauses sound + /// + /// true if successed to pause + public bool Pause() { + if ( m_filename == "" ) { + return false; + } + if ( !m_loaded ) { + ReLoad(); + } + m_playing = false; + pausing = true; + //return w_mciSendString( "pause \"" + m_filename + "\"", null, 0, 0 ); + return w_mciSendString( "pause " + m_alias ); + } + + /// + /// Gets the current playing position in millisecond + /// + /// playing position in millisecond + public int GetPosition() { + if ( this.SoundLocation == "" ) { + return -1; + } + if ( !m_loaded ) { + ReLoad(); + } + string ret; + w_mciSendString( "status " + m_alias + " position", out ret ); + int pos; + try { + pos = int.Parse( ret ); + } catch { + pos = -1; + } + return pos; + } + + /// + /// Gets the sound length in millisecond + /// + /// Sound length in millisecond + public int GetLength() { + if ( this.SoundLocation == "" ) { + return -1; + } + if ( !m_loaded ) { + ReLoad(); + } + string ret; + w_mciSendString( "status " + m_alias + " length", out ret ); + int length = -1; + if ( int.TryParse( ret, out length ) ) { + return length; + } else { + return -1; + } + } + + /// + /// Stops sound + /// + /// true if successed to stop + public bool Stop() { + m_playing = false; + return w_mciSendString( "stop " + m_alias ); + } + + public bool IsPlaying { + get { + return m_playing; + } + } + } + +} diff --git a/trunk/Boare.Lib.Media/MidiInDevice.cs b/trunk/Boare.Lib.Media/MidiInDevice.cs new file mode 100644 index 0000000..3c8b2ec --- /dev/null +++ b/trunk/Boare.Lib.Media/MidiInDevice.cs @@ -0,0 +1,164 @@ +/* + * MidiInDevice.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Runtime.InteropServices; +using System.Collections.Generic; + +using bocoree; + +namespace Boare.Lib.Media { + + public delegate void MidiReceivedEventHandler( DateTime time, byte[] data ); + + public class MidiInDevice : IDisposable { + delegate void MidiInProcDelegate( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 ); + + private const int CALLBACK_EVENT = 0x50000; + private const int CALLBACK_FUNCTION = 0x30000; + private const int CALLBACK_NULL = 0; + private const int CALLBACK_TASK = 0x20000; + private const int CALLBACK_THREAD = 0x20000; + private const int CALLBACK_TYPEMASK = 0x70000; + private const int CALLBACK_WINDOW = 0x10000; + private volatile MidiInProcDelegate m_delegate; + private IntPtr m_delegate_pointer; + private uint m_hmidiin = 0; + private int m_port_number; + private const int MM_MIM_CLOSE = 0x3c2; + private const int MM_MIM_DATA = 0x3c3; + private const int MM_MIM_ERROR = 0x3c5; + private const int MM_MIM_LONGDATA = 0x3c4; + private const int MM_MIM_LONGERROR = 0x3c6; + private const int MM_MIM_OPEN = 0x3c1; + + public event MidiReceivedEventHandler MidiReceived; + + public MidiInDevice( int port_number ) { + m_port_number = port_number; + m_delegate = new MidiInProcDelegate( MidiInProc ); + m_delegate_pointer = Marshal.GetFunctionPointerForDelegate( m_delegate ); + windows.midiInOpen( ref m_hmidiin, port_number, m_delegate_pointer, 0, CALLBACK_FUNCTION ); + } + + public void Start() { + if ( m_hmidiin > 0 ) { + try { + windows.midiInStart( m_hmidiin ); + } catch ( Exception ex ) { + debug.push_log( "MidiInDevice.Start" ); + debug.push_log( " ex=" + ex ); + } + } + } + + public void Stop() { + if ( m_hmidiin > 0 ) { + try { + windows.midiInReset( m_hmidiin ); + } catch ( Exception ex ) { + debug.push_log( "MidiInDevice.Stop" ); + debug.push_log( " ex=" + ex ); + } + } + } + + public void Close() { + if ( m_hmidiin > 0 ) { + try { + windows.midiInClose( m_hmidiin ); + } catch ( Exception ex ) { + debug.push_log( "MidiInDevice.Close" ); + debug.push_log( " ex=" + ex ); + } + } + m_hmidiin = 0; + } + + public void Dispose() { + Close(); + } + + public static int GetNumDevs() { + try { + int i = (int)windows.midiInGetNumDevs(); + return i; + } catch ( Exception ex ) { + debug.push_log( "MidiInDevice.GetNumDevs" ); + debug.push_log( " ex=" + ex ); + } + return 0; + } + + public static MIDIINCAPS[] GetMidiInDevices() { + List ret = new List(); + uint num = 0; + try { + num = windows.midiInGetNumDevs(); + } catch { + num = 0; + } + for ( uint i = 0; i < num; i++ ) { + MIDIINCAPS m = new MIDIINCAPS(); + uint r = windows.midiInGetDevCaps( i, ref m, (uint)Marshal.SizeOf( m ) ); + ret.Add( m ); + } + return ret.ToArray(); + } + + private void MidiInProc( uint hMidiIn, uint wMsg, int dwInstance, int dwParam1, int dwParam2 ) { + try { + switch ( wMsg ) { + case MM_MIM_OPEN: + return; + case MM_MIM_CLOSE: + return; + case MM_MIM_DATA: + int receive = dwParam1; + DateTime now = DateTime.Now; + switch ( receive & 0xF0 ) { + case 0x80: + case 0x90: + case 0xa0: + case 0xb0: + case 0xe0: + if ( MidiReceived != null ) { + MidiReceived( now, new byte[] { (byte)(receive & 0xff), + (byte)((receive & 0xffff) >> 8), + (byte)((receive & ((2 << 24) - 1)) >> 16) } ); + } + break; + case 0xc0: + case 0xd0: + if ( MidiReceived != null ) { + MidiReceived( now, new byte[] { (byte)( receive & 0xff ), + (byte)((receive & 0xffff) >> 8) } ); + } + break; + } + return; + case MM_MIM_LONGDATA: + return; + case MM_MIM_ERROR: + return; + case MM_MIM_LONGERROR: + return; + } + } catch ( Exception ex ) { + debug.push_log( "MidiInDevice.MidiInProc" ); + debug.push_log( " ex=" + ex ); + } + } + } + +} diff --git a/trunk/Boare.Lib.Media/PipedAviWriter.cs b/trunk/Boare.Lib.Media/PipedAviWriter.cs new file mode 100644 index 0000000..a4065a9 --- /dev/null +++ b/trunk/Boare.Lib.Media/PipedAviWriter.cs @@ -0,0 +1,251 @@ +/* + * PipedAviWriter.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +#if !MONO +#define TEST +using System; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +//using System.IO.Pipes; +using System.Runtime.InteropServices; +using System.Threading; + +using bocoree; + +namespace Boare.Lib.Media { + + public class PipedAviWriter { + private const string _PIPE_NAME = "fifo"; + private uint m_scale = 1; + private uint m_rate = 30; +#if TEST + private FileStream m_stream = null; +#else + private NamedPipeServerStream m_stream = null; +#endif + private MainAVIHeader m_main_avi_header; + private uint m_bitmapsize; + private bool m_header_written = false; + private ulong m_frames; + private Thread m_ffmpeg = null; + private PixelFormat m_pix_fmt = PixelFormat.Format24bppRgb; + private int m_bit_count = 24; + + public bool AddFrame( Bitmap bmp ) { + if ( bmp.PixelFormat != m_pix_fmt ) { + return false; + } + BitmapData bdat = bmp.LockBits( new Rectangle( 0, 0, bmp.Width, bmp.Height ), + ImageLockMode.ReadOnly, + bmp.PixelFormat ); + BinaryWriter bw = new BinaryWriter( new MemoryStream() ); + if ( !m_header_written ) { + m_bitmapsize = (uint)(bdat.Stride * bdat.Height); + //m_stream.SetLength( (long)(0xdc + (m_bitmapsize + 0x8) * m_frames) ); + + /*m_main_avi_header.dwWidth = (uint)bdat.Width; + m_main_avi_header.dwHeight = (uint)bdat.Height;// bmp%infoHeader%Height + m_main_avi_header.dwMaxBytesPerSec = (uint)((float)bdat.Stride * (float)bdat.Height * (float)m_rate / (float)m_scale); + m_main_avi_header.dwStreams = 1; + m_main_avi_header.dwSuggestedBufferSize = (uint)(bdat.Stride * bdat.Height); + + AVIStreamHeader stream_header = new AVIStreamHeader(); + stream_header.fccType = Util.mmioFOURCC( "vids" ); + stream_header.fccHandler = 0; + stream_header.dwFlags = 0; + stream_header.dwReserved1 = 0; + stream_header.dwInitialFrames = 0; + stream_header.dwScale = m_scale; + stream_header.dwRate = m_rate; + stream_header.dwStart = 0; + stream_header.dwSuggestedBufferSize = m_main_avi_header.dwSuggestedBufferSize; + stream_header.dwQuality = 0; + stream_header.dwSampleSize = 0; + + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); + bih.biSize = (uint)(Marshal.SizeOf( bih )); + bih.biWidth = bdat.Width; + bih.biHeight = bdat.Height; + bih.biPlanes = 1; + bih.biBitCount = m_pix_fmt == PixelFormat.Format24bppRgb ? (short)24 : (short)32; + bih.biCompression = 0;//BI_RGB + bih.biSizeImage = (uint)(bdat.Stride * bdat.Height); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + + bw.Write( "RIFF".ToCharArray() ); + bw.Write( (uint)(0xdc + (m_bitmapsize + 0x8) * m_frames) ); + bw.Write( "AVI ".ToCharArray() ); + bw.Write( "LIST".ToCharArray() ); + bw.Write( (uint)0xc0 ); + bw.Write( "hdrl".ToCharArray() ); + bw.Write( "avih".ToCharArray() ); + bw.Write( (uint)0x38 ); + m_main_avi_header.Write( bw.BaseStream ); + bw.Write( "LIST".ToCharArray() ); + bw.Write( (uint)0x7C ); + bw.Write( "strl".ToCharArray() ); + bw.Write( "strh".ToCharArray() ); + bw.Write( (uint)0x38 ); + stream_header.Write( bw.BaseStream ); + bw.Write( (uint)0x0 ); + bw.Write( (uint)0x0 ); + bw.Write( "strf".ToCharArray() ); + bw.Write( (uint)0x28 ); + bih.Write( bw.BaseStream ); + bw.Write( "LIST".ToCharArray() ); + bw.Write( (uint)((m_bitmapsize + 0x8) * m_frames) ); + bw.Write( "movi".ToCharArray() );*/ + + m_header_written = true; + } + + //bw.Write( "00db" ); + //bw.Write( (uint)m_bitmapsize ); + int address = bdat.Scan0.ToInt32(); + byte[] bitmapData = new byte[bdat.Stride * bdat.Height]; + Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); + //bw.Write( (uint)m_main_avi_header.dwSuggestedBufferSize ); + bw.Write( "BM".ToCharArray() ); + bw.Write( m_bitmapsize ); + bw.Write( (uint)0x0 ); + bw.Write( (uint)0x36 ); + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) ); + bih.biSize = (uint)(Marshal.SizeOf( bih )); + bih.biWidth = bdat.Width; + bih.biHeight = bdat.Height; + bih.biPlanes = 1; + bih.biBitCount = m_pix_fmt == PixelFormat.Format24bppRgb ? (short)24 : (short)32; + bih.biCompression = 0;//BI_RGB + bih.biSizeImage = (uint)(bdat.Stride * bdat.Height); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + bih.Write( bw ); + bw.Write( bitmapData, 0, bitmapData.Length ); + //const int _BUF_LEN = 512; + byte[] buf = new byte[m_bitmapsize + 6]; + bw.BaseStream.Seek( 0, SeekOrigin.Begin ); + int len = bw.BaseStream.Read( buf, 0, (int)(m_bitmapsize + 6) ); + if ( len > 0 ) { + m_stream.BeginWrite( buf, 0, len, null, null ); + } + m_stream.Flush(); + bw.Close(); + + bmp.UnlockBits( bdat ); + return true; + } + + + private void WriteFourCC( string value ) { + byte[] b = new byte[4]; + for ( int i = 0; i < 4; i++ ) { + b[i] = (byte)value[i]; + } + m_stream.Write( b, 0, 4 ); + } + + + private void Write4Byte( uint value ) { + byte[] b; + b = BitConverter.GetBytes( value ); + if ( !BitConverter.IsLittleEndian ) { + Array.Reverse( b ); + } + m_stream.Write( b, 0, 4 ); + } + + + public void Close() { + if ( m_stream != null ) { +#if !TEST + m_stream.Disconnect(); +#endif + m_stream.Close(); + } + if ( m_ffmpeg != null ) { + if ( m_ffmpeg.IsAlive ) { + m_ffmpeg.Abort(); + while ( m_ffmpeg.IsAlive ) { + } + } + } + } + + + public void Open( uint scale, uint rate, ulong frames, PixelFormat pix_fmt ) { + if ( m_stream != null ) { + m_stream.Close(); + } +#if TEST + m_stream = new FileStream( "test.out.avi", FileMode.Create ); +#else + m_stream = new NamedPipeServerStream( _PIPE_NAME, PipeDirection.Out, 1, PipeTransmissionMode.Byte, PipeOptions.None, 1, 1 ); +#endif + m_scale = scale; + m_rate = rate; + m_frames = frames; + + m_main_avi_header.dwMicroSecPerFrame = (uint)(1.0e6 * (double)scale / (double)rate);// ! 1秒は10^6μ秒 + m_main_avi_header.dwReserved1 = 0; + m_main_avi_header.dwFlags = 2064; + m_main_avi_header.dwInitialFrames = 0; + m_main_avi_header.dwStreams = 0; + m_main_avi_header.dwScale = scale; + m_main_avi_header.dwRate = rate; + m_main_avi_header.dwStart = 0; + m_main_avi_header.dwLength = 0; + m_main_avi_header.dwTotalFrames = (uint)m_frames; + + m_pix_fmt = pix_fmt; + if ( m_pix_fmt != PixelFormat.Format24bppRgb && m_pix_fmt != PixelFormat.Format32bppArgb ) { + throw new ApplicationException( "pixel format not supported" ); + } +#if !TEST + m_ffmpeg = new Thread( new ThreadStart( FFmpegEnc ) ); + m_ffmpeg.Start(); + m_stream.WaitForConnection(); +#endif + } + + + private void FFmpegEnc() { + Thread.Sleep( 1000 ); + Process client = new Process(); + client.StartInfo.FileName = "ffmpeg"; + + // windowsの場合 + client.StartInfo.Arguments = @"-f image2pipe -vcodec bmp -i \\.\pipe\" + _PIPE_NAME + " -isync -an -f avi -y test.avi"; + + // その他 + // client.StartInfo.Arguments = @"-i " + _PIPE_NAME + " -y test.mp3"; + + client.StartInfo.RedirectStandardOutput = true; + client.StartInfo.UseShellExecute = false; + client.Start(); + StreamReader sr = client.StandardOutput; + string line = ""; + while ( (line = sr.ReadLine()) != null ) { + Console.WriteLine( line ); + } + } + } + +} +#endif diff --git a/trunk/Boare.Lib.Media/Properties/AssemblyInfo.cs b/trunk/Boare.Lib.Media/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e996771 --- /dev/null +++ b/trunk/Boare.Lib.Media/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +/* + * AssemblyInfo.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Cadencii is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle( "Boare.Lib.Media" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "Boare.Lib.Media" )] +[assembly: AssemblyCopyright( "Copyright © 2008-2009" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] +[assembly: ComVisible( false )] +[assembly: Guid( "92853599-3628-440d-b15f-798fde36cf23" )] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0" )] diff --git a/trunk/Boare.Lib.Media/RawAvi2Writer.cs b/trunk/Boare.Lib.Media/RawAvi2Writer.cs new file mode 100644 index 0000000..9ea4f0b --- /dev/null +++ b/trunk/Boare.Lib.Media/RawAvi2Writer.cs @@ -0,0 +1,542 @@ +/* + * RawAvi2Writer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +#if DEBUG +using System.Windows.Forms; +#endif + +using bocoree; + +namespace Boare.Lib.Media { + + public struct _avistdindex_entry { + public UInt32 dwOffset; + public UInt32 dwSize; + } + + + public struct AVISTDINDEX { + public readonly string fcc; + //private UInt32 m_cb; + public UInt32 cb { + get { + if ( aIndex == null ) { + return 24; + } else { + return (uint)(24 + 8 * aIndex.Count); + } + } + } + public readonly UInt16 wLongsPerEntry; + public readonly byte bIndexSubType; + public readonly byte bIndexType; + //private UInt32 m_nEntriesInUse; + public UInt32 nEntriesInUse { + get { + if ( aIndex == null ) { + return 0; + } else { + return (uint)aIndex.Count; + } + } + } + public readonly string dwChunkId; + public UInt64 qwBaseOffset; + public readonly UInt32 dwReserved3; + public List<_avistdindex_entry> aIndex; + public AVISTDINDEX( ulong BaseOffset ) { + fcc = "ix00"; + wLongsPerEntry = 2; + bIndexSubType = 0; + bIndexType = Util.AVI_INDEX_OF_CHUNKS; + dwChunkId = "00db"; + qwBaseOffset = BaseOffset; + dwReserved3 = 0; + //m_nEntriesInUse = 0; + aIndex = new List<_avistdindex_entry>(); + } + public void SetBaseOffset( UInt64 base_offset ) { + this.qwBaseOffset = base_offset; + } + public void AddIndex( uint dwOffset, uint dwSize ) { + _avistdindex_entry entry = new _avistdindex_entry(); + entry.dwOffset = dwOffset; + entry.dwSize = dwSize; + this.aIndex.Add( entry ); + } + public void Write( BinaryWriter fp ) { + Util.fwrite( fcc, fp ); + Util.WriteDWORD( (uint)cb, fp ); + Util.WriteWORD( wLongsPerEntry, fp ); + Util.WriteBYTE( bIndexSubType, fp ); + Util.WriteBYTE( bIndexType, fp ); + Util.WriteDWORD( (uint)nEntriesInUse, fp ); + Util.fwrite( dwChunkId, fp ); + Util.WriteQWORD( (ulong)qwBaseOffset, fp ); + Util.WriteDWORD( (uint)dwReserved3, fp ); + foreach ( _avistdindex_entry entry in aIndex ) { + Util.WriteDWORD( (uint)entry.dwOffset, fp ); + Util.WriteDWORD( (uint)entry.dwSize, fp ); + } + } + } + + + public struct _avisuperindex_entry { + public UInt64 qwOffset; + public UInt32 dwSize; + public UInt32 dwDuration; + } + + + public struct AVISUPERINDEX { + public readonly string fcc; + //public UInt32 cb; + public UInt32 cb { + get { + if ( aIndex == null ) { + return 24; + } else { + return (uint)(24 + 16 * aIndex.Count); + } + } + } + public readonly UInt16 wLongsPerEntry; + public byte bIndexSubType; + public byte bIndexType; + public UInt32 nEntriesInUse; + public readonly string dwChunkId; + public UInt32 dwReserved1; + public UInt32 dwReserved2; + public UInt32 dwReserved3; + public List<_avisuperindex_entry> aIndex; + public AVISUPERINDEX( int dumy ) { + this.fcc = "indx"; + this.wLongsPerEntry = 4; + this.bIndexSubType = 0; + this.bIndexType = Util.AVI_INDEX_OF_INDEXES; + this.nEntriesInUse = 0; + this.dwChunkId = "00db"; + this.dwReserved1 = 0; + this.dwReserved2 = 0; + this.dwReserved3 = 0; + this.aIndex = new List<_avisuperindex_entry>(); + _avisuperindex_entry entry = new _avisuperindex_entry(); + entry.qwOffset = 0; + entry.dwSize = 0; + entry.dwDuration = 0; + for ( int i = 0; i < 126; i++ ) { + this.aIndex.Add( entry ); + } + } + public void Write( BinaryWriter fp ) { + Util.fwrite( fcc, fp ); + Util.WriteDWORD( (uint)cb, fp );//ここほんとは(int)cb + Util.WriteWORD( wLongsPerEntry, fp ); + Util.WriteBYTE( bIndexSubType, fp ); + Util.WriteBYTE( bIndexType, fp ); + Util.WriteDWORD( (uint)nEntriesInUse, fp ); + Util.fwrite( dwChunkId, fp ); + Util.WriteDWORD( (uint)dwReserved1, fp ); + Util.WriteDWORD( (uint)dwReserved2, fp ); + Util.WriteDWORD( (uint)dwReserved3, fp ); + foreach ( _avisuperindex_entry entry in aIndex ) { + Util.WriteQWORD( (ulong)entry.qwOffset, fp ); + Util.WriteDWORD( (uint)entry.dwSize, fp ); + Util.WriteDWORD( (uint)entry.dwDuration, fp ); + } + } + } + + public class RawAvi2Writer { + public MainAVIHeader m_main_header; + public AVIStreamHeader m_stream_header; + //long currentIndex; + BinaryWriter m_stream; + //int frameRate; + //int noOfFrame; + int m_current_chunk = 0; + long m_position_in_chunk = 0L; + const long SRESHOLD = 1000000000L; //AVIXリストの最大サイズ(byte) + long m_split_sreshold = 160000000L; //AVIリストの最大サイズ(byte) + AVISTDINDEX m_std_index; + AVISUPERINDEX m_super_index; + int m_linesize;//bitmapの1行分のデータサイズ(byte) + bool m_is_first = true; + long m_riff_position;//"RIFF*"の*が記入されているファイルの絶対位置。RIFF-AVI のときは必ず4。RIFF-AVIXの時は変化する + long m_movi_position; + long m_next_framedata_position;//次に00dbデータを記入するべき場所 + long m_avix_position; + int m_junk_length; + uint m_scale; + uint m_rate; + + internal float frameRate { + get { + return (float)m_rate / (float)m_scale; + } + } + + /// + /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に, + /// ファイルにヘッダー情報を書き込みます. + /// + /// 書き込み対象のファイル + /// AVIファイルのフレームレート + public void Open( string file, uint scale, uint rate ) { + this.m_stream = new BinaryWriter( new FileStream( file, FileMode.Create, FileAccess.Write ) ); + float fps = (float)rate / (float)scale; + this.m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);// ! 1秒は10^6μ秒 + this.m_main_header.dwReserved1 = 0; + this.m_main_header.dwFlags = 2064; + this.m_main_header.dwInitialFrames = 0; + this.m_main_header.dwStreams = 0; + this.m_main_header.dwScale = scale; + this.m_main_header.dwRate = rate; + this.m_main_header.dwStart = 0; + this.m_main_header.dwLength = 0; + this.m_rate = rate; + this.m_scale = scale; + //this.noOfFrame = 0; + Util.fwrite( "RIFF", this.m_stream ); + Util.WriteDWORD( 0, this.m_stream ); + Util.fwrite( "AVI ", this.m_stream ); + Util.fwrite( "LIST", this.m_stream ); + Util.WriteDWORD( 0x9cc, this.m_stream ); + Util.fwrite( "hdrl", this.m_stream ); + m_current_chunk = 0; + m_position_in_chunk = 0L; + m_std_index = new AVISTDINDEX( 0L ); + m_super_index = new AVISUPERINDEX( 0 ); + m_riff_position = 0x4; + } + + + + /*[Obsolete] + public void Open( string file, float frameRate ) { + uint scale, rate; + AviWriter.CalcScaleAndRate( (decimal)frameRate, out scale, out rate ); + Open( file, scale, rate ); + }*/ + + + //todo: AVIMainHeader.dwTotalFramesに、ファイル全体のフレーム数を入れる(仕様違反) + //todo: AVIStreamHeader.dwLengthに、ファイル全体のフレーム数を入れる(仕様違反) + /// + /// 全てのインデックスを更新し、ファイルが(動画ファイルとして)使用できる状態にします + /// この関数を読んだあとでも,さらにaviAddFrame関数を使うことでフレームを追加することが出来ます. + /// + public void UpdateIndex() { + _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk]; + entry.qwOffset = (ulong)m_stream.BaseStream.Position; + entry.dwSize = m_std_index.cb; + m_super_index.aIndex[m_current_chunk] = entry; + if ( m_stream.BaseStream.Position != m_next_framedata_position ) { + m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin ); + } + m_std_index.Write( m_stream ); + int frames = (int)m_super_index.aIndex[m_current_chunk].dwDuration; + m_avix_position = m_stream.BaseStream.Position; + + if ( m_current_chunk == 0 ) { + uint i, step, number; + step = this.m_main_header.dwSuggestedBufferSize + 8; + + Util.fwrite( "idx1", this.m_stream ); + Util.WriteDWORD( (uint)(16 * frames), this.m_stream ); + for ( i = 1; i <= frames; i++ ) { + Util.fwrite( "00db", this.m_stream ); + Util.WriteDWORD( Util.AVIF_HASINDEX, this.m_stream ); + Util.WriteDWORD( (uint)(4 + (i - 1) * step), this.m_stream ); + Util.WriteDWORD( this.m_main_header.dwSuggestedBufferSize, this.m_stream ); + }// end do + m_avix_position = m_stream.BaseStream.Position; + + number = (uint)frames; + //avi_writeIsolate( this.fp, number, 48 ); // AVIMainHeader.dwTotalFrames + m_stream.Seek( 48, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + //avi_writeIsolate( this.fp, number, 140 ); // AVIStreamHeader.dwLength + m_stream.Seek( 140, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + + //odml dlmhのdwTotalFrames + m_stream.Seek( 0x8e8, SeekOrigin.Begin ); + Util.WriteDWORD( (uint)frames, m_stream ); + + // LIST****moviの****の数値を計算 + number = 4;//"movi" + number += (uint)(frames * (m_linesize * m_main_header.dwHeight + 8));//フレーム数*(フレームのサイズ+"00db"+00dbチャンクのサイズ) + number += 4 + 4 + (uint)m_std_index.cb; //ix00のサイズ + //number += 4 + 4 + 16 * frames;//idx1のサイズ + //avi_writeIsolate( this.fp, number, 2040 ); // LIST****movi の ****部分 + m_stream.BaseStream.Seek( m_movi_position, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + + //number = 4096 + (this.mainHeader.dwSuggestedBufferSize + 24) * this.noOfFrame; + //avi_writeIsolate( this.fp, number, 4 ); // RIFF****AVI の ****部分 + number = (uint)m_junk_length/* 0xff4*/; //JUNKの終わりまでのサイズ。これは固定 + number += 4;//"movi" + number += (uint)(frames * (m_linesize * m_main_header.dwHeight + 8));//00db...の合計サイズ + number += 4 + 4 + (uint)m_std_index.cb; + number += (uint)(4 + 4 + 16 * frames);//idx1のサイズ + m_stream.BaseStream.Seek( m_riff_position, SeekOrigin.Begin ); + Util.WriteDWORD( number, m_stream ); + UpdateIndexOfIndex(); + } else { + + // LIST****moviの****を更新 + int number = 4; + number += (int)(frames * (m_linesize * m_main_header.dwHeight + 8)); + number += 8 + (int)m_std_index.cb; + m_stream.BaseStream.Seek( m_movi_position, SeekOrigin.Begin ); + Util.WriteDWORD( (uint)number, m_stream ); + + // odml dlmhのdwTotalFrames + uint frames2 = 0; + for ( int j = 0; j <= m_current_chunk; j++ ) { + frames2 += (uint)m_super_index.aIndex[j].dwDuration; + } + m_stream.BaseStream.Seek( 0x8e8, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + //avi_writeIsolate( this.fp, number, 48 ); // AVIMainHeader.dwTotalFrames + m_stream.Seek( 48, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + //avi_writeIsolate( this.fp, number, 140 ); // AVIStreamHeader.dwLength + m_stream.Seek( 140, SeekOrigin.Begin ); + Util.WriteDWORD( frames2, m_stream ); + + //RIFF****AVIXの****を更新 + long num2 = m_junk_length + number; + m_stream.BaseStream.Seek( m_riff_position, SeekOrigin.Begin ); + Util.WriteDWORD( (uint)num2, m_stream ); + UpdateIndexOfIndex(); + } + + } + + + /// + /// aviファイルを閉じます + /// + public void Close() { + UpdateIndex(); + this.m_stream.Close(); + } + + + /// + /// 最初の[AVI :AVI[LIST:hdrl[LIST:strl]]]に書き込まれているsuper indexチャンク[indx]を更新します + /// + private void UpdateIndexOfIndex() { + m_stream.Seek( 0xd4, SeekOrigin.Begin ); + m_super_index.Write( m_stream ); + } + + + /// + /// aviファイルにフレームを1つ追加します. + /// + /// + public void AddFrame( Bitmap bmp ) { + int i, width, height, lineSize; + + // BitmapDataからビットマップデータと、BITMPAINFOHEADERを取り出す + BitmapData bmpDat = bmp.LockBits( + new Rectangle( 0, 0, (int)bmp.Width, (int)bmp.Height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb ); + int address = bmpDat.Scan0.ToInt32(); + byte[] bitmapData = new byte[bmpDat.Stride * bmpDat.Height]; + Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length ); + + if ( m_is_first ) {//then + m_is_first = false; + this.m_main_header.dwWidth = (uint)bmpDat.Width;// bmp%infoHeader%Width + this.m_main_header.dwHeight = (uint)bmpDat.Height;// bmp%infoHeader%Height + this.m_main_header.dwMaxBytesPerSec = (uint)(bmpDat.Stride * bmpDat.Height * this.frameRate);// bmp%infoHeader%SizeImage * avi%frameRate + this.m_main_header.dwStreams = 1; + this.m_main_header.dwSuggestedBufferSize = (uint)(bmpDat.Stride * bmpDat.Height);// bmp.infoHeader%SizeImage + m_linesize = bmpDat.Stride; + + this.m_stream_header.fccType = Util.mmioFOURCC( "vids" ); + this.m_stream_header.fccHandler = 0; + this.m_stream_header.dwFlags = 0; + this.m_stream_header.dwReserved1 = 0; + this.m_stream_header.dwInitialFrames = 0; + this.m_stream_header.dwScale = m_scale; + this.m_stream_header.dwRate = m_rate; + this.m_stream_header.dwStart = 0; + this.m_stream_header.dwSuggestedBufferSize = this.m_main_header.dwSuggestedBufferSize; + this.m_stream_header.dwQuality = 0; + this.m_stream_header.dwSampleSize = 0; + + Util.aviWriteMainHeader( m_main_header, m_stream ); + + Util.fwrite( "LIST", this.m_stream );// i = fwrite( 'LIST', 1, 4, avi%fp ) + Util.WriteDWORD( 0x874, this.m_stream );// call bmpQWordWrite( 130, avi%fp ) + Util.fwrite( "strl", this.m_stream );// i = fwrite( 'strl', 1, 4, avi%fp ) + + Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream );// avi ) + + Util.fwrite( "strf", this.m_stream );// i = fwrite( 'strf', 1, 4, avi%fp ) + Util.WriteDWORD( 0x28, this.m_stream ); //call bmpQWordWrite( 40, avi%fp ) !// infoHeaderのサイズ + BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); + bih.biSize = (uint)(Marshal.SizeOf( bih )); + bih.biWidth = bmpDat.Width; + bih.biHeight = bmpDat.Height; + bih.biPlanes = 1; + bih.biBitCount = 24; + bih.biCompression = 0;//BI_RGB + bih.biSizeImage = (uint)(bmpDat.Stride * bmpDat.Height); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + bih.biClrUsed = 0; + bih.biClrImportant = 0; + bih.Write( m_stream ); + + /*fwrite( "strn", this.fp ); + WriteDWORD( 6, this.fp ); + fwrite( "VIDEO", this.fp ); + WriteBYTE( 0, this.fp );*/ + Util.fwrite( "indx", this.m_stream ); //fcc + Util.WriteDWORD( 0x7f8, this.m_stream ); // cb + Util.WriteWORD( (byte)0x4, this.m_stream ); // wLongsPerEntry + Util.WriteBYTE( 0x0, this.m_stream ); // bIndexSubType + Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, this.m_stream );// bIndexType + Util.WriteDWORD( 0x0, this.m_stream ); // nEntriesInUse + Util.fwrite( "00db", this.m_stream ); // dwChunkId + Util.WriteDWORD( 0x0, this.m_stream ); + Util.WriteDWORD( 0x0, this.m_stream ); + Util.WriteDWORD( 0x0, this.m_stream ); + for ( int ii = 1; ii <= 126; ii++ ) { + Util.WriteQWORD( 0x0, this.m_stream ); + Util.WriteDWORD( 0x0, this.m_stream ); + Util.WriteDWORD( 0x0, this.m_stream ); + } + + Util.fwrite( "LIST", this.m_stream ); + Util.WriteDWORD( 0x104, m_stream ); + Util.fwrite( "odml", this.m_stream ); + Util.fwrite( "dmlh", m_stream ); + Util.WriteDWORD( 0xf8, m_stream ); + Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき + for ( int ii = 1; ii <= 61; ii++ ) { + Util.WriteDWORD( 0x0, m_stream ); + } + + Util.fwrite( "JUNK", this.m_stream );// i = fwrite( 'JUNK', 1, 4, avi%fp ) + Util.WriteDWORD( 0x60c, m_stream ); + Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので + Util.fwrite( "This file was generated by RawAvi@LipSync", this.m_stream ); + //WriteDWORD( 1503, this.fp );// call bmpQWordWrite( 1802, avi%fp ) + for ( i = 1; i <= 1503; i++ ) {//do i = 1, 1802 + this.m_stream.Write( (byte)0 );// call fputc( 0, avi%fp ) + }//end do + m_junk_length = 0xff4; + + Util.fwrite( "LIST", this.m_stream );// i = fwrite( 'LIST', 1, 4, avi%fp ) + m_movi_position = m_stream.BaseStream.Position; + Util.WriteDWORD( 0, this.m_stream );// call bmpQWordWrite( 0, avi%fp ) !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も + Util.fwrite( "movi", this.m_stream );// i = fwrite( 'movi', 1, 4, avi%fp ) + m_next_framedata_position = m_stream.BaseStream.Position; + + m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); + m_super_index.nEntriesInUse++; + }//end if + + if ( m_next_framedata_position != m_stream.BaseStream.Position ) { + m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin ); + } + + long chunk_size = m_next_framedata_position - m_riff_position; +#if DEBUG +// MessageBox.Show( "chunk_size=" + chunk_size ); +#endif + if ( (m_current_chunk == 0 && chunk_size > m_split_sreshold) || + (m_current_chunk > 0 && chunk_size > SRESHOLD )) { + // AVIXリストへの書き込みに移行 + UpdateIndex(); + m_stream.BaseStream.Seek( m_avix_position, SeekOrigin.Begin ); + Util.fwrite( "RIFF", m_stream ); + m_riff_position = m_stream.BaseStream.Position; +#if DEBUG +// fp.Flush(); +// MessageBox.Show( "m_riff_position=" + m_riff_position ); +#endif + Util.WriteDWORD( 0, m_stream ); + Util.fwrite( "AVIX", m_stream ); + long current = m_stream.BaseStream.Position; + if ( (current + 12) % 0x800 != 0 ) { + long additional = (current + 20) % 0x800; + additional = 0x800 - ((current + 20) % 0x800); + m_junk_length = (int)additional + 20; + Util.fwrite( "JUNK", m_stream ); + Util.WriteDWORD( (uint)additional, m_stream ); + for ( long ii = 0; ii < additional; ii++ ) { + Util.WriteBYTE( (byte)0, m_stream ); + } + } else { + m_junk_length = 0; + } + m_junk_length = 0; + + Util.fwrite( "LIST", m_stream ); + m_movi_position = m_stream.BaseStream.Position; + Util.WriteDWORD( 0, m_stream );//後で更新するべき + Util.fwrite( "movi", m_stream ); + m_next_framedata_position = m_stream.BaseStream.Position; + m_std_index.aIndex.Clear(); + m_std_index.SetBaseOffset( (ulong)m_next_framedata_position ); + m_current_chunk++; + m_super_index.nEntriesInUse++; + } + + // フレームを書き込む処理 + width = (int)this.m_main_header.dwWidth; + height = (int)this.m_main_header.dwHeight; + if ( width != bmpDat.Width ) {//then + //aviAddFrame = -1 + return; + }//end if + if ( height != bmpDat.Height ) {//then + //aviAddframe = -1 + return; + }//end if + lineSize = bmpDat.Stride;// int( (width * 24 + 31) / 32 ) * 4 + + m_std_index.AddIndex( (uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)(lineSize * height) ); + Util.fwrite( "00db", this.m_stream );// i = fwrite( '00db', 1, 4, avi%fp ) + Util.WriteDWORD( m_main_header.dwSuggestedBufferSize, m_stream );// call bmpQWordWrite( avi%mainHeader%dwSuggestedBufferSize, avi%fp ) + m_stream.Write( bitmapData ); + m_next_framedata_position = m_stream.BaseStream.Position; + _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk]; + entry.dwDuration++; + m_super_index.aIndex[m_current_chunk] = entry;// avi%noOfFrame = avi%noOfFrame + 1 + this.m_stream.Flush();// aviAddFrame = fflush( avi%fp ) + bmp.UnlockBits( bmpDat ); + }// end function + + + + } +} + diff --git a/trunk/Boare.Lib.Media/Util.cs b/trunk/Boare.Lib.Media/Util.cs new file mode 100644 index 0000000..63ccf8c --- /dev/null +++ b/trunk/Boare.Lib.Media/Util.cs @@ -0,0 +1,222 @@ +/* + * Util.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; + +using bocoree; + +namespace Boare.Lib.Media { + + internal static class Util { + public const byte AVI_INDEX_OF_INDEXES = 0x00; //when each entry in aIndex + // array points to an index chunk + public const byte AVI_INDEX_OF_CHUNKS = 0x01; // when each entry in aIndex + // array points to a chunk in the file + public const byte AVI_INDEX_IS_DATA = 0x80; // when each entry is aIndex is + // really the data + public const byte AVI_INDEX_2FIELD = 0x01; // when fields within frames + // are also indexed + + public const int AVIF_HASINDEX = 16; // Indicates the AVI file has an “idx1” chunk. + public const int AVIF_MUSTUSEINDEX = 32; // Indicates the index should be used to determine the order of presentation of the data. + public const int AVIF_ISINTERLEAVED = 256; // Indicates the AVI file is interleaved. + public const int AVIF_WASCAPTUREFILE = 65536; // Indicates the AVI file is a specially allocated file used for capturing real-time video. + public const int AVIF_COPYRIGHTED = 131072; // Indicates the AVI file contains copyrighted data. + public const int AVIF_TRUSTCKTYPE = 2048; // Use CKType to find key frames + public const int BMP_MAGIC_COOKIE = 19778; //ascii string "BM" + + /*// + /// 指定されたBITMAP型変数の情報ヘッダーをファイルに書き込みます. + /// + /// + /// + public static void bmpWriteInfoHeader( BITMAPINFOHEADER infoHeader, BinaryWriter stream ) { + //type(INFO_HEADER), intent(in) :: infoHeader + //type(FILE), intent(inout) :: fp + Util.WriteDWORD( (uint)infoHeader.biSize, stream ); + Util.WriteDWORD( (uint)infoHeader.biWidth, stream ); + Util.WriteDWORD( (uint)infoHeader.biHeight, stream ); + Util.WriteWORD( (ushort)infoHeader.biPlanes, stream ); + Util.WriteWORD( (ushort)(infoHeader.biBitCount), stream ); + Util.WriteDWORD( (uint)infoHeader.biCompression, stream ); + Util.WriteDWORD( (uint)infoHeader.biSizeImage, stream ); + Util.WriteDWORD( (uint)infoHeader.biXPelsPerMeter, stream ); + Util.WriteDWORD( (uint)infoHeader.biYPelsPerMeter, stream ); + Util.WriteDWORD( (uint)infoHeader.biClrUsed, stream ); + Util.WriteDWORD( (uint)infoHeader.biClrImportant, stream ); + }*/ + + + /// + /// ファイルにAVIStreamHeader構造体の値を書き込みます + /// + public static void aviWriteStreamHeader( AVIStreamHeader streamHeader, MainAVIHeader mainHeader, BinaryWriter stream ) { + //type(AVI_CONTAINER), intent(inout) :: avi + Util.fwrite( "strh", stream ); + Util.WriteDWORD( 56, stream );// call bmpQWordWrite( 56, avi%fp ) !// AVIStreamHeaderのサイズ + //fwrite( streamHeader.fccType, fp );// i = fwrite( avi%streamHeader%fccType, 1, 4, avi%fp ) + Util.WriteDWORD( (uint)streamHeader.fccType, stream ); + //fwrite( streamHeader.fccHandler, fp );// i = fwrite( streamHeader.fccHandler, 1, 4, fp ); + Util.WriteDWORD( (uint)streamHeader.fccHandler, stream ); + //WriteDWORD( 0, fp ); + Util.WriteDWORD( streamHeader.dwFlags, stream ); + //WriteDWORD( streamHeader.dwReserved1, fp ); + Util.WriteWORD( 0, stream );//wPriority + Util.WriteWORD( 0, stream );//wLanghage + Util.WriteDWORD( streamHeader.dwInitialFrames, stream ); + Util.WriteDWORD( streamHeader.dwScale, stream ); + Util.WriteDWORD( streamHeader.dwRate, stream ); + Util.WriteDWORD( streamHeader.dwStart, stream ); + Util.WriteDWORD( streamHeader.dwLength, stream ); + Util.WriteDWORD( streamHeader.dwSuggestedBufferSize, stream ); + Util.WriteDWORD( streamHeader.dwQuality, stream ); + Util.WriteDWORD( streamHeader.dwSampleSize, stream ); + Util.WriteWORD( 0, stream );//left + Util.WriteWORD( 0, stream );//top + Util.WriteWORD( (ushort)mainHeader.dwWidth, stream );//right + Util.WriteWORD( (ushort)mainHeader.dwHeight, stream );//bottom + } + + + /// + /// ファイルにMainAviHeader構造体の値を書き込みます + /// + public static void aviWriteMainHeader( MainAVIHeader mainHeader, BinaryWriter stream ) { + //type(AVI_CONTAINER), intent(inout) :: avi + Util.fwrite( "avih", stream );// i = fwrite( 'avih', 1, 4, avi%fp ) + Util.WriteDWORD( 56, stream ); // MainAVIHeaderのサイズ + Util.WriteDWORD( mainHeader.dwMicroSecPerFrame, stream ); + Util.WriteDWORD( 0/*this.mainHeader.dwMaxBytesPerSec*/, stream ); + Util.WriteDWORD( mainHeader.dwReserved1, stream ); + Util.WriteDWORD( mainHeader.dwFlags, stream ); + Util.WriteDWORD( mainHeader.dwTotalFrames, stream ); + Util.WriteDWORD( mainHeader.dwInitialFrames, stream ); + Util.WriteDWORD( mainHeader.dwStreams, stream ); + Util.WriteDWORD( 0/*this.mainHeader.dwSuggestedBufferSize*/, stream ); + Util.WriteDWORD( mainHeader.dwWidth, stream ); + Util.WriteDWORD( mainHeader.dwHeight, stream ); + Util.WriteDWORD( mainHeader.dwScale, stream ); + Util.WriteDWORD( mainHeader.dwRate, stream ); + Util.WriteDWORD( mainHeader.dwStart, stream ); + Util.WriteDWORD( mainHeader.dwLength, stream ); + }//end subroutine + + + public static void fwrite( string str, BinaryWriter fp ) { + int length = str.Length; + if ( length <= 0 ) { + return; + } + foreach ( char ch in str ) { + fp.Write( (byte)ch ); + } + } + + + /// + /// BYTE値を1byte分ファイルに書き込みます. + /// + /// + /// + public static void WriteBYTE( byte number, BinaryWriter fp ) { + fp.Write( number ); + } + + + /// + /// integer(2)のDWORD値を2byte分ファイルに書き込みます. + /// + /// + /// + public static void WriteWORD( ushort number, BinaryWriter fp ) { + byte k1, k2; + k1 = (byte)(number >> 8); + k2 = (byte)(number - (k1 << 8)); + fp.Write( k2 ); + fp.Write( k1 ); + } + + + /// + /// integer(4)のDWORD値を4byte分ファイルに書き込みます + /// + /// + /// + public static void WriteDWORD( uint number, BinaryWriter fp ) { + uint tmp; + byte k1, k2, k3, k4; + k1 = (byte)(number >> 24); + number -= (uint)(k1 << 24); + k2 = (byte)(number >> 16); + number -= (uint)(k2 << 16); + k3 = (byte)(number >> 8); + k4 = (byte)(number - (k3 << 8)); + fp.Write( k4 ); + fp.Write( k3 ); + fp.Write( k2 ); + fp.Write( k1 ); + } + + + /// + /// integer(8)のQWORD値を8byte分ファイルに書き込みます + /// + /// + /// + public static void WriteQWORD( ulong number, BinaryWriter fp ) { + byte k1, k2, k3, k4, k5, k6, k7, k8; + k1 = (byte)(number >> 56); + number -= (ulong)k1 << 56; + k2 = (byte)(number >> 48); + number -= (ulong)k2 << 48; + k3 = (byte)(number >> 40); + number -= (ulong)k3 << 40; + k4 = (byte)(number >> 32); + number -= (ulong)k4 << 32; + k5 = (byte)(number >> 24); + number -= (ulong)k5 << 24; + k6 = (byte)(number >> 16); + number -= (ulong)k6 << 16; + k7 = (byte)(number >> 8); + k8 = (byte)(number - (ulong)(k7 << 8)); + fp.Write( k8 ); + fp.Write( k7 ); + fp.Write( k6 ); + fp.Write( k5 ); + fp.Write( k4 ); + fp.Write( k3 ); + fp.Write( k2 ); + fp.Write( k1 ); + } + + + public static uint mmioFOURCC( string fcc ) { + char[] str = new char[4]; + for ( int i = 0; i < 4; i++ ) { + if ( i < fcc.Length ) { + str[i] = fcc[i]; + } else { + str[i] = ' '; + } + } + return mmioFOURCC( str[0], str[1], str[2], str[3] ); + } + + + public static uint mmioFOURCC( char ch0, char ch1, char ch2, char ch3 ) { + return (uint)((byte)(ch0) | ((byte)(ch1) << 8) | ((byte)(ch2) << 16) | ((byte)(ch3) << 24)); + } + } + +} diff --git a/trunk/Boare.Lib.Media/VCM.cs b/trunk/Boare.Lib.Media/VCM.cs new file mode 100644 index 0000000..dbaf62b --- /dev/null +++ b/trunk/Boare.Lib.Media/VCM.cs @@ -0,0 +1,238 @@ +/* + * VCM.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using System.IO; + +using bocoree; + +namespace Boare.Lib.Media { + + public class VCM { + public const uint ICMODE_QUERY = 4; + public const uint ICMF_CHOOSE_ALLCOMPRESSORS = 0x08; + public static readonly uint ICTYPE_VIDEO = Util.mmioFOURCC( 'v', 'i', 'd', 'c' ); + public static readonly uint ICTYPE_AUDIO = Util.mmioFOURCC( 'a', 'u', 'd', 'c' ); + public const uint ICM_COMPRESS_GET_FORMAT = 0x4004; + + [DllImport( "msvfw32.dll" )] + public static extern UInt32 ICOpen( UInt32 fccType, UInt32 fccHandler, uint wMode ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern int ICGetInfo( UInt32 hic, ICINFO* icinfo, int size ); + /*unsafe public static int ICGetInfo( UInt32 hic, ref ICINFO icinfo, int size ) { + IntPtr pt = new IntPtr( 0 ); + int r = w_ICGetInfo( hic, &pt, size ); + ICINFO result = new ICINFO(); + result = (ICINFO)Marshal.PtrToStructure( pt, result.GetType() ); + icinfo = result; + return r; + }*/ + + [DllImport( "msvfw32.dll" )] + public static extern int ICClose( UInt32 hic ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern int ICCompressorChoose( + IntPtr hwnd, + UInt32 uiFlags, + IntPtr pvIn, + IntPtr lpData, + COMPVARS* pc, + string lpszTitle + ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern int ICSeqCompressFrameStart( + COMPVARS* pc, + BITMAPINFO* lpbiIn + ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern void ICSeqCompressFrameEnd( COMPVARS* pc ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern void ICCompressorFree( COMPVARS* pc ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern IntPtr ICSeqCompressFrame( + COMPVARS* pc, + UInt32 uiFlags, + IntPtr lpBits, + Int32* pfKey, + Int32* plSize + ); + + [DllImport( "msvfw32.dll" )] + public static unsafe extern UIntPtr ICSendMessage( UInt32 hic, UInt32 wMsg, IntPtr dw1, IntPtr dw2 ); + + public static unsafe uint ICCompressGetFormatSize( UInt32 hic, BITMAPINFO* lpbi ) { + return ICCompressGetFormat( hic, lpbi, (BITMAPINFO*)0 ); + } + + + public static unsafe uint ICCompressGetFormat( UInt32 hic, BITMAPINFO* lpbiInput, BITMAPINFO* lpbiOutput ) { + return (uint)ICSendMessage( hic, ICM_COMPRESS_GET_FORMAT, (IntPtr)lpbiInput, (IntPtr)lpbiOutput ); + } + } + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct ICINFO { + public UInt32 dwSize; + public UInt32 fccType; + public UInt32 fccHandler; + public UInt32 dwFlags; + public UInt32 dwVersion; + public UInt32 dwVersionICM; + private sz16 szName; + private sz128 szDescription; + private sz128 szDriver; + public string Name { + get { + string t = szName.Value; + //return t.ToCharArray(); + return t; + } + } + public string Description { + get { + string t = szDescription.Value; + //return t.ToCharArray(); + return t; + } + } + public string Driver { + get { + string t = szDriver.Value; + //return t.ToCharArray(); + return t; + } + } + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + private struct sz4 { + UInt16 UInt16_1; + UInt16 UInt16_2; + UInt16 UInt16_3; + UInt16 UInt16_4; + public string Value { + get { + return "" + (char)UInt16_1 + (char)UInt16_2 + (char)UInt16_3 + (char)UInt16_4; + } + } + } + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + private struct sz16 { + sz4 sz4_1; + sz4 sz4_2; + sz4 sz4_3; + sz4 sz4_4; + public string Value { + get { + return sz4_1.Value + sz4_2.Value + sz4_3.Value + sz4_4.Value; + } + } + } + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + private struct sz64 { + sz16 sz16_1; + sz16 sz16_2; + sz16 sz16_3; + sz16 sz16_4; + public string Value { + get { + return sz16_1.Value + sz16_2.Value + sz16_3.Value + sz16_4.Value; + } + } + } + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + private struct sz128 { + sz64 sz64_1; + sz64 sz64_2; + public string Value { + get { + return sz64_1.Value + sz64_2.Value; + } + } + } + } + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public unsafe struct COMPVARS { + public Int32 cbSize; + public UInt32 dwFlags; + public UInt32 hic; // 元はHIC + public UInt32 fccType; + public UInt32 fccHandler; + public BITMAPINFOHEADER* lpbiIn; + public BITMAPINFOHEADER* lpbiOut; + public void* lpBitsOut; + public void* lpBitsPrev; + public Int32 lFrame; + public Int32 lKey; + public Int32 lDataRate; + public Int32 lQ; + public Int32 lKeyCount; + public void* lpState; + public Int32 cbState; + public override string ToString() { + return "{cbSize=" + cbSize + + ",dwFlags=" + dwFlags + + ",hic=" + hic + + ",fccType=" + fccType + + ",fccHandler=" + fccHandler + + ",lpbiIn=" + ((int)lpbiIn).ToString() + + ",lpbiOut=" + ((int)lpbiOut).ToString() + + ",lpBitsOut=" + ((int)lpBitsOut).ToString() + + ",lpBitsPrev=" + ((int)lpBitsPrev).ToString() + + ",lFrame=" + lFrame + + ",lKey=" + lKey + + ",lDataRate=" + lDataRate + + ",lQ=" + lQ + + ",lKeyCount=" + lKeyCount + + ",lpState=" + ((int)lpState).ToString() + + ",cbState=" + cbState + "}"; + } + } + + [StructLayout(LayoutKind.Sequential, Pack=1)] + public struct BITMAPINFO { + public BITMAPINFOHEADER bmiHeader; + public RGBQUAD bmiColors; + public unsafe void Write( BinaryWriter bw ) { + bmiHeader.Write( bw ); + int remain = (int)((bmiHeader.biSize - sizeof( BITMAPINFOHEADER )) / sizeof( RGBQUAD )); + fixed ( RGBQUAD* rgbq = &bmiColors ) { // これ以外に,「落ちないやり方」が無かった.メモリーが連続していることを祈るのみ + for ( int i = 0; i < remain; i++ ) { + bw.Write( rgbq[i].rgbBlue ); + bw.Write( rgbq[i].rgbGreen ); + bw.Write( rgbq[i].rgbRed ); + bw.Write( rgbq[i].rgbReserved ); + } + } + } + } + + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct RGBQUAD { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbReserved; + } + +} diff --git a/trunk/Boare.Lib.Media/VFW.cs b/trunk/Boare.Lib.Media/VFW.cs new file mode 100644 index 0000000..75c81c3 --- /dev/null +++ b/trunk/Boare.Lib.Media/VFW.cs @@ -0,0 +1,384 @@ +/* + * VFW.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; + +using bocoree; + +namespace Boare.Lib.Media { + + public static class VFW { + public static UInt32 streamtypeVIDEO = Util.mmioFOURCC( 'v', 'i', 'd', 's' ); + public static UInt32 streamtypeAUDIO = Util.mmioFOURCC( 'a', 'u', 'd', 's' ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamOpenFromFileW( + out IntPtr ppavi, + [MarshalAs( UnmanagedType.LPWStr )]string szfile, + uint fccType, + int lParam, + int mode, + int dumy + ); + + [DllImport( "avifil32.dll" )] + public static extern void AVIFileInit(); + + [DllImport( "avifil32.dll" )] + public static extern int AVIFileOpenW( ref int ptr_pfile, [MarshalAs( UnmanagedType.LPWStr )]string fileName, int flags, int dummy ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIFileCreateStream( + int ptr_pfile, out IntPtr ptr_ptr_avi, ref AVISTREAMINFOW ptr_streaminfo ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIMakeCompressedStream( + out IntPtr ppsCompressed, IntPtr aviStream, ref AVICOMPRESSOPTIONS ao, int dummy ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamSetFormat( + IntPtr aviStream, Int32 lPos, ref BITMAPINFOHEADER lpFormat, Int32 cbFormat ); + + [DllImport( "avifil32.dll" )] + public static unsafe extern int AVISaveOptions( + IntPtr hwnd, UInt32 flags, int nStreams, IntPtr* ptr_ptr_avi, AVICOMPRESSOPTIONS** ao ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamWrite( + IntPtr aviStream, Int32 lStart, Int32 lSamples, IntPtr lpBuffer, + Int32 cbBuffer, Int32 dwFlags, Int32 dummy1, Int32 dummy2 ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamRelease( IntPtr aviStream ); + + [DllImport( "avifil32.dll" )] + public static extern int AVIFileRelease( int pfile ); + + [DllImport( "avifil32.dll" )] + public static extern void AVIFileExit(); + + //Get a pointer to a GETFRAME object (returns 0 on error) + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrameOpen( + IntPtr pAVIStream, + ref BITMAPINFOHEADER bih ); + + //Get a stream from an open AVI file + [DllImport( "avifil32.dll" )] + public static extern int AVIFileGetStream( + int pfile, + out IntPtr ppavi, + int fccType, + int lParam ); + + //Get the start position of a stream + [DllImport( "avifil32.dll", PreserveSig = true )] + public static extern int AVIStreamStart( int pavi ); + + //Get the length of a stream in frames + [DllImport( "avifil32.dll", PreserveSig = true )] + public static extern int AVIStreamLength( int pavi ); + + //Get information about an open stream + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamInfo( + int pAVIStream, + ref AVISTREAMINFOW psi, + int lSize ); + + //Get a pointer to a packed DIB (returns 0 on error) + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrame( + int pGetFrameObj, + int lPos ); + //Release the GETFRAME object + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrameClose( + int pGetFrameObj ); + } + + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct AVISTREAMINFOW { + public UInt32 fccType, fccHandler, dwFlags, dwCaps; + + public UInt16 wPriority, wLanguage; + + public UInt32 dwScale, dwRate, + dwStart, dwLength, dwInitialFrames, dwSuggestedBufferSize, + dwQuality, dwSampleSize, rect_left, rect_top, + rect_right, rect_bottom, dwEditCount, dwFormatChangeCount; + public UInt16 szName0, szName1, szName2, szName3, szName4, szName5, + szName6, szName7, szName8, szName9, szName10, szName11, + szName12, szName13, szName14, szName15, szName16, szName17, + szName18, szName19, szName20, szName21, szName22, szName23, + szName24, szName25, szName26, szName27, szName28, szName29, + szName30, szName31, szName32, szName33, szName34, szName35, + szName36, szName37, szName38, szName39, szName40, szName41, + szName42, szName43, szName44, szName45, szName46, szName47, + szName48, szName49, szName50, szName51, szName52, szName53, + szName54, szName55, szName56, szName57, szName58, szName59, + szName60, szName61, szName62, szName63; + } + + + [Serializable] + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct AVICOMPRESSOPTIONS { + public UInt32 fccType; + public UInt32 fccHandler; + public UInt32 dwKeyFrameEvery; // only used with AVICOMRPESSF_KEYFRAMES + public UInt32 dwQuality; + public UInt32 dwBytesPerSecond; // only used with AVICOMPRESSF_DATARATE + public UInt32 dwFlags; + public IntPtr lpFormat; + public UInt32 cbFormat; + public IntPtr lpParms; + public UInt32 cbParms; + public UInt32 dwInterleaveEvery; + new public string ToString() { + return "fccType=" + fccType + "\n" + + "fccHandler=" + fccHandler + "\n" + + "dwKeyFrameEvery=" + dwKeyFrameEvery + "\n" + + "dwQuality=" + dwQuality + "\n" + + "dwBytesPerSecond=" + dwBytesPerSecond + "\n" + + "dwFlags=" + dwFlags + "\n" + + "lpFormat=" + lpFormat + "\n" + + "cbFormat=" + cbFormat + "\n" + + "lpParms=" + lpParms + "\n" + + "cbParms=" + cbParms + "\n" + + "dwInterleaveEvery=" + dwInterleaveEvery; + } + } + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct AVIStreamHeader { + public uint fccType;// character(len = 4) fccType + public uint fccHandler;//character(len = 4) fccHandler + public uint dwFlags; + public uint dwReserved1; + public uint dwInitialFrames; + public uint dwScale; + public uint dwRate; + public uint dwStart; + public uint dwLength; + public uint dwSuggestedBufferSize; + public uint dwQuality; + public uint dwSampleSize; + public void Write( Stream s ) { + bool bigendian = !BitConverter.IsLittleEndian; + byte[] b; + b = BitConverter.GetBytes( fccType ); + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( fccHandler ); + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwFlags ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwReserved1 ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwInitialFrames ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwScale ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwRate ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwStart ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwLength ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwSuggestedBufferSize ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwQuality ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( dwSampleSize ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + } + } + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct MainAVIHeader { + public uint dwMicroSecPerFrame; // specifies the period between video frames. This value indicates the overall timing for the file. + public uint dwMaxBytesPerSec; // specifies the approximate maximum data rate of the file. + public uint dwReserved1; + public uint dwFlags; // AVIF_HASINDEX, AVIF_MUSTUSEINDEX, AVIF_ISINTERLEAVED, AVIF_WASCAPTUREFILE, AVIF_COPYRIGHTED + public uint dwTotalFrames; // specifies the total number of frames of data in file. + public uint dwInitialFrames; // used for interleaved files. If you are creating interleaved files, specify the number of frames in the file prior to the initial frame of the AVI sequence in this field. + public uint dwStreams; // specifies the number of streams in the file. For example, a file with audio and video has 2 streams. + public uint dwSuggestedBufferSize; // specifies the suggested buffer size for reading the file. + public uint dwWidth; // specify the width of the AVI file in pixels. + public uint dwHeight; // specify the height of the AVI file in pixels. + public uint dwScale; // used to specify the general time scale that the file will use. + public uint dwRate; // used to specify the general time scale that the file will use. + public uint dwStart; // specify the starting time of the AVI file and the length of the file. The units are + public uint dwLength; // defined by dwRate and dwScale. The dwStart field is usually set to zero. + public void Write( Stream s ) { + byte[] b; + bool bigendian = !BitConverter.IsLittleEndian; + + // dwMicroSecPerFrame + b = BitConverter.GetBytes( dwMicroSecPerFrame ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwMaxBytesPerSec + b = BitConverter.GetBytes( dwMaxBytesPerSec ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwReserved1 + b = BitConverter.GetBytes( dwReserved1 ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwFlags + b = BitConverter.GetBytes( dwFlags ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwtotalFrames + b = BitConverter.GetBytes( dwTotalFrames ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwInitialFrames + b = BitConverter.GetBytes( dwInitialFrames ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwStreams + b = BitConverter.GetBytes( dwStreams ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwSuggestedBufferSize + b = BitConverter.GetBytes( dwSuggestedBufferSize ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwWidth + b = BitConverter.GetBytes( dwWidth ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwHeight + b = BitConverter.GetBytes( dwHeight ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwScale + b = BitConverter.GetBytes( dwScale ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwrate + b = BitConverter.GetBytes( dwRate ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwStart + b = BitConverter.GetBytes( dwStart ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + // dwLength + b = BitConverter.GetBytes( dwLength ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + } + } + + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct BITMAPFILEHEADER { + public Int16 bfType; //"magic cookie" - must be "BM" + public Int32 bfSize; + public Int16 bfReserved1; + public Int16 bfReserved2; + public Int32 bfOffBits; + } +} diff --git a/trunk/Boare.Lib.Media/Wave.cs b/trunk/Boare.Lib.Media/Wave.cs new file mode 100644 index 0000000..2615824 --- /dev/null +++ b/trunk/Boare.Lib.Media/Wave.cs @@ -0,0 +1,1317 @@ +/* + * Wave.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; + +using bocoree; + +namespace Boare.Lib.Media { + + public enum Channel { + Right, + Left, + } + + public enum WaveChannel : int { + Monoral = 1, + Stereo = 2 + } + + /// + /// Parameters of first formanto detection algorithm + /// + public class FormantoDetectionArguments { + private double m_peak_detection_threashold = 0.2; + private double m_moving_average_width = 25.0; + + /// + /// ピークを検出する閾値。フーリエ変換後の周波数の強度分布関数の値がこの値よりも大きい箇所で + /// 密度関数の導関数の符号が正から負へ変わる位置をピークとみなす。周波数密度関数は、最大値で + /// 規格化したのを使う。従って、0~1の値を指定する。 + /// + public double PeakDetectionThreshold { + get { + return m_peak_detection_threashold; + } + set { + m_peak_detection_threashold = value; + } + } + + /// + /// フーリエ変換した生の周波数の強度分布を平滑化する幅を2で割った値。Hzで指定。 + /// + public double MovingAverageWidth { + get { + return m_moving_average_width; + } + set { + m_moving_average_width = value; + } + } + } + + public class Wave : IDisposable { + private WaveChannel m_channel; + private ushort m_bit_per_sample; + private uint m_sample_rate; + private uint m_total_samples; + private byte[] L8; + private byte[] R8; + private short[] L16; + private short[] R16; + + //public void +#if DEBUG + private static bool s_test = false; + public static bool TestEnabled { + get { + return s_test; + } + set { + s_test = value; + } + } +#endif + + public double GetF0( uint time, double[] window_function ) { + return GetF0( time, window_function, new FormantoDetectionArguments() ); + } + + /// + /// 第timeサンプルにおけるフォルマントを取得する + /// + /// + /// + /// + public double GetF0( uint time, double[] window_function, FormantoDetectionArguments argument ) { + int window_size = window_function.Length; + double[] formanto = GetFormanto( time, window_function ); + int length = formanto.Length; + double max = 0.0; + for ( int i = 0; i < length; i++ ) { + formanto[i] = Math.Abs( formanto[i] ); + max = Math.Max( max, formanto[i] ); + } + double inv_max = 1.0 / max; + for ( int i = 0; i < length; i++ ) { + formanto[i] = formanto[i] * inv_max; + } + + double hz_from_index = 1.0 / (double)window_size * m_sample_rate * 0.5; +#if DEBUG + Console.WriteLine( "Wave+GetF0" ); + if ( s_test ) { + using ( StreamWriter sw = new StreamWriter( "formanto.txt" ) ) { + for ( int i = 0; i < length; i++ ) { + sw.WriteLine( (i * hz_from_index) + "\t" + formanto[i] ); + } + } + } +#endif + // 移動平均を計算 + double ma_width = argument.MovingAverageWidth; // 移動平均を取るHzを2で割ったもの + int ma_width_sample = (int)(window_size * 2 * ma_width / (double)m_sample_rate); + if ( ma_width_sample < 1 ) { + ma_width_sample = 1; + } +#if DEBUG + Console.WriteLine( "ma_width_sample=" + ma_width_sample ); +#endif + double[] ma = new double[length]; + for ( int i = 0; i < length; i++ ) { + int count = 0; + double sum = 0.0; + for ( int j = i - ma_width_sample; j < i + 2 * ma_width_sample; j++ ) { + if ( 0 <= j && j < length ) { + sum += formanto[j]; + count++; + } + } + ma[i] = sum / (double)count; + } +#if DEBUG + if ( s_test ) { + using ( StreamWriter sw = new StreamWriter( "ma.txt" ) ) { + for ( int i = 0; i < length; i++ ) { + sw.WriteLine( (i * hz_from_index) + "\t" + ma[i] ); + } + } + } +#endif + // ピークの位置を探す + double threshold = argument.PeakDetectionThreshold; + double last_slope = 0.0; + int index = -1; + List peak_positions = new List(); + bool first = true; + for ( int i = 1; i < window_size - 1; i++ ) { + double slope = ma[i + 1] - ma[i - 1]; + if ( ma[i] > threshold && slope <= 0.0 && 0.0 < last_slope ) { + if ( first ) { + index = i; + first = false; + } + //break; + peak_positions.Add( i * hz_from_index ); + } + last_slope = slope; + } +#if DEBUG + if ( s_test ) { + using ( StreamWriter sw = new StreamWriter( "peak_positions.txt" ) ) { + for ( int i = 0; i < peak_positions.Count; i++ ) { + sw.WriteLine( peak_positions[i].ToString() ); + } + } + } +#endif + if ( index > 0 ) { + List peaks = new List(); + double peak_distance_tolerance = index * hz_from_index / 5.0; //最小の周波数の5分の1 + double last_peak_pos = index * hz_from_index; + peaks.Add( last_peak_pos ); + for ( int i = 1; i < peak_positions.Count; i++ ) { + if ( peak_positions[i] - last_peak_pos > peak_distance_tolerance ) { + peaks.Add( peak_positions[i] ); + last_peak_pos = peak_positions[i]; + } + } +#if DEBUG + if ( s_test ) { + using ( StreamWriter sw = new StreamWriter( "peaks.txt" ) ) { + for ( int i = 0; i < peaks.Count; i++ ) { + sw.WriteLine( peaks[i] ); + } + } + } +#endif + double min_peak_distance = index * hz_from_index * 2.0 / 3.0; + /*for ( int i = 1; i < peaks.Count; i++ ) { + min_peak_distance = Math.Min( min_peak_distance, peaks[i] - peaks[i - 1] ); + }*/ +#if DEBUG + Console.WriteLine( "min_peak_distance=" + min_peak_distance ); + if ( s_test ) { + using ( StreamWriter sw = new StreamWriter( "evaluation.txt" ) ) { + for ( int i = (int)min_peak_distance; i < (int)(4 * min_peak_distance); i++ ) { + sw.WriteLine( i + "\t" + GetFormantoGetEvaluationValue( peaks, i ) ); + } + } + } +#endif + int smallest = (int)min_peak_distance; + double min_eval = GetFormantoGetEvaluationValue( peaks, smallest ); + for ( int i = (int)min_peak_distance; i < (int)(4 * min_peak_distance); i++ ) { + double eval = GetFormantoGetEvaluationValue( peaks, i ); + if ( min_eval > eval ) { + min_eval = eval; + smallest = i; + } + } + return smallest; + } else { + return 0; + } + } + + private static double GetFormantoGetEvaluationValue( List peaks, double t ) { + double ret = 0.0; + for ( int i = 0; i < peaks.Count; i++ ) { + int n_i = (int)(peaks[i] / t + 0.5); + double dt_i = peaks[i] - n_i * t; + ret += Math.Abs( dt_i ); + } + return ret / t; + } + + /*public unsafe double[,] GetFormanto( uint time, uint count, double[] window_function ) { + int size = window_function.Length; + double[] buffer = new double[size]; // 波形のバッファ + int nmaxsqrt = (int)Math.Sqrt( size ); + int[] ip_ = new int[nmaxsqrt + 2]; + double[] w_ = new double[size * 5 / 4]; + ip_[0] = 0; + + double[,] ret = new double[count, size]; + + for ( uint j = time; j < time + count; j++ ) { + GetNormalizedWave( (uint)(time - size / 2), ref buffer ); + // 窓関数をかける + for ( int i = 0; i < size; i++ ) { + buffer[i] *= window_function[i]; + } + + fixed ( int* ip = &ip_[0] ) + fixed ( double* w = &w_[0] ) + fixed ( double* a = &buffer[0] ) { + fft.rdft( size, 1, a, ip, w ); + } + for ( int i = 0; i < size; i++ ) { + ret[j - time, i] = buffer[i]; + } + } + return ret; + }*/ + + /// + /// 第timeサンプルにおけるフォルマントを取得する + /// + /// + /// + /// + public unsafe double[] GetFormanto( uint time, double[] window_function ) { + int size = window_function.Length; + double[] wv = GetNormalizedWave( (int)(time - size / 2), (uint)(size + 1) ); + // 窓関数をかける + for ( int i = 0; i < size; i++ ) { + wv[i] = wv[i] * window_function[i]; + } + int nmaxsqrt = (int)Math.Sqrt( size ); + int[] ip_ = new int[nmaxsqrt + 2]; + double[] w_ = new double[size * 5 / 4]; + ip_[0] = 0; + + fixed ( int* ip = &ip_[0] ) + fixed ( double* w = &w_[0] ) + fixed ( double* a = &wv[0] ) { + fft.rdft( size, 1, a, ip, w ); + } + return wv; + } + + + public double GetVolume( int start_sample, double[] window_function ) { + int window_size = window_function.Length; + double[] conv = new double[window_size]; + GetNormalizedWave( start_sample - window_size / 2, ref conv ); + double ret = 0.0; + for ( int i = 0; i < window_size; i++ ) { + ret += Math.Abs( conv[i] ) * window_function[i]; + } + return ret / (double)window_size; + } + + + /// + /// 指定したサンプル位置における音量を計算します + /// + /// + /// + /// + /// + public double GetVolume( int start_sample, int window_size, math.WindowFunctionType window_function_type ) { + double[] conv = new double[window_size]; + GetNormalizedWave( start_sample - window_size / 2, ref conv ); + double ret = 0.0; + for ( int i = 0; i < window_size; i++ ) { + double x = i / (double)window_size; + ret += Math.Abs( conv[i] ) * math.window_func( window_function_type, x ); + } + return ret / (double)window_size; + } + + + /// + /// 音量の時間変化を取得します + /// + /// 窓の幅(サンプル数) + /// 使用する窓関数 + /// 解像度(サンプル数) + /// + public double[] GetVolume( int window_size, math.WindowFunctionType window_function_type ) { + double[] conv = GetNormalizedWave(); + for ( int i = 0; i < conv.Length; i++ ) { + conv[i] = Math.Abs( conv[i] ); + } + // 最初に重み関数を取得 + double[] w = new double[window_size]; + for ( int i = 0; i < window_size; i++ ) { + double x = i / (double)window_size; + w[i] = math.window_func( window_function_type, x ); + } + double[] ret = new double[m_total_samples]; + double inv = 1.0 / (double)window_size; + int ws2 = window_size / 2; + for ( int i = 0; i < m_total_samples; i++ ) { + int start0 = i - ws2; + int start = start0; + int end = i + ws2; + double tinv = inv; + if ( start < 0 ) { + start = 0; + tinv = 1.0 / (double)(end - start + 1); + } + if ( m_total_samples <= end ) { + end = (int)m_total_samples - 1; + tinv = 1.0 / (double)(end - start + 1); + } + ret[i] = 0.0; + for ( int j = start; j <= end; j++ ) { + ret[i] += conv[j] * w[i - start0]; + } + ret[i] = ret[i] * tinv; + } + return ret; + } + + + public void GetNormalizedWave( int start_index, ref double[] conv ) { + int count = conv.Length; + int cp_start = start_index; + int cp_end = start_index + count; + if ( start_index < 0 ) { + for ( int i = 0; i < cp_start - start_index; i++ ) { + conv[i] = 0.0; + } + cp_start = 0; + } + if ( m_total_samples <= cp_end ) { + for ( int i = cp_end - start_index; i < count; i++ ) { + conv[i] = 0.0; + } + cp_end = (int)m_total_samples - 1; + } + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + for ( int i = cp_start; i < cp_end; i++ ) { + conv[i - start_index] = (L8[i] - 64.0) / 64.0; + } + } else { + for (int i = cp_start; i < cp_end; i++ ) { + conv[i - start_index] = L16[i] / 32768.0; + } + } + } else { + if ( m_bit_per_sample == 8 ) { + for (int i = cp_start; i < cp_end; i++ ) { + conv[i - start_index] = ((L8[i] + R8[i]) * 0.5 - 64.0) / 64.0; + } + } else { + for (int i = cp_start; i < cp_end; i++ ) { + conv[i - start_index] = (L16[i] + R16[i]) * 0.5 / 32768.0; + } + } + } + } + + + public double[] GetNormalizedWave() { + return GetNormalizedWave( 0, m_total_samples ); + } + + + + /// + /// -1から1までに規格化された波形を取得します + /// + /// + public double[] GetNormalizedWave( int start_index, uint count ) { + double[] conv = new double[count]; + GetNormalizedWave( start_index, ref conv ); + return conv; + } + + + public int this[int index, Channel channel] { + get { + if ( m_channel == WaveChannel.Monoral || channel == Channel.Left ) { + if ( m_bit_per_sample == 8 ) { + return L8[index]; + } else { + return L16[index]; + } + } else { + if ( m_bit_per_sample == 8 ) { + return R8[index]; + } else { + return R16[index]; + } + } + } + set { + if ( m_channel == WaveChannel.Monoral || channel == Channel.Left ) { + if ( m_bit_per_sample == 8 ) { + L8[index] = (byte)value; + } else { + L16[index] = (short)value; + } + } else { + if ( m_bit_per_sample == 8 ) { + R8[index] = (byte)value; + } else { + R16[index] = (short)value; + } + } + } + } + + + public int this[int index] { + get { + if ( m_bit_per_sample == 8 ) { + return L8[index]; + } else { + return L16[index]; + } + } + set { + if ( m_bit_per_sample == 8 ) { + L8[index] = (byte)value; + if ( m_channel == WaveChannel.Stereo ) { + R8[index] = (byte)value; + } + } else { + L16[index] = (short)value; + if ( m_channel == WaveChannel.Stereo ) { + R16[index] = (short)value; + } + } + } + } + + public double Get( int index ) { + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + return (L8[index] - 64.0) / 64.0; + } else { + return L16[index] / 32768.0; + } + } else { + if ( m_bit_per_sample == 8 ) { + return ((L8[index] + R8[index]) * 0.5 - 64.0) / 64.0; + } else { + return (L16[index] + R16[index]) * 0.5 / 32768.0; + } + } + } + + public uint SampleRate { + get { + return m_sample_rate; + } + } + + + public uint TotalSamples { + get { + return m_total_samples; + } + set { + m_total_samples = value; + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null ) { + L8 = new byte[m_total_samples]; + } else { + Array.Resize( ref L8, (int)m_total_samples ); + } + } else { + if ( L16 == null ) { + L16 = new short[m_total_samples]; + } else { + Array.Resize( ref L16, (int)m_total_samples ); + } + } + } else { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null ) { + L8 = new byte[m_total_samples]; + R8 = new byte[m_total_samples]; + } else { + Array.Resize( ref L8, (int)m_total_samples ); + Array.Resize( ref R8, (int)m_total_samples ); + } + } else { + if ( L16 == null ) { + L16 = new short[m_total_samples]; + R16 = new short[m_total_samples]; + } else { + Array.Resize( ref L16, (int)m_total_samples ); + Array.Resize( ref R16, (int)m_total_samples ); + } + } + } + } + } + + + public void Replace( Wave srcWave, uint srcStart, uint destStart, uint count ) { +#if DEBUG + Console.WriteLine( "Wave.Replace(Wave,uint,uint,uint)" ); +#endif + if ( m_channel != srcWave.m_channel || m_bit_per_sample != srcWave.m_bit_per_sample ) { + return; + } + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null || srcWave.L8 == null ) { + return; + } + } else { + if ( L16 == null || srcWave.L16 == null ) { + return; + } + } + } else { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null || R8 == null || srcWave.L8 == null || srcWave.R8 == null ) { + return; + } + } else { + if ( L16 == null || R16 == null || srcWave.L16 == null || srcWave.R16 == null ) { + return; + } + } + } + + count = (count > srcWave.TotalSamples - srcStart) ? srcWave.TotalSamples - srcStart : count; + uint new_last_index = destStart + count; + if ( m_total_samples < new_last_index ) { + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + Array.Resize( ref L8, (int)new_last_index ); + } else { + Array.Resize( ref L16, (int)new_last_index ); + } + } else { + if ( m_bit_per_sample == 8 ) { + Array.Resize( ref L8, (int)new_last_index ); + Array.Resize( ref R8, (int)new_last_index ); + } else { + Array.Resize( ref L16, (int)new_last_index ); + Array.Resize( ref R16, (int)new_last_index ); + } + } + m_total_samples = new_last_index; + } + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + Array.Copy( srcWave.L8, srcStart, L8, destStart, count ); + } else { + Array.Copy( srcWave.L16, srcStart, L16, destStart, count ); + } + } else { + if ( m_bit_per_sample == 8 ) { + Array.Copy( srcWave.L8, srcStart, L8, destStart, count ); + Array.Copy( srcWave.R8, srcStart, R8, destStart, count ); + } else { + Array.Copy( srcWave.L16, srcStart, L16, destStart, count ); + Array.Copy( srcWave.R16, srcStart, R16, destStart, count ); + } + } + } + + + public void Replace( byte[] data, uint start_index ) { + if ( m_channel != WaveChannel.Monoral || m_bit_per_sample != 8 || L8 == null ) { + return; + } + uint new_last_index = (uint)(start_index + data.Length); + if ( m_total_samples < new_last_index ) { + Array.Resize( ref L8, (int)new_last_index ); + m_total_samples = new_last_index; + } + for ( int i = 0; i < data.Length; i++ ) { + L8[i + start_index] = data[i]; + } + } + + + public void Replace( short[] data, uint start_index ) { + if ( m_channel != WaveChannel.Monoral || m_bit_per_sample != 16 || L16 == null ) { + return; + } + uint new_last_index = (uint)(start_index + data.Length); + if ( m_total_samples < new_last_index ) { + Array.Resize( ref L16, (int)new_last_index ); + m_total_samples = new_last_index; + } + for ( int i = 0; i < data.Length; i++ ) { + L16[i + start_index] = data[i]; + } + } + + + public void Replace( byte[] left, byte[] right, uint start_index ) { + if ( m_channel != WaveChannel.Stereo || m_bit_per_sample != 8 || L8 == null || R8 == null ) { + return; + } + uint new_last_index = (uint)(start_index + left.Length); + if ( m_total_samples < new_last_index ) { + Array.Resize( ref L8, (int)new_last_index ); + Array.Resize( ref R8, (int)new_last_index ); + m_total_samples = new_last_index; + } + for ( int i = 0; i < left.Length; i++ ) { + L8[i + start_index] = left[i]; + R8[i + start_index] = right[i]; + } + } + + + public void Replace( short[] left, short[] right, uint start_index ) { + if ( m_channel != WaveChannel.Stereo || m_bit_per_sample != 16 || L16 == null || R16 == null ) { + return; + } + uint new_last_index = (uint)(start_index + left.Length); + if ( m_total_samples < new_last_index ) { + Array.Resize( ref L16, (int)new_last_index ); + Array.Resize( ref R16, (int)new_last_index ); + m_total_samples = new_last_index; + } + for ( int i = 0; i < left.Length; i++ ) { + L16[i + start_index] = left[i]; + R16[i + start_index] = right[i]; + } + } + + public void Replace( float[] left, float[] right, uint start_index ) { + uint new_last_index = (uint)(start_index + left.Length); + if ( m_total_samples < new_last_index ) { + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null ) { + return; + } + Array.Resize( ref L8, (int)new_last_index ); + } else { + if ( L16 == null ) { + return; + } + Array.Resize( ref L16, (int)new_last_index ); + } + } else { + if ( m_bit_per_sample == 8 ) { + if ( L8 == null || R8 == null ) { + return; + } + Array.Resize( ref L8, (int)new_last_index ); + Array.Resize( ref R8, (int)new_last_index ); + } else { + if ( L16 == null || R16 == null ) { + return; + } + Array.Resize( ref L16, (int)new_last_index ); + Array.Resize( ref R16, (int)new_last_index ); + } + } + m_total_samples = new_last_index; + } + if ( m_channel == WaveChannel.Monoral ) { + float[] mono = new float[left.Length]; + for( int i = 0; i < left.Length; i++ ){ + mono[i] = (left[i] + right[i]) / 2f; + } + if ( m_bit_per_sample == 8 ) { + for ( int i = 0; i < mono.Length; i++ ) { + L8[i + start_index] = (byte)((mono[i] + 1.0f) / 2f * 255f); + } + } else { + for ( int i = 0; i < mono.Length; i++ ) { + L16[i + start_index] = (short)(mono[i] * 32768f); + } + } + } else { + if ( m_bit_per_sample == 8 ) { + for ( int i = 0; i < left.Length; i++ ) { + L8[i + start_index] = (byte)((left[i] + 1.0f) / 2f * 255f); + R8[i + start_index] = (byte)((right[i] + 1.0f) / 2f * 255f); + } + } else { + for ( int i = 0; i < left.Length; i++ ) { + L16[i + start_index] = (short)(left[i] * 32768f); + R16[i + start_index] = (short)(right[i] * 32768f); + } + } + } + } + + public void PrintToText( string path ) { + using ( StreamWriter sw = new StreamWriter( path ) ) { + if ( m_channel == WaveChannel.Monoral ) { + if ( m_bit_per_sample == 8 ) { + for ( int i = 0; i < m_total_samples; i++ ) { + sw.WriteLine( L8[i] ); + } + } else { + for ( int i = 0; i < m_total_samples; i++ ) { + sw.WriteLine( L16[i] ); + } + } + } else { + if ( m_bit_per_sample == 8 ) { + for ( int i = 0; i < m_total_samples; i++ ) { + sw.WriteLine( L8[i] + "\t" + R8[i] ); + } + } else { + for ( int i = 0; i < m_total_samples; i++ ) { + sw.WriteLine( L16[i] + "\t" + R16[i] ); + } + } + } + } + } + + public void Dispose() { + L8 = null; + R8 = null; + L16 = null; + R16 = null; + GC.Collect(); + } + + /// + /// サンプルあたりのビット数を8に変更する + /// + public void ConvertTo8Bit() { + if ( m_bit_per_sample == 8 ) { + return; + } + + // 先ず左チャンネル + L8 = new byte[L16.Length]; + for ( int i = 0; i < L16.Length; i++ ) { + double new_val = (L16[i] + 32768.0) / 65535.0 * 255.0; + L8[i] = (byte)new_val; + } + L16 = null; + + // 存在すれば右チャンネルも + if ( m_channel == WaveChannel.Stereo ) { + R8 = new byte[R16.Length]; + for ( int i = 0; i < R16.Length; i++ ) { + double new_val = (R16[i] + 32768.0) / 65535.0 * 255.0; + R8[i] = (byte)new_val; + } + R16 = null; + } + + m_bit_per_sample = 8; + } + + /// + /// ファイルに保存 + /// + /// + public void Write( string file ) { + using ( FileStream fs = new FileStream( file, FileMode.Create ) ) { + // RIFF + fs.WriteByte( 0x52 ); + fs.WriteByte( 0x49 ); + fs.WriteByte( 0x46 ); + fs.WriteByte( 0x46 ); + + // ファイルサイズ - 8最後に記入 + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + + // WAVE + fs.WriteByte( 0x57 ); + fs.WriteByte( 0x41 ); + fs.WriteByte( 0x56 ); + fs.WriteByte( 0x45 ); + + // fmt + fs.WriteByte( 0x66 ); + fs.WriteByte( 0x6d ); + fs.WriteByte( 0x74 ); + fs.WriteByte( 0x20 ); + + // fmt チャンクのサイズ + fs.WriteByte( 0x12 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + + // format ID + fs.WriteByte( 0x01 ); + fs.WriteByte( 0x00 ); + + // チャンネル数 + if ( m_channel == WaveChannel.Monoral ) { + fs.WriteByte( 0x01 ); + fs.WriteByte( 0x00 ); + } else { + fs.WriteByte( 0x02 ); + fs.WriteByte( 0x00 ); + } + + // サンプリングレート + byte[] buf = BitConverter.GetBytes( m_sample_rate ); + WriteByteArray( fs, buf, 4 ); + + // データ速度 + ushort block_size = (ushort)(m_bit_per_sample / 8 * (int)m_channel); + uint data_rate = m_sample_rate * block_size; + buf = BitConverter.GetBytes( data_rate ); + WriteByteArray( fs, buf, 4 ); + + // ブロックサイズ + buf = BitConverter.GetBytes( block_size ); + WriteByteArray( fs, buf, 2 ); + + // サンプルあたりのビット数 + buf = BitConverter.GetBytes( m_bit_per_sample ); + WriteByteArray( fs, buf, 2 ); + + // 拡張部分 + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + + // data + fs.WriteByte( 0x64 ); + fs.WriteByte( 0x61 ); + fs.WriteByte( 0x74 ); + fs.WriteByte( 0x61 ); + + // size of data chunk + uint size = block_size * m_total_samples; + buf = BitConverter.GetBytes( size ); + WriteByteArray( fs, buf, 4 ); + + // 波形データ + for ( int i = 0; i < m_total_samples; i++ ) { + if ( m_bit_per_sample == 8 ) { + fs.WriteByte( L8[i] ); + if ( m_channel == WaveChannel.Stereo ) { + fs.WriteByte( R8[i] ); + } + } else { + buf = BitConverter.GetBytes( L16[i] ); + WriteByteArray( fs, buf, 2 ); + if ( m_channel == WaveChannel.Stereo ) { + buf = BitConverter.GetBytes( R16[i] ); + WriteByteArray( fs, buf, 2 ); + } + } + } + + // 最後にWAVEチャンクのサイズ + uint position = (uint)fs.Position; + fs.Seek( 4, SeekOrigin.Begin ); + buf = BitConverter.GetBytes( position - 8 ); + WriteByteArray( fs, buf, 4 ); + } + } + + private static void WriteByteArray( FileStream fs, byte[] dat, int limit ) { + fs.Write( dat, 0, (dat.Length > limit) ? limit : dat.Length ); + if ( dat.Length < limit ) { + for ( int i = 0; i < limit - dat.Length; i++ ) { + fs.WriteByte( 0x00 ); + } + } + } + + /// + /// ステレオをモノラル化 + /// + public void Monoralize() { + if ( m_channel != WaveChannel.Stereo ) { + return; + } + if ( m_bit_per_sample == 8 ) { + for ( int i = 0; i < L8.Length; i++ ) { + L8[i] = (byte)((L8[i] + R8[i]) / 2); + } + R8 = null; + m_channel = WaveChannel.Monoral; + } else { + for ( int i = 0; i < L16.Length; i++ ) { + L16[i] = (short)((L16[i] + R16[i]) / 2); + } + R16 = null; + m_channel = WaveChannel.Monoral; + } + } + + + /// + /// 前後の無音部分を削除します + /// + public void TrimSilence() { +#if DEBUG + Console.WriteLine( "Wave.TrimSilence" ); +#endif + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + int non_silence_begin = 1; + for ( int i = 1; i < L8.Length; i++ ) { + if ( L8[i] != 0x80 ) { + non_silence_begin = i; + break; + } + } + int non_silence_end = L8.Length - 1; + for ( int i = L8.Length - 1; i >= 0; i-- ) { + if ( L8[i] != 0x80 ) { + non_silence_end = i; + break; + } + } + int count = non_silence_end - non_silence_begin + 1; + R8 = new byte[count]; + Array.Copy( L8, non_silence_begin, R8, 0, count ); + L8 = null; + L8 = new byte[count]; + Array.Copy( R8, L8, count ); + R8 = null; + } else { + int non_silence_begin = 1; + for ( int i = 1; i < L8.Length; i++ ) { + if ( L8[i] != 0x80 || R8[i] != 0x80 ) { + non_silence_begin = i; + break; + } + } + int non_silence_end = L8.Length - 1; + for ( int i = L8.Length - 1; i >= 0; i-- ) { + if ( L8[i] != 0x80 || R8[i] != 0x80 ) { + non_silence_end = i; + break; + } + } + int count = non_silence_end - non_silence_begin + 1; + byte[] buf = new byte[count]; + Array.Copy( L8, non_silence_begin, buf, 0, count ); + L8 = null; + L8 = new byte[count]; + Array.Copy( buf, L8, count ); + Array.Copy( R8, non_silence_begin, buf, 0, count ); + R8 = null; + R8 = new byte[count]; + Array.Copy( buf, R8, count ); + buf = null; + } + } else { + if ( m_channel == WaveChannel.Monoral ) { + int non_silence_begin = 1; + for ( int i = 1; i < L16.Length; i++ ) { + if ( L16[i] != 0 ) { + non_silence_begin = i; + break; + } + } + int non_silence_end = L16.Length - 1; + for ( int i = L16.Length - 1; i >= 0; i-- ) { + if ( L16[i] != 0 ) { + non_silence_end = i; + break; + } + } + int count = non_silence_end - non_silence_begin + 1; + R16 = new short[count]; + Array.Copy( L16, non_silence_begin, R16, 0, count ); + Array.Resize( ref L16, count ); + Array.Copy( R16, L16, count ); + R16 = null; + } else { + int non_silence_begin = 1; + for ( int i = 1; i < L16.Length; i++ ) { + if ( L16[i] != 0 || R16[i] != 0 ) { + non_silence_begin = i; + break; + } + } + int non_silence_end = L16.Length - 1; + for ( int i = L16.Length - 1; i >= 0; i-- ) { + if ( L16[i] != 0 || R16[i] != 0 ) { + non_silence_end = i; + break; + } + } +#if DEBUG + Console.WriteLine( " non_silence_beign=" + non_silence_begin ); + Console.WriteLine( " non_silence_end=" + non_silence_end ); +#endif + int count = non_silence_end - non_silence_begin + 1; + short[] buf = new short[count]; + Array.Copy( L16, non_silence_begin, buf, 0, count ); + Array.Resize( ref L16, count ); + Array.Copy( buf, 0, L16, 0, count ); + + Array.Copy( R16, non_silence_begin, buf, 0, count ); + Array.Resize( ref R16, count ); + Array.Copy( buf, 0, R16, 0, count ); + buf = null; + } + } + + if ( m_bit_per_sample == 8 ) { + m_total_samples = (uint)L8.Length; + } else { + m_total_samples = (uint)L16.Length; + } + } + + public Wave() { + m_channel = WaveChannel.Stereo; + m_bit_per_sample = 16; + m_sample_rate = 44100; + } + + public Wave( WaveChannel channels, ushort bit_per_sample, uint sample_rate, uint initial_capacity ) { + m_channel = channels; + m_bit_per_sample = bit_per_sample; + m_sample_rate = sample_rate; + m_total_samples = initial_capacity; + if ( m_bit_per_sample == 8 ) { + L8 = new byte[m_total_samples]; + if ( m_channel == WaveChannel.Stereo ) { + R8 = new byte[m_total_samples]; + } + } else if ( m_bit_per_sample == 16 ) { + L16 = new short[m_total_samples]; + if ( m_channel == WaveChannel.Stereo ) { + R16 = new short[m_total_samples]; + } + } + } + + public void Append( double[] L, double[] R ) { + int length = Math.Min( L.Length, R.Length ); + int old_length = L16.Length; + if ( m_bit_per_sample == 16 && m_channel == WaveChannel.Stereo ) { + Array.Resize( ref L16, (int)(m_total_samples + length) ); + Array.Resize( ref R16, (int)(m_total_samples + length) ); + m_total_samples += (uint)length; + for ( int i = old_length; i < m_total_samples; i++ ) { + L16[i] = (short)(L[i - old_length] * 32768f); + R16[i] = (short)(R[i - old_length] * 32768f); + } + } //else ... TODO: Wave+Append他のbitpersec, channelのとき + } + + /*public void Append( short[] L, short[] R ) { + int length = Math.Min( L.Length, R.Length ); + int old_length = L16.Length; + if ( m_bit_per_sample == 16 && m_channel == WaveChannel.Stereo ) { + Array.Resize( ref L16, (int)(m_total_samples + length) ); + Array.Resize( ref R16, (int)(m_total_samples + length) ); + m_total_samples += (uint)length; + for ( int i = old_length; i < m_total_samples; i++ ) { + L16[i] = L[i - old_length]; + R16[i] = R[i - old_length]; + } + } //else ... TODO: Wave+Append他のbitpersec, channelのとき + }*/ + + public Wave( string path ) { + Read( path ); + } + + + public bool Read( string path ) { + FileStream fs = null; + try { + fs = new FileStream( path, FileMode.Open ); + // check RIFF header + byte[] buf = new byte[4]; + fs.Read( buf, 0, 4 ); + if ( buf[0] != 0x52 || + buf[1] != 0x49 || + buf[2] != 0x46 || + buf[3] != 0x46 ) { +#if DEBUG + System.Diagnostics.Debug.WriteLine( "invalid header" ); +#endif + fs.Close(); + return false; + } + + // detect size of RIFF chunk + fs.Read( buf, 0, 4 ); + uint riff_chunk_size = GetUIntFrom4Bytes( buf ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "riff_chunk_size=" + riff_chunk_size ); +#endif + + // check wave header + fs.Seek( 8, SeekOrigin.Begin ); + fs.Read( buf, 0, 4 ); + if ( buf[0] != 0x57 || + buf[1] != 0x41 || + buf[2] != 0x56 || + buf[3] != 0x45 ) { +#if DEBUG + System.Diagnostics.Debug.WriteLine( "invalid wave header" ); +#endif + fs.Close(); + return false; + } + + // check fmt chunk header + fs.Read( buf, 0, 4 ); + if ( buf[0] != 0x66 || + buf[1] != 0x6d || + buf[2] != 0x74 || + buf[3] != 0x20 ) { +#if DEBUG + System.Diagnostics.Debug.WriteLine( "invalid fmt header" ); +#endif + fs.Close(); + return false; + } + + // detect size of fmt chunk + uint fmt_chunk_bytes; + fs.Read( buf, 0, 4 ); + fmt_chunk_bytes = GetUIntFrom4Bytes( buf ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "fmt_chunk_bytes=" + fmt_chunk_bytes ); +#endif + + // get format ID + fs.Read( buf, 0, 2 ); + ushort format_id = GetUShortFrom2Bytes( buf ); + if ( format_id != 1 ) { + fs.Close(); + return false; + } +#if DEBUG + System.Diagnostics.Debug.WriteLine( "format_id=" + format_id ); +#endif + + // get the number of channel(s) + fs.Read( buf, 0, 2 ); + ushort num_channels = GetUShortFrom2Bytes( buf ); + if ( num_channels == 1 ) { + m_channel = WaveChannel.Monoral; + } else if ( num_channels == 2 ) { + m_channel = WaveChannel.Stereo; + } else { + fs.Close(); + return false; + } +#if DEBUG + System.Diagnostics.Debug.WriteLine( "num_channels=" + num_channels ); +#endif + + // get sampling rate + fs.Read( buf, 0, 4 ); + m_sample_rate = GetUIntFrom4Bytes( buf ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "m_sample_rate=" + m_sample_rate ); +#endif + + // get bit per sample + fs.Seek( 0x22, SeekOrigin.Begin ); + fs.Read( buf, 0, 2 ); + m_bit_per_sample = GetUShortFrom2Bytes( buf ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "m_bit_per_sample=" + m_bit_per_sample ); +#endif + if ( m_bit_per_sample != 0x08 && m_bit_per_sample != 0x10 ) { + fs.Close(); + return false; + } + + // move to the end of fmt chunk + fs.Seek( 0x14 + fmt_chunk_bytes, SeekOrigin.Begin ); + + // move to the top of data chunk + fs.Read( buf, 0, 4 ); + string tag = new string( new char[] { (char)buf[0], (char)buf[1], (char)buf[2], (char)buf[3] } ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "tag=" + tag ); +#endif + while ( tag != "data" ) { + fs.Read( buf, 0, 4 ); + uint size = GetUIntFrom4Bytes( buf ); + fs.Seek( size, SeekOrigin.Current ); + fs.Read( buf, 0, 4 ); + tag = new string( new char[] { (char)buf[0], (char)buf[1], (char)buf[2], (char)buf[3] } ); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "tag=" + tag ); +#endif + } + + // get size of data chunk + fs.Read( buf, 0, 4 ); + uint data_chunk_bytes = GetUIntFrom4Bytes( buf ); + m_total_samples = (uint)(data_chunk_bytes / (num_channels * m_bit_per_sample / 8)); +#if DEBUG + System.Diagnostics.Debug.WriteLine( "m_total_samples=" + m_total_samples ); +#endif + + // prepare data + if ( m_bit_per_sample == 8 ) { + L8 = new byte[m_total_samples]; + if ( m_channel == WaveChannel.Stereo ) { + R8 = new byte[m_total_samples]; + } + } else { + L16 = new short[m_total_samples]; + if ( m_channel == WaveChannel.Stereo ) { + R16 = new short[m_total_samples]; + } + } + + // read data + byte[] buf2 = new byte[2]; + for ( int i = 0; i < m_total_samples; i++ ) { + if ( m_bit_per_sample == 8 ) { + fs.Read( buf, 0, 1 ); + L8[i] = buf[0]; + if ( m_channel == WaveChannel.Stereo ) { + fs.Read( buf, 0, 1 ); + R8[i] = buf[0]; + } + } else { + fs.Read( buf2, 0, 2 ); + /*if ( BitConverter.IsLittleEndian ) { + byte b = buf2[0]; + buf2[0] = buf2[1]; + buf2[1] = b; + }*/ + L16[i] = BitConverter.ToInt16( buf2, 0 ); + if ( m_channel == WaveChannel.Stereo ) { + fs.Read( buf2, 0, 2 ); + /*if ( BitConverter.IsLittleEndian ) { + byte b = buf2[0]; + buf2[0] = buf2[1]; + buf2[1] = b; + }*/ + R16[i] = BitConverter.ToInt16( buf2, 0 ); + } + } + } + } catch ( Exception ex ) { +#if DEBUG + System.Diagnostics.Debug.Write( ex.StackTrace ); +#endif + } finally { + if ( fs != null ) { + fs.Close(); + } + } + return true; + } + + + private uint GetUIntFrom4Bytes( byte[] dat ) { + return (uint)(dat[3] << 24) + (uint)(dat[2] << 16) + (uint)(dat[1] << 8) + (uint)dat[0]; + } + + + private ushort GetUShortFrom2Bytes( byte[] dat ) { + return (ushort)((dat[1] << 8) | dat[0]); + } + } + +} diff --git a/trunk/Boare.Lib.Media/WavePlay.cs b/trunk/Boare.Lib.Media/WavePlay.cs new file mode 100644 index 0000000..3730602 --- /dev/null +++ b/trunk/Boare.Lib.Media/WavePlay.cs @@ -0,0 +1,626 @@ +/* + * WavePlay.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Runtime.InteropServices; + +using bocoree; + +namespace Boare.Lib.Media { + + public delegate void FirstBufferWrittenCallback(); + + public unsafe class WavePlay { + const int _NUM_BUF = 3; // バッファの数 + int s_block_size; // 1個のバッファのサイズ(サンプル) + int s_sample_rate; // サンプリングレート + WAVEFORMATEX s_wave_formatx; // WAVEファイルヘッダ + //IntPtr s_ptr_wave_formatx; + IntPtr s_hwave_out; // WAVE再生デバイス + + WAVEHDR[] s_wave_header = new WAVEHDR[_NUM_BUF];// WAVEヘッダ + IntPtr[] s_ptr_wave_header = new IntPtr[_NUM_BUF]; + + uint*[] s_wave = new uint*[_NUM_BUF]; // バッファ + IntPtr[] s_ptr_wave = new IntPtr[_NUM_BUF]; + + bool[] s_done = new bool[_NUM_BUF]; + int s_current_buffer; // 次回書き込むべきバッファのインデクス + uint s_processed_count; // 初回はバッファを_NUM_BUF個全部埋めなければいけないので、最初の _NUM_BUF + 1 回はカウントを行う。そのためのカウンタ + bool s_abort_required; // 再生の中断が要求された時立つフラグ + int s_buffer_loc; // 書き込み中のバッファ内の、現在位置 + bool s_playing; // 再生中かどうかを表すフラグ + int s_error_samples; // appendされた波形データの内、先頭のs_error_samples分を省く。通常の使い方なら常に0だが、vocaloid2 vstiで使う場合、プリセンド分を除いてwaveOutWriteしなければいけないので非0になる。 + int s_last_buffer; // 最後に再生されるバッファの番号。負値の場合、append_lastが未だ呼ばれていないことを意味する。 + FirstBufferWrittenCallback s_first_buffer_written_callback; // 最初のバッファが書き込まれたとき呼び出されるコールバック関数 + WaveReader[] s_wave_reader; + int s_num_wave_reader; // s_wave_readerの個数 + float*[] s_another_wave_l; + IntPtr[] s_ptr_another_wave_l; + float*[] s_another_wave_r; + IntPtr[] s_ptr_another_wave_r; + long s_wave_read_offset_samples; + float* s_wave_buffer_l; + IntPtr s_ptr_wave_buffer_l; + float* s_wave_buffer_r; + IntPtr s_ptr_wave_buffer_r; + + delegateWaveOutProc s_wave_callback; + + /// コールバック関数 + void wave_callback( IntPtr hwo, uint uMsg, uint dwInstance, uint dwParam1, uint dwParam2 ) { +#if DEBUG + Console.WriteLine( "WavePlay.wave_callback; uMsg=" + uMsg ); +#endif + if ( uMsg == windows.MM_WOM_DONE ) { + int index_done = 0; + WAVEHDR whdr = (WAVEHDR)Marshal.PtrToStructure( new IntPtr( dwParam1 ), typeof( WAVEHDR ) ); + int dwuser = whdr.dwUser.ToInt32(); + if ( dwuser >= _NUM_BUF ) { + index_done = dwuser - _NUM_BUF; + } else { + index_done = dwuser; + } +#if DEBUG + bocoree.debug.push_log( "dwuser=" + dwuser ); + bocoree.debug.push_log( "index_done=" + index_done ); +#endif + s_done[index_done] = true; + if ( s_last_buffer == index_done ) { + s_playing = false; + } + if ( dwuser >= _NUM_BUF ) { + s_wave_header[index_done].dwUser = new IntPtr( index_done ); + } +#if DEBUG + bocoree.debug.push_log( "whdr.dwUser=" + whdr.dwUser.ToInt32() ); + bocoree.debug.push_log( "dwParam1=0x" + Convert.ToString( dwParam1, 16 ) + "; dwParam2=0x" + Convert.ToString( dwParam2, 16 ) ); +#endif + } + } + + void append_cor( float** a_data, uint length, double amp_left, double amp_right, bool is_last_mode ) { +#if DEBUG + + bocoree.debug.push_log( "append_cor *************************************************************" ); + bocoree.debug.push_log( " length=" + length ); + bocoree.debug.push_log( " s_hwave_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + s_playing = true; + int jmax = (int)length; + int remain = 0; + IntPtr ptr_data = IntPtr.Zero; + IntPtr ptr_data0 = IntPtr.Zero; + IntPtr ptr_data1 = IntPtr.Zero; + ptr_data = Marshal.AllocHGlobal( sizeof( float* ) * 2 ); + float** data = (float**)ptr_data.ToPointer();// new float*[2]; + bool cleaning_required = false; + if ( s_error_samples > 0 ) { + if ( s_error_samples >= length ) { + s_error_samples -= (int)length; + return; + } + cleaning_required = true; + int actual_length = (int)length - s_error_samples; +#if DEBUG + bocoree.debug.push_log( " actual_length=" + actual_length ); +#endif + ptr_data0 = Marshal.AllocHGlobal( sizeof( float ) * actual_length ); + ptr_data1 = Marshal.AllocHGlobal( sizeof( float ) * actual_length ); + data[0] = (float*)ptr_data0.ToPointer(); + data[1] = (float*)ptr_data1.ToPointer(); + for ( int i = 0; i < actual_length; i++ ) { + data[0][i] = a_data[0][i + s_error_samples]; + data[1][i] = a_data[1][i + s_error_samples]; + } + s_error_samples = 0; + length = (uint)actual_length; + jmax = (int)length; + } else { + data = a_data; + } + + if ( length + s_buffer_loc >= s_block_size ) { + jmax = s_block_size - s_buffer_loc; + remain = (int)length - (int)jmax; + } + float aright = (float)amp_right; + float aleft = (float)amp_left; + + for ( int j = 0; j < jmax; j++ ) { + s_wave_buffer_l[j + s_buffer_loc] = data[1][j]; + s_wave_buffer_r[j + s_buffer_loc] = data[0][j]; + } + s_buffer_loc += jmax; + + if ( s_buffer_loc >= s_block_size ) { + // バッファー充填完了.バッファーを転送し、waveOutWriteが書き込めるタイミングまで待機 +#if DEBUG + bocoree.debug.push_log( "append_cor; waiting(1) " + s_current_buffer + "..." ); +#endif + while ( true ) { + if ( s_abort_required ) { + s_abort_required = false; + goto clean_and_exit; + } + if ( s_done[s_current_buffer] ) { + break; + } + } +#if DEBUG + bocoree.debug.push_log( "append_cor; ...exit" ); +#endif + + s_processed_count++; + mix( (int)s_processed_count, aleft, aright ); + + if ( s_processed_count == _NUM_BUF ) { + s_done[0] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret = windows.waveOutWrite( s_hwave_out, ref s_wave_header[0], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret=" + ret ); +#endif +#if DEBUG + bocoree.debug.push_log( "(s_first_buffer_wirtten_callback==null)=" + (s_first_buffer_written_callback == null) ); +#endif + if ( s_first_buffer_written_callback != null ) { +#if DEBUG + bocoree.debug.push_log( "append_cor; calling s_first_buffer_written_callback" ); +#endif + s_first_buffer_written_callback(); + } + for ( int buffer_index = 1; buffer_index < _NUM_BUF; buffer_index++ ) { + s_done[buffer_index] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret2 = windows.waveOutWrite( s_hwave_out, ref s_wave_header[buffer_index], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret2=" + ret2 ); +#endif + } + s_current_buffer = _NUM_BUF - 1; + } else if ( s_processed_count > _NUM_BUF ) { + s_done[s_current_buffer] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret3 = windows.waveOutWrite( s_hwave_out, ref s_wave_header[s_current_buffer], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret3=" + ret3 ); +#endif + } + s_current_buffer++; + if ( s_current_buffer >= _NUM_BUF ) { + s_current_buffer = 0; + } + + s_buffer_loc = 0; + } + + if ( remain > 0 ) { + for ( int j = jmax; j < length; j++ ) { + s_wave_buffer_l[j - jmax] = data[1][j]; + s_wave_buffer_r[j - jmax] = data[0][j]; + } + if ( is_last_mode ) { + for ( int j = (int)length - jmax; j < s_block_size; j++ ) { + s_wave_buffer_l[j] = 0.0f; + s_wave_buffer_r[j] = 0.0f; + } + } + s_buffer_loc = remain; + } + + if ( is_last_mode ) { + if ( s_processed_count < _NUM_BUF ) { + // _NUM_BUFブロック分のデータを未だ全て受信していない場合。バッファが未だひとつも書き込まれていないので + // 0番のブロックから順に書き込む + s_processed_count++; + mix( (int)s_processed_count, aleft, aright ); + s_done[0] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret35 = windows.waveOutWrite( s_hwave_out, ref s_wave_header[0], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret35=" + ret35 ); + bocoree.debug.push_log( "(s_first_buffer_written_callback==null)=" + (s_first_buffer_written_callback == null) ); +#endif + if ( s_first_buffer_written_callback != null ) { +#if DEBUG + bocoree.debug.push_log( "append_cor; calling s_first_buffer_written_callback" ); +#endif + s_first_buffer_written_callback(); + } + for ( int i = 1; i < _NUM_BUF - 1; i++ ) { + s_processed_count++; + mix( (int)s_processed_count, aleft, aright ); + s_done[i] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret36 = windows.waveOutWrite( s_hwave_out, ref s_wave_header[i], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret36=" + ret36 ); +#endif + } + } + ulong zero = MAKELONG( 0, 0 ); + for ( int j = s_buffer_loc; j < s_block_size; j++ ) { + s_wave_buffer_l[j] = 0.0f; + s_wave_buffer_r[j] = 0.0f; + } +#if DEBUG + bocoree.debug.push_log( "append_cor; waiting(3) " + s_current_buffer + "..." ); +#endif + while ( !s_done[s_current_buffer] ) { + if ( s_abort_required ) { + s_abort_required = false; + goto clean_and_exit; + } + } +#if DEBUG + bocoree.debug.push_log( "append_cor; ...exit" ); +#endif + s_processed_count++; + mix( (int)s_processed_count, aleft, aright ); + s_done[s_current_buffer] = false; +#if DEBUG + bocoree.debug.push_log( "calling waveOutWrite...; s_hawve_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + uint ret4 = windows.waveOutWrite( s_hwave_out, ref s_wave_header[s_current_buffer], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + bocoree.debug.push_log( "...done; ret4=" + ret4 ); +#endif + } + clean_and_exit: + if ( is_last_mode ) { + s_last_buffer = s_current_buffer; + } + if ( cleaning_required ) { + Marshal.FreeHGlobal( ptr_data0 ); //delete [] data[0]; + Marshal.FreeHGlobal( ptr_data1 ); //delete [] data[1]; + Marshal.FreeHGlobal( ptr_data ); //delete [] data; + } + } + + void mix( int processed_count, float amp_left, float amp_right ) { + int current_buffer = (processed_count - 1) % _NUM_BUF; + for ( int k = 0; k < s_num_wave_reader; k++ ) { + s_wave_reader[k].Read( s_block_size * (processed_count - 1) + (int)s_wave_read_offset_samples, + s_block_size, + out s_ptr_another_wave_l[k], + out s_ptr_another_wave_r[k] ); + } + for ( int i = 0; i < s_block_size; i++ ) { + float l = s_wave_buffer_l[i] * amp_left; + float r = s_wave_buffer_r[i] * amp_right; + for ( int k = 0; k < s_num_wave_reader; k++ ) { + l += s_another_wave_l[k][i]; + r += s_another_wave_r[k][i]; + } + s_wave[current_buffer][i] = MAKELONG( (ushort)(r * 32768.0f), (ushort)(l * 32768.0f) ); + } + } + + string util_get_errmsg( uint msg ) { + //IntPtr ptr_err = Marshal.AllocHGlobal( sizeof( byte ) * 260 ); + //byte* err = (byte*)ptr_err.ToPointer(); + //System.Text.StringBuilder sb = new System.Text.StringBuilder( 260 ); + string ret = ""; + windows.mciGetErrorStringA( msg, ret, 260 ); + /*int len = 260; + for ( int i = 1; i < 260; i++ ) { + if ( err[i] == '\0' ) { + len = i - 1; + break; + } + }*/ + //string ret = new string( err ); + //string ret = sb.ToString(); + //Marshal.FreeHGlobal( ptr_err ); + return ret; + } + + private WavePlay() { + } + + /// 初期化関数 + public WavePlay( int block_size, int sample_rate ) { +#if DEBUG + Console.WriteLine( "waveplay..ctor" ); +#endif + s_block_size = block_size; + s_sample_rate = sample_rate; + + //s_ptr_wave_formatx = Marshal.AllocHGlobal( sizeof( WAVEFORMATEX ) ); + s_wave_formatx = new WAVEFORMATEX(); + //Marshal.PtrToStructure( s_ptr_wave_formatx, s_wave_formatx ); + s_wave_formatx.cbSize = (ushort)sizeof( WAVEFORMATEX ); +#if DEBUG + Console.WriteLine( " s_wave_fomratx.cbSize=" + s_wave_formatx.cbSize ); + Console.WriteLine( " sizeof( WAVEHDR )=" + sizeof( WAVEHDR ) ); +#endif + s_wave_formatx.wFormatTag = windows.WAVE_FORMAT_PCM; + s_wave_formatx.nChannels = 2; + s_wave_formatx.wBitsPerSample = 16; + s_wave_formatx.nBlockAlign = (ushort)(s_wave_formatx.nChannels * s_wave_formatx.wBitsPerSample / 8); + s_wave_formatx.nSamplesPerSec = (uint)s_sample_rate; + s_wave_formatx.nAvgBytesPerSec = s_wave_formatx.nSamplesPerSec * s_wave_formatx.nBlockAlign; + + s_wave_callback = new delegateWaveOutProc( wave_callback ); + s_hwave_out = IntPtr.Zero; + Console.WriteLine( " calling waveOutOpen..." ); + uint ret = windows.waveOutOpen( ref s_hwave_out, + windows.WAVE_MAPPER, + ref s_wave_formatx, + s_wave_callback, + IntPtr.Zero, + (uint)windows.CALLBACK_FUNCTION ); + Console.WriteLine( " ...done; ret=" + ret ); +#if DEBUG + bocoree.debug.push_log( " s_hwave_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + + for ( int k = 0; k < _NUM_BUF; k++ ) { + s_ptr_wave[k] = Marshal.AllocHGlobal( sizeof( uint ) * s_block_size ); + s_wave[k] = (uint*)s_ptr_wave[k];// = (ulong*)calloc( sizeof( ulong ), s_block_size ); + s_ptr_wave_header[k] = Marshal.AllocHGlobal( sizeof( WAVEHDR ) ); + s_wave_header[k] = (WAVEHDR)Marshal.PtrToStructure( s_ptr_wave_header[k], typeof( WAVEHDR ) ); + s_wave_header[k].lpData = s_ptr_wave[k]; + s_wave_header[k].dwBufferLength = (uint)(sizeof( uint ) * s_block_size); + s_wave_header[k].dwFlags = windows.WHDR_BEGINLOOP | windows.WHDR_ENDLOOP; + s_wave_header[k].dwLoops = 1; + +#if DEBUG + Console.WriteLine( "calling waveOutPrepareHeader..." ); +#endif + uint ret2 = windows.waveOutPrepareHeader( s_hwave_out, ref s_wave_header[k], (uint)sizeof( WAVEHDR ) ); +#if DEBUG + Console.WriteLine( "...done; ret2=" + ret2 ); +#endif + s_wave_header[k].dwUser = new IntPtr( k ); + } +#if DEBUG + bocoree.debug.push_log( " exit waveplay..ctor; s_hwave_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + } + + /// 波形データをバッファに追加する。バッファが再生中などの理由で即座に書き込めない場合、バッファが書き込み可能となるまで待機させられる + public void append( float** data, uint length, double amp_left, double amp_right ) { + append_cor( data, length, amp_left, amp_right, false ); + } + + public void flush_and_exit( double amp_left, double amp_right ) { + append_cor( (float**)0, 0, amp_left, amp_right, true ); + } + + /// 再生中断を要求する + public void abort() { + s_abort_required = true; + reset(); + for ( int k = 0; k < _NUM_BUF; k++ ) { + if ( s_ptr_wave[k] != IntPtr.Zero ) { + for ( int i = 0; i < s_block_size; i++ ) { + s_wave[k][i] = 0; + } + //memset( s_wave[k], 0, s_block_size * sizeof( ulong ) ); + } + } + s_buffer_loc = 0; + s_current_buffer = 0; + s_processed_count = 0; + } + + /// 現在の再生位置を取得する。再生中でない場合負の値となる。 + public float get_play_time() { +#if DEBUG + bocoree.debug.push_log( "WavePlay.get_play_time" ); +#endif + if ( s_playing ) { + MMTIME mmt = new MMTIME(); + mmt.cb = (uint)sizeof( MMTIME ); + mmt.wType = windows.TIME_MS; + uint ret = windows.waveOutGetPosition( s_hwave_out, ref mmt, (uint)sizeof( MMTIME ) ); +#if DEBUG + bocoree.debug.push_log( " ret=" + ret ); +#endif + float ms = 0.0f; + switch ( mmt.wType ) { + case windows.TIME_MS: + return mmt.ms * 0.001f; + case windows.TIME_SAMPLES: + return (float)mmt.sample / (float)s_wave_formatx.nSamplesPerSec; + case windows.TIME_BYTES: + return (float)mmt.cb / (float)s_wave_formatx.nAvgBytesPerSec; + default: + return -1.0f; + } + } else { + return -1.0f; + } + } + + /// リセットする。abort関数でも呼び出される。 + public void reset() { + s_playing = false; + if ( s_hwave_out.ToInt32() != 0 ) { + for ( int k = 0; k < _NUM_BUF; k++ ) { + s_wave_header[k].dwUser = new IntPtr( _NUM_BUF + k ); + } + windows.waveOutReset( s_hwave_out ); + uint zero = MAKELONG( 0, 0 ); + for ( int k = 0; k < _NUM_BUF; k++ ) { + for ( int i = 0; i < s_block_size; i++ ) { + s_wave[k][i] = zero; + } + } + } + for ( int i = 0; i < s_num_wave_reader; i++ ) { + s_wave_reader[i].Close(); + } + } + + /// 再生のための準備を行う。この関数を呼び出した後は、バッファが再生開始されるまでget_play_timeの戻り値は0となる(負値にならない)。 + /// 戻り値は、filesに指定されたファイルの内、最も再生時間の長いwaveファイルの、合計サンプル数 + public int on_your_mark( string[] files, long wave_read_offset_samples ) { +#if DEBUG + bocoree.debug.push_log( "on_your_mark; s_hwave_out=0x" + Convert.ToString( s_hwave_out.ToInt32(), 16 ) ); +#endif + int num_files = files.Length; + reset(); + s_wave_read_offset_samples = wave_read_offset_samples; + for ( int k = 0; k < _NUM_BUF; k++ ) { + s_wave_header[k].dwUser = new IntPtr( k ); + s_done[k] = true; + } + s_abort_required = false; + s_buffer_loc = 0; + s_current_buffer = 0; + s_processed_count = 0; + s_playing = true; + s_last_buffer = -1; + + if ( (int)s_ptr_wave_buffer_l.ToPointer() == 0 ) { + s_ptr_wave_buffer_l = Marshal.AllocHGlobal( sizeof( float ) * s_block_size );// s_wave_buffer_l = new float[s_block_size]; + s_wave_buffer_l = (float*)s_ptr_wave_buffer_l.ToPointer(); + } + if ( (int)s_ptr_wave_buffer_r.ToPointer() == 0 ) { + s_ptr_wave_buffer_r = Marshal.AllocHGlobal( sizeof( float ) * s_block_size ); //s_wave_buffer_r = new float[s_block_size]; + s_wave_buffer_r = (float*)s_ptr_wave_buffer_r.ToPointer(); + } + + if ( s_wave_reader != null ) { + for ( int i = 0; i < s_num_wave_reader; i++ ) { + s_wave_reader[i].Close(); + } + //delete [] s_wave_reader; + } + s_wave_reader = new WaveReader[num_files]; + + if ( s_another_wave_l != null ) { + for ( int i = 0; i < s_num_wave_reader; i++ ) { + Marshal.FreeHGlobal( s_ptr_another_wave_l[i] );// delete [] s_another_wave_l[i]; + } + //delete [] s_another_wave_l; + } + if ( s_another_wave_r != null ) { + for ( int i = 0; i < s_num_wave_reader; i++ ) { + Marshal.FreeHGlobal( s_ptr_another_wave_r[i] ); //delete [] s_another_wave_r[i]; + } + //delete [] s_another_wave_r; + } + s_another_wave_l = new float*[num_files]; + s_another_wave_r = new float*[num_files]; + int max_samples = 0; + for ( int i = 0; i < num_files; i++ ) { + // waveファイルヘッダを読込む + /*int len = files[i].Length; + wchar_t *name = new wchar_t[len + 1]; + array ^buf = files[i]->ToCharArray(); + for( int k = 0; k < len; k++ ){ + name[k] = buf[k]; + } + name[len] = '\0';*/ + s_wave_reader[i].Open( files[i] ); + int samples = s_wave_reader[i].TotalSamples; + if ( samples > max_samples ) { + max_samples = samples; + } + //delete [] name; + + // バッファを用意 + s_ptr_another_wave_l[i] = Marshal.AllocHGlobal( sizeof( float ) * s_block_size ); + s_another_wave_l[i] = (float*)s_ptr_another_wave_l[i].ToPointer(); + s_ptr_another_wave_r[i] = Marshal.AllocHGlobal( sizeof( float ) * s_block_size ); + s_another_wave_r[i] = (float*)s_ptr_another_wave_r[i].ToPointer(); + //s_another_wave_l[i] = new float[s_block_size]; + //s_another_wave_r[i] = new float[s_block_size]; + } + s_num_wave_reader = num_files; + return max_samples; + } + + public void set_error_samples( int error_samples ) { + s_error_samples = error_samples; + } + + /// コールバック関数を設定する + public void set_first_buffer_written_callback( FirstBufferWrittenCallback proc ) { + s_first_buffer_written_callback = proc; + } + + public void terminate() { + if ( s_hwave_out.ToInt32() != 0 ) { + windows.waveOutReset( s_hwave_out ); +#if DEBUG + bocoree.debug.push_log( "waveplay::terminate; waveOutReset" ); +#endif + for ( int k = 0; k < _NUM_BUF; k++ ) { + windows.waveOutUnprepareHeader( s_hwave_out, ref s_wave_header[k], (uint)sizeof( WAVEHDR ) ); + } + windows.waveOutClose( s_hwave_out ); + } + for ( int i = 0; i < _NUM_BUF; i++ ) { + if ( s_ptr_wave[i].ToInt32() != 0 ) { + Marshal.FreeHGlobal( s_ptr_wave[i] ); //delete [] s_wave[i]; + } + } + } + + /// 現在再生中かどうかを取得する + public bool is_alive() { + return s_playing; + } + + /// ブロックサイズを変更します + public bool change_block_size( int block_size ) { + if ( s_playing ) { + return false; + } + if ( block_size <= 0 ) { + return false; + } + + for ( int k = 0; k < _NUM_BUF; k++ ) { + if ( s_ptr_wave[k].ToInt32() != 0 ) { + Marshal.FreeHGlobal( s_ptr_wave[k] );// delete [] s_wave[k]; + } + s_ptr_wave[k] = Marshal.AllocHGlobal( sizeof( uint ) * block_size ); + s_wave[k] = (uint*)s_ptr_wave[k].ToPointer();// calloc( sizeof( ulong ), block_size ); + s_wave_header[k].lpData = s_ptr_wave[k]; + s_wave_header[k].dwBufferLength = (uint)(sizeof( uint ) * block_size); + } + + // s_wave_buffer_l, s_wave_buffer_rは、NULLならばon_your_markで初期化されるので、開放だけやっておけばOK + if ( s_ptr_wave_buffer_l.ToInt32() != 0 ) { + Marshal.FreeHGlobal( s_ptr_wave_buffer_l ); //delete [] s_wave_buffer_l; + } + if ( s_ptr_wave_buffer_r.ToInt32() != 0 ) { + Marshal.FreeHGlobal( s_ptr_wave_buffer_r ); //delete[] s_wave_buffer_r; + } + // s_another_wave_l, s_another_wave_rは、on_your_markで全自動で初期化されるので特に操作の必要なし + s_block_size = block_size; + return true; + } + + uint MAKELONG( ushort a, ushort b ) { + return (uint)(a & 0xffff) | (uint)((b & 0xffff) << 16); + } + } + +} diff --git a/trunk/Boare.Lib.Media/WaveReader.cs b/trunk/Boare.Lib.Media/WaveReader.cs new file mode 100644 index 0000000..1cc9033 --- /dev/null +++ b/trunk/Boare.Lib.Media/WaveReader.cs @@ -0,0 +1,283 @@ +/* + * WaveReader.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Runtime.InteropServices; + +namespace Boare.Lib.Media { + + public class WaveReader : IDisposable{ + private int m_channel; + private int m_byte_per_sample; + private bool m_opened; + private FileStream m_stream; + private int m_total_samples; + + public WaveReader() { + m_opened = false; + } + + public WaveReader( string file ) { + Open( file ); + } + + public void Dispose() { + Close(); + } + + public bool Open( string file ) { + if ( m_opened ) { + m_stream.Close(); + } + m_stream = new FileStream( file, FileMode.Open ); + + // RIFF + byte[] buf = new byte[4]; + m_stream.Read( buf, 0, 4 ); + if ( buf[0] != 'R' || buf[1] != 'I' || buf[2] != 'F' || buf[3] != 'F' ) { + m_stream.Close(); + return false; + } + + // ファイルサイズ - 8最後に記入 + m_stream.Read( buf, 0, 4 ); + + // WAVE + m_stream.Read( buf, 0, 4 ); + if ( buf[0] != 'W' || buf[1] != 'A' || buf[2] != 'V' || buf[3] != 'E' ) { + m_stream.Close(); + return false; + } + + // fmt + m_stream.Read( buf, 0, 4 ); + if ( buf[0] != 'f' || buf[1] != 'm' || buf[2] != 't' || buf[3] != ' ' ) { + m_stream.Close(); + return false; + } + + // fmt チャンクのサイズ + m_stream.Read( buf, 0, 4 ); + + // format ID + m_stream.Read( buf, 0, 2 ); + + // チャンネル数 + m_stream.Read( buf, 0, 2 ); + m_channel = buf[1] << 8 | buf[0]; + + // サンプリングレート + m_stream.Read( buf, 0, 4 ); + + // データ速度 + m_stream.Read( buf, 0, 4 ); + + // ブロックサイズ + m_stream.Read( buf, 0, 2 ); + + // サンプルあたりのビット数 + m_stream.Read( buf, 0, 2 ); + int bit_per_sample = buf[1] << 8 | buf[0]; + m_byte_per_sample = bit_per_sample / 8; + + // 拡張部分 + m_stream.Read( buf, 0, 2 ); + + // data + m_stream.Read( buf, 0, 4 ); + if ( buf[0] != 'd' || buf[1] != 'a' || buf[2] != 't' || buf[3] != 'a' ) { + m_stream.Close(); + return false; + } + + // size of data chunk + m_stream.Read( buf, 0, 4 ); + int size = BitConverter.ToInt32( buf, 0 ); + m_total_samples = size / (m_channel * m_byte_per_sample); + + m_opened = true; + return true; + } + + public int TotalSamples { + get { + return m_total_samples; + } + } + + public void Read( int start, int length, out float[] left, out float[] right ) { + left = new float[length]; + right = new float[length]; + if ( !m_opened ) { + return; + } + int loc = 0x2e + m_byte_per_sample * m_channel * start; + m_stream.Seek( loc, SeekOrigin.Begin ); + + if ( m_byte_per_sample == 2 ) { + if ( m_channel == 2 ) { + byte[] buf = new byte[4]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 4 ); + if ( ret < 4 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + short l = (short)(buf[0] | buf[1] << 8); + short r = (short)(buf[2] | buf[3] << 8); + left[i] = l / 32768.0f; + right[i] = r / 32768.0f; + } + } else { + byte[] buf = new byte[2]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 2 ); + if ( ret < 2 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + short l = (short)(buf[0] | buf[1] << 8); + left[i] = l / 32768.0f; + right[i] = left[i]; + } + } + } else { + if ( m_channel == 2 ) { + byte[] buf = new byte[2]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 2 ); + if ( ret < 2 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + left[i] = (buf[0] - 64.0f) / 64.0f; + right[i] = (buf[1] - 64.0f) / 64.0f; + } + } else { + byte[] buf = new byte[1]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 1 ); + if ( ret < 1 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + left[i] = (buf[0] - 64.0f) / 64.0f; + right[i] = left[i]; + } + } + } + } + + public unsafe void Read( int start, int length, out IntPtr ptr_left, out IntPtr ptr_right ) { + ptr_left = Marshal.AllocHGlobal( sizeof( float ) * length ); + ptr_right = Marshal.AllocHGlobal( sizeof( float ) * length ); + float* left = (float*)ptr_left.ToPointer(); + float* right = (float*)ptr_right.ToPointer(); + if ( !m_opened ) { + return; + } + int loc = 0x2e + m_byte_per_sample * m_channel * start; + m_stream.Seek( loc, SeekOrigin.Begin ); + + if ( m_byte_per_sample == 2 ) { + if ( m_channel == 2 ) { + byte[] buf = new byte[4]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 4 ); + if ( ret < 4 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + short l = (short)(buf[0] | buf[1] << 8); + short r = (short)(buf[2] | buf[3] << 8); + left[i] = l / 32768.0f; + right[i] = r / 32768.0f; + } + } else { + byte[] buf = new byte[2]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 2 ); + if ( ret < 2 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + short l = (short)(buf[0] | buf[1] << 8); + left[i] = l / 32768.0f; + right[i] = left[i]; + } + } + } else { + if ( m_channel == 2 ) { + byte[] buf = new byte[2]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 2 ); + if ( ret < 2 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + left[i] = (buf[0] - 64.0f) / 64.0f; + right[i] = (buf[1] - 64.0f) / 64.0f; + } + } else { + byte[] buf = new byte[1]; + for ( int i = 0; i < length; i++ ) { + int ret = m_stream.Read( buf, 0, 1 ); + if ( ret < 1 ) { + for ( int j = i; j < length; j++ ) { + left[j] = 0.0f; + right[j] = 0.0f; + } + break; + } + left[i] = (buf[0] - 64.0f) / 64.0f; + right[i] = left[i]; + } + } + } + } + + public void Close() { + m_opened = false; + if ( m_stream != null ) { + m_stream.Close(); + } + } + + ~WaveReader() { + Close(); + } + } + +} diff --git a/trunk/Boare.Lib.Media/WaveWriter.cs b/trunk/Boare.Lib.Media/WaveWriter.cs new file mode 100644 index 0000000..e4591e7 --- /dev/null +++ b/trunk/Boare.Lib.Media/WaveWriter.cs @@ -0,0 +1,384 @@ +/* + * WaveWriter.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Media. + * + * Boare.Lib.Media is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Media is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; + +namespace Boare.Lib.Media { + + public class WaveWriter : IDisposable { + private WaveChannel m_channel; + private ushort m_bit_per_sample; + private uint m_sample_rate; + private uint m_total_samples = 0; + private FileStream m_stream = null; + private string m_path = ""; + + public WaveWriter( string path ) : + this ( path, WaveChannel.Stereo, 16, 44100 ) { + } + + public WaveWriter( string path, WaveChannel channel, ushort bit_per_sample, uint sample_rate ) { + m_path = path; + m_stream = new FileStream( m_path, FileMode.Create ); + m_channel = channel; + m_bit_per_sample = bit_per_sample; + m_sample_rate = sample_rate; + m_total_samples = 0; + WriteHeader(); + } + + /// + /// Writes header of WAVE file + /// + private void WriteHeader() { + // RIFF + m_stream.WriteByte( 0x52 ); // loc=0x00 + m_stream.WriteByte( 0x49 ); + m_stream.WriteByte( 0x46 ); + m_stream.WriteByte( 0x46 ); + + // ファイルサイズ - 8最後に記入 + m_stream.WriteByte( 0x00 ); // loc=0x04 + m_stream.WriteByte( 0x00 ); + m_stream.WriteByte( 0x00 ); + m_stream.WriteByte( 0x00 ); + + // WAVE + m_stream.WriteByte( 0x57 ); // loc=0x08 + m_stream.WriteByte( 0x41 ); + m_stream.WriteByte( 0x56 ); + m_stream.WriteByte( 0x45 ); + + // fmt + m_stream.WriteByte( 0x66 ); // loc=0x0c + m_stream.WriteByte( 0x6d ); + m_stream.WriteByte( 0x74 ); + m_stream.WriteByte( 0x20 ); + + // fmt チャンクのサイズ + m_stream.WriteByte( 0x12 ); // loc=0x10 + m_stream.WriteByte( 0x00 ); + m_stream.WriteByte( 0x00 ); + m_stream.WriteByte( 0x00 ); + + // format ID + m_stream.WriteByte( 0x01 ); // loc=0x14 + m_stream.WriteByte( 0x00 ); + + // チャンネル数 + if ( m_channel == WaveChannel.Monoral ) { + m_stream.WriteByte( 0x01 ); // loc=0x16 + m_stream.WriteByte( 0x00 ); + } else { + m_stream.WriteByte( 0x02 ); //loc=0x16 + m_stream.WriteByte( 0x00 ); + } + + // サンプリングレート + byte[] buf = BitConverter.GetBytes( m_sample_rate ); + WriteByteArray( m_stream, buf, 4 ); // 0x18 + + // データ速度 + ushort block_size = (ushort)(m_bit_per_sample / 8 * (int)m_channel); + uint data_rate = m_sample_rate * block_size; + buf = BitConverter.GetBytes( data_rate ); + WriteByteArray( m_stream, buf, 4 );//loc=0x1c + + // ブロックサイズ + buf = BitConverter.GetBytes( block_size ); + WriteByteArray( m_stream, buf, 2 ); //0x20 + + // サンプルあたりのビット数 + buf = BitConverter.GetBytes( m_bit_per_sample ); + WriteByteArray( m_stream, buf, 2 ); //loc=0x22 + + // 拡張部分 + m_stream.WriteByte( 0x00 ); //loc=0x24 + m_stream.WriteByte( 0x00 ); + + // data + m_stream.WriteByte( 0x64 ); //loc=0x26 + m_stream.WriteByte( 0x61 ); + m_stream.WriteByte( 0x74 ); + m_stream.WriteByte( 0x61 ); + + // size of data chunk + uint size = block_size * m_total_samples; + buf = BitConverter.GetBytes( size ); + WriteByteArray( m_stream, buf, 4 ); + } + + public void Close(){ + if ( m_stream != null ) { + // 最後にWAVEチャンクのサイズ + uint position = (uint)m_stream.Position; + m_stream.Seek( 4, SeekOrigin.Begin ); + byte[] buf = BitConverter.GetBytes( position - 8 ); + WriteByteArray( m_stream, buf, 4 ); + + // size of data chunk + ushort block_size = (ushort)(m_bit_per_sample / 8 * (int)m_channel); + uint size = block_size * m_total_samples; + m_stream.Seek( 42, SeekOrigin.Begin ); + buf = BitConverter.GetBytes( size ); + WriteByteArray( m_stream, buf, 4 ); + + m_stream.Close(); + } + } + + public uint SampleRate { + get { + return m_sample_rate; + } + } + + public void Dispose() { + Close(); + } + + public void Append( float[] L ) { + int total = L.Length; + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 1.0f) * 127.5f) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + byte b = (byte)((L[i] + 1.0f) * 127.5f); + m_stream.WriteByte( b ); + m_stream.WriteByte( b ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + public void Append( double[] L ) { + int total = L.Length; + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 1.0) * 127.5) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + byte b = (byte)((L[i] + 1.0) * 127.5); + m_stream.WriteByte( b ); + m_stream.WriteByte( b ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768.0) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768.0) ); + WriteByteArray( m_stream, buf, 2 ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + public void Append( float[] L, float[] R ) { + int total = Math.Min( L.Length, R.Length ); + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + R[i] + 2.0f) * 63.75f) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 1.0f) * 127.5f) ); + m_stream.WriteByte( (byte)((R[i] + 1.0f) * 127.5f) ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)((L[i] + R[i]) * 16384f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + buf = BitConverter.GetBytes( (short)(R[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + public unsafe void Append( float* L, float* R, int length ) { + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < length; i++ ) { + m_stream.WriteByte( (byte)((L[i] + R[i] + 2.0f) * 63.75f) ); + } + } else { + for ( int i = 0; i < length; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 1.0f) * 127.5f) ); + m_stream.WriteByte( (byte)((R[i] + 1.0f) * 127.5f) ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < length; i++ ) { + buf = BitConverter.GetBytes( (short)((L[i] + R[i]) * 16384f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < length; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + buf = BitConverter.GetBytes( (short)(R[i] * 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)length; + } + + public void Append( double[] L, double[] R ) { + int total = Math.Min( L.Length, R.Length ); + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + R[i] + 2.0) * 63.75) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 1.0) * 127.5) ); + m_stream.WriteByte( (byte)((R[i] + 1.0) * 127.5) ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)((L[i] + R[i]) * 16384.0) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 32768.0) ); + WriteByteArray( m_stream, buf, 2 ); + buf = BitConverter.GetBytes( (short)(R[i] * 32768.0) ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + public void Append( byte[] L, byte[] R ) { + int total = Math.Min( L.Length, R.Length ); + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + R[i]) / 2) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( L[i] ); + m_stream.WriteByte( R[i] ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)((L[i] + R[i]) * 128.5f - 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (short)(L[i] * 257f - 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + buf = BitConverter.GetBytes( (short)(R[i] * 257f - 32768f) ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + public void Append( short[] L, short[] R ) { + int total = Math.Min( L.Length, R.Length ); + if ( m_bit_per_sample == 8 ) { + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)(((L[i] + R[i]) / 2f + 32768f) / 255f) ); + } + } else { + for ( int i = 0; i < total; i++ ) { + m_stream.WriteByte( (byte)((L[i] + 32768f) / 255f) ); + m_stream.WriteByte( (byte)((R[i] + 32768f) / 255f) ); + } + } + } else { + byte[] buf; + if ( m_channel == WaveChannel.Monoral ) { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( (L[i] + R[i]) / 2 ); + WriteByteArray( m_stream, buf, 2 ); + } + } else { + for ( int i = 0; i < total; i++ ) { + buf = BitConverter.GetBytes( L[i] ); + WriteByteArray( m_stream, buf, 2 ); + buf = BitConverter.GetBytes( R[i] ); + WriteByteArray( m_stream, buf, 2 ); + } + } + } + m_total_samples += (uint)total; + } + + private static void WriteByteArray( FileStream fs, byte[] dat, int limit ) { + fs.Write( dat, 0, (dat.Length > limit) ? limit : dat.Length ); + if ( dat.Length < limit ) { + for ( int i = 0; i < limit - dat.Length; i++ ) { + fs.WriteByte( 0x00 ); + } + } + } + } + +} diff --git a/trunk/Boare.Lib.Media/makefile b/trunk/Boare.Lib.Media/makefile new file mode 100644 index 0000000..1de1b0b --- /dev/null +++ b/trunk/Boare.Lib.Media/makefile @@ -0,0 +1,17 @@ +CP=cp +RM=rm +SRC=AviReader.cs AviWriter.cs RawAvi2Writer.cs AviWriterEx.cs VCM.cs Util.cs VFW.cs MediaPlayer.cs Wave.cs +OPT= + +Boare.Lib.Media.dll: *.cs bocoree.dll + gmcs $(OPT) -recurse:*.cs -unsafe+ -target:library -out:Boare.Lib.Media.dll -r:bocoree.dll,System,System.Drawing,System.Windows.Forms -define:MONO + +bocoree.dll: ../bocoree/bocoree.dll + cp ../bocoree/bocoree.dll bocoree.dll + +../bocoree/bocoree.dll: + cd ../bocoree/ && $(MAKE) OPT=$(OPT) + +clean: + $(RM) Boare.Lib.Media.dll + $(RM) bocoree.dll diff --git a/trunk/Boare.Lib.Swf/Boare.Lib.Swf.csproj b/trunk/Boare.Lib.Swf/Boare.Lib.Swf.csproj new file mode 100644 index 0000000..d81fb7c --- /dev/null +++ b/trunk/Boare.Lib.Swf/Boare.Lib.Swf.csproj @@ -0,0 +1,59 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {D861973B-3BC6-4F52-83BE-49A8C269C09F} + Library + Properties + Boare.Lib.Swf + Boare.Lib.Swf + v2.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/Boare.Lib.Swf/Properties/AssemblyInfo.cs b/trunk/Boare.Lib.Swf/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b6e5149 --- /dev/null +++ b/trunk/Boare.Lib.Swf/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "Boare.Lib.Swf" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "" )] +[assembly: AssemblyProduct( "Boare.Lib.Swf" )] +[assembly: AssemblyCopyright( "Copyright © 2008" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "73d3cbb6-bae0-4703-9ef3-a18b1df0c08b" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "0.0a0" )] diff --git a/trunk/Boare.Lib.Swf/RECT.cs b/trunk/Boare.Lib.Swf/RECT.cs new file mode 100644 index 0000000..22e6341 --- /dev/null +++ b/trunk/Boare.Lib.Swf/RECT.cs @@ -0,0 +1,63 @@ +/* + * RECT.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Swf. + * + * Boare.Lib.Swf is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Swf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Swf{ + + public struct RECT{ + + private int m_xmin; + private int m_xmax; + private int m_ymin; + private int m_ymax; + + private int Xmin { + get { + return m_xmin; + } + set { + m_xmin = value; + } + } + + private int Xmax { + get { + return m_xmax; + } + set { + m_xmax = value; + } + } + + private int Ymin { + get { + return m_ymin; + } + set { + m_ymin = value; + } + } + + private int Ymax { + get { + return m_ymax; + } + set { + m_ymax = value; + } + } + + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Swf/SB.cs b/trunk/Boare.Lib.Swf/SB.cs new file mode 100644 index 0000000..5e5f5e5 --- /dev/null +++ b/trunk/Boare.Lib.Swf/SB.cs @@ -0,0 +1,54 @@ +/* + * SB.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Swf. + * + * Boare.Lib.Swf is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Swf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using Boare.Lib.Swf; + +namespace Boare.Lib.Swf { + + using UI8 = System.Byte; + using UI32 = System.UInt32; + using UI16 = System.UInt16; + using SI8 = System.SByte; + using SI16 = System.Int16; + using SI32 = System.Int32; + + /// + /// Signed-bit Value + /// + struct SB { + private byte[] m_value; + + public void SetValue( SI8 value ) { + + } + + public SI32 GetSI32Value() { + if ( m_value == null ) { + return 0; + } else { + throw new NotImplementedException(); + } + } + + public SI16 GetSI16Value() { + if ( m_value == null ) { + return 0; + } else { + throw new NotImplementedException(); + } + } + + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Swf/SwfWriter.cs b/trunk/Boare.Lib.Swf/SwfWriter.cs new file mode 100644 index 0000000..97d2dd8 --- /dev/null +++ b/trunk/Boare.Lib.Swf/SwfWriter.cs @@ -0,0 +1,81 @@ +/* + * SwfWriter.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Swf. + * + * Boare.Lib.Swf is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Swf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; + +namespace Boare.Lib.Swf { + + using UI8 = System.Byte; + using UI32 = System.UInt32; + using UI16 = System.UInt16; + using SI8 = System.SByte; + using SI16 = System.Int16; + using SI32 = System.Int32; + + public class SwfWriter : IDisposable { + + private const UI8 m_version = 0x6; + private UI16 m_frame_rate; + private UI16 m_frame_count; + private FileStream m_stream; + + public SwfWriter( FileStream s ) { + m_stream = s; + + // swf header + s.WriteByte( 0x46 ); // Signature + s.WriteByte( 0x57 ); // Signature + s.WriteByte( 0x53 ); // Signature + s.WriteByte( m_version ); // Version + s.WriteByte( 0x0 ); // FileLength + } + + + public void Close() { + if ( m_stream != null ) { + m_stream.Close(); + } + } + + + public void Dispose() { + Close(); + } + + + public static int GetEncodedU32( byte[] pos ) { + int result = pos[0]; + if ( (result & 0x00000080) == 0x0 ) { + return result; + } + result = (result & 0x0000007f) | pos[1] << 7; + if ( (result & 0x00004000) == 0x0 ) { + return result; + } + result = (result & 0x00003fff) | pos[2] << 14; + if ( (result & 0x00200000) == 0x0 ) { + return result; + } + result = (result & 0x001fffff) | pos[3] << 21; + if ( (result & 0x10000000) == 0x0 ) { + return result; + } + result = (result & 0x0fffffff) | pos[4] << 28; + return result; + } + + } + +} diff --git a/trunk/Boare.Lib.Swf/Util.cs b/trunk/Boare.Lib.Swf/Util.cs new file mode 100644 index 0000000..3f41988 --- /dev/null +++ b/trunk/Boare.Lib.Swf/Util.cs @@ -0,0 +1,22 @@ +/* + * Util.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Swf. + * + * Boare.Lib.Swf is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Swf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Swf { + + class Util { + + } + +} diff --git a/trunk/Boare.Lib.Swf/makefile b/trunk/Boare.Lib.Swf/makefile new file mode 100644 index 0000000..5e498ef --- /dev/null +++ b/trunk/Boare.Lib.Swf/makefile @@ -0,0 +1,8 @@ +RM=rm +CP=cp +Boare.Lib.Swf.dll: RECT.cs SB.cs SwfWriter.cs Util.cs + gmcs -target:library -out:Boare.Lib.Swf.dll \ + RECT.cs SB.cs SwfWriter.cs Util.cs + +clean: + $(RM) Boare.Lib.Swf.dll diff --git a/trunk/Boare.Lib.Vsq/BPPair.cs b/trunk/Boare.Lib.Vsq/BPPair.cs new file mode 100644 index 0000000..0e3cdd5 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/BPPair.cs @@ -0,0 +1,47 @@ +/* + * BPPair.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + /// + /// Stores the paired value of "Clock" and integer. Mainly used in VsqBPList + /// + [Serializable] + public class BPPair : IComparable { + public int Clock; + public int Value; + + /// + /// このインスタンスと、指定したオブジェクトを比較します + /// + /// + /// + public int CompareTo( BPPair item ) { + if ( Clock > item.Clock ) { + return 1; + } else if ( Clock < item.Clock ) { + return -1; + } else { + return 0; + } + } + + public BPPair( int clock_, int value_ ) { + Clock = clock_; + Value = value_; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/Boare.Lib.Vsq.csproj b/trunk/Boare.Lib.Vsq/Boare.Lib.Vsq.csproj new file mode 100644 index 0000000..55616ef --- /dev/null +++ b/trunk/Boare.Lib.Vsq/Boare.Lib.Vsq.csproj @@ -0,0 +1,114 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {673347F3-6FC2-4F82-9273-BF158E0F8CB1} + Library + Properties + Boare.Lib.Vsq + Boare.Lib.Vsq + + + 2.0 + v2.0 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + Boare.Lib.Vsq.xml + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + Boare.Lib.Vsq.xml + true + + + x86 + bin\x86\Debug\ + DEBUG + bin\x86\Debug\Boare.Lib.Vsq.XML + + + x86 + bin\x86\Release\ + bin\x86\Release\Boare.Lib.Vsq.XML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {C8AAE632-9C6C-4372-8175-811528A66742} + bocoree + + + + + + + + + \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/NRPN.cs b/trunk/Boare.Lib.Vsq/NRPN.cs new file mode 100644 index 0000000..294bcf4 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/NRPN.cs @@ -0,0 +1,249 @@ +/* + * NRPN.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.Vsq { + + public enum NRPN : ushort { + /// + /// (0x5000) Version number(MSB) &, Device number(LSB) + /// + CVM_NM_VERSION_AND_DEVICE = 0x5000, + /// + /// (0x5001) Delay in millisec(MSB, LSB) + /// + CVM_NM_DELAY = 0x5001, + /// + /// (0x5002) Note number(MSB) + /// + CVM_NM_NOTE_NUMBER = 0x5002, + /// + /// (0x5003) Velocity(MSB) + /// + CVM_NM_VELOCITY = 0x5003, + /// + /// (0x5004) Note Duration in millisec(MSB, LSB) + /// + CVM_NM_NOTE_DURATION = 0x5004, + /// + /// (0x5005) Note Location(MSB) + /// + CVM_NM_NOTE_LOCATION = 0x5005, + /// + /// (0x500c) Index of Vibrato DB(MSB: ID_H00, LSB:ID_L00) + /// + CVM_NM_INDEX_OF_VIBRATO_DB = 0x500c, + /// + /// (0x500d) Vibrato configuration(MSB: Index of Vibrato Type, LSB: Duration &, Configuration parameter of vibrato) + /// + CVM_NM_VIBRATO_CONFIG = 0x500d, + /// + /// (0x500e) Vibrato Delay(MSB) + /// + CVM_NM_VIBRATO_DELAY = 0x500e, + /// + /// (0x5012) Number of phonetic symbols in bytes(MSB) + /// + CVM_NM_PHONETIC_SYMBOL_BYTES = 0x5012, + /// + /// (0x5013) Phonetic symbol 1(MSB:Phonetic symbol 1, LSB: Consonant adjustment 1) + /// + CVM_NM_PHONETIC_SYMBOL1 = 0x5013, + /// + /// (0x504f) Phonetic symbol continuation(MSB, 0x7f=end, 0x00=continue) + /// + CVM_NM_PHONETIC_SYMBOL_CONTINUATION = 0x504f, + /// + /// (0x5050) v1mean in Cent/5(MSB) + /// + CVM_NM_V1MEAN = 0x5050, + /// + /// (0x5051) d1mean in millisec/5(MSB) + /// + CVM_NM_D1MEAN = 0x5051, + /// + /// (0x5052) d1meanFirstNote in millisec/5(MSB) + /// + CVM_NM_D1MEAN_FIRST_NOTE = 0x5052, + /// + /// (0x5053) d2mean in millisec/5(MSB) + /// + CVM_NM_D2MEAN = 0x5053, + /// + /// (0x5054) d4mean in millisec/5(MSB) + /// + CVM_NM_D4MEAN = 0x5054, + /// + /// (0x5055) pMeanOnsetFirstNote in Cent/5(MSB) + /// + CVM_NM_PMEAN_ONSET_FIRST_NOTE = 0x5055, + /// + /// (0x5056) vMeanNoteTransition in Cent/5(MSB) + /// + CVM_NM_VMEAN_NOTE_TRNSITION = 0x5056, + /// + /// (0x5057) pMeanEndingNote in Cent/5(MSB) + /// + CVM_NM_PMEAN_ENDING_NOTE = 0x5057, + /// + /// (0x5058) AddScooptoUpIntervals &, AddPortamentoToDownIntervals(MSB) + /// + CVM_NM_ADD_PORTAMENTO = 0x5058, + /// + /// (0x5059) changAfterPeak(MSB) + /// + CVM_NM_CHANGE_AFTER_PEAK = 0x5059, + /// + /// (0x505a) Accent(MSB) + /// + CVM_NM_ACCENT = 0x505a, + /// + /// (0x597f) Note message continuation(MSB) + /// + CVM_NM_NOTE_MESSAGE_CONTINUATION = 0x507f, + + /// + /// (0x6000) Version number &, Device number(MSB, LSB) + /// + CC_BS_VERSION_AND_DEVICE = 0x6000, + /// + /// (0x6001) Delay in millisec(MSB, LSB) + /// + CC_BS_DELAY = 0x6001, + /// + /// (0x6002) Laugnage type(MSB, optional LSB) + /// + CC_BS_LANGUAGE_TYPE = 0x6002, + + /// + /// (0x6100) Version number &, device number(MSB, LSB) + /// + CC_CV_VERSION_AND_DEVICE = 0x6100, + /// + /// (0x6101) Delay in millisec(MSB, LSB) + /// + CC_CV_DELAY = 0x6101, + /// + /// (0x6102) Volume value(MSB) + /// + CC_CV_VOLUME = 0x6102, + + /// + /// (0x6200) Version number &, device number(MSB, LSB) + /// + CC_P_VERSION_AND_DEVICE = 0x6200, + /// + /// (0x6201) Delay in millisec(MSB, LSB) + /// + CC_P_DELAY = 0x6201, + /// + /// (0x6202) Pan value(MSB) + /// + CC_PAN = 0x6202, + + /// + /// (0x6300) Version number &, device number(MSB, LSB) + /// + CC_E_VESION_AND_DEVICE = 0x6300, + /// + /// (0x6301) Delay in millisec(MSB, LSB) + /// + CC_E_DELAY = 0x6301, + /// + /// (0x6302) Expression vlaue(MSB) + /// + CC_E_EXPRESSION = 0x6302, + + /// + /// (0x6400) Version number &, device number(MSB, LSB) + /// + CC_VR_VERSION_AND_DEVICE = 0x6400, + /// + /// (0x6401) Delay in millisec(MSB, LSB) + /// + CC_VR_DELAY = 0x6401, + /// + /// (0x6402) Vibrato Rate value(MSB) + /// + CC_VR_VIBRATO_RATE = 0x6402, + + /// + /// (0x6500) Version number &, device number(MSB, LSB) + /// + CC_VD_VERSION_AND_DEVICE = 0x6500, + /// + /// (0x6501) Delay in millisec(MSB, LSB) + /// + CC_VD_DELAY = 0x6501, + /// + /// (0x6502) Vibrato Depth value(MSB) + /// + CC_VD_VIBRATO_DEPTH = 0x6502, + + /// + /// (0x6700) Version number &, device number(MSB, LSB) + /// + CC_PBS_VERSION_AND_DEVICE = 0x6700, + /// + /// (0x6701) Delay in millisec(MSB, LSB) + /// + CC_PBS_DELAY = 0x6701, + /// + /// (0x6702) Pitch Bend Sensitivity(MSB, LSB) + /// + CC_PBS_PITCH_BEND_SENSITIVITY = 0x6702, + + /// + /// (0x5300) Version number &, device number(MSB, LSB) + /// + PC_VERSION_AND_DEVICE = 0x5300, + /// + /// (0x5301) Delay in millisec(MSB, LSB) + /// + PC_DELAY = 0x5301, + /// + /// (0x5302) Voice Type(MSB) + /// + PC_VOICE_TYPE = 0x5302, + + /// + /// (0x5400) Version number &, device number(MSB, LSB) + /// + PB_VERSION_AND_DEVICE = 0x5400, + /// + /// (0x5401) Delay in millisec(MSB, LSB) + /// + PB_DELAY = 0x5401, + /// + /// (0x5402) Pitch Bend value(MSB, LSB) + /// + PB_PITCH_BEND = 0x5402, + + /// + /// (0x5500) Version number &, device number(MSB, LSB) + /// + VCP_VERSION_AND_DEVICE = 0x5500, + /// + /// (0x5501) Delay in millisec(MSB, LSB) + /// + VCP_DELAY = 0x5501, + /// + /// (0x5502) Voice Change Parameter ID(MSB) + /// + VCP_VOICE_CHANGE_PARAMETER_ID = 0x5502, + /// + /// (0x5503) Voice Change Parameter value(MSB) + /// + VCP_VOICE_CHANGE_PARAMETER = 0x5503, + } + +} diff --git a/trunk/Boare.Lib.Vsq/NrpnData.cs b/trunk/Boare.Lib.Vsq/NrpnData.cs new file mode 100644 index 0000000..05ebdba --- /dev/null +++ b/trunk/Boare.Lib.Vsq/NrpnData.cs @@ -0,0 +1,36 @@ +/* + * NrpnData.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.Vsq { + + public class NrpnData { + int m_clock; + byte m_parameter; + public byte Value; + + public NrpnData( int clock_, byte parameter, byte value ) { + m_clock = clock_; + m_parameter = parameter; + Value = value; + } + + public int getClock(){ + return m_clock; + } + + public byte getParameter(){ + return m_parameter; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/PortUtil.cs b/trunk/Boare.Lib.Vsq/PortUtil.cs new file mode 100644 index 0000000..9ddfc8c --- /dev/null +++ b/trunk/Boare.Lib.Vsq/PortUtil.cs @@ -0,0 +1,55 @@ +/* + * PortUtil.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + public interface Iterator { + bool hasNext(); + object next(); + void remove(); + } + + public class ListIterator : Iterator { + private List m_list; + private int m_pos; + + public ListIterator( List list ) { + m_list = list; + m_pos = -1; + } + + public Boolean hasNext() { + if ( m_list != null && 0 <= m_pos + 1 && m_pos + 1 < m_list.Count ) { + return true; + } else { + return false; + } + } + + public Object next() { + if ( m_list == null ) { + return null; + } + m_pos++; + return m_list[m_pos]; + } + + public void remove() { + m_list.RemoveAt( m_pos ); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/Properties/AssemblyInfo.cs b/trunk/Boare.Lib.Vsq/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5f15fb7 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +/* + * AssemblyInfo.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of Boare.Vsq.Lib. + * + * Boare.Vsq.Lib is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Cadencii is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle( "Boare.Lib.Vsq" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "Boare.Lib.Vsq" )] +[assembly: AssemblyCopyright( "Copyright © 2007-2009" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] +[assembly: ComVisible( false )] +[assembly: Guid( "b8b57651-e1db-421c-b518-16d661bcc863" )] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.2.0" )] diff --git a/trunk/Boare.Lib.Vsq/SMF/MidiFile.cs b/trunk/Boare.Lib.Vsq/SMF/MidiFile.cs new file mode 100644 index 0000000..987e6c2 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/SMF/MidiFile.cs @@ -0,0 +1,316 @@ +/* + * MidiFile.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + /// + /// midiイベント。メタイベントは、メタイベントのデータ長をData[1]に格納せず、生のデータをDataに格納するので、注意が必要 + /// + public struct MidiEvent : IComparable { + public long Clock; + public byte FirstByte; + public byte[] Data; + + private static void writeDeltaClock( Stream stream, long number ) { + bool[] bits = new bool[64]; + long val = 0x1; + bits[0] = (number & val) == val; + for ( int i = 1; i < 64; i++ ) { + val = val << 1; + bits[i] = (number & val) == val; + } + int first = 0; + for ( int i = 63; i >= 0; i-- ) { + if ( bits[i] ) { + first = i; + break; + } + } + // 何バイト必要か? + int bytes = first / 7 + 1; + for ( int i = 1; i <= bytes; i++ ) { + uint num = 0; + uint count = 0x80; + for ( int j = (bytes - i + 1) * 7 - 1; j >= (bytes - i + 1) * 7 - 6 - 1; j-- ) { + count = count >> 1; + if ( bits[j] ) { + num += count; + } + } + if ( i != bytes ) { + num += 0x80; + } + stream.WriteByte( (byte)num ); + } + } + + private static long readDeltaClock( Stream stream ) { + long ret = 0; + while ( true ) { + byte d = (byte)stream.ReadByte(); + ret = (ret << 7) | ((long)d & 0x7f); + if ( (d & 0x80) == 0x00 ) { + break; + } + } + return ret; + } + + public static MidiEvent read( Stream stream, ref long last_clock, ref byte last_status_byte ) { + long delta_clock = readDeltaClock( stream ); + last_clock += delta_clock; + byte first_byte = (byte)stream.ReadByte(); + if ( first_byte < 0x80 ) { + // ランニングステータスが適用される + stream.Seek( -1, SeekOrigin.Current ); + first_byte = last_status_byte; + } else { + last_status_byte = first_byte; + } + byte ctrl = (byte)(first_byte & (byte)0xf0); + if ( ctrl == 0x80 || ctrl == 0x90 || ctrl == 0xA0 || ctrl == 0xB0 || ctrl == 0xE0 || first_byte == 0xF2 ) { + // 3byte使用するチャンネルメッセージ: + // 0x8*: ノートオフ + // 0x9*: ノートオン + // 0xA*: ポリフォニック・キープレッシャ + // 0xB*: コントロールチェンジ + // 0xE*: ピッチベンドチェンジ + // 3byte使用するシステムメッセージ + // 0xF2: ソングポジション・ポインタ + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + me.Data = new byte[2]; + stream.Read( me.Data, 0, 2 ); + return me; + } else if ( ctrl == 0xC0 || ctrl == 0xD0 || first_byte == 0xF1 || first_byte == 0xF2 ) { + // 2byte使用するチャンネルメッセージ + // 0xC*: プログラムチェンジ + // 0xD*: チャンネルプレッシャ + // 2byte使用するシステムメッセージ + // 0xF1: クォータフレーム + // 0xF3: ソングセレクト + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + me.Data = new byte[1]; + stream.Read( me.Data, 0, 1 ); + return me; + } else if ( first_byte == 0xF6 ) { + // 1byte使用するシステムメッセージ + // 0xF6: チューンリクエスト + // 0xF7: エンドオブエクスクルーシブ(このクラスではF0ステータスのSysExの一部として取り扱う) + // 0xF8: タイミングクロック + // 0xFA: スタート + // 0xFB: コンティニュー + // 0xFC: ストップ + // 0xFE: アクティブセンシング + // 0xFF: システムリセット + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + me.Data = new byte[0]; + return me; + } else if ( first_byte == 0xff ) { + // メタイベント + byte meta_event_type = (byte)stream.ReadByte(); + long meta_event_length = readDeltaClock( stream ); + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + me.Data = new byte[meta_event_length + 1]; + me.Data[0] = meta_event_type; + stream.Read( me.Data, 1, (int)meta_event_length ); + return me; + } else if ( first_byte == 0xf0 ) { + // f0ステータスのSysEx + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + long sysex_length = readDeltaClock( stream ); + me.Data = new byte[sysex_length + 1]; + stream.Read( me.Data, 0, (int)(sysex_length + 1) ); + return me; + } else if ( first_byte == 0xf7 ) { + // f7ステータスのSysEx + MidiEvent me = new MidiEvent(); + me.Clock = last_clock; + me.FirstByte = first_byte; + long sysex_length = readDeltaClock( stream ); + me.Data = new byte[sysex_length]; + stream.Read( me.Data, 0, (int)sysex_length ); + return me; + } else { + throw new ApplicationException( "don't know how to process first_byte: 0x" + Convert.ToString( first_byte, 16 ) ); + } + } + + public void writeData( Stream stream ) { + stream.WriteByte( FirstByte ); + if ( FirstByte == 0xff ) { + stream.WriteByte( Data[0] ); + writeDeltaClock( stream, Data.Length - 1 ); + //stream.WriteByte( (byte)(Data.Length - 1) ); + stream.Write( Data, 1, Data.Length - 1 ); + } else { + stream.Write( Data, 0, Data.Length ); + } + } + + public int CompareTo( MidiEvent item ) { + return (int)(Clock - item.Clock); + } + + public static MidiEvent generateTimeSigEvent( int clock, int numerator, int denominator ) { + MidiEvent ret = new MidiEvent(); + ret.Clock = clock; + ret.FirstByte = 0xff; + byte b_numer = (byte)(Math.Log( numerator, 2 ) + 0.1); + ret.Data = new byte[5] { 0x58, (byte)denominator, b_numer, 0x18, 0x08 }; + return ret; + } + + public static MidiEvent generateTempoChangeEvent( int clock, int tempo ) { + MidiEvent ret = new MidiEvent(); + ret.Clock = clock; + ret.FirstByte = 0xff; + byte b1 = (byte)(tempo & 0xff); + tempo = tempo >> 8; + byte b2 = (byte)(tempo & 0xff); + tempo = tempo >> 8; + byte b3 = (byte)(tempo & 0xff); + ret.Data = new byte[4] { 0x51, b3, b2, b1 }; + return ret; + } + } + + public class MidiFile : IDisposable { + private List> m_events; + private ushort m_format; + private ushort m_time_format; + + public MidiFile( string path ) + : this( new FileStream( path, FileMode.Open ) ) { + } + + public MidiFile( Stream stream ) { + // ヘッダ + byte[] byte4 = new byte[4]; + stream.Read( byte4, 0, 4 ); + if ( makeUInt32( byte4 ) != 0x4d546864 ) { + throw new ApplicationException( "header error: MThd" ); + } + + // データ長 + stream.Read( byte4, 0, 4 ); + uint length = makeUInt32( byte4 ); + + // フォーマット + stream.Read( byte4, 0, 2 ); + m_format = makeUint16( byte4 ); + + // トラック数 + int tracks = 0; + stream.Read( byte4, 0, 2 ); + tracks = (int)makeUint16( byte4 ); + + // 時間分解能 + stream.Read( byte4, 0, 2 ); + m_time_format = makeUint16( byte4 ); + + // 各トラックを読込み + m_events = new List>(); + for ( int track = 0; track < tracks; track++ ) { + // ヘッダー + stream.Read( byte4, 0, 4 ); + if ( makeUInt32( byte4 ) != 0x4d54726b ) { + throw new ApplicationException( "header error; MTrk" ); + } + m_events.Add( new List() ); + + // チャンクサイズ + stream.Read( byte4, 0, 4 ); + long size = (long)makeUInt32( byte4 ); + long startpos = stream.Position; + + // チャンクの終わりまで読込み + long clock = 0; + byte last_status_byte = 0x00; + while ( stream.Position < startpos + size ) { + m_events[track].Add( MidiEvent.read( stream, ref clock, ref last_status_byte ) ); + } + } + stream.Close(); + } + + /*public void Write( string path ) { + }*/ + + public List getMidiEventList( int track ) { + if ( m_events == null ) { + return new List(); + } else if ( 0 <= track && track < m_events.Count ) { + return m_events[track]; + } else { + return new List(); + } + } + + public int getTrackCount() { + if ( m_events == null ) { + return 0; + } else { + return m_events.Count; + } + } + + public void Dispose() { + Close(); + } + + public void Close() { + if ( m_events != null ) { + for ( int i = 0; i < m_events.Count; i++ ) { + m_events[i].Clear(); + } + m_events.Clear(); + } + } + + private static UInt32 makeUInt32( byte[] value ) { + return (uint)((uint)((uint)((uint)(value[0] << 8) | value[1]) << 8 | value[2]) << 8 | value[3]); + } + + private static UInt16 makeUint16( byte[] value ) { + return (ushort)((ushort)(value[0] << 8) | value[1]); + } + + private static long readDeltaClock( Stream stream ) { + byte[] b; + long ret = 0; + while ( true ) { + byte d = (byte)stream.ReadByte(); + ret = (ret << 7) | ((long)d & 0x7f); + if ( (d & 0x80) == 0x00 ) { + break; + } + } + return ret; + } + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/SingerConfig.cs b/trunk/Boare.Lib.Vsq/SingerConfig.cs new file mode 100644 index 0000000..06f9d65 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/SingerConfig.cs @@ -0,0 +1,244 @@ +/* + * SingerConfig.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + public class SingerConfig { + public string ID; + public string FORMAT; + public string VOICEIDSTR; + public string VOICENAME; + public int Breathiness; + public int Brightness; + public int Clearness; + public int Opening; + public int GenderFactor; + public int Original; + + public static void decode_vvd_bytes( ref byte[] dat ) { + for ( int i = 0; i < dat.Length; i++ ) { + byte M = (byte)(dat[i] >> 4); + byte L = (byte)(dat[i] - (M << 4)); + byte newM = endecode_vvd_m( M ); + byte newL = endecode_vvd_l( L ); + dat[i] = (byte)((newM << 4) | newL); + } + } + + static byte endecode_vvd_l( byte value ) { + switch ( value ) { + case 0x0: + return 0xa; + case 0x1: + return 0xb; + case 0x2: + return 0x8; + case 0x3: + return 0x9; + case 0x4: + return 0xe; + case 0x5: + return 0xf; + case 0x6: + return 0xc; + case 0x7: + return 0xd; + case 0x8: + return 0x2; + case 0x9: + return 0x3; + case 0xa: + return 0x0; + case 0xb: + return 0x1; + case 0xc: + return 0x6; + case 0xd: + return 0x7; + case 0xe: + return 0x4; + case 0xf: + return 0x5; + } + return 0x0; + } + + static byte endecode_vvd_m( byte value ) { + switch ( value ) { + case 0x0: + return 0x1; + case 0x1: + return 0x0; + case 0x2: + return 0x3; + case 0x3: + return 0x2; + case 0x4: + return 0x5; + case 0x5: + return 0x4; + case 0x6: + return 0x7; + case 0x7: + return 0x6; + case 0x8: + return 0x9; + case 0x9: + return 0x8; + case 0xa: + return 0xb; + case 0xb: + return 0xa; + case 0xc: + return 0xd; + case 0xd: + return 0xc; + case 0xe: + return 0xf; + case 0xf: + return 0xe; + } + return 0x0; + } + + public SingerConfig( string file, int original ) { + original = original; + ID = "VOCALOID:VIRTUAL:VOICE"; + FORMAT = "2.0.0.0"; + VOICEIDSTR = ""; + VOICENAME = "Miku"; + Breathiness = 0; + Brightness = 0; + Clearness = 0; + Opening = 0; + GenderFactor = 0; + original = 0; + FileStream fs = null; + try { + fs = new FileStream( file, FileMode.Open, FileAccess.Read ); + int length = (int)fs.Length; + byte[] dat = new byte[length]; + fs.Read( dat, 0, length ); + decode_vvd_bytes( ref dat ); + for ( int i = 0; i < dat.Length - 1; i++ ) { + if ( dat[i] == 0x17 && dat[i + 1] == 0x10 ) { + dat[i] = 0x0d; + dat[i + 1] = 0x0a; + } + } + string str = bocoree.cp932.convert( dat ); + string crlf = ((char)0x0d).ToString() + ((char)0x0a).ToString(); + string[] spl = str.Split( new string[] { crlf }, StringSplitOptions.RemoveEmptyEntries ); + + foreach ( string s in spl ) { + int first = s.IndexOf( '"' ); + int first_end = get_quated_string( s, first ); + int second = s.IndexOf( '"', first_end + 1 ); + int second_end = get_quated_string( s, second ); + char[] chs = s.ToCharArray(); + string id = new string( chs, first, first_end - first + 1 ); + string value = new string( chs, second, second_end - second + 1 ); + id = id.Substring( 1, id.Length - 2 ); + value = value.Substring( 1, value.Length - 2 ); + value = value.Replace( "\\\"", "\"" ); + if ( id == "ID" ) { + ID = value; + } else if ( id == "FORMAT" ) { + FORMAT = value; + } else if ( id == "VOICEIDSTR" ) { + VOICEIDSTR = value; + } else if ( id == "VOICENAME" ) { + VOICENAME = value; + } else if ( id == "Breathiness" ) { + try { + Breathiness = int.Parse( value ); + } catch { + } + } else if ( id == "Brightness" ) { + try { + Brightness = int.Parse( value ); + } catch { + } + } else if ( id == "Clearness" ) { + try { + Clearness = int.Parse( value ); + } catch { + } + } else if ( id == "Opening" ) { + try { + Opening = int.Parse( value ); + } catch { + } + } else if ( id == "Gender:Factor" ) { + try { + GenderFactor = int.Parse( value ); + } catch { + } + } + } + } catch { + + } finally { + if ( fs != null ) { + fs.Close(); + } + } + } + + /// + /// 位置positionにある'"'から,次に現れる'"'の位置を調べる.エスケープされた\"はスキップされる.'"'が見つからなかった場合-1を返す + /// + /// + /// + /// + static int get_quated_string( string s, int position ) { + if ( position < 0 ) { + return -1; + } + char[] chs = s.ToCharArray(); + if ( position >= chs.Length ) { + return -1; + } + if ( chs[position] != '"' ) { + return -1; + } + int end = -1; + for ( int i = position + 1; i < chs.Length; i++ ) { + if ( chs[i] == '"' && chs[i - 1] != '\\' ) { + end = i; + break; + } + } + return end; + } + + public new string[] ToString() { + List ret = new List(); + ret.Add( "\"ID\":=:\"" + ID + "\"" ); + ret.Add( "\"FORMAT\":=:\"" + FORMAT + "\"" ); + ret.Add( "\"VOICEIDSTR\":=:\"" + VOICEIDSTR + "\"" ); + ret.Add( "\"VOICENAME\":=:\"" + VOICENAME.Replace( "\"", "\\\"" ) + "\"" ); + ret.Add( "\"Breathiness\":=:\"" + Breathiness + "\"" ); + ret.Add( "\"Brightness\":=:\"" + Brightness + "\"" ); + ret.Add( "\"Clearness\":=:\"" + Clearness + "\"" ); + ret.Add( "\"Opening\":=:\"" + Opening + "\"" ); + ret.Add( "\"Gender:Factor\":=:\"" + GenderFactor + "\"" ); + return ret.ToArray(); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/SymbolTable.cs b/trunk/Boare.Lib.Vsq/SymbolTable.cs new file mode 100644 index 0000000..2f31c87 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/SymbolTable.cs @@ -0,0 +1,676 @@ +/* + * SymbolTable.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; +using System.Windows.Forms; + +using bocoree; + +namespace Boare.Lib.Vsq { + + public class SymbolTable : ICloneable { + private Dictionary m_dict; + private string m_name; + private bool m_enabled; + + #region Static Field + private static SortedList s_table = new SortedList(); + private static SymbolTable s_default_jp = null; + private static bool s_initialized = false; + public static readonly string[,] _KEY_JP = { + {"あ", "a"}, + {"い", "i"}, + {"う", "M"}, + {"え", "e"}, + {"お", "o"}, + {"か", "k a"}, + {"き", "k' i"}, + {"く", "k M"}, + {"け", "k e"}, + {"こ", "k o"}, + {"さ", "s a"}, + {"し", "S i"}, + {"す", "s M"}, + {"せ", "s e"}, + {"そ", "s o"}, + {"た", "t a"}, + {"ち", "tS i"}, + {"つ", "ts M"}, + {"て", "t e"}, + {"と", "t o"}, + {"な", "n a"}, + {"に", "J i"}, + {"ぬ", "n M"}, + {"ね", "n e"}, + {"の", "n o"}, + {"は", "h a"}, + {"ひ", "C i"}, + {"ふ", @"p\ M"}, + {"へ", "h e"}, + {"ほ", "h o"}, + {"ま", "m a"}, + {"み", "m' i"}, + {"む", "m M"}, + {"め", "m e"}, + {"も", "m o"}, + {"や", "j a"}, + {"ゆ", "j M"}, + {"よ", "j o"}, + {"ら", "4 a"}, + {"り", "4' i"}, + {"る", "4 M"}, + {"れ", "4 e "}, + {"ろ", "4 o"}, + {"わ", "w a"}, + {"ゐ", "w i"}, + {"ゑ", "w e"}, + {"を", "o"}, + {"ぁ", "a"}, + {"ぃ", "i"}, + {"ぅ", "M"}, + {"ぇ", "e"}, + {"ぉ", "o"}, + {"が", "g a"}, + {"ぎ", "g' i"}, + {"ぐ", "g M"}, + {"げ", "g e"}, + {"ご", "g o"}, + {"ざ", "dz a"}, + {"じ", "dZ i"}, + {"ず", "dz M"}, + {"ぜ", "dz e"}, + {"ぞ", "dz o"}, + {"だ", "d a"}, + {"ぢ", "dZ i"}, + {"づ", "dz M"}, + {"で", "d e"}, + {"ど", "d o"}, + {"ば", "b a"}, + {"び", "b' i"}, + {"ぶ", "b M"}, + {"べ", "b e"}, + {"ぼ", "b o"}, + {"ぱ", "p a"}, + {"ぴ", "p' i"}, + {"ぷ", "p M"}, + {"ぺ", "p e"}, + {"ぽ", "p o"}, + {"いぇ", "j e"}, + {"うぃ", "w i"}, + {"うぇ", "w e"}, + {"うぉ", "w o"}, + {"きゃ", "k' a"}, + {"きゅ", "k' M"}, + {"きぇ", "k' e"}, + {"きょ", "k' o"}, + {"しゃ", "S a"}, + {"しゅ", "S M"}, + {"しぇ", "S e"}, + {"しょ", "S o"}, + {"ちゃ", "tS a"}, + {"ちゅ", "tS M"}, + {"ちぇ", "tS e"}, + {"ちょ", "tS o"}, + {"にゃ", "J a"}, + {"にゅ", "J M"}, + {"にぇ", "J e"}, + {"にょ", "J o"}, + {"ひゃ", "C a"}, + {"ひゅ", "C M"}, + {"ひぇ", "C e"}, + {"ひょ", "C o"}, + {"ふゃ", @"p\' a"}, + {"ふぃ", @"p\' i"}, + {"ふゅ", @"p\' M"}, + {"ふぇ", @"p\ e"}, + {"みゃ", "m' a"}, + {"みゅ", "m' M"}, + {"みぇ", "m' e"}, + {"みょ", "m' o"}, + {"りゃ", "4' a"}, + {"りゅ", "4' M"}, + {"りぇ", "4' e"}, + {"りょ", "4' o"}, + {"ぎゃ", "g' a"}, + {"ぎゅ", "g' M"}, + {"ぎぇ", "g' e"}, + {"ぎょ", "g' o"}, + {"じゃ", "dZ a"}, + {"じゅ", "dZ M"}, + {"じぇ", "dZ e"}, + {"じょ", "dZ o"}, + {"びゃ", "b' a"}, + {"びゅ", "b' M"}, + {"びぇ", "b' e"}, + {"びょ", "b' o"}, + {"ぴゃ", "p' a"}, + {"ぴゅ", "p' M"}, + {"ぴぇ", "p' e"}, + {"ぴょ", "p' o"}, + {"ふぁ", @"p\ a"}, + {"ふぉ", @"p\ o"}, + {"てゃ", "t' a"}, + {"てぃ", "t' i"}, + {"てゅ", "t' M"}, + {"てぇ", "t' e"}, + {"てょ", "t' o"}, + {"でゃ", "d' a"}, + {"でぃ", "d' i"}, + {"でゅ", "d' M"}, + {"でぇ", "d' e"}, + {"でょ", "d' o"}, + {"すぃ", "s i"}, + {"ずぃ", "dz i"}, + {"とぅ", "t M"}, + {"どぅ", "d M"}, + {"ゃ", "j a"}, + {"ゅ", "j M"}, + {"ょ", "j o"}, + {"ん", "n"}, + {"ア", "a"}, + {"イ", "i"}, + {"ウ", "M"}, + {"エ", "e"}, + {"オ", "o"}, + {"カ", "k a"}, + {"キ", "k' i"}, + {"ク", "k M"}, + {"ケ", "k e"}, + {"コ", "k o"}, + {"サ", "s a"}, + {"シ", "S i"}, + {"ス", "s M"}, + {"セ", "s e"}, + {"ソ", "s o"}, + {"タ", "t a"}, + {"チ", "tS i"}, + {"ツ", "ts M"}, + {"テ", "t e"}, + {"ト", "t o"}, + {"ナ", "n a"}, + {"ニ", "J i"}, + {"ヌ", "n M"}, + {"ネ", "n e"}, + {"ノ", "n o"}, + {"ハ", "h a"}, + {"ヒ", "C i"}, + {"フ", @"p\ M"}, + {"ヘ", "h e"}, + {"ホ", "h o"}, + {"マ", "m a"}, + {"ミ", "m' i"}, + {"ム", "m M"}, + {"メ", "m e"}, + {"モ", "m o"}, + {"ヤ", "j a"}, + {"ユ", "j M"}, + {"ヨ", "j o"}, + {"ラ", "4 a"}, + {"リ", "4' i"}, + {"ル", "4 M"}, + {"レ", "4 e "}, + {"ロ", "4 o"}, + {"ワ", "w a"}, + {"ヰ", "w i"}, + {"ヱ", "w e"}, + {"ヲ", "o"}, + {"ァ", "a"}, + {"ィ", "i"}, + {"ゥ", "M"}, + {"ェ", "e"}, + {"ォ", "o"}, + {"ガ", "g a"}, + {"ギ", "g' i"}, + {"グ", "g M"}, + {"ゲ", "g e"}, + {"ゴ", "g o"}, + {"ザ", "dz a"}, + {"ジ", "dZ i"}, + {"ズ", "dz M"}, + {"ゼ", "dz e"}, + {"ゾ", "dz o"}, + {"ダ", "d a"}, + {"ヂ", "dZ i"}, + {"ヅ", "dz M"}, + {"デ", "d e"}, + {"ド", "d o"}, + {"バ", "b a"}, + {"ビ", "b' i"}, + {"ブ", "b M"}, + {"ベ", "b e"}, + {"ボ", "b o"}, + {"パ", "p a"}, + {"ピ", "p' i"}, + {"プ", "p M"}, + {"ペ", "p e"}, + {"ポ", "p o"}, + {"イェ", "j e"}, + {"ウィ", "w i"}, + {"ウェ", "w e"}, + {"ウォ", "w o"}, + {"キャ", "k' a"}, + {"キュ", "k' M"}, + {"キェ", "k' e"}, + {"キョ", "k' o"}, + {"シャ", "S a"}, + {"シュ", "S M"}, + {"シェ", "S e"}, + {"ショ", "S o"}, + {"チャ", "tS a"}, + {"チュ", "tS M"}, + {"チェ", "tS e"}, + {"チョ", "tS o"}, + {"ニャ", "J a"}, + {"ニュ", "J M"}, + {"ニェ", "J e"}, + {"ニョ", "J o"}, + {"ヒャ", "C a"}, + {"ヒュ", "C M"}, + {"ヒェ", "C e"}, + {"ヒョ", "C o"}, + {"フャ", @"p\' a"}, + {"フィ", @"p\' i"}, + {"フュ", @"p\' M"}, + {"フェ", @"p\ e"}, + {"ミャ", "m' a"}, + {"ミュ", "m' M"}, + {"ミェ", "m' e"}, + {"ミョ", "m' o"}, + {"リャ", "4' a"}, + {"リュ", "4' M"}, + {"リェ", "4' e"}, + {"リョ", "4' o"}, + {"ギャ", "g' a"}, + {"ギュ", "g' M"}, + {"ギェ", "g' e"}, + {"ギョ", "g' o"}, + {"ジャ", "dZ a"}, + {"ジュ", "dZ M"}, + {"ジェ", "dZ e"}, + {"ジョ", "dZ o"}, + {"ビャ", "b' a"}, + {"ビュ", "b' M"}, + {"ビェ", "b' e"}, + {"ビョ", "b' o"}, + {"ピャ", "p' a"}, + {"ピュ", "p' M"}, + {"ピェ", "p' e"}, + {"ピョ", "p' o"}, + {"ファ", @"p\ a"}, + {"フォ", @"p\ o"}, + {"テャ", "t' a"}, + {"ティ", "t' i"}, + {"テュ", "t' M"}, + {"テェ", "t' e"}, + {"テョ", "t' o"}, + {"デャ", "d' a"}, + {"ディ", "d' i"}, + {"デュ", "d' M"}, + {"デェ", "d' e"}, + {"デョ", "d' o"}, + {"スィ", "s i"}, + {"ズィ", "dz i"}, + {"トゥ", "t M"}, + {"ドゥ", "d M"}, + {"ャ", "j a"}, + {"ュ", "j M"}, + {"ョ", "j o"}, + {"ン", "n"}, + {"ヴ", "b M"}, + {"a", "a"}, + {"e", "e"}, + {"i", "i"}, + {"m", "n"}, + {"n", "n"}, + {"o", "o"}, + {"u", "M"}, + {"A", "a"}, + {"E", "e"}, + {"I", "i"}, + {"M", "n"}, + {"N", "n"}, + {"O", "o"}, + {"U", "M"}, + {"ka", "k a"}, + {"ki", "k' i"}, + {"ku", "k M"}, + {"ke", "k e"}, + {"ko", "k o"}, + {"kya", "k' a"}, + {"kyu", "k' M"}, + {"kyo", "k' o"}, + {"sa", "s a"}, + {"si", "s i"}, + {"su", "s M"}, + {"se", "s e"}, + {"so", "s o"}, + {"ta", "t a"}, + {"ti", "t' i"}, + {"tu", "t M"}, + {"te", "t e"}, + {"to", "t o"}, + {"tya", "t' a"}, + {"tyu", "t' M"}, + {"tyo", "t' o"}, + {"na", "n a"}, + {"ni", "J i"}, + {"nu", "n M"}, + {"ne", "n e"}, + {"no", "n o"}, + {"nya", "J a"}, + {"nyu", "J M"}, + {"nyo", "J o"}, + {"ha", "h a"}, + {"hi", "C i"}, + {"he", "h e"}, + {"ho", "h o"}, + {"hya", "C a"}, + {"hyu", "C M"}, + {"hyo", "C o"}, + {"ma", "m a"}, + {"mi", "m' i"}, + {"mu", "m M"}, + {"me", "m e"}, + {"mo", "m o"}, + {"mya", "m' a"}, + {"myu", "m' M"}, + {"myo", "m' o"}, + {"ya", "j a"}, + {"yu", "j M"}, + {"ye", "j e"}, + {"yo", "j o"}, + {"ra", "4 a"}, + {"ri", "4' i"}, + {"ru", "4 M"}, + {"re", "4 e"}, + {"ro", "4 o"}, + {"rya", "4' a"}, + {"ryu", "4' M"}, + {"ryo", "4' o"}, + {"wa", "w a"}, + {"wi", "w i"}, + {"we", "w e"}, + {"wo", "w o"}, + {"ga", "g a"}, + {"gi", "g' i"}, + {"gu", "g M"}, + {"ge", "g e"}, + {"go", "g o"}, + {"gya", "g' a"}, + {"gyu", "g' M"}, + {"gyo", "g' o"}, + {"za", "dz a"}, + {"zi", "dz i"}, + {"zu", "dz M"}, + {"ze", "dz e"}, + {"zo", "dz o"}, + {"da", "d a"}, + {"di", "d' i"}, + {"du", "d M"}, + {"de", "d e"}, + {"do", "d o"}, + {"dya", "d' a"}, + {"dyu", "d' M"}, + {"dyo", "d' o"}, + {"ba", "b a"}, + {"bi", "b' i"}, + {"bu", "b M"}, + {"be", "b e"}, + {"bo", "b o"}, + {"bya", "b' a"}, + {"byu", "b' M"}, + {"byo", "b' o"}, + {"pa", "p a"}, + {"pi", "p' i"}, + {"pu", "p M"}, + {"pe", "p e"}, + {"po", "p o"}, + {"pya", "p' a"}, + {"pyu", "p' M"}, + {"pyo", "p' o"}, + {"sha", "S a"}, + {"shi", "S i"}, + {"shu", "S M"}, + {"sho", "S o"}, + {"tsu", "ts M"}, + {"cha", "tS a"}, + {"chi", "tS i"}, + {"chu", "tS M"}, + {"cho", "tS o"}, + {"fu", @"p\ M"}, + {"ja", "dZ a"}, + {"ji", "dZ i"}, + {"ju", "dZ M"}, + {"jo", "dZ o"}, + }; + #endregion + + #region Static Method and Property + public static SymbolTable getSymbolTable( int index ) { + if ( !s_initialized ) { + loadDictionary(); + } + if ( 0 <= index && index < s_table.Count ) { + return s_table[index]; + } else { + return null; + } + } + + public static void loadDictionary() { +#if DEBUG + Console.WriteLine( "SymbolTable.LoadDictionary()" ); +#endif + s_default_jp = new SymbolTable( "DEFAULT_JP", _KEY_JP, true ); + s_table.Clear(); + s_table.Add( 0, s_default_jp ); + int count = 0; + + // 辞書フォルダからの読込み + string editor_path = VsqUtil.getEditorPath(); + if ( editor_path.Length > 0 ) { + string path = Path.Combine( Path.GetDirectoryName( editor_path ), "UDIC" ); + if ( !Directory.Exists( path ) ) { + return; + } + string[] files = Directory.GetFiles( path, "*.udc" ); + for ( int i = 0; i < files.Length; i++ ) { + files[i] = Path.GetFileName( files[i] ); +#if DEBUG + Console.WriteLine( " files[i]=" + files[i] ); +#endif + count++; + string dict = Path.Combine( path, files[i] ); + s_table.Add( count, new SymbolTable( dict, true, false ) ); + } + } + + // 起動ディレクトリ + string path2 = Path.Combine( Application.StartupPath, "udic" ); + if ( Directory.Exists( path2 ) ) { + string[] files2 = Directory.GetFiles( path2, "*.eudc" ); + for ( int i = 0; i < files2.Length; i++ ) { + files2[i] = Path.GetFileName( files2[i] ); +#if DEBUG + Console.WriteLine( " files2[i]=" + files2[i] ); +#endif + count++; + string dict = Path.Combine( path2, files2[i] ); + s_table.Add( count, new SymbolTable( dict, false, false ) ); + } + } + s_initialized = true; + } + + + public static bool attatch( string phrase, out string result ) { +#if DEBUG + Console.WriteLine( "SymbolTable.Attatch" ); + Console.WriteLine( " phrase=" + phrase ); +#endif + for ( int i = 0; i < s_table.Keys.Count; i++ ) { + int key = s_table.Keys[i]; + if ( s_table[key].isEnabled() ) { + if ( s_table[key].attatchImp( phrase, out result ) ) { + return true; + } + } + } + result = "a"; + return false; + } + + public static int getCount() { + if ( !s_initialized ) { + loadDictionary(); + } + return s_table.Count; + } + + public static void changeOrder( KeyValuePair[] list ) { +#if DEBUG + Console.WriteLine( "SymbolTable.Sort()" ); +#endif + SortedList buff = new SortedList(); + foreach ( int key in s_table.Keys ) { + buff.Add( key, (SymbolTable)s_table[key].Clone() ); + } + s_table.Clear(); + for ( int i = 0; i < list.Length; i++ ) { +#if DEBUG + Console.WriteLine( " list[i]=" + list[i].Key + "," + list[i].Value ); +#endif + for ( int j = 0; j < buff.Keys.Count; j++ ) { + int key = buff.Keys[j]; + if ( buff[key].getName() == list[i].Key ) { + buff[key].setEnabled( list[i].Value ); + s_table.Add( i, buff[key] ); + break; + } + } + } + } + #endregion + + public object Clone() { + SymbolTable ret = new SymbolTable(); + ret.m_dict = new Dictionary(); + foreach ( string key in m_dict.Keys ) { + ret.m_dict.Add( key, m_dict[key] ); + } + ret.m_name = m_name; + ret.m_enabled = m_enabled; + return ret; + } + + private SymbolTable() { + } + + public string getName() { + return m_name; + } + + public bool isEnabled() { + return m_enabled; + } + + public void setEnabled( bool value ){ + m_enabled = value; + } + + public SymbolTable( string path, bool is_udc_mode, bool enabled ) { + m_dict = new Dictionary(); + m_enabled = enabled; + if ( !File.Exists( path ) ) { + return; + } + m_name = Path.GetFileName( path ); + cp932reader sr1 = null; + StreamReader sr2 = null; + try { + if ( is_udc_mode ) { + sr1 = new cp932reader( path ); + if ( sr1 == null ) { + return; + } + } else { + sr2 = new StreamReader( path, Encoding.UTF8 ); + if ( sr2 == null ) { + return; + } + } + string line; + int peek = (is_udc_mode) ? sr1.Peek() : sr2.Peek(); + while ( peek >= 0 ) { + line = (is_udc_mode) ? sr1.ReadLine() : sr2.ReadLine(); + if ( !line.StartsWith( "//" ) ) { + string[] spl = line.Split( "\t".ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries ); + if ( spl.Length >= 2 ) { + if ( m_dict.ContainsKey( spl[0] ) ) { + bocoree.debug.push_log( "SymbolTable..ctor" ); + bocoree.debug.push_log( " dictionary already contains key: " + spl[0] ); + } else { + m_dict.Add( spl[0], spl[1] ); + } + } + } + peek = (is_udc_mode) ? sr1.Peek() : sr2.Peek(); + } + } catch ( Exception ex ) { + bocoree.debug.push_log( "SymbolTable..ctor" ); + bocoree.debug.push_log( " " + ex ); + } finally { + if ( sr1 != null ) { + sr1.Close(); + } + if ( sr2 != null ) { + sr2.Close(); + } + } + } + + private bool attatchImp( string phrase, out string result ) { + string s = phrase.ToLower(); + if ( m_dict.ContainsKey( s ) ) { + result = m_dict[s]; + return true; + } else { + result = "a"; + return false; + } + } + + private SymbolTable( string name, string[,] key, bool enabled ) { +#if DEBUG + Console.WriteLine( "SymolTable.ctor(string,string[,])" ); + Console.WriteLine( " key.GetLength(0)=" + key.GetLength( 0 ) ); +#endif + m_enabled = enabled; + m_name = name; + m_dict = new Dictionary(); + for ( int i = 0; i < key.GetLength( 0 ); i++ ) { + if ( m_dict.ContainsKey( key[i, 0] ) ) { +#if DEBUG + throw new ApplicationException( "dictionary already contains key: " + key[i, 0] ); +#endif + } else { + m_dict.Add( key[i, 0], key[i, 1] ); + } + } + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/TempoTableEntry.cs b/trunk/Boare.Lib.Vsq/TempoTableEntry.cs new file mode 100644 index 0000000..005c52d --- /dev/null +++ b/trunk/Boare.Lib.Vsq/TempoTableEntry.cs @@ -0,0 +1,48 @@ +/* + * TempoTableEntry.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + [Serializable] + public class TempoTableEntry : IComparable, ICloneable { + public int Clock; + public int Tempo; + public double Time; + + public object Clone() { + return new TempoTableEntry( Clock, Tempo, Time ); + } + + public TempoTableEntry( int clock, int _tempo, double _time ) { + this.Clock = clock; + this.Tempo = _tempo; + this.Time = _time; + } + + public int CompareTo( TempoTableEntry entry ) { + return this.Clock - entry.Clock; + } + + public bool Equals( TempoTableEntry entry ) { + if ( this.Clock == entry.Clock ) { + return true; + } else { + return false; + } + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/TextMemoryStream.cs b/trunk/Boare.Lib.Vsq/TextMemoryStream.cs new file mode 100644 index 0000000..cecb7c5 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/TextMemoryStream.cs @@ -0,0 +1,127 @@ +/* + * TextMemoryStream.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + /// + /// メモリー上でテキストファイルを扱うためのクラス. + /// + public class TextMemoryStream : IDisposable { + FileAccess m_access; + MemoryStream m_ms = null; + Encoding m_enc; + byte[] NEW_LINE; + + /// + /// + /// + /// + public void write( string value ) { + byte[] buff = m_enc.GetBytes( value ); + m_ms.Write( buff, 0, buff.Length ); + } + + public void rewind() { + m_ms.Seek( 0, SeekOrigin.Begin ); + } + + public void writeLine( string s ) { + byte[] buff = m_enc.GetBytes( s + Environment.NewLine ); + m_ms.Write( buff, 0, buff.Length ); + } + + public void close() { + if ( m_ms != null ) { + m_ms.Close(); + } + } + + public int peek() { + long current = m_ms.Position; + int ret = m_ms.ReadByte(); + m_ms.Seek( current, SeekOrigin.Begin ); + return ret; + } + + public string readLine() { + List buffer = new List(); + byte value; + int ret; + ret = m_ms.ReadByte(); + while ( ret >= 0 ) { + value = (byte)ret; + if ( value == NEW_LINE[0] ) { + byte next; + long current = m_ms.Position; //0x0Dを検出した直後のストリームの位置 + for ( int i = 1; i < NEW_LINE.Length; i++ ) { + ret = m_ms.ReadByte(); + if ( ret >= 0 ) { + next = (byte)ret; + if ( next != NEW_LINE[i] ) { + m_ms.Seek( current, SeekOrigin.Begin ); + break; + } + } + } + break; + } + buffer.Add( value ); + ret = m_ms.ReadByte(); + } + return Encoding.Unicode.GetString( buffer.ToArray() ); + } + + public void Dispose() { + if ( m_ms != null ) { + m_ms.Close(); + } + } + + public TextMemoryStream( string path, Encoding encode ) { + m_access = FileAccess.Read; + m_ms = new MemoryStream(); + m_enc = encode; + if ( File.Exists( path ) ) { + using ( StreamReader sr = new StreamReader( path, encode ) ) { + while ( sr.Peek() >= 0 ) { + string line = sr.ReadLine(); + byte[] buffer = m_enc.GetBytes( line + Environment.NewLine ); + m_ms.Write( buffer, 0, buffer.Length ); + } + } + m_ms.Seek( 0, SeekOrigin.Begin ); + } + NEW_LINE = m_enc.GetBytes( Environment.NewLine ); + } + + public TextMemoryStream( FileAccess access ) { + m_access = access; + m_ms = new MemoryStream(); + m_enc = Encoding.Unicode; + NEW_LINE = m_enc.GetBytes( Environment.NewLine ); + } + + public TextMemoryStream() { + m_access = FileAccess.Write; + m_ms = new MemoryStream(); + m_enc = Encoding.Unicode; + NEW_LINE = m_enc.GetBytes( Environment.NewLine ); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/TimeSigTableEntry.cs b/trunk/Boare.Lib.Vsq/TimeSigTableEntry.cs new file mode 100644 index 0000000..7b4c8e1 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/TimeSigTableEntry.cs @@ -0,0 +1,61 @@ +/* + * TimeSigTableEntry.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq{ + + [Serializable] + public class TimeSigTableEntry : IComparable, ICloneable { + /// + /// クロック数 + /// + public int Clock; + /// + /// 拍子の分子 + /// + public int Numerator; + /// + /// 拍子の分母 + /// + public int Denominator; + /// + /// 何小節目か + /// + public int BarCount; + + public TimeSigTableEntry( + int clock, + int numerator, + int denominator, + int bar_count ) { + Clock = clock; + Numerator = numerator; + Denominator = denominator; + BarCount = bar_count; + } + + public override string ToString() { + return "{Clock=" + Clock + ", Numerator=" + Numerator + ", Denominator=" + Denominator + ", BarCount=" + BarCount + "}"; + } + + public object Clone() { + return new TimeSigTableEntry( Clock, Numerator, Denominator, BarCount ); + } + + public int CompareTo( TimeSigTableEntry item ) { + return this.BarCount - item.BarCount; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/UstEvent.cs b/trunk/Boare.Lib.Vsq/UstEvent.cs new file mode 100644 index 0000000..7fe1804 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/UstEvent.cs @@ -0,0 +1,74 @@ +/* + * UstEvent.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; + +namespace Boare.Lib.Vsq { + + public class UstEvent : ICloneable { + public object Tag; + public int Length = 0; + public string Lyric = ""; + public int Note = -1; + public int Intensity = -1; + public int PBType = -1; + public float[] Pitches = null; + public float Tempo = -1; + + public object Clone() { + UstEvent ret = new UstEvent(); + ret.Length = Length; + ret.Lyric = Lyric; + ret.Note = Note; + ret.Intensity = Intensity; + ret.PBType = PBType; + if ( Pitches != null ) { + ret.Pitches = new float[Pitches.Length]; + for ( int i = 0; i < Pitches.Length; i++ ) { + ret.Pitches[i] = Pitches[i]; + } + } + ret.Tempo = Tempo; + return ret; + } + + public void print( StreamWriter sw, uint index ) { + sw.WriteLine( string.Format( "[#{0:d4}]", index ) ); + sw.WriteLine( "Length=" + Length ); + sw.WriteLine( "Lyric=" + Lyric ); + sw.WriteLine( "NoteNum=" + Note ); + if ( Intensity >= 0 ) { + sw.WriteLine( "Intensity=" + Intensity ); + } + if ( PBType >= 0 && Pitches != null ) { + sw.WriteLine( "PBType=" + PBType ); + sw.Write( "Piches=" ); + for ( int i = 0; i < Pitches.Length; i++ ) { + if ( i == 0 ) { + sw.Write( Pitches[i] ); + } else { + sw.Write( "," + Pitches[i] ); + } + } + sw.WriteLine(); + } + if ( Tempo > 0 ) { + sw.WriteLine( "Tempo=" + Tempo ); + } + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/UstFile.cs b/trunk/Boare.Lib.Vsq/UstFile.cs new file mode 100644 index 0000000..2f43177 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/UstFile.cs @@ -0,0 +1,259 @@ +/* + * UstFile.cs + * Copyright (c) 2009 kbinani, PEX + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Collections.Generic; +using System.Text; + +using bocoree; + +namespace Boare.Lib.Vsq{ + + public class UstFile : ICloneable { + public object Tag; + private float m_tempo = 125.00f; + private string m_project_name = ""; + private string m_voice_dir = ""; + private string m_out_file = ""; + private string m_cache_dir = ""; + private string m_tool1 = ""; + private string m_tool2 = ""; + private List m_tracks = new List(); + private List m_tempo_table; + + public UstFile( string path ){ + cp932reader sr = new cp932reader( path ); + string line = sr.ReadLine(); + if ( line != "[#SETTING]" ) { + throw new Exception( "invalid ust file" ); + } + UstTrack track = new UstTrack(); + int type = 0; //0 => reading "SETTING" section + while( true ) { + UstEvent ue = null; + if ( type == 1 ) { + ue = new UstEvent(); + } + if ( line == "[#TRACKEND]" ) { + break; + } + line = sr.ReadLine(); // "[#" ̍s + while( !line.StartsWith( "[#" ) ){ + string[] spl = line.Split( "=".ToCharArray(), 2 ); + if ( type == 0 ) { + // reading "SETTING" section + if ( spl[0] == "Tempo" ) { + m_tempo = 125f; + float v = 125f; + if ( float.TryParse( spl[1], out v ) ) { + m_tempo = v; + } + } else if ( spl[0] == "ProjectName" ) { + m_project_name = spl[1]; + } else if ( spl[0] == "VoiceDir" ) { + m_voice_dir = spl[1]; + } else if ( spl[0] == "OutFile" ) { + m_out_file = spl[1]; + } else if ( spl[0] == "CacheDir" ) { + m_cache_dir = spl[1]; + } else if ( spl[0] == "Tool1" ) { + m_tool1 = spl[1]; + } else if ( spl[0] == "Tool2" ) { + m_tool2 = spl[1]; + } + } else if ( type == 1 ) { + // readin event section + if ( spl[0] == "Length" ) { + ue.Length = 0; + int v = 0; + if ( int.TryParse( spl[1], out v ) ){ + ue.Length =v; + } + } else if ( spl[0] == "Lyric" ) { + ue.Lyric = spl[1]; + } else if ( spl[0] == "NoteNum" ) { + ue.Note = 0; + int v = 0; + if ( int.TryParse( spl[1], out v ) ) { + ue.Note = v; + } + } else if ( spl[0] == "Intensity" ) { + ue.Intensity =64; + int v = 64; + if ( int.TryParse( spl[1], out v ) ) { + ue.Intensity = v; + } + } else if ( spl[0] == "PBType" ) { + ue.PBType = 5; + int v = 5; + if ( int.TryParse( spl[1], out v ) ) { + ue.PBType = v; + } + } else if ( spl[0] == "Piches" ) { + string[] spl2 = spl[1].Split( ",".ToCharArray() ); + float[] t = new float[spl2.Length]; + for ( int i = 0; i < spl2.Length; i++ ) { + float v = 0; + float.TryParse( spl2[i], out v ); + t[i] = v; + } + ue.Pitches = t; + } else if ( spl[0] == "Tempo" ) { + ue.Tempo = 125f; + float v; + if ( float.TryParse( spl[1], out v ) ){ + ue.Tempo = v; + } + } + } + line = sr.ReadLine(); + } + if ( type == 0 ) { + type = 1; + } else if ( type == 1 ) { + track.addEvent( ue ); + } + } + m_tracks.Add( track ); + sr.Close(); + updateTempoInfo(); + } + + private UstFile(){ + } + + public string getProjectName() { + return m_project_name; + } + + public int getBaseTempo() { + return (int)(6e7 / m_tempo); + } + + public double getTotalSec() { + int max = 0; + for ( int track = 0; track < m_tracks.Count; track++ ) { + int count = 0; + for ( int i = 0; i < m_tracks[track].getEventCount(); i++ ) { + count += (int)m_tracks[track].getEvent( i ).Length; + } + max = Math.Max( max, count ); + } + return getSecFromClock( max ); + } + + public List getTempoList() { + return m_tempo_table; + } + + public UstTrack getTrack( int track ) { + return m_tracks[track]; + } + + public int getTrackCount() { + return m_tracks.Count; + } + + /// + /// TempoTable[*].Time̕XV܂ + /// + /// + public void updateTempoInfo() { + m_tempo_table = new List(); + if ( m_tracks.Count <= 0 ) { + return; + } + int clock = 0; + double time = 0.0; + int last_tempo_clock = 0; //ŌTempolĂCxg̃NbN + float last_tempo = m_tempo; //ŌɑĂe|̒l + for ( int i = 0; i < m_tracks[0].getEventCount(); i++ ) { + if ( m_tracks[0].getEvent( i ).Tempo > 0f ) { + time += (clock - last_tempo_clock) / (8.0 * last_tempo); + if ( m_tempo_table.Count == 0 && clock != 0 ) { + m_tempo_table.Add( new TempoTableEntry( 0, (int)(6e7 / m_tempo), 0.0 ) ); + } + m_tempo_table.Add( new TempoTableEntry( clock, (int)(6e7 / m_tracks[0].getEvent( i ).Tempo), time ) ); + last_tempo = m_tracks[0].getEvent( i ).Tempo; + last_tempo_clock = clock; + } + clock += (int)m_tracks[0].getEvent( i ).Length; + } +#if DEBUG + using ( StreamWriter sw = new StreamWriter( Path.Combine( System.Windows.Forms.Application.StartupPath, "ust_tempo_info.txt" ) ) ) { + sw.WriteLine( "Clock\tTime\tTempo" ); + for ( int i = 0; i < m_tempo_table.Count; i++ ) { + sw.WriteLine( m_tempo_table[i].Clock + "\t" + m_tempo_table[i].Time + "\t" + m_tempo_table[i].Tempo ); + } + } +#endif + } + + /// + /// w肵NbNɂAclock=0̉toߎ(sec) + /// + /// + /// + public double getSecFromClock( int clock ) { + for ( int i = m_tempo_table.Count - 1; i >= 0; i-- ) { + if ( m_tempo_table[i].Clock < clock ) { + double init = m_tempo_table[i].Time; + int dclock = clock - m_tempo_table[i].Clock; + double sec_per_clock1 = m_tempo_table[i].Tempo * 1e-6 / 480.0; + return init + dclock * sec_per_clock1; + } + } + double sec_per_clock = 0.125 / m_tempo; + return clock * sec_per_clock; + } + + public void write( string file ) { + StreamWriter sw = new StreamWriter( file, false, Encoding.GetEncoding( "Shift_JIS" ) ); + sw.WriteLine( "[#SETTING]" ); + sw.WriteLine( "Tempo=" + m_tempo ); + sw.WriteLine( "Tracks=1" ); + sw.WriteLine( "ProjectName=" + m_project_name ); + sw.WriteLine( "VoiceDir=" + m_voice_dir ); + sw.WriteLine( "OutFile=" + m_out_file ); + sw.WriteLine( "CacheDir=" + m_cache_dir ); + sw.WriteLine( "Tool1=" + m_tool1 ); + sw.WriteLine( "Tool2=" + m_tool2 ); + for ( int i = 0; i < m_tracks[0].getEventCount(); i++ ) { + m_tracks[0].getEvent( i ).print( sw, (uint)i ); + } + sw.WriteLine( "[#TRACKEND]" ); + sw.Close(); + } + + public object Clone(){ + UstFile ret = new UstFile(); + ret.m_tempo = m_tempo; + ret.m_project_name = m_project_name; + ret.m_voice_dir = m_voice_dir; + ret.m_out_file = m_out_file; + ret.m_cache_dir = m_cache_dir; + ret.m_tool1 = m_tool1; + ret.m_tool2 = m_tool2; + for ( int i = 0; i < m_tracks.Count; i++ ) { + ret.m_tracks[i] = (UstTrack)m_tracks[i].Clone(); + } + ret.m_tempo_table = new List(); + for ( int i = 0; i < m_tempo_table.Count; i++ ) { + ret.m_tempo_table.Add( (TempoTableEntry)m_tempo_table[i].Clone() ); + } + return ret; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/UstTrack.cs b/trunk/Boare.Lib.Vsq/UstTrack.cs new file mode 100644 index 0000000..9e766e1 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/UstTrack.cs @@ -0,0 +1,60 @@ +/* + * UstTrack.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq{ + + public class UstTrack : ICloneable { + public object Tag; + private List m_events; + + public UstTrack(){ + m_events = new List(); + } + + public UstEvent getEvent( int index ) { + return m_events[index]; + } + + public void setEvent( int index, UstEvent item ) { + m_events[index] = item; + } + + public void addEvent( UstEvent item ) { + m_events.Add( item ); + } + + public void removeEvent( int index ) { + m_events.RemoveAt( index ); + } + + public int getEventCount() { + return m_events.Count; + } + + public Iterator getNoteEventIterator() { + return new ListIterator( m_events ); + } + + public object Clone() { + UstTrack ret = new UstTrack(); + for ( int i = 0; i < m_events.Count; i++ ) { + ret.m_events[i] = (UstEvent)m_events[i].Clone(); + } + return ret; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VibratoBPList.cs b/trunk/Boare.Lib.Vsq/VibratoBPList.cs new file mode 100644 index 0000000..754214b --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VibratoBPList.cs @@ -0,0 +1,62 @@ +/* + * VibratoBPList.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + public class VibratoBPList : ICloneable { + private List m_list; + + public VibratoBPList() { + m_list = new List(); + } + + public VibratoBPList( float[] x, int[] y ){ + if ( x == null ){ + throw new ArgumentNullException( "x" ); + } + if ( y == null ){ + throw new ArgumentNullException( "y" ); + } + int len = Math.Min( x.Length, y.Length ); + m_list = new List( len ); + for ( int i = 0; i < len; i++ ) { + m_list.Add( new VibratoBPPair( x[i], y[i] ) ); + } + m_list.Sort(); + } + + public object Clone() { + VibratoBPList ret = new VibratoBPList(); + for ( int i = 0; i < m_list.Count; i++ ) { + ret.m_list.Add( new VibratoBPPair( m_list[i].X, m_list[i].Y ) ); + } + return ret; + } + + public int getCount() { + return m_list.Count; + } + + public VibratoBPPair getElement( int index ) { + return m_list[index]; + } + + public void setElement( int index, VibratoBPPair value ) { + m_list[index] = value; + } + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/VibratoBPPair.cs b/trunk/Boare.Lib.Vsq/VibratoBPPair.cs new file mode 100644 index 0000000..daa75b1 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VibratoBPPair.cs @@ -0,0 +1,38 @@ +/* + * VibratoBPPair.cs + * Copyright (c) 2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + public class VibratoBPPair : IComparable { + public float X; + public int Y; + + public VibratoBPPair( float x, int y ) { + X = x; + Y = y; + } + + public int CompareTo( VibratoBPPair item ) { + float v = X - item.X; + if ( v > 0.0f ) { + return 1; + } else if ( v < 0.0f ) { + return -1; + } + return 0; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VibratoType.cs b/trunk/Boare.Lib.Vsq/VibratoType.cs new file mode 100644 index 0000000..58953cc --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VibratoType.cs @@ -0,0 +1,351 @@ +/* + * VibratoType.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + /// + /// ビブラートのプリセット・タイプを表します + /// + public enum VibratoType : int { + /// + /// NormalType1 + /// + NormalType1 = 1, + /// + /// NrormalType2 + /// + NormalType2, + /// + /// NormalType3 + /// + NormalType3, + /// + /// NormalType4 + /// + NormalType4, + /// + /// ExtremeType1 + /// + ExtremeType1, + /// + /// ExtremeType2 + /// + ExtremeType2, + /// + /// ExtremeType3 + /// + ExtremeType3, + /// + /// ExtremeType4 + /// + ExtremeType4, + /// + /// FastType1 + /// + FastType1, + /// + /// FastType2 + /// + FastType2, + /// + /// FastType3 + /// + FastType3, + /// + /// FastType4 + /// + FastType4, + /// + /// SlightType1 + /// + SlightType1, + /// + /// SlightType2 + /// + SlightType2, + /// + /// SlightType3 + /// + SlightType3, + /// + /// SlightType4 + /// + SlightType4, + } + + /// + /// VibratoTypeのためのユーティリティを集めたスタティック・クラス + /// + public static class VibratoTypeUtil { + /// + /// IconID文字列から,VibratoTypeを調べます + /// + /// + /// + public static VibratoType getVibratoTypeFromIconID( string icon_id ) { + switch ( icon_id ) { + case "$04040001": + return VibratoType.NormalType1; + case "$04040002": + return VibratoType.NormalType2; + case "$04040003": + return VibratoType.NormalType3; + case "$0400004": + return VibratoType.NormalType4; + case "$04040005": + return VibratoType.ExtremeType1; + case "$04040006": + return VibratoType.ExtremeType2; + case "$04040007": + return VibratoType.ExtremeType3; + case "$04040008": + return VibratoType.ExtremeType4; + case "$04040009": + return VibratoType.FastType1; + case "$0404000a": + return VibratoType.FastType2; + case "$0404000b": + return VibratoType.FastType3; + case "$0404000c": + return VibratoType.FastType4; + case "$0404000d": + return VibratoType.SlightType1; + case "$0404000e": + return VibratoType.SlightType2; + case "$0404000f": + return VibratoType.SlightType3; + case "$04040010": + return VibratoType.SlightType4; + } + return VibratoType.NormalType1; + } + + /// + /// 指定されたVibratoTypeを表すIconIDを取得します + /// + /// + /// + public static string getIconIDFromVibratoType( VibratoType type ) { + switch ( type ) { + case VibratoType.NormalType1: + return "$04040001"; + case VibratoType.NormalType2: + return "$04040002"; + case VibratoType.NormalType3: + return "$04040003"; + case VibratoType.NormalType4: + return "$0400004"; + case VibratoType.ExtremeType1: + return "$04040005"; + case VibratoType.ExtremeType2: + return "$04040006"; + case VibratoType.ExtremeType3: + return "$04040007"; + case VibratoType.ExtremeType4: + return "$04040008"; + case VibratoType.FastType1: + return "$04040009"; + case VibratoType.FastType2: + return "$0404000a"; + case VibratoType.FastType3: + return "$0404000b"; + case VibratoType.FastType4: + return "$0404000c"; + case VibratoType.SlightType1: + return "$0404000d"; + case VibratoType.SlightType2: + return "$0404000e"; + case VibratoType.SlightType3: + return "$0404000f"; + case VibratoType.SlightType4: + return "$04040010"; + } + return ""; + } + + /// + /// ビブラートのプリセットタイプから,VibratoHandleを作成します + /// + /// + /// + /// + public static VibratoHandle getDefaultVibratoHandle( VibratoType type, int vibrato_clocks ) { + VibratoHandle res = new VibratoHandle(); + res.Length = vibrato_clocks; + res.Original = 1; + //res.DepthBPNum = 0; + //res.RateBPNum = 0; + res.Caption = ToString( type ); + res.IconID = getIconIDFromVibratoType( type ); + switch ( type ) { + case VibratoType.NormalType1: + res.IDS = "normal"; + res.StartDepth = 64; + res.StartRate = 50; + break; + case VibratoType.NormalType2: + res.IDS = "normal"; + res.StartDepth = 40; + res.StartRate = 40; + break; + case VibratoType.NormalType3: + res.IDS = "normal"; + res.StartDepth = 127; + res.StartRate = 50; + break; + case VibratoType.NormalType4: + res.IDS = "normal"; + res.StartDepth = 64; + //res.DepthBPNum = 57; + res.DepthBP = new VibratoBPList( new float[57] { 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + res.StartRate = 50; + //res.RateBPNum = 52; + res.RateBP = new VibratoBPList( new float[52] { 0.600000f, 0.612500f, 0.616400f, 0.621100f, 0.628900f, 0.633600f, 0.637500f, 0.641400f, 0.653900f, 0.658600f, 0.662500f, 0.666400f, 0.675000f, 0.683600f, 0.687500f, 0.691400f, 0.700000f, 0.703900f, 0.708600f, 0.712500f, 0.725000f, 0.728900f, 0.732800f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.771100f, 0.775000f, 0.778900f, 0.783600f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.816400f, 0.821100f, 0.828900f, 0.833600f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.866400f, 0.871100f, 0.875000f, 0.878900f, 0.887500f, 0.891400f, 0.900000f, 1.000000f }, + new int[52] { 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + break; + case VibratoType.ExtremeType1: + res.IDS = "extreme"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case VibratoType.ExtremeType2: + res.IDS = "extreme"; + res.StartDepth = 32; + res.StartRate = 32; + break; + case VibratoType.ExtremeType3: + res.IDS = "extreme"; + res.StartDepth = 100; + res.StartRate = 50; + break; + case VibratoType.ExtremeType4: + res.IDS = "extreme"; + res.StartDepth = 64; + //res.DepthBPNum = 57; + res.DepthBP = new VibratoBPList( new float[57] { 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + res.StartRate = 64; + //res.RateBPNum = 57; + res.RateBP = new VibratoBPList( new float[57] { 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + break; + case VibratoType.FastType1: + res.IDS = "fast"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case VibratoType.FastType2: + res.IDS = "fast"; + res.StartDepth = 40; + res.StartRate = 50; + break; + case VibratoType.FastType3: + res.IDS = "fast"; + res.StartDepth = 80; + res.StartRate = 70; + break; + case VibratoType.FastType4: + res.IDS = "fast"; + res.StartDepth = 64; + //res.DepthBPNum = 57; + res.DepthBP = new VibratoBPList( new float[57] { 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + res.StartRate = 64; + //res.RateBPNum = 57; + res.RateBP = new VibratoBPList( new float[57] { 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + break; + case VibratoType.SlightType1: + res.IDS = "slight"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case VibratoType.SlightType2: + res.IDS = "slight"; + res.StartDepth = 40; + res.StartRate = 64; + break; + case VibratoType.SlightType3: + res.IDS = "slight"; + res.StartDepth = 72; + res.StartRate = 64; + break; + case VibratoType.SlightType4: + res.IDS = "slight"; + res.StartDepth = 64; + //res.DepthBPNum = 57; + res.DepthBP = new VibratoBPList( new float[57] { 0.604300f, 0.612500f, 0.616800f, 0.620700f, 0.625000f, 0.633200f, 0.637500f, 0.641800f, 0.645700f, 0.654300f, 0.658200f, 0.666800f, 0.670700f, 0.675000f, 0.679300f, 0.683200f, 0.691800f, 0.695700f, 0.704300f, 0.708200f, 0.712500f, 0.716800f, 0.720700f, 0.725000f, 0.729300f, 0.737500f, 0.745700f, 0.750000f, 0.758200f, 0.762500f, 0.766800f, 0.770700f, 0.775000f, 0.783200f, 0.791800f, 0.795700f, 0.800000f, 0.804300f, 0.808200f, 0.812500f, 0.820700f, 0.829300f, 0.837500f, 0.841800f, 0.845700f, 0.850000f, 0.854300f, 0.862500f, 0.866800f, 0.875000f, 0.879300f, 0.883200f, 0.887500f, 0.891800f, 0.895700f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + res.StartRate = 64; + //res.RateBPNum = 57; + res.RateBP = new VibratoBPList( new float[57] { 0.604300f, 0.612500f, 0.616800f, 0.620700f, 0.625000f, 0.633200f, 0.637500f, 0.641800f, 0.645700f, 0.654300f, 0.658200f, 0.666800f, 0.670700f, 0.675000f, 0.679300f, 0.683200f, 0.691800f, 0.695700f, 0.704300f, 0.708200f, 0.712500f, 0.716800f, 0.720700f, 0.725000f, 0.729300f, 0.737500f, 0.745700f, 0.750000f, 0.758200f, 0.762500f, 0.766800f, 0.770700f, 0.775000f, 0.783200f, 0.791800f, 0.795700f, 0.800000f, 0.804300f, 0.808200f, 0.812500f, 0.820700f, 0.829300f, 0.837500f, 0.841800f, 0.845700f, 0.850000f, 0.854300f, 0.862500f, 0.866800f, 0.875000f, 0.879300f, 0.883200f, 0.887500f, 0.891800f, 0.895700f, 0.900000f, 1.000000f }, + new int[57] { 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 } ); + break; + } + return res; + } + + /// + /// 指定されたVibratoTypeを文字列に変換します + /// + /// + /// + /// + /// string str = VibratoTypeUtil.ToString( VibratoType.NormalType1 ); + /// // str = "[Normal] Type 1" + /// + /// + /// + public static string ToString( VibratoType value ) { + switch ( value ) { + case VibratoType.NormalType1: + return "[Normal] Type 1"; + case VibratoType.NormalType2: + return "[Normal] Type 2"; + case VibratoType.NormalType3: + return "[Normal] Type 3"; + case VibratoType.NormalType4: + return "[Normal] Type 4"; + case VibratoType.ExtremeType1: + return "[Extreme] Type 1"; + case VibratoType.ExtremeType2: + return "[Extreme] Type 2"; + case VibratoType.ExtremeType3: + return "[Extreme] Type 3"; + case VibratoType.ExtremeType4: + return "[Extreme] Type 4"; + case VibratoType.FastType1: + return "[Fast] Type 1"; + case VibratoType.FastType2: + return "[Fast] Type 2"; + case VibratoType.FastType3: + return "[Fast] Type 3"; + case VibratoType.FastType4: + return "[Fast] Type 4"; + case VibratoType.SlightType1: + return "[Slight] Type 1"; + case VibratoType.SlightType2: + return "[Slight] Type 2"; + case VibratoType.SlightType3: + return "[Slight] Type 3"; + case VibratoType.SlightType4: + return "[Slight] Type 4"; + } + return ""; + } + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/VsqBPList.cs b/trunk/Boare.Lib.Vsq/VsqBPList.cs new file mode 100644 index 0000000..ee1127b --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqBPList.cs @@ -0,0 +1,228 @@ +/* + * VsqBPList.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// BPListのデータ部分を取り扱うためのクラス。 + /// + [Serializable] + public class VsqBPList : ICloneable { + private SortedList m_list = new SortedList(); + private int m_default = 0; + private int m_maximum = 127; + private int m_minimum = 0; + + private class KeyClockIterator : Iterator { + private SortedList m_list; + private int m_pos; + + public KeyClockIterator( SortedList list ) { + m_list = list; + m_pos = -1; + } + + public bool hasNext() { + if ( m_pos + 1 < m_list.Keys.Count ) { + return true; + } else { + return false; + } + } + + public object next() { + m_pos++; + return m_list.Keys[m_pos]; + } + + public void remove() { + if ( 0 <= m_pos && m_pos < m_list.Keys.Count ) { + int key = m_list.Keys[m_pos]; + m_list.Remove( key ); + } + } + } + + /// + /// このVsqBPListの同一コピーを作成します + /// + /// + public object Clone() { + VsqBPList res = new VsqBPList( m_default, m_minimum, m_maximum ); + foreach ( int key in m_list.Keys ) { + res.m_list.Add( key, m_list[key] ); + } + return res; + } + + /// + /// コンストラクタ。デフォルト値はココで指定する。 + /// + /// + public VsqBPList( int default_value, int minimum, int maximum ) { + m_default = default_value; + m_maximum = maximum; + m_minimum = minimum; + } + + /// + /// このリストに設定された最大値を取得します。 + /// + public int getMaximum() { + return m_maximum; + } + + /// + /// このリストに設定された最小値を取得します + /// + public int getMinimum() { + return m_minimum; + } + + public Iterator keyClockIterator() { + return new KeyClockIterator( m_list ); + } + + public void remove( int clock ) { + if ( m_list.ContainsKey( clock ) ) { + m_list.Remove( clock ); + } + } + + public bool isContainsKey( int clock ) { + return m_list.ContainsKey( clock ); + } + + public int getCount() { + return m_list.Count; + } + + public int[] getKeys() { + List t = new List( m_list.Keys ); + return t.ToArray(); + } + + public void clear() { + m_list.Clear(); + } + + /// + /// 新しいデータ点を追加します。 + /// + /// + /// + public void add( int clock, int value ) { + lock ( m_list ) { + if ( m_list.ContainsKey( clock ) ) { + m_list[clock] = value; + } else { + m_list.Add( clock, value ); + } + } + } + + public int getElement( int clock ) { + if ( m_list.Count == 0 ) { + return getDefault(); + } else { + if ( m_list.ContainsKey( clock ) ) { + return m_list[clock]; + } else { + int index = 0; + int prev = 0; + foreach ( int key in m_list.Keys ) { + if ( clock < key ) { + index = prev; + break; + } + prev = key; + } + if ( m_list.ContainsKey( index ) ) { + return m_list[index]; + } else { + return m_default; + } + } + } + } + + /// + /// このBPListのデフォルト値を取得します + /// + public int getDefault() { + return m_default; + } + + /// + /// このBPListの内容をテキストファイルに書き出します + /// + /// + public void print( StreamWriter writer ) { + bool first = true; + foreach ( int key in m_list.Keys ) { + int val = m_list[key]; + if ( first ) { + writer.WriteLine( key + "=" + val ); + first = false; + } else { + writer.WriteLine( key + "=" + val ); + } + } + } + + /// + /// このBPListの内容をテキストファイルに書き出します + /// + /// + public void print( TextMemoryStream writer, int start, string header ) { + bool first = true; + foreach ( int key in m_list.Keys ) { + if ( start <= key ) { + if ( first ) { + writer.writeLine( header ); + first = false; + } + int val = m_list[key]; + writer.writeLine( key + "=" + val ); + } + } + } + + /// + /// テキストファイルからデータ点を読込み、現在のリストに追加します + /// + /// + /// + public string appendFromText( TextMemoryStream reader ) { + string last_line = reader.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + string[] spl = last_line.Split( new char[] { '=' } ); + int i1 = int.Parse( spl[0] ); + int i2 = int.Parse( spl[1] ); + m_list.Add( i1, i2 ); + if ( reader.peek() < 0 ) { + break; + } else { + last_line = reader.readLine(); + } + } + return last_line; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqBarLineType.cs b/trunk/Boare.Lib.Vsq/VsqBarLineType.cs new file mode 100644 index 0000000..a4518f8 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqBarLineType.cs @@ -0,0 +1,54 @@ +/* + * VsqBarLineType.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + public struct VsqBarLineType { + private int m_clock; + private bool m_is_separator; + private int m_denominator; + private int m_numerator; + private int m_bar_count; + + public int getBarCount() { + return m_bar_count; + } + + public int getLocalDenominator() { + return m_denominator; + } + + public int getLocalNumerator() { + return m_numerator; + } + + public int clock() { + return m_clock; + } + + public bool isSeparator() { + return m_is_separator; + } + + public VsqBarLineType( int clock, bool is_separator, int denominator, int numerator, int bar_count ) { + m_clock = clock; + m_is_separator = is_separator; + m_denominator = denominator; + m_numerator = numerator; + m_bar_count = bar_count; + } + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/VsqCommand.cs b/trunk/Boare.Lib.Vsq/VsqCommand.cs new file mode 100644 index 0000000..12b406a --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqCommand.cs @@ -0,0 +1,498 @@ +/* + * VsqCommand.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.VECapture is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + /// + /// + /// + [Serializable] + public class VsqCommand { + public VsqCommandType Type; + /// + /// コマンドの処理内容を保持します。Args具体的な内容は、処理するクラスごとに異なります + /// + public object[] Args; + /// + /// 後続するコマンド + /// + public List Children = new List(); + /// + /// このコマンドの親 + /// + public VsqCommand Parent = null; + + /// + /// VsqCommandはgenerateCommand*からコンストラクトしなければならない。 + /// なので、無引数のコンストラクタを隠蔽するためのもの。 + /// + internal VsqCommand() { + } + + public static VsqCommand generateCommandTrackChangeRenderer( int track, string renderer ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackChangeRenderer; + command.Args = new object[2]; + command.Args[0] = track; + command.Args[1] = renderer; + return command; + } + + public static VsqCommand generateCommandRoot() { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.Root; + command.Args = null; + return command; + } + + public static VsqCommand generateCommandReplace( VsqFile vsq ) { + VsqCommand command = new VsqCommand(); + command.Args = new object[1]; + command.Type = VsqCommandType.Replace; + command.Args[0] = (VsqFile)vsq.Clone(); + return command; + } + + public static VsqCommand generateCommandTrackReplace( int track, VsqTrack item ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackReplace; + command.Args = new object[2]; + command.Args[0] = track; + command.Args[1] = (VsqTrack)item.Clone(); + return command; + } + + public static VsqCommand generateCommandUpdateTimesig( int bar_count, int new_barcount, int numerator, int denominator ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTimesig; + command.Args = new object[4]; + command.Args[0] = bar_count; + command.Args[1] = numerator; + command.Args[2] = denominator; + command.Args[3] = new_barcount; + return command; + } + + public static VsqCommand generateCommandUpdateTimesigRange( int[] bar_counts, int[] new_barcounts, int[] numerators, int[] denominators ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTimesigRange; + command.Args = new object[4]; + command.Args[0] = (int[])bar_counts.Clone(); + command.Args[1] = (int[])numerators.Clone(); + command.Args[2] = (int[])denominators.Clone(); + command.Args[3] = (int[])new_barcounts.Clone(); + return command; + } + + public static VsqCommand generateCommandUpdateTempoRange( int[] clocks, int[] new_clocks, int[] tempos ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTempoRange; + command.Args = new object[3]; + command.Args[0] = (int[])clocks.Clone(); + command.Args[1] = (int[])tempos.Clone(); + command.Args[2] = (int[])new_clocks.Clone(); + return command; + } + + public static VsqCommand generateCommandUpdateTempo( int clock, int new_clock, int tempo ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTempo; + command.Args = new object[3]; + command.Args[0] = clock; + command.Args[1] = tempo; + command.Args[2] = new_clock; + return command; + } + + public static VsqCommand generateCommandChangePreMeasure( int pre_measure ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.ChangePreMeasure; + command.Args = new object[1]; + command.Args[0] = pre_measure; + return command; + } + + public static VsqCommand generateCommandDeleteTrack( int track ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.DeleteTrack; + command.Args = new object[1]; + command.Args[0] = track; + return command; + } + + /// + /// トラックを追加するコマンドを発行します.trackはClone()して渡さなくてもよい + /// + /// + /// + public static VsqCommand generateCommandAddTrack( VsqTrack track, VsqMixerEntry mixer, int position ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.AddTrack; + command.Args = new object[5]; + command.Args[0] = track; + command.Args[1] = mixer; + command.Args[2] = position; + return command; + } + + /// + /// トラック名を変更するコマンドを作成します + /// + /// + /// + /// + public static VsqCommand generateCommandTrackChangeName( int track, string new_name ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackChangeName; + command.Args = new object[2]; + command.Args[0] = track; + command.Args[1] = new_name; + return command; + } + + /// + /// VsqIDとClockを同時に変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeClockAndIDContaintsRange( int track, int[] internal_ids, int[] clocks, VsqID[] values ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndIDContaintsRange; + int count = internal_ids.Length; + command.Args = new object[4]; + command.Args[0] = track; + command.Args[1] = (int[])internal_ids.Clone(); + command.Args[2] = (int[])clocks.Clone(); + command.Args[3] = (VsqID[])values.Clone(); + return command; + } + + /// + /// VsqIDとClockを同時に変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeClockAndIDContaints( int track, int internal_id, int clock, VsqID value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndIDContaints; + command.Args = new object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = clock; + command.Args[3] = (VsqID)value.Clone(); + return command; + } + + /// + /// VsqIDの内容を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeIDContaintsRange( int track, int[] internal_ids, VsqID[] values ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeIDContaintsRange; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = (int[])internal_ids.Clone(); + VsqID[] list = new VsqID[values.Length]; + for ( int i = 0; i < values.Length; i++ ) { + list[i] = (VsqID)values[i].Clone(); + } + command.Args[2] = list; + return command; + } + + /// + /// VsqIDの内容を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeIDContaints( int track, int internal_id, VsqID value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeIDContaints; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = (VsqID)value.Clone(); + return command; + } + + /// + /// ノートの長さを変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeClockAndLength( int track, int internal_id, int new_clock, int new_length ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndLength; + command.Args = new object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = new_clock; + command.Args[3] = new_length; + return command; + } + + /// + /// ノートの長さを変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeLength( int track, int internal_id, int new_length ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeLength; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = new_length; + return command; + } + + /// + /// 指定したトラックの,音符のベロシティ(VEL)を変更するコマンドを発行します. + /// リストvelocityには,音符を指定するInteralIDと,変更したいベロシティの値のペアを登録します + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeVelocity( int track, List> velocity ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeVelocity; + command.Args = new object[2]; + command.Args[0] = track; + List> list = new List>(); + foreach ( KeyValuePair item in velocity ) { + list.Add( new KeyValuePair( item.Key, item.Value ) ); + } + command.Args[1] = list; + return command; + } + + /// + /// 指定したトラックの、音符のアクセント(Accent)を変更するコマンドを発行します。 + /// リストaccent_listには、音符を指定するInternalIDと、変更したいアクセント値のペアを登録します + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeAccent( int track, List> accent_list ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeAccent; + command.Args = new object[2]; + command.Args[0] = track; + List> list = new List>(); + foreach ( KeyValuePair item in accent_list ) { + list.Add( new KeyValuePair( item.Key, item.Value ) ); + } + command.Args[1] = list; + return command; + } + + /// + /// 指定したトラックの、音符のディケイ(Decay)を変更するコマンドを発行します。 + /// リストdecay_listには、音符を指定するInternalIDと、変更したいディケイ値のペアを登録します + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeDecay( int track, List> decay_list ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeDecay; + command.Args = new object[2]; + command.Args[0] = track; + List> list = new List>(); + foreach ( KeyValuePair item in decay_list ) { + list.Add( new KeyValuePair( item.Key, item.Value ) ); + } + command.Args[1] = list; + return command; + } + + /// + /// vsqファイルのカーブを編集するコマンドを発行します. + /// + /// + /// + /// + /// + public static VsqCommand generateCommandTrackEditCurve( int track, string target, List edit ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackEditCurve; + command.Args = new object[5]; + command.Args[0] = track; + command.Args[1] = target; + List copied = new List(); + foreach ( BPPair item in edit ) { + copied.Add( item ); + } + command.Args[2] = copied; + return command; + } + + public static VsqCommand generateCommandTrackEditCurveRange( int track, string[] targets, List[] edits ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackEditCurveRange; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = (string[])targets.Clone(); + List[] cpy = new List[targets.Length]; + for ( int i = 0; i < edits.Length; i++ ) { + List copied = new List(); + foreach ( BPPair item in edits[i] ) { + copied.Add( new BPPair( item.Clock, item.Value ) ); + } + cpy[i] = copied; + } + command.Args[2] = cpy; + return command; + } + + /// + /// 特定位置のイベントの歌詞と発音記号を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeLyric( int track, int internal_id, string phrase, string phonetic_symbol, bool protect_symbol ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeLyric; + command.Args = new object[5]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = phrase; + command.Args[3] = phonetic_symbol; + command.Args[4] = protect_symbol; + return command; + } + + /// + /// ノートのクロック位置を変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeClock( int track, int internal_id, int value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClock; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = value; + return command; + } + + public static VsqCommand generateCommandEventDeleteRange( int track, int[] internal_ids ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventDeleteRange; + command.Args = new object[2]; + command.Args[0] = (int[])internal_ids.Clone(); + command.Args[1] = track; + return command; + } + + /// + /// ノートを削除するコマンドを発行します + /// + /// + /// + public static VsqCommand generateCommandEventDelete( int track, int internal_id ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventDelete; + command.Args = new object[2]; + command.Args[1] = track; + command.Args[0] = internal_id; + return command; + } + + public static VsqCommand generateCommandEventAddRange( int track, VsqEvent[] items ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventAddRange; + command.Args = new object[2]; + command.Args[0] = track; + command.Args[1] = (VsqEvent[])items.Clone(); + return command; + } + + /// + /// ノートを追加するコマンドを発行します。 + /// + /// + /// + /// + public static VsqCommand generateCommandEventAdd( int track, VsqEvent item ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventAdd; + command.Args = new object[2]; + command.Args[0] = track; + command.Args[1] = (VsqEvent)item.Clone(); + return command; + } + + /// + /// ノートの音程を変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeNote( int track, int internal_id, int note ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeNote; + command.Args = new object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = note; + return command; + } + + /// + /// ノートの音程とクロックを変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand generateCommandEventChangeClockAndNote( int track, int internal_id, int clock, int note ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndNote; + command.Args = new object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = clock; + command.Args[3] = note; + return command; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqCommandType.cs b/trunk/Boare.Lib.Vsq/VsqCommandType.cs new file mode 100644 index 0000000..97b3789 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqCommandType.cs @@ -0,0 +1,50 @@ +/* + * VsqCommandType.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Boare.Lib.Vsq { + + public enum VsqCommandType { + Root, + ChangePreMeasure, + EventAdd, + EventDelete, + EventChangeClock, + EventChangeLyric, + EventChangeNote, + EventChangeClockAndNote, + TrackEditCurve, + TrackEditCurveRange, + EventChangeVelocity, + EventChangeAccent, + EventChangeDecay, + EventChangeLength, + EventChangeClockAndLength, + EventChangeIDContaints, + EventChangeClockAndIDContaints, + TrackChangeName, + AddTrack, + DeleteTrack, + EventChangeClockAndIDContaintsRange, + EventDeleteRange, + EventAddRange, + UpdateTempo, + UpdateTempoRange, + UpdateTimesig, + UpdateTimesigRange, + EventChangeIDContaintsRange, + TrackReplace, + Replace, + TrackChangeRenderer, + } + +} \ No newline at end of file diff --git a/trunk/Boare.Lib.Vsq/VsqEvent.cs b/trunk/Boare.Lib.Vsq/VsqEvent.cs new file mode 100644 index 0000000..fa53f10 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqEvent.cs @@ -0,0 +1,70 @@ +/* + * VsqEvent.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + /// + /// vsqファイルのメタテキスト内に記述されるイベント。 + /// + [Serializable] + public class VsqEvent : IComparable, ICloneable { + public object Tag; + /// + /// 内部で使用するインスタンス固有のID + /// + public int InternalID; + public int Clock; + public VsqID ID; + + /// + /// このオブジェクトのコピーを作成します + /// + /// + public object Clone() { + VsqEvent ret = new VsqEvent( Clock, ID ); + ret.InternalID = InternalID; + return ret; + } + + public int CompareTo( VsqEvent item ) { + int ret = this.Clock - item.Clock; + if ( ret == 0 ) { + if ( this.ID != null && item.ID != null ) { + return (int)this.ID.type - (int)item.ID.type; + } else { + return ret; + } + } else { + return ret; + } + } + + public VsqEvent( string line ) { + string[] spl = line.Split( new char[] { '=' } ); + Clock = int.Parse( spl[0] ); + if ( spl[1] == "EOS" ) { + ID = VsqID.EOS; + } + } + + public VsqEvent( int clock, VsqID id /*, int internal_id*/ ) { + Clock = clock; + ID = (VsqID)id.Clone(); + //InternalID = internal_id; + InternalID = 0; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqEventList.cs b/trunk/Boare.Lib.Vsq/VsqEventList.cs new file mode 100644 index 0000000..5cfe739 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqEventList.cs @@ -0,0 +1,90 @@ +/* + * VsqEventList.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + /// + /// 固有ID付きのVsqEventのリストを取り扱う + /// + [Serializable] + public class VsqEventList { + private List m_list; + private List m_ids; + + /// + /// コンストラクタ + /// + public VsqEventList() { + m_list = new List(); + m_ids = new List(); + } + + public void clear() { + m_list.Clear(); + m_ids.Clear(); + } + + public Iterator iterator() { + return new ListIterator( m_list ); + } + + public void add( VsqEvent item ) { + int new_id = getNextId( 0 ); + item.InternalID = new_id; + m_list.Add( item ); + m_ids.Add( new_id ); + m_list.Sort(); + for ( int i = 0; i < m_list.Count; i++ ) { + m_ids[i] = m_list[i].InternalID; + } + } + + public void removeAt( int index ) { + m_list.RemoveAt( index ); + m_ids.RemoveAt( index ); + } + + private int getNextId( int next ) { + int index = -1; + List current = new List( m_ids ); + int nfound = 0; + while ( true ) { + index++; + if ( !current.Contains( index ) ) { + nfound++; + if ( nfound == next + 1 ) { + return index; + } else { + current.Add( index ); + } + } + } + } + + public int getCount() { + return m_list.Count; + } + + public VsqEvent getElement( int index ) { + return m_list[index]; + } + + public void setElement( int index, VsqEvent value ) { + m_list[index] = value; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqFile.cs b/trunk/Boare.Lib.Vsq/VsqFile.cs new file mode 100644 index 0000000..fa12ec6 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqFile.cs @@ -0,0 +1,2459 @@ +/* + * VsqFile.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// VSQファイルの内容を保持するクラス + /// + [Serializable] + public class VsqFile : ICloneable { + /// + /// トラックのリスト.最初のトラックはMasterTrackであり,通常の音符が格納されるトラックはインデックス1以降となる + /// + protected List m_tracks; + /// + /// テンポ情報を保持したテーブル + /// + protected List m_tempo_table; + protected List m_timesig_table; + protected int m_tpq; + /// + /// 曲の長さを取得します。(クロック(4分音符は480クロック)) + /// + public int TotalClocks = 0; + protected int m_base_tempo; + public VsqMaster Master; // VsqMaster, VsqMixerは通常,最初の非Master Trackに記述されるが,可搬性のため, + public VsqMixer Mixer; // ここではVsqFileに直属するものとして取り扱う. + protected int m_premeasure_clocks; + public object Tag; + + static readonly byte[] _MTRK = new byte[] { 0x4d, 0x54, 0x72, 0x6b }; + static readonly byte[] _MTHD = new byte[] { 0x4d, 0x54, 0x68, 0x64 }; + static readonly byte[] _MASTER_TRACK = new byte[] { 0x4D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, 0x63, 0x6B, }; + static readonly string[] _CURVES = new string[] { "VEL", "DYN", "BRE", "BRI", "CLE", "OPE", "GEN", "POR", "PIT", "PBS" }; + + /// + /// このインスタンスに編集を行うコマンドを実行します + /// + /// 実行するコマンド + /// 編集結果を元に戻すためのコマンドを返します + public VsqCommand executeCommand( VsqCommand command ) { +#if DEBUG + Console.WriteLine( "VsqFile.Execute(VsqCommand)" ); + Console.WriteLine( " type=" + command.Type ); +#endif + VsqCommandType type = command.Type; + if ( type == VsqCommandType.ChangePreMeasure ) { + #region ChangePreMeasure + VsqCommand ret = VsqCommand.generateCommandChangePreMeasure( Master.PreMeasure ); + int value = (int)command.Args[0]; + Master.PreMeasure = value; + updateTimesigInfo(); + return ret; + #endregion + } else if ( type == VsqCommandType.AddTrack ) { + #region AddTrack +#if DEBUG + System.Diagnostics.Debug.WriteLine( " AddTrack" ); +#endif + VsqTrack track = (VsqTrack)command.Args[0]; + VsqMixerEntry mixer = (VsqMixerEntry)command.Args[1]; + int position = (int)command.Args[2]; + VsqCommand ret = VsqCommand.generateCommandDeleteTrack( position ); + if ( m_tracks.Count <= 17 ) { + m_tracks.Insert( position, (VsqTrack)track.Clone() ); + Mixer.Slave.Add( (VsqMixerEntry)mixer.Clone() ); + return ret; + } else { + return null; + } + #endregion + } else if ( type == VsqCommandType.DeleteTrack ) { + #region DeleteTrack + int track = (int)command.Args[0]; + VsqCommand ret = VsqCommand.generateCommandAddTrack( m_tracks[track], Mixer.Slave[track - 1], track ); + m_tracks.RemoveAt( track ); + Mixer.Slave.RemoveAt( track - 1 ); + updateTotalClocks(); + return ret; + #endregion + } else if ( type == VsqCommandType.UpdateTempo ) { + #region UpdateTempo + int clock = (int)command.Args[0]; + int tempo = (int)command.Args[1]; + int new_clock = (int)command.Args[2]; + + int index = -1; + for ( int i = 0; i < getTempoList().Count; i++ ) { + if ( getTempoList()[i].Clock == clock ) { + index = i; + break; + } + } + VsqCommand ret = null; + if ( index >= 0 ) { + if ( tempo <= 0 ) { + ret = VsqCommand.generateCommandUpdateTempo( clock, clock, getTempoList()[index].Tempo ); + getTempoList().RemoveAt( index ); + } else { + ret = VsqCommand.generateCommandUpdateTempo( new_clock, clock, getTempoList()[index].Tempo ); + getTempoList()[index].Tempo= tempo ; + getTempoList()[index].Clock= new_clock ; + } + } else { + ret = VsqCommand.generateCommandUpdateTempo( clock, clock, -1 ); + getTempoList().Add( new TempoTableEntry( new_clock, tempo, 0.0 ) ); + } + updateTempoInfo(); + updateTotalClocks(); + + // 編集領域を更新 + int affected_clock = Math.Min( clock, new_clock ); + for ( int i = 1; i < m_tracks.Count; i++ ) { + if ( affected_clock < m_tracks[i].getEditedStart() ) { + m_tracks[i].setEditedStart( affected_clock ); + } + m_tracks[i].setEditedEnd( (int)TotalClocks ); + } + return ret; + #endregion + } else if ( type == VsqCommandType.UpdateTempoRange ) { + #region UpdateTempoRange + int[] clocks = (int[])command.Args[0]; + int[] tempos = (int[])command.Args[1]; + int[] new_clocks = (int[])command.Args[2]; + int[] new_tempos = new int[tempos.Length]; + int affected_clock = int.MaxValue; + for ( int i = 0; i < clocks.Length; i++ ) { + int index = -1; + affected_clock = Math.Min( affected_clock, clocks[i] ); + affected_clock = Math.Min( affected_clock, new_clocks[i] ); + for ( int j = 0; j < getTempoList().Count; j++ ) { + if ( getTempoList()[j].Clock == clocks[i] ) { + index = j; + break; + } + } + if ( index >= 0 ) { + new_tempos[i] = getTempoList()[index].Tempo; + if ( tempos[i] <= 0 ) { + getTempoList().RemoveAt( index ); + } else { + getTempoList()[index].Tempo = tempos[i]; + getTempoList()[index].Clock = new_clocks[i]; + } + } else { + new_tempos[i] = -1; + getTempoList().Add( new TempoTableEntry( new_clocks[i], tempos[i], 0.0 ) ); + } + } + updateTempoInfo(); + updateTotalClocks(); + for ( int i = 1; i < m_tracks.Count; i++ ) { + if ( affected_clock < m_tracks[i].getEditedStart() ) { + m_tracks[i].setEditedStart( affected_clock ); + } + m_tracks[i].setEditedEnd( (int)TotalClocks ); + } + return VsqCommand.generateCommandUpdateTempoRange( new_clocks, clocks, new_tempos ); + #endregion + } else if ( type == VsqCommandType.UpdateTimesig ) { + #region UpdateTimesig + int barcount = (int)command.Args[0]; + int numerator = (int)command.Args[1]; + int denominator = (int)command.Args[2]; + int new_barcount = (int)command.Args[3]; + int index = -1; + for ( int i = 0; i < getTimeSigList().Count; i++ ) { + if ( barcount == getTimeSigList()[i].BarCount ) { + index = i; + break; + } + } + VsqCommand ret = null; + if ( index >= 0 ) { + if ( numerator <= 0 ) { + ret = VsqCommand.generateCommandUpdateTimesig( barcount, barcount, getTimeSigList()[index].Numerator, getTimeSigList()[index].Denominator ); + getTimeSigList().RemoveAt( index ); + } else { + ret = VsqCommand.generateCommandUpdateTimesig( new_barcount, barcount, getTimeSigList()[index].Numerator, getTimeSigList()[index].Denominator ); + getTimeSigList()[index].BarCount = new_barcount; + getTimeSigList()[index].Numerator = numerator; + getTimeSigList()[index].Denominator = denominator; + } + } else { + ret = VsqCommand.generateCommandUpdateTimesig( new_barcount, new_barcount, -1, -1 ); + getTimeSigList().Add( new TimeSigTableEntry( 0, numerator, denominator, new_barcount ) ); + } + updateTimesigInfo(); + updateTotalClocks(); + return ret; + #endregion + } else if ( type == VsqCommandType.UpdateTimesigRange ) { + #region UpdateTimesigRange + int[] barcounts = (int[])command.Args[0]; + int[] numerators = (int[])command.Args[1]; + int[] denominators = (int[])command.Args[2]; + int[] new_barcounts = (int[])command.Args[3]; + int[] new_numerators = new int[numerators.Length]; + int[] new_denominators = new int[denominators.Length]; + for ( int i = 0; i < barcounts.Length; i++ ) { + int index = -1; + for ( int j = 0; j < getTimeSigList().Count; j++ ) { + if ( getTimeSigList()[j].BarCount == barcounts[i] ) { + index = j; + break; + } + } + if ( index >= 0 ) { + new_numerators[i] = getTimeSigList()[index].Numerator; + new_denominators[i] = getTimeSigList()[index].Denominator; + if ( numerators[i] <= 0 ) { + getTimeSigList().RemoveAt( index ); + } else { + getTimeSigList()[index].BarCount = new_barcounts[i]; + getTimeSigList()[index].Numerator = numerators[i]; + getTimeSigList()[index].Denominator = denominators[i]; + } + } else { + new_numerators[i] = -1; + new_denominators[i] = -1; + getTimeSigList().Add( new TimeSigTableEntry( 0, numerators[i], denominators[i], new_barcounts[i] ) ); + } + } + updateTimesigInfo(); + updateTotalClocks(); + return VsqCommand.generateCommandUpdateTimesigRange( new_barcounts, barcounts, new_numerators, new_denominators ); + #endregion + } else if ( type == VsqCommandType.Replace ) { + #region Replace + VsqFile vsq = (VsqFile)command.Args[0]; + VsqFile inv = (VsqFile)this.Clone(); + m_tracks.Clear(); + for ( int i = 0; i < vsq.m_tracks.Count; i++ ) { + m_tracks.Add( (VsqTrack)vsq.m_tracks[i].Clone() ); + } + m_tempo_table.Clear(); + for ( int i = 0; i < vsq.m_tempo_table.Count; i++ ) { + m_tempo_table.Add( (TempoTableEntry)vsq.m_tempo_table[i].Clone() ); + } + m_timesig_table.Clear(); + for ( int i = 0; i < vsq.m_timesig_table.Count; i++ ) { + m_timesig_table.Add( (TimeSigTableEntry)vsq.m_timesig_table[i].Clone() ); + } + m_tpq = vsq.m_tpq; + TotalClocks = vsq.TotalClocks; + m_base_tempo = vsq.m_base_tempo; + Master = (VsqMaster)vsq.Master.Clone(); + Mixer = (VsqMixer)vsq.Mixer.Clone(); + m_premeasure_clocks = vsq.m_premeasure_clocks; + updateTotalClocks(); + return VsqCommand.generateCommandReplace( inv ); + #endregion + } else if ( type == VsqCommandType.EventAdd ) { + #region TrackAddNote + int track = (int)command.Args[0]; + VsqEvent item = (VsqEvent)command.Args[1]; + //int key = this.Tracks[track].GetNextId( 0 ); + //item.InternalID = key; + m_tracks[track].addEvent( item ); + VsqCommand ret = VsqCommand.generateCommandEventDelete( track, item.InternalID ); + //this.Tracks[track].Events.Sort(); + updateTotalClocks(); + if ( item.Clock < m_tracks[track].getEditedStart() ) { + m_tracks[track].setEditedStart( item.Clock ); + } + if ( m_tracks[track].getEditedEnd() < item.Clock + item.ID.Length ) { + m_tracks[track].setEditedEnd( item.Clock + item.ID.Length ); + } + return ret; + #endregion + } else if ( type == VsqCommandType.EventAddRange ) { + #region TrackAddNoteRange +#if DEBUG + Console.WriteLine( " TrackAddNoteRange" ); +#endif + int track = (int)command.Args[0]; + VsqEvent[] items = (VsqEvent[])command.Args[1]; + List inv_ids = new List(); + int min_clock = (int)TotalClocks; + int max_clock = 0; + for ( int i = 0; i < items.Length; i++ ) { + VsqEvent item = (VsqEvent)items[i].Clone(); + min_clock = Math.Min( min_clock, item.Clock ); + max_clock = Math.Max( max_clock, item.Clock + item.ID.Length ); + //int key = Tracks[track].GetNextId( i ); + //item.InternalID = key; +#if DEBUG + Console.Write( " i=" + i + "; item.InternalID=" + item.InternalID ); +#endif + m_tracks[track].addEvent( item ); + inv_ids.Add( item.InternalID ); +#if DEBUG + Console.WriteLine( " => " + item.InternalID ); +#endif + } + //Tracks[track].Events.Sort(); + updateTotalClocks(); + if ( min_clock < m_tracks[track].getEditedStart() ) { + m_tracks[track].setEditedStart( min_clock ); + } + if ( m_tracks[track].getEditedEnd() < max_clock ) { + m_tracks[track].setEditedEnd( max_clock ); + } + return VsqCommand.generateCommandEventDeleteRange( track, inv_ids.ToArray() ); + #endregion + } else if ( type == VsqCommandType.EventDelete ) { + #region TrackDeleteNote + int internal_id = (int)command.Args[0]; + int track = (int)command.Args[1]; + VsqEvent[] original = new VsqEvent[1]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + original[0] = (VsqEvent)item.Clone(); + break; + } + } + if ( original[0].Clock < m_tracks[track].getEditedStart() ) { + m_tracks[track].setEditedStart( original[0].Clock ); + } + if ( m_tracks[track].getEditedEnd() < original[0].Clock + original[0].ID.Length ) { + m_tracks[track].setEditedEnd( original[0].Clock + original[0].ID.Length ); + } + VsqCommand ret = VsqCommand.generateCommandEventAddRange( track, original ); + for ( int i = 0; i < this.m_tracks[track].getEventCount(); i++ ) { + if ( this.m_tracks[track].getEvent( i ).InternalID == internal_id ) { + m_tracks[track].removeEvent( i ); + break; + } + } + updateTotalClocks(); + return ret; + #endregion + } else if ( type == VsqCommandType.EventDeleteRange ) { + #region TrackDeleteNoteRange + int[] internal_ids = (int[])command.Args[0]; + int track = (int)command.Args[1]; + List inv = new List(); + int min_clock = int.MaxValue; + int max_clock = int.MinValue; + for ( int j = 0; j < internal_ids.Length; j++ ) { + for ( int i = 0; i < m_tracks[track].getEventCount(); i++ ) { + if ( internal_ids[j] == m_tracks[track].getEvent( i ).InternalID ) { + inv.Add( (VsqEvent)m_tracks[track].getEvent( i ).Clone() ); + min_clock = Math.Min( min_clock, m_tracks[track].getEvent( i ).Clock ); + max_clock = Math.Max( max_clock, m_tracks[track].getEvent( i ).Clock + m_tracks[track].getEvent( i ).ID.Length ); + m_tracks[track].removeEvent( i ); + break; + } + } + } + updateTotalClocks(); + m_tracks[track].setEditedStart( min_clock ); + m_tracks[track].setEditedEnd( max_clock ); + return VsqCommand.generateCommandEventAddRange( track, inv.ToArray() ); + #endregion + } else if ( type == VsqCommandType.EventChangeClock ) { + #region TrackChangeClock + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int value = (int)command.Args[2]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeClock( track, internal_id, item.Clock ); + int min = Math.Min( item.Clock, value ); + int max = Math.Max( item.Clock + item.ID.Length, value + item.ID.Length ); + m_tracks[track].setEditedStart( min ); + m_tracks[track].setEditedEnd( max ); + item.Clock = value; + //this.Tracks[track].Events.Sort(); + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeLyric ) { + #region TrackChangeLyric + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + string phrase = (string)command.Args[2]; + string phonetic_symbol = (string)command.Args[3]; + bool protect_symbol = (bool)command.Args[4]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + if ( item.ID.type == VsqIDType.Anote ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeLyric( track, internal_id, item.ID.LyricHandle.L0.Phrase, item.ID.LyricHandle.L0.getPhoneticSymbol(), item.ID.LyricHandle.L0.PhoneticSymbolProtected ); + item.ID.LyricHandle.L0.Phrase = phrase; + item.ID.LyricHandle.L0.setPhoneticSymbol( phonetic_symbol ); + item.ID.LyricHandle.L0.PhoneticSymbolProtected = protect_symbol; + m_tracks[track].setEditedStart( item.Clock ); + m_tracks[track].setEditedEnd( item.Clock + item.ID.Length ); + updateTotalClocks(); + return ret; + } + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeNote ) { + #region TrackChangeNote + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int note = (int)command.Args[2]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeNote( track, internal_id, item.ID.Note ); + item.ID.Note = note; + updateTotalClocks(); + m_tracks[track].setEditedStart( item.Clock ); + m_tracks[track].setEditedEnd( item.Clock + item.ID.Length ); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeClockAndNote ) { + #region TrackChangeClockAndNote + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int clock = (int)command.Args[2]; + int note = (int)command.Args[3]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeClockAndNote( track, internal_id, item.Clock, item.ID.Note ); + int min = Math.Min( item.Clock, clock ); + int max = Math.Max( item.Clock + item.ID.Length, clock + item.ID.Length ); + m_tracks[track].setEditedStart( min ); + m_tracks[track].setEditedEnd( max ); + item.Clock = clock; + item.ID.Note = note; + //this.Tracks[track].Events.Sort(); + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.TrackEditCurve ) { + #region TrackEditCurve + int track = (int)command.Args[0]; + string curve = (string)command.Args[1]; + List com = (List)command.Args[2]; + + VsqCommand inv = null; + List edit = new List(); + if ( com != null ) { + if ( com.Count > 0 ) { + int start_clock = com[0].Clock; + int end_clock = com[0].Clock; + foreach ( BPPair item in com ) { + start_clock = Math.Min( start_clock, item.Clock ); + end_clock = Math.Max( end_clock, item.Clock ); + } + m_tracks[track].setEditedStart( start_clock ); + m_tracks[track].setEditedEnd( end_clock ); + int start_value = m_tracks[track].getCurve( curve ).getElement( start_clock ); + int end_value = m_tracks[track].getCurve( curve ).getElement( end_clock ); + for ( Iterator i = m_tracks[track].getCurve( curve ).keyClockIterator(); i.hasNext(); ){ + int clock = (int)i.next(); + if ( start_clock <= clock && clock <= end_clock ) { + edit.Add( new BPPair( clock, m_tracks[track].getCurve( curve ).getElement( clock ) ) ); + } + } + bool start_found = false; + bool end_found = false; + for ( int i = 0; i < edit.Count; i++ ) { + if ( edit[i].Clock == start_clock ) { + start_found = true; + edit[i].Value = start_value; + if ( start_found && end_found ) { + break; + } + } + if ( edit[i].Clock == end_clock ) { + end_found = true; + edit[i].Value = end_value; + if ( start_found && end_found ) { + break; + } + } + } + if ( !start_found ) { + edit.Add( new BPPair( start_clock, start_value ) ); + } + if ( !end_found ) { + edit.Add( new BPPair( end_clock, end_value ) ); + } + + // 並べ替え + edit.Sort(); + inv = VsqCommand.generateCommandTrackEditCurve( track, curve, edit ); + } else if ( com.Count == 0 ) { + inv = VsqCommand.generateCommandTrackEditCurve( track, curve, new List() ); + } + } + + updateTotalClocks(); + if ( com.Count == 0 ) { + return inv; + } else if ( com.Count == 1 ) { + bool found = false; + for ( Iterator itr = m_tracks[track].getCurve( curve ).keyClockIterator(); itr.hasNext(); ){ + int clock = (int)itr.next(); + if ( clock == com[0].Clock ) { + found = true; + m_tracks[track].getCurve( curve ).add( clock, com[0].Value ); + break; + } + } + if ( !found ) { + m_tracks[track].getCurve( curve ).add( com[0].Clock, com[0].Value ); + } + } else { + int start_clock = com[0].Clock; + int end_clock = com[com.Count - 1].Clock; + bool removed = true; + while ( removed ) { + removed = false; + for ( Iterator itr = m_tracks[track].getCurve( curve ).keyClockIterator(); itr.hasNext(); ) { + int clock = (int)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + m_tracks[track].getCurve( curve ).remove( clock ); + removed = true; + break; + } + } + } + foreach ( BPPair item in com ) { + m_tracks[track].getCurve( curve ).add( item.Clock, item.Value ); + } + } + return inv; + #endregion + } else if ( type == VsqCommandType.TrackEditCurveRange ) { + #region TrackEditCurveRange + int track = (int)command.Args[0]; + string[] curves = (string[])command.Args[1]; + List[] coms = (List[])command.Args[2]; + List[] inv_coms = new List[curves.Length]; + VsqCommand inv = null; + + for ( int k = 0; k < curves.Length; k++ ) { + string curve = curves[k]; + List com = coms[k]; + //SortedList list = Tracks[track][curve].List; + List edit = new List(); + if ( com != null ) { + if ( com.Count > 0 ) { + int start_clock = com[0].Clock; + int end_clock = com[0].Clock; + foreach ( BPPair item in com ) { + start_clock = Math.Min( start_clock, item.Clock ); + end_clock = Math.Max( end_clock, item.Clock ); + } + m_tracks[track].setEditedStart( start_clock ); + m_tracks[track].setEditedEnd( end_clock ); + int start_value = m_tracks[track].getCurve( curve ).getElement( start_clock ); + int end_value = m_tracks[track].getCurve( curve ).getElement( end_clock ); + for ( Iterator itr = m_tracks[track].getCurve( curve ).keyClockIterator(); itr.hasNext(); ) { + int clock = (int)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + edit.Add( new BPPair( clock, m_tracks[track].getCurve( curve ).getElement( clock ) ) ); + } + } + bool start_found = false; + bool end_found = false; + for ( int i = 0; i < edit.Count; i++ ) { + if ( edit[i].Clock == start_clock ) { + start_found = true; + edit[i].Value = start_value; + if ( start_found && end_found ) { + break; + } + } + if ( edit[i].Clock == end_clock ) { + end_found = true; + edit[i].Value = end_value; + if ( start_found && end_found ) { + break; + } + } + } + if ( !start_found ) { + edit.Add( new BPPair( start_clock, start_value ) ); + } + if ( !end_found ) { + edit.Add( new BPPair( end_clock, end_value ) ); + } + + // 並べ替え + edit.Sort(); + inv_coms[k] = edit; + //inv = generateCommandTrackEditCurve( track, curve, edit ); + } else if ( com.Count == 0 ) { + //inv = generateCommandTrackEditCurve( track, curve, new List() ); + inv_coms[k] = new List(); + } + } + + updateTotalClocks(); + if ( com.Count == 0 ) { + return inv; + } else if ( com.Count == 1 ) { + bool found = false; + for ( Iterator itr = m_tracks[track].getCurve( curve ).keyClockIterator(); itr.hasNext(); ) { + int clock = (int)itr.next(); + if ( clock == com[0].Clock ) { + found = true; + m_tracks[track].getCurve( curve ).add( clock, com[0].Value ); + break; + } + } + if ( !found ) { + m_tracks[track].getCurve( curve ).add( com[0].Clock, com[0].Value ); + } + } else { + int start_clock = com[0].Clock; + int end_clock = com[com.Count - 1].Clock; + bool removed = true; + while ( removed ) { + removed = false; + for ( Iterator itr = m_tracks[track].getCurve( curve ).keyClockIterator(); itr.hasNext(); ) { + int clock = (int)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + m_tracks[track].getCurve( curve ).remove( clock ); + removed = true; + break; + } + } + } + foreach ( BPPair item in com ) { + m_tracks[track].getCurve( curve ).add( item.Clock, item.Value ); + } + } + } + return VsqCommand.generateCommandTrackEditCurveRange( track, curves, inv_coms ); + #endregion + } else if ( type == VsqCommandType.EventChangeVelocity ) { + #region TrackChangeVelocity + int track = (int)command.Args[0]; + List> veloc = (List>)command.Args[1]; + List> inv = new List>(); + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent ev = (VsqEvent)itr.next(); + foreach ( KeyValuePair add in veloc ) { + if ( ev.InternalID == add.Key ) { + inv.Add( new KeyValuePair( ev.InternalID, ev.ID.Dynamics ) ); + ev.ID.Dynamics = add.Value; + m_tracks[track].setEditedStart( ev.Clock ); + m_tracks[track].setEditedEnd( ev.Clock + ev.ID.Length ); + break; + } + } + } + return VsqCommand.generateCommandEventChangeVelocity( track, inv ); + #endregion + } else if ( type == VsqCommandType.EventChangeAccent ) { + #region TrackChangeAccent + int track = (int)command.Args[0]; + List> veloc = (List>)command.Args[1]; + List> inv = new List>(); + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent ev = (VsqEvent)itr.next(); + foreach ( KeyValuePair add in veloc ) { + if ( ev.InternalID == add.Key ) { + inv.Add( new KeyValuePair( ev.InternalID, ev.ID.DEMaccent ) ); + ev.ID.DEMaccent = add.Value; + m_tracks[track].setEditedStart( ev.Clock ); + m_tracks[track].setEditedEnd( ev.Clock + ev.ID.Length ); + break; + } + } + } + return VsqCommand.generateCommandEventChangeAccent( track, inv ); + #endregion + } else if ( type == VsqCommandType.EventChangeDecay ) { + #region TrackChangeDecay + int track = (int)command.Args[0]; + List> veloc = (List>)command.Args[1]; + List> inv = new List>(); + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent ev = (VsqEvent)itr.next(); + foreach ( KeyValuePair add in veloc ) { + if ( ev.InternalID == add.Key ) { + inv.Add( new KeyValuePair( ev.InternalID, ev.ID.DEMdecGainRate ) ); + ev.ID.DEMdecGainRate = add.Value; + m_tracks[track].setEditedStart( ev.Clock ); + m_tracks[track].setEditedEnd( ev.Clock + ev.ID.Length ); + break; + } + } + } + return VsqCommand.generateCommandEventChangeDecay( track, inv ); + #endregion + } else if ( type == VsqCommandType.EventChangeLength ) { + #region TrackChangeLength + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int new_length = (int)command.Args[2]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeLength( track, internal_id, item.ID.Length ); + m_tracks[track].setEditedStart( item.Clock ); + int max = Math.Max( item.Clock + item.ID.Length, item.Clock + new_length ); + m_tracks[track].setEditedEnd( max ); + item.ID.Length = new_length; + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeClockAndLength ) { + #region TrackChangeClockAndLength + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int new_clock = (int)command.Args[2]; + int new_length = (int)command.Args[3]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeClockAndLength( track, internal_id, item.Clock, item.ID.Length ); + int min = Math.Min( item.Clock, new_clock ); + int max_length = Math.Max( item.ID.Length, new_length ); + int max = Math.Max( item.Clock + max_length, new_clock + max_length ); + m_tracks[track].setEditedStart( min ); + m_tracks[track].setEditedEnd( max ); + item.ID.Length = new_length; + item.Clock = new_clock; + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeIDContaints ) { + #region TrackChangeIDContaints + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + VsqID value = (VsqID)command.Args[2]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeIDContaints( track, internal_id, item.ID ); + int max_length = Math.Max( item.ID.Length, value.Length ); + m_tracks[track].setEditedStart( item.Clock ); + m_tracks[track].setEditedEnd( item.Clock + max_length ); + item.ID = (VsqID)value.Clone(); + if ( item.ID.type == VsqIDType.Singer ) { +#if DEBUG + Console.WriteLine( " EventChangeIDContaints" ); +#endif + // 歌手変更の場合、次に現れる歌手変更の位置まで編集の影響が及ぶ + bool found = false; + for ( Iterator itr2 = m_tracks[track].getSingerEventIterator(); itr2.hasNext(); ) { + VsqEvent item2 = (VsqEvent)itr2.next(); + if ( item.Clock < item2.Clock ) { + m_tracks[track].setEditedEnd( item2.Clock ); + found = true; + break; + } + } + if ( !found ) { + // 変更対象が、該当トラック最後の歌手変更イベントだった場合 + if ( m_tracks[track].getEventCount() >= 1 ) { + VsqEvent last_event = m_tracks[track].getEvent( m_tracks[track].getEventCount() - 1 ); + m_tracks[track].setEditedEnd( last_event.Clock + last_event.ID.Length ); + } + } +#if DEBUG + Console.WriteLine( " EditedStart,EditedEnd=" + m_tracks[track].getEditedStart() + "," + m_tracks[track].getEditedEnd() ); +#endif + } + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeIDContaintsRange ) { + #region TrackChangeIDContaintsRange + int track = (int)command.Args[0]; + int[] internal_ids = (int[])command.Args[1]; + VsqID[] values = (VsqID[])command.Args[2]; + VsqID[] inv_values = new VsqID[values.Length]; + for ( int i = 0; i < internal_ids.Length; i++ ) { + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_ids[i] ) { + inv_values[i] = (VsqID)item.ID.Clone(); + int max_length = Math.Max( item.ID.Length, values[i].Length ); + m_tracks[track].setEditedStart( item.Clock ); + m_tracks[track].setEditedEnd( item.Clock + max_length ); + item.ID = (VsqID)values[i].Clone(); + if ( item.ID.type == VsqIDType.Singer ) { + // 歌手変更の場合、次に現れる歌手変更の位置まで編集の影響が及ぶ + bool found = false; + for ( Iterator itr2 = m_tracks[track].getSingerEventIterator(); itr2.hasNext(); ) { + VsqEvent item2 = (VsqEvent)itr2.next(); + if ( item.Clock < item2.Clock ) { + m_tracks[track].setEditedEnd( item2.Clock ); + found = true; + break; + } + } + if ( !found ) { + // 変更対象が、該当トラック最後の歌手変更イベントだった場合 + if ( m_tracks[track].getEventCount() >= 1 ) { + VsqEvent last_event = m_tracks[track].getEvent( m_tracks[track].getEventCount() - 1 ); + m_tracks[track].setEditedEnd( last_event.Clock + last_event.ID.Length ); + } + } + } + break; + } + } + } + updateTotalClocks(); + return VsqCommand.generateCommandEventChangeIDContaintsRange( track, internal_ids, inv_values ); + #endregion + } else if ( type == VsqCommandType.EventChangeClockAndIDContaints ) { + #region TrackChangeClockAndIDContaints + int track = (int)command.Args[0]; + int internal_id = (int)command.Args[1]; + int new_clock = (int)command.Args[2]; + VsqID value = (VsqID)command.Args[3]; + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = VsqCommand.generateCommandEventChangeClockAndIDContaints( track, internal_id, item.Clock, item.ID ); + int max_length = Math.Max( item.ID.Length, value.Length ); + int min = Math.Min( item.Clock, new_clock ); + int max = Math.Max( item.Clock + max_length, new_clock + max_length ); + item.ID = (VsqID)value.Clone(); + item.Clock = new_clock; + m_tracks[track].setEditedStart( min ); + m_tracks[track].setEditedEnd( max ); + updateTotalClocks(); + return ret; + } + } + return null; + #endregion + } else if ( type == VsqCommandType.EventChangeClockAndIDContaintsRange ) { + #region TrackChangeClockAndIDContaintsRange + int track = (int)command.Args[0]; + int[] internal_ids = (int[])command.Args[1]; + int[] clocks = (int[])command.Args[2]; + VsqID[] values = (VsqID[])command.Args[3]; + List inv_id = new List(); + List inv_clock = new List(); + for ( int i = 0; i < internal_ids.Length; i++ ) { + for ( Iterator itr = m_tracks[track].getEventIterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_ids[i] ) { + inv_id.Add( (VsqID)item.ID.Clone() ); + inv_clock.Add( item.Clock ); + int max_length = Math.Max( item.ID.Length, values[i].Length ); + int min = Math.Min( item.Clock, clocks[i] ); + int max = Math.Max( item.Clock + max_length, clocks[i] + max_length ); + m_tracks[track].setEditedStart( min ); + m_tracks[track].setEditedEnd( max ); + item.ID = (VsqID)values[i].Clone(); + item.Clock = clocks[i]; + break; + } + } + } + updateTotalClocks(); + return VsqCommand.generateCommandEventChangeClockAndIDContaintsRange( + track, + internal_ids, + inv_clock.ToArray(), + inv_id.ToArray() ); +#if DEBUG + Console.WriteLine( " TrackChangeClockAndIDContaintsRange" ); + Console.WriteLine( " track=" + track ); + for ( int i = 0; i < internal_ids.Length; i++ ) { + Console.WriteLine( " id=" + internal_ids[i] + "; clock=" + clocks[i] + "; ID=" + values[i].ToString() ); + } +#endif + #endregion + } else if ( type == VsqCommandType.TrackChangeName ) { + #region TrackCangeName + int track = (int)command.Args[0]; + string new_name = (string)command.Args[1]; + VsqCommand ret = VsqCommand.generateCommandTrackChangeName( track, m_tracks[track].Name ); + m_tracks[track].Name = new_name; + return ret; + #endregion + } else if ( type == VsqCommandType.TrackReplace ) { + #region TrackReplace + int track = (int)command.Args[0]; + VsqTrack item = (VsqTrack)command.Args[1]; + VsqCommand ret = VsqCommand.generateCommandTrackReplace( track, (VsqTrack)m_tracks[track].Clone() ); + m_tracks[track] = item; + updateTotalClocks(); + return ret; + #endregion + } else if ( type == VsqCommandType.TrackChangeRenderer ) { + #region TrackChangeRenderer + int track = (int)command.Args[0]; + string renderer = (string)command.Args[1]; + string old_renderer = m_tracks[track].Renderer; + m_tracks[track].Renderer = renderer; + VsqCommand ret = VsqCommand.generateCommandTrackChangeRenderer( track, old_renderer ); + return ret; + #endregion + } + + return null; + } + + /// + /// VSQファイルの指定されたクロック範囲のイベント等を削除します + /// + /// 編集対象のVsqFileインスタンス + /// 削除を行う範囲の開始クロック + /// 削除を行う範囲の終了クロック + public static void removePart( VsqFile vsq, int clock_start, int clock_end ) { + int dclock = clock_end - clock_start; + + // テンポ情報の削除、シフト + bool changed = true; + List buf = new List( vsq.getTempoList() ); + int tempo_at_clock_start = vsq.getTempoAt( clock_start ); + vsq.getTempoList().Clear(); + bool just_on_clock_end_added = false; + for ( int i = 0; i < buf.Count; i++ ) { + if ( buf[i].Clock < clock_start ) { + vsq.getTempoList().Add( (TempoTableEntry)buf[i].Clone() ); + } else if ( clock_end <= buf[i].Clock ) { + TempoTableEntry tte = (TempoTableEntry)buf[i].Clone(); + tte.Clock = tte.Clock - dclock; + if ( clock_end == buf[i].Clock ) { + vsq.getTempoList().Add( tte ); + just_on_clock_end_added = true; + } else { + if ( !just_on_clock_end_added ) { + vsq.getTempoList().Add( new TempoTableEntry( clock_end - dclock, tempo_at_clock_start, 0.0 ) ); + just_on_clock_end_added = true; + } + vsq.getTempoList().Add( tte ); + } + } + } + vsq.updateTempoInfo(); + + for ( int track = 1; track < vsq.m_tracks.Count; track++ ) { + // 削除する範囲に歌手変更イベントが存在するかどうかを検査。 + VsqEvent t_last_singer = null; + for ( Iterator itr = vsq.m_tracks[track].getSingerEventIterator(); itr.hasNext(); ) { + VsqEvent ve = (VsqEvent)itr.next(); + if ( clock_start <= ve.Clock && ve.Clock < clock_end ) { + t_last_singer = ve; + } + if ( ve.Clock == clock_end ) { + t_last_singer = null; // 後でclock_endの位置に補うが、そこにに既に歌手変更イベントがあるとまずいので。 + } + } + VsqEvent last_singer = null; + if ( t_last_singer != null ) { + last_singer = (VsqEvent)t_last_singer.Clone(); + last_singer.Clock = clock_end; + } + + changed = true; + // イベントの削除 + while ( changed ) { + changed = false; + for ( int i = 0; i < vsq.m_tracks[track].getEventCount(); i++ ) { + if ( clock_start <= vsq.m_tracks[track].getEvent( i ).Clock && vsq.m_tracks[track].getEvent( i ).Clock < clock_end ) { + vsq.m_tracks[track].removeEvent( i ); + changed = true; + break; + } + } + } + + // クロックのシフト + if ( last_singer != null ) { + vsq.m_tracks[track].addEvent( last_singer ); //歌手変更イベントを補う + } + for ( int i = 0; i < vsq.m_tracks[track].getEventCount(); i++ ) { + if ( clock_end <= vsq.m_tracks[track].getEvent( i ).Clock ) { + vsq.m_tracks[track].getEvent( i ).Clock -= dclock; + } + } + + foreach ( string curve in _CURVES ) { + if ( curve == "VEL" ) { + continue; + } + VsqBPList buf_bplist = (VsqBPList)vsq.m_tracks[track].getCurve( curve ).Clone(); + vsq.m_tracks[track].getCurve( curve ).clear(); + for ( Iterator itr = buf_bplist.keyClockIterator(); itr.hasNext(); ) { + int key = (int)itr.next(); + if ( key < clock_start ) { + vsq.m_tracks[track].getCurve( curve ).add( key, buf_bplist.getElement( key ) ); + } else if ( clock_end <= key ) { + vsq.m_tracks[track].getCurve( curve ).add( key - dclock, buf_bplist.getElement( key ) ); + } + } + } + } + } + + /// + /// vsqファイル全体のイベントを,指定したクロックだけ遅らせます. + /// ただし,曲頭のテンポ変更イベントと歌手変更イベントはクロック0から移動しません. + /// この操作を行うことで,TimesigTableの情報は破綻します(仕様です). + /// + /// + public static void shift( VsqFile vsq, uint delta_clock ) { + if ( delta_clock == 0 ) { + return; + } + int dclock = (int)delta_clock; + for ( int i = 0; i < vsq.getTempoList().Count; i++ ) { + if ( vsq.getTempoList()[i].Clock > 0 ) { + vsq.getTempoList()[i].Clock =vsq.getTempoList()[i].Clock + dclock; + } + } + vsq.updateTempoInfo(); + for ( int track = 1; track < vsq.m_tracks.Count; track++ ) { + for ( int i = 0; i < vsq.m_tracks[track].getEventCount(); i++ ) { + if ( vsq.m_tracks[track].getEvent( i ).Clock > 0 ) { + vsq.m_tracks[track].getEvent( i ).Clock += dclock; + } + } + foreach ( string curve in _CURVES ) { + if ( curve == "VEL" ) { + continue; + + } + // 順番に+=dclockしていくとVsqBPList内部のSortedListの値がかぶる可能性がある. + VsqBPList edit = vsq.m_tracks[track].getCurve( curve ); + VsqBPList new_one = new VsqBPList( edit.getDefault(), edit.getMinimum(), edit.getMaximum() ); + foreach( int key in edit.getKeys() ){ + new_one.add( key + dclock, edit.getElement( key ) ); + } + vsq.m_tracks[track].setCurve( curve, new_one ); + } + } + vsq.updateTotalClocks(); + } + + /// + /// このインスタンスのコピーを作成します + /// + /// このインスタンスのコピー + public object Clone() { + VsqFile ret = new VsqFile(); + ret.m_tracks = new List(); + for ( int i = 0; i < m_tracks.Count; i++ ) { + ret.m_tracks.Add( (VsqTrack)m_tracks[i].Clone() ); + } + ret.m_tempo_table = new List(); + for ( int i = 0; i < m_tempo_table.Count; i++ ) { + ret.m_tempo_table.Add( (TempoTableEntry)m_tempo_table[i].Clone() ); + } + ret.m_timesig_table = new List(); + for ( int i = 0; i < m_timesig_table.Count; i++ ) { + ret.m_timesig_table.Add( (TimeSigTableEntry)m_timesig_table[i].Clone() ); + } + ret.m_tpq = m_tpq; + ret.TotalClocks = TotalClocks; + ret.m_base_tempo = m_base_tempo; + ret.Master = (VsqMaster)Master.Clone(); + ret.Mixer = (VsqMixer)Mixer.Clone(); + ret.m_premeasure_clocks = m_premeasure_clocks; + return ret; + } + + private VsqFile() { + VsqUtil.loadSingerConfigs(); + } + + private class BarLineIterator : Iterator { + private List m_list; + private int m_end_clock; + private int i; + private int clock; + int local_denominator; + int local_numerator; + int clock_step; + int t_end; + int local_clock; + int bar_counter; + + public BarLineIterator( List list, int end_clock ) { + m_list = list; + m_end_clock = end_clock; + i = 0; + t_end = -1; + clock = 0; + } + + public Object next() { + int mod = clock_step * local_numerator; + if ( clock < t_end ) { + if ( (clock - local_clock) % mod == 0 ) { + bar_counter++; + VsqBarLineType ret = new VsqBarLineType( clock, true, local_denominator, local_numerator, bar_counter ); + clock += clock_step; + return ret; + } else { + VsqBarLineType ret = new VsqBarLineType( clock, false, local_denominator, local_numerator, bar_counter ); + clock += clock_step; + return ret; + } + } + + if( i < m_list.Count ) { + local_denominator = m_list[i].Denominator; + local_numerator = m_list[i].Numerator; + local_clock = m_list[i].Clock; + int local_bar_count = m_list[i].BarCount; + clock_step = 480 * 4 / local_denominator; + mod = clock_step * local_numerator; + bar_counter = local_bar_count - 1; + t_end = m_end_clock; + if ( i + 1 < m_list.Count ) { + t_end = m_list[i + 1].Clock; + } + i++; + clock = local_clock; + if( clock < t_end ){ + if ( (clock - local_clock) % mod == 0 ) { + bar_counter++; + VsqBarLineType ret = new VsqBarLineType( clock, true, local_denominator, local_numerator, bar_counter ); + clock += clock_step; + return ret; + } else { + VsqBarLineType ret = new VsqBarLineType( clock, false, local_denominator, local_numerator, bar_counter ); + clock += clock_step; + return ret; + } + } + } + return null; + } + + public void remove() { + throw new NotImplementedException(); + } + + public Boolean hasNext() { + if ( clock < m_end_clock ) { + return true; + } else { + return false; + } + } + } + + /// + /// 小節の区切りを順次返すIterator。 + /// + /// + public Iterator getBarLineIterator( int end_clock ) { + return new BarLineIterator( getTimeSigList(), end_clock ); + } + + /// + /// 基本テンポ値を取得します + /// + public int getBaseTempo() { + return m_base_tempo; + } + + /// + /// プリメジャー値を取得します + /// + public int getPreMeasure() { + return Master.PreMeasure; + } + + /// + /// プリメジャー部分の長さをクロックに変換した値を取得します. + /// + public int getPreMeasureClocks() { + return m_premeasure_clocks; + } + + /// + /// プリメジャーの長さ(クロック)を計算します。 + /// + private int calculatePreMeasureInClock() { + int pre_measure = Master.PreMeasure; + int last_bar_count = getTimeSigList()[0].BarCount; + int last_clock = getTimeSigList()[0].Clock; + int last_denominator = getTimeSigList()[0].Denominator; + int last_numerator = getTimeSigList()[0].Numerator; + for ( int i = 1; i < getTimeSigList().Count; i++ ) { + if ( getTimeSigList()[i].BarCount >= pre_measure ) { + break; + } else { + last_bar_count = getTimeSigList()[i].BarCount; + last_clock = getTimeSigList()[i].Clock; + last_denominator = getTimeSigList()[i].Denominator; + last_numerator = getTimeSigList()[i].Numerator; + } + } + + int remained = pre_measure - last_bar_count;//プリメジャーの終わりまでの残り小節数 + return last_clock + remained * last_numerator * 480 * 4 / last_denominator; + } + + /// + /// 指定したクロックにおける、clock=0からの演奏経過時間(sec)を取得します + /// + /// + /// + public double getSecFromClock( int clock ) { + for ( int i = getTempoList().Count - 1; i >= 0; i-- ) { + if ( getTempoList()[i].Clock < clock ) { + double init = getTempoList()[i].Time; + int dclock = clock - getTempoList()[i].Clock; + double sec_per_clock1 = getTempoList()[i].Tempo * 1e-6 / 480.0; + return init + dclock * sec_per_clock1; + } + } + + double sec_per_clock = m_base_tempo * 1e-6 / 480.0; + return clock * sec_per_clock; + } + + /// + /// 指定した時刻における、クロックを取得します + /// + /// + /// + public double getClockFromSec( double time ) { + // timeにおけるテンポを取得 + int tempo = m_base_tempo; + double base_clock = 0; + double base_time = 0f; + if ( m_tempo_table.Count == 0 ) { + tempo = m_base_tempo; + base_clock = 0; + base_time = 0f; + } else if ( m_tempo_table.Count == 1 ) { + tempo = m_tempo_table[0].Tempo; + base_clock = m_tempo_table[0].Clock; + base_time = m_tempo_table[0].Time; + } else { + for ( int i = m_tempo_table.Count - 1; i >= 0; i-- ) { + if ( m_tempo_table[i].Time < time ) { + return m_tempo_table[i].Clock + (time - m_tempo_table[i].Time) * m_tpq * 1000000.0 / m_tempo_table[i].Tempo; + } + } + } + double dt = time - base_time; + return base_clock + dt * m_tpq * 1000000.0 / (double)tempo; + } + + /// + /// 指定したクロックにおける拍子を取得します + /// + /// + /// + /// + public void getTimesigAt( int clock, out int numerator, out int denominator ) { + int index = 0; + for ( int i = getTimeSigList().Count - 1; i >= 0; i-- ) { + index = i; + if ( getTimeSigList()[i].Clock <= clock ) { + break; + } + } + numerator = getTimeSigList()[index].Numerator; + denominator = getTimeSigList()[index].Denominator; + } + + /// + /// 指定したクロックにおけるテンポを取得します。 + /// + /// + /// + public int getTempoAt( int clock ) { + int index = 0; + for ( int i = getTempoList().Count - 1; i >= 0; i-- ) { + index = i; + if ( getTempoList()[i].Clock <= clock ) { + break; + } + } + return getTempoList()[index].Tempo; + } + + /// + /// 指定した小節の開始クロックを調べます。ここで使用する小節数は、プリメジャーを考慮しない。即ち、曲頭の小節が0である。 + /// + /// + /// + public int getClockFromBarCount( int bar_count ) { + int index = 0; + for ( int i = getTimeSigList().Count - 1; i >= 0; i-- ) { + index = i; + if ( getTimeSigList()[i].BarCount <= bar_count ) { + break; + } + } + int numerator = getTimeSigList()[index].Numerator; + int denominator = getTimeSigList()[index].Denominator; + int init_clock = getTimeSigList()[index].Clock; + int init_bar_count = getTimeSigList()[index].BarCount; + int clock_per_bar = numerator * 480 * 4 / denominator; + return init_clock + (bar_count - init_bar_count) * clock_per_bar; + } + + /// + /// 指定したクロックが、曲頭から何小節目に属しているかを調べます。ここで使用する小節数は、プリメジャーを考慮しない。即ち、曲頭の小節が0である。 + /// + /// + /// + public int getBarCountFromClock( int clock ) { + int index = 0; + for ( int i = getTimeSigList().Count - 1; i >= 0; i-- ) { + index = i; + if ( getTimeSigList()[i].Clock <= clock ) { + break; + } + } + int bar_count = 0; + if ( index >= 0 ) { + int last_clock = getTimeSigList()[index].Clock; + int t_bar_count = getTimeSigList()[index].BarCount; + int numerator = getTimeSigList()[index].Numerator; + int denominator = getTimeSigList()[index].Denominator; + int clock_per_bar = numerator * 480 * 4 / denominator; + bar_count = t_bar_count + (clock - last_clock) / clock_per_bar; + } + return bar_count; + } + + /// + /// 4分の1拍子1音あたりのクロック数を取得します + /// + public int getTickPerQuarter() { + return m_tpq; + } + + /// + /// テンポの変更情報を格納したテーブルを取得します + /// + public List getTempoList() { + return m_tempo_table; + } + + /// + /// 拍子の変更情報を格納したテーブルを取得します + /// + public List getTimeSigList() { + return m_timesig_table; + } + + public VsqTrack getTrack( int track ) { + return m_tracks[track]; + } + + public int getTrackCount() { + return m_tracks.Count; + } + + /// + /// 空のvsqファイルを構築します + /// + /// + /// + /// + /// + public VsqFile( int default_singer_program_change, int pre_measure, int numerator, int denominator, int tempo ) { + VsqUtil.loadSingerConfigs(); + TotalClocks = pre_measure * 480 * 4 / denominator * numerator; + m_tpq = 480; + + m_tracks = new List(); + m_tracks.Add( new VsqTrack( tempo, numerator, denominator ) ); + string singer = "Miku"; + SingerConfig sc = VsqUtil.getSingerInfo( default_singer_program_change ); + if ( sc != null ) { + singer = sc.VOICENAME; + } + m_tracks.Add( new VsqTrack( "Voice1", singer ) ); + Master = new VsqMaster( pre_measure ); +#if DEBUG + Console.WriteLine( "VsqFile.ctor()" ); +#endif + Mixer = new VsqMixer( 0, 0, 0, 0 ); + Mixer.Slave.Add( new VsqMixerEntry( 0, 0, 0, 0 ) ); + m_timesig_table = new List(); + m_timesig_table.Add( new TimeSigTableEntry( 0, numerator, denominator, 0 ) ); + m_tempo_table = new List(); + m_tempo_table.Add( new TempoTableEntry( 0, tempo, 0.0 ) ); + m_base_tempo = tempo; + m_premeasure_clocks = calculatePreMeasureInClock(); + } + + /// + /// vsqファイルからのコンストラクタ + /// + /// + public VsqFile( string _fpath ) { + VsqUtil.loadSingerConfigs(); + m_tempo_table = new List(); + m_timesig_table = new List(); + m_tpq = 480; + + // SMFをコンバートしたテキストファイルを作成 + using ( TextMemoryStream tms = new TextMemoryStream( FileAccess.ReadWrite ) ) { + MidiFile mf = new MidiFile( _fpath ); + m_tracks = new List(); + int num_track = mf.getTrackCount(); + for ( int i = 0; i < num_track; i++ ) { + m_tracks.Add( new VsqTrack( mf.getMidiEventList( i ) ) ); + } + } + + Master = (VsqMaster)m_tracks[1].getMaster().Clone(); + Mixer = (VsqMixer)m_tracks[1].getMixer().Clone(); + m_tracks[1].setMaster( null ); + m_tracks[1].setMixer( null ); + +#if DEBUG + System.Diagnostics.Debug.WriteLine( "VsqFile.ctor()" ); +#endif + int master_track = -1; + for ( int i = 0; i < m_tracks.Count; i++ ) { +#if DEBUG + System.Diagnostics.Debug.WriteLine( " m_tracks[i].Name=" + m_tracks[i].Name ); +#endif + if ( m_tracks[i].Name == "Master Track" ) { + master_track = i; + break; + } + } + + int prev_tempo; + int prev_index; + double prev_time; + if ( master_track >= 0 ) { + #region TempoListの作成 + // MIDI event リストの取得 + List midi_event = m_tracks[master_track].getTempoList(); + // とりあえずtempo_tableに格納 + prev_tempo = midi_event[0].Data[1] << 16 | midi_event[0].Data[2] << 8 | midi_event[0].Data[3];// midi_event[0].intValue[0]; + m_base_tempo = prev_tempo; + prev_index = 0; + m_tempo_table.Add( new TempoTableEntry( (int)midi_event[0].Clock/* midi_event[0].index*/, prev_tempo, 0.0 ) ); + double thistime; + prev_time = 0.0; + for ( int j = 1; j < midi_event.Count; j++ ) { + int current_tempo = midi_event[j].Data[1] << 16 | midi_event[j].Data[2] << 8 | midi_event[j].Data[3]; + int current_index = (int)midi_event[j].Clock; + thistime = prev_time + (double)(prev_tempo) * (double)(current_index - prev_index) / (m_tpq * 1000000.0); + m_tempo_table.Add( new TempoTableEntry( current_index, current_tempo, thistime ) ); + prev_tempo = current_tempo; + prev_index = current_index; + prev_time = thistime; + } + m_tempo_table.Sort(); + #endregion + + #region TimeSigTableの作成 + List time_sigs = m_tracks[master_track].getTimeSigList(); + int dnomi = time_sigs[0].Data[1]; + int numer = 1; + for ( int i = 0; i < time_sigs[0].Data[2]; i++ ) { + numer = numer * 2; + } + m_timesig_table.Add( new TimeSigTableEntry( 0, numer, dnomi, 0 ) ); + for ( int j = 1; j < time_sigs.Count; j++ ) { + int numerator = m_timesig_table[j - 1].Numerator; + int denominator = m_timesig_table[j - 1].Denominator; + int clock = m_timesig_table[j - 1].Clock; + int bar_count = m_timesig_table[j - 1].BarCount; + + int dif = 480 * 4 / denominator * numerator;//1小節が何クロックか? + bar_count += ((int)time_sigs[j].Clock - clock) / dif; + dnomi = time_sigs[j].Data[1]; + numer = 1; + for ( int i = 0; i < time_sigs[j].Data[2]; i++ ) { + numer = numer * 2; + } + m_timesig_table.Add( new TimeSigTableEntry( (int)time_sigs[j].Clock, numer, dnomi, bar_count ) ); + } + #endregion + } + + // 曲の長さを計算 + updateTempoInfo(); + updateTimesigInfo(); + m_premeasure_clocks = calculatePreMeasureInClock(); + updateTotalClocks(); +#if DEBUG + System.Diagnostics.Debug.WriteLine( " m_total_clocks=" + TotalClocks ); +#endif + } + + /// + /// TimeSigTableの[*].Clockの部分を更新します + /// + public void updateTimesigInfo() { +#if DEBUG + Console.WriteLine( "VsqFile.UpdateTimesigInfo()" ); +#endif + if ( m_timesig_table[0].Clock != 0 ) { + throw new ApplicationException( "initial timesig does not found" ); + } + m_timesig_table[0].Clock = 0; + m_timesig_table.Sort(); + for ( int j = 1; j < m_timesig_table.Count; j++ ) { + int numerator = m_timesig_table[j - 1].Numerator; + int denominator = m_timesig_table[j - 1].Denominator; + int clock = m_timesig_table[j - 1].Clock; + int bar_count = m_timesig_table[j - 1].BarCount; + int dif = 480 * 4 / denominator * numerator;//1小節が何クロックか? + clock += (m_timesig_table[j].BarCount - bar_count) * dif; + m_timesig_table[j].Clock = clock; + } + m_premeasure_clocks = calculatePreMeasureInClock(); +#if DEBUG + for ( int i = 0; i < m_timesig_table.Count; i++ ) { + Console.WriteLine( " clock=" + m_timesig_table[i].Clock + "; bar_count=" + m_timesig_table[i].BarCount + "; " + m_timesig_table[i].Numerator + "/" + m_timesig_table[i].Denominator ); + } +#endif + } + + /// + /// TempoTableの[*].Timeの部分を更新します + /// + public void updateTempoInfo() { + if ( m_tempo_table.Count == 0 ) { + m_tempo_table.Add( new TempoTableEntry( 0, getBaseTempo(), 0.0 ) ); + } + m_tempo_table.Sort(); + if ( m_tempo_table[0].Clock != 0 ) { + m_tempo_table[0].Time = (double)getBaseTempo() * (double)m_tempo_table[0].Clock / (getTickPerQuarter() * 1000000.0); + } else { + m_tempo_table[0].Time = 0.0; + } + double prev_time = m_tempo_table[0].Time; + int prev_clock = m_tempo_table[0].Clock; + int prev_tempo = m_tempo_table[0].Tempo; + double inv_tpq_sec = 1.0 / (getTickPerQuarter() * 1000000.0); + for ( int i = 1; i < m_tempo_table.Count; i++ ) { + m_tempo_table[i].Time = prev_time + (double)prev_tempo * (double)(m_tempo_table[i].Clock - prev_clock) * inv_tpq_sec; + prev_time = m_tempo_table[i].Time; + prev_tempo = m_tempo_table[i].Tempo; + prev_clock = m_tempo_table[i].Clock; + } +#if DEBUG + using ( StreamWriter sw = new StreamWriter( Path.Combine( System.Windows.Forms.Application.StartupPath, "vsq_tempo_info.txt" ) ) ) { + sw.WriteLine( "Clock\tTime\tTempo" ); + for ( int i = 0; i < m_tempo_table.Count; i++ ) { + sw.WriteLine( m_tempo_table[i].Clock + "\t" + m_tempo_table[i].Time + "\t" + m_tempo_table[i].Tempo ); + } + } +#endif + } + + /// + /// VsqFile.Executeの実行直後などに、m_total_clocksの値を更新する + /// + public void updateTotalClocks() { + int max = m_premeasure_clocks; + for( int i = 1; i < m_tracks.Count; i++ ){ + VsqTrack track = m_tracks[i]; + for ( Iterator itr = track.getEventIterator(); itr.hasNext(); ) { + VsqEvent ve = (VsqEvent)itr.next(); + max = Math.Max( max, ve.Clock + ve.ID.Length ); + } + foreach ( string vct in _CURVES ) { + if ( vct == "VEL" ) { + continue; + } + if ( track.getCurve( vct ).getCount() > 0 ) { + int keys = track.getCurve( vct ).getCount(); + int last_key = track.getCurve( vct ).getKeys()[keys - 1]; + max = Math.Max( max, last_key ); + } + } + } + TotalClocks = max; + } + + /// + /// 曲の長さを取得する。(sec) + /// + public double getTotalSec() { + return getSecFromClock( (int)TotalClocks ); + } + + /// + /// 指定された番号のトラックに含まれる歌詞を指定されたファイルに出力します + /// + /// + /// + public void printLyricTable( int track, string fpath ) { + using ( StreamWriter sw = new StreamWriter( fpath ) ) { + for ( int i = 0; i < m_tracks[track].getEventCount(); i++ ) { + int Length; + // timesignal + int time_signal = m_tracks[track].getEvent( i ).Clock; + // イベントで指定されたIDがLyricであった場合 + if ( m_tracks[track].getEvent( i ).ID.type == VsqIDType.Anote ) { + // 発音長を取得 + Length = m_tracks[track].getEvent( i ).ID.Length; + + // tempo_tableから、発音開始時のtempoを取得 + int last = getTempoList().Count - 1; + int tempo = getTempoList()[last].Tempo; + int prev_index = getTempoList()[last].Clock; + double prev_time = getTempoList()[last].Time; + for ( int j = 1; j < getTempoList().Count; j++ ) { + if ( getTempoList()[j].Clock > time_signal ) { + tempo = getTempoList()[j - 1].Tempo; + prev_index = getTempoList()[j - 1].Clock; + prev_time = getTempoList()[j - 1].Time; + break; + } + } + int current_index = m_tracks[track].getEvent( i ).Clock; + double start_time = prev_time + (double)(current_index - prev_index) * (double)tempo / (m_tpq * 1000000.0); + // TODO: 単純に + Lengthしただけではまずいはず。要検討 + double end_time = start_time + ((double)Length) * ((double)tempo) / (m_tpq * 1000000.0); + sw.WriteLine( m_tracks[track].getEvent( i ).Clock + "," + + start_time.ToString( "0.000000" ) + "," + + end_time.ToString( "0.000000" ) + "," + + m_tracks[track].getEvent( i ).ID.LyricHandle.L0.Phrase + "," + + m_tracks[track].getEvent( i ).ID.LyricHandle.L0.getPhoneticSymbol() ); + } + + } + } + } + + private static void printTrack( VsqFile vsq, int track, FileStream fs, int msPreSend ) { +#if DEBUG + Console.WriteLine( "PrintTrack" ); +#endif + //VsqTrack item = Tracks[track]; + string _NL = "" + (char)0x0a; + //ヘッダ + fs.Write( _MTRK, 0, 4 ); + //データ長。とりあえず0 + fs.Write( new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4 ); + long first_position = fs.Position; + //トラック名 + writeFlexibleLengthUnsignedLong( fs, 0x00 );//デルタタイム + fs.WriteByte( 0xff );//ステータスタイプ + fs.WriteByte( 0x03 );//イベントタイプSequence/Track Name + byte[] seq_name = bocoree.cp932.convert( vsq.m_tracks[track].Name ); + writeFlexibleLengthUnsignedLong( fs, (ulong)seq_name.Length );//seq_nameの文字数 + fs.Write( seq_name, 0, seq_name.Length ); + //Meta Textを準備 + using ( TextMemoryStream sr = new TextMemoryStream( FileAccess.ReadWrite ) ) { + vsq.m_tracks[track].printMetaText( sr, vsq.TotalClocks + 120, vsq.calculatePreMeasureInClock() ); + sr.rewind(); + int line_count = -1; + string tmp = ""; + if ( sr.peek() >= 0 ) { + tmp = sr.readLine(); + char[] line_char; + string line = ""; + while ( sr.peek() >= 0 ) { + line = sr.readLine(); + tmp += _NL + line; + while ( (tmp + getLinePrefix( line_count )).Length >= 127 ) { + line_count++; + tmp = getLinePrefix( line_count ) + tmp; + string work = tmp.Substring( 0, 127 ); + tmp = tmp.Substring( 127 ); + line_char = work.ToCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.WriteByte( 0xff );//ステータスタイプ + fs.WriteByte( 0x01 );//イベントタイプMeta Text + writeFlexibleLengthUnsignedLong( fs, (ulong)line_char.Length );//データ長 + writeCharArray( fs, line_char );//メタテキスト本体 + } + } + // 残りを出力 + line_count++; + tmp = getLinePrefix( line_count ) + tmp + _NL; + while ( tmp.Length > 127 ) { + string work = tmp.Substring( 0, 127 ); + tmp = tmp.Substring( 127 ); + line_char = work.ToCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.WriteByte( 0xff ); + fs.WriteByte( 0x01 ); + writeFlexibleLengthUnsignedLong( fs, (ulong)line_char.Length ); + writeCharArray( fs, line_char ); + line_count++; + tmp = getLinePrefix( line_count ); + } + line_char = tmp.ToCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.WriteByte( 0xff ); + fs.WriteByte( 0x01 ); + writeFlexibleLengthUnsignedLong( fs, (ulong)line_char.Length ); + writeCharArray( fs, line_char ); + } + } + + int last = 0; + VsqNrpn[] data = generateNRPN( vsq, track, msPreSend ); + NrpnData[] nrpns = VsqNrpn.convert( data ); + for ( int i = 0; i < nrpns.Length; i++ ) { + writeFlexibleLengthUnsignedLong( fs, (ulong)(nrpns[i].getClock() - last) ); + fs.WriteByte( 0xb0 ); + fs.WriteByte( nrpns[i].getParameter() ); + fs.WriteByte( nrpns[i].Value ); + last = nrpns[i].getClock(); + } + + //トラックエンド + VsqEvent last_event = vsq.m_tracks[track].getEvent( vsq.m_tracks[track].getEventCount() - 1 ); + int last_clock = last_event.Clock + last_event.ID.Length; + writeFlexibleLengthUnsignedLong( fs, (ulong)last_clock ); + fs.WriteByte( 0xff ); + fs.WriteByte( 0x2f ); + fs.WriteByte( 0x00 ); + long pos = fs.Position; + fs.Seek( first_position - 4, SeekOrigin.Begin ); + writeUnsignedInt( fs, (uint)(pos - first_position) ); + fs.Seek( pos, SeekOrigin.Begin ); + } + + /// + /// 指定したクロックにおけるプリセンド・クロックを取得します + /// + /// + /// + /// + public int getPresendClockAt( int clock, int msPreSend ) { + double clock_msec = getSecFromClock( clock ) * 1000.0; + float draft_clock_sec = (float)(clock_msec - msPreSend) / 1000.0f; + int draft_clock = (int)Math.Floor( getClockFromSec( draft_clock_sec ) ); + return clock - draft_clock; + } + + /// + /// 指定したトラックから、Expression(DYN)のNRPNリストを作成します + /// + /// + /// + /// + public static VsqNrpn[] generateExpressionNRPN( VsqFile vsq, int track, int msPreSend ) { + List ret = new List(); + int count = vsq.m_tracks[track].getCurve( "DYN" ).getCount(); + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + int start_clock = (int)vsq.getClockFromSec( msPreSend / 1000.0 ) + 1; + int start_value = vsq.m_tracks[track].getCurve( "DYN" ).getElement( start_clock ); + VsqNrpn add0 = new VsqNrpn( start_clock - vsq.getPresendClockAt( start_clock, msPreSend ), + (ushort)NRPN.CC_E_VESION_AND_DEVICE, + 0x00, 0x00 ); + add0.append( NRPN.CC_E_DELAY, delay0, delay1 ); + add0.append( NRPN.CC_E_EXPRESSION, (byte)start_value ); + ret.Add( add0 ); + int[] keys = vsq.m_tracks[track].getCurve( "DYN" ).getKeys(); + for ( int i = 0; i < keys.Length; i++ ) { + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i] - vsq.getPresendClockAt( keys[i], msPreSend ), + (ushort)NRPN.CC_E_EXPRESSION, + (byte)vsq.m_tracks[track].getCurve( "DYN" ).getElement( keys[i] ) ); + ret.Add( add ); + } + } + return ret.ToArray(); + } + + /// + /// 先頭に記録されるNRPNを作成します + /// + /// + public static VsqNrpn generateHeaderNRPN() { + VsqNrpn ret = new VsqNrpn( 0, (ushort)NRPN.CC_BS_VERSION_AND_DEVICE, 0x00, 0x00 ); + ret.append( NRPN.CC_BS_DELAY, 0x00, 0x00 ); + ret.append( NRPN.CC_BS_LANGUAGE_TYPE, 0x00 ); + return ret; + } + + /// + /// 歌手変更イベントから,NRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generateSingerNRPN( VsqFile vsq, VsqEvent ve, int msPreSend ) { + int clock = ve.Clock; + + double clock_msec = vsq.getSecFromClock( clock ) * 1000.0; + + int ttempo = vsq.getTempoAt( clock ); + double tempo = 6e7 / ttempo; + //double sStart = SecFromClock( ve.Clock ); + double msEnd = vsq.getSecFromClock( ve.Clock + ve.ID.Length ) * 1000.0; + ushort duration = (ushort)Math.Ceiling( msEnd - clock_msec ); +#if DEBUG + Console.WriteLine( "GenerateNoteNRPN" ); + Console.WriteLine( " duration=" + duration ); +#endif + byte duration0, duration1; + getMsbAndLsb( duration, out duration0, out duration1 ); + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + List ret = new List(); + + int i = clock - vsq.getPresendClockAt( clock, msPreSend ); + VsqNrpn add = new VsqNrpn( i, (ushort)NRPN.CC_BS_VERSION_AND_DEVICE, 0x00, 0x00 ); + add.append( NRPN.CC_BS_DELAY, delay0, delay1 ); + add.append( NRPN.CC_BS_LANGUAGE_TYPE, (byte)ve.ID.IconHandle.Language ); + add.append( NRPN.PC_VERSION_AND_DEVICE, 0x00, 0x00 ); + add.append( NRPN.PC_VOICE_TYPE, (byte)ve.ID.IconHandle.Program ); + return new VsqNrpn[] { add }; + } + + /// + /// 音符イベントから,NRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn generateNoteNRPN( VsqFile vsq, VsqEvent ve, int msPreSend, byte note_loc ) { + int clock = ve.Clock; + + double clock_msec = vsq.getSecFromClock( clock ) * 1000.0; + + int ttempo = vsq.getTempoAt( clock ); + double tempo = 6e7 / ttempo; + double msEnd = vsq.getSecFromClock( ve.Clock + ve.ID.Length ) * 1000.0; + ushort duration = (ushort)Math.Ceiling( msEnd - clock_msec ); + byte duration0, duration1; + getMsbAndLsb( duration, out duration0, out duration1 ); + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + + VsqNrpn add = new VsqNrpn( clock - vsq.getPresendClockAt( clock, msPreSend ), (ushort)NRPN.CVM_NM_DELAY, delay0, delay1 ); + add.append( NRPN.CVM_NM_NOTE_NUMBER, (byte)ve.ID.Note ); // Note number + add.append( NRPN.CVM_NM_VELOCITY, (byte)ve.ID.Dynamics ); // Velocity + add.append( NRPN.CVM_NM_NOTE_DURATION, duration0, duration1 ); // Note duration + add.append( NRPN.CVM_NM_NOTE_LOCATION, note_loc ); // Note Location + + if ( ve.ID.VibratoHandle != null ) { + add.append( NRPN.CVM_NM_INDEX_OF_VIBRATO_DB, 0x00, 0x00 ); + int vibrato_type = (int)VibratoTypeUtil.getVibratoTypeFromIconID( ve.ID.VibratoHandle.IconID ); + int note_length = ve.ID.Length; + int vibrato_delay = ve.ID.VibratoDelay; + byte bVibratoDuration = (byte)((float)(note_length - vibrato_delay) / (float)note_length * 127); + byte bVibratoDelay = (byte)(0x7f - bVibratoDuration); + add.append( NRPN.CVM_NM_VIBRATO_CONFIG, (byte)vibrato_type, bVibratoDuration ); + add.append( NRPN.CVM_NM_VIBRATO_DELAY, bVibratoDelay ); + } + + string[] spl = ve.ID.LyricHandle.L0.getPhoneticSymbolList(); + string s = ""; + for ( int j = 0; j < spl.Length; j++ ) { + s += spl[j]; + } + char[] symbols = s.ToCharArray(); + add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_BYTES, (byte)symbols.Length );// 0x12(Number of phonetic symbols in bytes) + int count = -1; + for ( int j = 0; j < spl.Length; j++ ) { + char[] chars = spl[j].ToCharArray(); + for ( int k = 0; k < chars.Length; k++ ) { + count++; + if ( k == 0 ) { + add.append( (NRPN)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k], (byte)ve.ID.LyricHandle.L0.getConsonantAdjustment()[j] ); // Phonetic symbol j + } else { + add.append( (NRPN)((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k] ); // Phonetic symbol j + } + } + } + add.append( NRPN.CVM_NM_PHONETIC_SYMBOL_CONTINUATION, 0x7f ); // End of phonetic symbols + add.append( NRPN.CVM_NM_V1MEAN, 0x04 );// 0x50(v1mean) + add.append( NRPN.CVM_NM_D1MEAN, 0x08 );// 0x51(d1mean) + add.append( NRPN.CVM_NM_D1MEAN_FIRST_NOTE, 0x14 );// 0x52(d1meanFirstNote) + add.append( NRPN.CVM_NM_D2MEAN, 0x1c );// 0x53(d2mean) + add.append( NRPN.CVM_NM_D4MEAN, 0x18 );// 0x54(d4mean) + add.append( NRPN.CVM_NM_PMEAN_ONSET_FIRST_NOTE, 0x0a ); // 055(pMeanOnsetFirstNote) + add.append( NRPN.CVM_NM_VMEAN_NOTE_TRNSITION, 0x0c ); // 0x56(vMeanNoteTransition) + add.append( NRPN.CVM_NM_PMEAN_ENDING_NOTE, 0x0c );// 0x57(pMeanEndingNote) + add.append( NRPN.CVM_NM_ADD_PORTAMENTO, (byte)ve.ID.PMbPortamentoUse );// 0x58(AddScoopToUpInternals&AddPortamentoToDownIntervals) + add.append( NRPN.CVM_NM_CHANGE_AFTER_PEAK, 0x32 );// 0x59(changeAfterPeak) + byte accent = (byte)(0x64 * ve.ID.DEMaccent / 100.0); + add.append( NRPN.CVM_NM_ACCENT, accent );// 0x5a(Accent) + add.append( NRPN.CVM_NM_NOTE_MESSAGE_CONTINUATION, 0x7f );// 0x7f(Note message continuation) + return add; + } + + /// + /// 指定したトラックのデータから,NRPNを作成します + /// + /// + /// + /// + /// + /// + /// + public static VsqNrpn[] generateNRPN( VsqFile vsq, int track, int msPreSend, int clock_start, int clock_end ) { + VsqFile temp = (VsqFile)vsq.Clone(); + removePart( temp, clock_end, vsq.TotalClocks ); + if ( 0 < clock_start ) { + removePart( temp, 0, clock_start ); + } + temp.Master.PreMeasure = 1; + temp.m_premeasure_clocks = temp.getClockFromBarCount( 1 ); + VsqNrpn[] ret = generateNRPN( temp, track, msPreSend ); + temp = null; + return ret; + } + + /// + /// 指定したトラックのデータから,NRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generateNRPN( VsqFile vsq, int track, int msPreSend ) { +#if DEBUG + Console.WriteLine( "GenerateNRPN(VsqTrack,int,int,int,int)" ); +#endif + + List list = new List(); + + int count = vsq.m_tracks[track].getEventCount(); + int note_start = 0; + int note_end = vsq.m_tracks[track].getEventCount() - 1; + for ( int i = 0; i < vsq.m_tracks[track].getEventCount(); i++ ) { + if ( 0 <= vsq.m_tracks[track].getEvent( i ).Clock ) { + note_start = i; + break; + } + note_start = i; + } + for ( int i = vsq.m_tracks[track].getEventCount() - 1; i >= 0; i-- ) { + if ( vsq.m_tracks[track].getEvent( i ).Clock <= vsq.TotalClocks ) { + note_end = i; + break; + } + } + + // 最初の歌手を決める + int singer_event = -1; + for ( int i = note_start; i >= 0; i-- ) { + if ( vsq.m_tracks[track].getEvent( i ).ID.type == VsqIDType.Singer ) { + singer_event = i; + break; + } + } + if ( singer_event >= 0 ) { //見つかった場合 + list.AddRange( generateSingerNRPN( vsq, vsq.m_tracks[track].getEvent( singer_event ), 0 ) ); + } else { //多分ありえないと思うが、歌手が不明の場合。 + throw new ApplicationException( "first singer was not specified" ); + list.Add( new VsqNrpn( 0, (ushort)NRPN.CC_BS_LANGUAGE_TYPE, 0 ) ); + list.Add( new VsqNrpn( 0, (ushort)NRPN.PC_VOICE_TYPE, 0 ) ); + } +#if DEBUG + Console.WriteLine( " note_start,note_end=" + note_start + "," + note_end ); +#endif + for ( int i = note_start; i <= note_end; i++ ) { + byte note_loc = 0x00; + if ( i == note_start ) { + if ( i == note_end ) { + note_loc = 0x03; + } else { + note_loc = 0x01; + } + } else if ( i == note_end ) { + note_loc = 0x02; + } + + if ( vsq.m_tracks[track].getEvent( i ).ID.type == VsqIDType.Anote ) { + list.Add( generateNoteNRPN( vsq, + vsq.m_tracks[track].getEvent( i ), + msPreSend, + note_loc ) ); + list.AddRange( generateVibratoNRPN( vsq, + vsq.m_tracks[track].getEvent( i ), + msPreSend ) ); + } else if ( vsq.m_tracks[track].getEvent( i ).ID.type == VsqIDType.Singer ) { + if ( i > note_start && i != singer_event) { + list.AddRange( generateSingerNRPN( vsq, vsq.m_tracks[track].getEvent( i ), msPreSend ) ); + } + } + } + list.AddRange( generateVoiceChangeParameterNRPN( vsq, track, msPreSend ) ); + list.AddRange( generateExpressionNRPN( vsq, track, msPreSend ) ); + list.AddRange( generatePitchBendSensitivityNRPN( vsq, track, msPreSend ) ); + list.AddRange( generatePitchBendNRPN( vsq, track, msPreSend ) ); + + list.Sort(); + List merged = new List(); + for ( int i = 0; i < list.Count; i++ ) { + merged.AddRange( list[i].expand() ); + } + return merged.ToArray(); + } + + /// + /// 指定したトラックから、PitchBendのNRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generatePitchBendNRPN( VsqFile vsq, int track, int msPreSend ) { + List ret = new List(); + int[] keys = vsq.m_tracks[track].getCurve( "PIT" ).getKeys(); + int count = keys.Length; + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + int start_clock = (int)vsq.getClockFromSec( msPreSend / 1000.0 ) + 1;// 0 < vsq.m_premeasure_clocks ? vsq.m_premeasure_clocks : 0; + VsqNrpn add0 = new VsqNrpn( start_clock - vsq.getPresendClockAt( start_clock, msPreSend ), + (ushort)NRPN.PB_VERSION_AND_DEVICE, + 0x00, + 0x00 ); + add0.append( NRPN.PB_DELAY, delay0, delay1 ); + + ushort start_value = (ushort)(vsq.m_tracks[track].getCurve( "PIT" ).getElement( start_clock ) + 0x2000); + byte start_value0, start_value1; + getMsbAndLsb( start_value, out start_value0, out start_value1 ); + add0.append( NRPN.PB_PITCH_BEND, start_value0, start_value1 ); + ret.Add( add0 ); + + for ( int i = 0; i < keys.Length; i++ ) { + if ( keys[i] > start_clock ) { + ushort value = (ushort)(vsq.m_tracks[track].getCurve( "PIT" ).getElement( keys[i] ) + 0x2000); + byte value0, value1; + getMsbAndLsb( value, out value0, out value1 ); + VsqNrpn add = new VsqNrpn( keys[i] - vsq.getPresendClockAt( keys[i], msPreSend ), + (ushort)NRPN.PB_PITCH_BEND, + value0, + value1 ); + ret.Add( add ); + } + } + return ret.ToArray(); + } + + /// + /// 指定したトラックからPitchBendSensitivityのNRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generatePitchBendSensitivityNRPN( VsqFile vsq, int track, int msPreSend ) { + List ret = new List(); + int[] keys = vsq.m_tracks[track].getCurve( "PBS" ).getKeys(); + int count = keys.Length; + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + int start_clock = (int)vsq.getClockFromSec( msPreSend / 1000.0 ) + 1;// 0 < vsq.m_premeasure_clocks ? vsq.m_premeasure_clocks : 0; + int start_value = vsq.m_tracks[track].getCurve( "PBS" ).getElement( start_clock ); + VsqNrpn add0 = new VsqNrpn( start_clock - vsq.getPresendClockAt( start_clock, msPreSend ), + (ushort)NRPN.CC_PBS_VERSION_AND_DEVICE, + 0x00, + 0x00 ); + add0.append( NRPN.CC_PBS_DELAY, delay0, delay1 ); + add0.append( NRPN.CC_PBS_PITCH_BEND_SENSITIVITY, (byte)start_value, 0x00 ); + ret.Add( add0 ); + for ( int i = 0; i < keys.Length; i++ ) { + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i] - vsq.getPresendClockAt( keys[i], msPreSend ), + (ushort)NRPN.CC_PBS_PITCH_BEND_SENSITIVITY, + (byte)vsq.m_tracks[track].getCurve( "PBS" ).getElement( keys[i] ), + 0x00 ); + ret.Add( add ); + } + } + return ret.ToArray(); + } + + /// + /// 指定した音符イベントから,ビブラート出力用のNRPNを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generateVibratoNRPN( VsqFile vsq, VsqEvent ve, int msPreSend ) { + List ret = new List(); + if ( ve.ID.VibratoHandle != null ){ + int vclock = ve.Clock + ve.ID.VibratoDelay; + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + VsqNrpn add2 = new VsqNrpn( vclock - vsq.getPresendClockAt( vclock, msPreSend ), + (ushort)NRPN.CC_VD_VERSION_AND_DEVICE, + 0x00, + 0x00 ); + add2.append( NRPN.CC_VD_DELAY, delay0, delay1 ); + add2.append( NRPN.CC_VD_VIBRATO_DEPTH, (byte)ve.ID.VibratoHandle.StartDepth ); + add2.append( NRPN.CC_VR_VIBRATO_RATE, (byte)ve.ID.VibratoHandle.StartRate ); + ret.Add( add2 ); + int vlength = ve.Clock + ve.ID.Length - ve.ID.VibratoDelay; + if ( ve.ID.VibratoHandle.RateBP.getCount() > 0 ) { + for ( int i = 0; i < ve.ID.VibratoHandle.RateBP.getCount(); i++ ) { + float percent = ve.ID.VibratoHandle.RateBP.getElement( i ).X; + int cl = vclock + (int)(percent * vlength); + ret.Add( new VsqNrpn( cl, (ushort)NRPN.CC_VR_VIBRATO_RATE, (byte)ve.ID.VibratoHandle.RateBP.getElement( i ).Y ) ); + } + } + if ( ve.ID.VibratoHandle.DepthBP.getCount() > 0 ) { + for ( int i = 0; i < ve.ID.VibratoHandle.DepthBP.getCount(); i++ ) { + float percent = ve.ID.VibratoHandle.DepthBP.getElement( i ).X; + int cl = vclock + (int)(percent * vlength); + ret.Add( new VsqNrpn( cl, (ushort)NRPN.CC_VD_VIBRATO_DEPTH, (byte)ve.ID.VibratoHandle.DepthBP.getElement( i ).Y ) ); + } + } + } + ret.Sort(); + return ret.ToArray(); + } + + /// + /// 指定したトラックから、VoiceChangeParameterのNRPNのリストを作成します + /// + /// + /// + /// + /// + public static VsqNrpn[] generateVoiceChangeParameterNRPN( VsqFile vsq, int track, int msPreSend ) { + int premeasure_clock = vsq.m_premeasure_clocks; + byte delay0, delay1; + getMsbAndLsb( (ushort)msPreSend, out delay0, out delay1 ); + List res = new List(); + int start_clock = (0 < premeasure_clock) ? premeasure_clock : 0; + VsqNrpn ret = new VsqNrpn( start_clock - vsq.getPresendClockAt( start_clock, msPreSend ), + (ushort)NRPN.VCP_VERSION_AND_DEVICE, + 0x00, + 0x00 ); + ret.append( NRPN.VCP_DELAY, delay0, delay1 ); // Voice Change Parameter delay + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x31 ); // BRE + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "BRE" ).getElement( start_clock ) ); + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x32 ); // BRI + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "BRI" ).getElement( start_clock ) ); + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x33 ); // CLE + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "CLE" ).getElement( start_clock ) ); + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x34 ); // POR + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "POR" ).getElement( start_clock ) ); + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x35 ); // OPE + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "OPE" ).getElement( start_clock ) ); + + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, 0x70 ); // GEN + ret.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( "GEN" ).getElement( start_clock ) ); + res.Add( ret ); + + foreach ( string vct in _CURVES ) { + byte lsb = 0x31; + switch ( vct ) { + case "DYN": + case "PBS": + case "PIT": + case "VEL": + continue; + case "BRE": + lsb = 0x31; + break; + case "BRI": + lsb = 0x32; + break; + case "CLE": + lsb = 0x33; + break; + case "POR": + lsb = 0x34; + break; + case "OPE": + lsb = 0x35; + break; + case "GEN": + lsb = 0x70; + break; + } + int[] keys = vsq.m_tracks[track].getCurve( vct ).getKeys(); + for ( int i = 0; i < keys.Length; i++ ) { + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i] - vsq.getPresendClockAt( keys[i], msPreSend ), + (ushort)NRPN.VCP_VOICE_CHANGE_PARAMETER_ID, + lsb ); + add.append( NRPN.VCP_VOICE_CHANGE_PARAMETER, (byte)vsq.m_tracks[track].getCurve( vct ).getElement( keys[i] ) ); + res.Add( add ); + } + } + } + + return res.ToArray(); + } + + private static void getMsbAndLsb( ushort value, out byte msb, out byte lsb ) { + msb = (byte)(value >> 7); + lsb = (byte)(value - (msb << 7)); + } + + /// + /// このインスタンスをファイルに出力します + /// + /// + public void write( string file ) { + write( file, 500 ); + } + + /// + /// このインスタンスをファイルに出力します + /// + /// + /// プリセンドタイム(msec) + public void write( string file, int msPreSend ) { +#if DEBUG + Console.WriteLine( "VsqFile.Write(string)" ); +#endif + int last_clock = 0; + for ( int track = 1; track < m_tracks.Count; track++ ) { + if ( m_tracks[track].getEventCount() > 0 ) { + int index = m_tracks[track].getEventCount() - 1; + VsqEvent last = m_tracks[track].getEvent( index ); + last_clock = Math.Max( last_clock, last.Clock + last.ID.Length ); + } + } + + using ( FileStream fs = new FileStream( file, FileMode.Create ) ) { + long first_position;//チャンクの先頭のファイル位置 + + #region ヘッダ + //チャンクタイプ + fs.Write( _MTHD, 0, 4 ); + //データ長 + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x06 ); + //フォーマット + fs.WriteByte( 0x00 ); + fs.WriteByte( 0x01 ); + //トラック数 + writeUnsignedShort( fs, (ushort)this.m_tracks.Count ); + //時間単位 + fs.WriteByte( 0x01 ); + fs.WriteByte( 0xe0 ); + #endregion + + #region Master Track + //チャンクタイプ + fs.Write( _MTRK, 0, 4 ); + //データ長。とりあえず0を入れておく + fs.Write( new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4 ); + first_position = fs.Position; + //トラック名 + writeFlexibleLengthUnsignedLong( fs, 0 );//デルタタイム + fs.WriteByte( 0xff );//ステータスタイプ + fs.WriteByte( 0x03 );//イベントタイプSequence/Track Name + fs.WriteByte( (byte)_MASTER_TRACK.Length );//トラック名の文字数。これは固定 + fs.Write( _MASTER_TRACK, 0, _MASTER_TRACK.Length ); + + List events = new List(); + foreach ( TimeSigTableEntry entry in m_timesig_table ) { + events.Add( MidiEvent.generateTimeSigEvent( entry.Clock, entry.Numerator, entry.Denominator ) ); + last_clock = Math.Max( last_clock, entry.Clock ); + } + foreach ( TempoTableEntry entry in m_tempo_table ) { + events.Add( MidiEvent.generateTempoChangeEvent( entry.Clock, entry.Tempo ) ); + last_clock = Math.Max( last_clock, entry.Clock ); + } +#if DEBUG + Console.WriteLine( " events.Count=" + events.Count ); +#endif + events.Sort(); + long last = 0; + foreach ( MidiEvent me in events ) { +#if DEBUG + Console.WriteLine( "me.Clock=" + me.Clock ); +#endif + writeFlexibleLengthUnsignedLong( fs, (ulong)(me.Clock - last) ); + me.writeData( fs ); + last = me.Clock; + } + + //WriteFlexibleLengthUnsignedLong( fs, (ulong)(last_clock + 120 - last) ); + writeFlexibleLengthUnsignedLong( fs, 0 ); + fs.WriteByte( 0xff ); + fs.WriteByte( 0x2f );//イベントタイプEnd of Track + fs.WriteByte( 0x00 ); + long pos = fs.Position; + fs.Seek( first_position - 4, SeekOrigin.Begin ); + writeUnsignedInt( fs, (uint)(pos - first_position) ); + fs.Seek( pos, SeekOrigin.Begin ); + #endregion + + #region トラック + VsqFile temp = (VsqFile)this.Clone(); + temp.m_tracks[1].setMaster( (VsqMaster)Master.Clone() ); + temp.m_tracks[1].setMixer( (VsqMixer)Mixer.Clone() ); + printTrack( temp, 1, fs, msPreSend ); + for ( int track = 2; track < m_tracks.Count; track++ ) { + printTrack( this, track, fs, msPreSend ); + } + #endregion + + } + } + + /// + /// メタテキストの行番号から、各行先頭のプレフィクス文字列("DM:0123:"等)を作成します + /// + /// + /// + public static string getLinePrefix( int count ) { + int digits = getHowManyDigits( count ); + int c = (digits - 1) / 4 + 1; + string format = ""; + for ( int i = 0; i < c; i++ ) { + format += "0000"; + } + return "DM:" + count.ToString( format ) + ":"; + } + + /// + /// 数numberの桁数を調べます。(10進数のみ) + /// + /// + /// + private static int getHowManyDigits( int number ) { + int val; + if ( number > 0 ) { + val = number; + } else { + val = -number; + } + int i = 1; + int digits = 1; + while ( true ) { + i++; + digits *= 10; + if ( val < digits ) { + return i - 1; + } + } + } + + /// + /// char[]を書き込む。 + /// + /// + /// + public static void writeCharArray( FileStream fs, char[] item ) { + for ( int i = 0; i < item.Length; i++ ) { + fs.WriteByte( (byte)item[i] ); + } + } + + /// + /// ushort値をビッグエンディアンでfsに書き込みます + /// + /// + public void writeUnsignedShort( FileStream fs, ushort data ) { + byte[] dat = BitConverter.GetBytes( data ); + if ( BitConverter.IsLittleEndian ) { + Array.Reverse( dat ); + } + fs.Write( dat, 0, dat.Length ); + } + + /// + /// uint値をビッグエンディアンでfsに書き込みます + /// + /// + public static void writeUnsignedInt( FileStream fs, uint data ) { + byte[] dat = BitConverter.GetBytes( data ); + if ( BitConverter.IsLittleEndian ) { + Array.Reverse( dat ); + } + fs.Write( dat, 0, dat.Length ); + } + + /// + /// SMFの可変長数値表現を使って、ulongをbyte[]に変換します + /// + /// + public static byte[] getBytesFlexibleLengthUnsignedLong( ulong number ) { + bool[] bits = new bool[64]; + ulong val = 0x1; + bits[0] = (number & val) == val; + for ( int i = 1; i < 64; i++ ) { + val = val << 1; + bits[i] = (number & val) == val; + } + int first = 0; + for ( int i = 63; i >= 0; i-- ) { + if ( bits[i] ) { + first = i; + break; + } + } + // 何バイト必要か? + int bytes = first / 7 + 1; + byte[] ret = new byte[bytes]; + for ( int i = 1; i <= bytes; i++ ) { + uint num = 0; + uint count = 0x80; + for ( int j = (bytes - i + 1) * 7 - 1; j >= (bytes - i + 1) * 7 - 6 - 1; j-- ) { + count = count >> 1; + if ( bits[j] ) { + num += count; + } + } + if ( i != bytes ) { + num += 0x80; + } + ret[i - 1] = (byte)num; + } + return ret; + } + + /// + /// 整数を書き込む。フォーマットはSMFの可変長数値表現。 + /// + /// + /// + public static void writeFlexibleLengthUnsignedLong( Stream fs, ulong number ) { + byte[] bytes = getBytesFlexibleLengthUnsignedLong( number ); + fs.Write( bytes, 0, bytes.Length ); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Common.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/Common.cs new file mode 100644 index 0000000..da580ba --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Common.cs @@ -0,0 +1,149 @@ +/* + * VsqMetaText/Common.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Drawing; + +namespace Boare.Lib.Vsq { + + /// + /// vsqファイルのメタテキストの[Common]セクションに記録される内容を取り扱う + /// + [Serializable] + public class VsqCommon : ICloneable { + public string Version; + public string Name; + public string Color; + public int DynamicsMode; + public int PlayMode; + + public object Clone() { + string[] spl = Color.Split( ",".ToCharArray(), 3 ); + int r = int.Parse( spl[0] ); + int g = int.Parse( spl[1] ); + int b = int.Parse( spl[2] ); + System.Drawing.Color color = System.Drawing.Color.FromArgb( r, g, b ); + VsqCommon res = new VsqCommon( Name, color, DynamicsMode, PlayMode ); + res.Version = Version; + return res; + } + + /// + /// 各パラメータを指定したコンストラクタ + /// + /// トラック名 + /// Color値(意味は不明) + /// DynamicsMode(デフォルトは1) + /// PlayMode(デフォルトは1) + public VsqCommon( string name, Color color, int dynamics_mode, int play_mode ) { + this.Version = "DSB301"; + this.Name = name; + this.Color = color.R + "," + color.G + "," + color.B; + this.DynamicsMode = dynamics_mode; + this.PlayMode = play_mode; + } + + /// + /// MetaTextのテキストファイルからのコンストラクタ + /// + /// 読み込むテキストファイル + /// 読み込んだ最後の行が返される + public VsqCommon( TextMemoryStream sr, ref string last_line ) { + Version = ""; + Name = ""; + Color = "0,0,0"; + DynamicsMode = 0; + PlayMode = 0; + last_line = sr.readLine(); + string[] spl; + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Version": + this.Version = spl[1]; + break; + case "Name": + this.Name = spl[1]; + break; + case "Color": + this.Color = spl[1]; + break; + case "DynamicsMode": + this.DynamicsMode = int.Parse( spl[1] ); + break; + case "PlayMode": + this.PlayMode = int.Parse( spl[1] ); + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line = sr.readLine(); + } + } + + /// + /// インスタンスの内容をテキストファイルに出力します + /// + /// 出力先 + public void write( TextMemoryStream sw ) { + sw.writeLine( "[Common]" ); + sw.writeLine( "Version=" + Version ); + sw.writeLine( "Name=" + Name ); + sw.writeLine( "Color=" + Color ); + sw.writeLine( "DynamicsMode=" + DynamicsMode ); + sw.writeLine( "PlayMode=" + PlayMode ); + } + + /// + /// VsqCommon構造体を構築するテストを行います + /// + /// テストに成功すればtrue、そうでなければfalse + public static bool test() { + string fpath = Path.GetTempFileName(); + StreamWriter sw = new StreamWriter( fpath, false, Encoding.Unicode ); + sw.WriteLine( "Version=DSB301" ); + sw.WriteLine( "Name=Voice1" ); + sw.WriteLine( "Color=181,162,123" ); + sw.WriteLine( "DynamicsMode=1" ); + sw.WriteLine( "PlayMode=1" ); + sw.WriteLine( "[Master]" ); + sw.Close(); + + VsqCommon vsqCommon; + string last_line = ""; + using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { + vsqCommon = new VsqCommon( sr, ref last_line ); + } + + bool result; + if ( vsqCommon.Version == "DSB301" && + vsqCommon.Name == "Voice1" && + vsqCommon.Color == "181,162,123" && + vsqCommon.DynamicsMode == 1 && + vsqCommon.PlayMode == 1 && + last_line == "[Master]" ) { + result = true; + } else { + result = false; + } + + File.Delete( fpath ); + return result; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Common.java b/trunk/Boare.Lib.Vsq/VsqMetaText/Common.java new file mode 100644 index 0000000..43a924b --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Common.java @@ -0,0 +1,151 @@ +/* + * VsqMetaText/Common.cs + * Copyright (c) 2008 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +/*using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Drawing;*/ + +package com.boare.vsq; + +/// +/// vsqt@C̃^eLXg[Common]ZNVɋL^e舵 +/// +public class VsqCommon implements Cloneable { + public String Version; + public String Name; + public String Color; + public int DynamicsMode; + public int PlayMode; + + public Object clone() { + String[] spl = Color.Split( ",".ToCharArray(), 3 ); + int r = Integer.parseInt( spl[0] ); + int g = Integer.parseInt( spl[1] ); + int b = Integer.parseInt( spl[2] ); + System.Drawing.Color color = System.Drawing.Color.FromArgb( r, g, b ); + VsqCommon res = new VsqCommon( Name, color, DynamicsMode, PlayMode ); + res.Version = Version; + return res; + } + + + /// + /// ep[^w肵RXgN^ + /// + /// gbN + /// ColorliӖ͕sj + /// DynamicsModeiftHg1j + /// PlayModeiftHg1j + public VsqCommon( string name, Color color, int dynamics_mode, int play_mode ) { + this.Version = "DSB301"; + this.Name = name; + this.Color = color.R + "," + color.G + "," + color.B; + this.DynamicsMode = dynamics_mode; + this.PlayMode = play_mode; + } + + + /// + /// MetaText̃eLXgt@C̃RXgN^ + /// + /// ǂݍރeLXgt@C + /// ǂݍ񂾍Ō̍sԂ + public VsqCommon( TextMemoryStream sr, ref string last_line ) { + Version = ""; + Name = ""; + Color = "0,0,0"; + DynamicsMode = 0; + PlayMode = 0; + last_line = sr.ReadLine(); + string[] spl; + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Version": + this.Version = spl[1]; + break; + case "Name": + this.Name = spl[1]; + break; + case "Color": + this.Color = spl[1]; + break; + case "DynamicsMode": + this.DynamicsMode = Integer.parseInt( spl[1] ); + break; + case "PlayMode": + this.PlayMode = Integer.parseInt( spl[1] ); + break; + } + if ( sr.Peek() < 0 ) { + break; + } + last_line = sr.ReadLine(); + } + } + + + /// + /// CX^X̓eeLXgt@Cɏo͂܂ + /// + /// o͐ + public void write( TextMemoryStream sw ) { + sw.WriteLine( "[Common]" ); + sw.WriteLine( "Version=" + Version ); + sw.WriteLine( "Name=" + Name ); + sw.WriteLine( "Color=" + Color ); + sw.WriteLine( "DynamicsMode=" + DynamicsMode ); + sw.WriteLine( "PlayMode=" + PlayMode ); + } + + + /// + /// VsqCommon\̂\zeXgs܂ + /// + /// eXgɐtrueAłȂfalse + public static bool test() { + string fpath = Path.GetTempFileName(); + StreamWriter sw = new StreamWriter( fpath, false, Encoding.Unicode ); + sw.WriteLine( "Version=DSB301" ); + sw.WriteLine( "Name=Voice1" ); + sw.WriteLine( "Color=181,162,123" ); + sw.WriteLine( "DynamicsMode=1" ); + sw.WriteLine( "PlayMode=1" ); + sw.WriteLine( "[Master]" ); + sw.Close(); + + VsqCommon vsqCommon; + string last_line = ""; + using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { + vsqCommon = new VsqCommon( sr, ref last_line ); + } + + bool result; + if ( vsqCommon.Version == "DSB301" && + vsqCommon.Name == "Voice1" && + vsqCommon.Color == "181,162,123" && + vsqCommon.DynamicsMode == 1 && + vsqCommon.PlayMode == 1 && + last_line == "[Master]" ) { + result = true; + } else { + result = false; + } + + File.Delete( fpath ); + return result; + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Handle.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/Handle.cs new file mode 100644 index 0000000..f7c0f04 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Handle.cs @@ -0,0 +1,448 @@ +/* + * VsqMetaText/Handle.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.Vsq { + + [Serializable] + public class IconHandle : ICloneable { + public string Caption; + public string IconID; + public string IDS; + public int Index; + public int Length; + public int Original; + public int Program; + public int Language; + + public object Clone() { + IconHandle ret = new IconHandle(); + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Language = Language; + ret.Length = Length; + ret.Original = Original; + ret.Program = Program; + return ret; + } + + public VsqHandle castToVsqHandle() { + VsqHandle ret = new VsqHandle(); + ret.m_type = VsqHandleType.Singer; + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Language = Language; + ret.Length = Length; + ret.Program = Program; + return ret; + } + } + + [Serializable] + public class LyricHandle : ICloneable { + public Lyric L0; + public int Index; + + internal LyricHandle() { + } + + /// + /// type = Lyric用のhandleのコンストラクタ + /// + /// 歌詞 + /// 発音記号 + public LyricHandle( string phrase, string phonetic_symbol ) { + L0 = new Lyric( phrase, phonetic_symbol ); + } + + public object Clone() { + LyricHandle ret = new LyricHandle(); + ret.Index = Index; + ret.L0 = (Lyric)L0.Clone(); + return ret; + } + + public VsqHandle castToVsqHandle() { + VsqHandle ret = new VsqHandle(); + ret.m_type = VsqHandleType.Lyric; + ret.L0 = (Lyric)L0.Clone(); + ret.Index = Index; + return ret; + } + } + + + [Serializable] + public class VibratoHandle : ICloneable { + public int StartDepth; + public VibratoBPList DepthBP; + public int StartRate; + public VibratoBPList RateBP; + public int Index; + public string IconID; + public string IDS; + public int Original; + public string Caption; + public int Length; + + public VibratoHandle(){ + RateBP = new VibratoBPList(); + DepthBP = new VibratoBPList(); + } + + public object Clone() { + VibratoHandle result = new VibratoHandle(); + result.Index = Index; + result.IconID = IconID; + result.IDS = this.IDS; + result.Original = this.Original; + result.Caption = this.Caption; + result.Length = this.Length; + result.StartDepth = this.StartDepth; + result.DepthBP = (VibratoBPList)DepthBP.Clone(); + result.StartRate = this.StartRate; + result.RateBP = (VibratoBPList)RateBP.Clone(); + return result; + } + + public VsqHandle castToVsqHandle() { + VsqHandle ret = new VsqHandle(); + ret.m_type = VsqHandleType.Vibrato; + ret.Index = Index; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Original = Original; + ret.Caption = Caption; + ret.Length = Length; + ret.StartDepth = StartDepth; + ret.StartRate = StartRate; + ret.DepthBP = (VibratoBPList)DepthBP.Clone(); + ret.RateBP = (VibratoBPList)RateBP.Clone(); + return ret; + } + } + + /// + /// ハンドルを取り扱います。ハンドルにはLyricHandle、VibratoHandleおよびIconHandleがある + /// + [Serializable] + public class VsqHandle { + public VsqHandleType m_type; + public int Index; + public string IconID; + public string IDS; + public Lyric L0; + public int Original; + public string Caption; + public int Length; + public int StartDepth; + public VibratoBPList DepthBP; + public int StartRate; + public VibratoBPList RateBP; + public int Language; + public int Program; + + public LyricHandle castToLyricHandle() { + LyricHandle ret = new LyricHandle(); + ret.L0 = (Lyric)L0; + ret.Index = Index; + return ret; + } + + public VibratoHandle castToVibratoHandle() { + VibratoHandle ret = new VibratoHandle(); + ret.Index = Index; + ret.Caption = Caption; + ret.DepthBP = (VibratoBPList)DepthBP.Clone(); + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Length = Length; + ret.Original = Original; + ret.RateBP = (VibratoBPList)RateBP.Clone(); + ret.StartDepth = StartDepth; + ret.StartRate = StartRate; + return ret; + } + + public IconHandle castToIconHandle() { + IconHandle ret = new IconHandle(); + ret.Index = Index; + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Language = Language; + ret.Length = Length; + ret.Original = Original; + ret.Program = Program; + return ret; + } + + internal VsqHandle() { + } + + /// + /// インスタンスをストリームに書き込みます。 + /// encode=trueの場合、2バイト文字をエンコードして出力します。 + /// + /// 書き込み対象 + /// 2バイト文字をエンコードするか否かを指定するフラグ + public void write( TextMemoryStream sw, bool encode ) { + sw.writeLine( this.ToString( encode ) ); + } + + /// + /// FileStreamから読み込みながらコンストラクト + /// + /// 読み込み対象 + public VsqHandle( TextMemoryStream sr, int value, ref string last_line ) { + this.Index = value; + string[] spl; + string[] spl2; + + // default値で梅 + m_type = VsqHandleType.Vibrato; + IconID = ""; + IDS = "normal"; + L0 = new Lyric( "" ); + Original = 0; + Caption = ""; + Length = 0; + StartDepth = 0; + DepthBP = null; + int depth_bp_num = 0; + StartRate = 0; + RateBP = null; + int rate_bp_num = 0; + Language = 0; + Program = 0; + + string tmpDepthBPX = ""; + string tmpDepthBPY = ""; + string tmpRateBPX = ""; + string tmpRateBPY = ""; + + // "["にぶち当たるまで読込む + last_line = sr.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Language": + Language = int.Parse( spl[1] ); + break; + case "Program": + Program = int.Parse( spl[1] ); + break; + case "IconID": + IconID = spl[1]; + break; + case "IDS": + IDS = spl[1]; + break; + case "Original": + Original = int.Parse( spl[1] ); + break; + case "Caption": + Caption = spl[1]; + for ( int i = 2; i < spl.Length; i++ ) { + Caption += "=" + spl[i]; + } + break; + case "Length": + Length = int.Parse( spl[1] ); + break; + case "StartDepth": + StartDepth = int.Parse( spl[1] ); + break; + case "DepthBPNum": + depth_bp_num = int.Parse( spl[1] ); + break; + case "DepthBPX": + tmpDepthBPX = spl[1]; + break; + case "DepthBPY": + tmpDepthBPY = spl[1]; + break; + case "StartRate": + StartRate = int.Parse( spl[1] ); + break; + case "RateBPNum": + rate_bp_num = int.Parse( spl[1] ); + break; + case "RateBPX": + tmpRateBPX = spl[1]; + break; + case "RateBPY": + tmpRateBPY = spl[1]; + break; + case "L0": + m_type = VsqHandleType.Lyric; + L0 = new Lyric( spl[1] ); + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line = sr.readLine(); + } + if ( IDS != "normal" ) { + m_type = VsqHandleType.Singer; + } else if ( IconID != "" ) { + m_type = VsqHandleType.Vibrato; + } else { + m_type = VsqHandleType.Lyric; + } + + // RateBPX, RateBPYの設定 + if ( m_type == VsqHandleType.Vibrato ) { + if ( rate_bp_num > 0 ) { + float[] rate_bp_x = new float[rate_bp_num]; + spl2 = tmpRateBPX.Split( new char[] { ',' } ); + for ( int i = 0; i < rate_bp_num; i++ ) { + rate_bp_x[i] = float.Parse( spl2[i] ); + } + + int[] rate_bp_y = new int[rate_bp_num]; + spl2 = tmpRateBPY.Split( new char[] { ',' } ); + for ( int i = 0; i < rate_bp_num; i++ ) { + rate_bp_y[i] = int.Parse( spl2[i] ); + } + RateBP = new VibratoBPList( rate_bp_x, rate_bp_y ); + } else { + //m_rate_bp_x = null; + //m_rate_bp_y = null; + RateBP = new VibratoBPList(); + } + + // DepthBPX, DepthBPYの設定 + if ( depth_bp_num > 0 ) { + float[] depth_bp_x = new float[depth_bp_num]; + spl2 = tmpDepthBPX.Split( new char[] { ',' } ); + for ( int i = 0; i < depth_bp_num; i++ ) { + depth_bp_x[i] = float.Parse( spl2[i] ); + } + + int[] depth_bp_y = new int[depth_bp_num]; + spl2 = tmpDepthBPY.Split( new char[] { ',' } ); + for ( int i = 0; i < depth_bp_num; i++ ) { + depth_bp_y[i] = int.Parse( spl2[i] ); + } + DepthBP = new VibratoBPList( depth_bp_x, depth_bp_y ); + } else { + DepthBP = new VibratoBPList(); + //m_depth_bp_x = null; + //m_depth_bp_y = null; + } + } else { + DepthBP = new VibratoBPList(); + RateBP = new VibratoBPList(); + } + } + + /// + /// ハンドル指定子(例えば"h#0123"という文字列)からハンドル番号を取得します + /// + /// ハンドル指定子 + /// ハンドル番号 + public static int HandleIndexFromString( string _string ) { + string[] spl = _string.Split( new char[] { '#' } ); + return int.Parse( spl[1] ); + } + + /// + /// インスタンスをテキストファイルに出力します + /// + /// 出力先 + public void Print( StreamWriter sw ) { + string result = this.ToString(); + sw.WriteLine( result ); + } + + /// + /// インスタンスをコンソール画面に出力します + /// + private void Print() { + string result = this.ToString(); + Console.WriteLine( result ); + } + + /// + /// インスタンスを文字列に変換します + /// + /// 2バイト文字をエンコードするか否かを指定するフラグ + /// インスタンスを変換した文字列 + public string ToString( bool encode ) { + string result = ""; + result += "[h#" + Index.ToString( "0000" ) + "]"; + switch ( m_type ) { + case VsqHandleType.Lyric: + result += Environment.NewLine + "L0=" + L0.ToString( encode ); + break; + case VsqHandleType.Vibrato: + result += Environment.NewLine + "IconID=" + IconID + Environment.NewLine; + result += "IDS=" + IDS + Environment.NewLine; + result += "Original=" + Original + Environment.NewLine; + result += "Caption=" + Caption + Environment.NewLine; + result += "Length=" + Length + Environment.NewLine; + result += "StartDepth=" + StartDepth + Environment.NewLine; + result += "DepthBPNum=" + DepthBP.getCount() + Environment.NewLine; + if ( DepthBP.getCount() > 0 ) { + result += "DepthBPX=" + DepthBP.getElement( 0 ).X.ToString( "0.000000" ); + for ( int i = 1; i < DepthBP.getCount(); i++ ) { + result += "," + DepthBP.getElement( i ).X.ToString( "0.000000" ); + } + result += Environment.NewLine + "DepthBPY=" + DepthBP.getElement( 0 ).Y; + for ( int i = 1; i < DepthBP.getCount(); i++ ) { + result += "," + DepthBP.getElement( i ).Y; + } + result += Environment.NewLine; + } + result += "StartRate=" + StartRate + Environment.NewLine; + result += "RateBPNum=" + RateBP.getCount(); + if ( RateBP.getCount() > 0 ) { + result += Environment.NewLine + "RateBPX=" + RateBP.getElement( 0 ).X.ToString( "0.000000" ); + for ( int i = 1; i < RateBP.getCount(); i++ ) { + result += "," + RateBP.getElement( i ).X.ToString( "0.000000" ); + } + result += Environment.NewLine + "RateBPY=" + RateBP.getElement( 0 ).Y; + for ( int i = 1; i < RateBP.getCount(); i++ ) { + result += "," + RateBP.getElement( i ).Y; + } + } + break; + case VsqHandleType.Singer: + result += Environment.NewLine + "IconID=" + IconID + Environment.NewLine; + result += "IDS=" + IDS + Environment.NewLine; + result += "Original=" + Original + Environment.NewLine; + result += "Caption=" + Caption + Environment.NewLine; + result += "Length=" + Length + Environment.NewLine; + result += "Language=" + Language + Environment.NewLine; + result += "Program=" + Program; + break; + default: + break; + } + return result; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/ID.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/ID.cs new file mode 100644 index 0000000..700395c --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/ID.cs @@ -0,0 +1,272 @@ +/* + * VsqMetaText/ID.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// メタテキストに埋め込まれるIDを表すクラス。 + /// + [Serializable] + public class VsqID : ICloneable { + public int value; + public VsqIDType type; + public int IconHandle_index; + public IconHandle IconHandle; + public int Length; + public int Note; + public int Dynamics; + public int PMBendDepth; + public int PMBendLength; + public int PMbPortamentoUse; + public int DEMdecGainRate; + public int DEMaccent; + public int LyricHandle_index; + public LyricHandle LyricHandle; + public int VibratoHandle_index; + public VibratoHandle VibratoHandle; + public int VibratoDelay; + + public static VsqID EOS = new VsqID( -1 ); + + /// + /// このインスタンスの簡易コピーを取得します。 + /// + /// このインスタンスの簡易コピー + public object Clone() { + VsqID result = new VsqID( this.value ); + result.type = this.type; + if ( this.IconHandle != null ) { + result.IconHandle = (IconHandle)this.IconHandle.Clone(); + } + result.Length = this.Length; + result.Note = this.Note; + result.Dynamics = this.Dynamics; + result.PMBendDepth = this.PMBendDepth; + result.PMBendLength = this.PMBendLength; + result.PMbPortamentoUse = this.PMbPortamentoUse; + result.DEMdecGainRate = this.DEMdecGainRate; + result.DEMaccent = this.DEMaccent; + if ( this.LyricHandle != null ) { + result.LyricHandle = (LyricHandle)this.LyricHandle.Clone(); + } + if ( this.VibratoHandle != null ) { + result.VibratoHandle = (VibratoHandle)this.VibratoHandle.Clone(); + } + result.VibratoDelay = this.VibratoDelay; + return result; + } + + + /// + /// IDの番号(ID#****の****)を指定したコンストラクタ。 + /// + /// IDの番号 + public VsqID( int a_value ) { + value = a_value; + } + + + /// + /// テキストファイルからのコンストラクタ + /// + /// 読み込み対象 + /// + /// 読み込んだ最後の行が返されます + public VsqID( TextMemoryStream sr, int value, ref string last_line ) { + string[] spl; + this.value = value; + this.type = VsqIDType.Unknown; + this.IconHandle_index = -2; + this.LyricHandle_index = -1; + this.VibratoHandle_index = -1; + this.Length = 0; + this.Note = 0; + this.Dynamics = 0; + this.PMBendDepth = 0; + this.PMBendLength = 0; + this.PMbPortamentoUse = 0; + this.DEMdecGainRate = 0; + this.DEMaccent = 0; + //this.LyricHandle_index = -2; + //this.VibratoHandle_index = -2; + this.VibratoDelay = 0; + last_line = sr.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Type": + if ( spl[1] == "Anote" ) { + type = VsqIDType.Anote; + } else if ( spl[1] == "Singer" ) { + type = VsqIDType.Singer; + } else { + type = VsqIDType.Unknown; + } + break; + case "Length": + this.Length = int.Parse( spl[1] ); + break; + case "Note#": + this.Note = int.Parse( spl[1] ); + break; + case "Dynamics": + this.Dynamics = int.Parse( spl[1] ); + break; + case "PMBendDepth": + this.PMBendDepth = int.Parse( spl[1] ); + break; + case "PMBendLength": + this.PMBendLength = int.Parse( spl[1] ); + break; + case "DEMdecGainRate": + this.DEMdecGainRate = int.Parse( spl[1] ); + break; + case "DEMaccent": + this.DEMaccent = int.Parse( spl[1] ); + break; + case "LyricHandle": + this.LyricHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "IconHandle": + this.IconHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "VibratoHandle": + this.VibratoHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "VibratoDelay": + this.VibratoDelay = int.Parse( spl[1] ); + break; + case "PMbPortamentoUse": + PMbPortamentoUse = int.Parse( spl[1] ); + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line = sr.readLine(); + } + } + + + public override string ToString() { + string ret = "{Type=" + type; + switch ( type ) { + case VsqIDType.Anote: + ret += ", Length=" + Length; + ret += ", Note#=" + Note; + ret += ", Dynamics=" + Dynamics; + ret += ", PMBendDepth=" + PMBendDepth ; + ret += ", PMBendLength=" + PMBendLength ; + ret += ", PMbPortamentoUse=" + PMbPortamentoUse ; + ret += ", DEMdecGainRate=" + DEMdecGainRate ; + ret += ", DEMaccent=" + DEMaccent ; + if ( LyricHandle != null ) { + ret += ", LyricHandle=h#" + LyricHandle_index.ToString( "0000" ) ; + } + if ( VibratoHandle != null ) { + ret += ", VibratoHandle=h#" + VibratoHandle_index.ToString( "0000" ); + ret += ", VibratoDelay=" + VibratoDelay ; + } + break; + case VsqIDType.Singer: + ret += ", IconHandle=h#" + IconHandle_index.ToString( "0000" ); + break; + } + ret += "}"; + return ret; + } + + + /// + /// インスタンスをテキストファイルに出力します + /// + /// 出力先 + public void write( TextMemoryStream sw ) { + sw.writeLine( "[ID#" + value.ToString( "0000" ) + "]" ); + sw.writeLine( "Type=" + type ); + switch( type ){ + case VsqIDType.Anote: + sw.writeLine( "Length=" + Length ); + sw.writeLine( "Note#=" + Note ); + sw.writeLine( "Dynamics=" + Dynamics ); + sw.writeLine( "PMBendDepth=" + PMBendDepth ); + sw.writeLine( "PMBendLength=" + PMBendLength ); + sw.writeLine( "PMbPortamentoUse=" + PMbPortamentoUse ); + sw.writeLine( "DEMdecGainRate=" + DEMdecGainRate ); + sw.writeLine( "DEMaccent=" + DEMaccent ); + if ( LyricHandle != null ) { + sw.writeLine( "LyricHandle=h#" + LyricHandle_index.ToString( "0000" ) ); + } + if ( VibratoHandle != null ) { + sw.writeLine( "VibratoHandle=h#" + VibratoHandle_index.ToString( "0000" ) ); + sw.writeLine( "VibratoDelay=" + VibratoDelay ); + } + break; + case VsqIDType.Singer: + sw.writeLine( "IconHandle=h#" + IconHandle_index.ToString( "0000" ) ); + break; + } + } + + + /// + /// VsqIDを構築するテストを行います。 + /// + /// テストに成功すればtrue、そうでなければfalseを返します + public static bool test() { + string fpath = Path.GetTempFileName(); + using ( StreamWriter sw = new StreamWriter( fpath, false, Encoding.Unicode ) ) { + sw.WriteLine( "Type=Anote" ); + sw.WriteLine( "Length=320" ); + sw.WriteLine( "Note#=67" ); + sw.WriteLine( "Dynamics=64" ); + sw.WriteLine( "PMBendDepth=8" ); + sw.WriteLine( "PMBendLength=1" ); + sw.WriteLine( "PMbPortamentoUse=1" ); + sw.WriteLine( "DEMdecGainRate=50" ); + sw.WriteLine( "DEMaccent=50" ); + sw.WriteLine( "LyricHandle=h#0111" ); + sw.WriteLine( "[ID#0104]" ); + } + + string last_line = ""; + bool result; + using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { + VsqID vsqID = new VsqID( sr, 103, ref last_line ); + if ( vsqID.type == VsqIDType.Anote && + vsqID.Length == 320 && + vsqID.Note == 67 && + vsqID.Dynamics == 64 && + vsqID.PMBendDepth == 8 && + vsqID.PMBendLength == 1 && + vsqID.PMbPortamentoUse == 1 && + vsqID.DEMdecGainRate == 50 && + vsqID.DEMaccent == 50 && + vsqID.LyricHandle_index == 111 && + last_line == "[ID#0104]" ) { + result = true; + } else { + result = false; + } + } + File.Delete( fpath ); + return result; + } + + } +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Lyric.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/Lyric.cs new file mode 100644 index 0000000..5c72a74 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Lyric.cs @@ -0,0 +1,210 @@ +/* + * VsqMetaText/Lyric.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Windows.Forms; + +using bocoree; + +namespace Boare.Lib.Vsq { + + /// + /// VsqHandleに格納される歌詞の情報を扱うクラス。 + /// + [Serializable] + public class Lyric { + /// + /// この歌詞のフレーズ + /// + public string Phrase; + private string[] m_phonetic_symbol; + public float UnknownFloat; + private int[] m_consonant_adjustment; + public bool PhoneticSymbolProtected; + + public int[] getConsonantAdjustment() { + return m_consonant_adjustment; + } + + /// + /// このオブジェクトの簡易コピーを取得します。 + /// + /// このインスタンスの簡易コピー + public Lyric Clone() { + Lyric result = new Lyric(); + result.Phrase = this.Phrase; + result.m_phonetic_symbol = (string[])this.m_phonetic_symbol.Clone(); + result.UnknownFloat = this.UnknownFloat; + result.m_consonant_adjustment = (int[])this.m_consonant_adjustment.Clone(); + result.PhoneticSymbolProtected = PhoneticSymbolProtected; + return result; + } + + /// + /// 歌詞、発音記号を指定したコンストラクタ + /// + /// 歌詞 + /// 発音記号 + public Lyric( string phrase, string phonetic_symbol ) { + Phrase = phrase; + setPhoneticSymbol( phonetic_symbol ); + UnknownFloat = 0.000000f; + } + + private Lyric() { + } + + /// + /// この歌詞の発音記号を取得します。 + /// + public string getPhoneticSymbol() { + string ret = m_phonetic_symbol[0]; + for ( int i = 1; i < m_phonetic_symbol.Length; i++ ) { + ret += " " + m_phonetic_symbol[i]; + } + return ret; + } + + /// + /// この歌詞の発音記号を設定します。 + /// + public void setPhoneticSymbol( string value ) { + string s = value.Replace( " ", " " ); + m_phonetic_symbol = s.Split( " ".ToCharArray(), 16 ); + for ( int i = 0; i < m_phonetic_symbol.Length; i++ ) { + m_phonetic_symbol[i] = m_phonetic_symbol[i].Replace( @"\\", @"\" ); + } + m_consonant_adjustment = new int[m_phonetic_symbol.Length]; + for ( int i = 0; i < m_phonetic_symbol.Length; i++ ) { + if ( VsqPhoneticSymbol.isConsonant( m_phonetic_symbol[i] ) ) { + m_consonant_adjustment[i] = 64; + } else { + m_consonant_adjustment[i] = 0; + } + } + } + + public string[] getPhoneticSymbolList() { + string[] ret = new string[m_phonetic_symbol.Length]; + for ( int i = 0; i < m_phonetic_symbol.Length; i++ ) { + ret[i] = m_phonetic_symbol[i]; + } + return ret; + } + + /// + /// 文字列からのコンストラクタ + /// + /// 生成元の文字列 + public Lyric( string _line ) { + byte[] b = new byte[_line.Length]; + for ( int i = 0; i < _line.Length; i++ ) { + b[i] = (byte)_line[i]; + } + string s = cp932.convert( b ); + string[] spl = s.Split( new char[] { ',' } ); + int c_length = spl.Length - 3; + if ( spl.Length < 4 ) { + Phrase = "a"; + setPhoneticSymbol( "a" ); + UnknownFloat = 0.0f; + PhoneticSymbolProtected = false; + } else { + Phrase = spl[0]; + if ( Phrase.StartsWith( "\"" ) ) { + Phrase = Phrase.Substring( 1 ); + } + if ( Phrase.EndsWith( "\"" ) ) { + Phrase = Phrase.Substring( 0, Phrase.Length - 1 ); + } + string symbols = spl[1]; + if ( symbols.StartsWith( "\"" ) ) { + symbols = symbols.Substring( 1 ); + } + if ( symbols.EndsWith( "\"" ) ) { + symbols = symbols.Substring( 0, symbols.Length - 1 ); + } + setPhoneticSymbol( symbols ); + UnknownFloat = float.Parse( spl[2] ); + PhoneticSymbolProtected = (spl[spl.Length - 1] == "0") ? false : true; + } + } + + /// + /// 与えられた文字列の中の2バイト文字を\x**の形式にエンコードします。 + /// + /// エンコード対象 + /// エンコードした文字列 + public static char[] encode( string item ) { + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] bytea = cp932.convert( item );// sjis.GetBytes( item ); + string result = ""; + for ( int i = 0; i < bytea.Length; i++ ) { + if ( isprint( (char)bytea[i] ) ) { + result += (char)bytea[i]; + } else { + result += "\\x" + Convert.ToString( bytea[i], 16 ); + } + } + char[] res = result.ToCharArray(); + return res; + } + + /// + /// このインスタンスを文字列に変換します + /// + /// 2バイト文字をエンコードするか否かを指定するフラグ + /// 変換後の文字列 + public string ToString( bool a_encode ) { + string result; + if ( a_encode ) { + string njp = new string( encode( this.Phrase ) ); + result = "\"" + njp + "\",\"" + this.getPhoneticSymbol() + "\"," + UnknownFloat.ToString( "0.000000" ); + } else { + result = "\""; + byte[] dat = cp932.convert( this.Phrase ); + for ( int i = 0; i < dat.Length; i++ ) { + result += (char)dat[i]; + } + result += "\",\"" + this.getPhoneticSymbol() + "\"," + UnknownFloat.ToString( "0.000000" ); + result = result.Replace( @"\\", @"\" ); + } + for ( int i = 0; i < m_consonant_adjustment.Length; i++ ) { + result += "," + m_consonant_adjustment[i]; + } + if ( PhoneticSymbolProtected ) { + result += ",1"; + } else { + result += ",0"; + } + return result; + } + + /// + /// 文字がプリント出力可能かどうかを判定します + /// + /// + /// + private static bool isprint( char ch ) { + if ( 32 <= (int)ch && (int)ch <= 126 ) { + return true; + } else { + return false; + } + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Master.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/Master.cs new file mode 100644 index 0000000..e0aaf1f --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Master.cs @@ -0,0 +1,100 @@ +/* + * VsqMetaText/Master.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// vsqファイルのメタテキストの[Master]に記録される内容を取り扱う + /// + [Serializable] + public class VsqMaster : ICloneable { + public int PreMeasure; + + public object Clone() { + VsqMaster res = new VsqMaster( PreMeasure ); + return res; + } + + /// + /// プリメジャー値を指定したコンストラクタ + /// + /// + public VsqMaster( int pre_measure ) { + this.PreMeasure = pre_measure; + } + + /// + /// テキストファイルからのコンストラクタ + /// + /// 読み込み元 + /// 最後に読み込んだ行が返されます + public VsqMaster( TextMemoryStream sr, ref string last_line ) { + PreMeasure = 0; + string[] spl; + last_line = sr.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "PreMeasure": + this.PreMeasure = int.Parse( spl[1] ); + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line = sr.readLine(); + } + } + + /// + /// インスタンスの内容をテキストファイルに出力します + /// + /// 出力先 + public void write( TextMemoryStream sw ) { + sw.writeLine( "[Master]" ); + sw.writeLine( "PreMeasure=" + PreMeasure ); + } + + /// + /// VsqMasterのインスタンスを構築するテストを行います + /// + /// テストに成功すればtrue、そうでなければfalseを返します + public static bool test() { + string fpath = Path.GetTempFileName(); + using ( StreamWriter sw = new StreamWriter( fpath, false, Encoding.Unicode ) ) { + sw.WriteLine( "PreMeasure=2" ); + sw.WriteLine( "[Mixer]" ); + } + + bool result; + using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { + string last_line = ""; + VsqMaster vsqMaster = new VsqMaster( sr, ref last_line ); + if ( vsqMaster.PreMeasure == 2 && + last_line == "[Mixer]" ) { + result = true; + } else { + result = false; + } + } + File.Delete( fpath ); + return result; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/Mixer.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/Mixer.cs new file mode 100644 index 0000000..827e959 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/Mixer.cs @@ -0,0 +1,266 @@ +/* + * VsqMetaText/Mixer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// vsqファイルのメタテキストの[Mixer]セクションに記録される内容を取り扱う + /// + [Serializable] + public class VsqMixer : ICloneable { + public int MasterFeder; + public int MasterPanpot; + public int MasterMute; + public int OutputMode; + + /// + /// vsqファイルの各トラックのfader, panpot, muteおよびoutputmode値を保持します + /// + public List Slave = new List(); + + public object Clone() { + VsqMixer res = new VsqMixer( MasterFeder, MasterPanpot, MasterMute, OutputMode ); + res.Slave = new List(); + foreach ( VsqMixerEntry item in Slave ) { + res.Slave.Add( (VsqMixerEntry)item.Clone() ); + } + return res; + } + + /// + /// 各パラメータを指定したコンストラクタ + /// + /// MasterFader値 + /// MasterPanpot値 + /// MasterMute値 + /// OutputMode値 + public VsqMixer( int master_fader, int master_panpot, int master_mute, int output_mode ) { + this.MasterFeder = master_fader; + this.MasterMute = master_mute; + this.MasterPanpot = master_panpot; + this.OutputMode = output_mode; + Slave = new List(); + } + + /// + /// テキストファイルからのコンストラクタ + /// + /// 読み込み対象 + /// 最後に読み込んだ行が返されます + public VsqMixer( TextMemoryStream sr, ref string last_line ) { + MasterFeder = 0; + MasterPanpot = 0; + MasterMute = 0; + OutputMode = 0; + //Tracks = 1; + int tracks = 0; + string[] spl; + string buffer = ""; + last_line = sr.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "MasterFeder": + MasterFeder = int.Parse( spl[1] ); + break; + case "MasterPanpot": + MasterPanpot = int.Parse( spl[1] ); + break; + case "MasterMute": + MasterMute = int.Parse( spl[1] ); + break; + case "OutputMode": + OutputMode = int.Parse( spl[1] ); + break; + case "Tracks": + tracks = int.Parse( spl[1] ); + break; + default: + if ( spl[0].StartsWith( "Feder" ) || + spl[0].StartsWith( "Panpot" ) || + spl[0].StartsWith( "Mute" ) || + spl[0].StartsWith( "Solo" ) ) { + buffer += spl[0] + "=" + spl[1] + Environment.NewLine; + } + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line = sr.readLine(); + } + + Slave = new List(); + for ( int i = 0; i < tracks; i++ ) { + Slave.Add( new VsqMixerEntry( 0, 0, 0, 0 ) ); + } + spl = buffer.Split( new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries ); + string[] spl2; + for ( int i = 0; i < spl.Length; i++ ) { + string ind = ""; + int index; + spl2 = spl[i].Split( new char[] { '=' } ); + if ( spl2[0].StartsWith( "Feder" ) ) { + ind = spl2[0].Replace( "Feder", "" ); + index = int.Parse( ind ); + Slave[index].Feder = int.Parse( spl2[1] ); + } else if ( spl2[0].StartsWith( "Panpot" ) ) { + ind = spl2[0].Replace( "Panpot", "" ); + index = int.Parse( ind ); + Slave[index].Panpot = int.Parse( spl2[1] ); + } else if ( spl2[0].StartsWith( "Mute" ) ) { + ind = spl2[0].Replace( "Mute", "" ); + index = int.Parse( ind ); + Slave[index].Mute = int.Parse( spl2[1] ); + } else if ( spl2[0].StartsWith( "Solo" ) ) { + ind = spl2[0].Replace( "Solo", "" ); + index = int.Parse( ind ); + Slave[index].Solo = int.Parse( spl2[1] ); + } + + } + } + + /// + /// このインスタンスをテキストファイルに出力します + /// + /// 出力対象 + public void write( TextMemoryStream sw ) { + sw.writeLine( "[Mixer]" ); + sw.writeLine( "MasterFeder=" + MasterFeder ); + sw.writeLine( "MasterPanpot=" + MasterPanpot ); + sw.writeLine( "MasterMute=" + MasterMute ); + sw.writeLine( "OutputMode=" + OutputMode ); + sw.writeLine( "Tracks=" + Slave.Count ); + for ( int i = 0; i < Slave.Count; i++ ) { + sw.writeLine( "Feder" + i + "=" + Slave[i].Feder ); + sw.writeLine( "Panpot" + i + "=" + Slave[i].Panpot ); + sw.writeLine( "Mute" + i + "=" + Slave[i].Mute ); + sw.writeLine( "Solo" + i + "=" + Slave[i].Solo ); + } + } + + /// + /// VsqMixerのインスタンスを構築するテストを行います + /// + /// テストに成功すればtrue、そうでなければfalseを返します + public static bool test() { + string fpath = Path.GetTempFileName(); + StreamWriter sw = new StreamWriter( fpath, false, Encoding.Unicode ); + sw.WriteLine( "MasterFeder=12" ); + sw.WriteLine( "MasterPanpot=13" ); + sw.WriteLine( "MasterMute=14" ); + sw.WriteLine( "OutputMode=15" ); + sw.WriteLine( "Tracks=8" ); + sw.WriteLine( "Feder0=1" ); + sw.WriteLine( "Panpot0=2" ); + sw.WriteLine( "Mute0=3" ); + sw.WriteLine( "Solo0=4" ); + sw.WriteLine( "Feder1=5" ); + sw.WriteLine( "Panpot1=6" ); + sw.WriteLine( "Mute1=7" ); + sw.WriteLine( "Solo1=8" ); + sw.WriteLine( "Feder2=9" ); + sw.WriteLine( "Panpot2=10" ); + sw.WriteLine( "Mute2=11" ); + sw.WriteLine( "Solo2=12" ); + sw.WriteLine( "Feder3=13" ); + sw.WriteLine( "Panpot3=14" ); + sw.WriteLine( "Mute3=15" ); + sw.WriteLine( "Solo3=16" ); + sw.WriteLine( "Feder4=17" ); + sw.WriteLine( "Panpot4=18" ); + sw.WriteLine( "Mute4=19" ); + sw.WriteLine( "Solo4=20" ); + sw.WriteLine( "Feder5=21" ); + sw.WriteLine( "Panpot5=22" ); + sw.WriteLine( "Mute5=23" ); + sw.WriteLine( "Solo5=24" ); + sw.WriteLine( "Feder6=25" ); + sw.WriteLine( "Panpot6=26" ); + sw.WriteLine( "Mute6=27" ); + sw.WriteLine( "Solo6=28" ); + sw.WriteLine( "Feder7=29" ); + sw.WriteLine( "Panpot7=30" ); + sw.WriteLine( "Mute7=31" ); + sw.WriteLine( "Solo7=32" ); + sw.WriteLine( "[EventList]" ); + sw.Close(); + + TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ); + string last_line = ""; + VsqMixer vsqMixer = new VsqMixer( sr, ref last_line ); + + if( vsqMixer.MasterFeder == 12 && + vsqMixer.MasterPanpot == 13 && + vsqMixer.MasterMute == 14 && + vsqMixer.OutputMode == 15 && + vsqMixer.Slave.Count == 8 ){ + for( int i = 0; i < vsqMixer.Slave.Count; i++ ){ + int start = 4 * i; + if ( vsqMixer.Slave[i].Feder != start + 1 || + vsqMixer.Slave[i].Panpot != start + 2 || + vsqMixer.Slave[i].Mute != start + 3 || + vsqMixer.Slave[i].Solo != start + 4 ) { + sr.close(); + File.Delete( fpath ); + return false; + } + } + }else{ + sr.close(); + File.Delete( fpath ); + return false; + } + sr.close(); + File.Delete( fpath ); + return true; + } + } + + /// + /// VsqMixerのSlave要素に格納される各エントリ + /// + [Serializable] + public class VsqMixerEntry : ICloneable { + public int Feder; + public int Panpot; + public int Mute; + public int Solo; + + public object Clone() { + VsqMixerEntry res = new VsqMixerEntry( Feder, Panpot, Mute, Solo ); + return res; + } + + /// + /// 各パラメータを指定したコンストラクタ + /// + /// Feder値 + /// Panpot値 + /// Mute値 + /// Solo値 + public VsqMixerEntry( int feder, int panpot, int mute, int solo ) { + this.Feder = feder; + this.Panpot = panpot; + this.Mute = mute; + this.Solo = solo; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqMetaText/VsqMetaText.cs b/trunk/Boare.Lib.Vsq/VsqMetaText/VsqMetaText.cs new file mode 100644 index 0000000..67ecfa3 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqMetaText/VsqMetaText.cs @@ -0,0 +1,811 @@ +/* + * VsqMetaText/VsqMetaText.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Drawing; +using System.Windows.Forms; + +namespace Boare.Lib.Vsq { + + /// + /// vsqのメタテキストの中身を処理するためのクラス + /// + [Serializable] + public class VsqMetaText : ICloneable { + public VsqCommon Common; + internal VsqMaster master; + internal VsqMixer mixer; + private VsqEventList m_events; + /// + /// PIT。ピッチベンド(pitchBendBPList)。default=0 + /// + public VsqBPList PIT; + /// + /// PBS。ピッチベンドセンシティビティ(pitchBendSensBPList)。dfault=2 + /// + public VsqBPList PBS; + /// + /// DYN。ダイナミクス(dynamicsBPList)。default=64 + /// + public VsqBPList DYN; + /// + /// BRE。ブレシネス(epRResidualBPList)。default=0 + /// + public VsqBPList BRE; + /// + /// BRI。ブライトネス(epRESlopeBPList)。default=64 + /// + public VsqBPList BRI; + /// + /// CLE。クリアネス(epRESlopeDepthBPList)。default=0 + /// + public VsqBPList CLE; + private VsqBPList reso1FreqBPList; + private VsqBPList reso2FreqBPList; + private VsqBPList reso3FreqBPList; + private VsqBPList reso4FreqBPList; + private VsqBPList reso1BWBPList; + private VsqBPList reso2BWBPList; + private VsqBPList reso3BWBPList; + private VsqBPList reso4BWBPList; + private VsqBPList reso1AmpBPList; + private VsqBPList reso2AmpBPList; + private VsqBPList reso3AmpBPList; + private VsqBPList reso4AmpBPList; + /// + /// GEN。ジェンダーファクター(genderFactorBPList)。default=64 + /// + public VsqBPList GEN; + /// + /// POR。ポルタメントタイミング(portamentoTimingBPList)。default=64 + /// + public VsqBPList POR; + /// + /// OPE。オープニング(openingBPList)。default=127 + /// + public VsqBPList OPE; + + public object Clone() { + VsqMetaText res = new VsqMetaText(); + if ( Common != null ) { + res.Common = (VsqCommon)Common.Clone(); + } + if ( master != null ) { + res.master = (VsqMaster)master.Clone(); + } + if ( mixer != null ) { + res.mixer = (VsqMixer)mixer.Clone(); + } + if ( m_events != null ) { + res.m_events = new VsqEventList(); + for ( Iterator itr = m_events.iterator(); itr.hasNext(); ) { + res.m_events.add( (VsqEvent)((VsqEvent)itr.next()).Clone() ); + } + } + if ( PIT != null ) { + res.PIT = (VsqBPList)PIT.Clone(); + } + if ( PBS != null ) { + res.PBS = (VsqBPList)PBS.Clone(); + } + if ( DYN != null ) { + res.DYN = (VsqBPList)DYN.Clone(); + } + if ( BRE != null ) { + res.BRE = (VsqBPList)BRE.Clone(); + } + if ( BRI != null ) { + res.BRI = (VsqBPList)BRI.Clone(); + } + if ( CLE != null ) { + res.CLE = (VsqBPList)CLE.Clone(); + } + if ( reso1FreqBPList != null ) { + res.reso1FreqBPList = (VsqBPList)reso1FreqBPList.Clone(); + } + if ( reso2FreqBPList != null ) { + res.reso2FreqBPList = (VsqBPList)reso2FreqBPList.Clone(); + } + if ( reso3FreqBPList != null ) { + res.reso3FreqBPList = (VsqBPList)reso3FreqBPList.Clone(); + } + if ( reso4FreqBPList != null ) { + res.reso4FreqBPList = (VsqBPList)reso4FreqBPList.Clone(); + } + if ( reso1BWBPList != null ) { + res.reso1BWBPList = (VsqBPList)reso1BWBPList.Clone(); + } + if ( reso2BWBPList != null ) { + res.reso2BWBPList = (VsqBPList)reso2BWBPList.Clone(); + } + if ( reso3BWBPList != null ) { + res.reso3BWBPList = (VsqBPList)reso3BWBPList.Clone(); + } + if ( reso4BWBPList != null ) { + res.reso4BWBPList = (VsqBPList)reso4BWBPList.Clone(); + } + if ( reso1AmpBPList != null ) { + res.reso1AmpBPList = (VsqBPList)reso1AmpBPList.Clone(); + } + if ( reso2AmpBPList != null ) { + res.reso2AmpBPList = (VsqBPList)reso2AmpBPList.Clone(); + } + if ( reso3AmpBPList != null ) { + res.reso3AmpBPList = (VsqBPList)reso3AmpBPList.Clone(); + } + if ( reso4AmpBPList != null ) { + res.reso4AmpBPList = (VsqBPList)reso4AmpBPList.Clone(); + } + if ( GEN != null ) { + res.GEN = (VsqBPList)GEN.Clone(); + } + if ( POR != null ) { + res.POR = (VsqBPList)POR.Clone(); + } + if ( OPE != null ) { + res.OPE = (VsqBPList)OPE.Clone(); + } + return res; + } + + public VsqEventList getEventList() { + return m_events; + } + + internal VsqBPList getElement( string curve ) { + switch ( curve.Trim().ToLower() ) { + case "bre": + return this.BRE; + case "bri": + return this.BRI; + case "cle": + return this.CLE; + case "dyn": + return this.DYN; + case "gen": + return this.GEN; + case "ope": + return this.OPE; + case "pbs": + return this.PBS; + case "pit": + return this.PIT; + case "por": + return this.POR; + default: + return null; + } + } + + internal void setElement( string curve, VsqBPList value ) { + switch ( curve.Trim().ToLower() ) { + case "bre": + this.BRE = value; + break; + case "bri": + this.BRI = value; + break; + case "cle": + this.CLE = value; + break; + case "dyn": + this.DYN = value; + break; + case "gen": + this.GEN = value; + break; + case "ope": + this.OPE = value; + break; + case "pbs": + this.PBS = value; + break; + case "pit": + this.PIT = value; + break; + case "por": + this.POR = value; + break; + } + } + + /// + /// Editor画面上で上からindex番目のカーブを表すBPListを求めます + /// + /// + /// + public VsqBPList getCurve( int index ) { + switch ( index ) { + case 1: + return DYN; + case 2: + return BRE; + case 3: + return BRI; + case 4: + return CLE; + case 5: + return OPE; + case 6: + return GEN; + case 7: + return POR; + case 8: + return PIT; + case 9: + return PBS; + default: + return null; + } + } + + + /// + /// Editor画面上で上からindex番目のカーブの名前を調べます + /// + /// + /// + public static string getCurveName( int index ) { + switch ( index ) { + case 0: + return "VEL"; + case 1: + return "DYN"; + case 2: + return "BRE"; + case 3: + return "BRI"; + case 4: + return "CLE"; + case 5: + return "OPE"; + case 6: + return "GEN"; + case 7: + return "POR"; + case 8: + return "PIT"; + case 9: + return "PBS"; + default: + return ""; + } + } + + /// + /// Singerプロパティに指定されている + /// + public string getSinger() { + for ( Iterator itr = m_events.iterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.ID.type == VsqIDType.Singer ) { + return item.ID.IconHandle.IDS; + } + } + return ""; + } + + public void setSinger( string value ) { + for ( Iterator itr = m_events.iterator(); itr.hasNext(); ) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.ID.type == VsqIDType.Singer ) { + item.ID.IconHandle.IDS = value; + break; + } + } + } + + /// + /// EOSイベントが記録されているクロックを取得します。 + /// + /// + public int getIndexOfEOS() { + int result; + if ( m_events.getCount() > 0 ) { + int ilast = m_events.getCount() - 1; + result = m_events.getElement( ilast ).Clock; + } else { + result = -1; + } + return result; + } + + /// + /// このインスタンスから、IDとHandleのリストを構築します + /// + /// + /// + void BuildIDHandleList( out List id, out List handle ) { + id = new List(); + handle = new List(); + int current_id = -1; + int current_handle = -1; + List events = new List(); + for ( Iterator itr = m_events.iterator(); itr.hasNext(); ) { + events.Add( (VsqEvent)itr.next() ); + } + events.Sort(); + for( int i = 0; i < events.Count; i++ ){ + VsqEvent item = events[i]; + VsqID id_item = (VsqID)item.ID.Clone(); + current_id++; + item.ID.value = current_id; + id_item.value = current_id; + // IconHandle + if ( item.ID.IconHandle != null ) { + current_handle++; + VsqHandle handle_item = item.ID.IconHandle.castToVsqHandle(); + handle_item.Index = current_handle; + handle.Add( handle_item ); + id_item.IconHandle_index = current_handle; + } + // LyricHandle + if ( item.ID.LyricHandle != null ) { + current_handle++; + VsqHandle handle_item = item.ID.LyricHandle.castToVsqHandle(); + handle_item.Index = current_handle; + handle.Add( handle_item ); + id_item.LyricHandle_index = current_handle; + } + // VibratoHandle + if ( item.ID.VibratoHandle != null ) { + current_handle++; + VsqHandle handle_item = item.ID.VibratoHandle.castToVsqHandle(); + handle_item.Index = current_handle; + handle.Add( handle_item ); + id_item.VibratoHandle_index = current_handle; + } + id.Add( id_item ); + } + } + + /// + /// このインスタンスの内容を指定されたファイルに出力します。 + /// + /// + /// + public void print( TextMemoryStream sw, bool encode, int eos, int start ) { + if ( Common != null ) { + Common.write( sw ); + } + if ( master != null ) { + master.write( sw ); + } + if ( mixer != null ) { + mixer.write( sw ); + } + List id; + List handle; + BuildIDHandleList( out id, out handle ); + writeEventList( sw, eos ); + int i; + for ( i = 0; i < id.Count; i++ ) { + id[i].write( sw ); + } + for ( i = 0; i < handle.Count; i++ ) { + handle[i].write( sw, encode ); + } + if ( PIT.getCount() > 0 ) { + PIT.print( sw, start, "[PitchBendBPList]" ); + } + if ( PBS.getCount() > 0 ) { + PBS.print( sw, start, "[PitchBendSensBPList]" ); + } + if ( DYN.getCount() > 0 ) { + DYN.print( sw, start, "[DynamicsBPList]" ); + } + if ( BRE.getCount() > 0 ) { + BRE.print( sw, start, "[EpRResidualBPList]" ); + } + if ( BRI.getCount() > 0 ) { + BRI.print( sw, start, "[EpRESlopeBPList]" ); + } + if ( CLE.getCount() > 0 ) { + CLE.print( sw, start, "[EpRESlopeDepthBPList]" ); + } + + if ( reso1FreqBPList.getCount() > 0 ) { + reso1FreqBPList.print( sw, start, "[Reso1FreqBPList]" ); + } + if ( reso2FreqBPList.getCount() > 0 ) { + reso2FreqBPList.print( sw, start, "[Reso2FreqBPList]" ); + } + if ( reso3FreqBPList.getCount() > 0 ) { + reso3FreqBPList.print( sw, start, "[Reso3FreqBPList]" ); + } + if ( reso4FreqBPList.getCount() > 0 ) { + reso4FreqBPList.print( sw, start, "[Reso4FreqBPList]" ); + } + + if ( reso1BWBPList.getCount() > 0 ) { + reso1BWBPList.print( sw, start, "[Reso1BWBPList]" ); + } + if ( reso2BWBPList.getCount() > 0 ) { + reso2BWBPList.print( sw, start, "[Reso2BWBPList]" ); + } + if ( reso3BWBPList.getCount() > 0 ) { + reso3BWBPList.print( sw, start, "[Reso3BWBPList]" ); + } + if ( reso4BWBPList.getCount() > 0 ) { + reso4BWBPList.print( sw, start, "[Reso4BWBPList]" ); + } + + if ( reso1AmpBPList.getCount() > 0 ) { + reso1AmpBPList.print( sw, start, "[Reso1AmpBPList]" ); + } + if ( reso2AmpBPList.getCount() > 0 ) { + reso2AmpBPList.print( sw, start, "[Reso2AmpBPList]" ); + } + if ( reso3AmpBPList.getCount() > 0 ) { + reso3AmpBPList.print( sw, start, "[Reso3AmpBPList]" ); + } + if ( reso4AmpBPList.getCount() > 0 ) { + reso4AmpBPList.print( sw, start, "[Reso4AmpBPList]" ); + } + + if ( GEN.getCount() > 0 ) { + GEN.print( sw, start, "[GenderFactorBPList]" ); + } + if ( POR.getCount() > 0 ) { + POR.print( sw, start, "[PortamentoTimingBPList]" ); + } + if ( OPE.getCount() > 0 ) { + OPE.print( sw, start, "[OpeningBPList]" ); + } + } + + private void writeEventList( TextMemoryStream sw, int eos ) { + sw.writeLine( "[EventList]" ); + List temp = new List(); + for ( Iterator itr = m_events.iterator(); itr.hasNext(); ) { + temp.Add( (VsqEvent)itr.next() ); + } + temp.Sort(); + int i = 0; + while ( i < temp.Count ) { + VsqEvent item = temp[i]; + if ( !item.ID.Equals( VsqID.EOS ) ) { + string ids = "ID#" + i.ToString( "0000" ); + int clock = temp[i].Clock; + while ( i + 1 < temp.Count && clock == temp[i + 1].Clock ) { + i++; + ids += ",ID#" + i.ToString( "0000" ); + } + sw.writeLine( clock + "=" + ids ); + } + i++; + } + sw.writeLine( eos + "=EOS" ); + } + + /// + /// 何も無いVsqMetaTextを構築する。これは、Master Track用のMetaTextとしてのみ使用されるべき + /// + public VsqMetaText() { + } + + /// + /// 最初のトラック以外の一般のメタテキストを構築。(Masterが作られない) + /// + public VsqMetaText( string name, string singer ) + : this( name, 0, singer, false ) { + } + + /// + /// 最初のトラックのメタテキストを構築。(Masterが作られる) + /// + /// + public VsqMetaText( string name, string singer, int pre_measure ) + : this( name, pre_measure, singer, true ) { + } + + private VsqMetaText( string name, int pre_measure, string singer, bool is_first_track ) { + Common = new VsqCommon( name, Color.FromArgb( 179, 181, 123 ), 1, 1 ); + PIT = new VsqBPList( 0, -8192, 8192 ); + PIT.add( 0, PIT.getDefault() ); + + PBS = new VsqBPList( 2, 0, 24 ); + PBS.add( 0, PBS.getDefault() ); + + DYN = new VsqBPList( 64, 0, 127 ); + DYN.add( 0, DYN.getDefault() ); + + BRE = new VsqBPList( 0, 0, 127 ); + BRE.add( 0, BRE.getDefault() ); + + BRI = new VsqBPList( 64, 0, 127 ); + BRI.add( 0, BRI.getDefault() ); + + CLE = new VsqBPList( 0, 0, 127 ); + CLE.add( 0, CLE.getDefault() ); + + reso1FreqBPList = new VsqBPList( 255, 0, 255 ); + reso1FreqBPList.add( 0, reso1FreqBPList.getDefault() ); + + reso2FreqBPList = new VsqBPList( 255, 0, 255 ); + reso2FreqBPList.add( 0, reso2FreqBPList.getDefault() ); + + reso3FreqBPList = new VsqBPList( 255, 0, 255 ); + reso3FreqBPList.add( 0, reso3FreqBPList.getDefault() ); + + reso4FreqBPList = new VsqBPList( 255, 0, 255 ); + reso4FreqBPList.add( 0, reso4FreqBPList.getDefault() ); + + reso1BWBPList = new VsqBPList( 255, 0, 255 ); + reso1BWBPList.add( 0, reso1BWBPList.getDefault() ); + + reso2BWBPList = new VsqBPList( 255, 0, 255 ); + reso2BWBPList.add( 0, reso2BWBPList.getDefault() ); + + reso3BWBPList = new VsqBPList( 255, 0, 255 ); + reso3BWBPList.add( 0, reso3BWBPList.getDefault() ); + + reso4BWBPList = new VsqBPList( 255, 0, 255 ); + reso4BWBPList.add( 0, reso4BWBPList.getDefault() ); + + reso1AmpBPList = new VsqBPList( 255, 0, 255 ); + reso1AmpBPList.add( 0, reso1AmpBPList.getDefault() ); + + reso2AmpBPList = new VsqBPList( 255, 0, 255 ); + reso2AmpBPList.add( 0, reso2AmpBPList.getDefault() ); + + reso3AmpBPList = new VsqBPList( 255, 0, 255 ); + reso3AmpBPList.add( 0, reso3AmpBPList.getDefault() ); + + reso4AmpBPList = new VsqBPList( 255, 0, 255 ); + reso4AmpBPList.add( 0, reso4AmpBPList.getDefault() ); + + GEN = new VsqBPList( 64, 0, 127 ); + GEN.add( 0, GEN.getDefault() ); + + POR = new VsqBPList( 64, 0, 127 ); + POR.add( 0, POR.getDefault() ); + + OPE = new VsqBPList( 127, 0, 127 ); + OPE.add( 0, OPE.getDefault() ); + + if ( is_first_track ) { + master = new VsqMaster( pre_measure ); + } else { + master = null; + } + m_events = new VsqEventList(); + VsqID id = new VsqID( 0 ); + id.type = VsqIDType.Singer; + id.IconHandle = new IconHandle(); + id.IconHandle.IconID = "$07010000"; + id.IconHandle.IDS = singer; + id.IconHandle.Original = 0; + id.IconHandle.Caption = ""; + id.IconHandle.Length = 1; + id.IconHandle.Language = 0; + id.IconHandle.Program = 0; + m_events.add( new VsqEvent( 0, id ) ); + } + + public VsqMetaText( TextMemoryStream sr ) { + List> t_event_list = new List>(); + Dictionary __id = new Dictionary(); + Dictionary __handle = new Dictionary(); + PIT = new VsqBPList( 0, -8192, 8192 ); + PBS = new VsqBPList( 2, 0, 24 ); + DYN = new VsqBPList( 64, 0, 127 ); + BRE = new VsqBPList( 0 , 0, 127); + BRI = new VsqBPList( 64, 0, 127 ); + CLE = new VsqBPList( 0, 0, 127 ); + reso1FreqBPList = new VsqBPList( 255, 0, 255 ); + reso2FreqBPList = new VsqBPList( 255, 0, 255 ); + reso3FreqBPList = new VsqBPList( 255, 0, 255 ); + reso4FreqBPList = new VsqBPList( 255, 0, 255 ); + reso1BWBPList = new VsqBPList( 255, 0, 255 ); + reso2BWBPList = new VsqBPList( 255, 0, 255 ); + reso3BWBPList = new VsqBPList( 255, 0, 255 ); + reso4BWBPList = new VsqBPList( 255, 0, 255 ); + reso1AmpBPList = new VsqBPList( 255, 0, 255 ); + reso2AmpBPList = new VsqBPList( 255, 0, 255 ); + reso3AmpBPList = new VsqBPList( 255, 0, 255 ); + reso4AmpBPList = new VsqBPList( 255, 0, 255 ); + GEN = new VsqBPList( 64, 0, 127 ); + POR = new VsqBPList( 64, 0, 127 ); + OPE = new VsqBPList( 127, 0, 127 ); + + string last_line = sr.readLine(); + while ( true ) { + #region "TextMemoryStreamから順次読込み" + if ( last_line.Length == 0 ) { + break; + } + switch ( last_line ) { + case "[Common]": + Common = new VsqCommon( sr, ref last_line ); + break; + case "[Master]": + master = new VsqMaster( sr, ref last_line ); + break; + case "[Mixer]": + mixer = new VsqMixer( sr, ref last_line ); + break; + case "[EventList]": + last_line = sr.readLine(); + while ( !last_line.StartsWith( "[" ) ) { + string[] spl2 = last_line.Split( new char[] { '=' } ); + int clock = int.Parse( spl2[0] ); + int id_number = -1; + if ( spl2[1] != "EOS" ) { + string[] ids = spl2[1].Split( ",".ToCharArray() ); + for ( int i = 0; i < ids.Length; i++ ) { + string[] spl3 = ids[i].Split( new char[] { '#' } ); + id_number = int.Parse( spl3[1] ); + t_event_list.Add( new KeyValuePair( clock, id_number ) ); + } + } else { + t_event_list.Add( new KeyValuePair( clock, -1) ); + } + if ( sr.peek() < 0 ) { + break; + } else { + last_line = sr.readLine(); + } + } + break; + case "[PitchBendBPList]": + last_line = PIT.appendFromText( sr ); + break; + case "[PitchBendSensBPList]": + last_line = PBS.appendFromText( sr ); + break; + case "[DynamicsBPList]": + last_line = DYN.appendFromText( sr ); + break; + case "[EpRResidualBPList]": + last_line = BRE.appendFromText( sr ); + break; + case "[EpRESlopeBPList]": + last_line = BRI.appendFromText( sr ); + break; + case "[EpRESlopeDepthBPList]": + last_line = CLE.appendFromText( sr ); + break; + case "[Reso1FreqBPList]": + last_line = reso1FreqBPList.appendFromText( sr ); + break; + case "[Reso2FreqBPList]": + last_line = reso2FreqBPList.appendFromText( sr ); + break; + case "[Reso3FreqBPList]": + last_line = reso3FreqBPList.appendFromText( sr ); + break; + case "[Reso4FreqBPList]": + last_line = reso4FreqBPList.appendFromText( sr ); + break; + case "[Reso1BWBPList]": + last_line = reso1BWBPList.appendFromText( sr ); + break; + case "[Reso2BWBPList]": + last_line = reso2BWBPList.appendFromText( sr ); + break; + case "[Reso3BWBPList]": + last_line = reso3BWBPList.appendFromText( sr ); + break; + case "[Reso4BWBPList]": + last_line = reso4BWBPList.appendFromText( sr ); + break; + case "[Reso1AmpBPList]": + last_line = reso1AmpBPList.appendFromText( sr ); + break; + case "[Reso2AmpBPList]": + last_line = reso2AmpBPList.appendFromText( sr ); + break; + case "[Reso3AmpBPList]": + last_line = reso3AmpBPList.appendFromText( sr ); + break; + case "[Reso4AmpBPList]": + last_line = reso4AmpBPList.appendFromText( sr ); + break; + case "[GenderFactorBPList]": + last_line = GEN.appendFromText( sr ); + break; + case "[PortamentoTimingBPList]": + last_line = POR.appendFromText( sr ); + break; + case "[OpeningBPList]": + last_line = OPE.appendFromText( sr ); + break; + default: + string buffer = last_line; + buffer = buffer.Replace( "[", "" ); + buffer = buffer.Replace( "]", "" ); + string[] spl = buffer.Split( new char[] { '#' } ); + int index = int.Parse( spl[1] ); + if ( last_line.StartsWith( "[ID#" ) ) { + __id.Add( index, new VsqID( sr, index, ref last_line ) ); + } else if ( last_line.StartsWith( "[h#" ) ) { + __handle.Add( index, new VsqHandle( sr, index, ref last_line ) ); + } + break; + #endregion + } + + if ( sr.peek() < 0 ) { + break; + } + } + + // まずhandleをidに埋め込み + for ( int i = 0; i < __id.Count; i++ ) { + if ( __handle.ContainsKey( __id[i].IconHandle_index ) ) { + __id[i].IconHandle = __handle[__id[i].IconHandle_index].castToIconHandle(); + } + if ( __handle.ContainsKey( __id[i].LyricHandle_index ) ) { + __id[i].LyricHandle = __handle[__id[i].LyricHandle_index].castToLyricHandle(); + } + if ( __handle.ContainsKey( __id[i].VibratoHandle_index ) ) { + __id[i].VibratoHandle = __handle[__id[i].VibratoHandle_index].castToVibratoHandle(); + } + } + + // idをeventListに埋め込み + m_events = new VsqEventList(); + for ( int i = 0; i < t_event_list.Count; i++ ) { + int clock = t_event_list[i].Key; + int id_number = t_event_list[i].Value; + if ( __id.ContainsKey( id_number ) ) { + m_events.add( new VsqEvent( clock, (VsqID)__id[id_number].Clone() ) ); + } + } + } + + public static bool test( string fpath ) { + VsqMetaText metaText; + using ( TextMemoryStream sr = new TextMemoryStream( fpath, Encoding.Unicode ) ) { + metaText = new VsqMetaText( sr ); + } + string result = "test.txt"; + + StreamReader honmono = new StreamReader( fpath ); + TextMemoryStream copy = new TextMemoryStream( FileAccess.ReadWrite ); + metaText.print( copy, true, 1000, 100 ); + copy.rewind(); + while ( honmono.Peek() >= 0 && copy.peek() >= 0 ) { + string hon = honmono.ReadLine(); + string cop = copy.readLine(); + if ( hon != cop ) { + Console.WriteLine( "honmono,copy=" + hon + "," + cop ); + honmono.Close(); + copy.close(); + return false; + } + } + honmono.Close(); + copy.close(); + + return true; + } + } + + public enum VsqIDType { + Singer, + Anote, + Unknown + } + + public enum VsqHandleType { + Lyric, + Vibrato, + Singer + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqNote.cs b/trunk/Boare.Lib.Vsq/VsqNote.cs new file mode 100644 index 0000000..c49927c --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqNote.cs @@ -0,0 +1,236 @@ +/* + * VsqNote.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Boare.Lib.Vsq { + + /// + /// 音階を表現するためのクラス + /// + [Serializable] + public class VsqNote { + /// + /// このインスタンスが表す音階のノート値 + /// + public int Value; + private static readonly bool[] _KEY_TYPE = new bool[128] { + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + }; + + /// + /// 音階のノート値からのコンストラクタ。 + /// + /// この音階を初期化するためのノート値 + public VsqNote( int note ) { + Value = note; + } + + /// + /// このインスタンスが表す音階が、ピアノの白鍵かどうかを返します + /// + public bool isWhiteKey() { + return isNoteWhiteKey( Value ); + } + + /// + /// 指定した音階が、ピアノの白鍵かどうかを返します + /// + /// + /// + public static bool isNoteWhiteKey( int note ) { + if ( 0 <= note && note <= 127 ) { + return _KEY_TYPE[note]; + } else { + int odd = note % 12; + switch ( odd ) { + case 1: + case 3: + case 6: + case 8: + case 10: + return false; + default: + return true; + } + } + } + + public static string getNoteString( int note ) { + int odd = note % 12; + int order = (note - odd) / 12 - 2; + switch ( odd ) { + case 0: + return "C" + order; + case 1: + return "C#" + order; + case 2: + return "D" + order; + case 3: + return "Eb" + order; + case 4: + return "E" + order; + case 5: + return "F" + order; + case 6: + return "F#" + order; + case 7: + return "G" + order; + case 8: + return "G#" + order; + case 9: + return "A" + order; + case 10: + return "Bb" + order; + case 11: + return "B" + order; + default: + return ""; + } + } + + override public string ToString() { + return getNoteString( Value ); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqNrpn.cs b/trunk/Boare.Lib.Vsq/VsqNrpn.cs new file mode 100644 index 0000000..3bf48c9 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqNrpn.cs @@ -0,0 +1,116 @@ +/* + * VsqNrpn.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace Boare.Lib.Vsq { + + public class VsqNrpn : IComparable { + public int Clock; + public ushort Nrpn; + public byte DataMsb; + public byte DataLsb; + public bool DataLsbSpecified = false; + private List m_list; + + public VsqNrpn( int clock, ushort nrpn, byte data_msb ) { + Clock = clock; + Nrpn = nrpn; + DataMsb = data_msb; + DataLsbSpecified = false; + m_list = new List(); + } + + public VsqNrpn( int clock, ushort nrpn, byte data_msb, byte data_lsb ) { + Clock = clock; + Nrpn = nrpn; + DataMsb = data_msb; + DataLsb = data_lsb; + DataLsbSpecified = true; + m_list = new List(); + } + + private VsqNrpn() { + } + + public VsqNrpn[] expand() { + List ret = new List(); + if ( DataLsbSpecified ) { + ret.Add( new VsqNrpn( Clock, Nrpn, DataMsb, DataLsb ) ); + } else { + ret.Add( new VsqNrpn( Clock, Nrpn, DataMsb ) ); + } + for ( int i = 0; i < m_list.Count; i++ ) { + ret.AddRange( m_list[i].expand() ); + } + return ret.ToArray(); + } + + public static VsqNrpn[] merge( VsqNrpn[] src1, VsqNrpn[] src2 ) { + List ret = new List(); + for ( int i = 0; i < src1.Length; i++ ) { + ret.Add( src1[i] ); + } + for ( int i = 0; i < src2.Length; i++ ) { + ret.Add( src2[i] ); + } + ret.Sort(); + return ret.ToArray(); + } + + public static NrpnData[] convert( VsqNrpn[] source ) { + ushort nrpn = (ushort)source[0].Nrpn; + byte msb = (byte)(nrpn >> 8); + byte lsb = (byte)(nrpn - (nrpn << 8)); + List ret = new List(); + ret.Add( new NrpnData( source[0].Clock, 0x63, msb ) ); + ret.Add( new NrpnData( source[0].Clock, 0x62, lsb ) ); + ret.Add( new NrpnData( source[0].Clock, 0x06, source[0].DataMsb ) ); + if ( source[0].DataLsbSpecified ) { + ret.Add( new NrpnData( source[0].Clock, 0x26, source[0].DataLsb ) ); + } + byte last_msb = msb; + for ( int i = 1; i < source.Length; i++ ) { + ushort tnrpn = (ushort)source[i].Nrpn; + msb = (byte)(tnrpn >> 8); + lsb = (byte)(tnrpn - (tnrpn << 8)); + //if ( msb != last_msb ) { + ret.Add( new NrpnData( source[i].Clock, 0x63, msb ) ); + //} else if ( msb == 0x63 ) { + // ret.Add( new NrpnData( source[i].Clock, 0x63, msb ) ); + //} + last_msb = msb; + ret.Add( new NrpnData( source[i].Clock, 0x62, lsb ) ); + ret.Add( new NrpnData( source[i].Clock, 0x06, source[i].DataMsb ) ); + if ( source[i].DataLsbSpecified ) { + ret.Add( new NrpnData( source[i].Clock, 0x26, source[i].DataLsb ) ); + } + } + return ret.ToArray(); + } + + public int CompareTo( VsqNrpn item ) { + return Clock - item.Clock; + } + + public void append( NRPN nrpn, byte data_msb ) { + m_list.Add( new VsqNrpn( Clock, (ushort)nrpn, data_msb ) ); + } + + public void append( NRPN nrpn, byte data_msb, byte data_lsb ) { + m_list.Add( new VsqNrpn( Clock, (ushort)nrpn, data_msb, data_lsb ) ); + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqPhoneticSymbol.cs b/trunk/Boare.Lib.Vsq/VsqPhoneticSymbol.cs new file mode 100644 index 0000000..66a6d2f --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqPhoneticSymbol.cs @@ -0,0 +1,153 @@ +/* + * VsqPhoneticSymbol.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace Boare.Lib.Vsq { + + public class VsqPhoneticSymbol { + private static string[] _SYMBOL_VOWEL_JP = new string[]{ + @"a", + @"i", + @"M", + @"e", + @"o", + }; + private static string[] _SYMBOL_CONSONANT_JP = new string[]{ + @"k", + @"k'", + @"g", + @"g'", + @"N", + @"N'", + @"s", + @"S", + @"z", + @"Z", + @"dz", + @"dZ", + @"t", + @"t'", + @"ts", + @"tS", + @"d", + @"d'", + @"n", + @"J", + @"h", + @"h\", + @"C", + @"p\", + @"p\'", + @"b", + @"b'", + @"p", + @"p'", + @"m", + @"m'", + @"j", + @"4", + @"4'", + @"w", + @"N\", + }; + private static string[] _SYMBOL_EN = new string[]{ + @"@", + @"V", + @"e", + @"e", + @"I", + @"i:", + @"{", + @"O:", + @"Q", + @"U", + @"u:", + @"@r", + @"eI", + @"aI", + @"OI", + @"@U", + @"aU", + @"I@", + @"e@", + @"U@", + @"O@", + @"Q@", + @"w", + @"j", + @"b", + @"d", + @"g", + @"bh", + @"dh", + @"gh", + @"dZ", + @"v", + @"D", + @"z", + @"Z", + @"m", + @"n", + @"N", + @"r", + @"l", + @"l0", + @"p", + @"t", + @"k", + @"ph", + @"th", + @"kh", + @"tS", + @"f", + @"T", + @"s", + @"S", + @"h", + }; + + public static bool isConsonant( string symbol ) { + for ( int i = 0; i < _SYMBOL_CONSONANT_JP.Length; i++ ){ + string s = _SYMBOL_CONSONANT_JP[i]; + if ( s == symbol ) { + return true; + } + } + return false; + } + + public static bool isValidSymbol( string symbol ) { + for ( int i = 0; i < _SYMBOL_VOWEL_JP.Length; i++ ){ + string s = _SYMBOL_VOWEL_JP[i]; + if ( s == symbol ) { + return true; + } + } + for ( int i = 0; i < _SYMBOL_CONSONANT_JP.Length; i++ ){ + string s = _SYMBOL_CONSONANT_JP[i]; + if ( s == symbol ) { + return true; + } + } + for ( int i = 0; i < _SYMBOL_EN.Length; i++ ){ + string s = _SYMBOL_EN[i]; + if ( s == symbol ) { + return true; + } + } + return false; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqTrack.cs b/trunk/Boare.Lib.Vsq/VsqTrack.cs new file mode 100644 index 0000000..8136892 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqTrack.cs @@ -0,0 +1,413 @@ +/* + * VsqTrack.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.IO; + +namespace Boare.Lib.Vsq { + + /// + /// Stores the data of a vsq track. + /// + [Serializable] + public partial class VsqTrack : ICloneable { + public object Tag; + /// + /// トラックの名前。 + /// + public string Name; + private VsqMetaText m_meta_text; + private List m_midi_event; + private int m_edited_start = int.MaxValue; + private int m_edited_end = int.MinValue; + public string Renderer = "VOCALOID2"; + + private class SingerEventIterator : Iterator { + VsqEventList m_list; + int m_pos; + + public SingerEventIterator( VsqEventList list ) { + m_list = list; + m_pos = -1; + } + + public bool hasNext() { + for ( int i = m_pos + 1; i < m_list.getCount(); i++ ) { + if ( m_list.getElement( i ).ID.type == VsqIDType.Singer ) { + return true; + } + } + return false; + } + + public object next() { + for ( int i = m_pos + 1; i < m_list.getCount(); i++ ) { + VsqEvent item = m_list.getElement( i ); + if ( item.ID.type == VsqIDType.Singer ) { + m_pos = i; + return item; + } + } + return null; + } + + public void remove() { + if ( 0 <= m_pos && m_pos < m_list.getCount() ) { + m_list.removeAt( m_pos ); + } + } + } + + private class NoteEventIterator : Iterator { + VsqEventList m_list; + int m_pos; + + public NoteEventIterator( VsqEventList list ) { + m_list = list; + m_pos = -1; + } + + public bool hasNext() { + for ( int i = m_pos + 1; i < m_list.getCount(); i++ ) { + if ( m_list.getElement( i ).ID.type == VsqIDType.Anote ) { + return true; + } + } + return false; + } + + public object next() { + for ( int i = m_pos + 1; i < m_list.getCount(); i++ ) { + VsqEvent item = m_list.getElement( i ); + if ( item.ID.type == VsqIDType.Anote ) { + m_pos = i; + return item; + } + } + return null; + } + + public void remove() { + if ( 0 <= m_pos && m_pos < m_list.getCount() ) { + m_list.removeAt( m_pos ); + } + } + } + + private class EventIterator : Iterator{ + private VsqEventList m_list; + private int m_pos; + + public EventIterator( VsqEventList list ) { + m_list = list; + m_pos = -1; + } + + public Boolean hasNext() { + if ( 0 <= m_pos + 1 && m_pos + 1 < m_list.getCount() ) { + return true; + } + return false; + } + + public Object next() { + m_pos++; + return m_list.getElement( m_pos ); + } + + public void remove() { + if ( 0 <= m_pos && m_pos < m_list.getCount() ) { + m_list.removeAt( m_pos ); + } + } + } + + + /// + /// 歌手変更イベントを,曲の先頭から順に返すIteratorを取得します + /// + /// + public Iterator getSingerEventIterator() { + return new SingerEventIterator( m_meta_text.getEventList() ); + } + + /// + /// 音符イベントを,曲の先頭から順に返すIteratorを取得します + /// + /// + public Iterator getNoteEventIterator() { + return new NoteEventIterator( m_meta_text.getEventList() ); + } + + /// + /// メタテキストを,メモリー上のストリームに出力します + /// + /// + /// + /// + /// + public void printMetaText( TextMemoryStream sw, int eos, int start ) { + m_meta_text.print( sw, false, eos, start ); + } + + /// + /// メタテキストを,指定されたファイルに出力します + /// + /// + public void printMetaText( string file ) { + TextMemoryStream tms = new TextMemoryStream( FileAccess.ReadWrite ); + int count = m_meta_text.getEventList().getCount(); + int clLast = m_meta_text.getEventList().getElement( count - 1 ).Clock + 480; + m_meta_text.print( tms, true, clLast, 0 ); + using ( StreamWriter sw = new StreamWriter( file ) ) { + tms.rewind(); + while ( tms.peek() >= 0 ) { + string line = tms.readLine(); + sw.WriteLine( line ); + } + } + } + + /// + /// Masterを取得します + /// + public VsqMaster getMaster() { + return m_meta_text.master; + } + + internal void setMaster( VsqMaster value ) { + m_meta_text.master = value; + } + + /// + /// Mixerを取得します + /// + public VsqMixer getMixer() { + return m_meta_text.mixer; + } + + internal void setMixer( VsqMixer value ) { + m_meta_text.mixer = value; + } + + /// + /// このトラックが保持している,指定されたカーブのBPListを取得します + /// + /// + /// + public VsqBPList getCurve( string curve ) { + return m_meta_text.getElement( curve ); + } + + public void setCurve( string curve, VsqBPList value ) { + m_meta_text.setElement( curve, value ); + } + + public int getEventCount() { + return m_meta_text.getEventList().getCount(); + } + + public VsqEvent getEvent( int index ) { + return m_meta_text.getEventList().getElement( index ); + } + + public void setEvent( int index, VsqEvent item ) { + m_meta_text.getEventList().setElement( index, item ); + } + + public void addEvent( VsqEvent item ) { + m_meta_text.getEventList().add( item ); + } + + public Iterator getEventIterator() { + return new EventIterator( m_meta_text.getEventList() ); + } + + public void removeEvent( int index ) { + m_meta_text.getEventList().removeAt( index ); + } + + /// + /// このトラックの,最後に編集が加えられた範囲の,開始位置(クロック)を取得します. + /// このインスタンスを保持しているVsqFileインスタンスのExecuteメソッドによって自動的に更新されます + /// + public int getEditedStart() { + return m_edited_start; + } + + internal void setEditedStart( int value ) { + if ( value < m_edited_start ) { + m_edited_start = value; + } + } + + /// + /// このトラックの,最後に編集が加えられた範囲の,終了位置(クロック)を取得します. + /// このインスタンスを保持しているVsqFileインスタンスのExecuteメソッドによって自動的に更新されます + /// + public int getEditedEnd() { + return m_edited_end; + } + + internal void setEditedEnd( int value ) { + if ( m_edited_end < value ) { + m_edited_end = value; + } + } + + /// + /// このトラックの,編集範囲(EditedStart, EditedEnd)をリセットします. + /// + public void resetEditedArea() { + m_edited_start = int.MaxValue; + m_edited_end = int.MinValue; + } + + /// + /// このインスタンスのコピーを作成します + /// + /// + public object Clone() { + VsqTrack res = new VsqTrack(); + res.Name = Name; + if ( m_meta_text != null ) { + res.m_meta_text = (VsqMetaText)m_meta_text.Clone(); + } + if ( m_midi_event != null ) { + res.m_midi_event = new List( m_midi_event ); + } + res.m_edited_start = m_edited_start; + res.m_edited_end = m_edited_end; + res.Renderer = Renderer; + return res; + } + + private VsqTrack() { + } + + /// + /// Master Trackを構築 + /// + /// + /// + /// + public VsqTrack( int tempo, int numerator, int denominator ) { + this.Name = "Master Track"; + this.m_meta_text = null; + m_midi_event = new List(); + + // テンポを設定 + MidiEvent mi_tempo = new MidiEvent(); + mi_tempo.Clock = 0; + mi_tempo.FirstByte = 0xff; + byte b1 = (byte)(tempo & 0xff); + tempo = tempo >> 8; + byte b2 = (byte)(tempo & 0xff); + tempo = tempo >> 8; + byte b3 = (byte)(tempo & 0xff); + mi_tempo.Data = new byte[5] { 0x51, 0x03, b3, b2, b1 }; + m_midi_event.Add( mi_tempo ); + + // 拍子を設定 + MidiEvent mi_timesig = MidiEvent.generateTimeSigEvent( 0, numerator, denominator ); + m_midi_event.Add( mi_timesig ); + } + + /// + /// Master Trackでないトラックを構築。 + /// + /// + /// + public VsqTrack( string name, string singer ) { + Name = name; + m_meta_text = new VsqMetaText( name, singer ); + m_midi_event = new List(); + } + + /// + /// 歌詞の文字数を調べます + /// + /// + public int getLyricLength() { + int counter = 0; + for ( int i = 0; i < m_meta_text.getEventList().getCount(); i++ ) { + if ( m_meta_text.getEventList().getElement( i ).ID.type == VsqIDType.Anote ) { + counter++; + } + } + return counter; + } + + public VsqTrack( List midi_events ) { + m_midi_event = new List( midi_events ); + Name = ""; +#if DEBUG + bocoree.debug.push_log( "VsqTrack..ctor" ); +#endif + using ( TextMemoryStream sw = new TextMemoryStream() ) { + for ( int i = 0; i < m_midi_event.Count; i++ ) { + if ( m_midi_event[i].FirstByte == 0xff && m_midi_event[i].Data.Length > 0 ) { + // meta textを抽出 + byte type = m_midi_event[i].Data[0]; + if ( type == 0x01 || type == 0x03 ) { + char[] ch = new char[m_midi_event[i].Data.Length - 1]; + for ( int j = 1; j < midi_events[i].Data.Length; j++ ) { + ch[j - 1] = (char)midi_events[i].Data[j]; + } + string line = new string( ch ); + if ( type == 0x01 ) { + int second_colon = line.IndexOf( ':', 3 ); + line = line.Substring( second_colon + 1 ); + line = line.Replace( "\\n", Environment.NewLine ); + line = line.Replace( "\n", Environment.NewLine ); + sw.write( line ); + } else { + Name = line; + } + } + } else { + continue; + } + } + sw.rewind(); + m_meta_text = new VsqMetaText( sw ); + } + } + + public List getTempoList() { + List list = new List(); + for ( int i = 0; i < m_midi_event.Count; i++ ) { + if ( m_midi_event[i].FirstByte == 0xff && m_midi_event[i].Data.Length >= 4 && m_midi_event[i].Data[0] == 0x51 ) { + list.Add( m_midi_event[i] ); + } + } + return list; + } + + /// + /// MidiEventの中から拍子情報を抽出します + /// + /// + public List getTimeSigList() { + List list = new List(); + for ( int i = 0; i < m_midi_event.Count; i++ ) { + if ( m_midi_event[i].FirstByte == 0xff && m_midi_event[i].Data.Length >= 5 && m_midi_event[i].Data[0] == 0x58 ) { + list.Add( m_midi_event[i] ); + } + } + return list; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/VsqUtil.cs b/trunk/Boare.Lib.Vsq/VsqUtil.cs new file mode 100644 index 0000000..f1455f4 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/VsqUtil.cs @@ -0,0 +1,390 @@ +/* + * VsqUtil.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of Boare.Lib.Vsq. + * + * Boare.Lib.Vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * Boare.Lib.Vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Text; +using System.Collections.Generic; + +using bocoree; + +namespace Boare.Lib.Vsq { + + /// + /// Represents the voice language of singer. + /// + public enum VsqVoiceLanguage : int { + /// + /// Default value, equivalent to "Japanese". + /// + Default = 0, + /// + /// Japanese + /// + Japanese = 0, + /// + /// English + /// + English = 1, + } + + /// + /// Static library to treat the information of VOCALOID2 system. + /// + public static class VsqUtil { + /// + /// Maximum number of singers which can be allowed in VOCALOID2 system. + /// + public const uint MAX_SINGERS = 0x4000; + + private static string s_dll2_path = ""; + private static string s_dll1_path = ""; + private static string s_exp_db_dir = ""; + private static bool s_initialized = false; + private static Dictionary s_singer_configs = null; + private static List s_installed_singers = new List(); + private static string s_editor_path = ""; + + public static double getAmplifyCoeffFromPanLeft( int pan ) { + return pan / -64.0 + 1.0; + } + + public static double getAmplifyCoeffFromPanRight( int pan ) { + return pan / 64.0 + 1.0; + } + + public static double getAmplifyCoeffFromFeder( int feder ) { + return Math.Exp( -1.26697245e-02 + 1.18448420e-01 * feder / 10.0 ); + } + + /// + /// Gets the list of installed singers which is installed in the computer. + /// + /// + public static SingerConfig[] getInstalledSingers() { + return s_installed_singers.ToArray(); + } + + /// + /// Gets the list of singer configs. + /// + /// + public static Dictionary getSingerConfigs() { + Dictionary ret = new Dictionary(); + foreach ( KeyValuePair kvp in s_singer_configs ) { + ret.Add( kvp.Key, kvp.Value ); + } + return ret; + } + + /// + /// Gets the path of VOCALOID Editor. + /// + public static string getEditorPath() { + if ( !s_initialized ) { + init(); + } + return s_editor_path; + } + + /// + /// Gets the voice language of specified program change + /// + /// program change to get the voice language + /// + public static VsqVoiceLanguage getLanguage( int program_change ) { + string name = getOriginalSinger( program_change ); + switch ( name ) { + case "Miku": + case "Rin": + case "Len": + case "Rin_ACT2": + case "Len_ACT2": + case "Gackpoid": + case "Luka_JPN": + return VsqVoiceLanguage.Japanese; + case "Sweet_Ann": + case "Prima": + case "Luka_ENG": + return VsqVoiceLanguage.English; + } + return VsqVoiceLanguage.Default; + } + + /// + /// Gets the name of original singer of specified program change. + /// + /// + /// + public static string getOriginalSinger( int program_change ) { + if ( s_singer_configs == null ) { + loadSingerConfigs(); + } + if ( s_singer_configs.ContainsKey( program_change ) ) { + SingerConfig sc = getSingerInfo( program_change ); + string voiceidstr = sc.VOICEIDSTR; + foreach ( SingerConfig installed in s_installed_singers ) { + if ( installed.VOICEIDSTR == voiceidstr ) { + return installed.VOICENAME; + } + } + } + return ""; + } + + /// + /// Gets the VsqID of program change. + /// + /// + /// + public static VsqID getSingerID( int program_change ) { + VsqID ret = new VsqID( 0 ); + ret.type = VsqIDType.Singer; + SingerConfig sc = getSingerInfo( program_change ); + int lang = 0; + foreach ( SingerConfig sc2 in s_installed_singers ) { + if ( sc.VOICEIDSTR == sc2.VOICEIDSTR ) { + switch ( sc2.VOICENAME ) { + case "Miku": + lang = 0; + break; + } + } + } + ret.IconHandle = new IconHandle(); + ret.IconHandle.IconID = "$0701" + program_change.ToString( "0000" ); + ret.IconHandle.IDS = sc.VOICENAME; + ret.IconHandle.Index = 0; + ret.IconHandle.Language = lang; + ret.IconHandle.Length = 1; + ret.IconHandle.Original = sc.Original; + ret.IconHandle.Program = program_change; + ret.IconHandle.Caption = ""; + return ret; + } + + /// + /// Gets the singer information of pecified program change. + /// + /// + /// + public static SingerConfig getSingerInfo( int program_change ) { + if ( s_singer_configs == null ) { + loadSingerConfigs(); + } + if ( s_singer_configs.ContainsKey( program_change ) ) { + return s_singer_configs[program_change]; + } else { + return null; + } + } + + /// + /// Loads the singer config from ExpDbPath. + /// This method will automatically called when GetSingerInfo method or GetSingerID method is called in first time. + /// + public static void loadSingerConfigs() { + if ( s_singer_configs == null ) { + loadSingerConfigs( getExpDbPath() ); + } + } + + /// + /// Loads the list of singer configuration from the specified path. + /// Keys in the dictionary "s_singer_configs" represents the program change of each singer. + /// + /// + /// + private static void loadSingerConfigs( string path ) { +#if DEBUG + bocoree.debug.push_log( "SingerConfig+LoadSingerConfigs(String)" ); +#endif + s_singer_configs = new Dictionary(); + string map_file = Path.Combine( path, "voice.map" ); + if ( !File.Exists( map_file ) ) { + return; + } + using ( FileStream fs = new FileStream( map_file, FileMode.Open, FileAccess.Read ) ) { + byte[] dat = new byte[8]; + fs.Seek( 0x20, SeekOrigin.Begin ); + for ( int i = 0; i < MAX_SINGERS; i++ ) { + fs.Read( dat, 0, 8 ); + ulong value = makelong_le( dat ); + if ( value >= 1 ) { + string file = Path.Combine( path, "vvoice" + value + ".vvd" ); + if ( File.Exists( file ) ) { + s_singer_configs.Add( i, new SingerConfig( file, (int)(value - 1) ) ); + } + } + } + } + List voiceidstrs = new List(); + foreach ( SingerConfig sc in s_singer_configs.Values ) { + if ( !voiceidstrs.Contains( sc.VOICEIDSTR ) ) { + voiceidstrs.Add( sc.VOICEIDSTR ); + } + } + foreach ( string s in voiceidstrs ) { + string dir = Path.Combine( path, s ); + string[] files = Directory.GetFiles( dir, "*.vvd" ); + foreach ( string s2 in files ) { + string file = Path.Combine( dir, s2 ); + if ( File.Exists( file ) ) { + s_installed_singers.Add( new SingerConfig( file, -1 ) ); + } + } + } +#if DEBUG + bocoree.debug.push_log( " s_singer_configs" ); + foreach ( SingerConfig sc in s_singer_configs.Values ) { + bocoree.debug.push_log( " VOICENAME=" + sc.VOICENAME ); + } + bocoree.debug.push_log( " s_installed_singers" ); + foreach( SingerConfig sc in s_installed_singers ){ + bocoree.debug.push_log( " VOICENAME=" + sc.VOICENAME ); + } +#endif + } + + /// + /// Transform the byte array(length=8) to unsigned long, assuming that the byte array is little endian. + /// + /// + /// + private static ulong makelong_le( byte[] oct ) { + return (ulong)oct[7] << 56 | (ulong)oct[6] << 48 | (ulong)oct[5] << 40 | (ulong)oct[4] << 32 | (ulong)oct[3] << 24 | (ulong)oct[2] << 16 | (ulong)oct[1] << 8 | (ulong)oct[0]; + } + + /// + /// Gets the path of VOCALOID2 Playback VSTi dll. + /// + /// + public static string getDllPathVsti2() { + if ( !s_initialized ) { + init(); + } + return s_dll2_path; + } + + /// + /// Gets the path of VOCALOID1 Playback VSTi dll. + /// + /// + public static string getDllPathVsti1() { + if ( !s_initialized ) { + init(); + } + return s_dll1_path; + } + + /// + /// Initializes the library. + /// + private static void init() { + try { +#if DEBUG + bocoree.debug.push_log( "VsqUtil+Init()" ); +#endif + + // vocaloid2 dll path + Microsoft.Win32.RegistryKey regkey_dll = null; + regkey_dll = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2\\APPLICATION", false ); + if ( regkey_dll == null ) { + regkey_dll = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2_DEMO\\APPLICATION", false ); + } + if ( regkey_dll != null ) { + string[] keys = regkey_dll.GetSubKeyNames(); + for ( int i = 0; i < keys.Length; i++ ) { + Microsoft.Win32.RegistryKey key = regkey_dll.OpenSubKey( keys[i], false ); + if ( key != null ) { + string name = (string)key.GetValue( "PATH" ); + if ( name.ToLower().EndsWith( "\\vocaloid2.dll" ) ) { + s_dll2_path = name; + } else if ( name.ToLower().EndsWith( "\\vocaloid2_demo.dll" ) ) { + s_dll2_path = name; + } else if ( name.ToLower().EndsWith( "\\vocaloid2.exe" ) ) { + s_editor_path = name; + } + key.Close(); + } + } + regkey_dll.Close(); + } + + // vocaloid1 dll path + Microsoft.Win32.RegistryKey regkey_dll1 = null; + regkey_dll1 = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID\\APPLICATION", false ); + if ( regkey_dll1 != null ){ + string[] keys = regkey_dll1.GetSubKeyNames(); + for ( int i = 0; i < keys.Length; i++ ) { + Microsoft.Win32.RegistryKey key = regkey_dll1.OpenSubKey( keys[i], false ); + if ( key != null ) { + string name = (string)key.GetValue( "PATH" ); + if ( name.ToLower().EndsWith( "\\vocaloid.dll" ) ) { + s_dll1_path = name; + key.Close(); + break; + } + key.Close(); + } + } + regkey_dll1.Close(); + } + + // voicedbdir + Microsoft.Win32.RegistryKey regkey_voicedb = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2\\DATABASE\\VOICE", false ); + if ( regkey_voicedb == null ) { + regkey_voicedb = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( "SOFTWARE\\VOCALOID2_DEMO\\DATABASE\\VOICE", false ); + } + if ( regkey_voicedb != null ) { + + string[] keys = regkey_voicedb.GetSubKeyNames(); + for ( int i = 0; i < keys.Length; i++ ) { + Microsoft.Win32.RegistryKey key = regkey_voicedb.OpenSubKey( keys[i], false ); + if ( key != null ) { + string name = (string)key.GetValue( "INSTALLDIR" ); + if ( name.ToLower().EndsWith( "\\voicedbdir" ) ) { + s_exp_db_dir = name; + break; + } + key.Close(); + } + } + regkey_voicedb.Close(); + } + + } catch ( Exception ex ) { + bocoree.debug.push_log( "VsqUtil.Init" ); + bocoree.debug.push_log( " ex=" + ex ); + } finally { + s_initialized = true; +#if DEBUG + bocoree.debug.push_log( " s_dll2_path=" + s_dll2_path ); + bocoree.debug.push_log( " s_exp_db_dir=" + s_exp_db_dir ); +#endif + } + } + + /// + /// Gets the path of directories in which singer expression database is installed. + /// + /// + public static string getExpDbPath() { + if ( !s_initialized ) { + init(); + } + return s_exp_db_dir; + } + } + +} diff --git a/trunk/Boare.Lib.Vsq/comhdr.h b/trunk/Boare.Lib.Vsq/comhdr.h new file mode 100644 index 0000000..e00956e --- /dev/null +++ b/trunk/Boare.Lib.Vsq/comhdr.h @@ -0,0 +1,173 @@ +#ifndef __comhdr_h__ +#define __comhdr_h__ +#include +#include +#include +#include +#include +#include +using namespace std; + +#if __cplusplus +template class Property{ +public: + Property( O *owner_, T (O::*get_)( void ), void (O::*set_)( T ) ) : + owner( owner_ ), + getMethod( get_ ), + setMethod( set_ ){ + } + + operator T(){ + return (owner->*getMethod)(); + } + + void operator=( const T value ){ + (owner->*setMethod)( value ); + } + +private: + O *owner; + T (O::*getMethod)( void ); + void (O::*setMethod)( T ); +}; + +template class ReadOnlyProperty{ +public: + ReadOnlyProperty( O *owner_, T (O::*get_)( void ) ) : + owner( owner_ ), + getMethod( get_ ){ + } + + operator T(){ + return (owner->*getMethod)(); + } + +private: + O *owner; + T (O::*getMethod)( void ); +}; + +template class WriteOnlyProperty{ +public: + WriteOnlyProperty( O *owner_, void (O::*set_)( T ) ) : + owner( owner_ ), + setMethod( set_ ){ + } + + void operator=( const T value ){ + (owner->*setMethod)( value ); + } + +private: + O *owner; + void (O::*setMethod)( T ); +}; + + +#define null NULL +typedef unsigned char byte; +string util_string_from_array( vector str ){ + string ret; + for( int i = 0; i < str.size(); i++ ){ + ret += str[i]; + } + return ret; +} + +string util_string_from_array( vector str, int start, int length ){ + string ret; + for( int i = start; i < str.size() && i - start < length ; i++ ){ + ret += str[i]; + } + return ret; +} + +vector util_string_to_array( string str ){ + std::vector ret( str.size() ); + for( int i = 0; i < str.size(); i++ ){ + ret[i] = str[i]; + } + return ret; +} + +vector util_split( string str, string delim ){ + vector result; + int cutAt; + while( (cutAt = str.find_first_of( delim )) != str.npos ){ + if( cutAt > 0 ){ + result.push_back( str.substr( 0, cutAt ) ); + } + str = str.substr( cutAt + 1 ); + } + if( str.length() > 0 ){ + result.push_back( str ); + } + return result; +} + +int util_parse_int( string str ){ + istringstream s( str ); + int ret = 0; + s >> ret; + return ret; +} +#endif + +namespace Boare{ namespace System{ namespace IO{ + +class StreamReader{ +public: + //StreamReader( Stream stream ); + StreamReader( string path ){ + m_ifs.open( path.c_str() ); + } + //StreamReader( Stream stream, bool detectEncodingFromByteOrderMarks ); + //StreamReader( Stream stream, Encoding encoding ); + //StreamReader( string path, bool detectEncodingFromByteOrderMarks ); + //StreamReader( string path, Encoding encoding ); + //StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks ); + //StreamReader( string path, Encoding encoding, bool detectEncodingFromByteOrderMarks ); + //StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize ); + //StreamReader( string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize ); + void Close(){ + m_ifs.close(); + } + + string ReadLine(){ + string ret; + if( get_line( &m_ifs, &ret ) ){ + return ret; + }else{ + return NULL; + } + } + + int Peek(){ + return m_ifs.peek(); + } +private: + ifstream m_ifs; + static bool get_line( ifstream *ifs, string *str ){ + char ch; + if( ifs->eof() ){ + return false; + } + while( ifs->get( ch ) ){ + if( ch == 0x0d ){ + if( ifs->get( ch ) ){ + if( ch != 0x0a ){ + ifs->seekg( -1, ios::cur ); + } + } + break; + }else if( ch == 0x0a ){ + break; + } + str->append( 1, ch ); + } + return true; + } +}; + +} } } +#endif // __comhdr_h__ diff --git a/trunk/Boare.Lib.Vsq/common.h b/trunk/Boare.Lib.Vsq/common.h new file mode 100644 index 0000000..3e1e9b4 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/common.h @@ -0,0 +1,46 @@ +#ifndef __common_h__ +#define __common_h__ + +#include +#include +#include +#include + +using namespace std; + +namespace Boare{ namespace Lib{ namespace Vsq{ + +typedef struct Color_t{ + int R; + int G; + int B; +} Color; + +vector split( string src, string delim ); + +int int_parse( string str ); + +typedef class StreamReader_t{ +public: + //StreamReader( Stream stream ); + StreamReader_t( string path ); + //StreamReader( Stream stream, bool detectEncodingFromByteOrderMarks ); + //StreamReader( Stream stream, Encoding encoding ); + //StreamReader( string path, bool detectEncodingFromByteOrderMarks ); + //StreamReader( string path, Encoding encoding ); + //StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks ); + //StreamReader( string path, Encoding encoding, bool detectEncodingFromByteOrderMarks ); + //StreamReader( Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize ); + //StreamReader( string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize ); + void Close(); + + string ReadLine(); + + int Peek(); +private: + ifstream m_ifs; + static bool get_line( ifstream *ifs, string *str ); +} StreamReader; + +} } } +#endif diff --git a/trunk/Boare.Lib.Vsq/makefile b/trunk/Boare.Lib.Vsq/makefile new file mode 100644 index 0000000..6db9f8e --- /dev/null +++ b/trunk/Boare.Lib.Vsq/makefile @@ -0,0 +1,21 @@ +CP=cp +RM=rm + +all: Boare.Lib.Vsq.dll libvsq.exe + +Boare.Lib.Vsq.dll: *.cs bocoree.dll + gmcs -recurse:*.cs -target:library -define:MONO -out:Boare.Lib.Vsq.dll -r:bocoree.dll,System,System.Windows.Forms,System.Drawing + +bocoree.dll: ../bocoree/bocoree.dll + cp ../bocoree/bocoree.dll bocoree.dll + +../bocoree/bocoree.dll: + cd ../bocoree/ && $(MAKE) + +libvsq.exe: common.cpp TextMemoryStream.cpp VsqCommon.cpp main.cpp + g++ common.cpp TextMemoryStream.cpp VsqCommon.cpp main.cpp -o libvsq.exe + +clean: + $(RM) Boare.Lib.Vsq.dll + $(RM) bocoree.dll + cd ../bocoree/ && $(MAKE) RM=$(RM) clean diff --git a/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.sln b/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.sln new file mode 100644 index 0000000..08c9bdc --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Boare.Lib.Vsq", "Boare.Lib.Vsq.vcproj", "{19B6B5B7-6ADD-42D9-9F1E-426417DF4827}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {19B6B5B7-6ADD-42D9-9F1E-426417DF4827}.Debug|Win32.ActiveCfg = Debug|Win32 + {19B6B5B7-6ADD-42D9-9F1E-426417DF4827}.Debug|Win32.Build.0 = Debug|Win32 + {19B6B5B7-6ADD-42D9-9F1E-426417DF4827}.Release|Win32.ActiveCfg = Release|Win32 + {19B6B5B7-6ADD-42D9-9F1E-426417DF4827}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.vcproj b/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.vcproj new file mode 100644 index 0000000..5e24423 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/Boare.Lib.Vsq.vcproj @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/Boare.Lib.Vsq/port_cpp/cp932.cpp b/trunk/Boare.Lib.Vsq/port_cpp/cp932.cpp new file mode 100644 index 0000000..23903eb --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/cp932.cpp @@ -0,0 +1,9579 @@ +/* + * cp932.cpp + * Copyright (c) 2008-2009 kbinani + * + * This file is part of utauvsti + * + * utauvsti is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * utauvsti is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +#include "cp932.h" + +static bool cp932_initialized = false; +const int _LEN_DICT = 9484; +static int _DICT_SRC[_LEN_DICT][2]; +static std::map _DICT; + +void cp932_init_cor(){ + int n[_LEN_DICT][2] = { + { 0, 0 }, + { 1, 1 }, + { 2, 2 }, + { 3, 3 }, + { 4, 4 }, + { 5, 5 }, + { 6, 6 }, + { 7, 7 }, + { 8, 8 }, + { 9, 9 }, + { 10, 10 }, + { 11, 11 }, + { 12, 12 }, + { 13, 13 }, + { 14, 14 }, + { 15, 15 }, + { 16, 16 }, + { 17, 17 }, + { 18, 18 }, + { 19, 19 }, + { 20, 20 }, + { 21, 21 }, + { 22, 22 }, + { 23, 23 }, + { 24, 24 }, + { 25, 25 }, + { 26, 26 }, + { 27, 27 }, + { 28, 28 }, + { 29, 29 }, + { 30, 30 }, + { 31, 31 }, + { 32, 32 }, + { 33, 33 }, + { 34, 34 }, + { 35, 35 }, + { 36, 36 }, + { 37, 37 }, + { 38, 38 }, + { 39, 39 }, + { 40, 40 }, + { 41, 41 }, + { 42, 42 }, + { 43, 43 }, + { 44, 44 }, + { 45, 45 }, + { 46, 46 }, + { 47, 47 }, + { 48, 48 }, + { 49, 49 }, + { 50, 50 }, + { 51, 51 }, + { 52, 52 }, + { 53, 53 }, + { 54, 54 }, + { 55, 55 }, + { 56, 56 }, + { 57, 57 }, + { 58, 58 }, + { 59, 59 }, + { 60, 60 }, + { 61, 61 }, + { 62, 62 }, + { 64, 64 }, + { 65, 65 }, + { 66, 66 }, + { 67, 67 }, + { 68, 68 }, + { 69, 69 }, + { 70, 70 }, + { 71, 71 }, + { 72, 72 }, + { 73, 73 }, + { 74, 74 }, + { 75, 75 }, + { 76, 76 }, + { 77, 77 }, + { 78, 78 }, + { 79, 79 }, + { 80, 80 }, + { 81, 81 }, + { 82, 82 }, + { 83, 83 }, + { 84, 84 }, + { 85, 85 }, + { 86, 86 }, + { 87, 87 }, + { 88, 88 }, + { 89, 89 }, + { 90, 90 }, + { 91, 91 }, + { 92, 92 }, + { 93, 93 }, + { 94, 94 }, + { 95, 95 }, + { 96, 96 }, + { 97, 97 }, + { 98, 98 }, + { 99, 99 }, + { 100, 100 }, + { 101, 101 }, + { 102, 102 }, + { 103, 103 }, + { 104, 104 }, + { 105, 105 }, + { 106, 106 }, + { 107, 107 }, + { 108, 108 }, + { 109, 109 }, + { 110, 110 }, + { 111, 111 }, + { 112, 112 }, + { 113, 113 }, + { 114, 114 }, + { 115, 115 }, + { 116, 116 }, + { 117, 117 }, + { 118, 118 }, + { 119, 119 }, + { 120, 120 }, + { 121, 121 }, + { 122, 122 }, + { 123, 123 }, + { 124, 124 }, + { 125, 125 }, + { 126, 126 }, + { 127, 127 }, + { 128, 128 }, + { 161, 33 }, + { 162, 33169 }, + { 163, 33170 }, + { 165, 92 }, + { 166, 124 }, + { 167, 33176 }, + { 168, 33102 }, + { 169, 99 }, + { 170, 97 }, + { 171, 33249 }, + { 172, 33226 }, + { 173, 45 }, + { 174, 82 }, + { 175, 33104 }, + { 176, 33163 }, + { 177, 33149 }, + { 178, 50 }, + { 179, 51 }, + { 180, 33100 }, + { 181, 33738 }, + { 182, 33271 }, + { 183, 33093 }, + { 184, 33091 }, + { 185, 49 }, + { 186, 111 }, + { 187, 33250 }, + { 192, 65 }, + { 193, 65 }, + { 194, 65 }, + { 195, 65 }, + { 196, 65 }, + { 197, 65 }, + { 198, 65 }, + { 199, 67 }, + { 200, 69 }, + { 201, 69 }, + { 202, 69 }, + { 203, 69 }, + { 204, 73 }, + { 205, 73 }, + { 206, 73 }, + { 207, 73 }, + { 208, 68 }, + { 209, 78 }, + { 210, 79 }, + { 211, 79 }, + { 212, 79 }, + { 213, 79 }, + { 214, 79 }, + { 215, 33150 }, + { 216, 79 }, + { 217, 85 }, + { 218, 85 }, + { 219, 85 }, + { 220, 85 }, + { 221, 89 }, + { 222, 84 }, + { 223, 115 }, + { 224, 97 }, + { 225, 97 }, + { 226, 97 }, + { 227, 97 }, + { 228, 97 }, + { 229, 97 }, + { 230, 97 }, + { 231, 99 }, + { 232, 101 }, + { 233, 101 }, + { 234, 101 }, + { 235, 101 }, + { 236, 105 }, + { 237, 105 }, + { 238, 105 }, + { 239, 105 }, + { 240, 100 }, + { 241, 110 }, + { 242, 111 }, + { 243, 111 }, + { 244, 111 }, + { 245, 111 }, + { 246, 111 }, + { 247, 33152 }, + { 248, 111 }, + { 249, 117 }, + { 250, 117 }, + { 251, 117 }, + { 252, 117 }, + { 253, 121 }, + { 254, 116 }, + { 255, 121 }, + { 913, 33695 }, + { 914, 33696 }, + { 915, 33697 }, + { 916, 33698 }, + { 917, 33699 }, + { 918, 33700 }, + { 919, 33701 }, + { 920, 33702 }, + { 921, 33703 }, + { 922, 33704 }, + { 923, 33705 }, + { 924, 33706 }, + { 925, 33707 }, + { 926, 33708 }, + { 927, 33709 }, + { 928, 33710 }, + { 929, 33711 }, + { 931, 33712 }, + { 932, 33713 }, + { 933, 33714 }, + { 934, 33715 }, + { 935, 33716 }, + { 936, 33717 }, + { 937, 33718 }, + { 945, 33727 }, + { 946, 33728 }, + { 947, 33729 }, + { 948, 33730 }, + { 949, 33731 }, + { 950, 33732 }, + { 951, 33733 }, + { 952, 33734 }, + { 953, 33735 }, + { 954, 33736 }, + { 955, 33737 }, + { 956, 33738 }, + { 957, 33739 }, + { 958, 33740 }, + { 959, 33741 }, + { 960, 33742 }, + { 961, 33743 }, + { 963, 33744 }, + { 964, 33745 }, + { 965, 33746 }, + { 966, 33747 }, + { 967, 33748 }, + { 968, 33749 }, + { 969, 33750 }, + { 1025, 33862 }, + { 1040, 33856 }, + { 1041, 33857 }, + { 1042, 33858 }, + { 1043, 33859 }, + { 1044, 33860 }, + { 1045, 33861 }, + { 1046, 33863 }, + { 1047, 33864 }, + { 1048, 33865 }, + { 1049, 33866 }, + { 1050, 33867 }, + { 1051, 33868 }, + { 1052, 33869 }, + { 1053, 33870 }, + { 1054, 33871 }, + { 1055, 33872 }, + { 1056, 33873 }, + { 1057, 33874 }, + { 1058, 33875 }, + { 1059, 33876 }, + { 1060, 33877 }, + { 1061, 33878 }, + { 1062, 33879 }, + { 1063, 33880 }, + { 1064, 33881 }, + { 1065, 33882 }, + { 1066, 33883 }, + { 1067, 33884 }, + { 1068, 33885 }, + { 1069, 33886 }, + { 1070, 33887 }, + { 1071, 33888 }, + { 1072, 33904 }, + { 1073, 33905 }, + { 1074, 33906 }, + { 1075, 33907 }, + { 1076, 33908 }, + { 1077, 33909 }, + { 1078, 33911 }, + { 1079, 33912 }, + { 1080, 33913 }, + { 1081, 33914 }, + { 1082, 33915 }, + { 1083, 33916 }, + { 1084, 33917 }, + { 1085, 33918 }, + { 1086, 33920 }, + { 1087, 33921 }, + { 1088, 33922 }, + { 1089, 33923 }, + { 1090, 33924 }, + { 1091, 33925 }, + { 1092, 33926 }, + { 1093, 33927 }, + { 1094, 33928 }, + { 1095, 33929 }, + { 1096, 33930 }, + { 1097, 33931 }, + { 1098, 33932 }, + { 1099, 33933 }, + { 1100, 33934 }, + { 1101, 33935 }, + { 1102, 33936 }, + { 1103, 33937 }, + { 1105, 33910 }, + { 8208, 33117 }, + { 8213, 33116 }, + { 8216, 33125 }, + { 8217, 33126 }, + { 8220, 33127 }, + { 8221, 33128 }, + { 8224, 33269 }, + { 8225, 33270 }, + { 8229, 33124 }, + { 8230, 33123 }, + { 8240, 33265 }, + { 8242, 33164 }, + { 8243, 33165 }, + { 8251, 33190 }, + { 8451, 33166 }, + { 8470, 34690 }, + { 8481, 34692 }, + { 8491, 33264 }, + { 8544, 34644 }, + { 8545, 34645 }, + { 8546, 34646 }, + { 8547, 34647 }, + { 8548, 34648 }, + { 8549, 34649 }, + { 8550, 34650 }, + { 8551, 34651 }, + { 8552, 34652 }, + { 8553, 34653 }, + { 8560, 64064 }, + { 8561, 64065 }, + { 8562, 64066 }, + { 8563, 64067 }, + { 8564, 64068 }, + { 8565, 64069 }, + { 8566, 64070 }, + { 8567, 64071 }, + { 8568, 64072 }, + { 8569, 64073 }, + { 8592, 33193 }, + { 8593, 33194 }, + { 8594, 33192 }, + { 8595, 33195 }, + { 8658, 33227 }, + { 8660, 33228 }, + { 8704, 33229 }, + { 8706, 33245 }, + { 8707, 33230 }, + { 8711, 33246 }, + { 8712, 33208 }, + { 8715, 33209 }, + { 8721, 34708 }, + { 8730, 33251 }, + { 8733, 33253 }, + { 8734, 33159 }, + { 8735, 34712 }, + { 8736, 33242 }, + { 8741, 33121 }, + { 8743, 33224 }, + { 8744, 33225 }, + { 8745, 33215 }, + { 8746, 33214 }, + { 8747, 33255 }, + { 8748, 33256 }, + { 8750, 34707 }, + { 8756, 33160 }, + { 8757, 33254 }, + { 8765, 33252 }, + { 8786, 33248 }, + { 8800, 33154 }, + { 8801, 33247 }, + { 8806, 33157 }, + { 8807, 33158 }, + { 8810, 33249 }, + { 8811, 33250 }, + { 8834, 33212 }, + { 8835, 33213 }, + { 8838, 33210 }, + { 8839, 33211 }, + { 8869, 33243 }, + { 8895, 34713 }, + { 8978, 33244 }, + { 9312, 34624 }, + { 9313, 34625 }, + { 9314, 34626 }, + { 9315, 34627 }, + { 9316, 34628 }, + { 9317, 34629 }, + { 9318, 34630 }, + { 9319, 34631 }, + { 9320, 34632 }, + { 9321, 34633 }, + { 9322, 34634 }, + { 9323, 34635 }, + { 9324, 34636 }, + { 9325, 34637 }, + { 9326, 34638 }, + { 9327, 34639 }, + { 9328, 34640 }, + { 9329, 34641 }, + { 9330, 34642 }, + { 9331, 34643 }, + { 9472, 33951 }, + { 9473, 33962 }, + { 9474, 33952 }, + { 9475, 33963 }, + { 9484, 33953 }, + { 9487, 33964 }, + { 9488, 33954 }, + { 9491, 33965 }, + { 9492, 33956 }, + { 9495, 33967 }, + { 9496, 33955 }, + { 9499, 33966 }, + { 9500, 33957 }, + { 9501, 33978 }, + { 9504, 33973 }, + { 9507, 33968 }, + { 9508, 33959 }, + { 9509, 33980 }, + { 9512, 33975 }, + { 9515, 33970 }, + { 9516, 33958 }, + { 9519, 33974 }, + { 9520, 33979 }, + { 9523, 33969 }, + { 9524, 33960 }, + { 9527, 33976 }, + { 9528, 33981 }, + { 9531, 33971 }, + { 9532, 33961 }, + { 9535, 33977 }, + { 9538, 33982 }, + { 9547, 33972 }, + { 9632, 33185 }, + { 9633, 33184 }, + { 9650, 33187 }, + { 9651, 33186 }, + { 9660, 33189 }, + { 9661, 33188 }, + { 9670, 33183 }, + { 9671, 33182 }, + { 9675, 33179 }, + { 9678, 33181 }, + { 9679, 33180 }, + { 9711, 33276 }, + { 9733, 33178 }, + { 9734, 33177 }, + { 9792, 33162 }, + { 9794, 33161 }, + { 9834, 33268 }, + { 9837, 33267 }, + { 9839, 33266 }, + { 12288, 33088 }, + { 12289, 33089 }, + { 12290, 33090 }, + { 12291, 33110 }, + { 12293, 33112 }, + { 12294, 33113 }, + { 12295, 33114 }, + { 12296, 33137 }, + { 12297, 33138 }, + { 12298, 33139 }, + { 12299, 33140 }, + { 12300, 33141 }, + { 12301, 33142 }, + { 12302, 33143 }, + { 12303, 33144 }, + { 12304, 33145 }, + { 12305, 33146 }, + { 12306, 33191 }, + { 12307, 33196 }, + { 12308, 33131 }, + { 12309, 33132 }, + { 12317, 34688 }, + { 12319, 34689 }, + { 12353, 33439 }, + { 12354, 33440 }, + { 12355, 33441 }, + { 12356, 33442 }, + { 12357, 33443 }, + { 12358, 33444 }, + { 12359, 33445 }, + { 12360, 33446 }, + { 12361, 33447 }, + { 12362, 33448 }, + { 12363, 33449 }, + { 12364, 33450 }, + { 12365, 33451 }, + { 12366, 33452 }, + { 12367, 33453 }, + { 12368, 33454 }, + { 12369, 33455 }, + { 12370, 33456 }, + { 12371, 33457 }, + { 12372, 33458 }, + { 12373, 33459 }, + { 12374, 33460 }, + { 12375, 33461 }, + { 12376, 33462 }, + { 12377, 33463 }, + { 12378, 33464 }, + { 12379, 33465 }, + { 12380, 33466 }, + { 12381, 33467 }, + { 12382, 33468 }, + { 12383, 33469 }, + { 12384, 33470 }, + { 12385, 33471 }, + { 12386, 33472 }, + { 12387, 33473 }, + { 12388, 33474 }, + { 12389, 33475 }, + { 12390, 33476 }, + { 12391, 33477 }, + { 12392, 33478 }, + { 12393, 33479 }, + { 12394, 33480 }, + { 12395, 33481 }, + { 12396, 33482 }, + { 12397, 33483 }, + { 12398, 33484 }, + { 12399, 33485 }, + { 12400, 33486 }, + { 12401, 33487 }, + { 12402, 33488 }, + { 12403, 33489 }, + { 12404, 33490 }, + { 12405, 33491 }, + { 12406, 33492 }, + { 12407, 33493 }, + { 12408, 33494 }, + { 12409, 33495 }, + { 12410, 33496 }, + { 12411, 33497 }, + { 12412, 33498 }, + { 12413, 33499 }, + { 12414, 33500 }, + { 12415, 33501 }, + { 12416, 33502 }, + { 12417, 33503 }, + { 12418, 33504 }, + { 12419, 33505 }, + { 12420, 33506 }, + { 12421, 33507 }, + { 12422, 33508 }, + { 12423, 33509 }, + { 12424, 33510 }, + { 12425, 33511 }, + { 12426, 33512 }, + { 12427, 33513 }, + { 12428, 33514 }, + { 12429, 33515 }, + { 12430, 33516 }, + { 12431, 33517 }, + { 12432, 33518 }, + { 12433, 33519 }, + { 12434, 33520 }, + { 12435, 33521 }, + { 12436, 33684 }, + { 12443, 33098 }, + { 12444, 33099 }, + { 12445, 33108 }, + { 12446, 33109 }, + { 12449, 33600 }, + { 12450, 33601 }, + { 12451, 33602 }, + { 12452, 33603 }, + { 12453, 33604 }, + { 12454, 33605 }, + { 12455, 33606 }, + { 12456, 33607 }, + { 12457, 33608 }, + { 12458, 33609 }, + { 12459, 33610 }, + { 12460, 33611 }, + { 12461, 33612 }, + { 12462, 33613 }, + { 12463, 33614 }, + { 12464, 33615 }, + { 12465, 33616 }, + { 12466, 33617 }, + { 12467, 33618 }, + { 12468, 33619 }, + { 12469, 33620 }, + { 12470, 33621 }, + { 12471, 33622 }, + { 12472, 33623 }, + { 12473, 33624 }, + { 12474, 33625 }, + { 12475, 33626 }, + { 12476, 33627 }, + { 12477, 33628 }, + { 12478, 33629 }, + { 12479, 33630 }, + { 12480, 33631 }, + { 12481, 33632 }, + { 12482, 33633 }, + { 12483, 33634 }, + { 12484, 33635 }, + { 12485, 33636 }, + { 12486, 33637 }, + { 12487, 33638 }, + { 12488, 33639 }, + { 12489, 33640 }, + { 12490, 33641 }, + { 12491, 33642 }, + { 12492, 33643 }, + { 12493, 33644 }, + { 12494, 33645 }, + { 12495, 33646 }, + { 12496, 33647 }, + { 12497, 33648 }, + { 12498, 33649 }, + { 12499, 33650 }, + { 12500, 33651 }, + { 12501, 33652 }, + { 12502, 33653 }, + { 12503, 33654 }, + { 12504, 33655 }, + { 12505, 33656 }, + { 12506, 33657 }, + { 12507, 33658 }, + { 12508, 33659 }, + { 12509, 33660 }, + { 12510, 33661 }, + { 12511, 33662 }, + { 12512, 33664 }, + { 12513, 33665 }, + { 12514, 33666 }, + { 12515, 33667 }, + { 12516, 33668 }, + { 12517, 33669 }, + { 12518, 33670 }, + { 12519, 33671 }, + { 12520, 33672 }, + { 12521, 33673 }, + { 12522, 33674 }, + { 12523, 33675 }, + { 12524, 33676 }, + { 12525, 33677 }, + { 12526, 33678 }, + { 12527, 33679 }, + { 12528, 33680 }, + { 12529, 33681 }, + { 12530, 33682 }, + { 12531, 33683 }, + { 12532, 33684 }, + { 12533, 33685 }, + { 12534, 33686 }, + { 12539, 33093 }, + { 12540, 33115 }, + { 12541, 33106 }, + { 12542, 33107 }, + { 12849, 34698 }, + { 12850, 34699 }, + { 12857, 34700 }, + { 12964, 34693 }, + { 12965, 34694 }, + { 12966, 34695 }, + { 12967, 34696 }, + { 12968, 34697 }, + { 13059, 34661 }, + { 13069, 34665 }, + { 13076, 34656 }, + { 13080, 34659 }, + { 13090, 34657 }, + { 13091, 34667 }, + { 13094, 34666 }, + { 13095, 34660 }, + { 13099, 34668 }, + { 13110, 34662 }, + { 13115, 34670 }, + { 13129, 34655 }, + { 13130, 34669 }, + { 13133, 34658 }, + { 13137, 34663 }, + { 13143, 34664 }, + { 13179, 34686 }, + { 13180, 34703 }, + { 13181, 34702 }, + { 13182, 34701 }, + { 13198, 34674 }, + { 13199, 34675 }, + { 13212, 34671 }, + { 13213, 34672 }, + { 13214, 34673 }, + { 13217, 34677 }, + { 13252, 34676 }, + { 13261, 34691 }, + { 19968, 35050 }, + { 19969, 37530 }, + { 19971, 36533 }, + { 19975, 38556 }, + { 19976, 36836 }, + { 19977, 36431 }, + { 19978, 36835 }, + { 19979, 35258 }, + { 19981, 38259 }, + { 19982, 38750 }, + { 19984, 39072 }, + { 19985, 35150 }, + { 19988, 35470 }, + { 19989, 39073 }, + { 19990, 37026 }, + { 19991, 39360 }, + { 19992, 35701 }, + { 19993, 38328 }, + { 19998, 36837 }, + { 20001, 38844 }, + { 20006, 38336 }, + { 20008, 64104 }, + { 20010, 39074 }, + { 20013, 37510 }, + { 20017, 39075 }, + { 20018, 35832 }, + { 20022, 39076 }, + { 20024, 35547 }, + { 20025, 37455 }, + { 20027, 36581 }, + { 20028, 39077 }, + { 20031, 39078 }, + { 20034, 39079 }, + { 20035, 37972 }, + { 20037, 35702 }, + { 20043, 37974 }, + { 20045, 37857 }, + { 20046, 36033 }, + { 20047, 38482 }, + { 20053, 58728 }, + { 20054, 39080 }, + { 20055, 36838 }, + { 20056, 39081 }, + { 20057, 35251 }, + { 20061, 35811 }, + { 20062, 36078 }, + { 20063, 38631 }, + { 20066, 39844 }, + { 20081, 38800 }, + { 20083, 37883 }, + { 20094, 35491 }, + { 20096, 35668 }, + { 20098, 39082 }, + { 20101, 39083 }, + { 20102, 38841 }, + { 20104, 38748 }, + { 20105, 37256 }, + { 20106, 39085 }, + { 20107, 36502 }, + { 20108, 37873 }, + { 20110, 39088 }, + { 20113, 35165 }, + { 20114, 36061 }, + { 20116, 36060 }, + { 20117, 35044 }, + { 20120, 39018 }, + { 20121, 39017 }, + { 20123, 36273 }, + { 20124, 34975 }, + { 20126, 39089 }, + { 20127, 39090 }, + { 20128, 39091 }, + { 20129, 38483 }, + { 20130, 39092 }, + { 20132, 36080 }, + { 20133, 35045 }, + { 20134, 38546 }, + { 20136, 35740 }, + { 20139, 35741 }, + { 20140, 35742 }, + { 20141, 37600 }, + { 20142, 38842 }, + { 20144, 39093 }, + { 20147, 39094 }, + { 20150, 39095 }, + { 20154, 36972 }, + { 20160, 36697 }, + { 20161, 36973 }, + { 20162, 39100 }, + { 20164, 39098 }, + { 20166, 39099 }, + { 20167, 35703 }, + { 20170, 36257 }, + { 20171, 35310 }, + { 20173, 39097 }, + { 20174, 39096 }, + { 20175, 38311 }, + { 20180, 36453 }, + { 20181, 36452 }, + { 20182, 37308 }, + { 20183, 39101 }, + { 20184, 38260 }, + { 20185, 37093 }, + { 20189, 33111 }, + { 20190, 39102 }, + { 20191, 39104 }, + { 20193, 64105 }, + { 20195, 37347 }, + { 20196, 38879 }, + { 20197, 35016 }, + { 20205, 39103 }, + { 20206, 35260 }, + { 20208, 35778 }, + { 20210, 37511 }, + { 20214, 35983 }, + { 20215, 39105 }, + { 20219, 37955 }, + { 20220, 64106 }, + { 20224, 64107 }, + { 20225, 35561 }, + { 20227, 64108 }, + { 20233, 39106 }, + { 20234, 35017 }, + { 20237, 36062 }, + { 20238, 35562 }, + { 20239, 38298 }, + { 20240, 38064 }, + { 20241, 35704 }, + { 20250, 35311 }, + { 20252, 39141 }, + { 20253, 37728 }, + { 20271, 38028 }, + { 20272, 39108 }, + { 20276, 38074 }, + { 20278, 38880 }, + { 20280, 36940 }, + { 20281, 64109 }, + { 20282, 36454 }, + { 20284, 36503 }, + { 20285, 35262 }, + { 20291, 37583 }, + { 20294, 37441 }, + { 20295, 39112 }, + { 20301, 35018 }, + { 20302, 37601 }, + { 20303, 36698 }, + { 20304, 36274 }, + { 20305, 38723 }, + { 20307, 37324 }, + { 20309, 35261 }, + { 20310, 64110 }, + { 20311, 39111 }, + { 20313, 38749 }, + { 20314, 39107 }, + { 20315, 39109 }, + { 20316, 36332 }, + { 20317, 39110 }, + { 20318, 39747 }, + { 20329, 39118 }, + { 20335, 39121 }, + { 20336, 39119 }, + { 20339, 35264 }, + { 20341, 38329 }, + { 20342, 39113 }, + { 20347, 39117 }, + { 20348, 36081 }, + { 20351, 36455 }, + { 20355, 35492 }, + { 20358, 39122 }, + { 20360, 39114 }, + { 20362, 64112 }, + { 20363, 38881 }, + { 20365, 36504 }, + { 20367, 39115 }, + { 20369, 39120 }, + { 20370, 64111 }, + { 20372, 64114 }, + { 20374, 39123 }, + { 20376, 39116 }, + { 20378, 64113 }, + { 20379, 35743 }, + { 20381, 35019 }, + { 20384, 35744 }, + { 20385, 35263 }, + { 20395, 39748 }, + { 20397, 38553 }, + { 20398, 38286 }, + { 20399, 36082 }, + { 20405, 36942 }, + { 20406, 38837 }, + { 20415, 38358 }, + { 20418, 35927 }, + { 20419, 37283 }, + { 20420, 35298 }, + { 20425, 64097 }, + { 20426, 36722 }, + { 20429, 64115 }, + { 20430, 39127 }, + { 20432, 39132 }, + { 20433, 39130 }, + { 20436, 39125 }, + { 20439, 37293 }, + { 20440, 39128 }, + { 20442, 39131 }, + { 20443, 39129 }, + { 20445, 38363 }, + { 20447, 39126 }, + { 20449, 36941 }, + { 20451, 38547 }, + { 20452, 39133 }, + { 20453, 39134 }, + { 20462, 36675 }, + { 20463, 39147 }, + { 20467, 37999 }, + { 20469, 38229 }, + { 20470, 39142 }, + { 20472, 38382 }, + { 20474, 35252 }, + { 20478, 39146 }, + { 20479, 64118 }, + { 20485, 39140 }, + { 20486, 39149 }, + { 20489, 37233 }, + { 20491, 36034 }, + { 20493, 38011 }, + { 20495, 57541 }, + { 20497, 39148 }, + { 20498, 37756 }, + { 20500, 39137 }, + { 20502, 36084 }, + { 20505, 36083 }, + { 20506, 39135 }, + { 20510, 64119 }, + { 20511, 36568 }, + { 20513, 39143 }, + { 20514, 64117 }, + { 20515, 38381 }, + { 20516, 37484 }, + { 20517, 39139 }, + { 20518, 35985 }, + { 20520, 39136 }, + { 20521, 39144 }, + { 20522, 39138 }, + { 20523, 38863 }, + { 20524, 39145 }, + { 20525, 39008 }, + { 20534, 35812 }, + { 20537, 35984 }, + { 20544, 64116 }, + { 20546, 64122 }, + { 20547, 39150 }, + { 20550, 64120 }, + { 20551, 39151 }, + { 20552, 39155 }, + { 20553, 35020 }, + { 20559, 38350 }, + { 20560, 39154 }, + { 20565, 39153 }, + { 20566, 39157 }, + { 20570, 39156 }, + { 20572, 37602 }, + { 20581, 35986 }, + { 20588, 39158 }, + { 20592, 64121 }, + { 20594, 36547 }, + { 20596, 37284 }, + { 20597, 37603 }, + { 20598, 35828 }, + { 20600, 39159 }, + { 20605, 35669 }, + { 20608, 39160 }, + { 20613, 39162 }, + { 20621, 38484 }, + { 20625, 35974 }, + { 20628, 64123 }, + { 20632, 36432 }, + { 20633, 38133 }, + { 20634, 39161 }, + { 20652, 36291 }, + { 20653, 38754 }, + { 20658, 39164 }, + { 20659, 39234 }, + { 20660, 39163 }, + { 20661, 36290 }, + { 20663, 36765 }, + { 20670, 35928 }, + { 20674, 39235 }, + { 20677, 35789 }, + { 20681, 39232 }, + { 20682, 39233 }, + { 20685, 37805 }, + { 20687, 37276 }, + { 20689, 35745 }, + { 20693, 38508 }, + { 20694, 39236 }, + { 20696, 64125 }, + { 20698, 38843 }, + { 20702, 39237 }, + { 20707, 39240 }, + { 20709, 39238 }, + { 20711, 37229 }, + { 20717, 39239 }, + { 20718, 39241 }, + { 20724, 64124 }, + { 20725, 39243 }, + { 20729, 39242 }, + { 20731, 38342 }, + { 20736, 35670 }, + { 20737, 39245 }, + { 20738, 39246 }, + { 20740, 35245 }, + { 20745, 39244 }, + { 20754, 36594 }, + { 20756, 39249 }, + { 20757, 39248 }, + { 20758, 39247 }, + { 20760, 39124 }, + { 20762, 39250 }, + { 20767, 36766 }, + { 20769, 39251 }, + { 20778, 38724 }, + { 20786, 38615 }, + { 20791, 39253 }, + { 20794, 39252 }, + { 20795, 39255 }, + { 20796, 39254 }, + { 20799, 39256 }, + { 20800, 39257 }, + { 20801, 35058 }, + { 20803, 36019 }, + { 20804, 35930 }, + { 20805, 36699 }, + { 20806, 37531 }, + { 20807, 35746 }, + { 20808, 37094 }, + { 20809, 36085 }, + { 20810, 64126 }, + { 20811, 36238 }, + { 20812, 39259 }, + { 20813, 38598 }, + { 20814, 37733 }, + { 20816, 36505 }, + { 20818, 39258 }, + { 20820, 39260 }, + { 20826, 37757 }, + { 20828, 35477 }, + { 20834, 39261 }, + { 20836, 64128 }, + { 20837, 37884 }, + { 20840, 37203 }, + { 20841, 39263 }, + { 20842, 39264 }, + { 20843, 38058 }, + { 20844, 36086 }, + { 20845, 39002 }, + { 20846, 39265 }, + { 20849, 35748 }, + { 20853, 38330 }, + { 20854, 37300 }, + { 20855, 35823 }, + { 20856, 37716 }, + { 20860, 35987 }, + { 20864, 39266 }, + { 20866, 39267 }, + { 20869, 37856 }, + { 20870, 35198 }, + { 20873, 39270 }, + { 20874, 36347 }, + { 20876, 39269 }, + { 20877, 36292 }, + { 20879, 39271 }, + { 20880, 58348 }, + { 20881, 39272 }, + { 20882, 38496 }, + { 20883, 39273 }, + { 20885, 39274 }, + { 20886, 39275 }, + { 20887, 36839 }, + { 20889, 36554 }, + { 20893, 64129 }, + { 20896, 35493 }, + { 20898, 39278 }, + { 20900, 39276 }, + { 20901, 38587 }, + { 20902, 39277 }, + { 20904, 38265 }, + { 20905, 39279 }, + { 20906, 39280 }, + { 20907, 39281 }, + { 20908, 37758 }, + { 20912, 39285 }, + { 20913, 39283 }, + { 20914, 39284 }, + { 20915, 39282 }, + { 20916, 36321 }, + { 20917, 39286 }, + { 20918, 38632 }, + { 20919, 38882 }, + { 20925, 39287 }, + { 20926, 64130 }, + { 20932, 37030 }, + { 20933, 39288 }, + { 20934, 36729 }, + { 20937, 39289 }, + { 20939, 37532 }, + { 20940, 38845 }, + { 20941, 37760 }, + { 20950, 39363 }, + { 20955, 39290 }, + { 20956, 60067 }, + { 20957, 35779 }, + { 20960, 39291 }, + { 20961, 38525 }, + { 20966, 36744 }, + { 20967, 37370 }, + { 20969, 39293 }, + { 20970, 37858 }, + { 20972, 64131 }, + { 20973, 39294 }, + { 20976, 39296 }, + { 20977, 35405 }, + { 20981, 39297 }, + { 20982, 35749 }, + { 20984, 37834 }, + { 20985, 35226 }, + { 20986, 36719 }, + { 20989, 38047 }, + { 20990, 39298 }, + { 20992, 37761 }, + { 20995, 36974 }, + { 20996, 39299 }, + { 20998, 38314 }, + { 20999, 37080 }, + { 21000, 35488 }, + { 21002, 35495 }, + { 21003, 39300 }, + { 21006, 39302 }, + { 21009, 35929 }, + { 21012, 39301 }, + { 21013, 64132 }, + { 21015, 38897 }, + { 21021, 36745 }, + { 21028, 38075 }, + { 21029, 38346 }, + { 21031, 39303 }, + { 21033, 38808 }, + { 21034, 39304 }, + { 21038, 39305 }, + { 21040, 37790 }, + { 21043, 39306 }, + { 21046, 37031 }, + { 21047, 36348 }, + { 21048, 35988 }, + { 21049, 39307 }, + { 21050, 36456 }, + { 21051, 36239 }, + { 21059, 37604 }, + { 21060, 39309 }, + { 21063, 37285 }, + { 21066, 36333 }, + { 21067, 39310 }, + { 21068, 39311 }, + { 21069, 37199 }, + { 21071, 39308 }, + { 21076, 39313 }, + { 21078, 38485 }, + { 21083, 36228 }, + { 21086, 39312 }, + { 21091, 35989 }, + { 21092, 36316 }, + { 21093, 38029 }, + { 21097, 39316 }, + { 21098, 39314 }, + { 21103, 38299 }, + { 21104, 36840 }, + { 21105, 39323 }, + { 21106, 35460 }, + { 21107, 39317 }, + { 21108, 39315 }, + { 21109, 37230 }, + { 21117, 39319 }, + { 21119, 39318 }, + { 21123, 35427 }, + { 21127, 35968 }, + { 21128, 39324 }, + { 21129, 38827 }, + { 21133, 39320 }, + { 21137, 39325 }, + { 21138, 39322 }, + { 21140, 39321 }, + { 21147, 38861 }, + { 21148, 64133 }, + { 21151, 36087 }, + { 21152, 35265 }, + { 21155, 38898 }, + { 21158, 64134 }, + { 21161, 36757 }, + { 21162, 37751 }, + { 21163, 36229 }, + { 21164, 39328 }, + { 21165, 39329 }, + { 21167, 64375 }, + { 21169, 38883 }, + { 21172, 38986 }, + { 21173, 39331 }, + { 21177, 36088 }, + { 21180, 39330 }, + { 21182, 35406 }, + { 21184, 64135 }, + { 21185, 39332 }, + { 21187, 38517 }, + { 21189, 37562 }, + { 21191, 38725 }, + { 21193, 38359 }, + { 21197, 39333 }, + { 21202, 59603 }, + { 21205, 37806 }, + { 21207, 39334 }, + { 21208, 35496 }, + { 21209, 38577 }, + { 21211, 64136 }, + { 21213, 36767 }, + { 21214, 39335 }, + { 21215, 38373 }, + { 21216, 39339 }, + { 21218, 37032 }, + { 21219, 39336 }, + { 21220, 35790 }, + { 21222, 39337 }, + { 21223, 35497 }, + { 21234, 35917 }, + { 21235, 39340 }, + { 21237, 39341 }, + { 21240, 39342 }, + { 21241, 39343 }, + { 21242, 36569 }, + { 21246, 36089 }, + { 21247, 38620 }, + { 21248, 64137 }, + { 21249, 38630 }, + { 21250, 37877 }, + { 21253, 38383 }, + { 21254, 39344 }, + { 21255, 64138 }, + { 21256, 39345 }, + { 21261, 39347 }, + { 21263, 39349 }, + { 21264, 39348 }, + { 21269, 39350 }, + { 21270, 35259 }, + { 21271, 38507 }, + { 21273, 36346 }, + { 21274, 39351 }, + { 21277, 37240 }, + { 21280, 36768 }, + { 21281, 35751 }, + { 21283, 39352 }, + { 21284, 64139 }, + { 21290, 38105 }, + { 21295, 39353 }, + { 21297, 39354 }, + { 21299, 39355 }, + { 21304, 39356 }, + { 21305, 38211 }, + { 21306, 35814 }, + { 21307, 35043 }, + { 21311, 37821 }, + { 21312, 39357 }, + { 21313, 36700 }, + { 21315, 37095 }, + { 21317, 39359 }, + { 21318, 39358 }, + { 21319, 36769 }, + { 21320, 36063 }, + { 21321, 39361 }, + { 21322, 38076 }, + { 21325, 39362 }, + { 21329, 38106 }, + { 21330, 37298 }, + { 21331, 37356 }, + { 21332, 35750 }, + { 21335, 37868 }, + { 21336, 37456 }, + { 21338, 38030 }, + { 21340, 38509 }, + { 21342, 39364 }, + { 21344, 37096 }, + { 21350, 35924 }, + { 21353, 39365 }, + { 21358, 39366 }, + { 21359, 35147 }, + { 21360, 35059 }, + { 21361, 35563 }, + { 21362, 64140 }, + { 21363, 37286 }, + { 21364, 35696 }, + { 21365, 38801 }, + { 21367, 39369 }, + { 21368, 35253 }, + { 21371, 39368 }, + { 21375, 35752 }, + { 21378, 39370 }, + { 21380, 38639 }, + { 21395, 64141 }, + { 21398, 39371 }, + { 21400, 38864 }, + { 21402, 36090 }, + { 21407, 36020 }, + { 21408, 39372 }, + { 21413, 39374 }, + { 21414, 39373 }, + { 21416, 36990 }, + { 21417, 35160 }, + { 21421, 35197 }, + { 21422, 39375 }, + { 21424, 39376 }, + { 21426, 64142 }, + { 21427, 36021 }, + { 21430, 39377 }, + { 21435, 35726 }, + { 21442, 36433 }, + { 21443, 39378 }, + { 21448, 38548 }, + { 21449, 36275 }, + { 21450, 35705 }, + { 21451, 38726 }, + { 21452, 37231 }, + { 21453, 38077 }, + { 21454, 36603 }, + { 21460, 36710 }, + { 21462, 36582 }, + { 21463, 36595 }, + { 21465, 36758 }, + { 21467, 38078 }, + { 21469, 64143 }, + { 21471, 39381 }, + { 21473, 35170 }, + { 21474, 37232 }, + { 21475, 36091 }, + { 21476, 36035 }, + { 21477, 35813 }, + { 21480, 39385 }, + { 21481, 37440 }, + { 21482, 37372 }, + { 21483, 35753 }, + { 21484, 36770 }, + { 21485, 39386 }, + { 21486, 39384 }, + { 21487, 35266 }, + { 21488, 37348 }, + { 21489, 36534 }, + { 21490, 36458 }, + { 21491, 35141 }, + { 21494, 35472 }, + { 21495, 36230 }, + { 21496, 36457 }, + { 21498, 39387 }, + { 21505, 39388 }, + { 21507, 35688 }, + { 21508, 35429 }, + { 21512, 36231 }, + { 21513, 35687 }, + { 21514, 37597 }, + { 21515, 35140 }, + { 21516, 37807 }, + { 21517, 38588 }, + { 21518, 36160 }, + { 21519, 38809 }, + { 21520, 37734 }, + { 21521, 36092 }, + { 21531, 35918 }, + { 21533, 39397 }, + { 21535, 35809 }, + { 21536, 38505 }, + { 21542, 38107 }, + { 21545, 39396 }, + { 21547, 35548 }, + { 21548, 39391 }, + { 21549, 39392 }, + { 21550, 39394 }, + { 21558, 39395 }, + { 21560, 35706 }, + { 21561, 36993 }, + { 21563, 38315 }, + { 21564, 39393 }, + { 21565, 39389 }, + { 21566, 36065 }, + { 21568, 39390 }, + { 21570, 38979 }, + { 21574, 38384 }, + { 21576, 37606 }, + { 21577, 36064 }, + { 21578, 36240 }, + { 21582, 39398 }, + { 21585, 37851 }, + { 21599, 39402 }, + { 21608, 36604 }, + { 21610, 36596 }, + { 21616, 39405 }, + { 21617, 39403 }, + { 21619, 38561 }, + { 21621, 39400 }, + { 21622, 39409 }, + { 21623, 39404 }, + { 21627, 39407 }, + { 21628, 36036 }, + { 21629, 38589 }, + { 21632, 39408 }, + { 21636, 39410 }, + { 21638, 39412 }, + { 21642, 64146 }, + { 21643, 36334 }, + { 21644, 39009 }, + { 21646, 39401 }, + { 21647, 39399 }, + { 21648, 39411 }, + { 21650, 39406 }, + { 21660, 64145 }, + { 21666, 39414 }, + { 21668, 39490 }, + { 21669, 39416 }, + { 21672, 39420 }, + { 21673, 64147 }, + { 21675, 39488 }, + { 21676, 39417 }, + { 21679, 39517 }, + { 21682, 36327 }, + { 21683, 35408 }, + { 21688, 39415 }, + { 21692, 39492 }, + { 21693, 35060 }, + { 21694, 39491 }, + { 21696, 34979 }, + { 21697, 38249 }, + { 21698, 39489 }, + { 21700, 39418 }, + { 21703, 39413 }, + { 21704, 39419 }, + { 21705, 36294 }, + { 21720, 39493 }, + { 21729, 35061 }, + { 21730, 39502 }, + { 21733, 39494 }, + { 21734, 39495 }, + { 21736, 36771 }, + { 21737, 38537 }, + { 21741, 39500 }, + { 21742, 39499 }, + { 21746, 37710 }, + { 21754, 39501 }, + { 21757, 39498 }, + { 21759, 64148 }, + { 21764, 35155 }, + { 21766, 36276 }, + { 21767, 36943 }, + { 21775, 39496 }, + { 21776, 37762 }, + { 21780, 39497 }, + { 21782, 34976 }, + { 21806, 39507 }, + { 21807, 38722 }, + { 21809, 36773 }, + { 21811, 39513 }, + { 21816, 39512 }, + { 21817, 39503 }, + { 21822, 37313 }, + { 21824, 39504 }, + { 21828, 37357 }, + { 21829, 39509 }, + { 21830, 36772 }, + { 21836, 39506 }, + { 21839, 38626 }, + { 21843, 35931 }, + { 21846, 39510 }, + { 21847, 39511 }, + { 21852, 39508 }, + { 21853, 39514 }, + { 21859, 39505 }, + { 21883, 39520 }, + { 21884, 39525 }, + { 21886, 39521 }, + { 21888, 39516 }, + { 21891, 39526 }, + { 21892, 37200 }, + { 21894, 64149 }, + { 21895, 39528 }, + { 21897, 36161 }, + { 21898, 39518 }, + { 21899, 37533 }, + { 21912, 39522 }, + { 21913, 39515 }, + { 21914, 35499 }, + { 21916, 35564 }, + { 21917, 35461 }, + { 21918, 39523 }, + { 21919, 39519 }, + { 21927, 35990 }, + { 21928, 39529 }, + { 21929, 39527 }, + { 21930, 37234 }, + { 21931, 35689 }, + { 21932, 35754 }, + { 21934, 39524 }, + { 21936, 35826 }, + { 21942, 35171 }, + { 21956, 39533 }, + { 21957, 39531 }, + { 21959, 39589 }, + { 21972, 39536 }, + { 21978, 39530 }, + { 21980, 39534 }, + { 21983, 39532 }, + { 21987, 36459 }, + { 21988, 39535 }, + { 22007, 39538 }, + { 22009, 39543 }, + { 22013, 39541 }, + { 22014, 39540 }, + { 22022, 37457 }, + { 22025, 35267 }, + { 22036, 39537 }, + { 22038, 39539 }, + { 22039, 36774 }, + { 22040, 35154 }, + { 22043, 39542 }, + { 22057, 35292 }, + { 22063, 39554 }, + { 22065, 36858 }, + { 22066, 39549 }, + { 22068, 39547 }, + { 22070, 39548 }, + { 22072, 39550 }, + { 22082, 35164 }, + { 22092, 37208 }, + { 22094, 39544 }, + { 22096, 39545 }, + { 22107, 35482 }, + { 22116, 39553 }, + { 22120, 35565 }, + { 22122, 39556 }, + { 22123, 39552 }, + { 22124, 39555 }, + { 22132, 38316 }, + { 22136, 37843 }, + { 22138, 38070 }, + { 22144, 39558 }, + { 22150, 39557 }, + { 22151, 35428 }, + { 22154, 39559 }, + { 22159, 39562 }, + { 22164, 39561 }, + { 22176, 39560 }, + { 22178, 37976 }, + { 22181, 39563 }, + { 22190, 39564 }, + { 22196, 39566 }, + { 22198, 39565 }, + { 22204, 39568 }, + { 22208, 39571 }, + { 22209, 39569 }, + { 22210, 39567 }, + { 22211, 39570 }, + { 22216, 39572 }, + { 22222, 39573 }, + { 22225, 39574 }, + { 22227, 39575 }, + { 22231, 39576 }, + { 22232, 39268 }, + { 22234, 36602 }, + { 22235, 36460 }, + { 22238, 35313 }, + { 22240, 35062 }, + { 22243, 37475 }, + { 22254, 39577 }, + { 22256, 36258 }, + { 22258, 35021 }, + { 22259, 36989 }, + { 22265, 39578 }, + { 22266, 36037 }, + { 22269, 36241 }, + { 22271, 39580 }, + { 22272, 39579 }, + { 22275, 38366 }, + { 22276, 39581 }, + { 22280, 39583 }, + { 22281, 39582 }, + { 22283, 39584 }, + { 22285, 39585 }, + { 22287, 35991 }, + { 22290, 35200 }, + { 22291, 39586 }, + { 22294, 39588 }, + { 22296, 39587 }, + { 22300, 39590 }, + { 22303, 37753 }, + { 22310, 39591 }, + { 22311, 34995 }, + { 22312, 36317 }, + { 22317, 35932 }, + { 22320, 37486 }, + { 22327, 39592 }, + { 22328, 39593 }, + { 22331, 39595 }, + { 22336, 39596 }, + { 22338, 36322 }, + { 22343, 35791 }, + { 22346, 38486 }, + { 22350, 39594 }, + { 22351, 39597 }, + { 22352, 36287 }, + { 22353, 36162 }, + { 22361, 64150 }, + { 22369, 39601 }, + { 22372, 36259 }, + { 22373, 64151 }, + { 22374, 37458 }, + { 22377, 39598 }, + { 22378, 37592 }, + { 22399, 39602 }, + { 22402, 36994 }, + { 22408, 39600 }, + { 22409, 39603 }, + { 22411, 35934 }, + { 22419, 39604 }, + { 22432, 39605 }, + { 22434, 36163 }, + { 22435, 35423 }, + { 22436, 39607 }, + { 22442, 39608 }, + { 22444, 64152 }, + { 22448, 39609 }, + { 22451, 39606 }, + { 22464, 39599 }, + { 22467, 39610 }, + { 22470, 39611 }, + { 22471, 64154 }, + { 22472, 64153 }, + { 22475, 38532 }, + { 22478, 36841 }, + { 22482, 39613 }, + { 22483, 39614 }, + { 22484, 39612 }, + { 22486, 39616 }, + { 22492, 37975 }, + { 22495, 35046 }, + { 22496, 38261 }, + { 22499, 39617 }, + { 22516, 36859 }, + { 22519, 36535 }, + { 22521, 38012 }, + { 22522, 35566 }, + { 22524, 36329 }, + { 22528, 38520 }, + { 22530, 37808 }, + { 22533, 35992 }, + { 22534, 37325 }, + { 22538, 39615 }, + { 22539, 39618 }, + { 22549, 37314 }, + { 22553, 39619 }, + { 22557, 39620 }, + { 22561, 39622 }, + { 22564, 37607 }, + { 22570, 35500 }, + { 22575, 60063 }, + { 22576, 35201 }, + { 22577, 38385 }, + { 22580, 36842 }, + { 22581, 37735 }, + { 22586, 36324 }, + { 22589, 39628 }, + { 22592, 38331 }, + { 22593, 38875 }, + { 22602, 35314 }, + { 22603, 39624 }, + { 22609, 37209 }, + { 22610, 39627 }, + { 22612, 37763 }, + { 22615, 37736 }, + { 22616, 37764 }, + { 22617, 38071 }, + { 22618, 37579 }, + { 22622, 36295 }, + { 22626, 39623 }, + { 22633, 35222 }, + { 22635, 37717 }, + { 22640, 39625 }, + { 22642, 39621 }, + { 22645, 36975 }, + { 22649, 39629 }, + { 22654, 36717 }, + { 22659, 35755 }, + { 22661, 39630 }, + { 22675, 38374 }, + { 22679, 37277 }, + { 22684, 37572 }, + { 22686, 64157 }, + { 22687, 39632 }, + { 22696, 38510 }, + { 22699, 39633 }, + { 22702, 39638 }, + { 22706, 64158 }, + { 22707, 38317 }, + { 22712, 39637 }, + { 22713, 39631 }, + { 22714, 39634 }, + { 22715, 39636 }, + { 22718, 36260 }, + { 22721, 38343 }, + { 22725, 39639 }, + { 22727, 37476 }, + { 22730, 35315 }, + { 22732, 36843 }, + { 22737, 39641 }, + { 22739, 39640 }, + { 22741, 36232 }, + { 22743, 39642 }, + { 22744, 39644 }, + { 22745, 39643 }, + { 22748, 39646 }, + { 22750, 39635 }, + { 22751, 39648 }, + { 22756, 39647 }, + { 22757, 39645 }, + { 22763, 36461 }, + { 22764, 36976 }, + { 22766, 37235 }, + { 22767, 39649 }, + { 22768, 37050 }, + { 22769, 35051 }, + { 22770, 38020 }, + { 22775, 37593 }, + { 22777, 39651 }, + { 22778, 39650 }, + { 22779, 39652 }, + { 22780, 39653 }, + { 22781, 39654 }, + { 22786, 39655 }, + { 22793, 38351 }, + { 22794, 39656 }, + { 22795, 64159 }, + { 22799, 35268 }, + { 22800, 39657 }, + { 22805, 38747 }, + { 22806, 35407 }, + { 22808, 39367 }, + { 22809, 36711 }, + { 22810, 37309 }, + { 22811, 39658 }, + { 22812, 38633 }, + { 22818, 38578 }, + { 22821, 39660 }, + { 22823, 37349 }, + { 22825, 37718 }, + { 22826, 37310 }, + { 22827, 38262 }, + { 22828, 39661 }, + { 22829, 39662 }, + { 22830, 35227 }, + { 22833, 36536 }, + { 22834, 39663 }, + { 22839, 35022 }, + { 22840, 39664 }, + { 22846, 39665 }, + { 22852, 35202 }, + { 22855, 35567 }, + { 22856, 37854 }, + { 22857, 38386 }, + { 22862, 39669 }, + { 22863, 37236 }, + { 22864, 39668 }, + { 22865, 35935 }, + { 22867, 64160 }, + { 22868, 38522 }, + { 22869, 39667 }, + { 22871, 37765 }, + { 22872, 39671 }, + { 22874, 39670 }, + { 22875, 64161 }, + { 22877, 64162 }, + { 22880, 39673 }, + { 22882, 39672 }, + { 22883, 64163 }, + { 22885, 35228 }, + { 22887, 39674 }, + { 22888, 36775 }, + { 22889, 39676 }, + { 22890, 37444 }, + { 22892, 39675 }, + { 22894, 38321 }, + { 22899, 36759 }, + { 22900, 37754 }, + { 22904, 39744 }, + { 22909, 36164 }, + { 22913, 39745 }, + { 22914, 37952 }, + { 22915, 38108 }, + { 22916, 38607 }, + { 22922, 37956 }, + { 22925, 39754 }, + { 22931, 35671 }, + { 22934, 38756 }, + { 22937, 38573 }, + { 22939, 39850 }, + { 22941, 39746 }, + { 22947, 39749 }, + { 22948, 64164 }, + { 22949, 37315 }, + { 22952, 38487 }, + { 22956, 37737 }, + { 22962, 39750 }, + { 22969, 38533 }, + { 22970, 64165 }, + { 22971, 36296 }, + { 22974, 36776 }, + { 22982, 39751 }, + { 22985, 36463 }, + { 22987, 36462 }, + { 22992, 34999 }, + { 22993, 36038 }, + { 22995, 37033 }, + { 22996, 35023 }, + { 23001, 39755 }, + { 23002, 39756 }, + { 23004, 39753 }, + { 23013, 35159 }, + { 23014, 35501 }, + { 23016, 39752 }, + { 23018, 38595 }, + { 23019, 38224 }, + { 23030, 34982 }, + { 23035, 35063 }, + { 23039, 36464 }, + { 23041, 35024 }, + { 23043, 34977 }, + { 23049, 39761 }, + { 23057, 39759 }, + { 23064, 38586 }, + { 23066, 39762 }, + { 23068, 39760 }, + { 23071, 39758 }, + { 23072, 36944 }, + { 23077, 39757 }, + { 23081, 38360 }, + { 23087, 36066 }, + { 23093, 39766 }, + { 23094, 39767 }, + { 23100, 36777 }, + { 23104, 39763 }, + { 23105, 38987 }, + { 23110, 37995 }, + { 23113, 39765 }, + { 23130, 36261 }, + { 23138, 39768 }, + { 23142, 38263 }, + { 23146, 39769 }, + { 23148, 39764 }, + { 23167, 38585 }, + { 23186, 38013 }, + { 23194, 39770 }, + { 23195, 38225 }, + { 23228, 39771 }, + { 23229, 39775 }, + { 23230, 39772 }, + { 23233, 35269 }, + { 23234, 39774 }, + { 23241, 36537 }, + { 23243, 39773 }, + { 23244, 35993 }, + { 23248, 39787 }, + { 23254, 39780 }, + { 23255, 39777 }, + { 23265, 37508 }, + { 23267, 39776 }, + { 23270, 39778 }, + { 23273, 39779 }, + { 23290, 39781 }, + { 23291, 39782 }, + { 23305, 35568 }, + { 23307, 39784 }, + { 23308, 39783 }, + { 23318, 39785 }, + { 23330, 36844 }, + { 23338, 39788 }, + { 23340, 37594 }, + { 23344, 35172 }, + { 23346, 39786 }, + { 23350, 39789 }, + { 23358, 39790 }, + { 23360, 39793 }, + { 23363, 39791 }, + { 23365, 39792 }, + { 23376, 36465 }, + { 23377, 39794 }, + { 23380, 36165 }, + { 23381, 39795 }, + { 23382, 64166 }, + { 23383, 36506 }, + { 23384, 37302 }, + { 23386, 39796 }, + { 23387, 39797 }, + { 23388, 36473 }, + { 23389, 36166 }, + { 23391, 38608 }, + { 23395, 35655 }, + { 23396, 36039 }, + { 23397, 39798 }, + { 23398, 35447 }, + { 23401, 39799 }, + { 23403, 37303 }, + { 23408, 39800 }, + { 23409, 39841 }, + { 23411, 39801 }, + { 23413, 39802 }, + { 23416, 39803 }, + { 23418, 39805 }, + { 23424, 39806 }, + { 23427, 39808 }, + { 23429, 37358 }, + { 23431, 35142 }, + { 23432, 36583 }, + { 23433, 35008 }, + { 23435, 37238 }, + { 23436, 35502 }, + { 23437, 36531 }, + { 23439, 36167 }, + { 23445, 37766 }, + { 23447, 36672 }, + { 23448, 35503 }, + { 23449, 37512 }, + { 23450, 37608 }, + { 23451, 34998 }, + { 23452, 35672 }, + { 23453, 38387 }, + { 23455, 36544 }, + { 23458, 35697 }, + { 23459, 37097 }, + { 23460, 36538 }, + { 23461, 38727 }, + { 23462, 39809 }, + { 23470, 35707 }, + { 23472, 36297 }, + { 23475, 35409 }, + { 23476, 35203 }, + { 23477, 36778 }, + { 23478, 35270 }, + { 23480, 39810 }, + { 23481, 38757 }, + { 23487, 36712 }, + { 23488, 64167 }, + { 23490, 36578 }, + { 23491, 39811 }, + { 23492, 35569 }, + { 23493, 37840 }, + { 23494, 38567 }, + { 23495, 39812 }, + { 23497, 39813 }, + { 23500, 38264 }, + { 23504, 39815 }, + { 23506, 35494 }, + { 23507, 35829 }, + { 23508, 39814 }, + { 23512, 64169 }, + { 23515, 35504 }, + { 23517, 36945 }, + { 23518, 39819 }, + { 23519, 36416 }, + { 23521, 35271 }, + { 23522, 39818 }, + { 23524, 39816 }, + { 23525, 39820 }, + { 23526, 39817 }, + { 23527, 37962 }, + { 23528, 40651 }, + { 23529, 36946 }, + { 23531, 39821 }, + { 23532, 64170 }, + { 23534, 38846 }, + { 23536, 39822 }, + { 23539, 39824 }, + { 23541, 37534 }, + { 23542, 39823 }, + { 23544, 37025 }, + { 23546, 36507 }, + { 23550, 37326 }, + { 23551, 36597 }, + { 23553, 38293 }, + { 23554, 37098 }, + { 23556, 36555 }, + { 23557, 39825 }, + { 23558, 36779 }, + { 23559, 39826 }, + { 23560, 39827 }, + { 23561, 35025 }, + { 23562, 37304 }, + { 23563, 36977 }, + { 23565, 39828 }, + { 23566, 37809 }, + { 23567, 36780 }, + { 23569, 36781 }, + { 23571, 39829 }, + { 23574, 37099 }, + { 23578, 36782 }, + { 23582, 64171 }, + { 23584, 39830 }, + { 23586, 39831 }, + { 23588, 38622 }, + { 23592, 39832 }, + { 23597, 35780 }, + { 23601, 36673 }, + { 23608, 39833 }, + { 23609, 39834 }, + { 23610, 36570 }, + { 23611, 36939 }, + { 23612, 37874 }, + { 23613, 36979 }, + { 23614, 38134 }, + { 23615, 37953 }, + { 23616, 35783 }, + { 23617, 39835 }, + { 23621, 35727 }, + { 23622, 39836 }, + { 23624, 35836 }, + { 23626, 37837 }, + { 23627, 35246 }, + { 23629, 36466 }, + { 23630, 39837 }, + { 23631, 39840 }, + { 23632, 39839 }, + { 23633, 35835 }, + { 23635, 39838 }, + { 23637, 37719 }, + { 23646, 37294 }, + { 23648, 37738 }, + { 23649, 36550 }, + { 23652, 37239 }, + { 23653, 38810 }, + { 23660, 39842 }, + { 23662, 39843 }, + { 23663, 37844 }, + { 23665, 36434 }, + { 23670, 39845 }, + { 23673, 39846 }, + { 23692, 39847 }, + { 23696, 35570 }, + { 23697, 39848 }, + { 23700, 39849 }, + { 23713, 35242 }, + { 23718, 64172 }, + { 23720, 37210 }, + { 23721, 35554 }, + { 23723, 39851 }, + { 23724, 38566 }, + { 23729, 37328 }, + { 23731, 35448 }, + { 23734, 39853 }, + { 23735, 39855 }, + { 23736, 35549 }, + { 23738, 64173 }, + { 23739, 39852 }, + { 23740, 39854 }, + { 23742, 39857 }, + { 23749, 39856 }, + { 23751, 39858 }, + { 23769, 39859 }, + { 23776, 37819 }, + { 23777, 35756 }, + { 23784, 35299 }, + { 23785, 39860 }, + { 23786, 39865 }, + { 23789, 39863 }, + { 23791, 38389 }, + { 23792, 38388 }, + { 23797, 64174 }, + { 23798, 37767 }, + { 23802, 39862 }, + { 23803, 36723 }, + { 23805, 39861 }, + { 23815, 37010 }, + { 23819, 39866 }, + { 23822, 36328 }, + { 23825, 39872 }, + { 23828, 39873 }, + { 23829, 39867 }, + { 23830, 35410 }, + { 23831, 39868 }, + { 23832, 39877 }, + { 23833, 39876 }, + { 23834, 39875 }, + { 23835, 39871 }, + { 23839, 39870 }, + { 23842, 39874 }, + { 23847, 64175 }, + { 23849, 38390 }, + { 23874, 64178 }, + { 23883, 39881 }, + { 23884, 39878 }, + { 23886, 39880 }, + { 23888, 38802 }, + { 23890, 39879 }, + { 23891, 64176 }, + { 23900, 39869 }, + { 23913, 37011 }, + { 23916, 39882 }, + { 23917, 64179 }, + { 23919, 36277 }, + { 23923, 39883 }, + { 23926, 39884 }, + { 23938, 39887 }, + { 23940, 39886 }, + { 23943, 39885 }, + { 23947, 37768 }, + { 23948, 39864 }, + { 23952, 39893 }, + { 23965, 39889 }, + { 23970, 39888 }, + { 23980, 39890 }, + { 23982, 39891 }, + { 23991, 39894 }, + { 23992, 64180 }, + { 23993, 64181 }, + { 23994, 38884 }, + { 23996, 39895 }, + { 23997, 39892 }, + { 24009, 39896 }, + { 24012, 35550 }, + { 24013, 39897 }, + { 24016, 64182 }, + { 24018, 39899 }, + { 24019, 39898 }, + { 24022, 39900 }, + { 24027, 39901 }, + { 24029, 37100 }, + { 24030, 36674 }, + { 24033, 36740 }, + { 24035, 37251 }, + { 24037, 36168 }, + { 24038, 36278 }, + { 24039, 36169 }, + { 24040, 35728 }, + { 24043, 39902 }, + { 24046, 36279 }, + { 24049, 36040 }, + { 24050, 39903 }, + { 24051, 38564 }, + { 24052, 37986 }, + { 24053, 39904 }, + { 24055, 36170 }, + { 24059, 35498 }, + { 24061, 37446 }, + { 24062, 35792 }, + { 24066, 36467 }, + { 24067, 38266 }, + { 24070, 38079 }, + { 24075, 39905 }, + { 24076, 35571 }, + { 24081, 39908 }, + { 24086, 37535 }, + { 24089, 39907 }, + { 24090, 39906 }, + { 24091, 39909 }, + { 24093, 37609 }, + { 24101, 36995 }, + { 24107, 36468 }, + { 24109, 37064 }, + { 24111, 37329 }, + { 24112, 35649 }, + { 24115, 37536 }, + { 24118, 39910 }, + { 24119, 39911 }, + { 24120, 36845 }, + { 24125, 38488 }, + { 24128, 39914 }, + { 24131, 39913 }, + { 24132, 39912 }, + { 24133, 38301 }, + { 24135, 39921 }, + { 24140, 38521 }, + { 24142, 39915 }, + { 24148, 39917 }, + { 24149, 38539 }, + { 24151, 39916 }, + { 24159, 39918 }, + { 24161, 38054 }, + { 24162, 39919 }, + { 24163, 38332 }, + { 24164, 39920 }, + { 24178, 35505 }, + { 24179, 38333 }, + { 24180, 37966 }, + { 24181, 39922 }, + { 24182, 39923 }, + { 24184, 36171 }, + { 24185, 35506 }, + { 24186, 39924 }, + { 24187, 36022 }, + { 24188, 38755 }, + { 24189, 38728 }, + { 24190, 35572 }, + { 24191, 39926 }, + { 24193, 37537 }, + { 24195, 36172 }, + { 24196, 36783 }, + { 24199, 38109 }, + { 24202, 36784 }, + { 24207, 36760 }, + { 24213, 37610 }, + { 24214, 38391 }, + { 24215, 37720 }, + { 24218, 36173 }, + { 24220, 38267 }, + { 24224, 39927 }, + { 24230, 37752 }, + { 24231, 36288 }, + { 24235, 36041 }, + { 24237, 37611 }, + { 24245, 35009 }, + { 24246, 36750 }, + { 24247, 36174 }, + { 24248, 38758 }, + { 24257, 39928 }, + { 24258, 39929 }, + { 24259, 38000 }, + { 24264, 39930 }, + { 24265, 38901 }, + { 24266, 38988 }, + { 24271, 39932 }, + { 24272, 39931 }, + { 24275, 35430 }, + { 24278, 40000 }, + { 24282, 40003 }, + { 24283, 40004 }, + { 24285, 40002 }, + { 24287, 38239 }, + { 24288, 36785 }, + { 24289, 40006 }, + { 24290, 40005 }, + { 24291, 40001 }, + { 24296, 40007 }, + { 24297, 40008 }, + { 24300, 40009 }, + { 24304, 40012 }, + { 24305, 40010 }, + { 24307, 40011 }, + { 24308, 40013 }, + { 24310, 35204 }, + { 24311, 37612 }, + { 24312, 40014 }, + { 24314, 35994 }, + { 24315, 35316 }, + { 24316, 37973 }, + { 24318, 40015 }, + { 24319, 37881 }, + { 24321, 38361 }, + { 24323, 40016 }, + { 24324, 38989 }, + { 24329, 40017 }, + { 24330, 38334 }, + { 24331, 40020 }, + { 24332, 39071 }, + { 24333, 39087 }, + { 24335, 36526 }, + { 24336, 37875 }, + { 24337, 40021 }, + { 24339, 35708 }, + { 24340, 37538 }, + { 24341, 35064 }, + { 24342, 40022 }, + { 24343, 38308 }, + { 24344, 36175 }, + { 24347, 37487 }, + { 24351, 37613 }, + { 24353, 64183 }, + { 24357, 38637 }, + { 24358, 36023 }, + { 24359, 36042 }, + { 24361, 40023 }, + { 24365, 40024 }, + { 24367, 40030 }, + { 24369, 36579 }, + { 24372, 64184 }, + { 24373, 37539 }, + { 24375, 35757 }, + { 24376, 40025 }, + { 24380, 38218 }, + { 24382, 37477 }, + { 24385, 40026 }, + { 24389, 64103 }, + { 24392, 40027 }, + { 24394, 35758 }, + { 24396, 40028 }, + { 24398, 40029 }, + { 24401, 40031 }, + { 24403, 37782 }, + { 24406, 40032 }, + { 24407, 40033 }, + { 24409, 40034 }, + { 24412, 40019 }, + { 24413, 40018 }, + { 24417, 40035 }, + { 24418, 35936 }, + { 24422, 38214 }, + { 24423, 64185 }, + { 24425, 36298 }, + { 24426, 38230 }, + { 24427, 37540 }, + { 24428, 38250 }, + { 24429, 40036 }, + { 24432, 36786 }, + { 24433, 35173 }, + { 24435, 40037 }, + { 24439, 40038 }, + { 24441, 38640 }, + { 24444, 38110 }, + { 24447, 40041 }, + { 24448, 35229 }, + { 24449, 37034 }, + { 24450, 40040 }, + { 24451, 40039 }, + { 24452, 35937 }, + { 24453, 37330 }, + { 24455, 40045 }, + { 24456, 40043 }, + { 24458, 40042 }, + { 24459, 38821 }, + { 24460, 36067 }, + { 24464, 36761 }, + { 24465, 40044 }, + { 24466, 37739 }, + { 24467, 36701 }, + { 24471, 37822 }, + { 24472, 40048 }, + { 24473, 40047 }, + { 24478, 40046 }, + { 24480, 40049 }, + { 24481, 36068 }, + { 24488, 40050 }, + { 24489, 38300 }, + { 24490, 36730 }, + { 24493, 40051 }, + { 24494, 38135 }, + { 24499, 37823 }, + { 24500, 37541 }, + { 24503, 64186 }, + { 24505, 37711 }, + { 24508, 40052 }, + { 24509, 35658 }, + { 24515, 36947 }, + { 24517, 38219 }, + { 24524, 35573 }, + { 24525, 37957 }, + { 24534, 40053 }, + { 24535, 36469 }, + { 24536, 38489 }, + { 24537, 38490 }, + { 24540, 35230 }, + { 24541, 40058 }, + { 24542, 64187 }, + { 24544, 37513 }, + { 24548, 40055 }, + { 24555, 35317 }, + { 24560, 40107 }, + { 24561, 40057 }, + { 24565, 37967 }, + { 24568, 40056 }, + { 24571, 40054 }, + { 24573, 36250 }, + { 24575, 40060 }, + { 24590, 40067 }, + { 24591, 40073 }, + { 24592, 40065 }, + { 24594, 37755 }, + { 24597, 40070 }, + { 24598, 38268 }, + { 24601, 40064 }, + { 24603, 40069 }, + { 24604, 38885 }, + { 24605, 36470 }, + { 24608, 37331 }, + { 24609, 40061 }, + { 24613, 35709 }, + { 24614, 40072 }, + { 24615, 37035 }, + { 24616, 35205 }, + { 24617, 40066 }, + { 24618, 35318 }, + { 24619, 40071 }, + { 24623, 35759 }, + { 24625, 40068 }, + { 24634, 40074 }, + { 24641, 40076 }, + { 24642, 40086 }, + { 24643, 40084 }, + { 24646, 40081 }, + { 24650, 40080 }, + { 24651, 38902 }, + { 24653, 40082 }, + { 24656, 35760 }, + { 24658, 36176 }, + { 24661, 36762 }, + { 24665, 40089 }, + { 24666, 40075 }, + { 24669, 64188 }, + { 24671, 40079 }, + { 24672, 40062 }, + { 24674, 35320 }, + { 24675, 40083 }, + { 24676, 40085 }, + { 24677, 37488 }, + { 24680, 36262 }, + { 24681, 35254 }, + { 24682, 40077 }, + { 24683, 40088 }, + { 24684, 40087 }, + { 24685, 35761 }, + { 24687, 37287 }, + { 24688, 35462 }, + { 24693, 35938 }, + { 24695, 40078 }, + { 24705, 40090 }, + { 24707, 40093 }, + { 24708, 40095 }, + { 24709, 64189 }, + { 24713, 36539 }, + { 24714, 64190 }, + { 24715, 40101 }, + { 24716, 37614 }, + { 24717, 40091 }, + { 24722, 40099 }, + { 24724, 35319 }, + { 24726, 40097 }, + { 24727, 40098 }, + { 24730, 40094 }, + { 24731, 40096 }, + { 24735, 36069 }, + { 24736, 38729 }, + { 24739, 35507 }, + { 24742, 35192 }, + { 24743, 40100 }, + { 24745, 37977 }, + { 24746, 34987 }, + { 24754, 38111 }, + { 24755, 40059 }, + { 24756, 40106 }, + { 24757, 40110 }, + { 24758, 38627 }, + { 24760, 40103 }, + { 24764, 37769 }, + { 24765, 40108 }, + { 24773, 36846 }, + { 24774, 40109 }, + { 24775, 37845 }, + { 24785, 39014 }, + { 24787, 40105 }, + { 24789, 64192 }, + { 24792, 40111 }, + { 24794, 36251 }, + { 24796, 37065 }, + { 24798, 64191 }, + { 24799, 35026 }, + { 24800, 40104 }, + { 24801, 40102 }, + { 24803, 37241 }, + { 24807, 40092 }, + { 24808, 36435 }, + { 24816, 37316 }, + { 24817, 40123 }, + { 24818, 64194 }, + { 24819, 37242 }, + { 24820, 40118 }, + { 24822, 40115 }, + { 24823, 40116 }, + { 24825, 36580 }, + { 24826, 40119 }, + { 24827, 40122 }, + { 24832, 40117 }, + { 24833, 36676 }, + { 24835, 40120 }, + { 24838, 40114 }, + { 24840, 38650 }, + { 24841, 38649 }, + { 24845, 40124 }, + { 24846, 40125 }, + { 24847, 35027 }, + { 24849, 64195 }, + { 24853, 40113 }, + { 24858, 35824 }, + { 24859, 34980 }, + { 24863, 35508 }, + { 24864, 64193 }, + { 24865, 40121 }, + { 24871, 40129 }, + { 24872, 40128 }, + { 24876, 40133 }, + { 24880, 64197 }, + { 24884, 40134 }, + { 24887, 64196 }, + { 24892, 40132 }, + { 24893, 40135 }, + { 24894, 40127 }, + { 24895, 40131 }, + { 24898, 40136 }, + { 24900, 40137 }, + { 24903, 40126 }, + { 24904, 36508 }, + { 24906, 40130 }, + { 24907, 37332 }, + { 24908, 36177 }, + { 24909, 40112 }, + { 24910, 36948 }, + { 24915, 40150 }, + { 24917, 38375 }, + { 24920, 40140 }, + { 24921, 40141 }, + { 24922, 40142 }, + { 24925, 40149 }, + { 24927, 40148 }, + { 24930, 38557 }, + { 24931, 35509 }, + { 24933, 40146 }, + { 24935, 35940 }, + { 24936, 35411 }, + { 24939, 40143 }, + { 24942, 38838 }, + { 24943, 40145 }, + { 24944, 35028 }, + { 24945, 40147 }, + { 24947, 40138 }, + { 24948, 40144 }, + { 24949, 40151 }, + { 24950, 35939 }, + { 24951, 40139 }, + { 24958, 38780 }, + { 24962, 38730 }, + { 24967, 40154 }, + { 24970, 40158 }, + { 24974, 37278 }, + { 24976, 38903 }, + { 24977, 40159 }, + { 24980, 40156 }, + { 24982, 40153 }, + { 24984, 64198 }, + { 24985, 40152 }, + { 24986, 40157 }, + { 24996, 38318 }, + { 24999, 37810 }, + { 25001, 35941 }, + { 25003, 40160 }, + { 25004, 40155 }, + { 25006, 40161 }, + { 25010, 35995 }, + { 25014, 35247 }, + { 25018, 40169 }, + { 25022, 35510 }, + { 25027, 40167 }, + { 25030, 40168 }, + { 25031, 36263 }, + { 25032, 40166 }, + { 25033, 40164 }, + { 25034, 40163 }, + { 25035, 40170 }, + { 25036, 40162 }, + { 25037, 40172 }, + { 25040, 35321 }, + { 25059, 40174 }, + { 25062, 40173 }, + { 25074, 37542 }, + { 25076, 40177 }, + { 25078, 40175 }, + { 25079, 40165 }, + { 25080, 35996 }, + { 25082, 40176 }, + { 25084, 40180 }, + { 25085, 40179 }, + { 25086, 40181 }, + { 25087, 40178 }, + { 25088, 40182 }, + { 25096, 40183 }, + { 25097, 40184 }, + { 25098, 38376 }, + { 25100, 40186 }, + { 25101, 40185 }, + { 25102, 36702 }, + { 25104, 37036 }, + { 25105, 35300 }, + { 25106, 35322 }, + { 25107, 64199 }, + { 25108, 40187 }, + { 25110, 35005 }, + { 25114, 37066 }, + { 25115, 40188 }, + { 25117, 59073 }, + { 25118, 40256 }, + { 25119, 35969 }, + { 25121, 40257 }, + { 25126, 37101 }, + { 25130, 40258 }, + { 25134, 40259 }, + { 25135, 35673 }, + { 25136, 40260 }, + { 25138, 40261 }, + { 25139, 40262 }, + { 25140, 37333 }, + { 25144, 36043 }, + { 25147, 38623 }, + { 25151, 38491 }, + { 25152, 36746 }, + { 25153, 40263 }, + { 25159, 37102 }, + { 25160, 59323 }, + { 25161, 38112 }, + { 25163, 36584 }, + { 25165, 36299 }, + { 25166, 40264 }, + { 25171, 37317 }, + { 25173, 38309 }, + { 25176, 37359 }, + { 25179, 40267 }, + { 25182, 40265 }, + { 25184, 40268 }, + { 25187, 40266 }, + { 25192, 40269 }, + { 25198, 38319 }, + { 25201, 34997 }, + { 25206, 38269 }, + { 25209, 38113 }, + { 25212, 40270 }, + { 25214, 40273 }, + { 25215, 36787 }, + { 25216, 35674 }, + { 25218, 40271 }, + { 25219, 40278 }, + { 25220, 36788 }, + { 25225, 40272 }, + { 25226, 37987 }, + { 25233, 38781 }, + { 25234, 40274 }, + { 25235, 40275 }, + { 25236, 40279 }, + { 25237, 37770 }, + { 25238, 40276 }, + { 25239, 36178 }, + { 25240, 37084 }, + { 25243, 40293 }, + { 25244, 38066 }, + { 25246, 37360 }, + { 25254, 64200 }, + { 25259, 38114 }, + { 25260, 40363 }, + { 25265, 38392 }, + { 25269, 37615 }, + { 25273, 38549 }, + { 25275, 40282 }, + { 25276, 35231 }, + { 25277, 37514 }, + { 25282, 40291 }, + { 25285, 37459 }, + { 25286, 40285 }, + { 25287, 40292 }, + { 25288, 40287 }, + { 25289, 40294 }, + { 25290, 40290 }, + { 25292, 40289 }, + { 25293, 38031 }, + { 25295, 40283 }, + { 25296, 35323 }, + { 25297, 40281 }, + { 25298, 35729 }, + { 25299, 37361 }, + { 25300, 40277 }, + { 25303, 40280 }, + { 25304, 36179 }, + { 25305, 37081 }, + { 25307, 36789 }, + { 25308, 40288 }, + { 25309, 38001 }, + { 25312, 35730 }, + { 25313, 35431 }, + { 25324, 35463 }, + { 25325, 36928 }, + { 25326, 40296 }, + { 25327, 40301 }, + { 25329, 40297 }, + { 25331, 35997 }, + { 25333, 40302 }, + { 25334, 36417 }, + { 25335, 36233 }, + { 25342, 36677 }, + { 25343, 40284 }, + { 25345, 36509 }, + { 25346, 40299 }, + { 25351, 36471 }, + { 25352, 40300 }, + { 25353, 35010 }, + { 25356, 40295 }, + { 25361, 37543 }, + { 25369, 35731 }, + { 25375, 35762 }, + { 25383, 40298 }, + { 25384, 34981 }, + { 25387, 36289 }, + { 25391, 36949 }, + { 25402, 37616 }, + { 25405, 38098 }, + { 25406, 40304 }, + { 25407, 37245 }, + { 25417, 37288 }, + { 25420, 36426 }, + { 25421, 40305 }, + { 25423, 40307 }, + { 25424, 40303 }, + { 25429, 38367 }, + { 25431, 37563 }, + { 25436, 37243 }, + { 25447, 38393 }, + { 25448, 36556 }, + { 25449, 40320 }, + { 25451, 40318 }, + { 25454, 37016 }, + { 25458, 35998 }, + { 25462, 40312 }, + { 25463, 36791 }, + { 25466, 37862 }, + { 25467, 37968 }, + { 25472, 40310 }, + { 25475, 37244 }, + { 25480, 36598 }, + { 25481, 40315 }, + { 25484, 36790 }, + { 25486, 40309 }, + { 25487, 40314 }, + { 25490, 38002 }, + { 25494, 40308 }, + { 25496, 35904 }, + { 25499, 35452 }, + { 25503, 40316 }, + { 25504, 38825 }, + { 25505, 36300 }, + { 25506, 37460 }, + { 25507, 40313 }, + { 25509, 37082 }, + { 25511, 36180 }, + { 25512, 36996 }, + { 25513, 35206 }, + { 25514, 37211 }, + { 25515, 40311 }, + { 25516, 35684 }, + { 25522, 35942 }, + { 25524, 37581 }, + { 25525, 40317 }, + { 25531, 37246 }, + { 25534, 40321 }, + { 25536, 40323 }, + { 25539, 37301 }, + { 25540, 40329 }, + { 25542, 40324 }, + { 25545, 40326 }, + { 25551, 38240 }, + { 25552, 37617 }, + { 25554, 40327 }, + { 25558, 38731 }, + { 25562, 38759 }, + { 25563, 35511 }, + { 25569, 34988 }, + { 25571, 40325 }, + { 25577, 40322 }, + { 25582, 35574 }, + { 25588, 35207 }, + { 25589, 64201 }, + { 25590, 40328 }, + { 25594, 38760 }, + { 25606, 40332 }, + { 25613, 37305 }, + { 25615, 40339 }, + { 25619, 40333 }, + { 25622, 40330 }, + { 25623, 40337 }, + { 25628, 40306 }, + { 25638, 40334 }, + { 25640, 40338 }, + { 25644, 38080 }, + { 25645, 37771 }, + { 25652, 40331 }, + { 25654, 40335 }, + { 25658, 35943 }, + { 25662, 36335 }, + { 25666, 37083 }, + { 25678, 40343 }, + { 25688, 37701 }, + { 25696, 64202 }, + { 25703, 40340 }, + { 25705, 38528 }, + { 25711, 40341 }, + { 25718, 40342 }, + { 25720, 38604 }, + { 25722, 37024 }, + { 25731, 35970 }, + { 25736, 40349 }, + { 25746, 36436 }, + { 25747, 40346 }, + { 25749, 40345 }, + { 25754, 37969 }, + { 25757, 64203 }, + { 25758, 37811 }, + { 25764, 37712 }, + { 25765, 40347 }, + { 25769, 40348 }, + { 25771, 38287 }, + { 25773, 37988 }, + { 25774, 36418 }, + { 25776, 37103 }, + { 25778, 38511 }, + { 25785, 35432 }, + { 25787, 40355 }, + { 25788, 40350 }, + { 25793, 38761 }, + { 25794, 40357 }, + { 25797, 40353 }, + { 25799, 40354 }, + { 25805, 37248 }, + { 25806, 64204 }, + { 25810, 40352 }, + { 25812, 40286 }, + { 25816, 40356 }, + { 25818, 40351 }, + { 25824, 40361 }, + { 25825, 40362 }, + { 25826, 37702 }, + { 25827, 40364 }, + { 25830, 36419 }, + { 25831, 40359 }, + { 25836, 35675 }, + { 25839, 40365 }, + { 25841, 40358 }, + { 25842, 40369 }, + { 25844, 40368 }, + { 25846, 40367 }, + { 25850, 40370 }, + { 25853, 40372 }, + { 25854, 36847 }, + { 25856, 40371 }, + { 25861, 40375 }, + { 25880, 40373 }, + { 25884, 40374 }, + { 25885, 40336 }, + { 25891, 40377 }, + { 25892, 40376 }, + { 25898, 40344 }, + { 25899, 40378 }, + { 25900, 40366 }, + { 25903, 36472 }, + { 25908, 40379 }, + { 25909, 40380 }, + { 25910, 40382 }, + { 25911, 40381 }, + { 25912, 40383 }, + { 25913, 35324 }, + { 25915, 36181 }, + { 25918, 38394 }, + { 25919, 37037 }, + { 25925, 36044 }, + { 25928, 40385 }, + { 25933, 40388 }, + { 25934, 64205 }, + { 25935, 38257 }, + { 25937, 35710 }, + { 25941, 40387 }, + { 25942, 40386 }, + { 25943, 38003 }, + { 25944, 40389 }, + { 25945, 35763 }, + { 25949, 40391 }, + { 25950, 40390 }, + { 25954, 35512 }, + { 25955, 36437 }, + { 25958, 37846 }, + { 25964, 35944 }, + { 25968, 37012 }, + { 25970, 40392 }, + { 25972, 37038 }, + { 25973, 37703 }, + { 25975, 38270 }, + { 25976, 40393 }, + { 25986, 40394 }, + { 25987, 40395 }, + { 25991, 38326 }, + { 25992, 39804 }, + { 25993, 37060 }, + { 25996, 38251 }, + { 25998, 36310 }, + { 26000, 38115 }, + { 26001, 38081 }, + { 26007, 37740 }, + { 26009, 38847 }, + { 26011, 40397 }, + { 26012, 36558 }, + { 26015, 40398 }, + { 26017, 34996 }, + { 26020, 35794 }, + { 26021, 37067 }, + { 26023, 38272 }, + { 26027, 40399 }, + { 26028, 36449 }, + { 26029, 37478 }, + { 26031, 36474 }, + { 26032, 36950 }, + { 26039, 40400 }, + { 26041, 38395 }, + { 26044, 35223 }, + { 26045, 36475 }, + { 26049, 40403 }, + { 26051, 40401 }, + { 26052, 40404 }, + { 26053, 38839 }, + { 26054, 40402 }, + { 26059, 37113 }, + { 26060, 40405 }, + { 26063, 37296 }, + { 26066, 40406 }, + { 26071, 35576 }, + { 26073, 40408 }, + { 26075, 40407 }, + { 26080, 40409 }, + { 26081, 40410 }, + { 26082, 35577 }, + { 26085, 37882 }, + { 26086, 37461 }, + { 26087, 35724 }, + { 26088, 36476 }, + { 26089, 37249 }, + { 26092, 36731 }, + { 26093, 34990 }, + { 26097, 40411 }, + { 26106, 35232 }, + { 26107, 40415 }, + { 26112, 64206 }, + { 26114, 36182 }, + { 26115, 40414 }, + { 26118, 36265 }, + { 26119, 36792 }, + { 26121, 64209 }, + { 26122, 40413 }, + { 26124, 36793 }, + { 26126, 38590 }, + { 26127, 36264 }, + { 26131, 35029 }, + { 26132, 37068 }, + { 26133, 64207 }, + { 26140, 40420 }, + { 26142, 64211 }, + { 26143, 37039 }, + { 26144, 35174 }, + { 26148, 64212 }, + { 26149, 36724 }, + { 26151, 38534 }, + { 26152, 36336 }, + { 26157, 36794 }, + { 26158, 64210 }, + { 26159, 37029 }, + { 26161, 64099 }, + { 26164, 40419 }, + { 26165, 40417 }, + { 26166, 40418 }, + { 26171, 64208 }, + { 26172, 37515 }, + { 26175, 40517 }, + { 26177, 40424 }, + { 26178, 36510 }, + { 26179, 36183 }, + { 26180, 40422 }, + { 26185, 40423 }, + { 26187, 36951 }, + { 26191, 40421 }, + { 26194, 36430 }, + { 26199, 64214 }, + { 26201, 64215 }, + { 26205, 40426 }, + { 26206, 40425 }, + { 26207, 40430 }, + { 26210, 40431 }, + { 26212, 40427 }, + { 26213, 64213 }, + { 26214, 35393 }, + { 26215, 40428 }, + { 26216, 40429 }, + { 26217, 38099 }, + { 26222, 38273 }, + { 26223, 35945 }, + { 26224, 40432 }, + { 26227, 64217 }, + { 26228, 37040 }, + { 26230, 36795 }, + { 26234, 37489 }, + { 26241, 35781 }, + { 26243, 40433 }, + { 26244, 40437 }, + { 26247, 35273 }, + { 26248, 40434 }, + { 26249, 40436 }, + { 26254, 40435 }, + { 26257, 36747 }, + { 26262, 37479 }, + { 26263, 35011 }, + { 26264, 40438 }, + { 26265, 64218 }, + { 26269, 40439 }, + { 26272, 64219 }, + { 26274, 37544 }, + { 26278, 38895 }, + { 26283, 36450 }, + { 26286, 38377 }, + { 26290, 64220 }, + { 26292, 38492 }, + { 26296, 40513 }, + { 26297, 40441 }, + { 26300, 40444 }, + { 26302, 40443 }, + { 26303, 64221 }, + { 26305, 40440 }, + { 26308, 40512 }, + { 26311, 37852 }, + { 26313, 40442 }, + { 26326, 40514 }, + { 26329, 36748 }, + { 26330, 40515 }, + { 26332, 38762 }, + { 26333, 38040 }, + { 26336, 40516 }, + { 26342, 40518 }, + { 26345, 40519 }, + { 26352, 40520 }, + { 26354, 35784 }, + { 26355, 35175 }, + { 26356, 36184 }, + { 26357, 40521 }, + { 26359, 40522 }, + { 26360, 36753 }, + { 26361, 37250 }, + { 26362, 64222 }, + { 26363, 64102 }, + { 26364, 39382 }, + { 26365, 37213 }, + { 26366, 37212 }, + { 26367, 37334 }, + { 26368, 36293 }, + { 26371, 39152 }, + { 26376, 35982 }, + { 26377, 38732 }, + { 26379, 38396 }, + { 26381, 38302 }, + { 26382, 64223 }, + { 26383, 40523 }, + { 26388, 36337 }, + { 26389, 37565 }, + { 26390, 40524 }, + { 26391, 38990 }, + { 26395, 38493 }, + { 26397, 37545 }, + { 26398, 40525 }, + { 26399, 35578 }, + { 26406, 40526 }, + { 26407, 40527 }, + { 26408, 38616 }, + { 26410, 38562 }, + { 26411, 38550 }, + { 26412, 38523 }, + { 26413, 36420 }, + { 26414, 40529 }, + { 26417, 36585 }, + { 26420, 38512 }, + { 26422, 40531 }, + { 26423, 40534 }, + { 26424, 40533 }, + { 26426, 35575 }, + { 26429, 35712 }, + { 26431, 40530 }, + { 26433, 40532 }, + { 26438, 40535 }, + { 26441, 37017 }, + { 26446, 38811 }, + { 26447, 35015 }, + { 26448, 36318 }, + { 26449, 37306 }, + { 26451, 36571 }, + { 26454, 36849 }, + { 26457, 40538 }, + { 26460, 37741 }, + { 26462, 40536 }, + { 26463, 37289 }, + { 26464, 40537 }, + { 26465, 36848 }, + { 26466, 38619 }, + { 26467, 40539 }, + { 26468, 40540 }, + { 26469, 38792 }, + { 26470, 64225 }, + { 26474, 40545 }, + { 26477, 36185 }, + { 26479, 38004 }, + { 26480, 40542 }, + { 26481, 37772 }, + { 26482, 40412 }, + { 26483, 40416 }, + { 26485, 35694 }, + { 26487, 37990 }, + { 26492, 40544 }, + { 26494, 36796 }, + { 26495, 38082 }, + { 26501, 40550 }, + { 26503, 38136 }, + { 26505, 40541 }, + { 26507, 40547 }, + { 26508, 40546 }, + { 26512, 37069 }, + { 26517, 38541 }, + { 26519, 38865 }, + { 26522, 38535 }, + { 26524, 35274 }, + { 26525, 36477 }, + { 26528, 39015 }, + { 26529, 40549 }, + { 26530, 37013 }, + { 26534, 40548 }, + { 26537, 40543 }, + { 26543, 36045 }, + { 26547, 40555 }, + { 26548, 40553 }, + { 26550, 35275 }, + { 26551, 40551 }, + { 26552, 40557 }, + { 26553, 40563 }, + { 26555, 64226 }, + { 26560, 64228 }, + { 26561, 37318 }, + { 26564, 38335 }, + { 26566, 40565 }, + { 26570, 38209 }, + { 26574, 40564 }, + { 26575, 38032 }, + { 26576, 38494 }, + { 26577, 35513 }, + { 26579, 37109 }, + { 26580, 36703 }, + { 26584, 37585 }, + { 26586, 38733 }, + { 26589, 40560 }, + { 26590, 40559 }, + { 26594, 40561 }, + { 26596, 40558 }, + { 26599, 40566 }, + { 26601, 40556 }, + { 26604, 40554 }, + { 26606, 40562 }, + { 26607, 40552 }, + { 26609, 37516 }, + { 26611, 38646 }, + { 26612, 36548 }, + { 26613, 36338 }, + { 26619, 36280 }, + { 26622, 38543 }, + { 26623, 35424 }, + { 26625, 64229 }, + { 26626, 37580 }, + { 26627, 37832 }, + { 26628, 35176 }, + { 26643, 37104 }, + { 26646, 37042 }, + { 26647, 35913 }, + { 26654, 40568 }, + { 26657, 36186 }, + { 26658, 35484 }, + { 26665, 40570 }, + { 26666, 35476 }, + { 26667, 40577 }, + { 26674, 40573 }, + { 26676, 37105 }, + { 26680, 35434 }, + { 26681, 36266 }, + { 26684, 35433 }, + { 26685, 36301 }, + { 26688, 40571 }, + { 26689, 35973 }, + { 26690, 35946 }, + { 26691, 37773 }, + { 26692, 64230 }, + { 26694, 40569 }, + { 26696, 35012 }, + { 26701, 40572 }, + { 26702, 40574 }, + { 26704, 35787 }, + { 26705, 35915 }, + { 26706, 64227 }, + { 26707, 35514 }, + { 26708, 35690 }, + { 26713, 40578 }, + { 26716, 36343 }, + { 26717, 38545 }, + { 26719, 36438 }, + { 26723, 40579 }, + { 26727, 38223 }, + { 26740, 40591 }, + { 26742, 35249 }, + { 26743, 40580 }, + { 26750, 40597 }, + { 26751, 40581 }, + { 26753, 38848 }, + { 26755, 40588 }, + { 26757, 38014 }, + { 26765, 40596 }, + { 26767, 40583 }, + { 26771, 34994 }, + { 26772, 40585 }, + { 26775, 36187 }, + { 26779, 40587 }, + { 26781, 40586 }, + { 26783, 40582 }, + { 26784, 40593 }, + { 26786, 36797 }, + { 26790, 39659 }, + { 26791, 36070 }, + { 26792, 38812 }, + { 26797, 40584 }, + { 26799, 37618 }, + { 26800, 35394 }, + { 26801, 36267 }, + { 26803, 40576 }, + { 26805, 40592 }, + { 26806, 35457 }, + { 26809, 40590 }, + { 26810, 40594 }, + { 26812, 37774 }, + { 26820, 35580 }, + { 26822, 40624 }, + { 26824, 64100 }, + { 26825, 38599 }, + { 26826, 40599 }, + { 26827, 35579 }, + { 26829, 40606 }, + { 26831, 64231 }, + { 26834, 38495 }, + { 26836, 40607 }, + { 26837, 40609 }, + { 26839, 40613 }, + { 26840, 40601 }, + { 26842, 37449 }, + { 26847, 37775 }, + { 26848, 40617 }, + { 26849, 40604 }, + { 26851, 40614 }, + { 26855, 40608 }, + { 26862, 36952 }, + { 26863, 40618 }, + { 26866, 37041 }, + { 26873, 40616 }, + { 26874, 35515 }, + { 26880, 39023 }, + { 26881, 40598 }, + { 26884, 40612 }, + { 26885, 35030 }, + { 26888, 40600 }, + { 26891, 38584 }, + { 26892, 40605 }, + { 26893, 36929 }, + { 26894, 37573 }, + { 26895, 40595 }, + { 26898, 40611 }, + { 26905, 37018 }, + { 26906, 40621 }, + { 26907, 35473 }, + { 26908, 35999 }, + { 26913, 40623 }, + { 26914, 40602 }, + { 26915, 40622 }, + { 26917, 40615 }, + { 26918, 40603 }, + { 26920, 40619 }, + { 26922, 40620 }, + { 26928, 40637 }, + { 26932, 37836 }, + { 26934, 40610 }, + { 26937, 40633 }, + { 26941, 40635 }, + { 26943, 37590 }, + { 26954, 38763 }, + { 26963, 38294 }, + { 26964, 40630 }, + { 26965, 37320 }, + { 26969, 40636 }, + { 26970, 37214 }, + { 26972, 40627 }, + { 26973, 40640 }, + { 26974, 40639 }, + { 26976, 37869 }, + { 26977, 40638 }, + { 26978, 37864 }, + { 26984, 64233 }, + { 26986, 40642 }, + { 26987, 40629 }, + { 26989, 35782 }, + { 26990, 40632 }, + { 26991, 36732 }, + { 26995, 38016 }, + { 26996, 40634 }, + { 26997, 35785 }, + { 26999, 40626 }, + { 27000, 40628 }, + { 27001, 40625 }, + { 27004, 38991 }, + { 27005, 35449 }, + { 27006, 40631 }, + { 27009, 40641 }, + { 27010, 35412 }, + { 27018, 36325 }, + { 27022, 35196 }, + { 27025, 40658 }, + { 27028, 38992 }, + { 27029, 40661 }, + { 27032, 64235 }, + { 27035, 36953 }, + { 27036, 40660 }, + { 27040, 40659 }, + { 27047, 40656 }, + { 27054, 40644 }, + { 27057, 40673 }, + { 27058, 40643 }, + { 27060, 40662 }, + { 27067, 40654 }, + { 27070, 40649 }, + { 27071, 40646 }, + { 27073, 40647 }, + { 27075, 40655 }, + { 27079, 60064 }, + { 27082, 40652 }, + { 27083, 36188 }, + { 27084, 37574 }, + { 27085, 37252 }, + { 27086, 40650 }, + { 27088, 40645 }, + { 27091, 40648 }, + { 27096, 38764 }, + { 27097, 38538 }, + { 27101, 40653 }, + { 27102, 40663 }, + { 27106, 64236 }, + { 27111, 40671 }, + { 27112, 40664 }, + { 27115, 40677 }, + { 27117, 40675 }, + { 27122, 40670 }, + { 27129, 40669 }, + { 27131, 37582 }, + { 27133, 37253 }, + { 27135, 40667 }, + { 27138, 40665 }, + { 27141, 40672 }, + { 27146, 40678 }, + { 27147, 38131 }, + { 27148, 40684 }, + { 27154, 40679 }, + { 27155, 40682 }, + { 27156, 40676 }, + { 27159, 37524 }, + { 27161, 38231 }, + { 27163, 40666 }, + { 27166, 40674 }, + { 27167, 36798 }, + { 27169, 38605 }, + { 27170, 40694 }, + { 27171, 40681 }, + { 27177, 36000 }, + { 27178, 35233 }, + { 27179, 35454 }, + { 27182, 40657 }, + { 27184, 64237 }, + { 27189, 36799 }, + { 27190, 40686 }, + { 27192, 40693 }, + { 27193, 36599 }, + { 27194, 35474 }, + { 27197, 37453 }, + { 27204, 40683 }, + { 27206, 64239 }, + { 27207, 40688 }, + { 27208, 40692 }, + { 27211, 35764 }, + { 27224, 35691 }, + { 27225, 40690 }, + { 27231, 35648 }, + { 27233, 37833 }, + { 27234, 40689 }, + { 27238, 40691 }, + { 27243, 64238 }, + { 27250, 40685 }, + { 27251, 64240 }, + { 27256, 40687 }, + { 27262, 64241 }, + { 27263, 35456 }, + { 27264, 37480 }, + { 27268, 40698 }, + { 27277, 40696 }, + { 27278, 36071 }, + { 27280, 40695 }, + { 27287, 40768 }, + { 27292, 40567 }, + { 27296, 40697 }, + { 27298, 40699 }, + { 27299, 40700 }, + { 27306, 40779 }, + { 27308, 40775 }, + { 27310, 40589 }, + { 27315, 40774 }, + { 27320, 40773 }, + { 27323, 40770 }, + { 27329, 40680 }, + { 27330, 40772 }, + { 27331, 40771 }, + { 27345, 40777 }, + { 27347, 38981 }, + { 27354, 40780 }, + { 27355, 35833 }, + { 27358, 40776 }, + { 27359, 40778 }, + { 27362, 64242 }, + { 27364, 64243 }, + { 27368, 38053 }, + { 27370, 40781 }, + { 27386, 40785 }, + { 27387, 40782 }, + { 27396, 38803 }, + { 27397, 40783 }, + { 27402, 40668 }, + { 27410, 40786 }, + { 27414, 40787 }, + { 27421, 35156 }, + { 27423, 40789 }, + { 27424, 35975 }, + { 27425, 36511 }, + { 27427, 35795 }, + { 27431, 35234 }, + { 27442, 38782 }, + { 27447, 40791 }, + { 27448, 40790 }, + { 27449, 40793 }, + { 27450, 35676 }, + { 27453, 35796 }, + { 27454, 35516 }, + { 27459, 40796 }, + { 27463, 40795 }, + { 27465, 40797 }, + { 27468, 35276 }, + { 27470, 37462 }, + { 27472, 40798 }, + { 27475, 35517 }, + { 27476, 40800 }, + { 27481, 40799 }, + { 27483, 40801 }, + { 27487, 40802 }, + { 27489, 40803 }, + { 27490, 36478 }, + { 27491, 37043 }, + { 27492, 36255 }, + { 27494, 38288 }, + { 27497, 38368 }, + { 27498, 39011 }, + { 27503, 36501 }, + { 27507, 36302 }, + { 27508, 38896 }, + { 27512, 40804 }, + { 27513, 40805 }, + { 27515, 36480 }, + { 27519, 40806 }, + { 27520, 40807 }, + { 27523, 40809 }, + { 27524, 40808 }, + { 27526, 38519 }, + { 27529, 36733 }, + { 27530, 36586 }, + { 27531, 36451 }, + { 27533, 40810 }, + { 27541, 40812 }, + { 27542, 36930 }, + { 27544, 40811 }, + { 27550, 40813 }, + { 27556, 40814 }, + { 27562, 40815 }, + { 27563, 40816 }, + { 27567, 40817 }, + { 27569, 40819 }, + { 27570, 40818 }, + { 27571, 40820 }, + { 27572, 35235 }, + { 27573, 37481 }, + { 27575, 40821 }, + { 27578, 36421 }, + { 27579, 35435 }, + { 27580, 40822 }, + { 27583, 37729 }, + { 27584, 39626 }, + { 27589, 35650 }, + { 27590, 40823 }, + { 27595, 40824 }, + { 27597, 38378 }, + { 27598, 38536 }, + { 27602, 37829 }, + { 27603, 40825 }, + { 27604, 38116 }, + { 27606, 64244 }, + { 27608, 38137 }, + { 27611, 38609 }, + { 27615, 40826 }, + { 27627, 40828 }, + { 27628, 40827 }, + { 27631, 40830 }, + { 27635, 40829 }, + { 27656, 40833 }, + { 27663, 36481 }, + { 27665, 38575 }, + { 27667, 40834 }, + { 27668, 40835 }, + { 27671, 35651 }, + { 27675, 40836 }, + { 27683, 40838 }, + { 27684, 40837 }, + { 27700, 36997 }, + { 27703, 38232 }, + { 27704, 35177 }, + { 27710, 38083 }, + { 27711, 64245 }, + { 27712, 37619 }, + { 27713, 36704 }, + { 27714, 35713 }, + { 27726, 38084 }, + { 27728, 36524 }, + { 27733, 40840 }, + { 27735, 35518 }, + { 27738, 35224 }, + { 27740, 64246 }, + { 27741, 37872 }, + { 27742, 40839 }, + { 27743, 36189 }, + { 27744, 37490 }, + { 27746, 40841 }, + { 27752, 40849 }, + { 27754, 40842 }, + { 27759, 64248 }, + { 27760, 37311 }, + { 27762, 35714 }, + { 27763, 40850 }, + { 27770, 35976 }, + { 27773, 35652 }, + { 27774, 40848 }, + { 27777, 40846 }, + { 27778, 40843 }, + { 27779, 38784 }, + { 27782, 64247 }, + { 27784, 37566 }, + { 27788, 37847 }, + { 27789, 40844 }, + { 27792, 40852 }, + { 27794, 40851 }, + { 27795, 35906 }, + { 27798, 35243 }, + { 27801, 36281 }, + { 27802, 40845 }, + { 27803, 40847 }, + { 27809, 38518 }, + { 27810, 37362 }, + { 27819, 38551 }, + { 27822, 40860 }, + { 27825, 40861 }, + { 27827, 35277 }, + { 27832, 38310 }, + { 27833, 38651 }, + { 27834, 40863 }, + { 27835, 36513 }, + { 27836, 36800 }, + { 27837, 40856 }, + { 27838, 40862 }, + { 27839, 35208 }, + { 27841, 35765 }, + { 27844, 40853 }, + { 27845, 40858 }, + { 27849, 37106 }, + { 27850, 38033 }, + { 27852, 38117 }, + { 27859, 40855 }, + { 27861, 38464 }, + { 27863, 40857 }, + { 27865, 40866 }, + { 27866, 64249 }, + { 27867, 40864 }, + { 27869, 40859 }, + { 27873, 38465 }, + { 27874, 37991 }, + { 27875, 35715 }, + { 27877, 37700 }, + { 27880, 37517 }, + { 27882, 40867 }, + { 27887, 40865 }, + { 27888, 37335 }, + { 27889, 40854 }, + { 27891, 35178 }, + { 27908, 64250 }, + { 27915, 38765 }, + { 27916, 40878 }, + { 27922, 40877 }, + { 27927, 37108 }, + { 27929, 40874 }, + { 27931, 38796 }, + { 27934, 37812 }, + { 27935, 40868 }, + { 27941, 37571 }, + { 27945, 35179 }, + { 27946, 36190 }, + { 27947, 40871 }, + { 27954, 36678 }, + { 27955, 40876 }, + { 27957, 40875 }, + { 27958, 40870 }, + { 27960, 40873 }, + { 27963, 35464 }, + { 27965, 40872 }, + { 27966, 37992 }, + { 27969, 38828 }, + { 27972, 36850 }, + { 27973, 37107 }, + { 27993, 40884 }, + { 27994, 40882 }, + { 27996, 38252 }, + { 28003, 40879 }, + { 28004, 40881 }, + { 28006, 35161 }, + { 28009, 36191 }, + { 28010, 38993 }, + { 28012, 35420 }, + { 28014, 38274 }, + { 28015, 64252 }, + { 28020, 38785 }, + { 28023, 35395 }, + { 28024, 36954 }, + { 28025, 40883 }, + { 28037, 40888 }, + { 28039, 64251 }, + { 28040, 36801 }, + { 28044, 38735 }, + { 28046, 40885 }, + { 28051, 40880 }, + { 28053, 40886 }, + { 28054, 64320 }, + { 28057, 38876 }, + { 28059, 37779 }, + { 28060, 37824 }, + { 28076, 64321 }, + { 28079, 35413 }, + { 28082, 35188 }, + { 28085, 40892 }, + { 28088, 40895 }, + { 28092, 38849 }, + { 28096, 38788 }, + { 28101, 40902 }, + { 28102, 40896 }, + { 28103, 40893 }, + { 28107, 38866 }, + { 28108, 40899 }, + { 28111, 64322 }, + { 28113, 36713 }, + { 28114, 40901 }, + { 28117, 40906 }, + { 28120, 37777 }, + { 28121, 40904 }, + { 28126, 40898 }, + { 28129, 37463 }, + { 28132, 40905 }, + { 28134, 40894 }, + { 28136, 40900 }, + { 28138, 40907 }, + { 28139, 35066 }, + { 28140, 40897 }, + { 28142, 40908 }, + { 28145, 36955 }, + { 28146, 64324 }, + { 28147, 36734 }, + { 28149, 38307 }, + { 28151, 36268 }, + { 28152, 64323 }, + { 28153, 40889 }, + { 28154, 40903 }, + { 28155, 37721 }, + { 28156, 64325 }, + { 28165, 37044 }, + { 28167, 35465 }, + { 28168, 36303 }, + { 28169, 36802 }, + { 28170, 40891 }, + { 28171, 36705 }, + { 28179, 35947 }, + { 28181, 40890 }, + { 28185, 40912 }, + { 28186, 36749 }, + { 28187, 36024 }, + { 28189, 40927 }, + { 28191, 40921 }, + { 28192, 35732 }, + { 28193, 37742 }, + { 28195, 40916 }, + { 28196, 40925 }, + { 28197, 34989 }, + { 28198, 35153 }, + { 28199, 64328 }, + { 28201, 35255 }, + { 28203, 40918 }, + { 28204, 37290 }, + { 28205, 40909 }, + { 28206, 40911 }, + { 28207, 36192 }, + { 28216, 40928 }, + { 28217, 64326 }, + { 28218, 40923 }, + { 28220, 64329 }, + { 28222, 40915 }, + { 28227, 40922 }, + { 28234, 38569 }, + { 28237, 40920 }, + { 28238, 40924 }, + { 28246, 36046 }, + { 28248, 36803 }, + { 28251, 37464 }, + { 28252, 64327 }, + { 28255, 40914 }, + { 28263, 38734 }, + { 28267, 40917 }, + { 28270, 40910 }, + { 28271, 37778 }, + { 28274, 40913 }, + { 28278, 40919 }, + { 28286, 39024 }, + { 28287, 36540 }, + { 28288, 38558 }, + { 28290, 40929 }, + { 28300, 38060 }, + { 28303, 40941 }, + { 28304, 36025 }, + { 28310, 36736 }, + { 28312, 40931 }, + { 28316, 38829 }, + { 28317, 36193 }, + { 28319, 40944 }, + { 28322, 35052 }, + { 28325, 40942 }, + { 28330, 40930 }, + { 28335, 40936 }, + { 28338, 40938 }, + { 28342, 38766 }, + { 28343, 40933 }, + { 28346, 37709 }, + { 28349, 40935 }, + { 28351, 64330 }, + { 28354, 40943 }, + { 28356, 40937 }, + { 28357, 38597 }, + { 28361, 40932 }, + { 28363, 36512 }, + { 28364, 40956 }, + { 28369, 35466 }, + { 28371, 40934 }, + { 28372, 40939 }, + { 28373, 40940 }, + { 28381, 37354 }, + { 28382, 37336 }, + { 28396, 40948 }, + { 28399, 40954 }, + { 28402, 40952 }, + { 28404, 37704 }, + { 28407, 57410 }, + { 28408, 40949 }, + { 28414, 40950 }, + { 28415, 40926 }, + { 28417, 35737 }, + { 28418, 38233 }, + { 28422, 36541 }, + { 28425, 36247 }, + { 28431, 38994 }, + { 28433, 40946 }, + { 28435, 57409 }, + { 28436, 35209 }, + { 28437, 37254 }, + { 28448, 38041 }, + { 28450, 35519 }, + { 28451, 38904 }, + { 28459, 38559 }, + { 28460, 37584 }, + { 28465, 40953 }, + { 28466, 40955 }, + { 28472, 37201 }, + { 28478, 57408 }, + { 28479, 40951 }, + { 28481, 40945 }, + { 28485, 35521 }, + { 28500, 35977 }, + { 28504, 57422 }, + { 28507, 57417 }, + { 28508, 37110 }, + { 28511, 35459 }, + { 28516, 36737 }, + { 28518, 57426 }, + { 28525, 57419 }, + { 28526, 37546 }, + { 28527, 57416 }, + { 28528, 37591 }, + { 28532, 57451 }, + { 28536, 57413 }, + { 28538, 57412 }, + { 28540, 57421 }, + { 28544, 57415 }, + { 28545, 57414 }, + { 28546, 57420 }, + { 28548, 37023 }, + { 28550, 57411 }, + { 28552, 64331 }, + { 28558, 57423 }, + { 28561, 57424 }, + { 28567, 35520 }, + { 28577, 57429 }, + { 28579, 57428 }, + { 28580, 57430 }, + { 28586, 57433 }, + { 28593, 37730 }, + { 28595, 57427 }, + { 28597, 64332 }, + { 28601, 57431 }, + { 28608, 35971 }, + { 28609, 37367 }, + { 28610, 57425 }, + { 28611, 37978 }, + { 28614, 57432 }, + { 28628, 57437 }, + { 28629, 57435 }, + { 28632, 57438 }, + { 28635, 57441 }, + { 28639, 57434 }, + { 28640, 36234 }, + { 28641, 37959 }, + { 28644, 40887 }, + { 28651, 38804 }, + { 28652, 57436 }, + { 28654, 57440 }, + { 28655, 37363 }, + { 28657, 57439 }, + { 28659, 57418 }, + { 28661, 64333 }, + { 28662, 59529 }, + { 28666, 57444 }, + { 28670, 57448 }, + { 28673, 57446 }, + { 28677, 64334 }, + { 28679, 64335 }, + { 28681, 57442 }, + { 28683, 57443 }, + { 28687, 57447 }, + { 28689, 57445 }, + { 28693, 38253 }, + { 28696, 57453 }, + { 28698, 57450 }, + { 28699, 57449 }, + { 28701, 57452 }, + { 28702, 37842 }, + { 28703, 57454 }, + { 28710, 37525 }, + { 28711, 37355 }, + { 28712, 64336 }, + { 28716, 37027 }, + { 28720, 57455 }, + { 28722, 57457 }, + { 28734, 57456 }, + { 28748, 40947 }, + { 28753, 57458 }, + { 28760, 37861 }, + { 28771, 57459 }, + { 28779, 35278 }, + { 28783, 37780 }, + { 28784, 35396 }, + { 28792, 35716 }, + { 28796, 36572 }, + { 28797, 36304 }, + { 28805, 64337 }, + { 28809, 38982 }, + { 28810, 36998 }, + { 28814, 35210 }, + { 28818, 57461 }, + { 28825, 57460 }, + { 28843, 64338 }, + { 28844, 57464 }, + { 28845, 37465 }, + { 28846, 57467 }, + { 28847, 57462 }, + { 28851, 57466 }, + { 28856, 57465 }, + { 28857, 37727 }, + { 28858, 35031 }, + { 28859, 64098 }, + { 28872, 38899 }, + { 28875, 57469 }, + { 28879, 35143 }, + { 28889, 57472 }, + { 28893, 57470 }, + { 28895, 57468 }, + { 28913, 57463 }, + { 28921, 38466 }, + { 28925, 57474 }, + { 28932, 64340 }, + { 28937, 57473 }, + { 28943, 64339 }, + { 28948, 35211 }, + { 28953, 57476 }, + { 28954, 38320 }, + { 28956, 57475 }, + { 28961, 38579 }, + { 28966, 36805 }, + { 28982, 37202 }, + { 28988, 36804 }, + { 28998, 64342 }, + { 28999, 64343 }, + { 29001, 38905 }, + { 29004, 57482 }, + { 29006, 37111 }, + { 29013, 57478 }, + { 29014, 57483 }, + { 29017, 35212 }, + { 29020, 64341 }, + { 29026, 57481 }, + { 29028, 38017 }, + { 29029, 57477 }, + { 29030, 57480 }, + { 29031, 36806 }, + { 29033, 38095 }, + { 29036, 57484 }, + { 29038, 36559 }, + { 29053, 37112 }, + { 29060, 57487 }, + { 29064, 57479 }, + { 29066, 35910 }, + { 29071, 57485 }, + { 29076, 38767 }, + { 29077, 57488 }, + { 29081, 60068 }, + { 29087, 36718 }, + { 29096, 57489 }, + { 29100, 57490 }, + { 29105, 37965 }, + { 29113, 57492 }, + { 29118, 57493 }, + { 29121, 64345 }, + { 29123, 37970 }, + { 29128, 37781 }, + { 29129, 57495 }, + { 29134, 57497 }, + { 29136, 38867 }, + { 29138, 57494 }, + { 29140, 57496 }, + { 29141, 35213 }, + { 29143, 57491 }, + { 29151, 39546 }, + { 29152, 57498 }, + { 29157, 37255 }, + { 29158, 36439 }, + { 29159, 57500 }, + { 29164, 57499 }, + { 29165, 36931 }, + { 29166, 39383 }, + { 29173, 57501 }, + { 29177, 57503 }, + { 29179, 57486 }, + { 29180, 57502 }, + { 29182, 64346 }, + { 29183, 57504 }, + { 29190, 38042 }, + { 29197, 57505 }, + { 29200, 57506 }, + { 29211, 57507 }, + { 29224, 57508 }, + { 29226, 37596 }, + { 29228, 57510 }, + { 29229, 57509 }, + { 29232, 57511 }, + { 29234, 57512 }, + { 29237, 36573 }, + { 29238, 38275 }, + { 29242, 38634 }, + { 29243, 57513 }, + { 29244, 57514 }, + { 29245, 37237 }, + { 29246, 36514 }, + { 29247, 57515 }, + { 29248, 57516 }, + { 29254, 57517 }, + { 29255, 38352 }, + { 29256, 38085 }, + { 29259, 57518 }, + { 29260, 38006 }, + { 29266, 37547 }, + { 29272, 57519 }, + { 29273, 35301 }, + { 29275, 35725 }, + { 29277, 38596 }, + { 29279, 38580 }, + { 29281, 35250 }, + { 29282, 38995 }, + { 29287, 38513 }, + { 29289, 38312 }, + { 29298, 37045 }, + { 29300, 57520 }, + { 29305, 37825 }, + { 29309, 36001 }, + { 29310, 57521 }, + { 29312, 36306 }, + { 29313, 57523 }, + { 29314, 57522 }, + { 29319, 57524 }, + { 29330, 57525 }, + { 29334, 57526 }, + { 29344, 35677 }, + { 29346, 57527 }, + { 29351, 57528 }, + { 29356, 36002 }, + { 29359, 38086 }, + { 29361, 64347 }, + { 29362, 57530 }, + { 29366, 36851 }, + { 29369, 57529 }, + { 29374, 64348 }, + { 29378, 35766 }, + { 29379, 57531 }, + { 29380, 57533 }, + { 29382, 57532 }, + { 29390, 57534 }, + { 29392, 36047 }, + { 29394, 57535 }, + { 29399, 35815 }, + { 29401, 37215 }, + { 29403, 36253 }, + { 29408, 57537 }, + { 29409, 57538 }, + { 29410, 57536 }, + { 29417, 36587 }, + { 29420, 37830 }, + { 29421, 35767 }, + { 29431, 57540 }, + { 29432, 37451 }, + { 29433, 57539 }, + { 29436, 38996 }, + { 29437, 38018 }, + { 29450, 57543 }, + { 29462, 57545 }, + { 29463, 57542 }, + { 29467, 38610 }, + { 29468, 57544 }, + { 29469, 57546 }, + { 29471, 38850 }, + { 29476, 64349 }, + { 29477, 57550 }, + { 29481, 57549 }, + { 29482, 37526 }, + { 29483, 37964 }, + { 29486, 36003 }, + { 29487, 57548 }, + { 29492, 57547 }, + { 29494, 38736 }, + { 29495, 38737 }, + { 29502, 57551 }, + { 29503, 35214 }, + { 29508, 36246 }, + { 29509, 36482 }, + { 29518, 57552 }, + { 29519, 57553 }, + { 29527, 57555 }, + { 29539, 36706 }, + { 29544, 57557 }, + { 29546, 57556 }, + { 29552, 57558 }, + { 29554, 35436 }, + { 29557, 57560 }, + { 29559, 64351 }, + { 29560, 57559 }, + { 29562, 57562 }, + { 29563, 57561 }, + { 29572, 36026 }, + { 29575, 38822 }, + { 29577, 35786 }, + { 29579, 35236 }, + { 29590, 35816 }, + { 29609, 35551 }, + { 29618, 38886 }, + { 29619, 57564 }, + { 29627, 57566 }, + { 29629, 64352 }, + { 29632, 57567 }, + { 29634, 35279 }, + { 29640, 57563 }, + { 29641, 64353 }, + { 29642, 36440 }, + { 29645, 37567 }, + { 29646, 57565 }, + { 29650, 64356 }, + { 29654, 64354 }, + { 29662, 57570 }, + { 29664, 36588 }, + { 29667, 64355 }, + { 29669, 57568 }, + { 29674, 35933 }, + { 29677, 38087 }, + { 29678, 57569 }, + { 29681, 57596 }, + { 29685, 64358 }, + { 29688, 57575 }, + { 29694, 36027 }, + { 29699, 35717 }, + { 29701, 57572 }, + { 29702, 38813 }, + { 29703, 64357 }, + { 29705, 38830 }, + { 29730, 37364 }, + { 29733, 57574 }, + { 29734, 64359 }, + { 29737, 64361 }, + { 29738, 64360 }, + { 29742, 64362 }, + { 29746, 57576 }, + { 29747, 38868 }, + { 29748, 35797 }, + { 29749, 38138 }, + { 29750, 37993 }, + { 29754, 57577 }, + { 29759, 57579 }, + { 29761, 57582 }, + { 29781, 57578 }, + { 29785, 57581 }, + { 29786, 36072 }, + { 29787, 35180 }, + { 29788, 57583 }, + { 29790, 37008 }, + { 29791, 57580 }, + { 29792, 38874 }, + { 29794, 64363 }, + { 29795, 57586 }, + { 29796, 60066 }, + { 29801, 57584 }, + { 29802, 57587 }, + { 29807, 57573 }, + { 29808, 57585 }, + { 29811, 36282 }, + { 29814, 57588 }, + { 29822, 57589 }, + { 29827, 38814 }, + { 29833, 64364 }, + { 29835, 57590 }, + { 29854, 57591 }, + { 29855, 64365 }, + { 29858, 57571 }, + { 29863, 57592 }, + { 29872, 35522 }, + { 29885, 36515 }, + { 29898, 57593 }, + { 29903, 57594 }, + { 29908, 57595 }, + { 29916, 35162 }, + { 29920, 57664 }, + { 29922, 38234 }, + { 29923, 57665 }, + { 29926, 35490 }, + { 29927, 57666 }, + { 29929, 57667 }, + { 29934, 57668 }, + { 29936, 57670 }, + { 29937, 57671 }, + { 29938, 57669 }, + { 29942, 38258 }, + { 29943, 57673 }, + { 29944, 57672 }, + { 29953, 64366 }, + { 29955, 57675 }, + { 29956, 57674 }, + { 29957, 57676 }, + { 29964, 57677 }, + { 29965, 57679 }, + { 29966, 57678 }, + { 29969, 36249 }, + { 29971, 57681 }, + { 29973, 57680 }, + { 29976, 35523 }, + { 29978, 36978 }, + { 29980, 37723 }, + { 29982, 57682 }, + { 29983, 37046 }, + { 29987, 36441 }, + { 29989, 35225 }, + { 29990, 57683 }, + { 29992, 38768 }, + { 29995, 38369 }, + { 29996, 57684 }, + { 29999, 64168 }, + { 30000, 37731 }, + { 30001, 38738 }, + { 30002, 36194 }, + { 30003, 36956 }, + { 30007, 37482 }, + { 30008, 39346 }, + { 30010, 37548 }, + { 30011, 35302 }, + { 30012, 57685 }, + { 30020, 57686 }, + { 30022, 57691 }, + { 30025, 57689 }, + { 30026, 57688 }, + { 30027, 40384 }, + { 30028, 35397 }, + { 30029, 57687 }, + { 30031, 35032 }, + { 30033, 38056 }, + { 30036, 38088 }, + { 30041, 38831 }, + { 30042, 57692 }, + { 30043, 57690 }, + { 30044, 37499 }, + { 30045, 37028 }, + { 30048, 38057 }, + { 30050, 38220 }, + { 30052, 57694 }, + { 30053, 38826 }, + { 30054, 35948 }, + { 30055, 57695 }, + { 30057, 57693 }, + { 30058, 38100 }, + { 30059, 57696 }, + { 30061, 57697 }, + { 30063, 64367 }, + { 30064, 35033 }, + { 30067, 36852 }, + { 30068, 57702 }, + { 30070, 57699 }, + { 30071, 37867 }, + { 30072, 57698 }, + { 30079, 35653 }, + { 30082, 57705 }, + { 30086, 57700 }, + { 30087, 57701 }, + { 30089, 57704 }, + { 30090, 57703 }, + { 30091, 38212 }, + { 30094, 37217 }, + { 30095, 37216 }, + { 30097, 35678 }, + { 30100, 57706 }, + { 30106, 57707 }, + { 30109, 57708 }, + { 30115, 57710 }, + { 30117, 57709 }, + { 30123, 35189 }, + { 30129, 57718 }, + { 30130, 38118 }, + { 30131, 57712 }, + { 30133, 57714 }, + { 30136, 57716 }, + { 30137, 36957 }, + { 30140, 57717 }, + { 30141, 57715 }, + { 30142, 36542 }, + { 30146, 57711 }, + { 30147, 57713 }, + { 30149, 38241 }, + { 30151, 36807 }, + { 30154, 57720 }, + { 30157, 57719 }, + { 30162, 57721 }, + { 30164, 36516 }, + { 30165, 36269 }, + { 30168, 37783 }, + { 30169, 57722 }, + { 30171, 37577 }, + { 30174, 57724 }, + { 30178, 38815 }, + { 30179, 57723 }, + { 30185, 37257 }, + { 30192, 57730 }, + { 30194, 57732 }, + { 30195, 57733 }, + { 30196, 37491 }, + { 30202, 57731 }, + { 30204, 57728 }, + { 30206, 57725 }, + { 30207, 57726 }, + { 30209, 57729 }, + { 30217, 57736 }, + { 30219, 57734 }, + { 30221, 57735 }, + { 30239, 57737 }, + { 30240, 57739 }, + { 30241, 57740 }, + { 30242, 57741 }, + { 30244, 57742 }, + { 30247, 57738 }, + { 30256, 57744 }, + { 30260, 57743 }, + { 30267, 57745 }, + { 30274, 38851 }, + { 30278, 57748 }, + { 30279, 57746 }, + { 30280, 57747 }, + { 30284, 35552 }, + { 30290, 38652 }, + { 30294, 38344 }, + { 30296, 57750 }, + { 30300, 57749 }, + { 30305, 57751 }, + { 30306, 57752 }, + { 30311, 57756 }, + { 30312, 57753 }, + { 30313, 57754 }, + { 30314, 57755 }, + { 30316, 57757 }, + { 30320, 57758 }, + { 30322, 57759 }, + { 30326, 57760 }, + { 30328, 57761 }, + { 30330, 38061 }, + { 30331, 37743 }, + { 30332, 57762 }, + { 30333, 38034 }, + { 30334, 38227 }, + { 30336, 57763 }, + { 30338, 64368 }, + { 30339, 57764 }, + { 30340, 37705 }, + { 30342, 35398 }, + { 30343, 36195 }, + { 30344, 57765 }, + { 30347, 57766 }, + { 30350, 57767 }, + { 30352, 36424 }, + { 30355, 57769 }, + { 30358, 57768 }, + { 30361, 57770 }, + { 30362, 57771 }, + { 30363, 64371 }, + { 30364, 64369 }, + { 30366, 64370 }, + { 30374, 64372 }, + { 30382, 38119 }, + { 30384, 57772 }, + { 30388, 57773 }, + { 30391, 60041 }, + { 30392, 57774 }, + { 30393, 57775 }, + { 30394, 57776 }, + { 30399, 36429 }, + { 30402, 57777 }, + { 30403, 38005 }, + { 30406, 38526 }, + { 30408, 35181 }, + { 30410, 35190 }, + { 30413, 57778 }, + { 30418, 57780 }, + { 30422, 57779 }, + { 30423, 37776 }, + { 30427, 37047 }, + { 30428, 40792 }, + { 30430, 57781 }, + { 30431, 38591 }, + { 30433, 57782 }, + { 30435, 35524 }, + { 30436, 38101 }, + { 30437, 57783 }, + { 30439, 57784 }, + { 30442, 57785 }, + { 30446, 38618 }, + { 30450, 38611 }, + { 30452, 37564 }, + { 30456, 37258 }, + { 30459, 57787 }, + { 30462, 36738 }, + { 30465, 36808 }, + { 30468, 57790 }, + { 30471, 57789 }, + { 30472, 57788 }, + { 30473, 38139 }, + { 30475, 35525 }, + { 30476, 36007 }, + { 30491, 57796 }, + { 30494, 57793 }, + { 30495, 36958 }, + { 30496, 38576 }, + { 30500, 57792 }, + { 30501, 57794 }, + { 30502, 57795 }, + { 30505, 57791 }, + { 30519, 57797 }, + { 30520, 57798 }, + { 30522, 37549 }, + { 30524, 35553 }, + { 30528, 37509 }, + { 30534, 64374 }, + { 30535, 57799 }, + { 30554, 57800 }, + { 30555, 57803 }, + { 30561, 36999 }, + { 30563, 37826 }, + { 30565, 57804 }, + { 30566, 38514 }, + { 30568, 57801 }, + { 30571, 57802 }, + { 30585, 57807 }, + { 30590, 57806 }, + { 30591, 57805 }, + { 30603, 57809 }, + { 30606, 57808 }, + { 30609, 57810 }, + { 30622, 57812 }, + { 30624, 57811 }, + { 30629, 38347 }, + { 30636, 36725 }, + { 30637, 38852 }, + { 30640, 57813 }, + { 30643, 37813 }, + { 30646, 57814 }, + { 30649, 57815 }, + { 30651, 57819 }, + { 30652, 57817 }, + { 30653, 57818 }, + { 30655, 57816 }, + { 30663, 57820 }, + { 30669, 57821 }, + { 30679, 57822 }, + { 30682, 57823 }, + { 30683, 38581 }, + { 30684, 57824 }, + { 30690, 38638 }, + { 30691, 57825 }, + { 30693, 37485 }, + { 30695, 38026 }, + { 30697, 35817 }, + { 30701, 37466 }, + { 30702, 57826 }, + { 30703, 35768 }, + { 30707, 37070 }, + { 30716, 57827 }, + { 30722, 36283 }, + { 30732, 57828 }, + { 30738, 57829 }, + { 30740, 36004 }, + { 30741, 36307 }, + { 30752, 57831 }, + { 30753, 64376 }, + { 30757, 37749 }, + { 30758, 36308 }, + { 30759, 35693 }, + { 30770, 38467 }, + { 30772, 37994 }, + { 30778, 37750 }, + { 30783, 36219 }, + { 30789, 57833 }, + { 30798, 64377 }, + { 30813, 36809 }, + { 30820, 64378 }, + { 30827, 38832 }, + { 30828, 36196 }, + { 30831, 36005 }, + { 30834, 38049 }, + { 30836, 57835 }, + { 30842, 64379 }, + { 30844, 57837 }, + { 30849, 36073 }, + { 30854, 57836 }, + { 30855, 37620 }, + { 30860, 57839 }, + { 30861, 35414 }, + { 30862, 57834 }, + { 30865, 38120 }, + { 30867, 35151 }, + { 30869, 36330 }, + { 30871, 39025 }, + { 30874, 57838 }, + { 30883, 57840 }, + { 30887, 38345 }, + { 30889, 37079 }, + { 30890, 57842 }, + { 30895, 57843 }, + { 30901, 57841 }, + { 30906, 35437 }, + { 30908, 57849 }, + { 30910, 57848 }, + { 30913, 36517 }, + { 30917, 57850 }, + { 30918, 57845 }, + { 30922, 57851 }, + { 30923, 57846 }, + { 30928, 38102 }, + { 30929, 57844 }, + { 30932, 57847 }, + { 30938, 57921 }, + { 30951, 57920 }, + { 30952, 38529 }, + { 30956, 57852 }, + { 30959, 35049 }, + { 30964, 57923 }, + { 30973, 57922 }, + { 30977, 36810 }, + { 30983, 57924 }, + { 30990, 37218 }, + { 30993, 57926 }, + { 30994, 57925 }, + { 31001, 57927 }, + { 31014, 57830 }, + { 31018, 57832 }, + { 31019, 57929 }, + { 31020, 57928 }, + { 31024, 64380 }, + { 31034, 36518 }, + { 31036, 38887 }, + { 31038, 36560 }, + { 31040, 57930 }, + { 31041, 35926 }, + { 31047, 35679 }, + { 31048, 35654 }, + { 31049, 36483 }, + { 31056, 38739 }, + { 31059, 57936 }, + { 31061, 57935 }, + { 31062, 37219 }, + { 31063, 57932 }, + { 31066, 57934 }, + { 31069, 36714 }, + { 31070, 36959 }, + { 31071, 57933 }, + { 31072, 57931 }, + { 31074, 37961 }, + { 31077, 36811 }, + { 31080, 38235 }, + { 31085, 36309 }, + { 31095, 37784 }, + { 31098, 57937 }, + { 31103, 57938 }, + { 31104, 57960 }, + { 31105, 35798 }, + { 31108, 39004 }, + { 31109, 37204 }, + { 31114, 57939 }, + { 31117, 35280 }, + { 31118, 37621 }, + { 31119, 38303 }, + { 31124, 64385 }, + { 31131, 64387 }, + { 31133, 57940 }, + { 31142, 35738 }, + { 31143, 57941 }, + { 31146, 57943 }, + { 31150, 57944 }, + { 31152, 37960 }, + { 31155, 57945 }, + { 31161, 57946 }, + { 31162, 57947 }, + { 31165, 35799 }, + { 31166, 35281 }, + { 31167, 37827 }, + { 31168, 36679 }, + { 31169, 36484 }, + { 31177, 57948 }, + { 31179, 36680 }, + { 31185, 35272 }, + { 31186, 38242 }, + { 31189, 57949 }, + { 31192, 38121 }, + { 31199, 37220 }, + { 31201, 57952 }, + { 31203, 57953 }, + { 31204, 38025 }, + { 31206, 36960 }, + { 31207, 57950 }, + { 31209, 37505 }, + { 31212, 57951 }, + { 31216, 36812 }, + { 31227, 35034 }, + { 31232, 35656 }, + { 31240, 57954 }, + { 31243, 37622 }, + { 31245, 57955 }, + { 31246, 37061 }, + { 31252, 38571 }, + { 31255, 38210 }, + { 31256, 57956 }, + { 31257, 57957 }, + { 31258, 37492 }, + { 31260, 38853 }, + { 31263, 57959 }, + { 31264, 57958 }, + { 31278, 36589 }, + { 31281, 57961 }, + { 31282, 35054 }, + { 31287, 57964 }, + { 31291, 57962 }, + { 31292, 35282 }, + { 31293, 35949 }, + { 31294, 57963 }, + { 31295, 36197 }, + { 31296, 36242 }, + { 31298, 38372 }, + { 31299, 57965 }, + { 31302, 38515 }, + { 31305, 57967 }, + { 31309, 37071 }, + { 31310, 35182 }, + { 31311, 35256 }, + { 31312, 34986 }, + { 31319, 57966 }, + { 31329, 57968 }, + { 31330, 57969 }, + { 31331, 36853 }, + { 31337, 57970 }, + { 31339, 35438 }, + { 31344, 57972 }, + { 31348, 35978 }, + { 31350, 35718 }, + { 31353, 57973 }, + { 31354, 35827 }, + { 31357, 57974 }, + { 31359, 37114 }, + { 31361, 37835 }, + { 31363, 37086 }, + { 31364, 36339 }, + { 31368, 57975 }, + { 31378, 37506 }, + { 31379, 37259 }, + { 31381, 57977 }, + { 31382, 57979 }, + { 31383, 57976 }, + { 31384, 57978 }, + { 31391, 35905 }, + { 31401, 57980 }, + { 31402, 35909 }, + { 31406, 35719 }, + { 31407, 38769 }, + { 31408, 57982 }, + { 31414, 57984 }, + { 31418, 35149 }, + { 31423, 57987 }, + { 31427, 35478 }, + { 31428, 57986 }, + { 31429, 57985 }, + { 31431, 57989 }, + { 31432, 57981 }, + { 31434, 57990 }, + { 31435, 38823 }, + { 31437, 57991 }, + { 31439, 57992 }, + { 31441, 64388 }, + { 31442, 39666 }, + { 31443, 57994 }, + { 31445, 57993 }, + { 31449, 57995 }, + { 31450, 57996 }, + { 31452, 38835 }, + { 31453, 57997 }, + { 31455, 59629 }, + { 31456, 36813 }, + { 31457, 57998 }, + { 31458, 57999 }, + { 31459, 36726 }, + { 31461, 37814 }, + { 31462, 58000 }, + { 31463, 64389 }, + { 31466, 37447 }, + { 31467, 64391 }, + { 31469, 58001 }, + { 31471, 37467 }, + { 31472, 58002 }, + { 31478, 35747 }, + { 31480, 39262 }, + { 31481, 37500 }, + { 31482, 36529 }, + { 31487, 35526 }, + { 31490, 58003 }, + { 31492, 58016 }, + { 31494, 58006 }, + { 31496, 35720 }, + { 31498, 58005 }, + { 31499, 58018 }, + { 31503, 58004 }, + { 31505, 36814 }, + { 31512, 58008 }, + { 31513, 58009 }, + { 31515, 37706 }, + { 31518, 58010 }, + { 31520, 35453 }, + { 31525, 36985 }, + { 31526, 38276 }, + { 31528, 58012 }, + { 31532, 37350 }, + { 31539, 58007 }, + { 31541, 58011 }, + { 31542, 58013 }, + { 31545, 36345 }, + { 31557, 58020 }, + { 31558, 38221 }, + { 31560, 38052 }, + { 31561, 37785 }, + { 31563, 35800 }, + { 31564, 58019 }, + { 31565, 58017 }, + { 31567, 38067 }, + { 31568, 58014 }, + { 31569, 37501 }, + { 31570, 37787 }, + { 31572, 37786 }, + { 31574, 36340 }, + { 31581, 58038 }, + { 31589, 58022 }, + { 31591, 58024 }, + { 31596, 58027 }, + { 31598, 58028 }, + { 31600, 58025 }, + { 31601, 58026 }, + { 31604, 58023 }, + { 31605, 58021 }, + { 31610, 58015 }, + { 31622, 38349 }, + { 31623, 35283 }, + { 31627, 58035 }, + { 31629, 58032 }, + { 31631, 58037 }, + { 31634, 58036 }, + { 31636, 38035 }, + { 31637, 38565 }, + { 31639, 36442 }, + { 31640, 58030 }, + { 31641, 58039 }, + { 31642, 58034 }, + { 31644, 58033 }, + { 31645, 58029 }, + { 31646, 64392 }, + { 31647, 58031 }, + { 31649, 35527 }, + { 31658, 37468 }, + { 31661, 37115 }, + { 31665, 38048 }, + { 31668, 58044 }, + { 31672, 38050 }, + { 31680, 37087 }, + { 31681, 58041 }, + { 31684, 38093 }, + { 31686, 58045 }, + { 31687, 38353 }, + { 31689, 37498 }, + { 31691, 58040 }, + { 31692, 58042 }, + { 31695, 58043 }, + { 31709, 58046 }, + { 31712, 36546 }, + { 31716, 37828 }, + { 31717, 58051 }, + { 31718, 58050 }, + { 31721, 58047 }, + { 31725, 38997 }, + { 31731, 58056 }, + { 31734, 58060 }, + { 31735, 58057 }, + { 31744, 58053 }, + { 31751, 58054 }, + { 31757, 58059 }, + { 31761, 58048 }, + { 31762, 39379 }, + { 31763, 58055 }, + { 31764, 58049 }, + { 31767, 58058 }, + { 31775, 58064 }, + { 31777, 35528 }, + { 31779, 58061 }, + { 31783, 58062 }, + { 31786, 58063 }, + { 31787, 58066 }, + { 31799, 58065 }, + { 31800, 38132 }, + { 31805, 58067 }, + { 31806, 38906 }, + { 31807, 38379 }, + { 31808, 58072 }, + { 31811, 58069 }, + { 31820, 58068 }, + { 31821, 37072 }, + { 31823, 58071 }, + { 31824, 58073 }, + { 31828, 58070 }, + { 31830, 58077 }, + { 31832, 58074 }, + { 31839, 58075 }, + { 31840, 58052 }, + { 31844, 58076 }, + { 31845, 58078 }, + { 31852, 58079 }, + { 31859, 38340 }, + { 31861, 58080 }, + { 31870, 38624 }, + { 31873, 35788 }, + { 31874, 35912 }, + { 31875, 58081 }, + { 31881, 38322 }, + { 31883, 37000 }, + { 31885, 38574 }, + { 31888, 58082 }, + { 31890, 38833 }, + { 31893, 38036 }, + { 31895, 37221 }, + { 31896, 37971 }, + { 31899, 36716 }, + { 31903, 35006 }, + { 31905, 58087 }, + { 31906, 58085 }, + { 31908, 58083 }, + { 31909, 35487 }, + { 31911, 36815 }, + { 31912, 58088 }, + { 31915, 58086 }, + { 31917, 58084 }, + { 31918, 58092 }, + { 31921, 58091 }, + { 31922, 58090 }, + { 31923, 58089 }, + { 31929, 58093 }, + { 31933, 58094 }, + { 31934, 37048 }, + { 31936, 58095 }, + { 31938, 58097 }, + { 31941, 58096 }, + { 31946, 36048 }, + { 31950, 37207 }, + { 31954, 58099 }, + { 31958, 37788 }, + { 31960, 58098 }, + { 31964, 58100 }, + { 31966, 38323 }, + { 31967, 37260 }, + { 31968, 36198 }, + { 31970, 58101 }, + { 31975, 38854 }, + { 31983, 58103 }, + { 31986, 58104 }, + { 31988, 58105 }, + { 31990, 58106 }, + { 31992, 36485 }, + { 31994, 58107 }, + { 31995, 35950 }, + { 31998, 35722 }, + { 32000, 35657 }, + { 32002, 58176 }, + { 32004, 38641 }, + { 32005, 36199 }, + { 32006, 58108 }, + { 32010, 58179 }, + { 32011, 38628 }, + { 32013, 37979 }, + { 32016, 38226 }, + { 32020, 36739 }, + { 32021, 58178 }, + { 32023, 36561 }, + { 32024, 36200 }, + { 32025, 36486 }, + { 32026, 35721 }, + { 32027, 38324 }, + { 32028, 58177 }, + { 32032, 37222 }, + { 32033, 38497 }, + { 32034, 36341 }, + { 32043, 36487 }, + { 32044, 37595 }, + { 32046, 58182 }, + { 32047, 38877 }, + { 32048, 36311 }, + { 32050, 58183 }, + { 32051, 36961 }, + { 32053, 58185 }, + { 32057, 36816 }, + { 32058, 36270 }, + { 32063, 58184 }, + { 32066, 36681 }, + { 32067, 36028 }, + { 32068, 37223 }, + { 32069, 58180 }, + { 32070, 58186 }, + { 32072, 64394 }, + { 32075, 58181 }, + { 32076, 35951 }, + { 32078, 58189 }, + { 32079, 58193 }, + { 32080, 35979 }, + { 32086, 58188 }, + { 32091, 58197 }, + { 32092, 64395 }, + { 32094, 36201 }, + { 32097, 38797 }, + { 32098, 35002 }, + { 32099, 58194 }, + { 32102, 35723 }, + { 32104, 58191 }, + { 32110, 58192 }, + { 32113, 37789 }, + { 32114, 58190 }, + { 32115, 58187 }, + { 32117, 35399 }, + { 32118, 37090 }, + { 32121, 36006 }, + { 32125, 58199 }, + { 32137, 58196 }, + { 32143, 58198 }, + { 32147, 58195 }, + { 32153, 35952 }, + { 32154, 37297 }, + { 32155, 58200 }, + { 32156, 37262 }, + { 32159, 58213 }, + { 32160, 64397 }, + { 32162, 58209 }, + { 32163, 58203 }, + { 32171, 58207 }, + { 32172, 36600 }, + { 32173, 35035 }, + { 32174, 58202 }, + { 32175, 58210 }, + { 32176, 58214 }, + { 32177, 36202 }, + { 32178, 38612 }, + { 32180, 37588 }, + { 32181, 58204 }, + { 32183, 64396 }, + { 32184, 58212 }, + { 32186, 58201 }, + { 32187, 37469 }, + { 32189, 58206 }, + { 32190, 35003 }, + { 32191, 38600 }, + { 32199, 58205 }, + { 32202, 35801 }, + { 32203, 38122 }, + { 32207, 37261 }, + { 32209, 38862 }, + { 32210, 36751 }, + { 32213, 58254 }, + { 32214, 64398 }, + { 32216, 58215 }, + { 32218, 37116 }, + { 32220, 58211 }, + { 32221, 58216 }, + { 32222, 58218 }, + { 32224, 37623 }, + { 32225, 58221 }, + { 32228, 58217 }, + { 32232, 38354 }, + { 32233, 35529 }, + { 32236, 38601 }, + { 32239, 35036 }, + { 32242, 58220 }, + { 32244, 38907 }, + { 32251, 58219 }, + { 32257, 35215 }, + { 32260, 37866 }, + { 32261, 58222 }, + { 32265, 58229 }, + { 32266, 58223 }, + { 32267, 58230 }, + { 32274, 58226 }, + { 32283, 38043 }, + { 32286, 36552 }, + { 32287, 58228 }, + { 32289, 58225 }, + { 32290, 58231 }, + { 32291, 58224 }, + { 32294, 36707 }, + { 32299, 38468 }, + { 32302, 36715 }, + { 32305, 58227 }, + { 32306, 58240 }, + { 32309, 58235 }, + { 32311, 58238 }, + { 32313, 58236 }, + { 32314, 58241 }, + { 32315, 58234 }, + { 32317, 58208 }, + { 32318, 37073 }, + { 32321, 38089 }, + { 32323, 58237 }, + { 32326, 58232 }, + { 32330, 37184 }, + { 32331, 35953 }, + { 32333, 36682 }, + { 32338, 64399 }, + { 32340, 36932 }, + { 32341, 37205 }, + { 32342, 58244 }, + { 32345, 58246 }, + { 32346, 58247 }, + { 32349, 58243 }, + { 32350, 58245 }, + { 32358, 58233 }, + { 32359, 58242 }, + { 32361, 58250 }, + { 32362, 58249 }, + { 32365, 38554 }, + { 32368, 35914 }, + { 32377, 58248 }, + { 32379, 58252 }, + { 32380, 58251 }, + { 32381, 58255 }, + { 32383, 58257 }, + { 32386, 36443 }, + { 32387, 58253 }, + { 32392, 58258 }, + { 32393, 58259 }, + { 32394, 64092 }, + { 32396, 58260 }, + { 32398, 58266 }, + { 32399, 37722 }, + { 32400, 58262 }, + { 32402, 58261 }, + { 32403, 58263 }, + { 32404, 58264 }, + { 32406, 58265 }, + { 32411, 58267 }, + { 32412, 58268 }, + { 32566, 35530 }, + { 32568, 58269 }, + { 32570, 58270 }, + { 32581, 58271 }, + { 32583, 64400 }, + { 32588, 58272 }, + { 32589, 58273 }, + { 32590, 58274 }, + { 32592, 58275 }, + { 32593, 58276 }, + { 32596, 58278 }, + { 32597, 58277 }, + { 32600, 58279 }, + { 32607, 58280 }, + { 32608, 58281 }, + { 32615, 58284 }, + { 32616, 58282 }, + { 32617, 58283 }, + { 32618, 36319 }, + { 32619, 35954 }, + { 32622, 37493 }, + { 32624, 38065 }, + { 32626, 36752 }, + { 32629, 37996 }, + { 32631, 38123 }, + { 32632, 58285 }, + { 32633, 40171 }, + { 32642, 58286 }, + { 32643, 58288 }, + { 32645, 38789 }, + { 32646, 58287 }, + { 32647, 58290 }, + { 32648, 58289 }, + { 32650, 38770 }, + { 32652, 58291 }, + { 32654, 38140 }, + { 32660, 58292 }, + { 32666, 58295 }, + { 32669, 58294 }, + { 32670, 58293 }, + { 32673, 64401 }, + { 32675, 58296 }, + { 32676, 35921 }, + { 32680, 37185 }, + { 32681, 35680 }, + { 32686, 58300 }, + { 32687, 58297 }, + { 32690, 58298 }, + { 32694, 58301 }, + { 32696, 58302 }, + { 32697, 58299 }, + { 32701, 35144 }, + { 32705, 35237 }, + { 32709, 58304 }, + { 32710, 58305 }, + { 32714, 58306 }, + { 32716, 38786 }, + { 32722, 36683 }, + { 32724, 58308 }, + { 32725, 58307 }, + { 32736, 37001 }, + { 32737, 58309 }, + { 32742, 58310 }, + { 32745, 58311 }, + { 32747, 35555 }, + { 32752, 35531 }, + { 32755, 58312 }, + { 32761, 58313 }, + { 32763, 38524 }, + { 32764, 38787 }, + { 32768, 38771 }, + { 32769, 38998 }, + { 32771, 36204 }, + { 32772, 58316 }, + { 32773, 36562 }, + { 32774, 58315 }, + { 32779, 58317 }, + { 32780, 36519 }, + { 32784, 37327 }, + { 32786, 58318 }, + { 32789, 36203 }, + { 32791, 38613 }, + { 32792, 58319 }, + { 32793, 58320 }, + { 32796, 58321 }, + { 32801, 58322 }, + { 32808, 58323 }, + { 32819, 36520 }, + { 32822, 38635 }, + { 32827, 58325 }, + { 32829, 37470 }, + { 32831, 58324 }, + { 32838, 58327 }, + { 32842, 58326 }, + { 32850, 58328 }, + { 32854, 37049 }, + { 32856, 58329 }, + { 32858, 58330 }, + { 32862, 38327 }, + { 32863, 58331 }, + { 32865, 37263 }, + { 32866, 58332 }, + { 32872, 58333 }, + { 32879, 38908 }, + { 32880, 58336 }, + { 32882, 58335 }, + { 32883, 58334 }, + { 32884, 37550 }, + { 32886, 58337 }, + { 32887, 36933 }, + { 32889, 58338 }, + { 32893, 58339 }, + { 32894, 38999 }, + { 32895, 58340 }, + { 32900, 58341 }, + { 32901, 58343 }, + { 32902, 58342 }, + { 32903, 38051 }, + { 32905, 37879 }, + { 32907, 39005 }, + { 32908, 38055 }, + { 32915, 58345 }, + { 32918, 36817 }, + { 32920, 38217 }, + { 32922, 58346 }, + { 32923, 58344 }, + { 32925, 35532 }, + { 32929, 36050 }, + { 32930, 36488 }, + { 32933, 38124 }, + { 32937, 36008 }, + { 32938, 38498 }, + { 32940, 58349 }, + { 32941, 58347 }, + { 32943, 36205 }, + { 32945, 36206 }, + { 32946, 35047 }, + { 32948, 36326 }, + { 32954, 38008 }, + { 32963, 35037 }, + { 32964, 58354 }, + { 32966, 37471 }, + { 32972, 38007 }, + { 32974, 37337 }, + { 32982, 58356 }, + { 32985, 58352 }, + { 32986, 58355 }, + { 32987, 58350 }, + { 32989, 58353 }, + { 32990, 38469 }, + { 32993, 36051 }, + { 32996, 35067 }, + { 32997, 58351 }, + { 33007, 58358 }, + { 33009, 58359 }, + { 33012, 37815 }, + { 33016, 35769 }, + { 33020, 58437 }, + { 33021, 37980 }, + { 33026, 36489 }, + { 33029, 35770 }, + { 33030, 37062 }, + { 33031, 39013 }, + { 33032, 38572 }, + { 33033, 58357 }, + { 33034, 37074 }, + { 33050, 35698 }, + { 33051, 58360 }, + { 33059, 58362 }, + { 33065, 58361 }, + { 33071, 58363 }, + { 33073, 37445 }, + { 33075, 37981 }, + { 33081, 37551 }, + { 33086, 58434 }, + { 33094, 58433 }, + { 33099, 58364 }, + { 33102, 36980 }, + { 33104, 38277 }, + { 33105, 58436 }, + { 33107, 58435 }, + { 33108, 36207 }, + { 33109, 39026 }, + { 33119, 58452 }, + { 33125, 58440 }, + { 33126, 58441 }, + { 33131, 36590 }, + { 33134, 58439 }, + { 33136, 36248 }, + { 33137, 58438 }, + { 33140, 58442 }, + { 33144, 37552 }, + { 33145, 38304 }, + { 33146, 37186 }, + { 33151, 37338 }, + { 33152, 58446 }, + { 33154, 58447 }, + { 33155, 58443 }, + { 33160, 58444 }, + { 33162, 58445 }, + { 33167, 36208 }, + { 33171, 58453 }, + { 33173, 58449 }, + { 33178, 38278 }, + { 33180, 38540 }, + { 33181, 38215 }, + { 33184, 58448 }, + { 33187, 58451 }, + { 33188, 58450 }, + { 33192, 38499 }, + { 33193, 58454 }, + { 33200, 58455 }, + { 33203, 37206 }, + { 33205, 58456 }, + { 33208, 58458 }, + { 33210, 58462 }, + { 33213, 58459 }, + { 33214, 58457 }, + { 33215, 37982 }, + { 33216, 58460 }, + { 33218, 58461 }, + { 33222, 35248 }, + { 33224, 58468 }, + { 33225, 58463 }, + { 33229, 58464 }, + { 33233, 58465 }, + { 33235, 37279 }, + { 33240, 58467 }, + { 33241, 58466 }, + { 33242, 58469 }, + { 33247, 58470 }, + { 33248, 58471 }, + { 33251, 36962 }, + { 33253, 35303 }, + { 33255, 58472 }, + { 33256, 38869 }, + { 33258, 36521 }, + { 33261, 36684 }, + { 33267, 36490 }, + { 33268, 37494 }, + { 33274, 58473 }, + { 33275, 58474 }, + { 33276, 35152 }, + { 33278, 58475 }, + { 33281, 58476 }, + { 33282, 58477 }, + { 33285, 58478 }, + { 33287, 58479 }, + { 33288, 35771 }, + { 33289, 40360 }, + { 33290, 58480 }, + { 33292, 37091 }, + { 33293, 58481 }, + { 33294, 36553 }, + { 33296, 58482 }, + { 33298, 39086 }, + { 33302, 58483 }, + { 33303, 38364 }, + { 33304, 35546 }, + { 33307, 37187 }, + { 33308, 36727 }, + { 33310, 38289 }, + { 33311, 36685 }, + { 33321, 58484 }, + { 33322, 36209 }, + { 33323, 58485 }, + { 33324, 38090 }, + { 33326, 58500 }, + { 33331, 58487 }, + { 33333, 37319 }, + { 33334, 38037 }, + { 33335, 36029 }, + { 33336, 58486 }, + { 33337, 37188 }, + { 33344, 58488 }, + { 33351, 37624 }, + { 33368, 58490 }, + { 33369, 58489 }, + { 33370, 58492 }, + { 33373, 58491 }, + { 33375, 58493 }, + { 33378, 58496 }, + { 33380, 58494 }, + { 33382, 35533 }, + { 33384, 58497 }, + { 33386, 58498 }, + { 33387, 58499 }, + { 33390, 36271 }, + { 33391, 38855 }, + { 33393, 58501 }, + { 33394, 36934 }, + { 33398, 35216 }, + { 33399, 58502 }, + { 33400, 58503 }, + { 33406, 58504 }, + { 33419, 35056 }, + { 33421, 58505 }, + { 33426, 58506 }, + { 33433, 38279 }, + { 33437, 36549 }, + { 33439, 58508 }, + { 33445, 35400 }, + { 33446, 34992 }, + { 33451, 58507 }, + { 33452, 58510 }, + { 33453, 37997 }, + { 33455, 36963 }, + { 33457, 35284 }, + { 33459, 38470 }, + { 33464, 35964 }, + { 33465, 35802 }, + { 33467, 58509 }, + { 33469, 35304 }, + { 33477, 35489 }, + { 33489, 35217 }, + { 33490, 58514 }, + { 33491, 38888 }, + { 33492, 37339 }, + { 33495, 38243 }, + { 33497, 58526 }, + { 33499, 35285 }, + { 33500, 58524 }, + { 33502, 58522 }, + { 33503, 58513 }, + { 33505, 58511 }, + { 33507, 58512 }, + { 33509, 36577 }, + { 33510, 35818 }, + { 33511, 37527 }, + { 33515, 37839 }, + { 33521, 35184 }, + { 33523, 58516 }, + { 33524, 58515 }, + { 33529, 58521 }, + { 33530, 58517 }, + { 33531, 58520 }, + { 33537, 64403 }, + { 33538, 38606 }, + { 33539, 58519 }, + { 33540, 35286 }, + { 33541, 35485 }, + { 33542, 58523 }, + { 33545, 58525 }, + { 33550, 35955 }, + { 33558, 58529 }, + { 33559, 58538 }, + { 33560, 58539 }, + { 33564, 34985 }, + { 33571, 58546 }, + { 33576, 35055 }, + { 33579, 58537 }, + { 33583, 58536 }, + { 33585, 58531 }, + { 33586, 58530 }, + { 33588, 58528 }, + { 33589, 58527 }, + { 33590, 37507 }, + { 33592, 37369 }, + { 33593, 58533 }, + { 33600, 58532 }, + { 33605, 58535 }, + { 33609, 37264 }, + { 33610, 35956 }, + { 33615, 35168 }, + { 33616, 58534 }, + { 33618, 36210 }, + { 33624, 37265 }, + { 33634, 64404 }, + { 33651, 58552 }, + { 33653, 58553 }, + { 33655, 35287 }, + { 33659, 35244 }, + { 33660, 58550 }, + { 33663, 64405 }, + { 33669, 58540 }, + { 33671, 58548 }, + { 33673, 58555 }, + { 33674, 58549 }, + { 33678, 58547 }, + { 33683, 58518 }, + { 33686, 58545 }, + { 33690, 58541 }, + { 33694, 35534 }, + { 33695, 58543 }, + { 33696, 58554 }, + { 33698, 58544 }, + { 33704, 58556 }, + { 33706, 58542 }, + { 33707, 38044 }, + { 33713, 38793 }, + { 33717, 58551 }, + { 33725, 58573 }, + { 33729, 58565 }, + { 33733, 37019 }, + { 33735, 64406 }, + { 33738, 35685 }, + { 33740, 35803 }, + { 33742, 58560 }, + { 33747, 35289 }, + { 33750, 36818 }, + { 33752, 58563 }, + { 33756, 36312 }, + { 33759, 37744 }, + { 33760, 58568 }, + { 33769, 38380 }, + { 33771, 58559 }, + { 33775, 35288 }, + { 33776, 36052 }, + { 33777, 38216 }, + { 33778, 58569 }, + { 33780, 58557 }, + { 33782, 64407 }, + { 33783, 58566 }, + { 33787, 58576 }, + { 33789, 58561 }, + { 33795, 58562 }, + { 33796, 37816 }, + { 33799, 58567 }, + { 33803, 58564 }, + { 33804, 38471 }, + { 33805, 58570 }, + { 33806, 35038 }, + { 33811, 58558 }, + { 33824, 58572 }, + { 33826, 58571 }, + { 33833, 38027 }, + { 33834, 58578 }, + { 33836, 58589 }, + { 33841, 35486 }, + { 33845, 58592 }, + { 33848, 58574 }, + { 33852, 58579 }, + { 33853, 38798 }, + { 33862, 58588 }, + { 33864, 64408 }, + { 33865, 38772 }, + { 33870, 38824 }, + { 33879, 37528 }, + { 33883, 35467 }, + { 33889, 38290 }, + { 33890, 58594 }, + { 33891, 37791 }, + { 33894, 34991 }, + { 33897, 58587 }, + { 33899, 58583 }, + { 33900, 37266 }, + { 33901, 58577 }, + { 33902, 58585 }, + { 33903, 58590 }, + { 33905, 37963 }, + { 33909, 34984 }, + { 33911, 58582 }, + { 33913, 58591 }, + { 33914, 38296 }, + { 33922, 58586 }, + { 33924, 58581 }, + { 33931, 36819 }, + { 33936, 36686 }, + { 33940, 36522 }, + { 33945, 38614 }, + { 33948, 38246 }, + { 33951, 58597 }, + { 33953, 58606 }, + { 33965, 58584 }, + { 33970, 35479 }, + { 33972, 64409 }, + { 33976, 36854 }, + { 33977, 58595 }, + { 33979, 58600 }, + { 33980, 37267 }, + { 33983, 58596 }, + { 33985, 58603 }, + { 33988, 37502 }, + { 33990, 58604 }, + { 33993, 38773 }, + { 33994, 58593 }, + { 33995, 35415 }, + { 33997, 58599 }, + { 34000, 58602 }, + { 34001, 38570 }, + { 34006, 58605 }, + { 34009, 58598 }, + { 34010, 58601 }, + { 34012, 64096 }, + { 34028, 38472 }, + { 34030, 38976 }, + { 34036, 58609 }, + { 34044, 58616 }, + { 34047, 58608 }, + { 34048, 36545 }, + { 34054, 58575 }, + { 34065, 38348 }, + { 34067, 38560 }, + { 34068, 58615 }, + { 34069, 58614 }, + { 34071, 58610 }, + { 34072, 58611 }, + { 34074, 35157 }, + { 34079, 58613 }, + { 34081, 58607 }, + { 34086, 37587 }, + { 34092, 58612 }, + { 34093, 35068 }, + { 34101, 37280 }, + { 34109, 38337 }, + { 34112, 58617 }, + { 34113, 58688 }, + { 34115, 38103 }, + { 34120, 58620 }, + { 34121, 36820 }, + { 34122, 36551 }, + { 34123, 58690 }, + { 34126, 35772 }, + { 34131, 64410 }, + { 34133, 58691 }, + { 34135, 38297 }, + { 34136, 58619 }, + { 34137, 64411 }, + { 34138, 58580 }, + { 34147, 58618 }, + { 34152, 39022 }, + { 34153, 37792 }, + { 34154, 38291 }, + { 34155, 64412 }, + { 34157, 58698 }, + { 34167, 58704 }, + { 34174, 58705 }, + { 34176, 58692 }, + { 34180, 38038 }, + { 34183, 58702 }, + { 34184, 58694 }, + { 34186, 58696 }, + { 34192, 58706 }, + { 34193, 58695 }, + { 34196, 58699 }, + { 34199, 35218 }, + { 34201, 37859 }, + { 34203, 58700 }, + { 34204, 58703 }, + { 34212, 58693 }, + { 34214, 37189 }, + { 34216, 58697 }, + { 34217, 36422 }, + { 34218, 36964 }, + { 34219, 35919 }, + { 34220, 38642 }, + { 34222, 38647 }, + { 34223, 36754 }, + { 34224, 64414 }, + { 34233, 58710 }, + { 34234, 58708 }, + { 34241, 39021 }, + { 34249, 58707 }, + { 34253, 38805 }, + { 34255, 58709 }, + { 34256, 58711 }, + { 34261, 58712 }, + { 34268, 58715 }, + { 34269, 58713 }, + { 34276, 37793 }, + { 34277, 58714 }, + { 34281, 38091 }, + { 34282, 58701 }, + { 34295, 36755 }, + { 34297, 58716 }, + { 34298, 58721 }, + { 34299, 37268 }, + { 34302, 58720 }, + { 34306, 58689 }, + { 34310, 58722 }, + { 34311, 37224 }, + { 34314, 58717 }, + { 34315, 58719 }, + { 34323, 58718 }, + { 34326, 40784 }, + { 34327, 40769 }, + { 34330, 58724 }, + { 34338, 58723 }, + { 34349, 38806 }, + { 34351, 57786 }, + { 34352, 58725 }, + { 34367, 58726 }, + { 34381, 58727 }, + { 34382, 36053 }, + { 34384, 35699 }, + { 34388, 58729 }, + { 34389, 39292 }, + { 34394, 35733 }, + { 34396, 38840 }, + { 34398, 35825 }, + { 34399, 58730 }, + { 34407, 58731 }, + { 34411, 37518 }, + { 34417, 58732 }, + { 34425, 37880 }, + { 34427, 35000 }, + { 34442, 35297 }, + { 34443, 58737 }, + { 34444, 58738 }, + { 34451, 58733 }, + { 34453, 36444 }, + { 34467, 58734 }, + { 34468, 37985 }, + { 34473, 58735 }, + { 34474, 58736 }, + { 34475, 58746 }, + { 34479, 58740 }, + { 34480, 58743 }, + { 34486, 58739 }, + { 34500, 58741 }, + { 34502, 58742 }, + { 34503, 36566 }, + { 34505, 58744 }, + { 34507, 37472 }, + { 34509, 35957 }, + { 34510, 35425 }, + { 34516, 58747 }, + { 34521, 35422 }, + { 34523, 58753 }, + { 34526, 58748 }, + { 34527, 58752 }, + { 34532, 38072 }, + { 34537, 58749 }, + { 34540, 58750 }, + { 34541, 38247 }, + { 34542, 38104 }, + { 34543, 58754 }, + { 34552, 37371 }, + { 34553, 58764 }, + { 34555, 58760 }, + { 34558, 35305 }, + { 34560, 58758 }, + { 34562, 38473 }, + { 34563, 58759 }, + { 34566, 58756 }, + { 34568, 58757 }, + { 34569, 58762 }, + { 34570, 58765 }, + { 34573, 58763 }, + { 34577, 58761 }, + { 34578, 58755 }, + { 34584, 37495 }, + { 34586, 58772 }, + { 34588, 38568 }, + { 34597, 58770 }, + { 34601, 58771 }, + { 34612, 58766 }, + { 34615, 58768 }, + { 34619, 58769 }, + { 34623, 58767 }, + { 34633, 37092 }, + { 34635, 39000 }, + { 34636, 58776 }, + { 34638, 58777 }, + { 34643, 58783 }, + { 34645, 36937 }, + { 34647, 58779 }, + { 34649, 58782 }, + { 34655, 58774 }, + { 34656, 58773 }, + { 34659, 58784 }, + { 34662, 35290 }, + { 34664, 58780 }, + { 34666, 58785 }, + { 34670, 58781 }, + { 34676, 58778 }, + { 34678, 37553 }, + { 34680, 58775 }, + { 34687, 38024 }, + { 34690, 58789 }, + { 34701, 38746 }, + { 34719, 58788 }, + { 34722, 58787 }, + { 34731, 58796 }, + { 34735, 58790 }, + { 34739, 58798 }, + { 34746, 38790 }, + { 34747, 58801 }, + { 34749, 58792 }, + { 34752, 58793 }, + { 34756, 58797 }, + { 34758, 58800 }, + { 34759, 58799 }, + { 34763, 58791 }, + { 34768, 58794 }, + { 34770, 58811 }, + { 34784, 58804 }, + { 34799, 58802 }, + { 34802, 58803 }, + { 34806, 58808 }, + { 34807, 58809 }, + { 34809, 35401 }, + { 34811, 35681 }, + { 34814, 58807 }, + { 34821, 58786 }, + { 34823, 64417 }, + { 34829, 58806 }, + { 34830, 58810 }, + { 34831, 58805 }, + { 34833, 58812 }, + { 34837, 58814 }, + { 34838, 58813 }, + { 34849, 58816 }, + { 34850, 58815 }, + { 34851, 58745 }, + { 34855, 58820 }, + { 34865, 58817 }, + { 34870, 58818 }, + { 34873, 58819 }, + { 34875, 58821 }, + { 34880, 35980 }, + { 34882, 58823 }, + { 34884, 58822 }, + { 34886, 36687 }, + { 34892, 36211 }, + { 34893, 40869 }, + { 34898, 58824 }, + { 34899, 36720 }, + { 34903, 35416 }, + { 34905, 58825 }, + { 34907, 35185 }, + { 34909, 36821 }, + { 34910, 58826 }, + { 34913, 36212 }, + { 34914, 58827 }, + { 34915, 35039 }, + { 34920, 38236 }, + { 34923, 58828 }, + { 34928, 37002 }, + { 34930, 58835 }, + { 34933, 58832 }, + { 34935, 37519 }, + { 34941, 58833 }, + { 34942, 58830 }, + { 34943, 35804 }, + { 34945, 58829 }, + { 34946, 58836 }, + { 34952, 35925 }, + { 34955, 37340 }, + { 34957, 58842 }, + { 34962, 58838 }, + { 34966, 37299 }, + { 34967, 58837 }, + { 34969, 58840 }, + { 34974, 58831 }, + { 34978, 58841 }, + { 34980, 58843 }, + { 34987, 38125 }, + { 34990, 58839 }, + { 34992, 58844 }, + { 34993, 58846 }, + { 34996, 36049 }, + { 34997, 58834 }, + { 34999, 35007 }, + { 35007, 58845 }, + { 35009, 36313 }, + { 35010, 38900 }, + { 35011, 58847 }, + { 35012, 58848 }, + { 35013, 37269 }, + { 35023, 38816 }, + { 35028, 58849 }, + { 35029, 38740 }, + { 35032, 58850 }, + { 35033, 58851 }, + { 35036, 38370 }, + { 35037, 58852 }, + { 35039, 36286 }, + { 35041, 38817 }, + { 35048, 58857 }, + { 35058, 58858 }, + { 35059, 36822 }, + { 35060, 58856 }, + { 35061, 64418 }, + { 35064, 38791 }, + { 35065, 58853 }, + { 35068, 58855 }, + { 35069, 37051 }, + { 35070, 37022 }, + { 35074, 58854 }, + { 35076, 58859 }, + { 35079, 38305 }, + { 35082, 58861 }, + { 35084, 58860 }, + { 35088, 35468 }, + { 35090, 38474 }, + { 35091, 58862 }, + { 35100, 64093 }, + { 35101, 58874 }, + { 35102, 58864 }, + { 35109, 58865 }, + { 35114, 58866 }, + { 35115, 58867 }, + { 35126, 58871 }, + { 35128, 58872 }, + { 35131, 58870 }, + { 35137, 58868 }, + { 35139, 58863 }, + { 35140, 58869 }, + { 35148, 58873 }, + { 35149, 59573 }, + { 35158, 35238 }, + { 35166, 58876 }, + { 35167, 35805 }, + { 35168, 58875 }, + { 35172, 58945 }, + { 35174, 58944 }, + { 35178, 58947 }, + { 35181, 58946 }, + { 35183, 58948 }, + { 35186, 36688 }, + { 35188, 58949 }, + { 35191, 58950 }, + { 35198, 58951 }, + { 35199, 37052 }, + { 35201, 38774 }, + { 35203, 58952 }, + { 35206, 38306 }, + { 35207, 37989 }, + { 35208, 58953 }, + { 35210, 58954 }, + { 35211, 36009 }, + { 35215, 35659 }, + { 35219, 58955 }, + { 35222, 36491 }, + { 35223, 37984 }, + { 35224, 58956 }, + { 35226, 35439 }, + { 35233, 58957 }, + { 35238, 58959 }, + { 35239, 38807 }, + { 35241, 58958 }, + { 35242, 36965 }, + { 35244, 58960 }, + { 35247, 58961 }, + { 35250, 58962 }, + { 35251, 35535 }, + { 35258, 58963 }, + { 35261, 58964 }, + { 35263, 58965 }, + { 35264, 58966 }, + { 35282, 35440 }, + { 35290, 58967 }, + { 35292, 58968 }, + { 35293, 58969 }, + { 35299, 35312 }, + { 35302, 36935 }, + { 35303, 58970 }, + { 35316, 58971 }, + { 35320, 58972 }, + { 35328, 36030 }, + { 35330, 37625 }, + { 35331, 58973 }, + { 35336, 35958 }, + { 35338, 36981 }, + { 35340, 58976 }, + { 35342, 37794 }, + { 35344, 58975 }, + { 35346, 64419 }, + { 35347, 35920 }, + { 35350, 58974 }, + { 35351, 37365 }, + { 35352, 35660 }, + { 35355, 58977 }, + { 35357, 58978 }, + { 35359, 36823 }, + { 35363, 35981 }, + { 35365, 58979 }, + { 35370, 38475 }, + { 35373, 37085 }, + { 35377, 35734 }, + { 35379, 38643 }, + { 35380, 37225 }, + { 35382, 58980 }, + { 35383, 64420 }, + { 35386, 36966 }, + { 35387, 37520 }, + { 35388, 36824 }, + { 35393, 58981 }, + { 35398, 58984 }, + { 35400, 58985 }, + { 35408, 36284 }, + { 35409, 37312 }, + { 35410, 58983 }, + { 35412, 36825 }, + { 35413, 38237 }, + { 35419, 58982 }, + { 35422, 36492 }, + { 35424, 35186 }, + { 35426, 58989 }, + { 35427, 35959 }, + { 35430, 36494 }, + { 35433, 36493 }, + { 35435, 39020 }, + { 35436, 58988 }, + { 35437, 58987 }, + { 35438, 37190 }, + { 35440, 35692 }, + { 35441, 39010 }, + { 35442, 35417 }, + { 35443, 36826 }, + { 35449, 64421 }, + { 35452, 58986 }, + { 35458, 58991 }, + { 35460, 58992 }, + { 35461, 58990 }, + { 35463, 36054 }, + { 35465, 38751 }, + { 35468, 36495 }, + { 35469, 37958 }, + { 35473, 58995 }, + { 35475, 37054 }, + { 35477, 37473 }, + { 35480, 38741 }, + { 35482, 58998 }, + { 35486, 36074 }, + { 35488, 37053 }, + { 35489, 58994 }, + { 35491, 58999 }, + { 35492, 36075 }, + { 35493, 58996 }, + { 35494, 58997 }, + { 35495, 64422 }, + { 35496, 58993 }, + { 35500, 37088 }, + { 35501, 37831 }, + { 35504, 37454 }, + { 35506, 35291 }, + { 35513, 38126 }, + { 35516, 35682 }, + { 35518, 64423 }, + { 35519, 37554 }, + { 35522, 59002 }, + { 35524, 59000 }, + { 35527, 37483 }, + { 35531, 37055 }, + { 35532, 35536 }, + { 35533, 59001 }, + { 35535, 36986 }, + { 35538, 38856 }, + { 35542, 39007 }, + { 35546, 59003 }, + { 35547, 59015 }, + { 35548, 37555 }, + { 35550, 59014 }, + { 35551, 64424 }, + { 35552, 59011 }, + { 35553, 59019 }, + { 35554, 59012 }, + { 35556, 59008 }, + { 35558, 37626 }, + { 35559, 59006 }, + { 35563, 59004 }, + { 35565, 38720 }, + { 35566, 36496 }, + { 35569, 59009 }, + { 35571, 59005 }, + { 35574, 64426 }, + { 35575, 59013 }, + { 35576, 36756 }, + { 35578, 36031 }, + { 35582, 37368 }, + { 35584, 38500 }, + { 35585, 35193 }, + { 35586, 35040 }, + { 35588, 37795 }, + { 35591, 59017 }, + { 35596, 59016 }, + { 35598, 37860 }, + { 35600, 59021 }, + { 35604, 59010 }, + { 35606, 59020 }, + { 35607, 59022 }, + { 35609, 36010 }, + { 35610, 59018 }, + { 35611, 36213 }, + { 35613, 36563 }, + { 35616, 59023 }, + { 35617, 38775 }, + { 35622, 59026 }, + { 35624, 59029 }, + { 35627, 59027 }, + { 35628, 38228 }, + { 35635, 59024 }, + { 35641, 35806 }, + { 35646, 59028 }, + { 35649, 59030 }, + { 35657, 59034 }, + { 35660, 59031 }, + { 35662, 59033 }, + { 35663, 59032 }, + { 35667, 64427 }, + { 35670, 59035 }, + { 35672, 36527 }, + { 35674, 59037 }, + { 35675, 59036 }, + { 35676, 38280 }, + { 35679, 59039 }, + { 35686, 35960 }, + { 35691, 59038 }, + { 35692, 59040 }, + { 35695, 59041 }, + { 35696, 35683 }, + { 35697, 58303 }, + { 35698, 36855 }, + { 35700, 59042 }, + { 35703, 36076 }, + { 35709, 59043 }, + { 35711, 64428 }, + { 35712, 59044 }, + { 35715, 36445 }, + { 35722, 40396 }, + { 35724, 59045 }, + { 35726, 59046 }, + { 35728, 36689 }, + { 35730, 59047 }, + { 35731, 59048 }, + { 35734, 59049 }, + { 35737, 59050 }, + { 35738, 59051 }, + { 35895, 37450 }, + { 35898, 59052 }, + { 35903, 59054 }, + { 35905, 59053 }, + { 35910, 37796 }, + { 35912, 59055 }, + { 35914, 38476 }, + { 35916, 59056 }, + { 35918, 59057 }, + { 35920, 59058 }, + { 35925, 59059 }, + { 35930, 37848 }, + { 35937, 36827 }, + { 35938, 59060 }, + { 35946, 36235 }, + { 35947, 39084 }, + { 35948, 59061 }, + { 35960, 59062 }, + { 35961, 38238 }, + { 35962, 59063 }, + { 35964, 59071 }, + { 35970, 59064 }, + { 35973, 59066 }, + { 35977, 59065 }, + { 35978, 59067 }, + { 35980, 38501 }, + { 35981, 59068 }, + { 35982, 59069 }, + { 35988, 59070 }, + { 35992, 59072 }, + { 35997, 35404 }, + { 35998, 37605 }, + { 36000, 38281 }, + { 36001, 36320 }, + { 36002, 36214 }, + { 36007, 38254 }, + { 36008, 35293 }, + { 36009, 38092 }, + { 36010, 59075 }, + { 36011, 35537 }, + { 36012, 37075 }, + { 36013, 59074 }, + { 36014, 59079 }, + { 36015, 37529 }, + { 36016, 38625 }, + { 36018, 59077 }, + { 36019, 59078 }, + { 36020, 35661 }, + { 36022, 59080 }, + { 36023, 38019 }, + { 36024, 37341 }, + { 36027, 38127 }, + { 36028, 37724 }, + { 36029, 59076 }, + { 36031, 38502 }, + { 36032, 35306 }, + { 36033, 59082 }, + { 36034, 38983 }, + { 36035, 37568 }, + { 36036, 39012 }, + { 36039, 36497 }, + { 36040, 59081 }, + { 36042, 37295 }, + { 36045, 59098 }, + { 36046, 37191 }, + { 36049, 37878 }, + { 36051, 38255 }, + { 36058, 59085 }, + { 36059, 36446 }, + { 36060, 36498 }, + { 36062, 36828 }, + { 36064, 38021 }, + { 36066, 36011 }, + { 36067, 59084 }, + { 36068, 59083 }, + { 36070, 38282 }, + { 36074, 36543 }, + { 36077, 37745 }, + { 36080, 64429 }, + { 36084, 64430 }, + { 36090, 59087 }, + { 36091, 59088 }, + { 36092, 36215 }, + { 36093, 59086 }, + { 36100, 59089 }, + { 36101, 59090 }, + { 36103, 59092 }, + { 36104, 37281 }, + { 36106, 59091 }, + { 36107, 35556 }, + { 36109, 59094 }, + { 36111, 59093 }, + { 36112, 59095 }, + { 36114, 64431 }, + { 36115, 59097 }, + { 36116, 59099 }, + { 36118, 59100 }, + { 36196, 37076 }, + { 36198, 36557 }, + { 36199, 59101 }, + { 36203, 35441 }, + { 36205, 59102 }, + { 36208, 37270 }, + { 36209, 59103 }, + { 36211, 59104 }, + { 36212, 38283 }, + { 36214, 64432 }, + { 36215, 35662 }, + { 36225, 59105 }, + { 36229, 37556 }, + { 36234, 35194 }, + { 36249, 59106 }, + { 36259, 36591 }, + { 36264, 37014 }, + { 36275, 37291 }, + { 36282, 59109 }, + { 36286, 59108 }, + { 36290, 59107 }, + { 36299, 59115 }, + { 36300, 59113 }, + { 36303, 59110 }, + { 36310, 59112 }, + { 36314, 59111 }, + { 36315, 59114 }, + { 36317, 35735 }, + { 36319, 59118 }, + { 36321, 37077 }, + { 36323, 59119 }, + { 36328, 36055 }, + { 36330, 59116 }, + { 36331, 59117 }, + { 36335, 38984 }, + { 36339, 37557 }, + { 36341, 37192 }, + { 36348, 59120 }, + { 36351, 59123 }, + { 36360, 59121 }, + { 36361, 59122 }, + { 36362, 38776 }, + { 36367, 37797 }, + { 36368, 59126 }, + { 36381, 59124 }, + { 36382, 59125 }, + { 36383, 59127 }, + { 36394, 59208 }, + { 36400, 59130 }, + { 36404, 59131 }, + { 36405, 59129 }, + { 36418, 59128 }, + { 36420, 37627 }, + { 36423, 59200 }, + { 36424, 59204 }, + { 36425, 59201 }, + { 36426, 59132 }, + { 36428, 59202 }, + { 36432, 59203 }, + { 36437, 59210 }, + { 36441, 59205 }, + { 36447, 37078 }, + { 36448, 59207 }, + { 36451, 59209 }, + { 36452, 59206 }, + { 36466, 59212 }, + { 36468, 36690 }, + { 36470, 59211 }, + { 36476, 59213 }, + { 36481, 59214 }, + { 36484, 59217 }, + { 36485, 59216 }, + { 36487, 59215 }, + { 36490, 59219 }, + { 36491, 59218 }, + { 36493, 38644 }, + { 36497, 59221 }, + { 36499, 59220 }, + { 36500, 59222 }, + { 36505, 59223 }, + { 36513, 59225 }, + { 36522, 59224 }, + { 36523, 36967 }, + { 36524, 59226 }, + { 36527, 35819 }, + { 36528, 59227 }, + { 36529, 59229 }, + { 36542, 59230 }, + { 36549, 59231 }, + { 36550, 59228 }, + { 36552, 59232 }, + { 36554, 36564 }, + { 36555, 59233 }, + { 36556, 35663 }, + { 36557, 35922 }, + { 36559, 64434 }, + { 36562, 36012 }, + { 36571, 59234 }, + { 36575, 37870 }, + { 36578, 37725 }, + { 36579, 59235 }, + { 36587, 59238 }, + { 36600, 36530 }, + { 36603, 59237 }, + { 36604, 59236 }, + { 36605, 35961 }, + { 36606, 59239 }, + { 36611, 35442 }, + { 36613, 59241 }, + { 36617, 36314 }, + { 36618, 59240 }, + { 36620, 59249 }, + { 36626, 59243 }, + { 36627, 59245 }, + { 36628, 38371 }, + { 36629, 59242 }, + { 36633, 59244 }, + { 36635, 59248 }, + { 36636, 59246 }, + { 36637, 35664 }, + { 36639, 59247 }, + { 36646, 59250 }, + { 36649, 38009 }, + { 36650, 38870 }, + { 36655, 36691 }, + { 36659, 59251 }, + { 36664, 38721 }, + { 36665, 59253 }, + { 36667, 59252 }, + { 36670, 59256 }, + { 36671, 38752 }, + { 36674, 59255 }, + { 36676, 35469 }, + { 36677, 59254 }, + { 36678, 59259 }, + { 36681, 59258 }, + { 36684, 59257 }, + { 36685, 37713 }, + { 36686, 59260 }, + { 36695, 59261 }, + { 36700, 59262 }, + { 36703, 36236 }, + { 36705, 35908 }, + { 36706, 59264 }, + { 36707, 59265 }, + { 36708, 59266 }, + { 36763, 36968 }, + { 36764, 59267 }, + { 36766, 36523 }, + { 36767, 59268 }, + { 36771, 59269 }, + { 36775, 39327 }, + { 36776, 39326 }, + { 36781, 59270 }, + { 36782, 58256 }, + { 36783, 59271 }, + { 36784, 37443 }, + { 36785, 36938 }, + { 36786, 37983 }, + { 36791, 59272 }, + { 36794, 38355 }, + { 36795, 37586 }, + { 36796, 36254 }, + { 36799, 37448 }, + { 36802, 35145 }, + { 36804, 38552 }, + { 36805, 36982 }, + { 36814, 35965 }, + { 36817, 35807 }, + { 36820, 38356 }, + { 36826, 59273 }, + { 36834, 59275 }, + { 36837, 59274 }, + { 36838, 35294 }, + { 36841, 37876 }, + { 36842, 59276 }, + { 36843, 38039 }, + { 36845, 37714 }, + { 36847, 59277 }, + { 36848, 36721 }, + { 36852, 59279 }, + { 36855, 38592 }, + { 36856, 59294 }, + { 36857, 59281 }, + { 36858, 59282 }, + { 36861, 37575 }, + { 36864, 37342 }, + { 36865, 37271 }, + { 36867, 37798 }, + { 36869, 59280 }, + { 36870, 35700 }, + { 36875, 59289 }, + { 36877, 59286 }, + { 36878, 59299 }, + { 36879, 37799 }, + { 36880, 37504 }, + { 36881, 59283 }, + { 36883, 37628 }, + { 36884, 37746 }, + { 36885, 59284 }, + { 36886, 59288 }, + { 36887, 36992 }, + { 36889, 38023 }, + { 36890, 37578 }, + { 36893, 37056 }, + { 36894, 59287 }, + { 36895, 37292 }, + { 36896, 37282 }, + { 36897, 59285 }, + { 36898, 34983 }, + { 36899, 38977 }, + { 36903, 59290 }, + { 36910, 37343 }, + { 36913, 36692 }, + { 36914, 36969 }, + { 36917, 59292 }, + { 36918, 59291 }, + { 36920, 35053 }, + { 36921, 59293 }, + { 36924, 38222 }, + { 36926, 59301 }, + { 36929, 37849 }, + { 36930, 37003 }, + { 36933, 37496 }, + { 36935, 35830 }, + { 36937, 59300 }, + { 36938, 38742 }, + { 36939, 35166 }, + { 36941, 38357 }, + { 36942, 35295 }, + { 36943, 59295 }, + { 36944, 59296 }, + { 36945, 59297 }, + { 36946, 59298 }, + { 36947, 37817 }, + { 36948, 37442 }, + { 36949, 35041 }, + { 36950, 59302 }, + { 36952, 59303 }, + { 36953, 60065 }, + { 36956, 37307 }, + { 36958, 59304 }, + { 36960, 35219 }, + { 36961, 37227 }, + { 36963, 36013 }, + { 36965, 38777 }, + { 36967, 64437 }, + { 36968, 59305 }, + { 36969, 37707 }, + { 36973, 37272 }, + { 36974, 36565 }, + { 36975, 59306 }, + { 36978, 59309 }, + { 36981, 36741 }, + { 36982, 59307 }, + { 36983, 37194 }, + { 36984, 37193 }, + { 36986, 35042 }, + { 36988, 38857 }, + { 36989, 59311 }, + { 36991, 38128 }, + { 36992, 59313 }, + { 36993, 59312 }, + { 36994, 59310 }, + { 36995, 57988 }, + { 36996, 35538 }, + { 36999, 59278 }, + { 37001, 59315 }, + { 37002, 59314 }, + { 37007, 59316 }, + { 37009, 38743 }, + { 37027, 37855 }, + { 37030, 38477 }, + { 37032, 59317 }, + { 37034, 36567 }, + { 37039, 59318 }, + { 37041, 59319 }, + { 37045, 59320 }, + { 37048, 37696 }, + { 37057, 35048 }, + { 37066, 36216 }, + { 37070, 39001 }, + { 37083, 59324 }, + { 37086, 64438 }, + { 37089, 35923 }, + { 37090, 59321 }, + { 37092, 59322 }, + { 37096, 38292 }, + { 37101, 35443 }, + { 37109, 38744 }, + { 37111, 35773 }, + { 37117, 37747 }, + { 37122, 59325 }, + { 37138, 59326 }, + { 37141, 64440 }, + { 37145, 59327 }, + { 37159, 64441 }, + { 37165, 37697 }, + { 37168, 59329 }, + { 37170, 59328 }, + { 37193, 37841 }, + { 37194, 59330 }, + { 37195, 36693 }, + { 37196, 36574 }, + { 37197, 38010 }, + { 37198, 37521 }, + { 37202, 36592 }, + { 37204, 37004 }, + { 37206, 59331 }, + { 37208, 59332 }, + { 37218, 36988 }, + { 37219, 59333 }, + { 37221, 59334 }, + { 37225, 59335 }, + { 37226, 38799 }, + { 37228, 36694 }, + { 37234, 59337 }, + { 37235, 59336 }, + { 37237, 36217 }, + { 37239, 36243 }, + { 37240, 36447 }, + { 37250, 59340 }, + { 37255, 36742 }, + { 37257, 59339 }, + { 37259, 59338 }, + { 37261, 37351 }, + { 37264, 36077 }, + { 37266, 37057 }, + { 37271, 38062 }, + { 37276, 36696 }, + { 37282, 59341 }, + { 37284, 36829 }, + { 37290, 59344 }, + { 37291, 59342 }, + { 37295, 59343 }, + { 37300, 59346 }, + { 37301, 59345 }, + { 37304, 36856 }, + { 37306, 59347 }, + { 37312, 59348 }, + { 37313, 59349 }, + { 37318, 38094 }, + { 37319, 36305 }, + { 37320, 36575 }, + { 37321, 59350 }, + { 37323, 59351 }, + { 37324, 38818 }, + { 37325, 36708 }, + { 37326, 38636 }, + { 37327, 38858 }, + { 37328, 59352 }, + { 37329, 35808 }, + { 37334, 59353 }, + { 37335, 64443 }, + { 37336, 37698 }, + { 37338, 64442 }, + { 37339, 59356 }, + { 37340, 35480 }, + { 37341, 36970 }, + { 37342, 64444 }, + { 37343, 59354 }, + { 37345, 59355 }, + { 37347, 37598 }, + { 37348, 64447 }, + { 37349, 64448 }, + { 37350, 38516 }, + { 37351, 35834 }, + { 37357, 64445 }, + { 37358, 64446 }, + { 37365, 59358 }, + { 37366, 59359 }, + { 37372, 59357 }, + { 37375, 59361 }, + { 37382, 64449 }, + { 37386, 64451 }, + { 37389, 37853 }, + { 37390, 35426 }, + { 37392, 64450 }, + { 37393, 59365 }, + { 37396, 59362 }, + { 37397, 59364 }, + { 37406, 59360 }, + { 37417, 59502 }, + { 37420, 59363 }, + { 37428, 38889 }, + { 37431, 36056 }, + { 37433, 64458 }, + { 37434, 64452 }, + { 37436, 64454 }, + { 37439, 59373 }, + { 37440, 64453 }, + { 37444, 37715 }, + { 37445, 59368 }, + { 37448, 59371 }, + { 37449, 59369 }, + { 37451, 59374 }, + { 37454, 64455 }, + { 37456, 59375 }, + { 37457, 64457 }, + { 37463, 59367 }, + { 37465, 64456 }, + { 37466, 59380 }, + { 37467, 35220 }, + { 37470, 59366 }, + { 37474, 38059 }, + { 37476, 59370 }, + { 37478, 36830 }, + { 37479, 64459 }, + { 37489, 36218 }, + { 37495, 64461 }, + { 37496, 64462 }, + { 37502, 38503 }, + { 37504, 35810 }, + { 37507, 36709 }, + { 37509, 37818 }, + { 37512, 64095 }, + { 37521, 37196 }, + { 37523, 59378 }, + { 37525, 59372 }, + { 37526, 59377 }, + { 37528, 38593 }, + { 37530, 37558 }, + { 37531, 59379 }, + { 37532, 59376 }, + { 37543, 64460 }, + { 37549, 37195 }, + { 37559, 59383 }, + { 37561, 59382 }, + { 37583, 59381 }, + { 37584, 64466 }, + { 37586, 38478 }, + { 37587, 64470 }, + { 37589, 64468 }, + { 37591, 64464 }, + { 37593, 64465 }, + { 37600, 64469 }, + { 37604, 36763 }, + { 37607, 64463 }, + { 37609, 59384 }, + { 37610, 38365 }, + { 37613, 35187 }, + { 37618, 38245 }, + { 37619, 37522 }, + { 37624, 35736 }, + { 37625, 64101 }, + { 37626, 59386 }, + { 37627, 64473 }, + { 37628, 36220 }, + { 37631, 64476 }, + { 37634, 64478 }, + { 37638, 36427 }, + { 37647, 59385 }, + { 37648, 37005 }, + { 37656, 37006 }, + { 37657, 59456 }, + { 37658, 59458 }, + { 37661, 64477 }, + { 37662, 64475 }, + { 37664, 36857 }, + { 37665, 64472 }, + { 37666, 59457 }, + { 37667, 59459 }, + { 37669, 64471 }, + { 37670, 35793 }, + { 37672, 38244 }, + { 37675, 36576 }, + { 37676, 38978 }, + { 37678, 59388 }, + { 37679, 36342 }, + { 37682, 39006 }, + { 37685, 59461 }, + { 37690, 59460 }, + { 37691, 59462 }, + { 37700, 59387 }, + { 37704, 64094 }, + { 37707, 37863 }, + { 37709, 37748 }, + { 37716, 37589 }, + { 37718, 59467 }, + { 37719, 64480 }, + { 37723, 37474 }, + { 37724, 59463 }, + { 37728, 59464 }, + { 37740, 35916 }, + { 37742, 59466 }, + { 37744, 64479 }, + { 37749, 36014 }, + { 37756, 59465 }, + { 37758, 36831 }, + { 37772, 35481 }, + { 37780, 59471 }, + { 37782, 36285 }, + { 37783, 37273 }, + { 37786, 37576 }, + { 37796, 64481 }, + { 37799, 35418 }, + { 37804, 59469 }, + { 37805, 59470 }, + { 37806, 37569 }, + { 37808, 59468 }, + { 37817, 59472 }, + { 37827, 59478 }, + { 37830, 64482 }, + { 37832, 59481 }, + { 37840, 59480 }, + { 37841, 37708 }, + { 37846, 59473 }, + { 37847, 59474 }, + { 37848, 59477 }, + { 37853, 59479 }, + { 37854, 64483 }, + { 37857, 35774 }, + { 37860, 59482 }, + { 37861, 59476 }, + { 37864, 59475 }, + { 37880, 64484 }, + { 37891, 59486 }, + { 37895, 59487 }, + { 37904, 59488 }, + { 37907, 59485 }, + { 37908, 59484 }, + { 37912, 36832 }, + { 37913, 37800 }, + { 37914, 59483 }, + { 37921, 59492 }, + { 37931, 59490 }, + { 37937, 64485 }, + { 37941, 59491 }, + { 37942, 59489 }, + { 37944, 37366 }, + { 37946, 59493 }, + { 37953, 59494 }, + { 37956, 59496 }, + { 37957, 64486 }, + { 37960, 64487 }, + { 37969, 35539 }, + { 37970, 59495 }, + { 37971, 38648 }, + { 37978, 59507 }, + { 37979, 59497 }, + { 37982, 59500 }, + { 37984, 59498 }, + { 37986, 59499 }, + { 37994, 59501 }, + { 38000, 59503 }, + { 38005, 59504 }, + { 38007, 59505 }, + { 38012, 59508 }, + { 38013, 59506 }, + { 38014, 59509 }, + { 38015, 59511 }, + { 38017, 59510 }, + { 38263, 37559 }, + { 38272, 38629 }, + { 38274, 59512 }, + { 38275, 37197 }, + { 38279, 59513 }, + { 38281, 38338 }, + { 38282, 59514 }, + { 38283, 35402 }, + { 38287, 35163 }, + { 38289, 35541 }, + { 38290, 64488 }, + { 38291, 35540 }, + { 38292, 59515 }, + { 38294, 59516 }, + { 38296, 59517 }, + { 38297, 59518 }, + { 38304, 59520 }, + { 38306, 35542 }, + { 38307, 35444 }, + { 38308, 36221 }, + { 38309, 38068 }, + { 38311, 59522 }, + { 38312, 59521 }, + { 38317, 59523 }, + { 38322, 35195 }, + { 38329, 59526 }, + { 38331, 59525 }, + { 38332, 59524 }, + { 38334, 59527 }, + { 38339, 59530 }, + { 38343, 35013 }, + { 38346, 59528 }, + { 38348, 59532 }, + { 38349, 59531 }, + { 38356, 59534 }, + { 38357, 59533 }, + { 38358, 59535 }, + { 38360, 37804 }, + { 38364, 59536 }, + { 38369, 59537 }, + { 38370, 59539 }, + { 38373, 59538 }, + { 38428, 38284 }, + { 38433, 59540 }, + { 38440, 59541 }, + { 38442, 36323 }, + { 38446, 59542 }, + { 38447, 59543 }, + { 38450, 38504 }, + { 38459, 37226 }, + { 38463, 34978 }, + { 38464, 37321 }, + { 38466, 59544 }, + { 38468, 38285 }, + { 38475, 59547 }, + { 38476, 59545 }, + { 38477, 36222 }, + { 38479, 59546 }, + { 38480, 36032 }, + { 38491, 38339 }, + { 38492, 59549 }, + { 38493, 59551 }, + { 38494, 59550 }, + { 38495, 59552 }, + { 38498, 35136 }, + { 38499, 36983 }, + { 38500, 36764 }, + { 38501, 35543 }, + { 38502, 59553 }, + { 38506, 38022 }, + { 38508, 59555 }, + { 38512, 35137 }, + { 38514, 59554 }, + { 38515, 37570 }, + { 38517, 38859 }, + { 38518, 37801 }, + { 38519, 59548 }, + { 38520, 38820 }, + { 38522, 36015 }, + { 38525, 38778 }, + { 38533, 35831 }, + { 38534, 38834 }, + { 38536, 35911 }, + { 38538, 37344 }, + { 38539, 58432 }, + { 38541, 59556 }, + { 38542, 35403 }, + { 38543, 37007 }, + { 38548, 35445 }, + { 38549, 59558 }, + { 38551, 59559 }, + { 38552, 59557 }, + { 38553, 35972 }, + { 38555, 36315 }, + { 38556, 36833 }, + { 38557, 64491 }, + { 38560, 35138 }, + { 38563, 38871 }, + { 38567, 59561 }, + { 38568, 59308 }, + { 38570, 59560 }, + { 38575, 64492 }, + { 38576, 59564 }, + { 38577, 59562 }, + { 38578, 59563 }, + { 38580, 59565 }, + { 38582, 59566 }, + { 38583, 38890 }, + { 38584, 59567 }, + { 38585, 59568 }, + { 38587, 37063 }, + { 38588, 38073 }, + { 38592, 37021 }, + { 38593, 35557 }, + { 38596, 38745 }, + { 38597, 35307 }, + { 38598, 36695 }, + { 38599, 36057 }, + { 38601, 59571 }, + { 38603, 59570 }, + { 38604, 36499 }, + { 38605, 59572 }, + { 38606, 59569 }, + { 38609, 36423 }, + { 38613, 59576 }, + { 38614, 58795 }, + { 38617, 39380 }, + { 38619, 37015 }, + { 38620, 59574 }, + { 38626, 38819 }, + { 38627, 37871 }, + { 38632, 35146 }, + { 38634, 37089 }, + { 38635, 36532 }, + { 38640, 38325 }, + { 38642, 35167 }, + { 38646, 38891 }, + { 38647, 38795 }, + { 38649, 59577 }, + { 38651, 37732 }, + { 38656, 36601 }, + { 38660, 59578 }, + { 38662, 59579 }, + { 38663, 36971 }, + { 38664, 59580 }, + { 38666, 38892 }, + { 38669, 59575 }, + { 38670, 59582 }, + { 38671, 59584 }, + { 38673, 59583 }, + { 38675, 59581 }, + { 38678, 59585 }, + { 38681, 59586 }, + { 38684, 37274 }, + { 38686, 35296 }, + { 38692, 59587 }, + { 38695, 38582 }, + { 38698, 59588 }, + { 38704, 59589 }, + { 38706, 38985 }, + { 38707, 64493 }, + { 38712, 40528 }, + { 38713, 59590 }, + { 38715, 64494 }, + { 38717, 59591 }, + { 38718, 59592 }, + { 38722, 59596 }, + { 38723, 64495 }, + { 38724, 59593 }, + { 38726, 59594 }, + { 38728, 59595 }, + { 38729, 59597 }, + { 38733, 64496 }, + { 38735, 64497 }, + { 38737, 64498 }, + { 38738, 37058 }, + { 38741, 64499 }, + { 38742, 38645 }, + { 38745, 37059 }, + { 38748, 59598 }, + { 38750, 38129 }, + { 38752, 59599 }, + { 38753, 60018 }, + { 38754, 38602 }, + { 38756, 59600 }, + { 38758, 59601 }, + { 38760, 59602 }, + { 38761, 35446 }, + { 38763, 59604 }, + { 38765, 36984 }, + { 38769, 59605 }, + { 38772, 35907 }, + { 38777, 59606 }, + { 38778, 59610 }, + { 38780, 59608 }, + { 38785, 59609 }, + { 38788, 35475 }, + { 38789, 59607 }, + { 38790, 59611 }, + { 38795, 59612 }, + { 38797, 35014 }, + { 38799, 59613 }, + { 38800, 59614 }, + { 38808, 36834 }, + { 38812, 59615 }, + { 38816, 35686 }, + { 38819, 59618 }, + { 38822, 59617 }, + { 38824, 59616 }, + { 38827, 59025 }, + { 38829, 38362 }, + { 38835, 59619 }, + { 38836, 59620 }, + { 38851, 59621 }, + { 38854, 59622 }, + { 38856, 59623 }, + { 38859, 59624 }, + { 38867, 35544 }, + { 38876, 59625 }, + { 38893, 59626 }, + { 38894, 37954 }, + { 38898, 59628 }, + { 38899, 35257 }, + { 38901, 59631 }, + { 38902, 59630 }, + { 38907, 35139 }, + { 38911, 35775 }, + { 38913, 38341 }, + { 38914, 37560 }, + { 38915, 36256 }, + { 38917, 36224 }, + { 38918, 36743 }, + { 38920, 36987 }, + { 38924, 59633 }, + { 38927, 59632 }, + { 38928, 38753 }, + { 38929, 35558 }, + { 38930, 38096 }, + { 38931, 37850 }, + { 38935, 37020 }, + { 38936, 38860 }, + { 38938, 35962 }, + { 38945, 59636 }, + { 38948, 59635 }, + { 38956, 38506 }, + { 38957, 37802 }, + { 38964, 35183 }, + { 38967, 59637 }, + { 38968, 59634 }, + { 38971, 38256 }, + { 38972, 38794 }, + { 38973, 59638 }, + { 38982, 59639 }, + { 38987, 59641 }, + { 38988, 37352 }, + { 38989, 35450 }, + { 38990, 35451 }, + { 38991, 59640 }, + { 38996, 35559 }, + { 38997, 36016 }, + { 38999, 64500 }, + { 39000, 35560 }, + { 39003, 37726 }, + { 39006, 38878 }, + { 39013, 64501 }, + { 39015, 36058 }, + { 39019, 59642 }, + { 39023, 59643 }, + { 39024, 59644 }, + { 39025, 59712 }, + { 39027, 59714 }, + { 39028, 59713 }, + { 39080, 38295 }, + { 39082, 59715 }, + { 39087, 59716 }, + { 39089, 59717 }, + { 39094, 59718 }, + { 39107, 59720 }, + { 39108, 59719 }, + { 39110, 59721 }, + { 39131, 38130 }, + { 39132, 58314 }, + { 39135, 36936 }, + { 39138, 35665 }, + { 39145, 59722 }, + { 39147, 59723 }, + { 39149, 39338 }, + { 39150, 40794 }, + { 39151, 38097 }, + { 39154, 35065 }, + { 39156, 35001 }, + { 39164, 36500 }, + { 39165, 38479 }, + { 39166, 36860 }, + { 39171, 59724 }, + { 39173, 38621 }, + { 39177, 59725 }, + { 39178, 38779 }, + { 39180, 35169 }, + { 39184, 36448 }, + { 39186, 59726 }, + { 39187, 35308 }, + { 39188, 59727 }, + { 39192, 59728 }, + { 39197, 59730 }, + { 39198, 59731 }, + { 39200, 59733 }, + { 39201, 59729 }, + { 39204, 59732 }, + { 39207, 64504 }, + { 39208, 35545 }, + { 39212, 59734 }, + { 39214, 59735 }, + { 39229, 59736 }, + { 39230, 59737 }, + { 39234, 59738 }, + { 39237, 59740 }, + { 39241, 59739 }, + { 39243, 59742 }, + { 39244, 59745 }, + { 39248, 59741 }, + { 39249, 59743 }, + { 39250, 59744 }, + { 39253, 59746 }, + { 39255, 35776 }, + { 39318, 36593 }, + { 39319, 59747 }, + { 39320, 59748 }, + { 39321, 36225 }, + { 39326, 64506 }, + { 39333, 59749 }, + { 39336, 35421 }, + { 39340, 37998 }, + { 39341, 59750 }, + { 39342, 59751 }, + { 39347, 37497 }, + { 39348, 37865 }, + { 39356, 59752 }, + { 39361, 38045 }, + { 39364, 37322 }, + { 39365, 35191 }, + { 39366, 35820 }, + { 39368, 35821 }, + { 39376, 37523 }, + { 39377, 59757 }, + { 39378, 35822 }, + { 39381, 35309 }, + { 39384, 59756 }, + { 39387, 59754 }, + { 39389, 59755 }, + { 39391, 59753 }, + { 39394, 59767 }, + { 39405, 59758 }, + { 39406, 59759 }, + { 39409, 59760 }, + { 39410, 59761 }, + { 39416, 59763 }, + { 39419, 59762 }, + { 39423, 36728 }, + { 39425, 59764 }, + { 39429, 59766 }, + { 39438, 35666 }, + { 39439, 59765 }, + { 39442, 37275 }, + { 39443, 36017 }, + { 39449, 59768 }, + { 39464, 37323 }, + { 39467, 59769 }, + { 39472, 37803 }, + { 39479, 59770 }, + { 39486, 59776 }, + { 39488, 59773 }, + { 39490, 59772 }, + { 39491, 59774 }, + { 39493, 59771 }, + { 39501, 59778 }, + { 39502, 64507 }, + { 39509, 59777 }, + { 39511, 59780 }, + { 39514, 35777 }, + { 39515, 59779 }, + { 39519, 59781 }, + { 39522, 59782 }, + { 39524, 59784 }, + { 39525, 59783 }, + { 39529, 59785 }, + { 39530, 59787 }, + { 39531, 59786 }, + { 39592, 36252 }, + { 39597, 59788 }, + { 39600, 59789 }, + { 39608, 35419 }, + { 39612, 59790 }, + { 39616, 59791 }, + { 39620, 37009 }, + { 39631, 59792 }, + { 39633, 59793 }, + { 39635, 59794 }, + { 39636, 59795 }, + { 39640, 36226 }, + { 39641, 64508 }, + { 39644, 64576 }, + { 39646, 59796 }, + { 39647, 59797 }, + { 39650, 59798 }, + { 39651, 59799 }, + { 39654, 59800 }, + { 39658, 38063 }, + { 39659, 59802 }, + { 39661, 38213 }, + { 39662, 59803 }, + { 39663, 59801 }, + { 39665, 59805 }, + { 39668, 59804 }, + { 39671, 59806 }, + { 39675, 59807 }, + { 39686, 59808 }, + { 39704, 59809 }, + { 39706, 59810 }, + { 39711, 59811 }, + { 39714, 59812 }, + { 39715, 59813 }, + { 39717, 59814 }, + { 39719, 59815 }, + { 39720, 59816 }, + { 39721, 59817 }, + { 39722, 59818 }, + { 39726, 59819 }, + { 39727, 59820 }, + { 39729, 40788 }, + { 39730, 59821 }, + { 39739, 58102 }, + { 39740, 35667 }, + { 39745, 35392 }, + { 39746, 36272 }, + { 39747, 59823 }, + { 39748, 59822 }, + { 39749, 38563 }, + { 39757, 59825 }, + { 39758, 59826 }, + { 39759, 59824 }, + { 39761, 59827 }, + { 39764, 38530 }, + { 39768, 59828 }, + { 39770, 35739 }, + { 39791, 38980 }, + { 39794, 64578 }, + { 39796, 59829 }, + { 39797, 64577 }, + { 39811, 59831 }, + { 39822, 35004 }, + { 39823, 64579 }, + { 39825, 59832 }, + { 39826, 38313 }, + { 39827, 59830 }, + { 39830, 59833 }, + { 39831, 59834 }, + { 39839, 59835 }, + { 39840, 59836 }, + { 39848, 59837 }, + { 39850, 38542 }, + { 39851, 36428 }, + { 39853, 36344 }, + { 39854, 37198 }, + { 39857, 64580 }, + { 39860, 59838 }, + { 39865, 59841 }, + { 39867, 64581 }, + { 39872, 59839 }, + { 39878, 59842 }, + { 39881, 36079 }, + { 39882, 59840 }, + { 39887, 59843 }, + { 39889, 59844 }, + { 39890, 59845 }, + { 39892, 59849 }, + { 39894, 36425 }, + { 39899, 37346 }, + { 39905, 59850 }, + { 39906, 59847 }, + { 39907, 59846 }, + { 39908, 59848 }, + { 39912, 35966 }, + { 39920, 59854 }, + { 39921, 59853 }, + { 39922, 59852 }, + { 39925, 34993 }, + { 39936, 64582 }, + { 39940, 59864 }, + { 39942, 59860 }, + { 39944, 59861 }, + { 39945, 59857 }, + { 39946, 59863 }, + { 39948, 59859 }, + { 39949, 35458 }, + { 39952, 39019 }, + { 39954, 59862 }, + { 39955, 59858 }, + { 39956, 59856 }, + { 39957, 59855 }, + { 39963, 59866 }, + { 39969, 59869 }, + { 39972, 59868 }, + { 39973, 59867 }, + { 39981, 38248 }, + { 39982, 59865 }, + { 39983, 35057 }, + { 39984, 59870 }, + { 39986, 59872 }, + { 39993, 35471 }, + { 39994, 59851 }, + { 39995, 35158 }, + { 39998, 59874 }, + { 40006, 59873 }, + { 40007, 59871 }, + { 40008, 37452 }, + { 40018, 38544 }, + { 40023, 38872 }, + { 40026, 59875 }, + { 40032, 59876 }, + { 40039, 59877 }, + { 40054, 59878 }, + { 40056, 59879 }, + { 40165, 37561 }, + { 40167, 59880 }, + { 40169, 38069 }, + { 40171, 59885 }, + { 40172, 59881 }, + { 40176, 59882 }, + { 40179, 38480 }, + { 40180, 38594 }, + { 40182, 37838 }, + { 40195, 59886 }, + { 40198, 59887 }, + { 40199, 37820 }, + { 40200, 59884 }, + { 40201, 59883 }, + { 40206, 35240 }, + { 40210, 59895 }, + { 40213, 59894 }, + { 40219, 35221 }, + { 40223, 59892 }, + { 40227, 59891 }, + { 40230, 59889 }, + { 40232, 35483 }, + { 40234, 59888 }, + { 40235, 36528 }, + { 40236, 35239 }, + { 40251, 36227 }, + { 40254, 59898 }, + { 40255, 59897 }, + { 40257, 59896 }, + { 40260, 59893 }, + { 40262, 59899 }, + { 40264, 59900 }, + { 40272, 59972 }, + { 40273, 59971 }, + { 40281, 59973 }, + { 40284, 35148 }, + { 40285, 59968 }, + { 40286, 59969 }, + { 40288, 36244 }, + { 40289, 38583 }, + { 40292, 59970 }, + { 40299, 64584 }, + { 40300, 38481 }, + { 40303, 59978 }, + { 40304, 64583 }, + { 40306, 59974 }, + { 40314, 59979 }, + { 40327, 59976 }, + { 40329, 59975 }, + { 40335, 35963 }, + { 40346, 59980 }, + { 40356, 59981 }, + { 40361, 59982 }, + { 40363, 59977 }, + { 40367, 59890 }, + { 40370, 59983 }, + { 40372, 37599 }, + { 40376, 59987 }, + { 40378, 59988 }, + { 40379, 59986 }, + { 40385, 59985 }, + { 40386, 59991 }, + { 40388, 59984 }, + { 40390, 59989 }, + { 40399, 59990 }, + { 40403, 59993 }, + { 40409, 59992 }, + { 40422, 59995 }, + { 40429, 59996 }, + { 40431, 59997 }, + { 40434, 39016 }, + { 40440, 59994 }, + { 40441, 37353 }, + { 40442, 36331 }, + { 40445, 59998 }, + { 40473, 64586 }, + { 40474, 59999 }, + { 40475, 60000 }, + { 40478, 60001 }, + { 40565, 60002 }, + { 40568, 36018 }, + { 40569, 60003 }, + { 40573, 60004 }, + { 40575, 36525 }, + { 40577, 60005 }, + { 40584, 60006 }, + { 40587, 60007 }, + { 40588, 60008 }, + { 40593, 60011 }, + { 40594, 60009 }, + { 40595, 39003 }, + { 40597, 60010 }, + { 40599, 38893 }, + { 40605, 60012 }, + { 40607, 38873 }, + { 40613, 60013 }, + { 40614, 38046 }, + { 40617, 60014 }, + { 40618, 60016 }, + { 40621, 60017 }, + { 40632, 60015 }, + { 40633, 36237 }, + { 40634, 38603 }, + { 40635, 38531 }, + { 40636, 39925 }, + { 40638, 40832 }, + { 40639, 38555 }, + { 40644, 35241 }, + { 40652, 60019 }, + { 40653, 35695 }, + { 40654, 60020 }, + { 40655, 60021 }, + { 40656, 60022 }, + { 40657, 64587 }, + { 40658, 36245 }, + { 40660, 60023 }, + { 40664, 57554 }, + { 40665, 38617 }, + { 40667, 37345 }, + { 40668, 60024 }, + { 40669, 60026 }, + { 40670, 60025 }, + { 40672, 60027 }, + { 40677, 60028 }, + { 40680, 60029 }, + { 40687, 60030 }, + { 40692, 60032 }, + { 40694, 60033 }, + { 40695, 60034 }, + { 40697, 60035 }, + { 40699, 60036 }, + { 40700, 60037 }, + { 40701, 60038 }, + { 40711, 60039 }, + { 40712, 60040 }, + { 40718, 37699 }, + { 40723, 36059 }, + { 40725, 60042 }, + { 40736, 37228 }, + { 40737, 60043 }, + { 40748, 60044 }, + { 40763, 38208 }, + { 40766, 60045 }, + { 40778, 60046 }, + { 40779, 57942 }, + { 40782, 59096 }, + { 40783, 59627 }, + { 40786, 60047 }, + { 40788, 60048 }, + { 40799, 60050 }, + { 40800, 60051 }, + { 40801, 60052 }, + { 40802, 38894 }, + { 40803, 60049 }, + { 40806, 60053 }, + { 40807, 60054 }, + { 40810, 60056 }, + { 40812, 60055 }, + { 40818, 60058 }, + { 40822, 60059 }, + { 40823, 60057 }, + { 40845, 38836 }, + { 40853, 60060 }, + { 40860, 60061 }, + { 40861, 57971 }, + { 40864, 60062 }, + { 57344, 61504 }, + { 57345, 61505 }, + { 57346, 61506 }, + { 57347, 61507 }, + { 57348, 61508 }, + { 57349, 61509 }, + { 57350, 61510 }, + { 57351, 61511 }, + { 57352, 61512 }, + { 57353, 61513 }, + { 57354, 61514 }, + { 57355, 61515 }, + { 57356, 61516 }, + { 57357, 61517 }, + { 57358, 61518 }, + { 57359, 61519 }, + { 57360, 61520 }, + { 57361, 61521 }, + { 57362, 61522 }, + { 57363, 61523 }, + { 57364, 61524 }, + { 57365, 61525 }, + { 57366, 61526 }, + { 57367, 61527 }, + { 57368, 61528 }, + { 57369, 61529 }, + { 57370, 61530 }, + { 57371, 61531 }, + { 57372, 61532 }, + { 57373, 61533 }, + { 57374, 61534 }, + { 57375, 61535 }, + { 57376, 61536 }, + { 57377, 61537 }, + { 57378, 61538 }, + { 57379, 61539 }, + { 57380, 61540 }, + { 57381, 61541 }, + { 57382, 61542 }, + { 57383, 61543 }, + { 57384, 61544 }, + { 57385, 61545 }, + { 57386, 61546 }, + { 57387, 61547 }, + { 57388, 61548 }, + { 57389, 61549 }, + { 57390, 61550 }, + { 57391, 61551 }, + { 57392, 61552 }, + { 57393, 61553 }, + { 57394, 61554 }, + { 57395, 61555 }, + { 57396, 61556 }, + { 57397, 61557 }, + { 57398, 61558 }, + { 57399, 61559 }, + { 57400, 61560 }, + { 57401, 61561 }, + { 57402, 61562 }, + { 57403, 61563 }, + { 57404, 61564 }, + { 57405, 61565 }, + { 57406, 61566 }, + { 57407, 61568 }, + { 57408, 61569 }, + { 57409, 61570 }, + { 57410, 61571 }, + { 57411, 61572 }, + { 57412, 61573 }, + { 57413, 61574 }, + { 57414, 61575 }, + { 57415, 61576 }, + { 57416, 61577 }, + { 57417, 61578 }, + { 57418, 61579 }, + { 57419, 61580 }, + { 57420, 61581 }, + { 57421, 61582 }, + { 57422, 61583 }, + { 57423, 61584 }, + { 57424, 61585 }, + { 57425, 61586 }, + { 57426, 61587 }, + { 57427, 61588 }, + { 57428, 61589 }, + { 57429, 61590 }, + { 57430, 61591 }, + { 57431, 61592 }, + { 57432, 61593 }, + { 57433, 61594 }, + { 57434, 61595 }, + { 57435, 61596 }, + { 57436, 61597 }, + { 57437, 61598 }, + { 57438, 61599 }, + { 57439, 61600 }, + { 57440, 61601 }, + { 57441, 61602 }, + { 57442, 61603 }, + { 57443, 61604 }, + { 57444, 61605 }, + { 57445, 61606 }, + { 57446, 61607 }, + { 57447, 61608 }, + { 57448, 61609 }, + { 57449, 61610 }, + { 57450, 61611 }, + { 57451, 61612 }, + { 57452, 61613 }, + { 57453, 61614 }, + { 57454, 61615 }, + { 57455, 61616 }, + { 57456, 61617 }, + { 57457, 61618 }, + { 57458, 61619 }, + { 57459, 61620 }, + { 57460, 61621 }, + { 57461, 61622 }, + { 57462, 61623 }, + { 57463, 61624 }, + { 57464, 61625 }, + { 57465, 61626 }, + { 57466, 61627 }, + { 57467, 61628 }, + { 57468, 61629 }, + { 57469, 61630 }, + { 57470, 61631 }, + { 57471, 61632 }, + { 57472, 61633 }, + { 57473, 61634 }, + { 57474, 61635 }, + { 57475, 61636 }, + { 57476, 61637 }, + { 57477, 61638 }, + { 57478, 61639 }, + { 57479, 61640 }, + { 57480, 61641 }, + { 57481, 61642 }, + { 57482, 61643 }, + { 57483, 61644 }, + { 57484, 61645 }, + { 57485, 61646 }, + { 57486, 61647 }, + { 57487, 61648 }, + { 57488, 61649 }, + { 57489, 61650 }, + { 57490, 61651 }, + { 57491, 61652 }, + { 57492, 61653 }, + { 57493, 61654 }, + { 57494, 61655 }, + { 57495, 61656 }, + { 57496, 61657 }, + { 57497, 61658 }, + { 57498, 61659 }, + { 57499, 61660 }, + { 57500, 61661 }, + { 57501, 61662 }, + { 57502, 61663 }, + { 57503, 61664 }, + { 57504, 61665 }, + { 57505, 61666 }, + { 57506, 61667 }, + { 57507, 61668 }, + { 57508, 61669 }, + { 57509, 61670 }, + { 57510, 61671 }, + { 57511, 61672 }, + { 57512, 61673 }, + { 57513, 61674 }, + { 57514, 61675 }, + { 57515, 61676 }, + { 57516, 61677 }, + { 57517, 61678 }, + { 57518, 61679 }, + { 57519, 61680 }, + { 57520, 61681 }, + { 57521, 61682 }, + { 57522, 61683 }, + { 57523, 61684 }, + { 57524, 61685 }, + { 57525, 61686 }, + { 57526, 61687 }, + { 57527, 61688 }, + { 57528, 61689 }, + { 57529, 61690 }, + { 57530, 61691 }, + { 57531, 61692 }, + { 57532, 61760 }, + { 57533, 61761 }, + { 57534, 61762 }, + { 57535, 61763 }, + { 57536, 61764 }, + { 57537, 61765 }, + { 57538, 61766 }, + { 57539, 61767 }, + { 57540, 61768 }, + { 57541, 61769 }, + { 57542, 61770 }, + { 57543, 61771 }, + { 57544, 61772 }, + { 57545, 61773 }, + { 57546, 61774 }, + { 57547, 61775 }, + { 57548, 61776 }, + { 57549, 61777 }, + { 57550, 61778 }, + { 57551, 61779 }, + { 57552, 61780 }, + { 57553, 61781 }, + { 57554, 61782 }, + { 57555, 61783 }, + { 57556, 61784 }, + { 57557, 61785 }, + { 57558, 61786 }, + { 57559, 61787 }, + { 57560, 61788 }, + { 57561, 61789 }, + { 57562, 61790 }, + { 57563, 61791 }, + { 57564, 61792 }, + { 57565, 61793 }, + { 57566, 61794 }, + { 57567, 61795 }, + { 57568, 61796 }, + { 57569, 61797 }, + { 57570, 61798 }, + { 57571, 61799 }, + { 57572, 61800 }, + { 57573, 61801 }, + { 57574, 61802 }, + { 57575, 61803 }, + { 57576, 61804 }, + { 57577, 61805 }, + { 57578, 61806 }, + { 57579, 61807 }, + { 57580, 61808 }, + { 57581, 61809 }, + { 57582, 61810 }, + { 57583, 61811 }, + { 57584, 61812 }, + { 57585, 61813 }, + { 57586, 61814 }, + { 57587, 61815 }, + { 57588, 61816 }, + { 57589, 61817 }, + { 57590, 61818 }, + { 57591, 61819 }, + { 57592, 61820 }, + { 57593, 61821 }, + { 57594, 61822 }, + { 57595, 61824 }, + { 57596, 61825 }, + { 57597, 61826 }, + { 57598, 61827 }, + { 57599, 61828 }, + { 57600, 61829 }, + { 57601, 61830 }, + { 57602, 61831 }, + { 57603, 61832 }, + { 57604, 61833 }, + { 57605, 61834 }, + { 57606, 61835 }, + { 57607, 61836 }, + { 57608, 61837 }, + { 57609, 61838 }, + { 57610, 61839 }, + { 57611, 61840 }, + { 57612, 61841 }, + { 57613, 61842 }, + { 57614, 61843 }, + { 57615, 61844 }, + { 57616, 61845 }, + { 57617, 61846 }, + { 57618, 61847 }, + { 57619, 61848 }, + { 57620, 61849 }, + { 57621, 61850 }, + { 57622, 61851 }, + { 57623, 61852 }, + { 57624, 61853 }, + { 57625, 61854 }, + { 57626, 61855 }, + { 57627, 61856 }, + { 57628, 61857 }, + { 57629, 61858 }, + { 57630, 61859 }, + { 57631, 61860 }, + { 57632, 61861 }, + { 57633, 61862 }, + { 57634, 61863 }, + { 57635, 61864 }, + { 57636, 61865 }, + { 57637, 61866 }, + { 57638, 61867 }, + { 57639, 61868 }, + { 57640, 61869 }, + { 57641, 61870 }, + { 57642, 61871 }, + { 57643, 61872 }, + { 57644, 61873 }, + { 57645, 61874 }, + { 57646, 61875 }, + { 57647, 61876 }, + { 57648, 61877 }, + { 57649, 61878 }, + { 57650, 61879 }, + { 57651, 61880 }, + { 57652, 61881 }, + { 57653, 61882 }, + { 57654, 61883 }, + { 57655, 61884 }, + { 57656, 61885 }, + { 57657, 61886 }, + { 57658, 61887 }, + { 57659, 61888 }, + { 57660, 61889 }, + { 57661, 61890 }, + { 57662, 61891 }, + { 57663, 61892 }, + { 57664, 61893 }, + { 57665, 61894 }, + { 57666, 61895 }, + { 57667, 61896 }, + { 57668, 61897 }, + { 57669, 61898 }, + { 57670, 61899 }, + { 57671, 61900 }, + { 57672, 61901 }, + { 57673, 61902 }, + { 57674, 61903 }, + { 57675, 61904 }, + { 57676, 61905 }, + { 57677, 61906 }, + { 57678, 61907 }, + { 57679, 61908 }, + { 57680, 61909 }, + { 57681, 61910 }, + { 57682, 61911 }, + { 57683, 61912 }, + { 57684, 61913 }, + { 57685, 61914 }, + { 57686, 61915 }, + { 57687, 61916 }, + { 57688, 61917 }, + { 57689, 61918 }, + { 57690, 61919 }, + { 57691, 61920 }, + { 57692, 61921 }, + { 57693, 61922 }, + { 57694, 61923 }, + { 57695, 61924 }, + { 57696, 61925 }, + { 57697, 61926 }, + { 57698, 61927 }, + { 57699, 61928 }, + { 57700, 61929 }, + { 57701, 61930 }, + { 57702, 61931 }, + { 57703, 61932 }, + { 57704, 61933 }, + { 57705, 61934 }, + { 57706, 61935 }, + { 57707, 61936 }, + { 57708, 61937 }, + { 57709, 61938 }, + { 57710, 61939 }, + { 57711, 61940 }, + { 57712, 61941 }, + { 57713, 61942 }, + { 57714, 61943 }, + { 57715, 61944 }, + { 57716, 61945 }, + { 57717, 61946 }, + { 57718, 61947 }, + { 57719, 61948 }, + { 57720, 62016 }, + { 57721, 62017 }, + { 57722, 62018 }, + { 57723, 62019 }, + { 57724, 62020 }, + { 57725, 62021 }, + { 57726, 62022 }, + { 57727, 62023 }, + { 57728, 62024 }, + { 57729, 62025 }, + { 57730, 62026 }, + { 57731, 62027 }, + { 57732, 62028 }, + { 57733, 62029 }, + { 57734, 62030 }, + { 57735, 62031 }, + { 57736, 62032 }, + { 57737, 62033 }, + { 57738, 62034 }, + { 57739, 62035 }, + { 57740, 62036 }, + { 57741, 62037 }, + { 57742, 62038 }, + { 57743, 62039 }, + { 57744, 62040 }, + { 57745, 62041 }, + { 57746, 62042 }, + { 57747, 62043 }, + { 57748, 62044 }, + { 57749, 62045 }, + { 57750, 62046 }, + { 57751, 62047 }, + { 57752, 62048 }, + { 57753, 62049 }, + { 57754, 62050 }, + { 57755, 62051 }, + { 57756, 62052 }, + { 57757, 62053 }, + { 57758, 62054 }, + { 57759, 62055 }, + { 57760, 62056 }, + { 57761, 62057 }, + { 57762, 62058 }, + { 57763, 62059 }, + { 57764, 62060 }, + { 57765, 62061 }, + { 57766, 62062 }, + { 57767, 62063 }, + { 57768, 62064 }, + { 57769, 62065 }, + { 57770, 62066 }, + { 57771, 62067 }, + { 57772, 62068 }, + { 57773, 62069 }, + { 57774, 62070 }, + { 57775, 62071 }, + { 57776, 62072 }, + { 57777, 62073 }, + { 57778, 62074 }, + { 57779, 62075 }, + { 57780, 62076 }, + { 57781, 62077 }, + { 57782, 62078 }, + { 57783, 62080 }, + { 57784, 62081 }, + { 57785, 62082 }, + { 57786, 62083 }, + { 57787, 62084 }, + { 57788, 62085 }, + { 57789, 62086 }, + { 57790, 62087 }, + { 57791, 62088 }, + { 57792, 62089 }, + { 57793, 62090 }, + { 57794, 62091 }, + { 57795, 62092 }, + { 57796, 62093 }, + { 57797, 62094 }, + { 57798, 62095 }, + { 57799, 62096 }, + { 57800, 62097 }, + { 57801, 62098 }, + { 57802, 62099 }, + { 57803, 62100 }, + { 57804, 62101 }, + { 57805, 62102 }, + { 57806, 62103 }, + { 57807, 62104 }, + { 57808, 62105 }, + { 57809, 62106 }, + { 57810, 62107 }, + { 57811, 62108 }, + { 57812, 62109 }, + { 57813, 62110 }, + { 57814, 62111 }, + { 57815, 62112 }, + { 57816, 62113 }, + { 57817, 62114 }, + { 57818, 62115 }, + { 57819, 62116 }, + { 57820, 62117 }, + { 57821, 62118 }, + { 57822, 62119 }, + { 57823, 62120 }, + { 57824, 62121 }, + { 57825, 62122 }, + { 57826, 62123 }, + { 57827, 62124 }, + { 57828, 62125 }, + { 57829, 62126 }, + { 57830, 62127 }, + { 57831, 62128 }, + { 57832, 62129 }, + { 57833, 62130 }, + { 57834, 62131 }, + { 57835, 62132 }, + { 57836, 62133 }, + { 57837, 62134 }, + { 57838, 62135 }, + { 57839, 62136 }, + { 57840, 62137 }, + { 57841, 62138 }, + { 57842, 62139 }, + { 57843, 62140 }, + { 57844, 62141 }, + { 57845, 62142 }, + { 57846, 62143 }, + { 57847, 62144 }, + { 57848, 62145 }, + { 57849, 62146 }, + { 57850, 62147 }, + { 57851, 62148 }, + { 57852, 62149 }, + { 57853, 62150 }, + { 57854, 62151 }, + { 57855, 62152 }, + { 57856, 62153 }, + { 57857, 62154 }, + { 57858, 62155 }, + { 57859, 62156 }, + { 57860, 62157 }, + { 57861, 62158 }, + { 57862, 62159 }, + { 57863, 62160 }, + { 57864, 62161 }, + { 57865, 62162 }, + { 57866, 62163 }, + { 57867, 62164 }, + { 57868, 62165 }, + { 57869, 62166 }, + { 57870, 62167 }, + { 57871, 62168 }, + { 57872, 62169 }, + { 57873, 62170 }, + { 57874, 62171 }, + { 57875, 62172 }, + { 57876, 62173 }, + { 57877, 62174 }, + { 57878, 62175 }, + { 57879, 62176 }, + { 57880, 62177 }, + { 57881, 62178 }, + { 57882, 62179 }, + { 57883, 62180 }, + { 57884, 62181 }, + { 57885, 62182 }, + { 57886, 62183 }, + { 57887, 62184 }, + { 57888, 62185 }, + { 57889, 62186 }, + { 57890, 62187 }, + { 57891, 62188 }, + { 57892, 62189 }, + { 57893, 62190 }, + { 57894, 62191 }, + { 57895, 62192 }, + { 57896, 62193 }, + { 57897, 62194 }, + { 57898, 62195 }, + { 57899, 62196 }, + { 57900, 62197 }, + { 57901, 62198 }, + { 57902, 62199 }, + { 57903, 62200 }, + { 57904, 62201 }, + { 57905, 62202 }, + { 57906, 62203 }, + { 57907, 62204 }, + { 57908, 62272 }, + { 57909, 62273 }, + { 57910, 62274 }, + { 57911, 62275 }, + { 57912, 62276 }, + { 57913, 62277 }, + { 57914, 62278 }, + { 57915, 62279 }, + { 57916, 62280 }, + { 57917, 62281 }, + { 57918, 62282 }, + { 57919, 62283 }, + { 57920, 62284 }, + { 57921, 62285 }, + { 57922, 62286 }, + { 57923, 62287 }, + { 57924, 62288 }, + { 57925, 62289 }, + { 57926, 62290 }, + { 57927, 62291 }, + { 57928, 62292 }, + { 57929, 62293 }, + { 57930, 62294 }, + { 57931, 62295 }, + { 57932, 62296 }, + { 57933, 62297 }, + { 57934, 62298 }, + { 57935, 62299 }, + { 57936, 62300 }, + { 57937, 62301 }, + { 57938, 62302 }, + { 57939, 62303 }, + { 57940, 62304 }, + { 57941, 62305 }, + { 57942, 62306 }, + { 57943, 62307 }, + { 57944, 62308 }, + { 57945, 62309 }, + { 57946, 62310 }, + { 57947, 62311 }, + { 57948, 62312 }, + { 57949, 62313 }, + { 57950, 62314 }, + { 57951, 62315 }, + { 57952, 62316 }, + { 57953, 62317 }, + { 57954, 62318 }, + { 57955, 62319 }, + { 57956, 62320 }, + { 57957, 62321 }, + { 57958, 62322 }, + { 57959, 62323 }, + { 57960, 62324 }, + { 57961, 62325 }, + { 57962, 62326 }, + { 57963, 62327 }, + { 57964, 62328 }, + { 57965, 62329 }, + { 57966, 62330 }, + { 57967, 62331 }, + { 57968, 62332 }, + { 57969, 62333 }, + { 57970, 62334 }, + { 57971, 62336 }, + { 57972, 62337 }, + { 57973, 62338 }, + { 57974, 62339 }, + { 57975, 62340 }, + { 57976, 62341 }, + { 57977, 62342 }, + { 57978, 62343 }, + { 57979, 62344 }, + { 57980, 62345 }, + { 57981, 62346 }, + { 57982, 62347 }, + { 57983, 62348 }, + { 57984, 62349 }, + { 57985, 62350 }, + { 57986, 62351 }, + { 57987, 62352 }, + { 57988, 62353 }, + { 57989, 62354 }, + { 57990, 62355 }, + { 57991, 62356 }, + { 57992, 62357 }, + { 57993, 62358 }, + { 57994, 62359 }, + { 57995, 62360 }, + { 57996, 62361 }, + { 57997, 62362 }, + { 57998, 62363 }, + { 57999, 62364 }, + { 58000, 62365 }, + { 58001, 62366 }, + { 58002, 62367 }, + { 58003, 62368 }, + { 58004, 62369 }, + { 58005, 62370 }, + { 58006, 62371 }, + { 58007, 62372 }, + { 58008, 62373 }, + { 58009, 62374 }, + { 58010, 62375 }, + { 58011, 62376 }, + { 58012, 62377 }, + { 58013, 62378 }, + { 58014, 62379 }, + { 58015, 62380 }, + { 58016, 62381 }, + { 58017, 62382 }, + { 58018, 62383 }, + { 58019, 62384 }, + { 58020, 62385 }, + { 58021, 62386 }, + { 58022, 62387 }, + { 58023, 62388 }, + { 58024, 62389 }, + { 58025, 62390 }, + { 58026, 62391 }, + { 58027, 62392 }, + { 58028, 62393 }, + { 58029, 62394 }, + { 58030, 62395 }, + { 58031, 62396 }, + { 58032, 62397 }, + { 58033, 62398 }, + { 58034, 62399 }, + { 58035, 62400 }, + { 58036, 62401 }, + { 58037, 62402 }, + { 58038, 62403 }, + { 58039, 62404 }, + { 58040, 62405 }, + { 58041, 62406 }, + { 58042, 62407 }, + { 58043, 62408 }, + { 58044, 62409 }, + { 58045, 62410 }, + { 58046, 62411 }, + { 58047, 62412 }, + { 58048, 62413 }, + { 58049, 62414 }, + { 58050, 62415 }, + { 58051, 62416 }, + { 58052, 62417 }, + { 58053, 62418 }, + { 58054, 62419 }, + { 58055, 62420 }, + { 58056, 62421 }, + { 58057, 62422 }, + { 58058, 62423 }, + { 58059, 62424 }, + { 58060, 62425 }, + { 58061, 62426 }, + { 58062, 62427 }, + { 58063, 62428 }, + { 58064, 62429 }, + { 58065, 62430 }, + { 58066, 62431 }, + { 58067, 62432 }, + { 58068, 62433 }, + { 58069, 62434 }, + { 58070, 62435 }, + { 58071, 62436 }, + { 58072, 62437 }, + { 58073, 62438 }, + { 58074, 62439 }, + { 58075, 62440 }, + { 58076, 62441 }, + { 58077, 62442 }, + { 58078, 62443 }, + { 58079, 62444 }, + { 58080, 62445 }, + { 58081, 62446 }, + { 58082, 62447 }, + { 58083, 62448 }, + { 58084, 62449 }, + { 58085, 62450 }, + { 58086, 62451 }, + { 58087, 62452 }, + { 58088, 62453 }, + { 58089, 62454 }, + { 58090, 62455 }, + { 58091, 62456 }, + { 58092, 62457 }, + { 58093, 62458 }, + { 58094, 62459 }, + { 58095, 62460 }, + { 58096, 62528 }, + { 58097, 62529 }, + { 58098, 62530 }, + { 58099, 62531 }, + { 58100, 62532 }, + { 58101, 62533 }, + { 58102, 62534 }, + { 58103, 62535 }, + { 58104, 62536 }, + { 58105, 62537 }, + { 58106, 62538 }, + { 58107, 62539 }, + { 58108, 62540 }, + { 58109, 62541 }, + { 58110, 62542 }, + { 58111, 62543 }, + { 58112, 62544 }, + { 58113, 62545 }, + { 58114, 62546 }, + { 58115, 62547 }, + { 58116, 62548 }, + { 58117, 62549 }, + { 58118, 62550 }, + { 58119, 62551 }, + { 58120, 62552 }, + { 58121, 62553 }, + { 58122, 62554 }, + { 58123, 62555 }, + { 58124, 62556 }, + { 58125, 62557 }, + { 58126, 62558 }, + { 58127, 62559 }, + { 58128, 62560 }, + { 58129, 62561 }, + { 58130, 62562 }, + { 58131, 62563 }, + { 58132, 62564 }, + { 58133, 62565 }, + { 58134, 62566 }, + { 58135, 62567 }, + { 58136, 62568 }, + { 58137, 62569 }, + { 58138, 62570 }, + { 58139, 62571 }, + { 58140, 62572 }, + { 58141, 62573 }, + { 58142, 62574 }, + { 58143, 62575 }, + { 58144, 62576 }, + { 58145, 62577 }, + { 58146, 62578 }, + { 58147, 62579 }, + { 58148, 62580 }, + { 58149, 62581 }, + { 58150, 62582 }, + { 58151, 62583 }, + { 58152, 62584 }, + { 58153, 62585 }, + { 58154, 62586 }, + { 58155, 62587 }, + { 58156, 62588 }, + { 58157, 62589 }, + { 58158, 62590 }, + { 58159, 62592 }, + { 58160, 62593 }, + { 58161, 62594 }, + { 58162, 62595 }, + { 58163, 62596 }, + { 58164, 62597 }, + { 58165, 62598 }, + { 58166, 62599 }, + { 58167, 62600 }, + { 58168, 62601 }, + { 58169, 62602 }, + { 58170, 62603 }, + { 58171, 62604 }, + { 58172, 62605 }, + { 58173, 62606 }, + { 58174, 62607 }, + { 58175, 62608 }, + { 58176, 62609 }, + { 58177, 62610 }, + { 58178, 62611 }, + { 58179, 62612 }, + { 58180, 62613 }, + { 58181, 62614 }, + { 58182, 62615 }, + { 58183, 62616 }, + { 58184, 62617 }, + { 58185, 62618 }, + { 58186, 62619 }, + { 58187, 62620 }, + { 58188, 62621 }, + { 58189, 62622 }, + { 58190, 62623 }, + { 58191, 62624 }, + { 58192, 62625 }, + { 58193, 62626 }, + { 58194, 62627 }, + { 58195, 62628 }, + { 58196, 62629 }, + { 58197, 62630 }, + { 58198, 62631 }, + { 58199, 62632 }, + { 58200, 62633 }, + { 58201, 62634 }, + { 58202, 62635 }, + { 58203, 62636 }, + { 58204, 62637 }, + { 58205, 62638 }, + { 58206, 62639 }, + { 58207, 62640 }, + { 58208, 62641 }, + { 58209, 62642 }, + { 58210, 62643 }, + { 58211, 62644 }, + { 58212, 62645 }, + { 58213, 62646 }, + { 58214, 62647 }, + { 58215, 62648 }, + { 58216, 62649 }, + { 58217, 62650 }, + { 58218, 62651 }, + { 58219, 62652 }, + { 58220, 62653 }, + { 58221, 62654 }, + { 58222, 62655 }, + { 58223, 62656 }, + { 58224, 62657 }, + { 58225, 62658 }, + { 58226, 62659 }, + { 58227, 62660 }, + { 58228, 62661 }, + { 58229, 62662 }, + { 58230, 62663 }, + { 58231, 62664 }, + { 58232, 62665 }, + { 58233, 62666 }, + { 58234, 62667 }, + { 58235, 62668 }, + { 58236, 62669 }, + { 58237, 62670 }, + { 58238, 62671 }, + { 58239, 62672 }, + { 58240, 62673 }, + { 58241, 62674 }, + { 58242, 62675 }, + { 58243, 62676 }, + { 58244, 62677 }, + { 58245, 62678 }, + { 58246, 62679 }, + { 58247, 62680 }, + { 58248, 62681 }, + { 58249, 62682 }, + { 58250, 62683 }, + { 58251, 62684 }, + { 58252, 62685 }, + { 58253, 62686 }, + { 58254, 62687 }, + { 58255, 62688 }, + { 58256, 62689 }, + { 58257, 62690 }, + { 58258, 62691 }, + { 58259, 62692 }, + { 58260, 62693 }, + { 58261, 62694 }, + { 58262, 62695 }, + { 58263, 62696 }, + { 58264, 62697 }, + { 58265, 62698 }, + { 58266, 62699 }, + { 58267, 62700 }, + { 58268, 62701 }, + { 58269, 62702 }, + { 58270, 62703 }, + { 58271, 62704 }, + { 58272, 62705 }, + { 58273, 62706 }, + { 58274, 62707 }, + { 58275, 62708 }, + { 58276, 62709 }, + { 58277, 62710 }, + { 58278, 62711 }, + { 58279, 62712 }, + { 58280, 62713 }, + { 58281, 62714 }, + { 58282, 62715 }, + { 58283, 62716 }, + { 58284, 62784 }, + { 58285, 62785 }, + { 58286, 62786 }, + { 58287, 62787 }, + { 58288, 62788 }, + { 58289, 62789 }, + { 58290, 62790 }, + { 58291, 62791 }, + { 58292, 62792 }, + { 58293, 62793 }, + { 58294, 62794 }, + { 58295, 62795 }, + { 58296, 62796 }, + { 58297, 62797 }, + { 58298, 62798 }, + { 58299, 62799 }, + { 58300, 62800 }, + { 58301, 62801 }, + { 58302, 62802 }, + { 58303, 62803 }, + { 58304, 62804 }, + { 58305, 62805 }, + { 58306, 62806 }, + { 58307, 62807 }, + { 58308, 62808 }, + { 58309, 62809 }, + { 58310, 62810 }, + { 58311, 62811 }, + { 58312, 62812 }, + { 58313, 62813 }, + { 58314, 62814 }, + { 58315, 62815 }, + { 58316, 62816 }, + { 58317, 62817 }, + { 58318, 62818 }, + { 58319, 62819 }, + { 58320, 62820 }, + { 58321, 62821 }, + { 58322, 62822 }, + { 58323, 62823 }, + { 58324, 62824 }, + { 58325, 62825 }, + { 58326, 62826 }, + { 58327, 62827 }, + { 58328, 62828 }, + { 58329, 62829 }, + { 58330, 62830 }, + { 58331, 62831 }, + { 58332, 62832 }, + { 58333, 62833 }, + { 58334, 62834 }, + { 58335, 62835 }, + { 58336, 62836 }, + { 58337, 62837 }, + { 58338, 62838 }, + { 58339, 62839 }, + { 58340, 62840 }, + { 58341, 62841 }, + { 58342, 62842 }, + { 58343, 62843 }, + { 58344, 62844 }, + { 58345, 62845 }, + { 58346, 62846 }, + { 58347, 62848 }, + { 58348, 62849 }, + { 58349, 62850 }, + { 58350, 62851 }, + { 58351, 62852 }, + { 58352, 62853 }, + { 58353, 62854 }, + { 58354, 62855 }, + { 58355, 62856 }, + { 58356, 62857 }, + { 58357, 62858 }, + { 58358, 62859 }, + { 58359, 62860 }, + { 58360, 62861 }, + { 58361, 62862 }, + { 58362, 62863 }, + { 58363, 62864 }, + { 58364, 62865 }, + { 58365, 62866 }, + { 58366, 62867 }, + { 58367, 62868 }, + { 58368, 62869 }, + { 58369, 62870 }, + { 58370, 62871 }, + { 58371, 62872 }, + { 58372, 62873 }, + { 58373, 62874 }, + { 58374, 62875 }, + { 58375, 62876 }, + { 58376, 62877 }, + { 58377, 62878 }, + { 58378, 62879 }, + { 58379, 62880 }, + { 58380, 62881 }, + { 58381, 62882 }, + { 58382, 62883 }, + { 58383, 62884 }, + { 58384, 62885 }, + { 58385, 62886 }, + { 58386, 62887 }, + { 58387, 62888 }, + { 58388, 62889 }, + { 58389, 62890 }, + { 58390, 62891 }, + { 58391, 62892 }, + { 58392, 62893 }, + { 58393, 62894 }, + { 58394, 62895 }, + { 58395, 62896 }, + { 58396, 62897 }, + { 58397, 62898 }, + { 58398, 62899 }, + { 58399, 62900 }, + { 58400, 62901 }, + { 58401, 62902 }, + { 58402, 62903 }, + { 58403, 62904 }, + { 58404, 62905 }, + { 58405, 62906 }, + { 58406, 62907 }, + { 58407, 62908 }, + { 58408, 62909 }, + { 58409, 62910 }, + { 58410, 62911 }, + { 58411, 62912 }, + { 58412, 62913 }, + { 58413, 62914 }, + { 58414, 62915 }, + { 58415, 62916 }, + { 58416, 62917 }, + { 58417, 62918 }, + { 58418, 62919 }, + { 58419, 62920 }, + { 58420, 62921 }, + { 58421, 62922 }, + { 58422, 62923 }, + { 58423, 62924 }, + { 58424, 62925 }, + { 58425, 62926 }, + { 58426, 62927 }, + { 58427, 62928 }, + { 58428, 62929 }, + { 58429, 62930 }, + { 58430, 62931 }, + { 58431, 62932 }, + { 58432, 62933 }, + { 58433, 62934 }, + { 58434, 62935 }, + { 58435, 62936 }, + { 58436, 62937 }, + { 58437, 62938 }, + { 58438, 62939 }, + { 58439, 62940 }, + { 58440, 62941 }, + { 58441, 62942 }, + { 58442, 62943 }, + { 58443, 62944 }, + { 58444, 62945 }, + { 58445, 62946 }, + { 58446, 62947 }, + { 58447, 62948 }, + { 58448, 62949 }, + { 58449, 62950 }, + { 58450, 62951 }, + { 58451, 62952 }, + { 58452, 62953 }, + { 58453, 62954 }, + { 58454, 62955 }, + { 58455, 62956 }, + { 58456, 62957 }, + { 58457, 62958 }, + { 58458, 62959 }, + { 58459, 62960 }, + { 58460, 62961 }, + { 58461, 62962 }, + { 58462, 62963 }, + { 58463, 62964 }, + { 58464, 62965 }, + { 58465, 62966 }, + { 58466, 62967 }, + { 58467, 62968 }, + { 58468, 62969 }, + { 58469, 62970 }, + { 58470, 62971 }, + { 58471, 62972 }, + { 58472, 63040 }, + { 58473, 63041 }, + { 58474, 63042 }, + { 58475, 63043 }, + { 58476, 63044 }, + { 58477, 63045 }, + { 58478, 63046 }, + { 58479, 63047 }, + { 58480, 63048 }, + { 58481, 63049 }, + { 58482, 63050 }, + { 58483, 63051 }, + { 58484, 63052 }, + { 58485, 63053 }, + { 58486, 63054 }, + { 58487, 63055 }, + { 58488, 63056 }, + { 58489, 63057 }, + { 58490, 63058 }, + { 58491, 63059 }, + { 58492, 63060 }, + { 58493, 63061 }, + { 58494, 63062 }, + { 58495, 63063 }, + { 58496, 63064 }, + { 58497, 63065 }, + { 58498, 63066 }, + { 58499, 63067 }, + { 58500, 63068 }, + { 58501, 63069 }, + { 58502, 63070 }, + { 58503, 63071 }, + { 58504, 63072 }, + { 58505, 63073 }, + { 58506, 63074 }, + { 58507, 63075 }, + { 58508, 63076 }, + { 58509, 63077 }, + { 58510, 63078 }, + { 58511, 63079 }, + { 58512, 63080 }, + { 58513, 63081 }, + { 58514, 63082 }, + { 58515, 63083 }, + { 58516, 63084 }, + { 58517, 63085 }, + { 58518, 63086 }, + { 58519, 63087 }, + { 58520, 63088 }, + { 58521, 63089 }, + { 58522, 63090 }, + { 58523, 63091 }, + { 58524, 63092 }, + { 58525, 63093 }, + { 58526, 63094 }, + { 58527, 63095 }, + { 58528, 63096 }, + { 58529, 63097 }, + { 58530, 63098 }, + { 58531, 63099 }, + { 58532, 63100 }, + { 58533, 63101 }, + { 58534, 63102 }, + { 58535, 63104 }, + { 58536, 63105 }, + { 58537, 63106 }, + { 58538, 63107 }, + { 58539, 63108 }, + { 58540, 63109 }, + { 58541, 63110 }, + { 58542, 63111 }, + { 58543, 63112 }, + { 58544, 63113 }, + { 58545, 63114 }, + { 58546, 63115 }, + { 58547, 63116 }, + { 58548, 63117 }, + { 58549, 63118 }, + { 58550, 63119 }, + { 58551, 63120 }, + { 58552, 63121 }, + { 58553, 63122 }, + { 58554, 63123 }, + { 58555, 63124 }, + { 58556, 63125 }, + { 58557, 63126 }, + { 58558, 63127 }, + { 58559, 63128 }, + { 58560, 63129 }, + { 58561, 63130 }, + { 58562, 63131 }, + { 58563, 63132 }, + { 58564, 63133 }, + { 58565, 63134 }, + { 58566, 63135 }, + { 58567, 63136 }, + { 58568, 63137 }, + { 58569, 63138 }, + { 58570, 63139 }, + { 58571, 63140 }, + { 58572, 63141 }, + { 58573, 63142 }, + { 58574, 63143 }, + { 58575, 63144 }, + { 58576, 63145 }, + { 58577, 63146 }, + { 58578, 63147 }, + { 58579, 63148 }, + { 58580, 63149 }, + { 58581, 63150 }, + { 58582, 63151 }, + { 58583, 63152 }, + { 58584, 63153 }, + { 58585, 63154 }, + { 58586, 63155 }, + { 58587, 63156 }, + { 58588, 63157 }, + { 58589, 63158 }, + { 58590, 63159 }, + { 58591, 63160 }, + { 58592, 63161 }, + { 58593, 63162 }, + { 58594, 63163 }, + { 58595, 63164 }, + { 58596, 63165 }, + { 58597, 63166 }, + { 58598, 63167 }, + { 58599, 63168 }, + { 58600, 63169 }, + { 58601, 63170 }, + { 58602, 63171 }, + { 58603, 63172 }, + { 58604, 63173 }, + { 58605, 63174 }, + { 58606, 63175 }, + { 58607, 63176 }, + { 58608, 63177 }, + { 58609, 63178 }, + { 58610, 63179 }, + { 58611, 63180 }, + { 58612, 63181 }, + { 58613, 63182 }, + { 58614, 63183 }, + { 58615, 63184 }, + { 58616, 63185 }, + { 58617, 63186 }, + { 58618, 63187 }, + { 58619, 63188 }, + { 58620, 63189 }, + { 58621, 63190 }, + { 58622, 63191 }, + { 58623, 63192 }, + { 58624, 63193 }, + { 58625, 63194 }, + { 58626, 63195 }, + { 58627, 63196 }, + { 58628, 63197 }, + { 58629, 63198 }, + { 58630, 63199 }, + { 58631, 63200 }, + { 58632, 63201 }, + { 58633, 63202 }, + { 58634, 63203 }, + { 58635, 63204 }, + { 58636, 63205 }, + { 58637, 63206 }, + { 58638, 63207 }, + { 58639, 63208 }, + { 58640, 63209 }, + { 58641, 63210 }, + { 58642, 63211 }, + { 58643, 63212 }, + { 58644, 63213 }, + { 58645, 63214 }, + { 58646, 63215 }, + { 58647, 63216 }, + { 58648, 63217 }, + { 58649, 63218 }, + { 58650, 63219 }, + { 58651, 63220 }, + { 58652, 63221 }, + { 58653, 63222 }, + { 58654, 63223 }, + { 58655, 63224 }, + { 58656, 63225 }, + { 58657, 63226 }, + { 58658, 63227 }, + { 58659, 63228 }, + { 58660, 63296 }, + { 58661, 63297 }, + { 58662, 63298 }, + { 58663, 63299 }, + { 58664, 63300 }, + { 58665, 63301 }, + { 58666, 63302 }, + { 58667, 63303 }, + { 58668, 63304 }, + { 58669, 63305 }, + { 58670, 63306 }, + { 58671, 63307 }, + { 58672, 63308 }, + { 58673, 63309 }, + { 58674, 63310 }, + { 58675, 63311 }, + { 58676, 63312 }, + { 58677, 63313 }, + { 58678, 63314 }, + { 58679, 63315 }, + { 58680, 63316 }, + { 58681, 63317 }, + { 58682, 63318 }, + { 58683, 63319 }, + { 58684, 63320 }, + { 58685, 63321 }, + { 58686, 63322 }, + { 58687, 63323 }, + { 58688, 63324 }, + { 58689, 63325 }, + { 58690, 63326 }, + { 58691, 63327 }, + { 58692, 63328 }, + { 58693, 63329 }, + { 58694, 63330 }, + { 58695, 63331 }, + { 58696, 63332 }, + { 58697, 63333 }, + { 58698, 63334 }, + { 58699, 63335 }, + { 58700, 63336 }, + { 58701, 63337 }, + { 58702, 63338 }, + { 58703, 63339 }, + { 58704, 63340 }, + { 58705, 63341 }, + { 58706, 63342 }, + { 58707, 63343 }, + { 58708, 63344 }, + { 58709, 63345 }, + { 58710, 63346 }, + { 58711, 63347 }, + { 58712, 63348 }, + { 58713, 63349 }, + { 58714, 63350 }, + { 58715, 63351 }, + { 58716, 63352 }, + { 58717, 63353 }, + { 58718, 63354 }, + { 58719, 63355 }, + { 58720, 63356 }, + { 58721, 63357 }, + { 58722, 63358 }, + { 58723, 63360 }, + { 58724, 63361 }, + { 58725, 63362 }, + { 58726, 63363 }, + { 58727, 63364 }, + { 58728, 63365 }, + { 58729, 63366 }, + { 58730, 63367 }, + { 58731, 63368 }, + { 58732, 63369 }, + { 58733, 63370 }, + { 58734, 63371 }, + { 58735, 63372 }, + { 58736, 63373 }, + { 58737, 63374 }, + { 58738, 63375 }, + { 58739, 63376 }, + { 58740, 63377 }, + { 58741, 63378 }, + { 58742, 63379 }, + { 58743, 63380 }, + { 58744, 63381 }, + { 58745, 63382 }, + { 58746, 63383 }, + { 58747, 63384 }, + { 58748, 63385 }, + { 58749, 63386 }, + { 58750, 63387 }, + { 58751, 63388 }, + { 58752, 63389 }, + { 58753, 63390 }, + { 58754, 63391 }, + { 58755, 63392 }, + { 58756, 63393 }, + { 58757, 63394 }, + { 58758, 63395 }, + { 58759, 63396 }, + { 58760, 63397 }, + { 58761, 63398 }, + { 58762, 63399 }, + { 58763, 63400 }, + { 58764, 63401 }, + { 58765, 63402 }, + { 58766, 63403 }, + { 58767, 63404 }, + { 58768, 63405 }, + { 58769, 63406 }, + { 58770, 63407 }, + { 58771, 63408 }, + { 58772, 63409 }, + { 58773, 63410 }, + { 58774, 63411 }, + { 58775, 63412 }, + { 58776, 63413 }, + { 58777, 63414 }, + { 58778, 63415 }, + { 58779, 63416 }, + { 58780, 63417 }, + { 58781, 63418 }, + { 58782, 63419 }, + { 58783, 63420 }, + { 58784, 63421 }, + { 58785, 63422 }, + { 58786, 63423 }, + { 58787, 63424 }, + { 58788, 63425 }, + { 58789, 63426 }, + { 58790, 63427 }, + { 58791, 63428 }, + { 58792, 63429 }, + { 58793, 63430 }, + { 58794, 63431 }, + { 58795, 63432 }, + { 58796, 63433 }, + { 58797, 63434 }, + { 58798, 63435 }, + { 58799, 63436 }, + { 58800, 63437 }, + { 58801, 63438 }, + { 58802, 63439 }, + { 58803, 63440 }, + { 58804, 63441 }, + { 58805, 63442 }, + { 58806, 63443 }, + { 58807, 63444 }, + { 58808, 63445 }, + { 58809, 63446 }, + { 58810, 63447 }, + { 58811, 63448 }, + { 58812, 63449 }, + { 58813, 63450 }, + { 58814, 63451 }, + { 58815, 63452 }, + { 58816, 63453 }, + { 58817, 63454 }, + { 58818, 63455 }, + { 58819, 63456 }, + { 58820, 63457 }, + { 58821, 63458 }, + { 58822, 63459 }, + { 58823, 63460 }, + { 58824, 63461 }, + { 58825, 63462 }, + { 58826, 63463 }, + { 58827, 63464 }, + { 58828, 63465 }, + { 58829, 63466 }, + { 58830, 63467 }, + { 58831, 63468 }, + { 58832, 63469 }, + { 58833, 63470 }, + { 58834, 63471 }, + { 58835, 63472 }, + { 58836, 63473 }, + { 58837, 63474 }, + { 58838, 63475 }, + { 58839, 63476 }, + { 58840, 63477 }, + { 58841, 63478 }, + { 58842, 63479 }, + { 58843, 63480 }, + { 58844, 63481 }, + { 58845, 63482 }, + { 58846, 63483 }, + { 58847, 63484 }, + { 58848, 63552 }, + { 58849, 63553 }, + { 58850, 63554 }, + { 58851, 63555 }, + { 58852, 63556 }, + { 58853, 63557 }, + { 58854, 63558 }, + { 58855, 63559 }, + { 58856, 63560 }, + { 58857, 63561 }, + { 58858, 63562 }, + { 58859, 63563 }, + { 58860, 63564 }, + { 58861, 63565 }, + { 58862, 63566 }, + { 58863, 63567 }, + { 58864, 63568 }, + { 58865, 63569 }, + { 58866, 63570 }, + { 58867, 63571 }, + { 58868, 63572 }, + { 58869, 63573 }, + { 58870, 63574 }, + { 58871, 63575 }, + { 58872, 63576 }, + { 58873, 63577 }, + { 58874, 63578 }, + { 58875, 63579 }, + { 58876, 63580 }, + { 58877, 63581 }, + { 58878, 63582 }, + { 58879, 63583 }, + { 58880, 63584 }, + { 58881, 63585 }, + { 58882, 63586 }, + { 58883, 63587 }, + { 58884, 63588 }, + { 58885, 63589 }, + { 58886, 63590 }, + { 58887, 63591 }, + { 58888, 63592 }, + { 58889, 63593 }, + { 58890, 63594 }, + { 58891, 63595 }, + { 58892, 63596 }, + { 58893, 63597 }, + { 58894, 63598 }, + { 58895, 63599 }, + { 58896, 63600 }, + { 58897, 63601 }, + { 58898, 63602 }, + { 58899, 63603 }, + { 58900, 63604 }, + { 58901, 63605 }, + { 58902, 63606 }, + { 58903, 63607 }, + { 58904, 63608 }, + { 58905, 63609 }, + { 58906, 63610 }, + { 58907, 63611 }, + { 58908, 63612 }, + { 58909, 63613 }, + { 58910, 63614 }, + { 58911, 63616 }, + { 58912, 63617 }, + { 58913, 63618 }, + { 58914, 63619 }, + { 58915, 63620 }, + { 58916, 63621 }, + { 58917, 63622 }, + { 58918, 63623 }, + { 58919, 63624 }, + { 58920, 63625 }, + { 58921, 63626 }, + { 58922, 63627 }, + { 58923, 63628 }, + { 58924, 63629 }, + { 58925, 63630 }, + { 58926, 63631 }, + { 58927, 63632 }, + { 58928, 63633 }, + { 58929, 63634 }, + { 58930, 63635 }, + { 58931, 63636 }, + { 58932, 63637 }, + { 58933, 63638 }, + { 58934, 63639 }, + { 58935, 63640 }, + { 58936, 63641 }, + { 58937, 63642 }, + { 58938, 63643 }, + { 58939, 63644 }, + { 58940, 63645 }, + { 58941, 63646 }, + { 58942, 63647 }, + { 58943, 63648 }, + { 58944, 63649 }, + { 58945, 63650 }, + { 58946, 63651 }, + { 58947, 63652 }, + { 58948, 63653 }, + { 58949, 63654 }, + { 58950, 63655 }, + { 58951, 63656 }, + { 58952, 63657 }, + { 58953, 63658 }, + { 58954, 63659 }, + { 58955, 63660 }, + { 58956, 63661 }, + { 58957, 63662 }, + { 58958, 63663 }, + { 58959, 63664 }, + { 58960, 63665 }, + { 58961, 63666 }, + { 58962, 63667 }, + { 58963, 63668 }, + { 58964, 63669 }, + { 58965, 63670 }, + { 58966, 63671 }, + { 58967, 63672 }, + { 58968, 63673 }, + { 58969, 63674 }, + { 58970, 63675 }, + { 58971, 63676 }, + { 58972, 63677 }, + { 58973, 63678 }, + { 58974, 63679 }, + { 58975, 63680 }, + { 58976, 63681 }, + { 58977, 63682 }, + { 58978, 63683 }, + { 58979, 63684 }, + { 58980, 63685 }, + { 58981, 63686 }, + { 58982, 63687 }, + { 58983, 63688 }, + { 58984, 63689 }, + { 58985, 63690 }, + { 58986, 63691 }, + { 58987, 63692 }, + { 58988, 63693 }, + { 58989, 63694 }, + { 58990, 63695 }, + { 58991, 63696 }, + { 58992, 63697 }, + { 58993, 63698 }, + { 58994, 63699 }, + { 58995, 63700 }, + { 58996, 63701 }, + { 58997, 63702 }, + { 58998, 63703 }, + { 58999, 63704 }, + { 59000, 63705 }, + { 59001, 63706 }, + { 59002, 63707 }, + { 59003, 63708 }, + { 59004, 63709 }, + { 59005, 63710 }, + { 59006, 63711 }, + { 59007, 63712 }, + { 59008, 63713 }, + { 59009, 63714 }, + { 59010, 63715 }, + { 59011, 63716 }, + { 59012, 63717 }, + { 59013, 63718 }, + { 59014, 63719 }, + { 59015, 63720 }, + { 59016, 63721 }, + { 59017, 63722 }, + { 59018, 63723 }, + { 59019, 63724 }, + { 59020, 63725 }, + { 59021, 63726 }, + { 59022, 63727 }, + { 59023, 63728 }, + { 59024, 63729 }, + { 59025, 63730 }, + { 59026, 63731 }, + { 59027, 63732 }, + { 59028, 63733 }, + { 59029, 63734 }, + { 59030, 63735 }, + { 59031, 63736 }, + { 59032, 63737 }, + { 59033, 63738 }, + { 59034, 63739 }, + { 59035, 63740 }, + { 59036, 63808 }, + { 59037, 63809 }, + { 59038, 63810 }, + { 59039, 63811 }, + { 59040, 63812 }, + { 59041, 63813 }, + { 59042, 63814 }, + { 59043, 63815 }, + { 59044, 63816 }, + { 59045, 63817 }, + { 59046, 63818 }, + { 59047, 63819 }, + { 59048, 63820 }, + { 59049, 63821 }, + { 59050, 63822 }, + { 59051, 63823 }, + { 59052, 63824 }, + { 59053, 63825 }, + { 59054, 63826 }, + { 59055, 63827 }, + { 59056, 63828 }, + { 59057, 63829 }, + { 59058, 63830 }, + { 59059, 63831 }, + { 59060, 63832 }, + { 59061, 63833 }, + { 59062, 63834 }, + { 59063, 63835 }, + { 59064, 63836 }, + { 59065, 63837 }, + { 59066, 63838 }, + { 59067, 63839 }, + { 59068, 63840 }, + { 59069, 63841 }, + { 59070, 63842 }, + { 59071, 63843 }, + { 59072, 63844 }, + { 59073, 63845 }, + { 59074, 63846 }, + { 59075, 63847 }, + { 59076, 63848 }, + { 59077, 63849 }, + { 59078, 63850 }, + { 59079, 63851 }, + { 59080, 63852 }, + { 59081, 63853 }, + { 59082, 63854 }, + { 59083, 63855 }, + { 59084, 63856 }, + { 59085, 63857 }, + { 59086, 63858 }, + { 59087, 63859 }, + { 59088, 63860 }, + { 59089, 63861 }, + { 59090, 63862 }, + { 59091, 63863 }, + { 59092, 63864 }, + { 59093, 63865 }, + { 59094, 63866 }, + { 59095, 63867 }, + { 59096, 63868 }, + { 59097, 63869 }, + { 59098, 63870 }, + { 59099, 63872 }, + { 59100, 63873 }, + { 59101, 63874 }, + { 59102, 63875 }, + { 59103, 63876 }, + { 59104, 63877 }, + { 59105, 63878 }, + { 59106, 63879 }, + { 59107, 63880 }, + { 59108, 63881 }, + { 59109, 63882 }, + { 59110, 63883 }, + { 59111, 63884 }, + { 59112, 63885 }, + { 59113, 63886 }, + { 59114, 63887 }, + { 59115, 63888 }, + { 59116, 63889 }, + { 59117, 63890 }, + { 59118, 63891 }, + { 59119, 63892 }, + { 59120, 63893 }, + { 59121, 63894 }, + { 59122, 63895 }, + { 59123, 63896 }, + { 59124, 63897 }, + { 59125, 63898 }, + { 59126, 63899 }, + { 59127, 63900 }, + { 59128, 63901 }, + { 59129, 63902 }, + { 59130, 63903 }, + { 59131, 63904 }, + { 59132, 63905 }, + { 59133, 63906 }, + { 59134, 63907 }, + { 59135, 63908 }, + { 59136, 63909 }, + { 59137, 63910 }, + { 59138, 63911 }, + { 59139, 63912 }, + { 59140, 63913 }, + { 59141, 63914 }, + { 59142, 63915 }, + { 59143, 63916 }, + { 59144, 63917 }, + { 59145, 63918 }, + { 59146, 63919 }, + { 59147, 63920 }, + { 59148, 63921 }, + { 59149, 63922 }, + { 59150, 63923 }, + { 59151, 63924 }, + { 59152, 63925 }, + { 59153, 63926 }, + { 59154, 63927 }, + { 59155, 63928 }, + { 59156, 63929 }, + { 59157, 63930 }, + { 59158, 63931 }, + { 59159, 63932 }, + { 59160, 63933 }, + { 59161, 63934 }, + { 59162, 63935 }, + { 59163, 63936 }, + { 59164, 63937 }, + { 59165, 63938 }, + { 59166, 63939 }, + { 59167, 63940 }, + { 59168, 63941 }, + { 59169, 63942 }, + { 59170, 63943 }, + { 59171, 63944 }, + { 59172, 63945 }, + { 59173, 63946 }, + { 59174, 63947 }, + { 59175, 63948 }, + { 59176, 63949 }, + { 59177, 63950 }, + { 59178, 63951 }, + { 59179, 63952 }, + { 59180, 63953 }, + { 59181, 63954 }, + { 59182, 63955 }, + { 59183, 63956 }, + { 59184, 63957 }, + { 59185, 63958 }, + { 59186, 63959 }, + { 59187, 63960 }, + { 59188, 63961 }, + { 59189, 63962 }, + { 59190, 63963 }, + { 59191, 63964 }, + { 59192, 63965 }, + { 59193, 63966 }, + { 59194, 63967 }, + { 59195, 63968 }, + { 59196, 63969 }, + { 59197, 63970 }, + { 59198, 63971 }, + { 59199, 63972 }, + { 59200, 63973 }, + { 59201, 63974 }, + { 59202, 63975 }, + { 59203, 63976 }, + { 59204, 63977 }, + { 59205, 63978 }, + { 59206, 63979 }, + { 59207, 63980 }, + { 59208, 63981 }, + { 59209, 63982 }, + { 59210, 63983 }, + { 59211, 63984 }, + { 59212, 63985 }, + { 59213, 63986 }, + { 59214, 63987 }, + { 59215, 63988 }, + { 59216, 63989 }, + { 59217, 63990 }, + { 59218, 63991 }, + { 59219, 63992 }, + { 59220, 63993 }, + { 59221, 63994 }, + { 59222, 63995 }, + { 59223, 63996 }, + { 63728, 160 }, + { 63729, 253 }, + { 63730, 254 }, + { 63731, 255 }, + { 63785, 64224 }, + { 63964, 64489 }, + { 64014, 64144 }, + { 64015, 64155 }, + { 64016, 64156 }, + { 64017, 64177 }, + { 64018, 64216 }, + { 64019, 64232 }, + { 64020, 64234 }, + { 64021, 64344 }, + { 64022, 64350 }, + { 64023, 64373 }, + { 64024, 64381 }, + { 64025, 64382 }, + { 64026, 64384 }, + { 64027, 64386 }, + { 64028, 64390 }, + { 64029, 64393 }, + { 64030, 64402 }, + { 64031, 64413 }, + { 64032, 64415 }, + { 64033, 64416 }, + { 64034, 64425 }, + { 64035, 64433 }, + { 64036, 64435 }, + { 64037, 64436 }, + { 64038, 64439 }, + { 64039, 64467 }, + { 64040, 64474 }, + { 64041, 64490 }, + { 64042, 64502 }, + { 64043, 64503 }, + { 64044, 64505 }, + { 64045, 64585 }, + { 65281, 33097 }, + { 65282, 64087 }, + { 65283, 33172 }, + { 65284, 33168 }, + { 65285, 33171 }, + { 65286, 33173 }, + { 65287, 64086 }, + { 65288, 33129 }, + { 65289, 33130 }, + { 65290, 33174 }, + { 65291, 33147 }, + { 65292, 33091 }, + { 65293, 33148 }, + { 65294, 33092 }, + { 65295, 33118 }, + { 65296, 33359 }, + { 65297, 33360 }, + { 65298, 33361 }, + { 65299, 33362 }, + { 65300, 33363 }, + { 65301, 33364 }, + { 65302, 33365 }, + { 65303, 33366 }, + { 65304, 33367 }, + { 65305, 33368 }, + { 65306, 33094 }, + { 65307, 33095 }, + { 65308, 33155 }, + { 65309, 33153 }, + { 65310, 33156 }, + { 65311, 33096 }, + { 65312, 33175 }, + { 65313, 33376 }, + { 65314, 33377 }, + { 65315, 33378 }, + { 65316, 33379 }, + { 65317, 33380 }, + { 65318, 33381 }, + { 65319, 33382 }, + { 65320, 33383 }, + { 65321, 33384 }, + { 65322, 33385 }, + { 65323, 33386 }, + { 65324, 33387 }, + { 65325, 33388 }, + { 65326, 33389 }, + { 65327, 33390 }, + { 65328, 33391 }, + { 65329, 33392 }, + { 65330, 33393 }, + { 65331, 33394 }, + { 65332, 33395 }, + { 65333, 33396 }, + { 65334, 33397 }, + { 65335, 33398 }, + { 65336, 33399 }, + { 65337, 33400 }, + { 65338, 33401 }, + { 65339, 33133 }, + { 65340, 33119 }, + { 65341, 33134 }, + { 65342, 33103 }, + { 65343, 33105 }, + { 65344, 33101 }, + { 65345, 33409 }, + { 65346, 33410 }, + { 65347, 33411 }, + { 65348, 33412 }, + { 65349, 33413 }, + { 65350, 33414 }, + { 65351, 33415 }, + { 65352, 33416 }, + { 65353, 33417 }, + { 65354, 33418 }, + { 65355, 33419 }, + { 65356, 33420 }, + { 65357, 33421 }, + { 65358, 33422 }, + { 65359, 33423 }, + { 65360, 33424 }, + { 65361, 33425 }, + { 65362, 33426 }, + { 65363, 33427 }, + { 65364, 33428 }, + { 65365, 33429 }, + { 65366, 33430 }, + { 65367, 33431 }, + { 65368, 33432 }, + { 65369, 33433 }, + { 65370, 33434 }, + { 65371, 33135 }, + { 65372, 33122 }, + { 65373, 33136 }, + { 65374, 33120 }, + { 65377, 161 }, + { 65378, 162 }, + { 65379, 163 }, + { 65380, 164 }, + { 65381, 165 }, + { 65382, 166 }, + { 65383, 167 }, + { 65384, 168 }, + { 65385, 169 }, + { 65386, 170 }, + { 65387, 171 }, + { 65388, 172 }, + { 65389, 173 }, + { 65390, 174 }, + { 65391, 175 }, + { 65392, 176 }, + { 65393, 177 }, + { 65394, 178 }, + { 65395, 179 }, + { 65396, 180 }, + { 65397, 181 }, + { 65398, 182 }, + { 65399, 183 }, + { 65400, 184 }, + { 65401, 185 }, + { 65402, 186 }, + { 65403, 187 }, + { 65404, 188 }, + { 65405, 189 }, + { 65406, 190 }, + { 65407, 191 }, + { 65408, 192 }, + { 65409, 193 }, + { 65410, 194 }, + { 65411, 195 }, + { 65412, 196 }, + { 65413, 197 }, + { 65414, 198 }, + { 65415, 199 }, + { 65416, 200 }, + { 65417, 201 }, + { 65418, 202 }, + { 65419, 203 }, + { 65420, 204 }, + { 65421, 205 }, + { 65422, 206 }, + { 65423, 207 }, + { 65424, 208 }, + { 65425, 209 }, + { 65426, 210 }, + { 65427, 211 }, + { 65428, 212 }, + { 65429, 213 }, + { 65430, 214 }, + { 65431, 215 }, + { 65432, 216 }, + { 65433, 217 }, + { 65434, 218 }, + { 65435, 219 }, + { 65436, 220 }, + { 65437, 221 }, + { 65438, 222 }, + { 65439, 223 }, + { 65504, 33169 }, + { 65505, 33170 }, + { 65506, 33226 }, + { 65507, 33104 }, + { 65508, 64085 }, + { 65509, 33167 } + }; + for( int i = 0; i < _LEN_DICT; i++ ){ + _DICT_SRC[i][0] = n[i][0]; + _DICT_SRC[i][1] = n[i][1]; + } +} + +void cp932_init() { + cp932_init_cor(); + for( int i = 0; i < _LEN_DICT; i++ ){ + _DICT.insert( map::value_type( _DICT_SRC[i][0], _DICT_SRC[i][1] ) ); + } + cp932_initialized = true; +} + +vector cp932_convert( wstring str ){ + int len = str.size(); + wchar_t *arr = new wchar_t[len]; + vector list( 0 ); + for( int i = 0; i < len; i++ ){ + map::const_iterator finder = _DICT.find( (int)arr[i] ); + if( finder != _DICT.end() ){ + int t = _DICT[(int)arr[i]]; + if ( t > 0xff ) { + char b1 = (char)(t >> 8); + char b2 = (char)(t - (b1 << 8)); + list.push_back( b1 ); + list.push_back( b2 ); + } else { + list.push_back( (char)t ); + } + } else { + list.push_back( 0x63 ); + } + } + return list; +} + + +wstring cp932_convert( vector dat ){ + if ( !cp932_initialized ) { + cp932_init(); + } + wostringstream sb; + int i = 0; + while( i < dat.size() ){ + int b1 = dat[i]; + bool found = false; + for( int j = 0; j < _LEN_DICT; j++ ){ + int key = _DICT_SRC[j][0]; + int test = _DICT_SRC[j][1]; + if ( b1 == test ) { + found = true; + sb << (wchar_t)key; + break; + } + } + i++; + if( !found && i < dat.size() ){ + int b2 = (dat[i - 1] << 8) + dat[i]; + for( int j = 0; j < _LEN_DICT; j++ ){ + int key = _DICT_SRC[j][0]; + int test = _DICT_SRC[j][1]; + if ( test == b2 ) { + sb << (wchar_t)key; + break; + } + } + i++; + } + } + return sb.str(); +} diff --git a/trunk/Boare.Lib.Vsq/port_cpp/cp932.h b/trunk/Boare.Lib.Vsq/port_cpp/cp932.h new file mode 100644 index 0000000..9cc77cd --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/cp932.h @@ -0,0 +1,13 @@ +#ifndef __cp932_h__ +#define __cp932_h__ + +#include +#include +#include + +using namespace std; + +wstring cp932_convert( vector dat ); +vector cp932_convert( wstring str ); + +#endif // __cp932_h__ diff --git a/trunk/Boare.Lib.Vsq/port_cpp/libvsq.cpp b/trunk/Boare.Lib.Vsq/port_cpp/libvsq.cpp new file mode 100644 index 0000000..b460a7e --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/libvsq.cpp @@ -0,0 +1,2 @@ +#include "libvsq.h" + diff --git a/trunk/Boare.Lib.Vsq/port_cpp/libvsq.h b/trunk/Boare.Lib.Vsq/port_cpp/libvsq.h new file mode 100644 index 0000000..f4c37e6 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/libvsq.h @@ -0,0 +1,1184 @@ +#ifndef __libvsq_h__ +#define __libvsq_h__ +#include +#include +#include +#include +#include +#include "cp932.h" + +using namespace std; + +namespace vsq{ + +inline vector util_split( string str, string delim ){ + vector result; + int cutAt; + while( (cutAt = str.find_first_of( delim )) != str.npos ){ + if( cutAt > 0 ){ + result.push_back( str.substr( 0, cutAt ) ); + } + str = str.substr( cutAt + 1 ); + } + if( str.length() > 0 ){ + result.push_back( str ); + } + return result; +} + +inline string string_replace( string str, string before, string after ){ + int start = 0; + int index = str.find( before, start ); + string newone = str; + while( index < 0 ){ + newone = newone.substr( 0, index ) + after + newone.substr( index + before.length() + 1 ); + start = index + before.length() + 1 + (after.length() - before.length()); + index = newone.find( before, start ); + } + return newone; +} + +template T parse( string s ){ + ostringstream oss( "" ); + T ret; + oss >> ret; + return ret; +} + +typedef unsigned char byte; + +struct TColor{ + int R; + int G; + int B; +}; + +class StreamReader{ +public: + StreamReader( string path ){ + m_ifs.open( path.c_str() ); + }; + + void Close(){ + m_ifs.close(); + }; + + string ReadLine(){ + string ret; + if( get_line( &m_ifs, &ret ) ){ + return ret; + }else{ + return NULL; + } + }; + int Peek(){ + return m_ifs.peek(); + }; +private: + ifstream m_ifs; + static bool get_line( ifstream *ifs, string *str ){ + char ch; + if( ifs->eof() ){ + return false; + } + while( ifs->get( ch ) ){ + if( ch == 0x0d ){ + if( ifs->get( ch ) ){ + if( ch != 0x0a ){ + ifs->seekg( -1, ios::cur ); + } + } + break; + }else if( ch == 0x0a ){ + break; + } + str->append( 1, ch ); + } + return true; + }; +}; + +/// +/// [ŃeLXgt@C߂̃NXD +/// +class TextMemoryStream { +public: + /// + /// + /// + /// + void Write( string value ){ + m_ms << value; + }; + void Rewind(){ + m_ms.seekg( 0, ios::beg ); + }; + void WriteLine( string s ){ + m_ms << s << "\x0d\x0a"; + }; + void Close(){ + m_ms.str( "" ); + }; + int Peek(){ + long current = m_ms.tellg(); + int ret = m_ms.get(); + if( m_ms.gcount() <= 0 ){ + m_ms.seekg( current, ios::beg ); + return -1; + } + m_ms.seekg( current, ios::beg ); + return ret; + }; + string ReadLine(){ + ostringstream buffer; + char value; + char ret; + ret = m_ms.get(); + while ( ret >= 0 ) { + value = (char)ret; + if ( value == NEW_LINE[0] ) { + char next; + long current = m_ms.tellg(); //0x0DõXg[̈ʒu + for ( int i = 1; i < 2; i++ ) { + ret = m_ms.get(); + if ( ret >= 0 ) { + next = ret; + if ( next != NEW_LINE[i] ) { + m_ms.seekg( current, ios::beg ); + break; + } + } + } + break; + } + buffer << value; + ret = m_ms.get(); + } + return buffer.str(); + }; + void Dispose(){ + m_ms.str( "" ); + }; + TextMemoryStream( string path ){ + m_ms.str( "" ); + //if ( File.Exists( path ) ) { + StreamReader sr( path ); + while( sr.Peek() >= 0 ){ + string line = sr.ReadLine(); + m_ms << line << "\x0d\x0a"; + } + sr.Close(); + m_ms.seekg( 0, ios::beg ); + NEW_LINE[0] = '\x0d'; + NEW_LINE[1] = '\x0a'; + }; + TextMemoryStream(){ + m_ms.str( "" ); + NEW_LINE[0] = '\x0d'; + NEW_LINE[1] = '\x0a'; + }; +private: + //FileAccess m_access; + stringstream m_ms; + //Encoding m_enc; + char NEW_LINE[2]; +}; + +class VsqCommon { +public: + string Version; + string Name; + string Color; + int DynamicsMode; + int PlayMode; + + /// + /// ep[^w肵RXgN^ + /// + /// gbN + /// ColorliӖ͕sj + /// DynamicsModeiftHg1j + /// PlayModeiftHg1j + VsqCommon( string name, TColor color, int dynamics_mode, int play_mode ); + + /// + /// MetaText̃eLXgt@C̃RXgN^ + /// + /// ǂݍރeLXgt@C + /// ǂݍ񂾍Ō̍sԂ + VsqCommon( TextMemoryStream sr, string& last_line ); + + /// + /// CX^X̓eeLXgt@Cɏo͂܂ + /// + /// o͐ + void write( TextMemoryStream& sw ); + + /// + /// VsqCommon\̂\zeXgs܂ + /// + /// eXgɐtrueAłȂfalse + static bool test(); +}; + +enum VsqHandleType { + Lyric, + Vibrato, + Singer +}; + +const int _NUM_SYMBOL_VOWEL_JP = 5; +static string _SYMBOL_VOWEL_JP[_NUM_SYMBOL_VOWEL_JP] = { + "a", + "i", + "M", + "e", + "o", +}; + +const int _NUM_SYMBOL_CONSONANT_JP = 36; +static string _SYMBOL_CONSONANT_JP[_NUM_SYMBOL_CONSONANT_JP] = { + "k", + "k'", + "g", + "g'", + "N", + "N'", + "s", + "S", + "z", + "Z", + "dz", + "dZ", + "t", + "t'", + "ts", + "tS", + "d", + "d'", + "n", + "J", + "h", + "h\\", + "C", + "p\\", + "p\\'", + "b", + "b'", + "p", + "p'", + "m", + "m'", + "j", + "4", + "4'", + "w", + "N\\", +}; + +const int _NUM_SYMBOL_EN = 53; +static string _SYMBOL_EN[_NUM_SYMBOL_EN] = { + "@", + "V", + "e", + "e", + "I", + "i:", + "{", + "O:", + "Q", + "U", + "u:", + "@r", + "eI", + "aI", + "OI", + "@U", + "aU", + "I@", + "e@", + "U@", + "O@", + "Q@", + "w", + "j", + "b", + "d", + "g", + "bh", + "dh", + "gh", + "dZ", + "v", + "D", + "z", + "Z", + "m", + "n", + "N", + "r", + "l", + "l0", + "p", + "t", + "k", + "ph", + "th", + "kh", + "tS", + "f", + "T", + "s", + "S", + "h", +}; + +class VsqPhoneticSymbol { +public: + static bool IsConsonant( string symbol ) { + for( int i = 0; i < _NUM_SYMBOL_CONSONANT_JP; i++ ){ + string s = _SYMBOL_CONSONANT_JP[i]; + if ( s == symbol ) { + return true; + } + } + return false; + } + static bool IsValidSymbol( string symbol ) { + for( int i = 0; i < _NUM_SYMBOL_VOWEL_JP; i++ ){ + string s = _SYMBOL_VOWEL_JP[i]; + if ( s == symbol ) { + return true; + } + } + for( int i = 0; i < _NUM_SYMBOL_CONSONANT_JP; i++ ){ + string s = _SYMBOL_CONSONANT_JP[i]; + if ( s == symbol ) { + return true; + } + } + for( int i = 0; i < _NUM_SYMBOL_EN; i++ ){ + string s = _SYMBOL_EN[i]; + if ( s == symbol ) { + return true; + } + } + return false; + } +}; + + +/// +/// VsqHandleɊi[̎̏NXB +/// +class Lyric { +private: + string m_phrase; + vector m_phonetic_symbol; + float d1; + vector m_consonant_adjustment; + bool m_protected; + + Lyric(){ + } + + /// + /// oCgsearch̒Ɋ܂܂oCgvaluëʒuT܂B + /// + /// Ώۂ̃oCg + /// oCg + /// value‚΂̃CfbNXA‚Ȃ-1Ԃ܂ + static int mIndexOf( vector search, vector value ) { + int i, j; + int search_length = search.size(); + int value_length = value.size(); + + // oCgтAΏۂ̃oCgт蒷ƂB + // ‚킯Ȃ + if ( value_length > search_length ) { + return -1; + } + + // i : ̊_ + for ( i = 0; i <= search_length - value_length; i++ ) { + bool failed = false; + for ( j = 0; j < value_length; j++ ) { + if ( search[i + j] != value[j] ) { + failed = true; + break; + } + } + if ( !failed ) { + return i; + } + } + return -1; + } + + + /// + /// vgo͉”\ǂ𔻒肵܂ + /// + /// + /// + static bool isprint( char ch ) { + if ( 32 <= (int)ch && (int)ch <= 126 ) { + return true; + } else { + return false; + } + } + +public: + bool PhoneticSymbolProtected() { + return m_protected; + } + + void PhoneticSymbolProtected( bool value ){ + m_protected = value; + } + + float UnknownFloat() { + return d1; + } + + void UnknownFloat( float value ){ + d1 = value; + } + + vector ConsonantAdjustment() { + return m_consonant_adjustment; + } + + /// + /// ̎ALw肵RXgN^ + /// + /// ̎ + /// L + Lyric( string phrase, string phonetic_symbol ) { + m_phrase = phrase; + PhoneticSymbol( phonetic_symbol ); + d1 = 0.000000f; + } + + /// + /// ̉̎̃t[Y擾܂͐ݒ肵܂B + /// + string Phrase() { + return m_phrase; + } + + void Phrase( string value ){ + m_phrase = value; + } + + /// + /// ̉̎̔L擾܂͐ݒ肵܂B + /// + string PhoneticSymbol() { + string ret = m_phonetic_symbol[0]; + for ( int i = 1; i < m_phonetic_symbol.size(); i++ ) { + ret += " " + m_phonetic_symbol[i]; + } + return ret; + } + + void PhoneticSymbol( string value ){ + string s = string_replace( value, " ", " " ); + m_phonetic_symbol = util_split( s, " " ); + for ( int i = 0; i < m_phonetic_symbol.size(); i++ ) { + m_phonetic_symbol[i] = string_replace( m_phonetic_symbol[i], "\\\\", "\\" ); + } + m_consonant_adjustment = vector( m_phonetic_symbol.size() ); + for ( int i = 0; i < m_phonetic_symbol.size(); i++ ) { + if ( VsqPhoneticSymbol::IsConsonant( m_phonetic_symbol[i] ) ) { + m_consonant_adjustment[i] = 64; + } else { + m_consonant_adjustment[i] = 0; + } + } + } + + vector PhoneticSymbolList(){ + vector ret = vector( m_phonetic_symbol.size() ); + for ( int i = 0; i < m_phonetic_symbol.size(); i++ ) { + ret[i] = m_phonetic_symbol[i]; + } + return ret; + } + + /// + /// 񂩂̃RXgN^ + /// + /// ̕ + Lyric( string _line ) { + if ( _line.length() <= 0 ) { + m_phrase = "a"; + PhoneticSymbol( "a" ); + d1 = 1.0f; + m_protected = false; + } else { + vector spl = util_split( _line, "," ); + int c_length = spl.size() - 3; + if ( spl.size() < 4 ) { + m_phrase = "a"; + PhoneticSymbol( "a" ); + d1 = 0.0f; + m_protected = false; + } else { + m_phrase = decode( spl[0] ); + PhoneticSymbol( decode( spl[1] ) ); + d1 = parse( spl[2] ); + m_protected = (spl[spl.size() - 1] == "0") ? false : true; + } + } + } + + /// + /// mIndexOf̃eXg\bhBsearch, value낢ςăeXg鎖B + /// + /// + static bool test_mIndexOf() { + vector search; + vector value; + unsigned char src_search[6] = { 0, 12, 3, 5, 16, 34 }; + unsigned char src_value[2] = { 16, 34 }; + for( int i = 0; i < 6; i++ ){ + search.push_back( src_search[i] ); + } + for( int i = 0; i < 2; i++ ){ + value.push_back( src_value[i] ); + } + if ( mIndexOf( search, value ) == 4 ) { + return true; + } else { + return false; + } + } + + /// + /// GXP[vꂽ\"A\x**𕜋A܂ + /// + /// fR[hΏۂ̕ + /// fR[h̕ + static string decode( string _string ) { + string result = _string; + result = string_replace( result, "\\\"", "" ); + vector str; + for( int i = 0; i < result.length(); i++ ){ + str.push_back( (unsigned char)result[i] ); + } + + vector x16; + string xx = "\\x"; + for( int i = 0; i < xx.length(); i++ ){ + x16.push_back( (unsigned char)xx[i] ); + } + int index = mIndexOf( str, x16 ); + while ( index >= 0 ) { + char chr_byte[2]; + chr_byte[0] = str[index + 2]; + chr_byte[1] = str[index + 3]; + string chr( chr_byte ); + char *endstr; + int chrcode = strtol( chr.c_str(), &endstr, 16 ); + str[index] = (byte)chrcode; + for ( int i = index + 4; i < str.size(); i++ ) { + str[i - 3] = str[i]; + } + int length = str.size() - 3; + vector new_str; + for ( int i = 0; i < length; i++ ) { + new_str.push_back( str[i] ); + } + Array.Resize( ref str, length ); + str = new_str; + index = mIndexOf( str, x16 ); + } + return cp932_convert( str ); + } + + + /// + /// ^ꂽ̒2oCg\x**̌`ɃGR[h܂B + /// + /// GR[hΏ + /// GR[h + static vector encode( string item ) { + //Encoding sjis = Encoding.GetEncoding( 932 ); + unsigned char[] bytea = cp932_convert( item );// sjis.GetBytes( item ); + string result = ""; + for ( int i = 0; i < bytea.Length; i++ ) { + if ( isprint( (char)bytea[i] ) ) { + result += (char)bytea[i]; + } else { + result += "\\x" + Convert.ToString( bytea[i], 16 ); + } + } + wchar_t[] res = result.ToCharArray(); + return res; + } + + + /// + /// ^ꂽShift_JISƂ݂ȂAbyte[]ɕϊchar[]ɕϊ̕Ԃ܂ + /// + /// ϊ̕ + /// ϊchar[] + static vector encodeEx( string item ) { + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] dat = cp932_convert( item );// sjis.GetBytes( item ); + char[] result = new char[dat.Length]; + for ( int i = 0; i < dat.Length; i++ ) { + result[i] = (char)dat[i]; + } + return result; + } + + + /// + /// ̃CX^X𕶎ɕϊ܂ + /// + /// 2oCgGR[h邩ۂw肷tO + /// ϊ̕ + string ToString( bool a_encode ) { + string result; + if ( a_encode ) { + string njp = new string( encode( this.Phrase ) ); + result = "\"" + njp + "\",\"" + this.PhoneticSymbol + "\"," + d1.ToString( "0.000000" ); + } else { + result = "\""; + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] dat = cp932.convert( this.Phrase );// sjis.GetBytes( this.Phrase ); + for ( int i = 0; i < dat.Length; i++ ) { + result += (char)dat[i]; + } + result += "\",\"" + this.PhoneticSymbol + "\"," + d1.ToString( "0.000000" ); + result = result.Replace( "\\\\", "\\" ); + } + for ( int i = 0; i < m_consonant_adjustment.Length; i++ ) { + result += "," + m_consonant_adjustment[i]; + } + if ( m_protected ) { + result += ",1"; + } else { + result += ",0"; + } + return result; + } + + /// + /// LyricCX^X\zeXgs܂ + /// + /// eXgɐtrueAłȂfalseԂ܂ + static bool test() { + string line = "\\\"\\x82\\xe7\\\",\\\"4 a\\\",1.000000,64,1,1"; + //Console.WriteLine( "Lyric.test; line=" + line ); + Lyric lyric( line ); + if ( lyric.Phrase == "" && + lyric.PhoneticSymbol == "4 a" && + lyric.d1 == 1.0 && + lyric.m_consonant_adjustment[0] == 64 && + lyric.m_consonant_adjustment[1] == 1 && + lyric.m_consonant_adjustment[2] == 1 ) { + return true; + } else { + return false; + } + } + +}; + +/// +/// nh舵܂BnhɂLyricHandleAVibratoHandleIconHandle +/// +class VsqHandle { +private: + VsqHandleType m_type; + /// + /// CX^XR\[ʂɏo͂܂ + /// + void Print() { + string result = this.ToString(); + Console.WriteLine( result ); + } +public: + int Index; + string IconID; + string IDS; + Lyric L0; + int Original; + string Caption; + int Length; + int StartDepth; + VibratoBPList DepthBP; + int StartRate; + VibratoBPList RateBP; +protected: + int m_language; + int m_program; + protected VsqHandle() { + } +public: + LyricHandle ConvertToLyricHandle() { + LyricHandle ret = new LyricHandle(); + ret.L0 = (Lyric)L0; + ret.m_type = m_type; + ret.Index = Index; + return ret; + } + + VibratoHandle ConvertToVibratoHandle() { + VibratoHandle ret = new VibratoHandle(); + ret.m_type = m_type; + ret.Index = Index; + ret.Caption = Caption; + ret.DepthBP = (VibratoBPList)DepthBP.Clone(); + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Length = Length; + ret.Original = Original; + ret.RateBP = (VibratoBPList)RateBP.Clone(); + ret.StartDepth = StartDepth; + ret.StartRate = StartRate; + return ret; + } + + IconHandle ConvertToIconHandle() { + IconHandle ret = new IconHandle(); + ret.m_type = m_type; + ret.Index = Index; + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Language( m_language ); + ret.Length = Length; + ret.Original = Original; + ret.Program( m_program ); + return ret; + } + + VsqHandleType type() { + return m_type; + } + + void type( VsqHandleType value ) { + m_type = value; + } + + /// + /// CX^XXg[ɏ݂܂B + /// encode=truȅꍇA2oCgGR[hďo͂܂B + /// + /// ݑΏ + /// 2oCgGR[h邩ۂw肷tO + void write( TextMemoryStream sw, bool encode ) { + sw.WriteLine( this.ToString( encode ) ); + } + + /// + /// FileStreamǂݍ݂ȂRXgNg + /// + /// ǂݍݑΏ + VsqHandle( TextMemoryStream sr, int value, ref string last_line ) { + this.Index = value; + string[] spl; + string[] spl2; + + // defaultlŔ~ + this.type( VsqHandleType.Vibrato ); + IconID = ""; + IDS = "normal"; + L0 = new Lyric( "" ); + Original = 0; + Caption = ""; + Length = 0; + StartDepth = 0; + DepthBP = null; + int depth_bp_num = 0; + StartRate = 0; + RateBP = null; + int rate_bp_num = 0; + m_language = 0; + m_program = 0; + + string tmpDepthBPX = ""; + string tmpDepthBPY = ""; + string tmpRateBPX = ""; + string tmpRateBPY = ""; + + // "["ɂԂ܂œǍ + last_line = sr.ReadLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Language": + m_language = int.Parse( spl[1] ); + break; + case "Program": + m_program = int.Parse( spl[1] ); + break; + case "IconID": + IconID = spl[1]; + break; + case "IDS": + IDS = spl[1]; + break; + case "Original": + Original = int.Parse( spl[1] ); + break; + case "Caption": + Caption = spl[1]; + for ( int i = 2; i < spl.Length; i++ ) { + Caption += "=" + spl[i]; + } + break; + case "Length": + Length = int.Parse( spl[1] ); + break; + case "StartDepth": + StartDepth = int.Parse( spl[1] ); + break; + case "DepthBPNum": + depth_bp_num = int.Parse( spl[1] ); + break; + case "DepthBPX": + tmpDepthBPX = spl[1]; + break; + case "DepthBPY": + tmpDepthBPY = spl[1]; + break; + case "StartRate": + StartRate = int.Parse( spl[1] ); + break; + case "RateBPNum": + rate_bp_num = int.Parse( spl[1] ); + break; + case "RateBPX": + tmpRateBPX = spl[1]; + break; + case "RateBPY": + tmpRateBPY = spl[1]; + break; + case "L0": + m_type = VsqHandleType.Lyric; + L0 = new Lyric( spl[1] ); + break; + } + if ( sr.Peek() < 0 ) { + break; + } + last_line = sr.ReadLine(); + } + if ( IDS != "normal" ) { + type( VsqHandleType.Singer ); + } else if ( IconID != "" ) { + type( VsqHandleType.Vibrato ); + } else { + type( VsqHandleType.Lyric ); + } + + // RateBPX, RateBPY̐ݒ + if ( this.type() == VsqHandleType.Vibrato ) { + if ( rate_bp_num > 0 ) { + float[] rate_bp_x = new float[rate_bp_num]; + spl2 = tmpRateBPX.Split( new char[] { ',' } ); + for ( int i = 0; i < rate_bp_num; i++ ) { + rate_bp_x[i] = float.Parse( spl2[i] ); + } + + int[] rate_bp_y = new int[rate_bp_num]; + spl2 = tmpRateBPY.Split( new char[] { ',' } ); + for ( int i = 0; i < rate_bp_num; i++ ) { + rate_bp_y[i] = int.Parse( spl2[i] ); + } + RateBP = new VibratoBPList( rate_bp_x, rate_bp_y ); + } else { + //m_rate_bp_x = null; + //m_rate_bp_y = null; + RateBP = new VibratoBPList(); + } + + // DepthBPX, DepthBPY̐ݒ + if ( depth_bp_num > 0 ) { + float[] depth_bp_x = new float[depth_bp_num]; + spl2 = tmpDepthBPX.Split( new char[] { ',' } ); + for ( int i = 0; i < depth_bp_num; i++ ) { + depth_bp_x[i] = float.Parse( spl2[i] ); + } + + int[] depth_bp_y = new int[depth_bp_num]; + spl2 = tmpDepthBPY.Split( new char[] { ',' } ); + for ( int i = 0; i < depth_bp_num; i++ ) { + depth_bp_y[i] = int.Parse( spl2[i] ); + } + DepthBP = new VibratoBPList( depth_bp_x, depth_bp_y ); + } else { + DepthBP = new VibratoBPList(); + //m_depth_bp_x = null; + //m_depth_bp_y = null; + } + } else { + DepthBP = new VibratoBPList(); + RateBP = new VibratoBPList(); + } + } + + /// + /// nhwqiႦ"h#0123"Ƃjnhԍ擾܂ + /// + /// nhwq + /// nhԍ + static int HandleIndexFromString( string _string ) { + string[] spl = _string.Split( new char[] { '#' } ); + return int.Parse( spl[1] ); + } + + + /// + /// CX^XeLXgt@Cɏo͂܂ + /// + /// o͐ + void Print( StreamWriter sw ) { + string result = this.ToString(); + sw.WriteLine( result ); + } + + /// + /// CX^X𕶎ɕϊ܂ + /// + /// 2oCgGR[h邩ۂw肷tO + /// CX^Xϊ + string ToString( bool encode ) { + string result = ""; + result += "[h#" + Index.ToString( "0000" ) + "]"; + switch ( type() ) { + case VsqHandleType.Lyric: + result += Environment.NewLine + "L0=" + L0.ToString( encode ); + break; + case VsqHandleType.Vibrato: + result += Environment.NewLine + "IconID=" + IconID + Environment.NewLine; + result += "IDS=" + IDS + Environment.NewLine; + result += "Original=" + Original + Environment.NewLine; + result += "Caption=" + Caption + Environment.NewLine; + result += "Length=" + Length + Environment.NewLine; + result += "StartDepth=" + StartDepth + Environment.NewLine; + result += "DepthBPNum=" + DepthBP.Num() + Environment.NewLine; + if ( DepthBP.Num() > 0 ) { + result += "DepthBPX=" + DepthBP.getElement( 0 ).X.ToString( "0.000000" ); + for ( int i = 1; i < DepthBP.Num(); i++ ) { + result += "," + DepthBP.getElement( i ).X.ToString( "0.000000" ); + } + result += Environment.NewLine + "DepthBPY=" + DepthBP.getElement( 0 ).Y; + for ( int i = 1; i < DepthBP.Num(); i++ ) { + result += "," + DepthBP.getElement( i ).Y; + } + result += Environment.NewLine; + } + result += "StartRate=" + StartRate + Environment.NewLine; + result += "RateBPNum=" + RateBP.Num(); + if ( RateBP.Num() > 0 ) { + result += Environment.NewLine + "RateBPX=" + RateBP.getElement( 0 ).X.ToString( "0.000000" ); + for ( int i = 1; i < RateBP.Num(); i++ ) { + result += "," + RateBP.getElement( i ).X.ToString( "0.000000" ); + } + result += Environment.NewLine + "RateBPY=" + RateBP.getElement( 0 ).Y; + for ( int i = 1; i < RateBP.Num(); i++ ) { + result += "," + RateBP.getElement( i ).Y; + } + } + break; + case VsqHandleType.Singer: + result += Environment.NewLine + "IconID=" + IconID + Environment.NewLine; + result += "IDS=" + IDS + Environment.NewLine; + result += "Original=" + Original + Environment.NewLine; + result += "Caption=" + Caption + Environment.NewLine; + result += "Length=" + Length + Environment.NewLine; + result += "Language=" + m_language + Environment.NewLine; + result += "Program=" + m_program; + break; + default: + break; + } + return result; + } +}; + + +class VsqID { +public: + int value; + VsqIDType type; + int IconHandle_index; + IconHandle IconHandle; + int Length; + int Note; + int Dynamics; + int PMBendDepth; + int PMBendLength; + int PMbPortamentoUse; + int DEMdecGainRate; + int DEMaccent; + int LyricHandle_index; + LyricHandle LyricHandle; + int VibratoHandle_index; + VibratoHandle VibratoHandle; + int VibratoDelay; + + static VsqID EOS( -1 ); + + /// + /// ID̔ԍiID#********jw肵RXgN^B + /// + /// ID̔ԍ + VsqID( int a_value ) { + value = a_value; + } + + + /// + /// eLXgt@C̃RXgN^ + /// + /// ǂݍݑΏ + /// + /// ǂݍ񂾍Ō̍sԂ܂ + VsqID( TextMemoryStream sr, int value, string& last_line ) { + string[] spl; + this.value = value; + this.type = VsqIDType.Unknown; + this.IconHandle_index = -2; + this.LyricHandle_index = -1; + this.VibratoHandle_index = -1; + this.Length = 0; + this.Note = 0; + this.Dynamics = 0; + this.PMBendDepth = 0; + this.PMBendLength = 0; + this.PMbPortamentoUse = 0; + this.DEMdecGainRate = 0; + this.DEMaccent = 0; + //this.LyricHandle_index = -2; + //this.VibratoHandle_index = -2; + this.VibratoDelay = 0; + last_line = sr.ReadLine(); + while ( !last_line.StartsWith( "[" ) ) { + spl = last_line.Split( new char[] { '=' } ); + switch ( spl[0] ) { + case "Type": + if ( spl[1] == "Anote" ) { + type = VsqIDType.Anote; + } else if ( spl[1] == "Singer" ) { + type = VsqIDType.Singer; + } else { + type = VsqIDType.Unknown; + } + break; + case "Length": + this.Length = int.Parse( spl[1] ); + break; + case "Note#": + this.Note = int.Parse( spl[1] ); + break; + case "Dynamics": + this.Dynamics = int.Parse( spl[1] ); + break; + case "PMBendDepth": + this.PMBendDepth = int.Parse( spl[1] ); + break; + case "PMBendLength": + this.PMBendLength = int.Parse( spl[1] ); + break; + case "DEMdecGainRate": + this.DEMdecGainRate = int.Parse( spl[1] ); + break; + case "DEMaccent": + this.DEMaccent = int.Parse( spl[1] ); + break; + case "LyricHandle": + this.LyricHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "IconHandle": + this.IconHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "VibratoHandle": + this.VibratoHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + break; + case "VibratoDelay": + this.VibratoDelay = int.Parse( spl[1] ); + break; + case "PMbPortamentoUse": + PMbPortamentoUse = int.Parse( spl[1] ); + break; + } + if ( sr.Peek() < 0 ) { + break; + } + last_line = sr.ReadLine(); + } + } + + string ToString() { + string ret = "{Type=" + type; + switch ( type ) { + case VsqIDType.Anote: + ret += ", Length=" + Length; + ret += ", Note#=" + Note; + ret += ", Dynamics=" + Dynamics; + ret += ", PMBendDepth=" + PMBendDepth ; + ret += ", PMBendLength=" + PMBendLength ; + ret += ", PMbPortamentoUse=" + PMbPortamentoUse ; + ret += ", DEMdecGainRate=" + DEMdecGainRate ; + ret += ", DEMaccent=" + DEMaccent ; + if ( LyricHandle != null ) { + ret += ", LyricHandle=h#" + LyricHandle_index.ToString( "0000" ) ; + } + if ( VibratoHandle != null ) { + ret += ", VibratoHandle=h#" + VibratoHandle_index.ToString( "0000" ); + ret += ", VibratoDelay=" + VibratoDelay ; + } + break; + case VsqIDType.Singer: + ret += ", IconHandle=h#" + IconHandle_index.ToString( "0000" ); + break; + } + ret += "}"; + return ret; + } + + + /// + /// CX^XeLXgt@Cɏo͂܂ + /// + /// o͐ + void write( TextMemoryStream sw ) { + sw.WriteLine( "[ID#" + value.ToString( "0000" ) + "]" ); + sw.WriteLine( "Type=" + type ); + switch( type ){ + case VsqIDType.Anote: + sw.WriteLine( "Length=" + Length ); + sw.WriteLine( "Note#=" + Note ); + sw.WriteLine( "Dynamics=" + Dynamics ); + sw.WriteLine( "PMBendDepth=" + PMBendDepth ); + sw.WriteLine( "PMBendLength=" + PMBendLength ); + sw.WriteLine( "PMbPortamentoUse=" + PMbPortamentoUse ); + sw.WriteLine( "DEMdecGainRate=" + DEMdecGainRate ); + sw.WriteLine( "DEMaccent=" + DEMaccent ); + if ( LyricHandle != null ) { + sw.WriteLine( "LyricHandle=h#" + LyricHandle_index.ToString( "0000" ) ); + } + if ( VibratoHandle != null ) { + sw.WriteLine( "VibratoHandle=h#" + VibratoHandle_index.ToString( "0000" ) ); + sw.WriteLine( "VibratoDelay=" + VibratoDelay ); + } + break; + case VsqIDType.Singer: + sw.WriteLine( "IconHandle=h#" + IconHandle_index.ToString( "0000" ) ); + break; + } + } +}; + +} +#endif // __libvsq_h__ diff --git a/trunk/Boare.Lib.Vsq/port_cpp/main.cpp b/trunk/Boare.Lib.Vsq/port_cpp/main.cpp new file mode 100644 index 0000000..eba7b38 --- /dev/null +++ b/trunk/Boare.Lib.Vsq/port_cpp/main.cpp @@ -0,0 +1,17 @@ +#include "libvsq.h" +#include + +using namespace std; +using namespace vsq; + +int main(){ + TextMemoryStream tms; + tms.WriteLine( "foo" ); + tms.WriteLine( "bar" ); + tms.Rewind(); + while( tms.Peek() >= 0 ){ + cout << tms.ReadLine() << endl; + } + tms.Close(); + return 0; +} diff --git a/trunk/LipSync/Background/Background.cs b/trunk/LipSync/Background/Background.cs new file mode 100644 index 0000000..7b573ce --- /dev/null +++ b/trunk/LipSync/Background/Background.cs @@ -0,0 +1,239 @@ +namespace Background { + + using System; + using System.Collections.Generic; + using System.Text; + using System.Windows.Forms; + using System.Drawing; + using System.Drawing.Imaging; + using System.IO; + using Plugin; + + public class Background : IPlugin { + + public void ApplyLanguage( string language_code ) { + + } + + /// + /// vOC̖ + /// + public string Name { + get { + return "Background"; + } + } + + /// + /// vOC̃^Cv\B + /// + public ulong Type { + get { + return Constants.LS_ENABLES_ENTRY_SETTING + Constants.LS_NO_EVENT_HANDLER; + } + } + + /// + /// vOC̊ȌȐB + /// + public string Abstract { + get { + return "摜zuvOCłBlXȓg܂B"; + } + } + + /// + /// CxgnhB̃vOC̐ݒ胁j[ꂽĂяo܂B + /// + /// + /// + public DialogResult BaseSetting() { + return DialogResult.Cancel; + } + + public DialogResult EntrySetting( ref string config ) { + EntryConfig cfg = new EntryConfig( config ); + DialogResult result; + using ( entry_config dlg = new entry_config( cfg ) ) { + result = dlg.ShowDialog(); + if ( result == DialogResult.OK ) { + cfg = dlg.Config; + config = cfg.ToString(); + } + } + return result; + } + + /// + /// ݒli[w肵܂B + /// + /// + public string Config { + get { + return ""; + } + set { + } + } + + private Bitmap m_bmp; + private string m_last_file = ""; + + /// + /// t[ɉH{֐ + /// + /// + /// + public void Apply( ref Bitmap bmp, float time, float e_begin, float e_end, ref string e_body ) { + EntryConfig cfg = new EntryConfig( e_body ); + if ( m_last_file != "" ) { + if ( m_last_file != cfg.File ) { + Image img = ImageFromFile( cfg.File ); + if ( img != null ) { + m_bmp = new Bitmap( img.Width, img.Height, PixelFormat.Format32bppArgb ); + using ( Graphics gx = Graphics.FromImage( m_bmp ) ) { + gx.DrawImage( img, 0, 0, img.Width, img.Height ); + } + } + m_last_file = cfg.File; + } + } else { + Image img = ImageFromFile( cfg.File ); + if ( img != null ) { + m_bmp = new Bitmap( img.Width, img.Height, PixelFormat.Format32bppArgb ); + using ( Graphics gx = Graphics.FromImage( m_bmp ) ) { + gx.DrawImage( img, 0, 0, img.Width, img.Height ); + } + } + } + float alpha = 1f; + if ( cfg.FadeIn ) { + float diff = time - e_begin; + if ( 0f <= diff && diff <= cfg.FadeInRatio ) { + alpha = 1.0f / cfg.FadeInRatio * diff; + } + } + if ( cfg.FadeOut ) { + float diff = e_end - time; + if ( 0f <= diff && diff <= cfg.FadeOutRatio ) { + alpha = 1.0f / cfg.FadeOutRatio * diff; + } + } + if ( m_bmp != null ) { + using ( Graphics g = Graphics.FromImage( bmp ) ) { + //g.DrawImage( m_bmp, cfg.X, cfg.Y, m_bmp.Width * cfg.Scale, m_bmp.Height * cfg.Scale ); + ColorMatrix cm = new ColorMatrix(); + cm.Matrix00 = 1; + cm.Matrix11 = 1; + cm.Matrix22 = 1; + cm.Matrix33 = alpha; + cm.Matrix44 = 1; + ImageAttributes ia = new ImageAttributes(); + ia.SetColorMatrix( cm ); + + int width = (int)(m_bmp.Width * cfg.Scale); + int height = (int)(m_bmp.Height * cfg.Scale); + int iwidth = m_bmp.Width; + int iheight = m_bmp.Height; + g.DrawImage( m_bmp, new Rectangle( cfg.X, cfg.Y, width, height ), + 0, 0, iwidth, iheight, GraphicsUnit.Pixel, ia ); + } + } + } + + /// + /// w肵pX̃t@CC[Wǂݍ݂܂ + /// + /// + /// + public static Image ImageFromFile( string fpath ) { + Image result = null; + if ( File.Exists( fpath ) ) { + using ( FileStream fs = new FileStream( fpath, FileMode.Open, FileAccess.Read ) ) { + result = Image.FromStream( fs ); + } + } + return result; + } + + public void Render( Graphics g, Size size, float time, string mouth, string reserved ) { + } + } + + + public struct EntryConfig { + public string File; + public bool FadeIn; + public bool FadeOut; + public int X; + public int Y; + public float Scale; + public float FadeInRatio; + public float FadeOutRatio; + public EntryConfig( string config ) { + string[] spl = config.Split( new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries ); + File = ""; + FadeIn = false; + FadeOut = false; + X = 0; + Y = 0; + Scale = 1f; + FadeInRatio = 2f; + FadeOutRatio = 2f; + foreach ( string entry in spl ) { + string[] spl2 = entry.Split( new char[] { '=' } ); + switch ( spl2[0] ) { + case "File": + File = spl2[1]; + break; + case "FadeIn": + if ( spl2[1] == TRUE ) { + FadeIn = true; + } else { + FadeIn = false; + } + break; + case "FadeOut": + if ( spl2[1] == TRUE ) { + FadeOut = true; + } else { + FadeOut = false; + } + break; + case "X": + X = int.Parse( spl2[1] ); + break; + case "Y": + Y = int.Parse( spl2[1] ); + break; + case "Scale": + Scale = float.Parse( spl2[1] ); + break; + case "FadeInRatio": + FadeInRatio = float.Parse( spl2[1] ); + break; + case "FadeOutRatio": + FadeOutRatio = float.Parse( spl2[1] ); + break; + } + } + } + private const string TRUE = "true"; + private const string FALSE = "false"; + new public string ToString() { + string fadein, fadeout; + if ( FadeIn ) { + fadein = TRUE; + } else { + fadein = FALSE; + } + if ( FadeOut ) { + fadeout = TRUE; + } else { + fadeout = FALSE; + } + return "File=" + File + "\nFadeIn=" + fadein + "\nFadeOut=" + fadeout + "\nX=" + X + "\nY=" + Y + "\nScale=" + Scale + "\nFadeInRatio=" + FadeInRatio + "\nFadeOutRatio=" + FadeOutRatio; + } + + } +} diff --git a/trunk/LipSync/Background/Background.csproj b/trunk/LipSync/Background/Background.csproj new file mode 100644 index 0000000..66cb9ae --- /dev/null +++ b/trunk/LipSync/Background/Background.csproj @@ -0,0 +1,77 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9} + Library + Properties + Background + Background + + + 2.0 + v3.5 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + Form + + + entry_config.cs + + + + + + Designer + entry_config.cs + + + + + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00} + IPlugin + + + + + + + + + \ No newline at end of file diff --git a/trunk/LipSync/Background/Properties/AssemblyInfo.cs b/trunk/LipSync/Background/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fe1e6fd --- /dev/null +++ b/trunk/LipSync/Background/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "Background" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "Background" )] +[assembly: AssemblyCopyright( "Copyright (C) 2008" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "8c648f56-5cc7-432d-a8a5-73ed17b699b1" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってリビジョンおよびビルド番号を +// 既定値にすることができます: +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/Background/entry_config.Designer.cs b/trunk/LipSync/Background/entry_config.Designer.cs new file mode 100644 index 0000000..37f8610 --- /dev/null +++ b/trunk/LipSync/Background/entry_config.Designer.cs @@ -0,0 +1,289 @@ +namespace Background { + partial class entry_config { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.txtFile = new System.Windows.Forms.TextBox(); + this.btnFile = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.txtX = new System.Windows.Forms.TextBox(); + this.txtY = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.dialogImage = new System.Windows.Forms.OpenFileDialog(); + this.label4 = new System.Windows.Forms.Label(); + this.txtScale = new System.Windows.Forms.TextBox(); + this.chkFadeIn = new System.Windows.Forms.CheckBox(); + this.chkFadeOut = new System.Windows.Forms.CheckBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.txtFadeOutRatio = new System.Windows.Forms.TextBox(); + this.txtFadeInRatio = new System.Windows.Forms.TextBox(); + this.label6 = new System.Windows.Forms.Label(); + this.label5 = new System.Windows.Forms.Label(); + this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.groupBox1.SuspendLayout(); + this.groupBox2.SuspendLayout(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 280, 238 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 21; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 181, 238 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 20; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 12, 15 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 63, 12 ); + this.label1.TabIndex = 22; + this.label1.Text = "画像ファイル"; + // + // txtFile + // + this.txtFile.Location = new System.Drawing.Point( 81, 12 ); + this.txtFile.Name = "txtFile"; + this.txtFile.Size = new System.Drawing.Size( 244, 19 ); + this.txtFile.TabIndex = 23; + // + // btnFile + // + this.btnFile.Location = new System.Drawing.Point( 331, 10 ); + this.btnFile.Name = "btnFile"; + this.btnFile.Size = new System.Drawing.Size( 24, 23 ); + this.btnFile.TabIndex = 24; + this.btnFile.Text = "..."; + this.btnFile.UseVisualStyleBackColor = true; + this.btnFile.Click += new System.EventHandler( this.btnFile_Click ); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point( 12, 24 ); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size( 12, 12 ); + this.label2.TabIndex = 25; + this.label2.Text = "X"; + // + // txtX + // + this.txtX.Location = new System.Drawing.Point( 30, 21 ); + this.txtX.Name = "txtX"; + this.txtX.Size = new System.Drawing.Size( 100, 19 ); + this.txtX.TabIndex = 26; + this.txtX.Text = "0"; + // + // txtY + // + this.txtY.Location = new System.Drawing.Point( 213, 21 ); + this.txtY.Name = "txtY"; + this.txtY.Size = new System.Drawing.Size( 100, 19 ); + this.txtY.TabIndex = 28; + this.txtY.Text = "0"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point( 195, 24 ); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size( 12, 12 ); + this.label3.TabIndex = 27; + this.label3.Text = "Y"; + // + // dialogImage + // + this.dialogImage.Filter = "Image Files|*.bmp;*.png;*.jpg|All Files|*.*"; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point( 12, 60 ); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size( 53, 12 ); + this.label4.TabIndex = 29; + this.label4.Text = "表示倍率"; + // + // txtScale + // + this.txtScale.Location = new System.Drawing.Point( 71, 57 ); + this.txtScale.Name = "txtScale"; + this.txtScale.Size = new System.Drawing.Size( 100, 19 ); + this.txtScale.TabIndex = 30; + this.txtScale.Text = "1.0"; + // + // chkFadeIn + // + this.chkFadeIn.AutoSize = true; + this.chkFadeIn.Location = new System.Drawing.Point( 18, 24 ); + this.chkFadeIn.Name = "chkFadeIn"; + this.chkFadeIn.Size = new System.Drawing.Size( 76, 16 ); + this.chkFadeIn.TabIndex = 31; + this.chkFadeIn.Text = "フェードイン"; + this.chkFadeIn.UseVisualStyleBackColor = true; + this.chkFadeIn.CheckedChanged += new System.EventHandler( this.chkFadeIn_CheckedChanged ); + // + // chkFadeOut + // + this.chkFadeOut.AutoSize = true; + this.chkFadeOut.Location = new System.Drawing.Point( 18, 59 ); + this.chkFadeOut.Name = "chkFadeOut"; + this.chkFadeOut.Size = new System.Drawing.Size( 84, 16 ); + this.chkFadeOut.TabIndex = 32; + this.chkFadeOut.Text = "フェードアウト"; + this.chkFadeOut.UseVisualStyleBackColor = true; + this.chkFadeOut.CheckedChanged += new System.EventHandler( this.chkFadeOut_CheckedChanged ); + // + // groupBox1 + // + this.groupBox1.Controls.Add( this.txtFadeOutRatio ); + this.groupBox1.Controls.Add( this.txtFadeInRatio ); + this.groupBox1.Controls.Add( this.label6 ); + this.groupBox1.Controls.Add( this.label5 ); + this.groupBox1.Controls.Add( this.chkFadeIn ); + this.groupBox1.Controls.Add( this.chkFadeOut ); + this.groupBox1.Location = new System.Drawing.Point( 12, 136 ); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size( 343, 90 ); + this.groupBox1.TabIndex = 33; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Fade IN/OUT"; + // + // txtFadeOutRatio + // + this.txtFadeOutRatio.Enabled = false; + this.txtFadeOutRatio.Location = new System.Drawing.Point( 227, 57 ); + this.txtFadeOutRatio.Name = "txtFadeOutRatio"; + this.txtFadeOutRatio.Size = new System.Drawing.Size( 103, 19 ); + this.txtFadeOutRatio.TabIndex = 36; + // + // txtFadeInRatio + // + this.txtFadeInRatio.Enabled = false; + this.txtFadeInRatio.Location = new System.Drawing.Point( 227, 22 ); + this.txtFadeInRatio.Name = "txtFadeInRatio"; + this.txtFadeInRatio.Size = new System.Drawing.Size( 103, 19 ); + this.txtFadeInRatio.TabIndex = 35; + // + // label6 + // + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point( 138, 60 ); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size( 83, 12 ); + this.label6.TabIndex = 34; + this.label6.Text = "効果時間(秒):"; + // + // label5 + // + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point( 138, 25 ); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size( 83, 12 ); + this.label5.TabIndex = 33; + this.label5.Text = "効果時間(秒):"; + // + // groupBox2 + // + this.groupBox2.Controls.Add( this.txtScale ); + this.groupBox2.Controls.Add( this.label4 ); + this.groupBox2.Controls.Add( this.txtX ); + this.groupBox2.Controls.Add( this.label2 ); + this.groupBox2.Controls.Add( this.txtY ); + this.groupBox2.Controls.Add( this.label3 ); + this.groupBox2.Location = new System.Drawing.Point( 12, 37 ); + this.groupBox2.Name = "groupBox2"; + this.groupBox2.Size = new System.Drawing.Size( 343, 93 ); + this.groupBox2.TabIndex = 34; + this.groupBox2.TabStop = false; + this.groupBox2.Text = "Position and Scale"; + // + // entry_config + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 369, 273 ); + this.Controls.Add( this.groupBox2 ); + this.Controls.Add( this.groupBox1 ); + this.Controls.Add( this.btnFile ); + this.Controls.Add( this.txtFile ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "entry_config"; + this.ShowInTaskbar = false; + this.Text = "EntryConfig"; + this.groupBox1.ResumeLayout( false ); + this.groupBox1.PerformLayout(); + this.groupBox2.ResumeLayout( false ); + this.groupBox2.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox txtFile; + private System.Windows.Forms.Button btnFile; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtX; + private System.Windows.Forms.TextBox txtY; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.OpenFileDialog dialogImage; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.TextBox txtScale; + private System.Windows.Forms.CheckBox chkFadeIn; + private System.Windows.Forms.CheckBox chkFadeOut; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox txtFadeOutRatio; + private System.Windows.Forms.TextBox txtFadeInRatio; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.GroupBox groupBox2; + } +} \ No newline at end of file diff --git a/trunk/LipSync/Background/entry_config.cs b/trunk/LipSync/Background/entry_config.cs new file mode 100644 index 0000000..15707eb --- /dev/null +++ b/trunk/LipSync/Background/entry_config.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace Background { + public partial class entry_config : Form { + EntryConfig m_entry_config; + public entry_config( EntryConfig config ) { + InitializeComponent(); + m_entry_config = config; + txtFile.Text = m_entry_config.File; + txtX.Text = m_entry_config.X.ToString(); + txtY.Text = m_entry_config.Y.ToString(); + txtScale.Text = m_entry_config.Scale.ToString(); + chkFadeIn.Checked = m_entry_config.FadeIn; + chkFadeOut.Checked = m_entry_config.FadeOut; + txtFadeInRatio.Text = m_entry_config.FadeInRatio.ToString(); + txtFadeOutRatio.Text = m_entry_config.FadeOutRatio.ToString(); + } + + private void btnFile_Click( object sender, EventArgs e ) { + if ( dialogImage.ShowDialog() == DialogResult.OK ) { + txtFile.Text = dialogImage.FileName; + } + } + + + private void btnOK_Click( object sender, EventArgs e ) { + EntryConfig old = m_entry_config; + try { + m_entry_config.File = txtFile.Text; + m_entry_config.X = int.Parse( txtX.Text ); + m_entry_config.Y = int.Parse( txtY.Text ); + m_entry_config.Scale = float.Parse( txtScale.Text ); + m_entry_config.FadeIn = chkFadeIn.Checked; + m_entry_config.FadeOut = chkFadeOut.Checked; + m_entry_config.FadeInRatio = float.Parse( txtFadeInRatio.Text ); + m_entry_config.FadeOutRatio = float.Parse( txtFadeOutRatio.Text ); + if ( m_entry_config.FadeInRatio <= 0f ) { + m_entry_config.FadeIn = false; + m_entry_config.FadeInRatio = 2f; + } + if ( m_entry_config.FadeOutRatio <= 0f ) { + m_entry_config.FadeOut = false; + m_entry_config.FadeOutRatio = 2f; + } + this.DialogResult = DialogResult.OK; + } catch { + m_entry_config = old; + this.DialogResult = DialogResult.Cancel; + } + } + + + public EntryConfig Config { + get { + return m_entry_config; + } + } + + + private void chkFadeIn_CheckedChanged( object sender, EventArgs e ) { + txtFadeInRatio.Enabled = chkFadeIn.Checked; + } + + + private void chkFadeOut_CheckedChanged( object sender, EventArgs e ) { + txtFadeOutRatio.Enabled = chkFadeOut.Checked; + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/Background/entry_config.resx b/trunk/LipSync/Background/entry_config.resx new file mode 100644 index 0000000..0101e26 --- /dev/null +++ b/trunk/LipSync/Background/entry_config.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/trunk/LipSync/Background/makefile b/trunk/LipSync/Background/makefile new file mode 100644 index 0000000..f6db45a --- /dev/null +++ b/trunk/LipSync/Background/makefile @@ -0,0 +1,10 @@ +RM=rm +CP=cp + +Background.dll: Background.cs entry_config.cs entry_config.Designer.cs IPlugin.dll + gmcs -target:library -out:Background.dll \ + -r:System.Windows.Forms,System.Drawing,IPlugin.dll \ + Background.cs entry_config.cs entry_config.Designer.cs + +clean: + $(RM) Background.dll IPlugin.dll diff --git a/trunk/LipSync/DevUtl/DevUtl.csproj b/trunk/LipSync/DevUtl/DevUtl.csproj new file mode 100644 index 0000000..246c80b --- /dev/null +++ b/trunk/LipSync/DevUtl/DevUtl.csproj @@ -0,0 +1,65 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {A7798205-28BD-4DCD-A4EC-56FD23EE7AB9} + Exe + Properties + DevUtl + DevUtl + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + {0C58B068-272F-4390-A14F-3D72AFCF3DFB} + Boare.Lib.AppUtil + + + + + \ No newline at end of file diff --git a/trunk/LipSync/DevUtl/Program.cs b/trunk/LipSync/DevUtl/Program.cs new file mode 100644 index 0000000..7c954c3 --- /dev/null +++ b/trunk/LipSync/DevUtl/Program.cs @@ -0,0 +1,139 @@ +//#define BINARYFILE_TO_BYTEARRAY +#define BINARYFILE_TO_BASE64 +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +using Boare.Lib.AppUtil; + +namespace DevUtl { + class Program { + static void Main( string[] args ) { +#if BINARYFILE_TO_BASE64 + Console.WriteLine( "BINARYFILE_TO_BASE64" ); + if ( args.Length < 1 ) { + Console.WriteLine( "error; too few arguments" ); + return; + } + if ( !File.Exists( args[0] ) ) { + Console.WriteLine( "error; file not found" ); + return; + } + string str = ""; + using ( FileStream fs = new FileStream( args[0], FileMode.Open ) ) { + byte[] b = new byte[fs.Length]; + fs.Read( b, 0, b.Length ); + str = Convert.ToBase64String( b ); + } + int length = str.Length; + int split_length = 100; + Console.Write( "string foo = " ); + uint count = 0; + while ( length > 0 ) { + count++; + string pref = " "; + if ( count == 1 ) { + pref = ""; + } + if ( length < split_length ) { + Console.WriteLine( pref + "\"" + str + "\";" ); + break; + } else { + string part = str.Substring( 0, split_length ); + str = str.Substring( split_length ); + length = str.Length; + Console.WriteLine( pref + "\"" + part + "\" +" ); + } + } +#endif +#if BINARYFILE_TO_BYTEARRAY + Console.WriteLine( "BINARYFILE_TO_BYTEARRAY" ); + if ( args.Length < 2 ) { + Console.WriteLine( "error; too few arguments" ); + return; + } + if ( !File.Exists( args[0] ) ) { + Console.WriteLine( "error; file not found" ); + return; + } + byte[] hoge = new byte[] { 0x00, 0x01, }; + using ( StreamWriter sw = new StreamWriter( args[1], false, Encoding.UTF8 ) ) { + sw.Write( "byte[] foo = new byte[] { " ); + bool first = true; + using ( FileStream fs = new FileStream( args[0], FileMode.Open ) ) { + const int BUF = 20; + byte[] buffer = new byte[BUF]; + while ( true ) { + int len = fs.Read( buffer, 0, BUF ); + if ( len <= 0 ) { + break; + } + if ( first ) { + first = false; + } else { + sw.WriteLine(); + sw.Write( " " ); + } + for ( int i = 0; i < len; i++ ) { + sw.Write( "0x" + Convert.ToString( buffer[i], 16 ) + ", " ); + } + } + } + sw.WriteLine( "};" ); + } +#else +#if LANGUAGE_FILE_CONVERSION + Console.WriteLine( "LANGUAGE_FILE_CONVERSION" ); + //Console.WriteLine( "input the name of message definition file" ); + string msg_dat = @"C:\cvs\lipsync\LipSync\en.lang";// Console.ReadLine(); + Dictionary dict = new Dictionary(); + using ( StreamReader sr = new StreamReader( msg_dat ) ) { + while ( sr.Peek() >= 0 ) { + string line = sr.ReadLine(); + if ( line.StartsWith( "#" ) ) { + continue; + } + string[] spl = line.Split( "\t".ToCharArray() ); + dict.Add( spl[0], spl[1] ); + } + } + + while ( true ) { + Console.WriteLine( "input edit target file" ); + string cs = Console.ReadLine(); + string new_file = Path.Combine( Path.GetDirectoryName( cs ), Path.GetFileNameWithoutExtension( cs ) + "_.tmp" ); + using ( StreamWriter sw = new StreamWriter( new_file ) ) + using ( StreamReader sr = new StreamReader( cs ) ) { + while ( sr.Peek() >= 0 ) { + sw.WriteLine( sr.ReadLine() ); + } + } + + using ( StreamWriter sw = new StreamWriter( cs ) ) + using ( StreamReader sr = new StreamReader( new_file ) ) { + while ( sr.Peek() >= 0 ) { + string line = sr.ReadLine(); + int index = line.IndexOf( "Messaging.GetMessage( MessageID." ); + if ( index >= 0 ) { + while ( index >= 0 ) { + int right = line.IndexOf( ")", index ); + string item = line.Substring( index + 32, right - (index + 32) ); + item = item.Trim(); + Console.WriteLine( "item=\"" + item + "\"" ); + string new_line = line.Substring( 0, index ) + "_( \"" + dict[item] + "\" )" + line.Substring( right + 1 ); + line = new_line; + index = line.IndexOf( "Messaging.GetMessage( MessageID." ); + } + sw.WriteLine( line ); + } else { + sw.WriteLine( line ); + } + } + } + } +#endif +#endif + } + } +} diff --git a/trunk/LipSync/DevUtl/Properties/AssemblyInfo.cs b/trunk/LipSync/DevUtl/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..fa46fdf --- /dev/null +++ b/trunk/LipSync/DevUtl/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "DevUtl" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "" )] +[assembly: AssemblyProduct( "DevUtl" )] +[assembly: AssemblyCopyright( "Copyright © 2008" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "568982bb-45a8-4ebc-bf4f-e3d4d4606b1d" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/IPlugin/AviReader.cs b/trunk/LipSync/IPlugin/AviReader.cs new file mode 100644 index 0000000..1be5ee4 --- /dev/null +++ b/trunk/LipSync/IPlugin/AviReader.cs @@ -0,0 +1,483 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.Runtime.InteropServices; +using System.IO; + +namespace Plugin { + + public class Avi { + + public const int StreamtypeVIDEO = 1935960438; //mmioStringToFOURCC("vids", 0) + public const int OF_SHARE_DENY_WRITE = 32; + public const int BMP_MAGIC_COOKIE = 19778; //ascii string "BM" + + #region structure declarations + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct RECT { + public UInt32 left; + public UInt32 top; + public UInt32 right; + public UInt32 bottom; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct BITMAPINFOHEADER { + public UInt32 biSize; + public Int32 biWidth; + public Int32 biHeight; + public Int16 biPlanes; + public Int16 biBitCount; + public UInt32 biCompression; + public UInt32 biSizeImage; + public Int32 biXPelsPerMeter; + public Int32 biYPelsPerMeter; + public UInt32 biClrUsed; + public UInt32 biClrImportant; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct AVISTREAMINFO { + public UInt32 fccType; + public UInt32 fccHandler; + public UInt32 dwFlags; + public UInt32 dwCaps; + public UInt16 wPriority; + public UInt16 wLanguage; + public UInt32 dwScale; + public UInt32 dwRate; + public UInt32 dwStart; + public UInt32 dwLength; + public UInt32 dwInitialFrames; + public UInt32 dwSuggestedBufferSize; + public UInt32 dwQuality; + public UInt32 dwSampleSize; + public RECT rcFrame; + public UInt32 dwEditCount; + public UInt32 dwFormatChangeCount; + [MarshalAs( UnmanagedType.ByValArray, SizeConst = 64 )] + public UInt16[] szName; + } + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct BITMAPFILEHEADER { + public Int16 bfType; //"magic cookie" - must be "BM" + public Int32 bfSize; + public Int16 bfReserved1; + public Int16 bfReserved2; + public Int32 bfOffBits; + } + + #endregion structure declarations + + #region method declarations + + //Initialize the AVI library + [DllImport( "avifil32.dll" )] + public static extern void AVIFileInit(); + + //Open an AVI file + [DllImport( "avifil32.dll", PreserveSig = true )] + public static extern int AVIFileOpen( + ref int ppfile, + String szFile, + int uMode, + int pclsidHandler ); + + //Get a stream from an open AVI file + [DllImport( "avifil32.dll" )] + public static extern int AVIFileGetStream( + int pfile, + out IntPtr ppavi, + int fccType, + int lParam ); + + //Get the start position of a stream + [DllImport( "avifil32.dll", PreserveSig = true )] + public static extern int AVIStreamStart( int pavi ); + + //Get the length of a stream in frames + [DllImport( "avifil32.dll", PreserveSig = true )] + public static extern int AVIStreamLength( int pavi ); + + //Get information about an open stream + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamInfo( + int pAVIStream, + ref AVISTREAMINFO psi, + int lSize ); + + //Get a pointer to a GETFRAME object (returns 0 on error) + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrameOpen( + IntPtr pAVIStream, + ref BITMAPINFOHEADER bih ); + + /*[DllImport("avifil32.dll")] + public static extern int AVIStreamGetFrameOpen( + IntPtr pAVIStream, + int dummy);*/ + + //Get a pointer to a packed DIB (returns 0 on error) + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrame( + int pGetFrameObj, + int lPos ); + + //Create a new stream in an open AVI file + [DllImport( "avifil32.dll" )] + public static extern int AVIFileCreateStream( + int pfile, + out IntPtr ppavi, + ref AVISTREAMINFO ptr_streaminfo ); + + //Set the format for a new stream + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamSetFormat( + IntPtr aviStream, Int32 lPos, + ref BITMAPINFOHEADER lpFormat, Int32 cbFormat ); + + //Write a sample to a stream + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamWrite( + IntPtr aviStream, Int32 lStart, Int32 lSamples, + IntPtr lpBuffer, Int32 cbBuffer, Int32 dwFlags, + Int32 dummy1, Int32 dummy2 ); + + //Release the GETFRAME object + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamGetFrameClose( + int pGetFrameObj ); + + //Release an open AVI stream + [DllImport( "avifil32.dll" )] + public static extern int AVIStreamRelease( IntPtr aviStream ); + + //Release an open AVI file + [DllImport( "avifil32.dll" )] + public static extern int AVIFileRelease( int pfile ); + + //Close the AVI library + [DllImport( "avifil32.dll" )] + public static extern void AVIFileExit(); + + #endregion methos declarations + + #region other useful avi functions + + //public const int StreamtypeAUDIO = 1935963489; //mmioStringToFOURCC("auds", 0) + //public const int StreamtypeMIDI = 1935960429; //mmioStringToFOURCC("mids", 0) + //public const int StreamtypeTEXT = 1937012852; //mmioStringToFOURCC("txts", 0) + + /*[StructLayout(LayoutKind.Sequential, Pack=1)] + public struct AVIFILEINFO{ + public Int32 dwMaxBytesPerSecond; + public Int32 dwFlags; + public Int32 dwCaps; + public Int32 dwStreams; + public Int32 dwSuggestedBufferSize; + public Int32 dwWidth; + public Int32 dwHeight; + public Int32 dwScale; + public Int32 dwRate; + public Int32 dwLength; + public Int32 dwEditCount; + [MarshalAs(UnmanagedType.ByValArray, SizeConst=64)] + public char[] szFileType; + }*/ + + /*[StructLayout(LayoutKind.Sequential, Pack=1)] + public struct AVICOMPRESSOPTIONS { + public UInt32 fccType; + public UInt32 fccHandler; + public UInt32 dwKeyFrameEvery; // only used with AVICOMRPESSF_KEYFRAMES + public UInt32 dwQuality; + public UInt32 dwBytesPerSecond; // only used with AVICOMPRESSF_DATARATE + public UInt32 dwFlags; + public IntPtr lpFormat; + public UInt32 cbFormat; + public IntPtr lpParms; + public UInt32 cbParms; + public UInt32 dwInterleaveEvery; + }*/ + + /*[DllImport("avifil32.dll")] + public static extern int AVIMakeCompressedStream( + out IntPtr ppsCompressed, IntPtr aviStream, + ref AVICOMPRESSOPTIONS ao, int dummy);*/ + + /*[DllImport("avifil32.dll")] + public static extern int AVISaveOptions( + IntPtr hWnd, + int uiFlags, + int nStreams, + ref IntPtr ppavi, + ref IntPtr ppOptions);*/ + + /*[DllImport("avifil32.dll")] + public static extern int AVIFileInfo( + int pfile, + ref AVIFILEINFO pfi, + int lSize);*/ + + /*[DllImport("winmm.dll", EntryPoint="mmioStringToFOURCCA")] + public static extern int mmioStringToFOURCC(String sz, int uFlags);*/ + + /*[DllImport("avifil32.dll")] + public static extern int AVIStreamRead( + IntPtr pavi, + Int32 lStart, + Int32 lSamples, + IntPtr lpBuffer, + Int32 cbBuffer, + Int32 plBytes, + Int32 plSamples + );*/ + + #endregion other useful avi functions + + } + + /// Extract bitmaps from AVI files + public class AviReader { + + //position of the first frame, count of frames in the stream + private int firstFrame = 0, countFrames = 0; + //pointers + private int aviFile = 0; + private int getFrameObject; + private IntPtr aviStream; + //stream and header info + private Avi.AVISTREAMINFO streamInfo; + + public int CountFrames { + get { + return countFrames; + } + } + + public UInt32 FrameRate { + get { + return streamInfo.dwRate / streamInfo.dwScale; + } + } + + public Size BitmapSize { + get { + return new Size( (int)streamInfo.rcFrame.right, (int)streamInfo.rcFrame.bottom ); + } + } + + /// Opens an AVI file and creates a GetFrame object + /// Name of the AVI file + public void Open( string fileName ) { + //Intitialize AVI library + Avi.AVIFileInit(); + + //Open the file + int result = Avi.AVIFileOpen( + ref aviFile, fileName, + Avi.OF_SHARE_DENY_WRITE, 0 ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIFileOpen: " + result.ToString() ); + } + + //Get the video stream + result = Avi.AVIFileGetStream( + aviFile, + out aviStream, + Avi.StreamtypeVIDEO, 0 ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIFileGetStream: " + result.ToString() ); + } + + firstFrame = Avi.AVIStreamStart( aviStream.ToInt32() ); + countFrames = Avi.AVIStreamLength( aviStream.ToInt32() ); + + streamInfo = new Avi.AVISTREAMINFO(); + result = Avi.AVIStreamInfo( aviStream.ToInt32(), ref streamInfo, Marshal.SizeOf( streamInfo ) ); + + if ( result != 0 ) { + throw new Exception( "Exception in AVIStreamInfo: " + result.ToString() ); + } + + //Open frames + + Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); + bih.biBitCount = 24; + bih.biClrImportant = 0; + bih.biClrUsed = 0; + bih.biCompression = 0; //BI_RGB; + bih.biHeight = (Int32)streamInfo.rcFrame.bottom; + bih.biWidth = (Int32)streamInfo.rcFrame.right; + bih.biPlanes = 1; + bih.biSize = (UInt32)Marshal.SizeOf( bih ); + bih.biXPelsPerMeter = 0; + bih.biYPelsPerMeter = 0; + + getFrameObject = Avi.AVIStreamGetFrameOpen( aviStream, ref bih ); //force function to return 24bit DIBS + //getFrameObject = Avi.AVIStreamGetFrameOpen(aviStream, 0); //return any bitmaps + if ( getFrameObject == 0 ) { + throw new Exception( "Exception in AVIStreamGetFrameOpen!" ); + } + } + + /// Closes all streams, files and libraries + public void Close() { + if ( getFrameObject != 0 ) { + Avi.AVIStreamGetFrameClose( getFrameObject ); + getFrameObject = 0; + } + if ( aviStream != IntPtr.Zero ) { + Avi.AVIStreamRelease( aviStream ); + aviStream = IntPtr.Zero; + } + if ( aviFile != 0 ) { + Avi.AVIFileRelease( aviFile ); + aviFile = 0; + } + Avi.AVIFileExit(); + } + + + public Bitmap Export( int position ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + + //Decompress the frame and return a pointer to the DIB + int pDib = Avi.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + //Copy the bitmap header into a managed struct + Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); + bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + + /*if(bih.biBitCount < 24){ + throw new Exception("Not enough colors! DIB color depth is less than 24 bit."); + }else */ + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + + //Copy the image + byte[] bitmapData = new byte[bih.biSizeImage]; + int address = pDib + Marshal.SizeOf( bih ); + for ( int offset = 0; offset < bitmapData.Length; offset++ ) { + bitmapData[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Copy bitmap info + byte[] bitmapInfo = new byte[Marshal.SizeOf( bih )]; + IntPtr ptr; + ptr = Marshal.AllocHGlobal( bitmapInfo.Length ); + Marshal.StructureToPtr( bih, ptr, false ); + address = ptr.ToInt32(); + for ( int offset = 0; offset < bitmapInfo.Length; offset++ ) { + bitmapInfo[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Create file header + Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER(); + bfh.bfType = Avi.BMP_MAGIC_COOKIE; + bfh.bfSize = (Int32)(55 + bih.biSizeImage); //size of file as written to disk + bfh.bfReserved1 = 0; + bfh.bfReserved2 = 0; + bfh.bfOffBits = Marshal.SizeOf( bih ) + Marshal.SizeOf( bfh ); + + //Create or overwrite the destination file + MemoryStream fs = new MemoryStream(); + //FileStream fs = new FileStream( dstFileName, System.IO.FileMode.Create ); + BinaryWriter bw = new BinaryWriter( fs ); + + //Write header + bw.Write( bfh.bfType ); + bw.Write( bfh.bfSize ); + bw.Write( bfh.bfReserved1 ); + bw.Write( bfh.bfReserved2 ); + bw.Write( bfh.bfOffBits ); + //Write bitmap info + bw.Write( bitmapInfo ); + //Write bitmap data + bw.Write( bitmapData ); + bw.Close(); +// fs.Close(); + fs.Flush(); + + fs.Seek( 0, SeekOrigin.Begin ); + Bitmap bmp = new Bitmap( fs ); + fs.Close(); + return bmp; + } + + + /// Exports a frame into a bitmap file + /// Position of the frame + /// Name ofthe file to store the bitmap + public void ExportBitmap( int position, String dstFileName ) { + if ( position > countFrames ) { + throw new Exception( "Invalid frame position" ); + } + + //Decompress the frame and return a pointer to the DIB + int pDib = Avi.AVIStreamGetFrame( getFrameObject, firstFrame + position ); + //Copy the bitmap header into a managed struct + Avi.BITMAPINFOHEADER bih = new Avi.BITMAPINFOHEADER(); + bih = (Avi.BITMAPINFOHEADER)Marshal.PtrToStructure( new IntPtr( pDib ), bih.GetType() ); + + /*if(bih.biBitCount < 24){ + throw new Exception("Not enough colors! DIB color depth is less than 24 bit."); + }else */ + if ( bih.biSizeImage < 1 ) { + throw new Exception( "Exception in AVIStreamGetFrame: Not bitmap decompressed." ); + } + + //Copy the image + byte[] bitmapData = new byte[bih.biSizeImage]; + int address = pDib + Marshal.SizeOf( bih ); + for ( int offset = 0; offset < bitmapData.Length; offset++ ) { + bitmapData[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Copy bitmap info + byte[] bitmapInfo = new byte[Marshal.SizeOf( bih )]; + IntPtr ptr; + ptr = Marshal.AllocHGlobal( bitmapInfo.Length ); + Marshal.StructureToPtr( bih, ptr, false ); + address = ptr.ToInt32(); + for ( int offset = 0; offset < bitmapInfo.Length; offset++ ) { + bitmapInfo[offset] = Marshal.ReadByte( new IntPtr( address ) ); + address++; + } + + //Create file header + Avi.BITMAPFILEHEADER bfh = new Avi.BITMAPFILEHEADER(); + bfh.bfType = Avi.BMP_MAGIC_COOKIE; + bfh.bfSize = (Int32)(55 + bih.biSizeImage); //size of file as written to disk + bfh.bfReserved1 = 0; + bfh.bfReserved2 = 0; + bfh.bfOffBits = Marshal.SizeOf( bih ) + Marshal.SizeOf( bfh ); + + //Create or overwrite the destination file + FileStream fs = new FileStream( dstFileName, System.IO.FileMode.Create ); + BinaryWriter bw = new BinaryWriter( fs ); + + //Write header + bw.Write( bfh.bfType ); + bw.Write( bfh.bfSize ); + bw.Write( bfh.bfReserved1 ); + bw.Write( bfh.bfReserved2 ); + bw.Write( bfh.bfOffBits ); + //Write bitmap info + bw.Write( bitmapInfo ); + //Write bitmap data + bw.Write( bitmapData ); + bw.Close(); + fs.Close(); + } + } + +} diff --git a/trunk/LipSync/IPlugin/IPlugin.cs b/trunk/LipSync/IPlugin/IPlugin.cs new file mode 100644 index 0000000..b0a2764 --- /dev/null +++ b/trunk/LipSync/IPlugin/IPlugin.cs @@ -0,0 +1,129 @@ +/* + * IPlugin.cs + * Copyright (c) 2007, 2008 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Windows.Forms; + +namespace Plugin { + + + public class Constants { + /// + /// エントリーごとの設定が可能なプラグインであることを表します。 + /// + public const ulong LS_ENABLES_ENTRY_SETTING = 1; + /// + /// このプラグインが、設定用ウィンドウを持たないことを表します。 + /// + public const ulong LS_NO_EVENT_HANDLER = 2; + /// + /// このプラグインが、キャラクタ描画用のプラグインであることを表します。 + /// + public const ulong LS_TYPE_CHARACTER = 4; + } + + + /// + /// メイン画面で使用されている変数へのプロキシを提供 + /// + public class Proxy { + + } + + + /// + /// プラグイン用のインターフェースを定義します + /// + public interface IPlugin { + + /// + /// プラグインの名称 + /// + string Name { + get; + } + + + /// + /// プラグインの簡潔な説明文。 + /// + string Abstract { + get; + } + + + /// + /// フレームに加工を施す関数 + /// + /// 加工の対象 + /// ビデオの先頭からの時刻(秒) + /// エントリの開始時刻 + /// エントリの終了時刻 + /// エントリの設定値 + void Apply( ref Bitmap frame, float time, float e_begin, float e_end, ref string e_body ); + + + /// + /// プラグイン用の設定値を格納した文字列を指定します。 + /// + /// + string Config { + get; + set; + } + + + /// + /// メイン画面の言語設定が変更されたとき呼び出されます。 + /// + /// + void ApplyLanguage( string language_code ); + + + /// + /// このプラグインの設定メニューが押された時呼び出されます。 + /// + DialogResult BaseSetting(); + + + /// + /// エントリーごとの設定メニューが押された時呼び出されます。 + /// エントリーごとの設定は、ぷらぐいん側で任意に設定できます。 + /// + /// 編集するエントリの設定 + DialogResult EntrySetting( ref string entry_config ); + + + /// + /// このプラグインのタイプを指定します。 + /// + ulong Type { + get; + } + + + /// + /// キャラクタ描画関数。 + /// + /// キャラクタの描画先 + /// gのサイズ + /// ビデオの先頭からの時刻 + /// 時刻timeにおける口の形がコンマ区切りで列挙されている + /// (予約) + void Render( Graphics g, Size size, float time, string mouth, string Reserved ); + + } +} diff --git a/trunk/LipSync/IPlugin/IPlugin.csproj b/trunk/LipSync/IPlugin/IPlugin.csproj new file mode 100644 index 0000000..5194710 --- /dev/null +++ b/trunk/LipSync/IPlugin/IPlugin.csproj @@ -0,0 +1,74 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00} + Library + Properties + IPlugin + IPlugin + + + 2.0 + v3.5 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\IPlugin.XML + + + pdbonly + true + bin\Release\ + DEBUG;TRACE + prompt + 4 + bin\Release\IPlugin.XML + + + + + + + + + + + Form + + + InputBox.cs + + + + + + + + InputBox.cs + Designer + + + + + + + + + \ No newline at end of file diff --git a/trunk/LipSync/IPlugin/ISO639.cs b/trunk/LipSync/IPlugin/ISO639.cs new file mode 100644 index 0000000..cc144a3 --- /dev/null +++ b/trunk/LipSync/IPlugin/ISO639.cs @@ -0,0 +1,29 @@ +/* + * ISO639.cs + * Copyright (c) 2007, 2008 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Globalization; + +namespace Plugin { + + public class ISO639 { + public static bool CheckValidity( string code_string ) { + try { + CultureInfo c = CultureInfo.CreateSpecificCulture( code_string ); + } catch { + return false; + } + return true; + } + } + +} diff --git a/trunk/LipSync/IPlugin/InputBox.cs b/trunk/LipSync/IPlugin/InputBox.cs new file mode 100644 index 0000000..60cb02e --- /dev/null +++ b/trunk/LipSync/IPlugin/InputBox.cs @@ -0,0 +1,44 @@ +/* + * InputBox.cs + * Copyright (c) 2007, 2008 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace Plugin { + public partial class InputBox : Form { + + public string rText{ + get{ + return input.Text; + } + set { + input.Text = value; + } + } + + public InputBox( string title, string message ) { + InitializeComponent(); + this.message.Text = message; + this.Text = title; + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + this.Close(); + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/IPlugin/InputBox.designer.cs b/trunk/LipSync/IPlugin/InputBox.designer.cs new file mode 100644 index 0000000..bf31744 --- /dev/null +++ b/trunk/LipSync/IPlugin/InputBox.designer.cs @@ -0,0 +1,111 @@ +/* + * InputBox.designer.cs + * Copyright (c) 2007, 2008 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace Plugin { + partial class InputBox { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.message = new System.Windows.Forms.Label(); + this.input = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 114, 73 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 208, 73 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // message + // + this.message.AutoEllipsis = true; + this.message.AutoSize = true; + this.message.Location = new System.Drawing.Point( 12, 9 ); + this.message.Name = "message"; + this.message.Size = new System.Drawing.Size( 50, 12 ); + this.message.TabIndex = 2; + this.message.Text = "message"; + // + // input + // + this.input.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.input.Location = new System.Drawing.Point( 29, 35 ); + this.input.Name = "input"; + this.input.Size = new System.Drawing.Size( 254, 19 ); + this.input.TabIndex = 0; + // + // InputBox + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 298, 113 ); + this.Controls.Add( this.input ); + this.Controls.Add( this.message ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InputBox"; + this.Text = "InputBox"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label message; + private System.Windows.Forms.TextBox input; + } +} \ No newline at end of file diff --git a/trunk/LipSync/IPlugin/InputBox.resx b/trunk/LipSync/IPlugin/InputBox.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/trunk/LipSync/IPlugin/InputBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/LipSync/IPlugin/Properties/AssemblyInfo.cs b/trunk/LipSync/IPlugin/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..6a9e8a0 --- /dev/null +++ b/trunk/LipSync/IPlugin/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "IPlugin" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "IPlugin" )] +[assembly: AssemblyCopyright( "Copyright (C) 2007" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "eb60d449-2a04-4bc0-b45c-d4ebf429cf13" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってリビジョンおよびビルド番号を +// 既定値にすることができます: +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/IPlugin/makefile b/trunk/LipSync/IPlugin/makefile new file mode 100644 index 0000000..9cfce04 --- /dev/null +++ b/trunk/LipSync/IPlugin/makefile @@ -0,0 +1,10 @@ +CP=cp +RM=rm +OPT=-r:System,System.Drawing,System.Windows.Forms +IPLUGIN_SRC=IPlugin.cs ISO639.cs InputBox.cs InputBox.designer.cs + +IPlugin.dll: $(IPLUGIN_SRC) + gmcs -target:library -out:IPlugin.dll $(IPLUGIN_SRC) $(OPT) + +clean: + $(RM) IPlugin.dll diff --git a/trunk/LipSync/JVsq/build.xml b/trunk/LipSync/JVsq/build.xml new file mode 100644 index 0000000..41cd686 --- /dev/null +++ b/trunk/LipSync/JVsq/build.xml @@ -0,0 +1,69 @@ + + + + + + Builds, tests, and runs the project JVsq. + + + diff --git a/trunk/LipSync/JVsq/nbproject/build-impl.xml b/trunk/LipSync/JVsq/nbproject/build-impl.xml new file mode 100644 index 0000000..27c520d --- /dev/null +++ b/trunk/LipSync/JVsq/nbproject/build-impl.xml @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + diff --git a/trunk/LipSync/JVsq/nbproject/genfiles.properties b/trunk/LipSync/JVsq/nbproject/genfiles.properties new file mode 100644 index 0000000..fb72ef9 --- /dev/null +++ b/trunk/LipSync/JVsq/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=56626a14 +build.xml.script.CRC32=9b5d8d76 +build.xml.stylesheet.CRC32=be360661 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=56626a14 +nbproject/build-impl.xml.script.CRC32=c54cb890 +nbproject/build-impl.xml.stylesheet.CRC32=487672f9 diff --git a/trunk/LipSync/JVsq/nbproject/project.properties b/trunk/LipSync/JVsq/nbproject/project.properties new file mode 100644 index 0000000..e901ce6 --- /dev/null +++ b/trunk/LipSync/JVsq/nbproject/project.properties @@ -0,0 +1,57 @@ +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/JVsq.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.source=1.5 +javac.target=1.5 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir}:\ + ${libs.junit.classpath}:\ + ${libs.junit_4.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +meta.inf.dir=${src.dir}/META-INF +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/trunk/LipSync/JVsq/nbproject/project.xml b/trunk/LipSync/JVsq/nbproject/project.xml new file mode 100644 index 0000000..3b64cc4 --- /dev/null +++ b/trunk/LipSync/JVsq/nbproject/project.xml @@ -0,0 +1,16 @@ + + + org.netbeans.modules.java.j2seproject + + + JVsq + 1.6.5 + + + + + + + + + diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932.java new file mode 100644 index 0000000..a5c2f3b --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932.java @@ -0,0 +1,130 @@ +/* + * cp932.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.bocoree + * + * jp.sourceforge.lipsync.bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.bocoree; + +import java.util.*; +import java.nio.charset.*; + +public class cp932 { + //private static HashMap _DICT = new HashMap(); + private static boolean m_initialized = false; + private static boolean m_cp932_available = false; + //private static Charset m_cp932 = null; + private static String s_sjis = "Shift_JIS"; + + private static int attatchKey( int key ) { + if ( cp932_a.getMinKey() <= key && key <= cp932_a.getMaxKey() ) { + return cp932_a.get( key ); + } else if ( cp932_b.getMinKey() <= key && key <= cp932_b.getMaxKey() ) { + return cp932_b.get( key ); + } else if ( cp932_c.getMinKey() <= key && key <= cp932_c.getMaxKey() ) { + return cp932_c.get( key ); + } else { + return -1; + } + } + + private static void init() { + m_cp932_available = Charset.isSupported( "Shift_JIS" ); + m_initialized = true; + } + + public static byte[] convert( String str ) { + if ( !m_initialized ) { + init(); + } + if ( m_cp932_available ) { + byte[] ret; + try{ + ret = str.getBytes( s_sjis ); + }catch( Exception e ){ + ret = new byte[0]; + } + return ret; + } else { + char[] arr = str.toCharArray(); + ArrayList list = new ArrayList(); + for ( int i = 0; i < arr.length; i++ ) { + int att = attatchKey( arr[i] ); + if ( att >= 0 ) { + if ( att > 0xff ) { + byte b1 = (byte) (att >> 8); + byte b2 = (byte) (att - (b1 << 8)); + list.add( b1 ); + list.add( b2 ); + } else { + list.add( (byte) att ); + } + } else { + list.add( 0x63 ); + } + } + byte[] ret = new byte[list.size()]; + for ( int i = 0; i < list.size(); i++ ) { + Integer value = (Integer) list.get( i ); + ret[i] = (byte) value.intValue(); + } + return ret; + } + } + + public static String convert( byte[] dat ) { + if ( !m_initialized ) { + init(); + } + if ( m_cp932_available ) { + String ret; + try{ + ret = new String( dat, s_sjis ); + }catch( Exception e ){ + ret = ""; + } + return ret; + } else { + StringBuilder sb = new StringBuilder(); + /*int i = 0; + while ( i < dat.length ) { + int b1 = dat[i]; + boolean found = false; + for ( Iterator keys = _DICT.keySet().iterator(); keys.hasNext();) { + int key = ((Integer) keys.next()).intValue(); + int test = (Integer) _DICT.get( key ); + if ( b1 == test ) { + found = true; + char ch = (char) key; + sb.append( ch + "" ); + break; + } + } + i++; + if ( !found && i < dat.length ) { + int b2 = (dat[i - 1] << 8) + dat[i]; + for ( Iterator keys = _DICT.keySet().iterator(); keys.hasNext();) { + Integer key = (Integer) keys.next(); + int test = ((Integer) _DICT.get( key )).intValue(); + if ( test == b2 ) { + int ik = key.intValue(); + char ch = (char) ik; + sb.append( ch + "" ); + break; + } + } + i++; + } + }*/ + return sb.toString(); + } + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_a.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_a.java new file mode 100644 index 0000000..3680c35 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_a.java @@ -0,0 +1,3093 @@ +/* + * cp932_a.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.bocoree + * + * jp.sourceforge.lipsync.bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.bocoree; + +import java.util.*; + +public class cp932_a { + private static HashMap _DICT = new HashMap(); + private static boolean m_initialized = false; + + public static int getMinKey() { + return 0; + } + + public static int getMaxKey() { + return 26333; + } + + public static int get( int key ) { + if( !m_initialized ){ + init(); + } + if ( _DICT.containsKey( key ) ) { + return ((Integer) _DICT.get( key )).intValue(); + } else { + return -1; + } + } + + private static void init() { + _DICT.put( 0, 0 ); + _DICT.put( 1, 1 ); + _DICT.put( 2, 2 ); + _DICT.put( 3, 3 ); + _DICT.put( 4, 4 ); + _DICT.put( 5, 5 ); + _DICT.put( 6, 6 ); + _DICT.put( 7, 7 ); + _DICT.put( 8, 8 ); + _DICT.put( 9, 9 ); + _DICT.put( 10, 10 ); + _DICT.put( 11, 11 ); + _DICT.put( 12, 12 ); + _DICT.put( 13, 13 ); + _DICT.put( 14, 14 ); + _DICT.put( 15, 15 ); + _DICT.put( 16, 16 ); + _DICT.put( 17, 17 ); + _DICT.put( 18, 18 ); + _DICT.put( 19, 19 ); + _DICT.put( 20, 20 ); + _DICT.put( 21, 21 ); + _DICT.put( 22, 22 ); + _DICT.put( 23, 23 ); + _DICT.put( 24, 24 ); + _DICT.put( 25, 25 ); + _DICT.put( 26, 26 ); + _DICT.put( 27, 27 ); + _DICT.put( 28, 28 ); + _DICT.put( 29, 29 ); + _DICT.put( 30, 30 ); + _DICT.put( 31, 31 ); + _DICT.put( 32, 32 ); + _DICT.put( 33, 33 ); + _DICT.put( 34, 34 ); + _DICT.put( 35, 35 ); + _DICT.put( 36, 36 ); + _DICT.put( 37, 37 ); + _DICT.put( 38, 38 ); + _DICT.put( 39, 39 ); + _DICT.put( 40, 40 ); + _DICT.put( 41, 41 ); + _DICT.put( 42, 42 ); + _DICT.put( 43, 43 ); + _DICT.put( 44, 44 ); + _DICT.put( 45, 45 ); + _DICT.put( 46, 46 ); + _DICT.put( 47, 47 ); + _DICT.put( 48, 48 ); + _DICT.put( 49, 49 ); + _DICT.put( 50, 50 ); + _DICT.put( 51, 51 ); + _DICT.put( 52, 52 ); + _DICT.put( 53, 53 ); + _DICT.put( 54, 54 ); + _DICT.put( 55, 55 ); + _DICT.put( 56, 56 ); + _DICT.put( 57, 57 ); + _DICT.put( 58, 58 ); + _DICT.put( 59, 59 ); + _DICT.put( 60, 60 ); + _DICT.put( 61, 61 ); + _DICT.put( 62, 62 ); + _DICT.put( 64, 64 ); + _DICT.put( 65, 65 ); + _DICT.put( 66, 66 ); + _DICT.put( 67, 67 ); + _DICT.put( 68, 68 ); + _DICT.put( 69, 69 ); + _DICT.put( 70, 70 ); + _DICT.put( 71, 71 ); + _DICT.put( 72, 72 ); + _DICT.put( 73, 73 ); + _DICT.put( 74, 74 ); + _DICT.put( 75, 75 ); + _DICT.put( 76, 76 ); + _DICT.put( 77, 77 ); + _DICT.put( 78, 78 ); + _DICT.put( 79, 79 ); + _DICT.put( 80, 80 ); + _DICT.put( 81, 81 ); + _DICT.put( 82, 82 ); + _DICT.put( 83, 83 ); + _DICT.put( 84, 84 ); + _DICT.put( 85, 85 ); + _DICT.put( 86, 86 ); + _DICT.put( 87, 87 ); + _DICT.put( 88, 88 ); + _DICT.put( 89, 89 ); + _DICT.put( 90, 90 ); + _DICT.put( 91, 91 ); + _DICT.put( 92, 92 ); + _DICT.put( 93, 93 ); + _DICT.put( 94, 94 ); + _DICT.put( 95, 95 ); + _DICT.put( 96, 96 ); + _DICT.put( 97, 97 ); + _DICT.put( 98, 98 ); + _DICT.put( 99, 99 ); + _DICT.put( 100, 100 ); + _DICT.put( 101, 101 ); + _DICT.put( 102, 102 ); + _DICT.put( 103, 103 ); + _DICT.put( 104, 104 ); + _DICT.put( 105, 105 ); + _DICT.put( 106, 106 ); + _DICT.put( 107, 107 ); + _DICT.put( 108, 108 ); + _DICT.put( 109, 109 ); + _DICT.put( 110, 110 ); + _DICT.put( 111, 111 ); + _DICT.put( 112, 112 ); + _DICT.put( 113, 113 ); + _DICT.put( 114, 114 ); + _DICT.put( 115, 115 ); + _DICT.put( 116, 116 ); + _DICT.put( 117, 117 ); + _DICT.put( 118, 118 ); + _DICT.put( 119, 119 ); + _DICT.put( 120, 120 ); + _DICT.put( 121, 121 ); + _DICT.put( 122, 122 ); + _DICT.put( 123, 123 ); + _DICT.put( 124, 124 ); + _DICT.put( 125, 125 ); + _DICT.put( 126, 126 ); + _DICT.put( 127, 127 ); + _DICT.put( 128, 128 ); + _DICT.put( 161, 33 ); + _DICT.put( 162, 33169 ); + _DICT.put( 163, 33170 ); + _DICT.put( 165, 92 ); + _DICT.put( 166, 124 ); + _DICT.put( 167, 33176 ); + _DICT.put( 168, 33102 ); + _DICT.put( 169, 99 ); + _DICT.put( 170, 97 ); + _DICT.put( 171, 33249 ); + _DICT.put( 172, 33226 ); + _DICT.put( 173, 45 ); + _DICT.put( 174, 82 ); + _DICT.put( 175, 33104 ); + _DICT.put( 176, 33163 ); + _DICT.put( 177, 33149 ); + _DICT.put( 178, 50 ); + _DICT.put( 179, 51 ); + _DICT.put( 180, 33100 ); + _DICT.put( 181, 33738 ); + _DICT.put( 182, 33271 ); + _DICT.put( 183, 33093 ); + _DICT.put( 184, 33091 ); + _DICT.put( 185, 49 ); + _DICT.put( 186, 111 ); + _DICT.put( 187, 33250 ); + _DICT.put( 192, 65 ); + _DICT.put( 193, 65 ); + _DICT.put( 194, 65 ); + _DICT.put( 195, 65 ); + _DICT.put( 196, 65 ); + _DICT.put( 197, 65 ); + _DICT.put( 198, 65 ); + _DICT.put( 199, 67 ); + _DICT.put( 200, 69 ); + _DICT.put( 201, 69 ); + _DICT.put( 202, 69 ); + _DICT.put( 203, 69 ); + _DICT.put( 204, 73 ); + _DICT.put( 205, 73 ); + _DICT.put( 206, 73 ); + _DICT.put( 207, 73 ); + _DICT.put( 208, 68 ); + _DICT.put( 209, 78 ); + _DICT.put( 210, 79 ); + _DICT.put( 211, 79 ); + _DICT.put( 212, 79 ); + _DICT.put( 213, 79 ); + _DICT.put( 214, 79 ); + _DICT.put( 215, 33150 ); + _DICT.put( 216, 79 ); + _DICT.put( 217, 85 ); + _DICT.put( 218, 85 ); + _DICT.put( 219, 85 ); + _DICT.put( 220, 85 ); + _DICT.put( 221, 89 ); + _DICT.put( 222, 84 ); + _DICT.put( 223, 115 ); + _DICT.put( 224, 97 ); + _DICT.put( 225, 97 ); + _DICT.put( 226, 97 ); + _DICT.put( 227, 97 ); + _DICT.put( 228, 97 ); + _DICT.put( 229, 97 ); + _DICT.put( 230, 97 ); + _DICT.put( 231, 99 ); + _DICT.put( 232, 101 ); + _DICT.put( 233, 101 ); + _DICT.put( 234, 101 ); + _DICT.put( 235, 101 ); + _DICT.put( 236, 105 ); + _DICT.put( 237, 105 ); + _DICT.put( 238, 105 ); + _DICT.put( 239, 105 ); + _DICT.put( 240, 100 ); + _DICT.put( 241, 110 ); + _DICT.put( 242, 111 ); + _DICT.put( 243, 111 ); + _DICT.put( 244, 111 ); + _DICT.put( 245, 111 ); + _DICT.put( 246, 111 ); + _DICT.put( 247, 33152 ); + _DICT.put( 248, 111 ); + _DICT.put( 249, 117 ); + _DICT.put( 250, 117 ); + _DICT.put( 251, 117 ); + _DICT.put( 252, 117 ); + _DICT.put( 253, 121 ); + _DICT.put( 254, 116 ); + _DICT.put( 255, 121 ); + _DICT.put( 913, 33695 ); + _DICT.put( 914, 33696 ); + _DICT.put( 915, 33697 ); + _DICT.put( 916, 33698 ); + _DICT.put( 917, 33699 ); + _DICT.put( 918, 33700 ); + _DICT.put( 919, 33701 ); + _DICT.put( 920, 33702 ); + _DICT.put( 921, 33703 ); + _DICT.put( 922, 33704 ); + _DICT.put( 923, 33705 ); + _DICT.put( 924, 33706 ); + _DICT.put( 925, 33707 ); + _DICT.put( 926, 33708 ); + _DICT.put( 927, 33709 ); + _DICT.put( 928, 33710 ); + _DICT.put( 929, 33711 ); + _DICT.put( 931, 33712 ); + _DICT.put( 932, 33713 ); + _DICT.put( 933, 33714 ); + _DICT.put( 934, 33715 ); + _DICT.put( 935, 33716 ); + _DICT.put( 936, 33717 ); + _DICT.put( 937, 33718 ); + _DICT.put( 945, 33727 ); + _DICT.put( 946, 33728 ); + _DICT.put( 947, 33729 ); + _DICT.put( 948, 33730 ); + _DICT.put( 949, 33731 ); + _DICT.put( 950, 33732 ); + _DICT.put( 951, 33733 ); + _DICT.put( 952, 33734 ); + _DICT.put( 953, 33735 ); + _DICT.put( 954, 33736 ); + _DICT.put( 955, 33737 ); + _DICT.put( 956, 33738 ); + _DICT.put( 957, 33739 ); + _DICT.put( 958, 33740 ); + _DICT.put( 959, 33741 ); + _DICT.put( 960, 33742 ); + _DICT.put( 961, 33743 ); + _DICT.put( 963, 33744 ); + _DICT.put( 964, 33745 ); + _DICT.put( 965, 33746 ); + _DICT.put( 966, 33747 ); + _DICT.put( 967, 33748 ); + _DICT.put( 968, 33749 ); + _DICT.put( 969, 33750 ); + _DICT.put( 1025, 33862 ); + _DICT.put( 1040, 33856 ); + _DICT.put( 1041, 33857 ); + _DICT.put( 1042, 33858 ); + _DICT.put( 1043, 33859 ); + _DICT.put( 1044, 33860 ); + _DICT.put( 1045, 33861 ); + _DICT.put( 1046, 33863 ); + _DICT.put( 1047, 33864 ); + _DICT.put( 1048, 33865 ); + _DICT.put( 1049, 33866 ); + _DICT.put( 1050, 33867 ); + _DICT.put( 1051, 33868 ); + _DICT.put( 1052, 33869 ); + _DICT.put( 1053, 33870 ); + _DICT.put( 1054, 33871 ); + _DICT.put( 1055, 33872 ); + _DICT.put( 1056, 33873 ); + _DICT.put( 1057, 33874 ); + _DICT.put( 1058, 33875 ); + _DICT.put( 1059, 33876 ); + _DICT.put( 1060, 33877 ); + _DICT.put( 1061, 33878 ); + _DICT.put( 1062, 33879 ); + _DICT.put( 1063, 33880 ); + _DICT.put( 1064, 33881 ); + _DICT.put( 1065, 33882 ); + _DICT.put( 1066, 33883 ); + _DICT.put( 1067, 33884 ); + _DICT.put( 1068, 33885 ); + _DICT.put( 1069, 33886 ); + _DICT.put( 1070, 33887 ); + _DICT.put( 1071, 33888 ); + _DICT.put( 1072, 33904 ); + _DICT.put( 1073, 33905 ); + _DICT.put( 1074, 33906 ); + _DICT.put( 1075, 33907 ); + _DICT.put( 1076, 33908 ); + _DICT.put( 1077, 33909 ); + _DICT.put( 1078, 33911 ); + _DICT.put( 1079, 33912 ); + _DICT.put( 1080, 33913 ); + _DICT.put( 1081, 33914 ); + _DICT.put( 1082, 33915 ); + _DICT.put( 1083, 33916 ); + _DICT.put( 1084, 33917 ); + _DICT.put( 1085, 33918 ); + _DICT.put( 1086, 33920 ); + _DICT.put( 1087, 33921 ); + _DICT.put( 1088, 33922 ); + _DICT.put( 1089, 33923 ); + _DICT.put( 1090, 33924 ); + _DICT.put( 1091, 33925 ); + _DICT.put( 1092, 33926 ); + _DICT.put( 1093, 33927 ); + _DICT.put( 1094, 33928 ); + _DICT.put( 1095, 33929 ); + _DICT.put( 1096, 33930 ); + _DICT.put( 1097, 33931 ); + _DICT.put( 1098, 33932 ); + _DICT.put( 1099, 33933 ); + _DICT.put( 1100, 33934 ); + _DICT.put( 1101, 33935 ); + _DICT.put( 1102, 33936 ); + _DICT.put( 1103, 33937 ); + _DICT.put( 1105, 33910 ); + _DICT.put( 8208, 33117 ); + _DICT.put( 8213, 33116 ); + _DICT.put( 8216, 33125 ); + _DICT.put( 8217, 33126 ); + _DICT.put( 8220, 33127 ); + _DICT.put( 8221, 33128 ); + _DICT.put( 8224, 33269 ); + _DICT.put( 8225, 33270 ); + _DICT.put( 8229, 33124 ); + _DICT.put( 8230, 33123 ); + _DICT.put( 8240, 33265 ); + _DICT.put( 8242, 33164 ); + _DICT.put( 8243, 33165 ); + _DICT.put( 8251, 33190 ); + _DICT.put( 8451, 33166 ); + _DICT.put( 8470, 34690 ); + _DICT.put( 8481, 34692 ); + _DICT.put( 8491, 33264 ); + _DICT.put( 8544, 34644 ); + _DICT.put( 8545, 34645 ); + _DICT.put( 8546, 34646 ); + _DICT.put( 8547, 34647 ); + _DICT.put( 8548, 34648 ); + _DICT.put( 8549, 34649 ); + _DICT.put( 8550, 34650 ); + _DICT.put( 8551, 34651 ); + _DICT.put( 8552, 34652 ); + _DICT.put( 8553, 34653 ); + _DICT.put( 8560, 64064 ); + _DICT.put( 8561, 64065 ); + _DICT.put( 8562, 64066 ); + _DICT.put( 8563, 64067 ); + _DICT.put( 8564, 64068 ); + _DICT.put( 8565, 64069 ); + _DICT.put( 8566, 64070 ); + _DICT.put( 8567, 64071 ); + _DICT.put( 8568, 64072 ); + _DICT.put( 8569, 64073 ); + _DICT.put( 8592, 33193 ); + _DICT.put( 8593, 33194 ); + _DICT.put( 8594, 33192 ); + _DICT.put( 8595, 33195 ); + _DICT.put( 8658, 33227 ); + _DICT.put( 8660, 33228 ); + _DICT.put( 8704, 33229 ); + _DICT.put( 8706, 33245 ); + _DICT.put( 8707, 33230 ); + _DICT.put( 8711, 33246 ); + _DICT.put( 8712, 33208 ); + _DICT.put( 8715, 33209 ); + _DICT.put( 8721, 34708 ); + _DICT.put( 8730, 33251 ); + _DICT.put( 8733, 33253 ); + _DICT.put( 8734, 33159 ); + _DICT.put( 8735, 34712 ); + _DICT.put( 8736, 33242 ); + _DICT.put( 8741, 33121 ); + _DICT.put( 8743, 33224 ); + _DICT.put( 8744, 33225 ); + _DICT.put( 8745, 33215 ); + _DICT.put( 8746, 33214 ); + _DICT.put( 8747, 33255 ); + _DICT.put( 8748, 33256 ); + _DICT.put( 8750, 34707 ); + _DICT.put( 8756, 33160 ); + _DICT.put( 8757, 33254 ); + _DICT.put( 8765, 33252 ); + _DICT.put( 8786, 33248 ); + _DICT.put( 8800, 33154 ); + _DICT.put( 8801, 33247 ); + _DICT.put( 8806, 33157 ); + _DICT.put( 8807, 33158 ); + _DICT.put( 8810, 33249 ); + _DICT.put( 8811, 33250 ); + _DICT.put( 8834, 33212 ); + _DICT.put( 8835, 33213 ); + _DICT.put( 8838, 33210 ); + _DICT.put( 8839, 33211 ); + _DICT.put( 8869, 33243 ); + _DICT.put( 8895, 34713 ); + _DICT.put( 8978, 33244 ); + _DICT.put( 9312, 34624 ); + _DICT.put( 9313, 34625 ); + _DICT.put( 9314, 34626 ); + _DICT.put( 9315, 34627 ); + _DICT.put( 9316, 34628 ); + _DICT.put( 9317, 34629 ); + _DICT.put( 9318, 34630 ); + _DICT.put( 9319, 34631 ); + _DICT.put( 9320, 34632 ); + _DICT.put( 9321, 34633 ); + _DICT.put( 9322, 34634 ); + _DICT.put( 9323, 34635 ); + _DICT.put( 9324, 34636 ); + _DICT.put( 9325, 34637 ); + _DICT.put( 9326, 34638 ); + _DICT.put( 9327, 34639 ); + _DICT.put( 9328, 34640 ); + _DICT.put( 9329, 34641 ); + _DICT.put( 9330, 34642 ); + _DICT.put( 9331, 34643 ); + _DICT.put( 9472, 33951 ); + _DICT.put( 9473, 33962 ); + _DICT.put( 9474, 33952 ); + _DICT.put( 9475, 33963 ); + _DICT.put( 9484, 33953 ); + _DICT.put( 9487, 33964 ); + _DICT.put( 9488, 33954 ); + _DICT.put( 9491, 33965 ); + _DICT.put( 9492, 33956 ); + _DICT.put( 9495, 33967 ); + _DICT.put( 9496, 33955 ); + _DICT.put( 9499, 33966 ); + _DICT.put( 9500, 33957 ); + _DICT.put( 9501, 33978 ); + _DICT.put( 9504, 33973 ); + _DICT.put( 9507, 33968 ); + _DICT.put( 9508, 33959 ); + _DICT.put( 9509, 33980 ); + _DICT.put( 9512, 33975 ); + _DICT.put( 9515, 33970 ); + _DICT.put( 9516, 33958 ); + _DICT.put( 9519, 33974 ); + _DICT.put( 9520, 33979 ); + _DICT.put( 9523, 33969 ); + _DICT.put( 9524, 33960 ); + _DICT.put( 9527, 33976 ); + _DICT.put( 9528, 33981 ); + _DICT.put( 9531, 33971 ); + _DICT.put( 9532, 33961 ); + _DICT.put( 9535, 33977 ); + _DICT.put( 9538, 33982 ); + _DICT.put( 9547, 33972 ); + _DICT.put( 9632, 33185 ); + _DICT.put( 9633, 33184 ); + _DICT.put( 9650, 33187 ); + _DICT.put( 9651, 33186 ); + _DICT.put( 9660, 33189 ); + _DICT.put( 9661, 33188 ); + _DICT.put( 9670, 33183 ); + _DICT.put( 9671, 33182 ); + _DICT.put( 9675, 33179 ); + _DICT.put( 9678, 33181 ); + _DICT.put( 9679, 33180 ); + _DICT.put( 9711, 33276 ); + _DICT.put( 9733, 33178 ); + _DICT.put( 9734, 33177 ); + _DICT.put( 9792, 33162 ); + _DICT.put( 9794, 33161 ); + _DICT.put( 9834, 33268 ); + _DICT.put( 9837, 33267 ); + _DICT.put( 9839, 33266 ); + _DICT.put( 12288, 33088 ); + _DICT.put( 12289, 33089 ); + _DICT.put( 12290, 33090 ); + _DICT.put( 12291, 33110 ); + _DICT.put( 12293, 33112 ); + _DICT.put( 12294, 33113 ); + _DICT.put( 12295, 33114 ); + _DICT.put( 12296, 33137 ); + _DICT.put( 12297, 33138 ); + _DICT.put( 12298, 33139 ); + _DICT.put( 12299, 33140 ); + _DICT.put( 12300, 33141 ); + _DICT.put( 12301, 33142 ); + _DICT.put( 12302, 33143 ); + _DICT.put( 12303, 33144 ); + _DICT.put( 12304, 33145 ); + _DICT.put( 12305, 33146 ); + _DICT.put( 12306, 33191 ); + _DICT.put( 12307, 33196 ); + _DICT.put( 12308, 33131 ); + _DICT.put( 12309, 33132 ); + _DICT.put( 12317, 34688 ); + _DICT.put( 12319, 34689 ); + _DICT.put( 12353, 33439 ); + _DICT.put( 12354, 33440 ); + _DICT.put( 12355, 33441 ); + _DICT.put( 12356, 33442 ); + _DICT.put( 12357, 33443 ); + _DICT.put( 12358, 33444 ); + _DICT.put( 12359, 33445 ); + _DICT.put( 12360, 33446 ); + _DICT.put( 12361, 33447 ); + _DICT.put( 12362, 33448 ); + _DICT.put( 12363, 33449 ); + _DICT.put( 12364, 33450 ); + _DICT.put( 12365, 33451 ); + _DICT.put( 12366, 33452 ); + _DICT.put( 12367, 33453 ); + _DICT.put( 12368, 33454 ); + _DICT.put( 12369, 33455 ); + _DICT.put( 12370, 33456 ); + _DICT.put( 12371, 33457 ); + _DICT.put( 12372, 33458 ); + _DICT.put( 12373, 33459 ); + _DICT.put( 12374, 33460 ); + _DICT.put( 12375, 33461 ); + _DICT.put( 12376, 33462 ); + _DICT.put( 12377, 33463 ); + _DICT.put( 12378, 33464 ); + _DICT.put( 12379, 33465 ); + _DICT.put( 12380, 33466 ); + _DICT.put( 12381, 33467 ); + _DICT.put( 12382, 33468 ); + _DICT.put( 12383, 33469 ); + _DICT.put( 12384, 33470 ); + _DICT.put( 12385, 33471 ); + _DICT.put( 12386, 33472 ); + _DICT.put( 12387, 33473 ); + _DICT.put( 12388, 33474 ); + _DICT.put( 12389, 33475 ); + _DICT.put( 12390, 33476 ); + _DICT.put( 12391, 33477 ); + _DICT.put( 12392, 33478 ); + _DICT.put( 12393, 33479 ); + _DICT.put( 12394, 33480 ); + _DICT.put( 12395, 33481 ); + _DICT.put( 12396, 33482 ); + _DICT.put( 12397, 33483 ); + _DICT.put( 12398, 33484 ); + _DICT.put( 12399, 33485 ); + _DICT.put( 12400, 33486 ); + _DICT.put( 12401, 33487 ); + _DICT.put( 12402, 33488 ); + _DICT.put( 12403, 33489 ); + _DICT.put( 12404, 33490 ); + _DICT.put( 12405, 33491 ); + _DICT.put( 12406, 33492 ); + _DICT.put( 12407, 33493 ); + _DICT.put( 12408, 33494 ); + _DICT.put( 12409, 33495 ); + _DICT.put( 12410, 33496 ); + _DICT.put( 12411, 33497 ); + _DICT.put( 12412, 33498 ); + _DICT.put( 12413, 33499 ); + _DICT.put( 12414, 33500 ); + _DICT.put( 12415, 33501 ); + _DICT.put( 12416, 33502 ); + _DICT.put( 12417, 33503 ); + _DICT.put( 12418, 33504 ); + _DICT.put( 12419, 33505 ); + _DICT.put( 12420, 33506 ); + _DICT.put( 12421, 33507 ); + _DICT.put( 12422, 33508 ); + _DICT.put( 12423, 33509 ); + _DICT.put( 12424, 33510 ); + _DICT.put( 12425, 33511 ); + _DICT.put( 12426, 33512 ); + _DICT.put( 12427, 33513 ); + _DICT.put( 12428, 33514 ); + _DICT.put( 12429, 33515 ); + _DICT.put( 12430, 33516 ); + _DICT.put( 12431, 33517 ); + _DICT.put( 12432, 33518 ); + _DICT.put( 12433, 33519 ); + _DICT.put( 12434, 33520 ); + _DICT.put( 12435, 33521 ); + _DICT.put( 12436, 33684 ); + _DICT.put( 12443, 33098 ); + _DICT.put( 12444, 33099 ); + _DICT.put( 12445, 33108 ); + _DICT.put( 12446, 33109 ); + _DICT.put( 12449, 33600 ); + _DICT.put( 12450, 33601 ); + _DICT.put( 12451, 33602 ); + _DICT.put( 12452, 33603 ); + _DICT.put( 12453, 33604 ); + _DICT.put( 12454, 33605 ); + _DICT.put( 12455, 33606 ); + _DICT.put( 12456, 33607 ); + _DICT.put( 12457, 33608 ); + _DICT.put( 12458, 33609 ); + _DICT.put( 12459, 33610 ); + _DICT.put( 12460, 33611 ); + _DICT.put( 12461, 33612 ); + _DICT.put( 12462, 33613 ); + _DICT.put( 12463, 33614 ); + _DICT.put( 12464, 33615 ); + _DICT.put( 12465, 33616 ); + _DICT.put( 12466, 33617 ); + _DICT.put( 12467, 33618 ); + _DICT.put( 12468, 33619 ); + _DICT.put( 12469, 33620 ); + _DICT.put( 12470, 33621 ); + _DICT.put( 12471, 33622 ); + _DICT.put( 12472, 33623 ); + _DICT.put( 12473, 33624 ); + _DICT.put( 12474, 33625 ); + _DICT.put( 12475, 33626 ); + _DICT.put( 12476, 33627 ); + _DICT.put( 12477, 33628 ); + _DICT.put( 12478, 33629 ); + _DICT.put( 12479, 33630 ); + _DICT.put( 12480, 33631 ); + _DICT.put( 12481, 33632 ); + _DICT.put( 12482, 33633 ); + _DICT.put( 12483, 33634 ); + _DICT.put( 12484, 33635 ); + _DICT.put( 12485, 33636 ); + _DICT.put( 12486, 33637 ); + _DICT.put( 12487, 33638 ); + _DICT.put( 12488, 33639 ); + _DICT.put( 12489, 33640 ); + _DICT.put( 12490, 33641 ); + _DICT.put( 12491, 33642 ); + _DICT.put( 12492, 33643 ); + _DICT.put( 12493, 33644 ); + _DICT.put( 12494, 33645 ); + _DICT.put( 12495, 33646 ); + _DICT.put( 12496, 33647 ); + _DICT.put( 12497, 33648 ); + _DICT.put( 12498, 33649 ); + _DICT.put( 12499, 33650 ); + _DICT.put( 12500, 33651 ); + _DICT.put( 12501, 33652 ); + _DICT.put( 12502, 33653 ); + _DICT.put( 12503, 33654 ); + _DICT.put( 12504, 33655 ); + _DICT.put( 12505, 33656 ); + _DICT.put( 12506, 33657 ); + _DICT.put( 12507, 33658 ); + _DICT.put( 12508, 33659 ); + _DICT.put( 12509, 33660 ); + _DICT.put( 12510, 33661 ); + _DICT.put( 12511, 33662 ); + _DICT.put( 12512, 33664 ); + _DICT.put( 12513, 33665 ); + _DICT.put( 12514, 33666 ); + _DICT.put( 12515, 33667 ); + _DICT.put( 12516, 33668 ); + _DICT.put( 12517, 33669 ); + _DICT.put( 12518, 33670 ); + _DICT.put( 12519, 33671 ); + _DICT.put( 12520, 33672 ); + _DICT.put( 12521, 33673 ); + _DICT.put( 12522, 33674 ); + _DICT.put( 12523, 33675 ); + _DICT.put( 12524, 33676 ); + _DICT.put( 12525, 33677 ); + _DICT.put( 12526, 33678 ); + _DICT.put( 12527, 33679 ); + _DICT.put( 12528, 33680 ); + _DICT.put( 12529, 33681 ); + _DICT.put( 12530, 33682 ); + _DICT.put( 12531, 33683 ); + _DICT.put( 12532, 33684 ); + _DICT.put( 12533, 33685 ); + _DICT.put( 12534, 33686 ); + _DICT.put( 12539, 33093 ); + _DICT.put( 12540, 33115 ); + _DICT.put( 12541, 33106 ); + _DICT.put( 12542, 33107 ); + _DICT.put( 12849, 34698 ); + _DICT.put( 12850, 34699 ); + _DICT.put( 12857, 34700 ); + _DICT.put( 12964, 34693 ); + _DICT.put( 12965, 34694 ); + _DICT.put( 12966, 34695 ); + _DICT.put( 12967, 34696 ); + _DICT.put( 12968, 34697 ); + _DICT.put( 13059, 34661 ); + _DICT.put( 13069, 34665 ); + _DICT.put( 13076, 34656 ); + _DICT.put( 13080, 34659 ); + _DICT.put( 13090, 34657 ); + _DICT.put( 13091, 34667 ); + _DICT.put( 13094, 34666 ); + _DICT.put( 13095, 34660 ); + _DICT.put( 13099, 34668 ); + _DICT.put( 13110, 34662 ); + _DICT.put( 13115, 34670 ); + _DICT.put( 13129, 34655 ); + _DICT.put( 13130, 34669 ); + _DICT.put( 13133, 34658 ); + _DICT.put( 13137, 34663 ); + _DICT.put( 13143, 34664 ); + _DICT.put( 13179, 34686 ); + _DICT.put( 13180, 34703 ); + _DICT.put( 13181, 34702 ); + _DICT.put( 13182, 34701 ); + _DICT.put( 13198, 34674 ); + _DICT.put( 13199, 34675 ); + _DICT.put( 13212, 34671 ); + _DICT.put( 13213, 34672 ); + _DICT.put( 13214, 34673 ); + _DICT.put( 13217, 34677 ); + _DICT.put( 13252, 34676 ); + _DICT.put( 13261, 34691 ); + _DICT.put( 19968, 35050 ); + _DICT.put( 19969, 37530 ); + _DICT.put( 19971, 36533 ); + _DICT.put( 19975, 38556 ); + _DICT.put( 19976, 36836 ); + _DICT.put( 19977, 36431 ); + _DICT.put( 19978, 36835 ); + _DICT.put( 19979, 35258 ); + _DICT.put( 19981, 38259 ); + _DICT.put( 19982, 38750 ); + _DICT.put( 19984, 39072 ); + _DICT.put( 19985, 35150 ); + _DICT.put( 19988, 35470 ); + _DICT.put( 19989, 39073 ); + _DICT.put( 19990, 37026 ); + _DICT.put( 19991, 39360 ); + _DICT.put( 19992, 35701 ); + _DICT.put( 19993, 38328 ); + _DICT.put( 19998, 36837 ); + _DICT.put( 20001, 38844 ); + _DICT.put( 20006, 38336 ); + _DICT.put( 20008, 64104 ); + _DICT.put( 20010, 39074 ); + _DICT.put( 20013, 37510 ); + _DICT.put( 20017, 39075 ); + _DICT.put( 20018, 35832 ); + _DICT.put( 20022, 39076 ); + _DICT.put( 20024, 35547 ); + _DICT.put( 20025, 37455 ); + _DICT.put( 20027, 36581 ); + _DICT.put( 20028, 39077 ); + _DICT.put( 20031, 39078 ); + _DICT.put( 20034, 39079 ); + _DICT.put( 20035, 37972 ); + _DICT.put( 20037, 35702 ); + _DICT.put( 20043, 37974 ); + _DICT.put( 20045, 37857 ); + _DICT.put( 20046, 36033 ); + _DICT.put( 20047, 38482 ); + _DICT.put( 20053, 58728 ); + _DICT.put( 20054, 39080 ); + _DICT.put( 20055, 36838 ); + _DICT.put( 20056, 39081 ); + _DICT.put( 20057, 35251 ); + _DICT.put( 20061, 35811 ); + _DICT.put( 20062, 36078 ); + _DICT.put( 20063, 38631 ); + _DICT.put( 20066, 39844 ); + _DICT.put( 20081, 38800 ); + _DICT.put( 20083, 37883 ); + _DICT.put( 20094, 35491 ); + _DICT.put( 20096, 35668 ); + _DICT.put( 20098, 39082 ); + _DICT.put( 20101, 39083 ); + _DICT.put( 20102, 38841 ); + _DICT.put( 20104, 38748 ); + _DICT.put( 20105, 37256 ); + _DICT.put( 20106, 39085 ); + _DICT.put( 20107, 36502 ); + _DICT.put( 20108, 37873 ); + _DICT.put( 20110, 39088 ); + _DICT.put( 20113, 35165 ); + _DICT.put( 20114, 36061 ); + _DICT.put( 20116, 36060 ); + _DICT.put( 20117, 35044 ); + _DICT.put( 20120, 39018 ); + _DICT.put( 20121, 39017 ); + _DICT.put( 20123, 36273 ); + _DICT.put( 20124, 34975 ); + _DICT.put( 20126, 39089 ); + _DICT.put( 20127, 39090 ); + _DICT.put( 20128, 39091 ); + _DICT.put( 20129, 38483 ); + _DICT.put( 20130, 39092 ); + _DICT.put( 20132, 36080 ); + _DICT.put( 20133, 35045 ); + _DICT.put( 20134, 38546 ); + _DICT.put( 20136, 35740 ); + _DICT.put( 20139, 35741 ); + _DICT.put( 20140, 35742 ); + _DICT.put( 20141, 37600 ); + _DICT.put( 20142, 38842 ); + _DICT.put( 20144, 39093 ); + _DICT.put( 20147, 39094 ); + _DICT.put( 20150, 39095 ); + _DICT.put( 20154, 36972 ); + _DICT.put( 20160, 36697 ); + _DICT.put( 20161, 36973 ); + _DICT.put( 20162, 39100 ); + _DICT.put( 20164, 39098 ); + _DICT.put( 20166, 39099 ); + _DICT.put( 20167, 35703 ); + _DICT.put( 20170, 36257 ); + _DICT.put( 20171, 35310 ); + _DICT.put( 20173, 39097 ); + _DICT.put( 20174, 39096 ); + _DICT.put( 20175, 38311 ); + _DICT.put( 20180, 36453 ); + _DICT.put( 20181, 36452 ); + _DICT.put( 20182, 37308 ); + _DICT.put( 20183, 39101 ); + _DICT.put( 20184, 38260 ); + _DICT.put( 20185, 37093 ); + _DICT.put( 20189, 33111 ); + _DICT.put( 20190, 39102 ); + _DICT.put( 20191, 39104 ); + _DICT.put( 20193, 64105 ); + _DICT.put( 20195, 37347 ); + _DICT.put( 20196, 38879 ); + _DICT.put( 20197, 35016 ); + _DICT.put( 20205, 39103 ); + _DICT.put( 20206, 35260 ); + _DICT.put( 20208, 35778 ); + _DICT.put( 20210, 37511 ); + _DICT.put( 20214, 35983 ); + _DICT.put( 20215, 39105 ); + _DICT.put( 20219, 37955 ); + _DICT.put( 20220, 64106 ); + _DICT.put( 20224, 64107 ); + _DICT.put( 20225, 35561 ); + _DICT.put( 20227, 64108 ); + _DICT.put( 20233, 39106 ); + _DICT.put( 20234, 35017 ); + _DICT.put( 20237, 36062 ); + _DICT.put( 20238, 35562 ); + _DICT.put( 20239, 38298 ); + _DICT.put( 20240, 38064 ); + _DICT.put( 20241, 35704 ); + _DICT.put( 20250, 35311 ); + _DICT.put( 20252, 39141 ); + _DICT.put( 20253, 37728 ); + _DICT.put( 20271, 38028 ); + _DICT.put( 20272, 39108 ); + _DICT.put( 20276, 38074 ); + _DICT.put( 20278, 38880 ); + _DICT.put( 20280, 36940 ); + _DICT.put( 20281, 64109 ); + _DICT.put( 20282, 36454 ); + _DICT.put( 20284, 36503 ); + _DICT.put( 20285, 35262 ); + _DICT.put( 20291, 37583 ); + _DICT.put( 20294, 37441 ); + _DICT.put( 20295, 39112 ); + _DICT.put( 20301, 35018 ); + _DICT.put( 20302, 37601 ); + _DICT.put( 20303, 36698 ); + _DICT.put( 20304, 36274 ); + _DICT.put( 20305, 38723 ); + _DICT.put( 20307, 37324 ); + _DICT.put( 20309, 35261 ); + _DICT.put( 20310, 64110 ); + _DICT.put( 20311, 39111 ); + _DICT.put( 20313, 38749 ); + _DICT.put( 20314, 39107 ); + _DICT.put( 20315, 39109 ); + _DICT.put( 20316, 36332 ); + _DICT.put( 20317, 39110 ); + _DICT.put( 20318, 39747 ); + _DICT.put( 20329, 39118 ); + _DICT.put( 20335, 39121 ); + _DICT.put( 20336, 39119 ); + _DICT.put( 20339, 35264 ); + _DICT.put( 20341, 38329 ); + _DICT.put( 20342, 39113 ); + _DICT.put( 20347, 39117 ); + _DICT.put( 20348, 36081 ); + _DICT.put( 20351, 36455 ); + _DICT.put( 20355, 35492 ); + _DICT.put( 20358, 39122 ); + _DICT.put( 20360, 39114 ); + _DICT.put( 20362, 64112 ); + _DICT.put( 20363, 38881 ); + _DICT.put( 20365, 36504 ); + _DICT.put( 20367, 39115 ); + _DICT.put( 20369, 39120 ); + _DICT.put( 20370, 64111 ); + _DICT.put( 20372, 64114 ); + _DICT.put( 20374, 39123 ); + _DICT.put( 20376, 39116 ); + _DICT.put( 20378, 64113 ); + _DICT.put( 20379, 35743 ); + _DICT.put( 20381, 35019 ); + _DICT.put( 20384, 35744 ); + _DICT.put( 20385, 35263 ); + _DICT.put( 20395, 39748 ); + _DICT.put( 20397, 38553 ); + _DICT.put( 20398, 38286 ); + _DICT.put( 20399, 36082 ); + _DICT.put( 20405, 36942 ); + _DICT.put( 20406, 38837 ); + _DICT.put( 20415, 38358 ); + _DICT.put( 20418, 35927 ); + _DICT.put( 20419, 37283 ); + _DICT.put( 20420, 35298 ); + _DICT.put( 20425, 64097 ); + _DICT.put( 20426, 36722 ); + _DICT.put( 20429, 64115 ); + _DICT.put( 20430, 39127 ); + _DICT.put( 20432, 39132 ); + _DICT.put( 20433, 39130 ); + _DICT.put( 20436, 39125 ); + _DICT.put( 20439, 37293 ); + _DICT.put( 20440, 39128 ); + _DICT.put( 20442, 39131 ); + _DICT.put( 20443, 39129 ); + _DICT.put( 20445, 38363 ); + _DICT.put( 20447, 39126 ); + _DICT.put( 20449, 36941 ); + _DICT.put( 20451, 38547 ); + _DICT.put( 20452, 39133 ); + _DICT.put( 20453, 39134 ); + _DICT.put( 20462, 36675 ); + _DICT.put( 20463, 39147 ); + _DICT.put( 20467, 37999 ); + _DICT.put( 20469, 38229 ); + _DICT.put( 20470, 39142 ); + _DICT.put( 20472, 38382 ); + _DICT.put( 20474, 35252 ); + _DICT.put( 20478, 39146 ); + _DICT.put( 20479, 64118 ); + _DICT.put( 20485, 39140 ); + _DICT.put( 20486, 39149 ); + _DICT.put( 20489, 37233 ); + _DICT.put( 20491, 36034 ); + _DICT.put( 20493, 38011 ); + _DICT.put( 20495, 57541 ); + _DICT.put( 20497, 39148 ); + _DICT.put( 20498, 37756 ); + _DICT.put( 20500, 39137 ); + _DICT.put( 20502, 36084 ); + _DICT.put( 20505, 36083 ); + _DICT.put( 20506, 39135 ); + _DICT.put( 20510, 64119 ); + _DICT.put( 20511, 36568 ); + _DICT.put( 20513, 39143 ); + _DICT.put( 20514, 64117 ); + _DICT.put( 20515, 38381 ); + _DICT.put( 20516, 37484 ); + _DICT.put( 20517, 39139 ); + _DICT.put( 20518, 35985 ); + _DICT.put( 20520, 39136 ); + _DICT.put( 20521, 39144 ); + _DICT.put( 20522, 39138 ); + _DICT.put( 20523, 38863 ); + _DICT.put( 20524, 39145 ); + _DICT.put( 20525, 39008 ); + _DICT.put( 20534, 35812 ); + _DICT.put( 20537, 35984 ); + _DICT.put( 20544, 64116 ); + _DICT.put( 20546, 64122 ); + _DICT.put( 20547, 39150 ); + _DICT.put( 20550, 64120 ); + _DICT.put( 20551, 39151 ); + _DICT.put( 20552, 39155 ); + _DICT.put( 20553, 35020 ); + _DICT.put( 20559, 38350 ); + _DICT.put( 20560, 39154 ); + _DICT.put( 20565, 39153 ); + _DICT.put( 20566, 39157 ); + _DICT.put( 20570, 39156 ); + _DICT.put( 20572, 37602 ); + _DICT.put( 20581, 35986 ); + _DICT.put( 20588, 39158 ); + _DICT.put( 20592, 64121 ); + _DICT.put( 20594, 36547 ); + _DICT.put( 20596, 37284 ); + _DICT.put( 20597, 37603 ); + _DICT.put( 20598, 35828 ); + _DICT.put( 20600, 39159 ); + _DICT.put( 20605, 35669 ); + _DICT.put( 20608, 39160 ); + _DICT.put( 20613, 39162 ); + _DICT.put( 20621, 38484 ); + _DICT.put( 20625, 35974 ); + _DICT.put( 20628, 64123 ); + _DICT.put( 20632, 36432 ); + _DICT.put( 20633, 38133 ); + _DICT.put( 20634, 39161 ); + _DICT.put( 20652, 36291 ); + _DICT.put( 20653, 38754 ); + _DICT.put( 20658, 39164 ); + _DICT.put( 20659, 39234 ); + _DICT.put( 20660, 39163 ); + _DICT.put( 20661, 36290 ); + _DICT.put( 20663, 36765 ); + _DICT.put( 20670, 35928 ); + _DICT.put( 20674, 39235 ); + _DICT.put( 20677, 35789 ); + _DICT.put( 20681, 39232 ); + _DICT.put( 20682, 39233 ); + _DICT.put( 20685, 37805 ); + _DICT.put( 20687, 37276 ); + _DICT.put( 20689, 35745 ); + _DICT.put( 20693, 38508 ); + _DICT.put( 20694, 39236 ); + _DICT.put( 20696, 64125 ); + _DICT.put( 20698, 38843 ); + _DICT.put( 20702, 39237 ); + _DICT.put( 20707, 39240 ); + _DICT.put( 20709, 39238 ); + _DICT.put( 20711, 37229 ); + _DICT.put( 20717, 39239 ); + _DICT.put( 20718, 39241 ); + _DICT.put( 20724, 64124 ); + _DICT.put( 20725, 39243 ); + _DICT.put( 20729, 39242 ); + _DICT.put( 20731, 38342 ); + _DICT.put( 20736, 35670 ); + _DICT.put( 20737, 39245 ); + _DICT.put( 20738, 39246 ); + _DICT.put( 20740, 35245 ); + _DICT.put( 20745, 39244 ); + _DICT.put( 20754, 36594 ); + _DICT.put( 20756, 39249 ); + _DICT.put( 20757, 39248 ); + _DICT.put( 20758, 39247 ); + _DICT.put( 20760, 39124 ); + _DICT.put( 20762, 39250 ); + _DICT.put( 20767, 36766 ); + _DICT.put( 20769, 39251 ); + _DICT.put( 20778, 38724 ); + _DICT.put( 20786, 38615 ); + _DICT.put( 20791, 39253 ); + _DICT.put( 20794, 39252 ); + _DICT.put( 20795, 39255 ); + _DICT.put( 20796, 39254 ); + _DICT.put( 20799, 39256 ); + _DICT.put( 20800, 39257 ); + _DICT.put( 20801, 35058 ); + _DICT.put( 20803, 36019 ); + _DICT.put( 20804, 35930 ); + _DICT.put( 20805, 36699 ); + _DICT.put( 20806, 37531 ); + _DICT.put( 20807, 35746 ); + _DICT.put( 20808, 37094 ); + _DICT.put( 20809, 36085 ); + _DICT.put( 20810, 64126 ); + _DICT.put( 20811, 36238 ); + _DICT.put( 20812, 39259 ); + _DICT.put( 20813, 38598 ); + _DICT.put( 20814, 37733 ); + _DICT.put( 20816, 36505 ); + _DICT.put( 20818, 39258 ); + _DICT.put( 20820, 39260 ); + _DICT.put( 20826, 37757 ); + _DICT.put( 20828, 35477 ); + _DICT.put( 20834, 39261 ); + _DICT.put( 20836, 64128 ); + _DICT.put( 20837, 37884 ); + _DICT.put( 20840, 37203 ); + _DICT.put( 20841, 39263 ); + _DICT.put( 20842, 39264 ); + _DICT.put( 20843, 38058 ); + _DICT.put( 20844, 36086 ); + _DICT.put( 20845, 39002 ); + _DICT.put( 20846, 39265 ); + _DICT.put( 20849, 35748 ); + _DICT.put( 20853, 38330 ); + _DICT.put( 20854, 37300 ); + _DICT.put( 20855, 35823 ); + _DICT.put( 20856, 37716 ); + _DICT.put( 20860, 35987 ); + _DICT.put( 20864, 39266 ); + _DICT.put( 20866, 39267 ); + _DICT.put( 20869, 37856 ); + _DICT.put( 20870, 35198 ); + _DICT.put( 20873, 39270 ); + _DICT.put( 20874, 36347 ); + _DICT.put( 20876, 39269 ); + _DICT.put( 20877, 36292 ); + _DICT.put( 20879, 39271 ); + _DICT.put( 20880, 58348 ); + _DICT.put( 20881, 39272 ); + _DICT.put( 20882, 38496 ); + _DICT.put( 20883, 39273 ); + _DICT.put( 20885, 39274 ); + _DICT.put( 20886, 39275 ); + _DICT.put( 20887, 36839 ); + _DICT.put( 20889, 36554 ); + _DICT.put( 20893, 64129 ); + _DICT.put( 20896, 35493 ); + _DICT.put( 20898, 39278 ); + _DICT.put( 20900, 39276 ); + _DICT.put( 20901, 38587 ); + _DICT.put( 20902, 39277 ); + _DICT.put( 20904, 38265 ); + _DICT.put( 20905, 39279 ); + _DICT.put( 20906, 39280 ); + _DICT.put( 20907, 39281 ); + _DICT.put( 20908, 37758 ); + _DICT.put( 20912, 39285 ); + _DICT.put( 20913, 39283 ); + _DICT.put( 20914, 39284 ); + _DICT.put( 20915, 39282 ); + _DICT.put( 20916, 36321 ); + _DICT.put( 20917, 39286 ); + _DICT.put( 20918, 38632 ); + _DICT.put( 20919, 38882 ); + _DICT.put( 20925, 39287 ); + _DICT.put( 20926, 64130 ); + _DICT.put( 20932, 37030 ); + _DICT.put( 20933, 39288 ); + _DICT.put( 20934, 36729 ); + _DICT.put( 20937, 39289 ); + _DICT.put( 20939, 37532 ); + _DICT.put( 20940, 38845 ); + _DICT.put( 20941, 37760 ); + _DICT.put( 20950, 39363 ); + _DICT.put( 20955, 39290 ); + _DICT.put( 20956, 60067 ); + _DICT.put( 20957, 35779 ); + _DICT.put( 20960, 39291 ); + _DICT.put( 20961, 38525 ); + _DICT.put( 20966, 36744 ); + _DICT.put( 20967, 37370 ); + _DICT.put( 20969, 39293 ); + _DICT.put( 20970, 37858 ); + _DICT.put( 20972, 64131 ); + _DICT.put( 20973, 39294 ); + _DICT.put( 20976, 39296 ); + _DICT.put( 20977, 35405 ); + _DICT.put( 20981, 39297 ); + _DICT.put( 20982, 35749 ); + _DICT.put( 20984, 37834 ); + _DICT.put( 20985, 35226 ); + _DICT.put( 20986, 36719 ); + _DICT.put( 20989, 38047 ); + _DICT.put( 20990, 39298 ); + _DICT.put( 20992, 37761 ); + _DICT.put( 20995, 36974 ); + _DICT.put( 20996, 39299 ); + _DICT.put( 20998, 38314 ); + _DICT.put( 20999, 37080 ); + _DICT.put( 21000, 35488 ); + _DICT.put( 21002, 35495 ); + _DICT.put( 21003, 39300 ); + _DICT.put( 21006, 39302 ); + _DICT.put( 21009, 35929 ); + _DICT.put( 21012, 39301 ); + _DICT.put( 21013, 64132 ); + _DICT.put( 21015, 38897 ); + _DICT.put( 21021, 36745 ); + _DICT.put( 21028, 38075 ); + _DICT.put( 21029, 38346 ); + _DICT.put( 21031, 39303 ); + _DICT.put( 21033, 38808 ); + _DICT.put( 21034, 39304 ); + _DICT.put( 21038, 39305 ); + _DICT.put( 21040, 37790 ); + _DICT.put( 21043, 39306 ); + _DICT.put( 21046, 37031 ); + _DICT.put( 21047, 36348 ); + _DICT.put( 21048, 35988 ); + _DICT.put( 21049, 39307 ); + _DICT.put( 21050, 36456 ); + _DICT.put( 21051, 36239 ); + _DICT.put( 21059, 37604 ); + _DICT.put( 21060, 39309 ); + _DICT.put( 21063, 37285 ); + _DICT.put( 21066, 36333 ); + _DICT.put( 21067, 39310 ); + _DICT.put( 21068, 39311 ); + _DICT.put( 21069, 37199 ); + _DICT.put( 21071, 39308 ); + _DICT.put( 21076, 39313 ); + _DICT.put( 21078, 38485 ); + _DICT.put( 21083, 36228 ); + _DICT.put( 21086, 39312 ); + _DICT.put( 21091, 35989 ); + _DICT.put( 21092, 36316 ); + _DICT.put( 21093, 38029 ); + _DICT.put( 21097, 39316 ); + _DICT.put( 21098, 39314 ); + _DICT.put( 21103, 38299 ); + _DICT.put( 21104, 36840 ); + _DICT.put( 21105, 39323 ); + _DICT.put( 21106, 35460 ); + _DICT.put( 21107, 39317 ); + _DICT.put( 21108, 39315 ); + _DICT.put( 21109, 37230 ); + _DICT.put( 21117, 39319 ); + _DICT.put( 21119, 39318 ); + _DICT.put( 21123, 35427 ); + _DICT.put( 21127, 35968 ); + _DICT.put( 21128, 39324 ); + _DICT.put( 21129, 38827 ); + _DICT.put( 21133, 39320 ); + _DICT.put( 21137, 39325 ); + _DICT.put( 21138, 39322 ); + _DICT.put( 21140, 39321 ); + _DICT.put( 21147, 38861 ); + _DICT.put( 21148, 64133 ); + _DICT.put( 21151, 36087 ); + _DICT.put( 21152, 35265 ); + _DICT.put( 21155, 38898 ); + _DICT.put( 21158, 64134 ); + _DICT.put( 21161, 36757 ); + _DICT.put( 21162, 37751 ); + _DICT.put( 21163, 36229 ); + _DICT.put( 21164, 39328 ); + _DICT.put( 21165, 39329 ); + _DICT.put( 21167, 64375 ); + _DICT.put( 21169, 38883 ); + _DICT.put( 21172, 38986 ); + _DICT.put( 21173, 39331 ); + _DICT.put( 21177, 36088 ); + _DICT.put( 21180, 39330 ); + _DICT.put( 21182, 35406 ); + _DICT.put( 21184, 64135 ); + _DICT.put( 21185, 39332 ); + _DICT.put( 21187, 38517 ); + _DICT.put( 21189, 37562 ); + _DICT.put( 21191, 38725 ); + _DICT.put( 21193, 38359 ); + _DICT.put( 21197, 39333 ); + _DICT.put( 21202, 59603 ); + _DICT.put( 21205, 37806 ); + _DICT.put( 21207, 39334 ); + _DICT.put( 21208, 35496 ); + _DICT.put( 21209, 38577 ); + _DICT.put( 21211, 64136 ); + _DICT.put( 21213, 36767 ); + _DICT.put( 21214, 39335 ); + _DICT.put( 21215, 38373 ); + _DICT.put( 21216, 39339 ); + _DICT.put( 21218, 37032 ); + _DICT.put( 21219, 39336 ); + _DICT.put( 21220, 35790 ); + _DICT.put( 21222, 39337 ); + _DICT.put( 21223, 35497 ); + _DICT.put( 21234, 35917 ); + _DICT.put( 21235, 39340 ); + _DICT.put( 21237, 39341 ); + _DICT.put( 21240, 39342 ); + _DICT.put( 21241, 39343 ); + _DICT.put( 21242, 36569 ); + _DICT.put( 21246, 36089 ); + _DICT.put( 21247, 38620 ); + _DICT.put( 21248, 64137 ); + _DICT.put( 21249, 38630 ); + _DICT.put( 21250, 37877 ); + _DICT.put( 21253, 38383 ); + _DICT.put( 21254, 39344 ); + _DICT.put( 21255, 64138 ); + _DICT.put( 21256, 39345 ); + _DICT.put( 21261, 39347 ); + _DICT.put( 21263, 39349 ); + _DICT.put( 21264, 39348 ); + _DICT.put( 21269, 39350 ); + _DICT.put( 21270, 35259 ); + _DICT.put( 21271, 38507 ); + _DICT.put( 21273, 36346 ); + _DICT.put( 21274, 39351 ); + _DICT.put( 21277, 37240 ); + _DICT.put( 21280, 36768 ); + _DICT.put( 21281, 35751 ); + _DICT.put( 21283, 39352 ); + _DICT.put( 21284, 64139 ); + _DICT.put( 21290, 38105 ); + _DICT.put( 21295, 39353 ); + _DICT.put( 21297, 39354 ); + _DICT.put( 21299, 39355 ); + _DICT.put( 21304, 39356 ); + _DICT.put( 21305, 38211 ); + _DICT.put( 21306, 35814 ); + _DICT.put( 21307, 35043 ); + _DICT.put( 21311, 37821 ); + _DICT.put( 21312, 39357 ); + _DICT.put( 21313, 36700 ); + _DICT.put( 21315, 37095 ); + _DICT.put( 21317, 39359 ); + _DICT.put( 21318, 39358 ); + _DICT.put( 21319, 36769 ); + _DICT.put( 21320, 36063 ); + _DICT.put( 21321, 39361 ); + _DICT.put( 21322, 38076 ); + _DICT.put( 21325, 39362 ); + _DICT.put( 21329, 38106 ); + _DICT.put( 21330, 37298 ); + _DICT.put( 21331, 37356 ); + _DICT.put( 21332, 35750 ); + _DICT.put( 21335, 37868 ); + _DICT.put( 21336, 37456 ); + _DICT.put( 21338, 38030 ); + _DICT.put( 21340, 38509 ); + _DICT.put( 21342, 39364 ); + _DICT.put( 21344, 37096 ); + _DICT.put( 21350, 35924 ); + _DICT.put( 21353, 39365 ); + _DICT.put( 21358, 39366 ); + _DICT.put( 21359, 35147 ); + _DICT.put( 21360, 35059 ); + _DICT.put( 21361, 35563 ); + _DICT.put( 21362, 64140 ); + _DICT.put( 21363, 37286 ); + _DICT.put( 21364, 35696 ); + _DICT.put( 21365, 38801 ); + _DICT.put( 21367, 39369 ); + _DICT.put( 21368, 35253 ); + _DICT.put( 21371, 39368 ); + _DICT.put( 21375, 35752 ); + _DICT.put( 21378, 39370 ); + _DICT.put( 21380, 38639 ); + _DICT.put( 21395, 64141 ); + _DICT.put( 21398, 39371 ); + _DICT.put( 21400, 38864 ); + _DICT.put( 21402, 36090 ); + _DICT.put( 21407, 36020 ); + _DICT.put( 21408, 39372 ); + _DICT.put( 21413, 39374 ); + _DICT.put( 21414, 39373 ); + _DICT.put( 21416, 36990 ); + _DICT.put( 21417, 35160 ); + _DICT.put( 21421, 35197 ); + _DICT.put( 21422, 39375 ); + _DICT.put( 21424, 39376 ); + _DICT.put( 21426, 64142 ); + _DICT.put( 21427, 36021 ); + _DICT.put( 21430, 39377 ); + _DICT.put( 21435, 35726 ); + _DICT.put( 21442, 36433 ); + _DICT.put( 21443, 39378 ); + _DICT.put( 21448, 38548 ); + _DICT.put( 21449, 36275 ); + _DICT.put( 21450, 35705 ); + _DICT.put( 21451, 38726 ); + _DICT.put( 21452, 37231 ); + _DICT.put( 21453, 38077 ); + _DICT.put( 21454, 36603 ); + _DICT.put( 21460, 36710 ); + _DICT.put( 21462, 36582 ); + _DICT.put( 21463, 36595 ); + _DICT.put( 21465, 36758 ); + _DICT.put( 21467, 38078 ); + _DICT.put( 21469, 64143 ); + _DICT.put( 21471, 39381 ); + _DICT.put( 21473, 35170 ); + _DICT.put( 21474, 37232 ); + _DICT.put( 21475, 36091 ); + _DICT.put( 21476, 36035 ); + _DICT.put( 21477, 35813 ); + _DICT.put( 21480, 39385 ); + _DICT.put( 21481, 37440 ); + _DICT.put( 21482, 37372 ); + _DICT.put( 21483, 35753 ); + _DICT.put( 21484, 36770 ); + _DICT.put( 21485, 39386 ); + _DICT.put( 21486, 39384 ); + _DICT.put( 21487, 35266 ); + _DICT.put( 21488, 37348 ); + _DICT.put( 21489, 36534 ); + _DICT.put( 21490, 36458 ); + _DICT.put( 21491, 35141 ); + _DICT.put( 21494, 35472 ); + _DICT.put( 21495, 36230 ); + _DICT.put( 21496, 36457 ); + _DICT.put( 21498, 39387 ); + _DICT.put( 21505, 39388 ); + _DICT.put( 21507, 35688 ); + _DICT.put( 21508, 35429 ); + _DICT.put( 21512, 36231 ); + _DICT.put( 21513, 35687 ); + _DICT.put( 21514, 37597 ); + _DICT.put( 21515, 35140 ); + _DICT.put( 21516, 37807 ); + _DICT.put( 21517, 38588 ); + _DICT.put( 21518, 36160 ); + _DICT.put( 21519, 38809 ); + _DICT.put( 21520, 37734 ); + _DICT.put( 21521, 36092 ); + _DICT.put( 21531, 35918 ); + _DICT.put( 21533, 39397 ); + _DICT.put( 21535, 35809 ); + _DICT.put( 21536, 38505 ); + _DICT.put( 21542, 38107 ); + _DICT.put( 21545, 39396 ); + _DICT.put( 21547, 35548 ); + _DICT.put( 21548, 39391 ); + _DICT.put( 21549, 39392 ); + _DICT.put( 21550, 39394 ); + _DICT.put( 21558, 39395 ); + _DICT.put( 21560, 35706 ); + _DICT.put( 21561, 36993 ); + _DICT.put( 21563, 38315 ); + _DICT.put( 21564, 39393 ); + _DICT.put( 21565, 39389 ); + _DICT.put( 21566, 36065 ); + _DICT.put( 21568, 39390 ); + _DICT.put( 21570, 38979 ); + _DICT.put( 21574, 38384 ); + _DICT.put( 21576, 37606 ); + _DICT.put( 21577, 36064 ); + _DICT.put( 21578, 36240 ); + _DICT.put( 21582, 39398 ); + _DICT.put( 21585, 37851 ); + _DICT.put( 21599, 39402 ); + _DICT.put( 21608, 36604 ); + _DICT.put( 21610, 36596 ); + _DICT.put( 21616, 39405 ); + _DICT.put( 21617, 39403 ); + _DICT.put( 21619, 38561 ); + _DICT.put( 21621, 39400 ); + _DICT.put( 21622, 39409 ); + _DICT.put( 21623, 39404 ); + _DICT.put( 21627, 39407 ); + _DICT.put( 21628, 36036 ); + _DICT.put( 21629, 38589 ); + _DICT.put( 21632, 39408 ); + _DICT.put( 21636, 39410 ); + _DICT.put( 21638, 39412 ); + _DICT.put( 21642, 64146 ); + _DICT.put( 21643, 36334 ); + _DICT.put( 21644, 39009 ); + _DICT.put( 21646, 39401 ); + _DICT.put( 21647, 39399 ); + _DICT.put( 21648, 39411 ); + _DICT.put( 21650, 39406 ); + _DICT.put( 21660, 64145 ); + _DICT.put( 21666, 39414 ); + _DICT.put( 21668, 39490 ); + _DICT.put( 21669, 39416 ); + _DICT.put( 21672, 39420 ); + _DICT.put( 21673, 64147 ); + _DICT.put( 21675, 39488 ); + _DICT.put( 21676, 39417 ); + _DICT.put( 21679, 39517 ); + _DICT.put( 21682, 36327 ); + _DICT.put( 21683, 35408 ); + _DICT.put( 21688, 39415 ); + _DICT.put( 21692, 39492 ); + _DICT.put( 21693, 35060 ); + _DICT.put( 21694, 39491 ); + _DICT.put( 21696, 34979 ); + _DICT.put( 21697, 38249 ); + _DICT.put( 21698, 39489 ); + _DICT.put( 21700, 39418 ); + _DICT.put( 21703, 39413 ); + _DICT.put( 21704, 39419 ); + _DICT.put( 21705, 36294 ); + _DICT.put( 21720, 39493 ); + _DICT.put( 21729, 35061 ); + _DICT.put( 21730, 39502 ); + _DICT.put( 21733, 39494 ); + _DICT.put( 21734, 39495 ); + _DICT.put( 21736, 36771 ); + _DICT.put( 21737, 38537 ); + _DICT.put( 21741, 39500 ); + _DICT.put( 21742, 39499 ); + _DICT.put( 21746, 37710 ); + _DICT.put( 21754, 39501 ); + _DICT.put( 21757, 39498 ); + _DICT.put( 21759, 64148 ); + _DICT.put( 21764, 35155 ); + _DICT.put( 21766, 36276 ); + _DICT.put( 21767, 36943 ); + _DICT.put( 21775, 39496 ); + _DICT.put( 21776, 37762 ); + _DICT.put( 21780, 39497 ); + _DICT.put( 21782, 34976 ); + _DICT.put( 21806, 39507 ); + _DICT.put( 21807, 38722 ); + _DICT.put( 21809, 36773 ); + _DICT.put( 21811, 39513 ); + _DICT.put( 21816, 39512 ); + _DICT.put( 21817, 39503 ); + _DICT.put( 21822, 37313 ); + _DICT.put( 21824, 39504 ); + _DICT.put( 21828, 37357 ); + _DICT.put( 21829, 39509 ); + _DICT.put( 21830, 36772 ); + _DICT.put( 21836, 39506 ); + _DICT.put( 21839, 38626 ); + _DICT.put( 21843, 35931 ); + _DICT.put( 21846, 39510 ); + _DICT.put( 21847, 39511 ); + _DICT.put( 21852, 39508 ); + _DICT.put( 21853, 39514 ); + _DICT.put( 21859, 39505 ); + _DICT.put( 21883, 39520 ); + _DICT.put( 21884, 39525 ); + _DICT.put( 21886, 39521 ); + _DICT.put( 21888, 39516 ); + _DICT.put( 21891, 39526 ); + _DICT.put( 21892, 37200 ); + _DICT.put( 21894, 64149 ); + _DICT.put( 21895, 39528 ); + _DICT.put( 21897, 36161 ); + _DICT.put( 21898, 39518 ); + _DICT.put( 21899, 37533 ); + _DICT.put( 21912, 39522 ); + _DICT.put( 21913, 39515 ); + _DICT.put( 21914, 35499 ); + _DICT.put( 21916, 35564 ); + _DICT.put( 21917, 35461 ); + _DICT.put( 21918, 39523 ); + _DICT.put( 21919, 39519 ); + _DICT.put( 21927, 35990 ); + _DICT.put( 21928, 39529 ); + _DICT.put( 21929, 39527 ); + _DICT.put( 21930, 37234 ); + _DICT.put( 21931, 35689 ); + _DICT.put( 21932, 35754 ); + _DICT.put( 21934, 39524 ); + _DICT.put( 21936, 35826 ); + _DICT.put( 21942, 35171 ); + _DICT.put( 21956, 39533 ); + _DICT.put( 21957, 39531 ); + _DICT.put( 21959, 39589 ); + _DICT.put( 21972, 39536 ); + _DICT.put( 21978, 39530 ); + _DICT.put( 21980, 39534 ); + _DICT.put( 21983, 39532 ); + _DICT.put( 21987, 36459 ); + _DICT.put( 21988, 39535 ); + _DICT.put( 22007, 39538 ); + _DICT.put( 22009, 39543 ); + _DICT.put( 22013, 39541 ); + _DICT.put( 22014, 39540 ); + _DICT.put( 22022, 37457 ); + _DICT.put( 22025, 35267 ); + _DICT.put( 22036, 39537 ); + _DICT.put( 22038, 39539 ); + _DICT.put( 22039, 36774 ); + _DICT.put( 22040, 35154 ); + _DICT.put( 22043, 39542 ); + _DICT.put( 22057, 35292 ); + _DICT.put( 22063, 39554 ); + _DICT.put( 22065, 36858 ); + _DICT.put( 22066, 39549 ); + _DICT.put( 22068, 39547 ); + _DICT.put( 22070, 39548 ); + _DICT.put( 22072, 39550 ); + _DICT.put( 22082, 35164 ); + _DICT.put( 22092, 37208 ); + _DICT.put( 22094, 39544 ); + _DICT.put( 22096, 39545 ); + _DICT.put( 22107, 35482 ); + _DICT.put( 22116, 39553 ); + _DICT.put( 22120, 35565 ); + _DICT.put( 22122, 39556 ); + _DICT.put( 22123, 39552 ); + _DICT.put( 22124, 39555 ); + _DICT.put( 22132, 38316 ); + _DICT.put( 22136, 37843 ); + _DICT.put( 22138, 38070 ); + _DICT.put( 22144, 39558 ); + _DICT.put( 22150, 39557 ); + _DICT.put( 22151, 35428 ); + _DICT.put( 22154, 39559 ); + _DICT.put( 22159, 39562 ); + _DICT.put( 22164, 39561 ); + _DICT.put( 22176, 39560 ); + _DICT.put( 22178, 37976 ); + _DICT.put( 22181, 39563 ); + _DICT.put( 22190, 39564 ); + _DICT.put( 22196, 39566 ); + _DICT.put( 22198, 39565 ); + _DICT.put( 22204, 39568 ); + _DICT.put( 22208, 39571 ); + _DICT.put( 22209, 39569 ); + _DICT.put( 22210, 39567 ); + _DICT.put( 22211, 39570 ); + _DICT.put( 22216, 39572 ); + _DICT.put( 22222, 39573 ); + _DICT.put( 22225, 39574 ); + _DICT.put( 22227, 39575 ); + _DICT.put( 22231, 39576 ); + _DICT.put( 22232, 39268 ); + _DICT.put( 22234, 36602 ); + _DICT.put( 22235, 36460 ); + _DICT.put( 22238, 35313 ); + _DICT.put( 22240, 35062 ); + _DICT.put( 22243, 37475 ); + _DICT.put( 22254, 39577 ); + _DICT.put( 22256, 36258 ); + _DICT.put( 22258, 35021 ); + _DICT.put( 22259, 36989 ); + _DICT.put( 22265, 39578 ); + _DICT.put( 22266, 36037 ); + _DICT.put( 22269, 36241 ); + _DICT.put( 22271, 39580 ); + _DICT.put( 22272, 39579 ); + _DICT.put( 22275, 38366 ); + _DICT.put( 22276, 39581 ); + _DICT.put( 22280, 39583 ); + _DICT.put( 22281, 39582 ); + _DICT.put( 22283, 39584 ); + _DICT.put( 22285, 39585 ); + _DICT.put( 22287, 35991 ); + _DICT.put( 22290, 35200 ); + _DICT.put( 22291, 39586 ); + _DICT.put( 22294, 39588 ); + _DICT.put( 22296, 39587 ); + _DICT.put( 22300, 39590 ); + _DICT.put( 22303, 37753 ); + _DICT.put( 22310, 39591 ); + _DICT.put( 22311, 34995 ); + _DICT.put( 22312, 36317 ); + _DICT.put( 22317, 35932 ); + _DICT.put( 22320, 37486 ); + _DICT.put( 22327, 39592 ); + _DICT.put( 22328, 39593 ); + _DICT.put( 22331, 39595 ); + _DICT.put( 22336, 39596 ); + _DICT.put( 22338, 36322 ); + _DICT.put( 22343, 35791 ); + _DICT.put( 22346, 38486 ); + _DICT.put( 22350, 39594 ); + _DICT.put( 22351, 39597 ); + _DICT.put( 22352, 36287 ); + _DICT.put( 22353, 36162 ); + _DICT.put( 22361, 64150 ); + _DICT.put( 22369, 39601 ); + _DICT.put( 22372, 36259 ); + _DICT.put( 22373, 64151 ); + _DICT.put( 22374, 37458 ); + _DICT.put( 22377, 39598 ); + _DICT.put( 22378, 37592 ); + _DICT.put( 22399, 39602 ); + _DICT.put( 22402, 36994 ); + _DICT.put( 22408, 39600 ); + _DICT.put( 22409, 39603 ); + _DICT.put( 22411, 35934 ); + _DICT.put( 22419, 39604 ); + _DICT.put( 22432, 39605 ); + _DICT.put( 22434, 36163 ); + _DICT.put( 22435, 35423 ); + _DICT.put( 22436, 39607 ); + _DICT.put( 22442, 39608 ); + _DICT.put( 22444, 64152 ); + _DICT.put( 22448, 39609 ); + _DICT.put( 22451, 39606 ); + _DICT.put( 22464, 39599 ); + _DICT.put( 22467, 39610 ); + _DICT.put( 22470, 39611 ); + _DICT.put( 22471, 64154 ); + _DICT.put( 22472, 64153 ); + _DICT.put( 22475, 38532 ); + _DICT.put( 22478, 36841 ); + _DICT.put( 22482, 39613 ); + _DICT.put( 22483, 39614 ); + _DICT.put( 22484, 39612 ); + _DICT.put( 22486, 39616 ); + _DICT.put( 22492, 37975 ); + _DICT.put( 22495, 35046 ); + _DICT.put( 22496, 38261 ); + _DICT.put( 22499, 39617 ); + _DICT.put( 22516, 36859 ); + _DICT.put( 22519, 36535 ); + _DICT.put( 22521, 38012 ); + _DICT.put( 22522, 35566 ); + _DICT.put( 22524, 36329 ); + _DICT.put( 22528, 38520 ); + _DICT.put( 22530, 37808 ); + _DICT.put( 22533, 35992 ); + _DICT.put( 22534, 37325 ); + _DICT.put( 22538, 39615 ); + _DICT.put( 22539, 39618 ); + _DICT.put( 22549, 37314 ); + _DICT.put( 22553, 39619 ); + _DICT.put( 22557, 39620 ); + _DICT.put( 22561, 39622 ); + _DICT.put( 22564, 37607 ); + _DICT.put( 22570, 35500 ); + _DICT.put( 22575, 60063 ); + _DICT.put( 22576, 35201 ); + _DICT.put( 22577, 38385 ); + _DICT.put( 22580, 36842 ); + _DICT.put( 22581, 37735 ); + _DICT.put( 22586, 36324 ); + _DICT.put( 22589, 39628 ); + _DICT.put( 22592, 38331 ); + _DICT.put( 22593, 38875 ); + _DICT.put( 22602, 35314 ); + _DICT.put( 22603, 39624 ); + _DICT.put( 22609, 37209 ); + _DICT.put( 22610, 39627 ); + _DICT.put( 22612, 37763 ); + _DICT.put( 22615, 37736 ); + _DICT.put( 22616, 37764 ); + _DICT.put( 22617, 38071 ); + _DICT.put( 22618, 37579 ); + _DICT.put( 22622, 36295 ); + _DICT.put( 22626, 39623 ); + _DICT.put( 22633, 35222 ); + _DICT.put( 22635, 37717 ); + _DICT.put( 22640, 39625 ); + _DICT.put( 22642, 39621 ); + _DICT.put( 22645, 36975 ); + _DICT.put( 22649, 39629 ); + _DICT.put( 22654, 36717 ); + _DICT.put( 22659, 35755 ); + _DICT.put( 22661, 39630 ); + _DICT.put( 22675, 38374 ); + _DICT.put( 22679, 37277 ); + _DICT.put( 22684, 37572 ); + _DICT.put( 22686, 64157 ); + _DICT.put( 22687, 39632 ); + _DICT.put( 22696, 38510 ); + _DICT.put( 22699, 39633 ); + _DICT.put( 22702, 39638 ); + _DICT.put( 22706, 64158 ); + _DICT.put( 22707, 38317 ); + _DICT.put( 22712, 39637 ); + _DICT.put( 22713, 39631 ); + _DICT.put( 22714, 39634 ); + _DICT.put( 22715, 39636 ); + _DICT.put( 22718, 36260 ); + _DICT.put( 22721, 38343 ); + _DICT.put( 22725, 39639 ); + _DICT.put( 22727, 37476 ); + _DICT.put( 22730, 35315 ); + _DICT.put( 22732, 36843 ); + _DICT.put( 22737, 39641 ); + _DICT.put( 22739, 39640 ); + _DICT.put( 22741, 36232 ); + _DICT.put( 22743, 39642 ); + _DICT.put( 22744, 39644 ); + _DICT.put( 22745, 39643 ); + _DICT.put( 22748, 39646 ); + _DICT.put( 22750, 39635 ); + _DICT.put( 22751, 39648 ); + _DICT.put( 22756, 39647 ); + _DICT.put( 22757, 39645 ); + _DICT.put( 22763, 36461 ); + _DICT.put( 22764, 36976 ); + _DICT.put( 22766, 37235 ); + _DICT.put( 22767, 39649 ); + _DICT.put( 22768, 37050 ); + _DICT.put( 22769, 35051 ); + _DICT.put( 22770, 38020 ); + _DICT.put( 22775, 37593 ); + _DICT.put( 22777, 39651 ); + _DICT.put( 22778, 39650 ); + _DICT.put( 22779, 39652 ); + _DICT.put( 22780, 39653 ); + _DICT.put( 22781, 39654 ); + _DICT.put( 22786, 39655 ); + _DICT.put( 22793, 38351 ); + _DICT.put( 22794, 39656 ); + _DICT.put( 22795, 64159 ); + _DICT.put( 22799, 35268 ); + _DICT.put( 22800, 39657 ); + _DICT.put( 22805, 38747 ); + _DICT.put( 22806, 35407 ); + _DICT.put( 22808, 39367 ); + _DICT.put( 22809, 36711 ); + _DICT.put( 22810, 37309 ); + _DICT.put( 22811, 39658 ); + _DICT.put( 22812, 38633 ); + _DICT.put( 22818, 38578 ); + _DICT.put( 22821, 39660 ); + _DICT.put( 22823, 37349 ); + _DICT.put( 22825, 37718 ); + _DICT.put( 22826, 37310 ); + _DICT.put( 22827, 38262 ); + _DICT.put( 22828, 39661 ); + _DICT.put( 22829, 39662 ); + _DICT.put( 22830, 35227 ); + _DICT.put( 22833, 36536 ); + _DICT.put( 22834, 39663 ); + _DICT.put( 22839, 35022 ); + _DICT.put( 22840, 39664 ); + _DICT.put( 22846, 39665 ); + _DICT.put( 22852, 35202 ); + _DICT.put( 22855, 35567 ); + _DICT.put( 22856, 37854 ); + _DICT.put( 22857, 38386 ); + _DICT.put( 22862, 39669 ); + _DICT.put( 22863, 37236 ); + _DICT.put( 22864, 39668 ); + _DICT.put( 22865, 35935 ); + _DICT.put( 22867, 64160 ); + _DICT.put( 22868, 38522 ); + _DICT.put( 22869, 39667 ); + _DICT.put( 22871, 37765 ); + _DICT.put( 22872, 39671 ); + _DICT.put( 22874, 39670 ); + _DICT.put( 22875, 64161 ); + _DICT.put( 22877, 64162 ); + _DICT.put( 22880, 39673 ); + _DICT.put( 22882, 39672 ); + _DICT.put( 22883, 64163 ); + _DICT.put( 22885, 35228 ); + _DICT.put( 22887, 39674 ); + _DICT.put( 22888, 36775 ); + _DICT.put( 22889, 39676 ); + _DICT.put( 22890, 37444 ); + _DICT.put( 22892, 39675 ); + _DICT.put( 22894, 38321 ); + _DICT.put( 22899, 36759 ); + _DICT.put( 22900, 37754 ); + _DICT.put( 22904, 39744 ); + _DICT.put( 22909, 36164 ); + _DICT.put( 22913, 39745 ); + _DICT.put( 22914, 37952 ); + _DICT.put( 22915, 38108 ); + _DICT.put( 22916, 38607 ); + _DICT.put( 22922, 37956 ); + _DICT.put( 22925, 39754 ); + _DICT.put( 22931, 35671 ); + _DICT.put( 22934, 38756 ); + _DICT.put( 22937, 38573 ); + _DICT.put( 22939, 39850 ); + _DICT.put( 22941, 39746 ); + _DICT.put( 22947, 39749 ); + _DICT.put( 22948, 64164 ); + _DICT.put( 22949, 37315 ); + _DICT.put( 22952, 38487 ); + _DICT.put( 22956, 37737 ); + _DICT.put( 22962, 39750 ); + _DICT.put( 22969, 38533 ); + _DICT.put( 22970, 64165 ); + _DICT.put( 22971, 36296 ); + _DICT.put( 22974, 36776 ); + _DICT.put( 22982, 39751 ); + _DICT.put( 22985, 36463 ); + _DICT.put( 22987, 36462 ); + _DICT.put( 22992, 34999 ); + _DICT.put( 22993, 36038 ); + _DICT.put( 22995, 37033 ); + _DICT.put( 22996, 35023 ); + _DICT.put( 23001, 39755 ); + _DICT.put( 23002, 39756 ); + _DICT.put( 23004, 39753 ); + _DICT.put( 23013, 35159 ); + _DICT.put( 23014, 35501 ); + _DICT.put( 23016, 39752 ); + _DICT.put( 23018, 38595 ); + _DICT.put( 23019, 38224 ); + _DICT.put( 23030, 34982 ); + _DICT.put( 23035, 35063 ); + _DICT.put( 23039, 36464 ); + _DICT.put( 23041, 35024 ); + _DICT.put( 23043, 34977 ); + _DICT.put( 23049, 39761 ); + _DICT.put( 23057, 39759 ); + _DICT.put( 23064, 38586 ); + _DICT.put( 23066, 39762 ); + _DICT.put( 23068, 39760 ); + _DICT.put( 23071, 39758 ); + _DICT.put( 23072, 36944 ); + _DICT.put( 23077, 39757 ); + _DICT.put( 23081, 38360 ); + _DICT.put( 23087, 36066 ); + _DICT.put( 23093, 39766 ); + _DICT.put( 23094, 39767 ); + _DICT.put( 23100, 36777 ); + _DICT.put( 23104, 39763 ); + _DICT.put( 23105, 38987 ); + _DICT.put( 23110, 37995 ); + _DICT.put( 23113, 39765 ); + _DICT.put( 23130, 36261 ); + _DICT.put( 23138, 39768 ); + _DICT.put( 23142, 38263 ); + _DICT.put( 23146, 39769 ); + _DICT.put( 23148, 39764 ); + _DICT.put( 23167, 38585 ); + _DICT.put( 23186, 38013 ); + _DICT.put( 23194, 39770 ); + _DICT.put( 23195, 38225 ); + _DICT.put( 23228, 39771 ); + _DICT.put( 23229, 39775 ); + _DICT.put( 23230, 39772 ); + _DICT.put( 23233, 35269 ); + _DICT.put( 23234, 39774 ); + _DICT.put( 23241, 36537 ); + _DICT.put( 23243, 39773 ); + _DICT.put( 23244, 35993 ); + _DICT.put( 23248, 39787 ); + _DICT.put( 23254, 39780 ); + _DICT.put( 23255, 39777 ); + _DICT.put( 23265, 37508 ); + _DICT.put( 23267, 39776 ); + _DICT.put( 23270, 39778 ); + _DICT.put( 23273, 39779 ); + _DICT.put( 23290, 39781 ); + _DICT.put( 23291, 39782 ); + _DICT.put( 23305, 35568 ); + _DICT.put( 23307, 39784 ); + _DICT.put( 23308, 39783 ); + _DICT.put( 23318, 39785 ); + _DICT.put( 23330, 36844 ); + _DICT.put( 23338, 39788 ); + _DICT.put( 23340, 37594 ); + _DICT.put( 23344, 35172 ); + _DICT.put( 23346, 39786 ); + _DICT.put( 23350, 39789 ); + _DICT.put( 23358, 39790 ); + _DICT.put( 23360, 39793 ); + _DICT.put( 23363, 39791 ); + _DICT.put( 23365, 39792 ); + _DICT.put( 23376, 36465 ); + _DICT.put( 23377, 39794 ); + _DICT.put( 23380, 36165 ); + _DICT.put( 23381, 39795 ); + _DICT.put( 23382, 64166 ); + _DICT.put( 23383, 36506 ); + _DICT.put( 23384, 37302 ); + _DICT.put( 23386, 39796 ); + _DICT.put( 23387, 39797 ); + _DICT.put( 23388, 36473 ); + _DICT.put( 23389, 36166 ); + _DICT.put( 23391, 38608 ); + _DICT.put( 23395, 35655 ); + _DICT.put( 23396, 36039 ); + _DICT.put( 23397, 39798 ); + _DICT.put( 23398, 35447 ); + _DICT.put( 23401, 39799 ); + _DICT.put( 23403, 37303 ); + _DICT.put( 23408, 39800 ); + _DICT.put( 23409, 39841 ); + _DICT.put( 23411, 39801 ); + _DICT.put( 23413, 39802 ); + _DICT.put( 23416, 39803 ); + _DICT.put( 23418, 39805 ); + _DICT.put( 23424, 39806 ); + _DICT.put( 23427, 39808 ); + _DICT.put( 23429, 37358 ); + _DICT.put( 23431, 35142 ); + _DICT.put( 23432, 36583 ); + _DICT.put( 23433, 35008 ); + _DICT.put( 23435, 37238 ); + _DICT.put( 23436, 35502 ); + _DICT.put( 23437, 36531 ); + _DICT.put( 23439, 36167 ); + _DICT.put( 23445, 37766 ); + _DICT.put( 23447, 36672 ); + _DICT.put( 23448, 35503 ); + _DICT.put( 23449, 37512 ); + _DICT.put( 23450, 37608 ); + _DICT.put( 23451, 34998 ); + _DICT.put( 23452, 35672 ); + _DICT.put( 23453, 38387 ); + _DICT.put( 23455, 36544 ); + _DICT.put( 23458, 35697 ); + _DICT.put( 23459, 37097 ); + _DICT.put( 23460, 36538 ); + _DICT.put( 23461, 38727 ); + _DICT.put( 23462, 39809 ); + _DICT.put( 23470, 35707 ); + _DICT.put( 23472, 36297 ); + _DICT.put( 23475, 35409 ); + _DICT.put( 23476, 35203 ); + _DICT.put( 23477, 36778 ); + _DICT.put( 23478, 35270 ); + _DICT.put( 23480, 39810 ); + _DICT.put( 23481, 38757 ); + _DICT.put( 23487, 36712 ); + _DICT.put( 23488, 64167 ); + _DICT.put( 23490, 36578 ); + _DICT.put( 23491, 39811 ); + _DICT.put( 23492, 35569 ); + _DICT.put( 23493, 37840 ); + _DICT.put( 23494, 38567 ); + _DICT.put( 23495, 39812 ); + _DICT.put( 23497, 39813 ); + _DICT.put( 23500, 38264 ); + _DICT.put( 23504, 39815 ); + _DICT.put( 23506, 35494 ); + _DICT.put( 23507, 35829 ); + _DICT.put( 23508, 39814 ); + _DICT.put( 23512, 64169 ); + _DICT.put( 23515, 35504 ); + _DICT.put( 23517, 36945 ); + _DICT.put( 23518, 39819 ); + _DICT.put( 23519, 36416 ); + _DICT.put( 23521, 35271 ); + _DICT.put( 23522, 39818 ); + _DICT.put( 23524, 39816 ); + _DICT.put( 23525, 39820 ); + _DICT.put( 23526, 39817 ); + _DICT.put( 23527, 37962 ); + _DICT.put( 23528, 40651 ); + _DICT.put( 23529, 36946 ); + _DICT.put( 23531, 39821 ); + _DICT.put( 23532, 64170 ); + _DICT.put( 23534, 38846 ); + _DICT.put( 23536, 39822 ); + _DICT.put( 23539, 39824 ); + _DICT.put( 23541, 37534 ); + _DICT.put( 23542, 39823 ); + _DICT.put( 23544, 37025 ); + _DICT.put( 23546, 36507 ); + _DICT.put( 23550, 37326 ); + _DICT.put( 23551, 36597 ); + _DICT.put( 23553, 38293 ); + _DICT.put( 23554, 37098 ); + _DICT.put( 23556, 36555 ); + _DICT.put( 23557, 39825 ); + _DICT.put( 23558, 36779 ); + _DICT.put( 23559, 39826 ); + _DICT.put( 23560, 39827 ); + _DICT.put( 23561, 35025 ); + _DICT.put( 23562, 37304 ); + _DICT.put( 23563, 36977 ); + _DICT.put( 23565, 39828 ); + _DICT.put( 23566, 37809 ); + _DICT.put( 23567, 36780 ); + _DICT.put( 23569, 36781 ); + _DICT.put( 23571, 39829 ); + _DICT.put( 23574, 37099 ); + _DICT.put( 23578, 36782 ); + _DICT.put( 23582, 64171 ); + _DICT.put( 23584, 39830 ); + _DICT.put( 23586, 39831 ); + _DICT.put( 23588, 38622 ); + _DICT.put( 23592, 39832 ); + _DICT.put( 23597, 35780 ); + _DICT.put( 23601, 36673 ); + _DICT.put( 23608, 39833 ); + _DICT.put( 23609, 39834 ); + _DICT.put( 23610, 36570 ); + _DICT.put( 23611, 36939 ); + _DICT.put( 23612, 37874 ); + _DICT.put( 23613, 36979 ); + _DICT.put( 23614, 38134 ); + _DICT.put( 23615, 37953 ); + _DICT.put( 23616, 35783 ); + _DICT.put( 23617, 39835 ); + _DICT.put( 23621, 35727 ); + _DICT.put( 23622, 39836 ); + _DICT.put( 23624, 35836 ); + _DICT.put( 23626, 37837 ); + _DICT.put( 23627, 35246 ); + _DICT.put( 23629, 36466 ); + _DICT.put( 23630, 39837 ); + _DICT.put( 23631, 39840 ); + _DICT.put( 23632, 39839 ); + _DICT.put( 23633, 35835 ); + _DICT.put( 23635, 39838 ); + _DICT.put( 23637, 37719 ); + _DICT.put( 23646, 37294 ); + _DICT.put( 23648, 37738 ); + _DICT.put( 23649, 36550 ); + _DICT.put( 23652, 37239 ); + _DICT.put( 23653, 38810 ); + _DICT.put( 23660, 39842 ); + _DICT.put( 23662, 39843 ); + _DICT.put( 23663, 37844 ); + _DICT.put( 23665, 36434 ); + _DICT.put( 23670, 39845 ); + _DICT.put( 23673, 39846 ); + _DICT.put( 23692, 39847 ); + _DICT.put( 23696, 35570 ); + _DICT.put( 23697, 39848 ); + _DICT.put( 23700, 39849 ); + _DICT.put( 23713, 35242 ); + _DICT.put( 23718, 64172 ); + _DICT.put( 23720, 37210 ); + _DICT.put( 23721, 35554 ); + _DICT.put( 23723, 39851 ); + _DICT.put( 23724, 38566 ); + _DICT.put( 23729, 37328 ); + _DICT.put( 23731, 35448 ); + _DICT.put( 23734, 39853 ); + _DICT.put( 23735, 39855 ); + _DICT.put( 23736, 35549 ); + _DICT.put( 23738, 64173 ); + _DICT.put( 23739, 39852 ); + _DICT.put( 23740, 39854 ); + _DICT.put( 23742, 39857 ); + _DICT.put( 23749, 39856 ); + _DICT.put( 23751, 39858 ); + _DICT.put( 23769, 39859 ); + _DICT.put( 23776, 37819 ); + _DICT.put( 23777, 35756 ); + _DICT.put( 23784, 35299 ); + _DICT.put( 23785, 39860 ); + _DICT.put( 23786, 39865 ); + _DICT.put( 23789, 39863 ); + _DICT.put( 23791, 38389 ); + _DICT.put( 23792, 38388 ); + _DICT.put( 23797, 64174 ); + _DICT.put( 23798, 37767 ); + _DICT.put( 23802, 39862 ); + _DICT.put( 23803, 36723 ); + _DICT.put( 23805, 39861 ); + _DICT.put( 23815, 37010 ); + _DICT.put( 23819, 39866 ); + _DICT.put( 23822, 36328 ); + _DICT.put( 23825, 39872 ); + _DICT.put( 23828, 39873 ); + _DICT.put( 23829, 39867 ); + _DICT.put( 23830, 35410 ); + _DICT.put( 23831, 39868 ); + _DICT.put( 23832, 39877 ); + _DICT.put( 23833, 39876 ); + _DICT.put( 23834, 39875 ); + _DICT.put( 23835, 39871 ); + _DICT.put( 23839, 39870 ); + _DICT.put( 23842, 39874 ); + _DICT.put( 23847, 64175 ); + _DICT.put( 23849, 38390 ); + _DICT.put( 23874, 64178 ); + _DICT.put( 23883, 39881 ); + _DICT.put( 23884, 39878 ); + _DICT.put( 23886, 39880 ); + _DICT.put( 23888, 38802 ); + _DICT.put( 23890, 39879 ); + _DICT.put( 23891, 64176 ); + _DICT.put( 23900, 39869 ); + _DICT.put( 23913, 37011 ); + _DICT.put( 23916, 39882 ); + _DICT.put( 23917, 64179 ); + _DICT.put( 23919, 36277 ); + _DICT.put( 23923, 39883 ); + _DICT.put( 23926, 39884 ); + _DICT.put( 23938, 39887 ); + _DICT.put( 23940, 39886 ); + _DICT.put( 23943, 39885 ); + _DICT.put( 23947, 37768 ); + _DICT.put( 23948, 39864 ); + _DICT.put( 23952, 39893 ); + _DICT.put( 23965, 39889 ); + _DICT.put( 23970, 39888 ); + _DICT.put( 23980, 39890 ); + _DICT.put( 23982, 39891 ); + _DICT.put( 23991, 39894 ); + _DICT.put( 23992, 64180 ); + _DICT.put( 23993, 64181 ); + _DICT.put( 23994, 38884 ); + _DICT.put( 23996, 39895 ); + _DICT.put( 23997, 39892 ); + _DICT.put( 24009, 39896 ); + _DICT.put( 24012, 35550 ); + _DICT.put( 24013, 39897 ); + _DICT.put( 24016, 64182 ); + _DICT.put( 24018, 39899 ); + _DICT.put( 24019, 39898 ); + _DICT.put( 24022, 39900 ); + _DICT.put( 24027, 39901 ); + _DICT.put( 24029, 37100 ); + _DICT.put( 24030, 36674 ); + _DICT.put( 24033, 36740 ); + _DICT.put( 24035, 37251 ); + _DICT.put( 24037, 36168 ); + _DICT.put( 24038, 36278 ); + _DICT.put( 24039, 36169 ); + _DICT.put( 24040, 35728 ); + _DICT.put( 24043, 39902 ); + _DICT.put( 24046, 36279 ); + _DICT.put( 24049, 36040 ); + _DICT.put( 24050, 39903 ); + _DICT.put( 24051, 38564 ); + _DICT.put( 24052, 37986 ); + _DICT.put( 24053, 39904 ); + _DICT.put( 24055, 36170 ); + _DICT.put( 24059, 35498 ); + _DICT.put( 24061, 37446 ); + _DICT.put( 24062, 35792 ); + _DICT.put( 24066, 36467 ); + _DICT.put( 24067, 38266 ); + _DICT.put( 24070, 38079 ); + _DICT.put( 24075, 39905 ); + _DICT.put( 24076, 35571 ); + _DICT.put( 24081, 39908 ); + _DICT.put( 24086, 37535 ); + _DICT.put( 24089, 39907 ); + _DICT.put( 24090, 39906 ); + _DICT.put( 24091, 39909 ); + _DICT.put( 24093, 37609 ); + _DICT.put( 24101, 36995 ); + _DICT.put( 24107, 36468 ); + _DICT.put( 24109, 37064 ); + _DICT.put( 24111, 37329 ); + _DICT.put( 24112, 35649 ); + _DICT.put( 24115, 37536 ); + _DICT.put( 24118, 39910 ); + _DICT.put( 24119, 39911 ); + _DICT.put( 24120, 36845 ); + _DICT.put( 24125, 38488 ); + _DICT.put( 24128, 39914 ); + _DICT.put( 24131, 39913 ); + _DICT.put( 24132, 39912 ); + _DICT.put( 24133, 38301 ); + _DICT.put( 24135, 39921 ); + _DICT.put( 24140, 38521 ); + _DICT.put( 24142, 39915 ); + _DICT.put( 24148, 39917 ); + _DICT.put( 24149, 38539 ); + _DICT.put( 24151, 39916 ); + _DICT.put( 24159, 39918 ); + _DICT.put( 24161, 38054 ); + _DICT.put( 24162, 39919 ); + _DICT.put( 24163, 38332 ); + _DICT.put( 24164, 39920 ); + _DICT.put( 24178, 35505 ); + _DICT.put( 24179, 38333 ); + _DICT.put( 24180, 37966 ); + _DICT.put( 24181, 39922 ); + _DICT.put( 24182, 39923 ); + _DICT.put( 24184, 36171 ); + _DICT.put( 24185, 35506 ); + _DICT.put( 24186, 39924 ); + _DICT.put( 24187, 36022 ); + _DICT.put( 24188, 38755 ); + _DICT.put( 24189, 38728 ); + _DICT.put( 24190, 35572 ); + _DICT.put( 24191, 39926 ); + _DICT.put( 24193, 37537 ); + _DICT.put( 24195, 36172 ); + _DICT.put( 24196, 36783 ); + _DICT.put( 24199, 38109 ); + _DICT.put( 24202, 36784 ); + _DICT.put( 24207, 36760 ); + _DICT.put( 24213, 37610 ); + _DICT.put( 24214, 38391 ); + _DICT.put( 24215, 37720 ); + _DICT.put( 24218, 36173 ); + _DICT.put( 24220, 38267 ); + _DICT.put( 24224, 39927 ); + _DICT.put( 24230, 37752 ); + _DICT.put( 24231, 36288 ); + _DICT.put( 24235, 36041 ); + _DICT.put( 24237, 37611 ); + _DICT.put( 24245, 35009 ); + _DICT.put( 24246, 36750 ); + _DICT.put( 24247, 36174 ); + _DICT.put( 24248, 38758 ); + _DICT.put( 24257, 39928 ); + _DICT.put( 24258, 39929 ); + _DICT.put( 24259, 38000 ); + _DICT.put( 24264, 39930 ); + _DICT.put( 24265, 38901 ); + _DICT.put( 24266, 38988 ); + _DICT.put( 24271, 39932 ); + _DICT.put( 24272, 39931 ); + _DICT.put( 24275, 35430 ); + _DICT.put( 24278, 40000 ); + _DICT.put( 24282, 40003 ); + _DICT.put( 24283, 40004 ); + _DICT.put( 24285, 40002 ); + _DICT.put( 24287, 38239 ); + _DICT.put( 24288, 36785 ); + _DICT.put( 24289, 40006 ); + _DICT.put( 24290, 40005 ); + _DICT.put( 24291, 40001 ); + _DICT.put( 24296, 40007 ); + _DICT.put( 24297, 40008 ); + _DICT.put( 24300, 40009 ); + _DICT.put( 24304, 40012 ); + _DICT.put( 24305, 40010 ); + _DICT.put( 24307, 40011 ); + _DICT.put( 24308, 40013 ); + _DICT.put( 24310, 35204 ); + _DICT.put( 24311, 37612 ); + _DICT.put( 24312, 40014 ); + _DICT.put( 24314, 35994 ); + _DICT.put( 24315, 35316 ); + _DICT.put( 24316, 37973 ); + _DICT.put( 24318, 40015 ); + _DICT.put( 24319, 37881 ); + _DICT.put( 24321, 38361 ); + _DICT.put( 24323, 40016 ); + _DICT.put( 24324, 38989 ); + _DICT.put( 24329, 40017 ); + _DICT.put( 24330, 38334 ); + _DICT.put( 24331, 40020 ); + _DICT.put( 24332, 39071 ); + _DICT.put( 24333, 39087 ); + _DICT.put( 24335, 36526 ); + _DICT.put( 24336, 37875 ); + _DICT.put( 24337, 40021 ); + _DICT.put( 24339, 35708 ); + _DICT.put( 24340, 37538 ); + _DICT.put( 24341, 35064 ); + _DICT.put( 24342, 40022 ); + _DICT.put( 24343, 38308 ); + _DICT.put( 24344, 36175 ); + _DICT.put( 24347, 37487 ); + _DICT.put( 24351, 37613 ); + _DICT.put( 24353, 64183 ); + _DICT.put( 24357, 38637 ); + _DICT.put( 24358, 36023 ); + _DICT.put( 24359, 36042 ); + _DICT.put( 24361, 40023 ); + _DICT.put( 24365, 40024 ); + _DICT.put( 24367, 40030 ); + _DICT.put( 24369, 36579 ); + _DICT.put( 24372, 64184 ); + _DICT.put( 24373, 37539 ); + _DICT.put( 24375, 35757 ); + _DICT.put( 24376, 40025 ); + _DICT.put( 24380, 38218 ); + _DICT.put( 24382, 37477 ); + _DICT.put( 24385, 40026 ); + _DICT.put( 24389, 64103 ); + _DICT.put( 24392, 40027 ); + _DICT.put( 24394, 35758 ); + _DICT.put( 24396, 40028 ); + _DICT.put( 24398, 40029 ); + _DICT.put( 24401, 40031 ); + _DICT.put( 24403, 37782 ); + _DICT.put( 24406, 40032 ); + _DICT.put( 24407, 40033 ); + _DICT.put( 24409, 40034 ); + _DICT.put( 24412, 40019 ); + _DICT.put( 24413, 40018 ); + _DICT.put( 24417, 40035 ); + _DICT.put( 24418, 35936 ); + _DICT.put( 24422, 38214 ); + _DICT.put( 24423, 64185 ); + _DICT.put( 24425, 36298 ); + _DICT.put( 24426, 38230 ); + _DICT.put( 24427, 37540 ); + _DICT.put( 24428, 38250 ); + _DICT.put( 24429, 40036 ); + _DICT.put( 24432, 36786 ); + _DICT.put( 24433, 35173 ); + _DICT.put( 24435, 40037 ); + _DICT.put( 24439, 40038 ); + _DICT.put( 24441, 38640 ); + _DICT.put( 24444, 38110 ); + _DICT.put( 24447, 40041 ); + _DICT.put( 24448, 35229 ); + _DICT.put( 24449, 37034 ); + _DICT.put( 24450, 40040 ); + _DICT.put( 24451, 40039 ); + _DICT.put( 24452, 35937 ); + _DICT.put( 24453, 37330 ); + _DICT.put( 24455, 40045 ); + _DICT.put( 24456, 40043 ); + _DICT.put( 24458, 40042 ); + _DICT.put( 24459, 38821 ); + _DICT.put( 24460, 36067 ); + _DICT.put( 24464, 36761 ); + _DICT.put( 24465, 40044 ); + _DICT.put( 24466, 37739 ); + _DICT.put( 24467, 36701 ); + _DICT.put( 24471, 37822 ); + _DICT.put( 24472, 40048 ); + _DICT.put( 24473, 40047 ); + _DICT.put( 24478, 40046 ); + _DICT.put( 24480, 40049 ); + _DICT.put( 24481, 36068 ); + _DICT.put( 24488, 40050 ); + _DICT.put( 24489, 38300 ); + _DICT.put( 24490, 36730 ); + _DICT.put( 24493, 40051 ); + _DICT.put( 24494, 38135 ); + _DICT.put( 24499, 37823 ); + _DICT.put( 24500, 37541 ); + _DICT.put( 24503, 64186 ); + _DICT.put( 24505, 37711 ); + _DICT.put( 24508, 40052 ); + _DICT.put( 24509, 35658 ); + _DICT.put( 24515, 36947 ); + _DICT.put( 24517, 38219 ); + _DICT.put( 24524, 35573 ); + _DICT.put( 24525, 37957 ); + _DICT.put( 24534, 40053 ); + _DICT.put( 24535, 36469 ); + _DICT.put( 24536, 38489 ); + _DICT.put( 24537, 38490 ); + _DICT.put( 24540, 35230 ); + _DICT.put( 24541, 40058 ); + _DICT.put( 24542, 64187 ); + _DICT.put( 24544, 37513 ); + _DICT.put( 24548, 40055 ); + _DICT.put( 24555, 35317 ); + _DICT.put( 24560, 40107 ); + _DICT.put( 24561, 40057 ); + _DICT.put( 24565, 37967 ); + _DICT.put( 24568, 40056 ); + _DICT.put( 24571, 40054 ); + _DICT.put( 24573, 36250 ); + _DICT.put( 24575, 40060 ); + _DICT.put( 24590, 40067 ); + _DICT.put( 24591, 40073 ); + _DICT.put( 24592, 40065 ); + _DICT.put( 24594, 37755 ); + _DICT.put( 24597, 40070 ); + _DICT.put( 24598, 38268 ); + _DICT.put( 24601, 40064 ); + _DICT.put( 24603, 40069 ); + _DICT.put( 24604, 38885 ); + _DICT.put( 24605, 36470 ); + _DICT.put( 24608, 37331 ); + _DICT.put( 24609, 40061 ); + _DICT.put( 24613, 35709 ); + _DICT.put( 24614, 40072 ); + _DICT.put( 24615, 37035 ); + _DICT.put( 24616, 35205 ); + _DICT.put( 24617, 40066 ); + _DICT.put( 24618, 35318 ); + _DICT.put( 24619, 40071 ); + _DICT.put( 24623, 35759 ); + _DICT.put( 24625, 40068 ); + _DICT.put( 24634, 40074 ); + _DICT.put( 24641, 40076 ); + _DICT.put( 24642, 40086 ); + _DICT.put( 24643, 40084 ); + _DICT.put( 24646, 40081 ); + _DICT.put( 24650, 40080 ); + _DICT.put( 24651, 38902 ); + _DICT.put( 24653, 40082 ); + _DICT.put( 24656, 35760 ); + _DICT.put( 24658, 36176 ); + _DICT.put( 24661, 36762 ); + _DICT.put( 24665, 40089 ); + _DICT.put( 24666, 40075 ); + _DICT.put( 24669, 64188 ); + _DICT.put( 24671, 40079 ); + _DICT.put( 24672, 40062 ); + _DICT.put( 24674, 35320 ); + _DICT.put( 24675, 40083 ); + _DICT.put( 24676, 40085 ); + _DICT.put( 24677, 37488 ); + _DICT.put( 24680, 36262 ); + _DICT.put( 24681, 35254 ); + _DICT.put( 24682, 40077 ); + _DICT.put( 24683, 40088 ); + _DICT.put( 24684, 40087 ); + _DICT.put( 24685, 35761 ); + _DICT.put( 24687, 37287 ); + _DICT.put( 24688, 35462 ); + _DICT.put( 24693, 35938 ); + _DICT.put( 24695, 40078 ); + _DICT.put( 24705, 40090 ); + _DICT.put( 24707, 40093 ); + _DICT.put( 24708, 40095 ); + _DICT.put( 24709, 64189 ); + _DICT.put( 24713, 36539 ); + _DICT.put( 24714, 64190 ); + _DICT.put( 24715, 40101 ); + _DICT.put( 24716, 37614 ); + _DICT.put( 24717, 40091 ); + _DICT.put( 24722, 40099 ); + _DICT.put( 24724, 35319 ); + _DICT.put( 24726, 40097 ); + _DICT.put( 24727, 40098 ); + _DICT.put( 24730, 40094 ); + _DICT.put( 24731, 40096 ); + _DICT.put( 24735, 36069 ); + _DICT.put( 24736, 38729 ); + _DICT.put( 24739, 35507 ); + _DICT.put( 24742, 35192 ); + _DICT.put( 24743, 40100 ); + _DICT.put( 24745, 37977 ); + _DICT.put( 24746, 34987 ); + _DICT.put( 24754, 38111 ); + _DICT.put( 24755, 40059 ); + _DICT.put( 24756, 40106 ); + _DICT.put( 24757, 40110 ); + _DICT.put( 24758, 38627 ); + _DICT.put( 24760, 40103 ); + _DICT.put( 24764, 37769 ); + _DICT.put( 24765, 40108 ); + _DICT.put( 24773, 36846 ); + _DICT.put( 24774, 40109 ); + _DICT.put( 24775, 37845 ); + _DICT.put( 24785, 39014 ); + _DICT.put( 24787, 40105 ); + _DICT.put( 24789, 64192 ); + _DICT.put( 24792, 40111 ); + _DICT.put( 24794, 36251 ); + _DICT.put( 24796, 37065 ); + _DICT.put( 24798, 64191 ); + _DICT.put( 24799, 35026 ); + _DICT.put( 24800, 40104 ); + _DICT.put( 24801, 40102 ); + _DICT.put( 24803, 37241 ); + _DICT.put( 24807, 40092 ); + _DICT.put( 24808, 36435 ); + _DICT.put( 24816, 37316 ); + _DICT.put( 24817, 40123 ); + _DICT.put( 24818, 64194 ); + _DICT.put( 24819, 37242 ); + _DICT.put( 24820, 40118 ); + _DICT.put( 24822, 40115 ); + _DICT.put( 24823, 40116 ); + _DICT.put( 24825, 36580 ); + _DICT.put( 24826, 40119 ); + _DICT.put( 24827, 40122 ); + _DICT.put( 24832, 40117 ); + _DICT.put( 24833, 36676 ); + _DICT.put( 24835, 40120 ); + _DICT.put( 24838, 40114 ); + _DICT.put( 24840, 38650 ); + _DICT.put( 24841, 38649 ); + _DICT.put( 24845, 40124 ); + _DICT.put( 24846, 40125 ); + _DICT.put( 24847, 35027 ); + _DICT.put( 24849, 64195 ); + _DICT.put( 24853, 40113 ); + _DICT.put( 24858, 35824 ); + _DICT.put( 24859, 34980 ); + _DICT.put( 24863, 35508 ); + _DICT.put( 24864, 64193 ); + _DICT.put( 24865, 40121 ); + _DICT.put( 24871, 40129 ); + _DICT.put( 24872, 40128 ); + _DICT.put( 24876, 40133 ); + _DICT.put( 24880, 64197 ); + _DICT.put( 24884, 40134 ); + _DICT.put( 24887, 64196 ); + _DICT.put( 24892, 40132 ); + _DICT.put( 24893, 40135 ); + _DICT.put( 24894, 40127 ); + _DICT.put( 24895, 40131 ); + _DICT.put( 24898, 40136 ); + _DICT.put( 24900, 40137 ); + _DICT.put( 24903, 40126 ); + _DICT.put( 24904, 36508 ); + _DICT.put( 24906, 40130 ); + _DICT.put( 24907, 37332 ); + _DICT.put( 24908, 36177 ); + _DICT.put( 24909, 40112 ); + _DICT.put( 24910, 36948 ); + _DICT.put( 24915, 40150 ); + _DICT.put( 24917, 38375 ); + _DICT.put( 24920, 40140 ); + _DICT.put( 24921, 40141 ); + _DICT.put( 24922, 40142 ); + _DICT.put( 24925, 40149 ); + _DICT.put( 24927, 40148 ); + _DICT.put( 24930, 38557 ); + _DICT.put( 24931, 35509 ); + _DICT.put( 24933, 40146 ); + _DICT.put( 24935, 35940 ); + _DICT.put( 24936, 35411 ); + _DICT.put( 24939, 40143 ); + _DICT.put( 24942, 38838 ); + _DICT.put( 24943, 40145 ); + _DICT.put( 24944, 35028 ); + _DICT.put( 24945, 40147 ); + _DICT.put( 24947, 40138 ); + _DICT.put( 24948, 40144 ); + _DICT.put( 24949, 40151 ); + _DICT.put( 24950, 35939 ); + _DICT.put( 24951, 40139 ); + _DICT.put( 24958, 38780 ); + _DICT.put( 24962, 38730 ); + _DICT.put( 24967, 40154 ); + _DICT.put( 24970, 40158 ); + _DICT.put( 24974, 37278 ); + _DICT.put( 24976, 38903 ); + _DICT.put( 24977, 40159 ); + _DICT.put( 24980, 40156 ); + _DICT.put( 24982, 40153 ); + _DICT.put( 24984, 64198 ); + _DICT.put( 24985, 40152 ); + _DICT.put( 24986, 40157 ); + _DICT.put( 24996, 38318 ); + _DICT.put( 24999, 37810 ); + _DICT.put( 25001, 35941 ); + _DICT.put( 25003, 40160 ); + _DICT.put( 25004, 40155 ); + _DICT.put( 25006, 40161 ); + _DICT.put( 25010, 35995 ); + _DICT.put( 25014, 35247 ); + _DICT.put( 25018, 40169 ); + _DICT.put( 25022, 35510 ); + _DICT.put( 25027, 40167 ); + _DICT.put( 25030, 40168 ); + _DICT.put( 25031, 36263 ); + _DICT.put( 25032, 40166 ); + _DICT.put( 25033, 40164 ); + _DICT.put( 25034, 40163 ); + _DICT.put( 25035, 40170 ); + _DICT.put( 25036, 40162 ); + _DICT.put( 25037, 40172 ); + _DICT.put( 25040, 35321 ); + _DICT.put( 25059, 40174 ); + _DICT.put( 25062, 40173 ); + _DICT.put( 25074, 37542 ); + _DICT.put( 25076, 40177 ); + _DICT.put( 25078, 40175 ); + _DICT.put( 25079, 40165 ); + _DICT.put( 25080, 35996 ); + _DICT.put( 25082, 40176 ); + _DICT.put( 25084, 40180 ); + _DICT.put( 25085, 40179 ); + _DICT.put( 25086, 40181 ); + _DICT.put( 25087, 40178 ); + _DICT.put( 25088, 40182 ); + _DICT.put( 25096, 40183 ); + _DICT.put( 25097, 40184 ); + _DICT.put( 25098, 38376 ); + _DICT.put( 25100, 40186 ); + _DICT.put( 25101, 40185 ); + _DICT.put( 25102, 36702 ); + _DICT.put( 25104, 37036 ); + _DICT.put( 25105, 35300 ); + _DICT.put( 25106, 35322 ); + _DICT.put( 25107, 64199 ); + _DICT.put( 25108, 40187 ); + _DICT.put( 25110, 35005 ); + _DICT.put( 25114, 37066 ); + _DICT.put( 25115, 40188 ); + _DICT.put( 25117, 59073 ); + _DICT.put( 25118, 40256 ); + _DICT.put( 25119, 35969 ); + _DICT.put( 25121, 40257 ); + _DICT.put( 25126, 37101 ); + _DICT.put( 25130, 40258 ); + _DICT.put( 25134, 40259 ); + _DICT.put( 25135, 35673 ); + _DICT.put( 25136, 40260 ); + _DICT.put( 25138, 40261 ); + _DICT.put( 25139, 40262 ); + _DICT.put( 25140, 37333 ); + _DICT.put( 25144, 36043 ); + _DICT.put( 25147, 38623 ); + _DICT.put( 25151, 38491 ); + _DICT.put( 25152, 36746 ); + _DICT.put( 25153, 40263 ); + _DICT.put( 25159, 37102 ); + _DICT.put( 25160, 59323 ); + _DICT.put( 25161, 38112 ); + _DICT.put( 25163, 36584 ); + _DICT.put( 25165, 36299 ); + _DICT.put( 25166, 40264 ); + _DICT.put( 25171, 37317 ); + _DICT.put( 25173, 38309 ); + _DICT.put( 25176, 37359 ); + _DICT.put( 25179, 40267 ); + _DICT.put( 25182, 40265 ); + _DICT.put( 25184, 40268 ); + _DICT.put( 25187, 40266 ); + _DICT.put( 25192, 40269 ); + _DICT.put( 25198, 38319 ); + _DICT.put( 25201, 34997 ); + _DICT.put( 25206, 38269 ); + _DICT.put( 25209, 38113 ); + _DICT.put( 25212, 40270 ); + _DICT.put( 25214, 40273 ); + _DICT.put( 25215, 36787 ); + _DICT.put( 25216, 35674 ); + _DICT.put( 25218, 40271 ); + _DICT.put( 25219, 40278 ); + _DICT.put( 25220, 36788 ); + _DICT.put( 25225, 40272 ); + _DICT.put( 25226, 37987 ); + _DICT.put( 25233, 38781 ); + _DICT.put( 25234, 40274 ); + _DICT.put( 25235, 40275 ); + _DICT.put( 25236, 40279 ); + _DICT.put( 25237, 37770 ); + _DICT.put( 25238, 40276 ); + _DICT.put( 25239, 36178 ); + _DICT.put( 25240, 37084 ); + _DICT.put( 25243, 40293 ); + _DICT.put( 25244, 38066 ); + _DICT.put( 25246, 37360 ); + _DICT.put( 25254, 64200 ); + _DICT.put( 25259, 38114 ); + _DICT.put( 25260, 40363 ); + _DICT.put( 25265, 38392 ); + _DICT.put( 25269, 37615 ); + _DICT.put( 25273, 38549 ); + _DICT.put( 25275, 40282 ); + _DICT.put( 25276, 35231 ); + _DICT.put( 25277, 37514 ); + _DICT.put( 25282, 40291 ); + _DICT.put( 25285, 37459 ); + _DICT.put( 25286, 40285 ); + _DICT.put( 25287, 40292 ); + _DICT.put( 25288, 40287 ); + _DICT.put( 25289, 40294 ); + _DICT.put( 25290, 40290 ); + _DICT.put( 25292, 40289 ); + _DICT.put( 25293, 38031 ); + _DICT.put( 25295, 40283 ); + _DICT.put( 25296, 35323 ); + _DICT.put( 25297, 40281 ); + _DICT.put( 25298, 35729 ); + _DICT.put( 25299, 37361 ); + _DICT.put( 25300, 40277 ); + _DICT.put( 25303, 40280 ); + _DICT.put( 25304, 36179 ); + _DICT.put( 25305, 37081 ); + _DICT.put( 25307, 36789 ); + _DICT.put( 25308, 40288 ); + _DICT.put( 25309, 38001 ); + _DICT.put( 25312, 35730 ); + _DICT.put( 25313, 35431 ); + _DICT.put( 25324, 35463 ); + _DICT.put( 25325, 36928 ); + _DICT.put( 25326, 40296 ); + _DICT.put( 25327, 40301 ); + _DICT.put( 25329, 40297 ); + _DICT.put( 25331, 35997 ); + _DICT.put( 25333, 40302 ); + _DICT.put( 25334, 36417 ); + _DICT.put( 25335, 36233 ); + _DICT.put( 25342, 36677 ); + _DICT.put( 25343, 40284 ); + _DICT.put( 25345, 36509 ); + _DICT.put( 25346, 40299 ); + _DICT.put( 25351, 36471 ); + _DICT.put( 25352, 40300 ); + _DICT.put( 25353, 35010 ); + _DICT.put( 25356, 40295 ); + _DICT.put( 25361, 37543 ); + _DICT.put( 25369, 35731 ); + _DICT.put( 25375, 35762 ); + _DICT.put( 25383, 40298 ); + _DICT.put( 25384, 34981 ); + _DICT.put( 25387, 36289 ); + _DICT.put( 25391, 36949 ); + _DICT.put( 25402, 37616 ); + _DICT.put( 25405, 38098 ); + _DICT.put( 25406, 40304 ); + _DICT.put( 25407, 37245 ); + _DICT.put( 25417, 37288 ); + _DICT.put( 25420, 36426 ); + _DICT.put( 25421, 40305 ); + _DICT.put( 25423, 40307 ); + _DICT.put( 25424, 40303 ); + _DICT.put( 25429, 38367 ); + _DICT.put( 25431, 37563 ); + _DICT.put( 25436, 37243 ); + _DICT.put( 25447, 38393 ); + _DICT.put( 25448, 36556 ); + _DICT.put( 25449, 40320 ); + _DICT.put( 25451, 40318 ); + _DICT.put( 25454, 37016 ); + _DICT.put( 25458, 35998 ); + _DICT.put( 25462, 40312 ); + _DICT.put( 25463, 36791 ); + _DICT.put( 25466, 37862 ); + _DICT.put( 25467, 37968 ); + _DICT.put( 25472, 40310 ); + _DICT.put( 25475, 37244 ); + _DICT.put( 25480, 36598 ); + _DICT.put( 25481, 40315 ); + _DICT.put( 25484, 36790 ); + _DICT.put( 25486, 40309 ); + _DICT.put( 25487, 40314 ); + _DICT.put( 25490, 38002 ); + _DICT.put( 25494, 40308 ); + _DICT.put( 25496, 35904 ); + _DICT.put( 25499, 35452 ); + _DICT.put( 25503, 40316 ); + _DICT.put( 25504, 38825 ); + _DICT.put( 25505, 36300 ); + _DICT.put( 25506, 37460 ); + _DICT.put( 25507, 40313 ); + _DICT.put( 25509, 37082 ); + _DICT.put( 25511, 36180 ); + _DICT.put( 25512, 36996 ); + _DICT.put( 25513, 35206 ); + _DICT.put( 25514, 37211 ); + _DICT.put( 25515, 40311 ); + _DICT.put( 25516, 35684 ); + _DICT.put( 25522, 35942 ); + _DICT.put( 25524, 37581 ); + _DICT.put( 25525, 40317 ); + _DICT.put( 25531, 37246 ); + _DICT.put( 25534, 40321 ); + _DICT.put( 25536, 40323 ); + _DICT.put( 25539, 37301 ); + _DICT.put( 25540, 40329 ); + _DICT.put( 25542, 40324 ); + _DICT.put( 25545, 40326 ); + _DICT.put( 25551, 38240 ); + _DICT.put( 25552, 37617 ); + _DICT.put( 25554, 40327 ); + _DICT.put( 25558, 38731 ); + _DICT.put( 25562, 38759 ); + _DICT.put( 25563, 35511 ); + _DICT.put( 25569, 34988 ); + _DICT.put( 25571, 40325 ); + _DICT.put( 25577, 40322 ); + _DICT.put( 25582, 35574 ); + _DICT.put( 25588, 35207 ); + _DICT.put( 25589, 64201 ); + _DICT.put( 25590, 40328 ); + _DICT.put( 25594, 38760 ); + _DICT.put( 25606, 40332 ); + _DICT.put( 25613, 37305 ); + _DICT.put( 25615, 40339 ); + _DICT.put( 25619, 40333 ); + _DICT.put( 25622, 40330 ); + _DICT.put( 25623, 40337 ); + _DICT.put( 25628, 40306 ); + _DICT.put( 25638, 40334 ); + _DICT.put( 25640, 40338 ); + _DICT.put( 25644, 38080 ); + _DICT.put( 25645, 37771 ); + _DICT.put( 25652, 40331 ); + _DICT.put( 25654, 40335 ); + _DICT.put( 25658, 35943 ); + _DICT.put( 25662, 36335 ); + _DICT.put( 25666, 37083 ); + _DICT.put( 25678, 40343 ); + _DICT.put( 25688, 37701 ); + _DICT.put( 25696, 64202 ); + _DICT.put( 25703, 40340 ); + _DICT.put( 25705, 38528 ); + _DICT.put( 25711, 40341 ); + _DICT.put( 25718, 40342 ); + _DICT.put( 25720, 38604 ); + _DICT.put( 25722, 37024 ); + _DICT.put( 25731, 35970 ); + _DICT.put( 25736, 40349 ); + _DICT.put( 25746, 36436 ); + _DICT.put( 25747, 40346 ); + _DICT.put( 25749, 40345 ); + _DICT.put( 25754, 37969 ); + _DICT.put( 25757, 64203 ); + _DICT.put( 25758, 37811 ); + _DICT.put( 25764, 37712 ); + _DICT.put( 25765, 40347 ); + _DICT.put( 25769, 40348 ); + _DICT.put( 25771, 38287 ); + _DICT.put( 25773, 37988 ); + _DICT.put( 25774, 36418 ); + _DICT.put( 25776, 37103 ); + _DICT.put( 25778, 38511 ); + _DICT.put( 25785, 35432 ); + _DICT.put( 25787, 40355 ); + _DICT.put( 25788, 40350 ); + _DICT.put( 25793, 38761 ); + _DICT.put( 25794, 40357 ); + _DICT.put( 25797, 40353 ); + _DICT.put( 25799, 40354 ); + _DICT.put( 25805, 37248 ); + _DICT.put( 25806, 64204 ); + _DICT.put( 25810, 40352 ); + _DICT.put( 25812, 40286 ); + _DICT.put( 25816, 40356 ); + _DICT.put( 25818, 40351 ); + _DICT.put( 25824, 40361 ); + _DICT.put( 25825, 40362 ); + _DICT.put( 25826, 37702 ); + _DICT.put( 25827, 40364 ); + _DICT.put( 25830, 36419 ); + _DICT.put( 25831, 40359 ); + _DICT.put( 25836, 35675 ); + _DICT.put( 25839, 40365 ); + _DICT.put( 25841, 40358 ); + _DICT.put( 25842, 40369 ); + _DICT.put( 25844, 40368 ); + _DICT.put( 25846, 40367 ); + _DICT.put( 25850, 40370 ); + _DICT.put( 25853, 40372 ); + _DICT.put( 25854, 36847 ); + _DICT.put( 25856, 40371 ); + _DICT.put( 25861, 40375 ); + _DICT.put( 25880, 40373 ); + _DICT.put( 25884, 40374 ); + _DICT.put( 25885, 40336 ); + _DICT.put( 25891, 40377 ); + _DICT.put( 25892, 40376 ); + _DICT.put( 25898, 40344 ); + _DICT.put( 25899, 40378 ); + _DICT.put( 25900, 40366 ); + _DICT.put( 25903, 36472 ); + _DICT.put( 25908, 40379 ); + _DICT.put( 25909, 40380 ); + _DICT.put( 25910, 40382 ); + _DICT.put( 25911, 40381 ); + _DICT.put( 25912, 40383 ); + _DICT.put( 25913, 35324 ); + _DICT.put( 25915, 36181 ); + _DICT.put( 25918, 38394 ); + _DICT.put( 25919, 37037 ); + _DICT.put( 25925, 36044 ); + _DICT.put( 25928, 40385 ); + _DICT.put( 25933, 40388 ); + _DICT.put( 25934, 64205 ); + _DICT.put( 25935, 38257 ); + _DICT.put( 25937, 35710 ); + _DICT.put( 25941, 40387 ); + _DICT.put( 25942, 40386 ); + _DICT.put( 25943, 38003 ); + _DICT.put( 25944, 40389 ); + _DICT.put( 25945, 35763 ); + _DICT.put( 25949, 40391 ); + _DICT.put( 25950, 40390 ); + _DICT.put( 25954, 35512 ); + _DICT.put( 25955, 36437 ); + _DICT.put( 25958, 37846 ); + _DICT.put( 25964, 35944 ); + _DICT.put( 25968, 37012 ); + _DICT.put( 25970, 40392 ); + _DICT.put( 25972, 37038 ); + _DICT.put( 25973, 37703 ); + _DICT.put( 25975, 38270 ); + _DICT.put( 25976, 40393 ); + _DICT.put( 25986, 40394 ); + _DICT.put( 25987, 40395 ); + _DICT.put( 25991, 38326 ); + _DICT.put( 25992, 39804 ); + _DICT.put( 25993, 37060 ); + _DICT.put( 25996, 38251 ); + _DICT.put( 25998, 36310 ); + _DICT.put( 26000, 38115 ); + _DICT.put( 26001, 38081 ); + _DICT.put( 26007, 37740 ); + _DICT.put( 26009, 38847 ); + _DICT.put( 26011, 40397 ); + _DICT.put( 26012, 36558 ); + _DICT.put( 26015, 40398 ); + _DICT.put( 26017, 34996 ); + _DICT.put( 26020, 35794 ); + _DICT.put( 26021, 37067 ); + _DICT.put( 26023, 38272 ); + _DICT.put( 26027, 40399 ); + _DICT.put( 26028, 36449 ); + _DICT.put( 26029, 37478 ); + _DICT.put( 26031, 36474 ); + _DICT.put( 26032, 36950 ); + _DICT.put( 26039, 40400 ); + _DICT.put( 26041, 38395 ); + _DICT.put( 26044, 35223 ); + _DICT.put( 26045, 36475 ); + _DICT.put( 26049, 40403 ); + _DICT.put( 26051, 40401 ); + _DICT.put( 26052, 40404 ); + _DICT.put( 26053, 38839 ); + _DICT.put( 26054, 40402 ); + _DICT.put( 26059, 37113 ); + _DICT.put( 26060, 40405 ); + _DICT.put( 26063, 37296 ); + _DICT.put( 26066, 40406 ); + _DICT.put( 26071, 35576 ); + _DICT.put( 26073, 40408 ); + _DICT.put( 26075, 40407 ); + _DICT.put( 26080, 40409 ); + _DICT.put( 26081, 40410 ); + _DICT.put( 26082, 35577 ); + _DICT.put( 26085, 37882 ); + _DICT.put( 26086, 37461 ); + _DICT.put( 26087, 35724 ); + _DICT.put( 26088, 36476 ); + _DICT.put( 26089, 37249 ); + _DICT.put( 26092, 36731 ); + _DICT.put( 26093, 34990 ); + _DICT.put( 26097, 40411 ); + _DICT.put( 26106, 35232 ); + _DICT.put( 26107, 40415 ); + _DICT.put( 26112, 64206 ); + _DICT.put( 26114, 36182 ); + _DICT.put( 26115, 40414 ); + _DICT.put( 26118, 36265 ); + _DICT.put( 26119, 36792 ); + _DICT.put( 26121, 64209 ); + _DICT.put( 26122, 40413 ); + _DICT.put( 26124, 36793 ); + _DICT.put( 26126, 38590 ); + _DICT.put( 26127, 36264 ); + _DICT.put( 26131, 35029 ); + _DICT.put( 26132, 37068 ); + _DICT.put( 26133, 64207 ); + _DICT.put( 26140, 40420 ); + _DICT.put( 26142, 64211 ); + _DICT.put( 26143, 37039 ); + _DICT.put( 26144, 35174 ); + _DICT.put( 26148, 64212 ); + _DICT.put( 26149, 36724 ); + _DICT.put( 26151, 38534 ); + _DICT.put( 26152, 36336 ); + _DICT.put( 26157, 36794 ); + _DICT.put( 26158, 64210 ); + _DICT.put( 26159, 37029 ); + _DICT.put( 26161, 64099 ); + _DICT.put( 26164, 40419 ); + _DICT.put( 26165, 40417 ); + _DICT.put( 26166, 40418 ); + _DICT.put( 26171, 64208 ); + _DICT.put( 26172, 37515 ); + _DICT.put( 26175, 40517 ); + _DICT.put( 26177, 40424 ); + _DICT.put( 26178, 36510 ); + _DICT.put( 26179, 36183 ); + _DICT.put( 26180, 40422 ); + _DICT.put( 26185, 40423 ); + _DICT.put( 26187, 36951 ); + _DICT.put( 26191, 40421 ); + _DICT.put( 26194, 36430 ); + _DICT.put( 26199, 64214 ); + _DICT.put( 26201, 64215 ); + _DICT.put( 26205, 40426 ); + _DICT.put( 26206, 40425 ); + _DICT.put( 26207, 40430 ); + _DICT.put( 26210, 40431 ); + _DICT.put( 26212, 40427 ); + _DICT.put( 26213, 64213 ); + _DICT.put( 26214, 35393 ); + _DICT.put( 26215, 40428 ); + _DICT.put( 26216, 40429 ); + _DICT.put( 26217, 38099 ); + _DICT.put( 26222, 38273 ); + _DICT.put( 26223, 35945 ); + _DICT.put( 26224, 40432 ); + _DICT.put( 26227, 64217 ); + _DICT.put( 26228, 37040 ); + _DICT.put( 26230, 36795 ); + _DICT.put( 26234, 37489 ); + _DICT.put( 26241, 35781 ); + _DICT.put( 26243, 40433 ); + _DICT.put( 26244, 40437 ); + _DICT.put( 26247, 35273 ); + _DICT.put( 26248, 40434 ); + _DICT.put( 26249, 40436 ); + _DICT.put( 26254, 40435 ); + _DICT.put( 26257, 36747 ); + _DICT.put( 26262, 37479 ); + _DICT.put( 26263, 35011 ); + _DICT.put( 26264, 40438 ); + _DICT.put( 26265, 64218 ); + _DICT.put( 26269, 40439 ); + _DICT.put( 26272, 64219 ); + _DICT.put( 26274, 37544 ); + _DICT.put( 26278, 38895 ); + _DICT.put( 26283, 36450 ); + _DICT.put( 26286, 38377 ); + _DICT.put( 26290, 64220 ); + _DICT.put( 26292, 38492 ); + _DICT.put( 26296, 40513 ); + _DICT.put( 26297, 40441 ); + _DICT.put( 26300, 40444 ); + _DICT.put( 26302, 40443 ); + _DICT.put( 26303, 64221 ); + _DICT.put( 26305, 40440 ); + _DICT.put( 26308, 40512 ); + _DICT.put( 26311, 37852 ); + _DICT.put( 26313, 40442 ); + _DICT.put( 26326, 40514 ); + _DICT.put( 26329, 36748 ); + _DICT.put( 26330, 40515 ); + _DICT.put( 26332, 38762 ); + _DICT.put( 26333, 38040 ); + m_initialized = true; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_b.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_b.java new file mode 100644 index 0000000..db3e4fc --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_b.java @@ -0,0 +1,3093 @@ +/* + * cp932_b.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.bocoree + * + * jp.sourceforge.lipsync.bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.bocoree; + +import java.util.*; + +public class cp932_b { + private static HashMap _DICT = new HashMap(); + private static boolean m_initialized = false; + + public static int getMinKey() { + return 26336; + } + + public static int getMaxKey() { + return 35997; + } + + public static int get( int key ) { + if( !m_initialized ){ + init(); + } + if ( _DICT.containsKey( key ) ) { + return ((Integer) _DICT.get( key )).intValue(); + } else { + return -1; + } + } + + private static void init() { + _DICT.put( 26336, 40516 ); + _DICT.put( 26342, 40518 ); + _DICT.put( 26345, 40519 ); + _DICT.put( 26352, 40520 ); + _DICT.put( 26354, 35784 ); + _DICT.put( 26355, 35175 ); + _DICT.put( 26356, 36184 ); + _DICT.put( 26357, 40521 ); + _DICT.put( 26359, 40522 ); + _DICT.put( 26360, 36753 ); + _DICT.put( 26361, 37250 ); + _DICT.put( 26362, 64222 ); + _DICT.put( 26363, 64102 ); + _DICT.put( 26364, 39382 ); + _DICT.put( 26365, 37213 ); + _DICT.put( 26366, 37212 ); + _DICT.put( 26367, 37334 ); + _DICT.put( 26368, 36293 ); + _DICT.put( 26371, 39152 ); + _DICT.put( 26376, 35982 ); + _DICT.put( 26377, 38732 ); + _DICT.put( 26379, 38396 ); + _DICT.put( 26381, 38302 ); + _DICT.put( 26382, 64223 ); + _DICT.put( 26383, 40523 ); + _DICT.put( 26388, 36337 ); + _DICT.put( 26389, 37565 ); + _DICT.put( 26390, 40524 ); + _DICT.put( 26391, 38990 ); + _DICT.put( 26395, 38493 ); + _DICT.put( 26397, 37545 ); + _DICT.put( 26398, 40525 ); + _DICT.put( 26399, 35578 ); + _DICT.put( 26406, 40526 ); + _DICT.put( 26407, 40527 ); + _DICT.put( 26408, 38616 ); + _DICT.put( 26410, 38562 ); + _DICT.put( 26411, 38550 ); + _DICT.put( 26412, 38523 ); + _DICT.put( 26413, 36420 ); + _DICT.put( 26414, 40529 ); + _DICT.put( 26417, 36585 ); + _DICT.put( 26420, 38512 ); + _DICT.put( 26422, 40531 ); + _DICT.put( 26423, 40534 ); + _DICT.put( 26424, 40533 ); + _DICT.put( 26426, 35575 ); + _DICT.put( 26429, 35712 ); + _DICT.put( 26431, 40530 ); + _DICT.put( 26433, 40532 ); + _DICT.put( 26438, 40535 ); + _DICT.put( 26441, 37017 ); + _DICT.put( 26446, 38811 ); + _DICT.put( 26447, 35015 ); + _DICT.put( 26448, 36318 ); + _DICT.put( 26449, 37306 ); + _DICT.put( 26451, 36571 ); + _DICT.put( 26454, 36849 ); + _DICT.put( 26457, 40538 ); + _DICT.put( 26460, 37741 ); + _DICT.put( 26462, 40536 ); + _DICT.put( 26463, 37289 ); + _DICT.put( 26464, 40537 ); + _DICT.put( 26465, 36848 ); + _DICT.put( 26466, 38619 ); + _DICT.put( 26467, 40539 ); + _DICT.put( 26468, 40540 ); + _DICT.put( 26469, 38792 ); + _DICT.put( 26470, 64225 ); + _DICT.put( 26474, 40545 ); + _DICT.put( 26477, 36185 ); + _DICT.put( 26479, 38004 ); + _DICT.put( 26480, 40542 ); + _DICT.put( 26481, 37772 ); + _DICT.put( 26482, 40412 ); + _DICT.put( 26483, 40416 ); + _DICT.put( 26485, 35694 ); + _DICT.put( 26487, 37990 ); + _DICT.put( 26492, 40544 ); + _DICT.put( 26494, 36796 ); + _DICT.put( 26495, 38082 ); + _DICT.put( 26501, 40550 ); + _DICT.put( 26503, 38136 ); + _DICT.put( 26505, 40541 ); + _DICT.put( 26507, 40547 ); + _DICT.put( 26508, 40546 ); + _DICT.put( 26512, 37069 ); + _DICT.put( 26517, 38541 ); + _DICT.put( 26519, 38865 ); + _DICT.put( 26522, 38535 ); + _DICT.put( 26524, 35274 ); + _DICT.put( 26525, 36477 ); + _DICT.put( 26528, 39015 ); + _DICT.put( 26529, 40549 ); + _DICT.put( 26530, 37013 ); + _DICT.put( 26534, 40548 ); + _DICT.put( 26537, 40543 ); + _DICT.put( 26543, 36045 ); + _DICT.put( 26547, 40555 ); + _DICT.put( 26548, 40553 ); + _DICT.put( 26550, 35275 ); + _DICT.put( 26551, 40551 ); + _DICT.put( 26552, 40557 ); + _DICT.put( 26553, 40563 ); + _DICT.put( 26555, 64226 ); + _DICT.put( 26560, 64228 ); + _DICT.put( 26561, 37318 ); + _DICT.put( 26564, 38335 ); + _DICT.put( 26566, 40565 ); + _DICT.put( 26570, 38209 ); + _DICT.put( 26574, 40564 ); + _DICT.put( 26575, 38032 ); + _DICT.put( 26576, 38494 ); + _DICT.put( 26577, 35513 ); + _DICT.put( 26579, 37109 ); + _DICT.put( 26580, 36703 ); + _DICT.put( 26584, 37585 ); + _DICT.put( 26586, 38733 ); + _DICT.put( 26589, 40560 ); + _DICT.put( 26590, 40559 ); + _DICT.put( 26594, 40561 ); + _DICT.put( 26596, 40558 ); + _DICT.put( 26599, 40566 ); + _DICT.put( 26601, 40556 ); + _DICT.put( 26604, 40554 ); + _DICT.put( 26606, 40562 ); + _DICT.put( 26607, 40552 ); + _DICT.put( 26609, 37516 ); + _DICT.put( 26611, 38646 ); + _DICT.put( 26612, 36548 ); + _DICT.put( 26613, 36338 ); + _DICT.put( 26619, 36280 ); + _DICT.put( 26622, 38543 ); + _DICT.put( 26623, 35424 ); + _DICT.put( 26625, 64229 ); + _DICT.put( 26626, 37580 ); + _DICT.put( 26627, 37832 ); + _DICT.put( 26628, 35176 ); + _DICT.put( 26643, 37104 ); + _DICT.put( 26646, 37042 ); + _DICT.put( 26647, 35913 ); + _DICT.put( 26654, 40568 ); + _DICT.put( 26657, 36186 ); + _DICT.put( 26658, 35484 ); + _DICT.put( 26665, 40570 ); + _DICT.put( 26666, 35476 ); + _DICT.put( 26667, 40577 ); + _DICT.put( 26674, 40573 ); + _DICT.put( 26676, 37105 ); + _DICT.put( 26680, 35434 ); + _DICT.put( 26681, 36266 ); + _DICT.put( 26684, 35433 ); + _DICT.put( 26685, 36301 ); + _DICT.put( 26688, 40571 ); + _DICT.put( 26689, 35973 ); + _DICT.put( 26690, 35946 ); + _DICT.put( 26691, 37773 ); + _DICT.put( 26692, 64230 ); + _DICT.put( 26694, 40569 ); + _DICT.put( 26696, 35012 ); + _DICT.put( 26701, 40572 ); + _DICT.put( 26702, 40574 ); + _DICT.put( 26704, 35787 ); + _DICT.put( 26705, 35915 ); + _DICT.put( 26706, 64227 ); + _DICT.put( 26707, 35514 ); + _DICT.put( 26708, 35690 ); + _DICT.put( 26713, 40578 ); + _DICT.put( 26716, 36343 ); + _DICT.put( 26717, 38545 ); + _DICT.put( 26719, 36438 ); + _DICT.put( 26723, 40579 ); + _DICT.put( 26727, 38223 ); + _DICT.put( 26740, 40591 ); + _DICT.put( 26742, 35249 ); + _DICT.put( 26743, 40580 ); + _DICT.put( 26750, 40597 ); + _DICT.put( 26751, 40581 ); + _DICT.put( 26753, 38848 ); + _DICT.put( 26755, 40588 ); + _DICT.put( 26757, 38014 ); + _DICT.put( 26765, 40596 ); + _DICT.put( 26767, 40583 ); + _DICT.put( 26771, 34994 ); + _DICT.put( 26772, 40585 ); + _DICT.put( 26775, 36187 ); + _DICT.put( 26779, 40587 ); + _DICT.put( 26781, 40586 ); + _DICT.put( 26783, 40582 ); + _DICT.put( 26784, 40593 ); + _DICT.put( 26786, 36797 ); + _DICT.put( 26790, 39659 ); + _DICT.put( 26791, 36070 ); + _DICT.put( 26792, 38812 ); + _DICT.put( 26797, 40584 ); + _DICT.put( 26799, 37618 ); + _DICT.put( 26800, 35394 ); + _DICT.put( 26801, 36267 ); + _DICT.put( 26803, 40576 ); + _DICT.put( 26805, 40592 ); + _DICT.put( 26806, 35457 ); + _DICT.put( 26809, 40590 ); + _DICT.put( 26810, 40594 ); + _DICT.put( 26812, 37774 ); + _DICT.put( 26820, 35580 ); + _DICT.put( 26822, 40624 ); + _DICT.put( 26824, 64100 ); + _DICT.put( 26825, 38599 ); + _DICT.put( 26826, 40599 ); + _DICT.put( 26827, 35579 ); + _DICT.put( 26829, 40606 ); + _DICT.put( 26831, 64231 ); + _DICT.put( 26834, 38495 ); + _DICT.put( 26836, 40607 ); + _DICT.put( 26837, 40609 ); + _DICT.put( 26839, 40613 ); + _DICT.put( 26840, 40601 ); + _DICT.put( 26842, 37449 ); + _DICT.put( 26847, 37775 ); + _DICT.put( 26848, 40617 ); + _DICT.put( 26849, 40604 ); + _DICT.put( 26851, 40614 ); + _DICT.put( 26855, 40608 ); + _DICT.put( 26862, 36952 ); + _DICT.put( 26863, 40618 ); + _DICT.put( 26866, 37041 ); + _DICT.put( 26873, 40616 ); + _DICT.put( 26874, 35515 ); + _DICT.put( 26880, 39023 ); + _DICT.put( 26881, 40598 ); + _DICT.put( 26884, 40612 ); + _DICT.put( 26885, 35030 ); + _DICT.put( 26888, 40600 ); + _DICT.put( 26891, 38584 ); + _DICT.put( 26892, 40605 ); + _DICT.put( 26893, 36929 ); + _DICT.put( 26894, 37573 ); + _DICT.put( 26895, 40595 ); + _DICT.put( 26898, 40611 ); + _DICT.put( 26905, 37018 ); + _DICT.put( 26906, 40621 ); + _DICT.put( 26907, 35473 ); + _DICT.put( 26908, 35999 ); + _DICT.put( 26913, 40623 ); + _DICT.put( 26914, 40602 ); + _DICT.put( 26915, 40622 ); + _DICT.put( 26917, 40615 ); + _DICT.put( 26918, 40603 ); + _DICT.put( 26920, 40619 ); + _DICT.put( 26922, 40620 ); + _DICT.put( 26928, 40637 ); + _DICT.put( 26932, 37836 ); + _DICT.put( 26934, 40610 ); + _DICT.put( 26937, 40633 ); + _DICT.put( 26941, 40635 ); + _DICT.put( 26943, 37590 ); + _DICT.put( 26954, 38763 ); + _DICT.put( 26963, 38294 ); + _DICT.put( 26964, 40630 ); + _DICT.put( 26965, 37320 ); + _DICT.put( 26969, 40636 ); + _DICT.put( 26970, 37214 ); + _DICT.put( 26972, 40627 ); + _DICT.put( 26973, 40640 ); + _DICT.put( 26974, 40639 ); + _DICT.put( 26976, 37869 ); + _DICT.put( 26977, 40638 ); + _DICT.put( 26978, 37864 ); + _DICT.put( 26984, 64233 ); + _DICT.put( 26986, 40642 ); + _DICT.put( 26987, 40629 ); + _DICT.put( 26989, 35782 ); + _DICT.put( 26990, 40632 ); + _DICT.put( 26991, 36732 ); + _DICT.put( 26995, 38016 ); + _DICT.put( 26996, 40634 ); + _DICT.put( 26997, 35785 ); + _DICT.put( 26999, 40626 ); + _DICT.put( 27000, 40628 ); + _DICT.put( 27001, 40625 ); + _DICT.put( 27004, 38991 ); + _DICT.put( 27005, 35449 ); + _DICT.put( 27006, 40631 ); + _DICT.put( 27009, 40641 ); + _DICT.put( 27010, 35412 ); + _DICT.put( 27018, 36325 ); + _DICT.put( 27022, 35196 ); + _DICT.put( 27025, 40658 ); + _DICT.put( 27028, 38992 ); + _DICT.put( 27029, 40661 ); + _DICT.put( 27032, 64235 ); + _DICT.put( 27035, 36953 ); + _DICT.put( 27036, 40660 ); + _DICT.put( 27040, 40659 ); + _DICT.put( 27047, 40656 ); + _DICT.put( 27054, 40644 ); + _DICT.put( 27057, 40673 ); + _DICT.put( 27058, 40643 ); + _DICT.put( 27060, 40662 ); + _DICT.put( 27067, 40654 ); + _DICT.put( 27070, 40649 ); + _DICT.put( 27071, 40646 ); + _DICT.put( 27073, 40647 ); + _DICT.put( 27075, 40655 ); + _DICT.put( 27079, 60064 ); + _DICT.put( 27082, 40652 ); + _DICT.put( 27083, 36188 ); + _DICT.put( 27084, 37574 ); + _DICT.put( 27085, 37252 ); + _DICT.put( 27086, 40650 ); + _DICT.put( 27088, 40645 ); + _DICT.put( 27091, 40648 ); + _DICT.put( 27096, 38764 ); + _DICT.put( 27097, 38538 ); + _DICT.put( 27101, 40653 ); + _DICT.put( 27102, 40663 ); + _DICT.put( 27106, 64236 ); + _DICT.put( 27111, 40671 ); + _DICT.put( 27112, 40664 ); + _DICT.put( 27115, 40677 ); + _DICT.put( 27117, 40675 ); + _DICT.put( 27122, 40670 ); + _DICT.put( 27129, 40669 ); + _DICT.put( 27131, 37582 ); + _DICT.put( 27133, 37253 ); + _DICT.put( 27135, 40667 ); + _DICT.put( 27138, 40665 ); + _DICT.put( 27141, 40672 ); + _DICT.put( 27146, 40678 ); + _DICT.put( 27147, 38131 ); + _DICT.put( 27148, 40684 ); + _DICT.put( 27154, 40679 ); + _DICT.put( 27155, 40682 ); + _DICT.put( 27156, 40676 ); + _DICT.put( 27159, 37524 ); + _DICT.put( 27161, 38231 ); + _DICT.put( 27163, 40666 ); + _DICT.put( 27166, 40674 ); + _DICT.put( 27167, 36798 ); + _DICT.put( 27169, 38605 ); + _DICT.put( 27170, 40694 ); + _DICT.put( 27171, 40681 ); + _DICT.put( 27177, 36000 ); + _DICT.put( 27178, 35233 ); + _DICT.put( 27179, 35454 ); + _DICT.put( 27182, 40657 ); + _DICT.put( 27184, 64237 ); + _DICT.put( 27189, 36799 ); + _DICT.put( 27190, 40686 ); + _DICT.put( 27192, 40693 ); + _DICT.put( 27193, 36599 ); + _DICT.put( 27194, 35474 ); + _DICT.put( 27197, 37453 ); + _DICT.put( 27204, 40683 ); + _DICT.put( 27206, 64239 ); + _DICT.put( 27207, 40688 ); + _DICT.put( 27208, 40692 ); + _DICT.put( 27211, 35764 ); + _DICT.put( 27224, 35691 ); + _DICT.put( 27225, 40690 ); + _DICT.put( 27231, 35648 ); + _DICT.put( 27233, 37833 ); + _DICT.put( 27234, 40689 ); + _DICT.put( 27238, 40691 ); + _DICT.put( 27243, 64238 ); + _DICT.put( 27250, 40685 ); + _DICT.put( 27251, 64240 ); + _DICT.put( 27256, 40687 ); + _DICT.put( 27262, 64241 ); + _DICT.put( 27263, 35456 ); + _DICT.put( 27264, 37480 ); + _DICT.put( 27268, 40698 ); + _DICT.put( 27277, 40696 ); + _DICT.put( 27278, 36071 ); + _DICT.put( 27280, 40695 ); + _DICT.put( 27287, 40768 ); + _DICT.put( 27292, 40567 ); + _DICT.put( 27296, 40697 ); + _DICT.put( 27298, 40699 ); + _DICT.put( 27299, 40700 ); + _DICT.put( 27306, 40779 ); + _DICT.put( 27308, 40775 ); + _DICT.put( 27310, 40589 ); + _DICT.put( 27315, 40774 ); + _DICT.put( 27320, 40773 ); + _DICT.put( 27323, 40770 ); + _DICT.put( 27329, 40680 ); + _DICT.put( 27330, 40772 ); + _DICT.put( 27331, 40771 ); + _DICT.put( 27345, 40777 ); + _DICT.put( 27347, 38981 ); + _DICT.put( 27354, 40780 ); + _DICT.put( 27355, 35833 ); + _DICT.put( 27358, 40776 ); + _DICT.put( 27359, 40778 ); + _DICT.put( 27362, 64242 ); + _DICT.put( 27364, 64243 ); + _DICT.put( 27368, 38053 ); + _DICT.put( 27370, 40781 ); + _DICT.put( 27386, 40785 ); + _DICT.put( 27387, 40782 ); + _DICT.put( 27396, 38803 ); + _DICT.put( 27397, 40783 ); + _DICT.put( 27402, 40668 ); + _DICT.put( 27410, 40786 ); + _DICT.put( 27414, 40787 ); + _DICT.put( 27421, 35156 ); + _DICT.put( 27423, 40789 ); + _DICT.put( 27424, 35975 ); + _DICT.put( 27425, 36511 ); + _DICT.put( 27427, 35795 ); + _DICT.put( 27431, 35234 ); + _DICT.put( 27442, 38782 ); + _DICT.put( 27447, 40791 ); + _DICT.put( 27448, 40790 ); + _DICT.put( 27449, 40793 ); + _DICT.put( 27450, 35676 ); + _DICT.put( 27453, 35796 ); + _DICT.put( 27454, 35516 ); + _DICT.put( 27459, 40796 ); + _DICT.put( 27463, 40795 ); + _DICT.put( 27465, 40797 ); + _DICT.put( 27468, 35276 ); + _DICT.put( 27470, 37462 ); + _DICT.put( 27472, 40798 ); + _DICT.put( 27475, 35517 ); + _DICT.put( 27476, 40800 ); + _DICT.put( 27481, 40799 ); + _DICT.put( 27483, 40801 ); + _DICT.put( 27487, 40802 ); + _DICT.put( 27489, 40803 ); + _DICT.put( 27490, 36478 ); + _DICT.put( 27491, 37043 ); + _DICT.put( 27492, 36255 ); + _DICT.put( 27494, 38288 ); + _DICT.put( 27497, 38368 ); + _DICT.put( 27498, 39011 ); + _DICT.put( 27503, 36501 ); + _DICT.put( 27507, 36302 ); + _DICT.put( 27508, 38896 ); + _DICT.put( 27512, 40804 ); + _DICT.put( 27513, 40805 ); + _DICT.put( 27515, 36480 ); + _DICT.put( 27519, 40806 ); + _DICT.put( 27520, 40807 ); + _DICT.put( 27523, 40809 ); + _DICT.put( 27524, 40808 ); + _DICT.put( 27526, 38519 ); + _DICT.put( 27529, 36733 ); + _DICT.put( 27530, 36586 ); + _DICT.put( 27531, 36451 ); + _DICT.put( 27533, 40810 ); + _DICT.put( 27541, 40812 ); + _DICT.put( 27542, 36930 ); + _DICT.put( 27544, 40811 ); + _DICT.put( 27550, 40813 ); + _DICT.put( 27556, 40814 ); + _DICT.put( 27562, 40815 ); + _DICT.put( 27563, 40816 ); + _DICT.put( 27567, 40817 ); + _DICT.put( 27569, 40819 ); + _DICT.put( 27570, 40818 ); + _DICT.put( 27571, 40820 ); + _DICT.put( 27572, 35235 ); + _DICT.put( 27573, 37481 ); + _DICT.put( 27575, 40821 ); + _DICT.put( 27578, 36421 ); + _DICT.put( 27579, 35435 ); + _DICT.put( 27580, 40822 ); + _DICT.put( 27583, 37729 ); + _DICT.put( 27584, 39626 ); + _DICT.put( 27589, 35650 ); + _DICT.put( 27590, 40823 ); + _DICT.put( 27595, 40824 ); + _DICT.put( 27597, 38378 ); + _DICT.put( 27598, 38536 ); + _DICT.put( 27602, 37829 ); + _DICT.put( 27603, 40825 ); + _DICT.put( 27604, 38116 ); + _DICT.put( 27606, 64244 ); + _DICT.put( 27608, 38137 ); + _DICT.put( 27611, 38609 ); + _DICT.put( 27615, 40826 ); + _DICT.put( 27627, 40828 ); + _DICT.put( 27628, 40827 ); + _DICT.put( 27631, 40830 ); + _DICT.put( 27635, 40829 ); + _DICT.put( 27656, 40833 ); + _DICT.put( 27663, 36481 ); + _DICT.put( 27665, 38575 ); + _DICT.put( 27667, 40834 ); + _DICT.put( 27668, 40835 ); + _DICT.put( 27671, 35651 ); + _DICT.put( 27675, 40836 ); + _DICT.put( 27683, 40838 ); + _DICT.put( 27684, 40837 ); + _DICT.put( 27700, 36997 ); + _DICT.put( 27703, 38232 ); + _DICT.put( 27704, 35177 ); + _DICT.put( 27710, 38083 ); + _DICT.put( 27711, 64245 ); + _DICT.put( 27712, 37619 ); + _DICT.put( 27713, 36704 ); + _DICT.put( 27714, 35713 ); + _DICT.put( 27726, 38084 ); + _DICT.put( 27728, 36524 ); + _DICT.put( 27733, 40840 ); + _DICT.put( 27735, 35518 ); + _DICT.put( 27738, 35224 ); + _DICT.put( 27740, 64246 ); + _DICT.put( 27741, 37872 ); + _DICT.put( 27742, 40839 ); + _DICT.put( 27743, 36189 ); + _DICT.put( 27744, 37490 ); + _DICT.put( 27746, 40841 ); + _DICT.put( 27752, 40849 ); + _DICT.put( 27754, 40842 ); + _DICT.put( 27759, 64248 ); + _DICT.put( 27760, 37311 ); + _DICT.put( 27762, 35714 ); + _DICT.put( 27763, 40850 ); + _DICT.put( 27770, 35976 ); + _DICT.put( 27773, 35652 ); + _DICT.put( 27774, 40848 ); + _DICT.put( 27777, 40846 ); + _DICT.put( 27778, 40843 ); + _DICT.put( 27779, 38784 ); + _DICT.put( 27782, 64247 ); + _DICT.put( 27784, 37566 ); + _DICT.put( 27788, 37847 ); + _DICT.put( 27789, 40844 ); + _DICT.put( 27792, 40852 ); + _DICT.put( 27794, 40851 ); + _DICT.put( 27795, 35906 ); + _DICT.put( 27798, 35243 ); + _DICT.put( 27801, 36281 ); + _DICT.put( 27802, 40845 ); + _DICT.put( 27803, 40847 ); + _DICT.put( 27809, 38518 ); + _DICT.put( 27810, 37362 ); + _DICT.put( 27819, 38551 ); + _DICT.put( 27822, 40860 ); + _DICT.put( 27825, 40861 ); + _DICT.put( 27827, 35277 ); + _DICT.put( 27832, 38310 ); + _DICT.put( 27833, 38651 ); + _DICT.put( 27834, 40863 ); + _DICT.put( 27835, 36513 ); + _DICT.put( 27836, 36800 ); + _DICT.put( 27837, 40856 ); + _DICT.put( 27838, 40862 ); + _DICT.put( 27839, 35208 ); + _DICT.put( 27841, 35765 ); + _DICT.put( 27844, 40853 ); + _DICT.put( 27845, 40858 ); + _DICT.put( 27849, 37106 ); + _DICT.put( 27850, 38033 ); + _DICT.put( 27852, 38117 ); + _DICT.put( 27859, 40855 ); + _DICT.put( 27861, 38464 ); + _DICT.put( 27863, 40857 ); + _DICT.put( 27865, 40866 ); + _DICT.put( 27866, 64249 ); + _DICT.put( 27867, 40864 ); + _DICT.put( 27869, 40859 ); + _DICT.put( 27873, 38465 ); + _DICT.put( 27874, 37991 ); + _DICT.put( 27875, 35715 ); + _DICT.put( 27877, 37700 ); + _DICT.put( 27880, 37517 ); + _DICT.put( 27882, 40867 ); + _DICT.put( 27887, 40865 ); + _DICT.put( 27888, 37335 ); + _DICT.put( 27889, 40854 ); + _DICT.put( 27891, 35178 ); + _DICT.put( 27908, 64250 ); + _DICT.put( 27915, 38765 ); + _DICT.put( 27916, 40878 ); + _DICT.put( 27922, 40877 ); + _DICT.put( 27927, 37108 ); + _DICT.put( 27929, 40874 ); + _DICT.put( 27931, 38796 ); + _DICT.put( 27934, 37812 ); + _DICT.put( 27935, 40868 ); + _DICT.put( 27941, 37571 ); + _DICT.put( 27945, 35179 ); + _DICT.put( 27946, 36190 ); + _DICT.put( 27947, 40871 ); + _DICT.put( 27954, 36678 ); + _DICT.put( 27955, 40876 ); + _DICT.put( 27957, 40875 ); + _DICT.put( 27958, 40870 ); + _DICT.put( 27960, 40873 ); + _DICT.put( 27963, 35464 ); + _DICT.put( 27965, 40872 ); + _DICT.put( 27966, 37992 ); + _DICT.put( 27969, 38828 ); + _DICT.put( 27972, 36850 ); + _DICT.put( 27973, 37107 ); + _DICT.put( 27993, 40884 ); + _DICT.put( 27994, 40882 ); + _DICT.put( 27996, 38252 ); + _DICT.put( 28003, 40879 ); + _DICT.put( 28004, 40881 ); + _DICT.put( 28006, 35161 ); + _DICT.put( 28009, 36191 ); + _DICT.put( 28010, 38993 ); + _DICT.put( 28012, 35420 ); + _DICT.put( 28014, 38274 ); + _DICT.put( 28015, 64252 ); + _DICT.put( 28020, 38785 ); + _DICT.put( 28023, 35395 ); + _DICT.put( 28024, 36954 ); + _DICT.put( 28025, 40883 ); + _DICT.put( 28037, 40888 ); + _DICT.put( 28039, 64251 ); + _DICT.put( 28040, 36801 ); + _DICT.put( 28044, 38735 ); + _DICT.put( 28046, 40885 ); + _DICT.put( 28051, 40880 ); + _DICT.put( 28053, 40886 ); + _DICT.put( 28054, 64320 ); + _DICT.put( 28057, 38876 ); + _DICT.put( 28059, 37779 ); + _DICT.put( 28060, 37824 ); + _DICT.put( 28076, 64321 ); + _DICT.put( 28079, 35413 ); + _DICT.put( 28082, 35188 ); + _DICT.put( 28085, 40892 ); + _DICT.put( 28088, 40895 ); + _DICT.put( 28092, 38849 ); + _DICT.put( 28096, 38788 ); + _DICT.put( 28101, 40902 ); + _DICT.put( 28102, 40896 ); + _DICT.put( 28103, 40893 ); + _DICT.put( 28107, 38866 ); + _DICT.put( 28108, 40899 ); + _DICT.put( 28111, 64322 ); + _DICT.put( 28113, 36713 ); + _DICT.put( 28114, 40901 ); + _DICT.put( 28117, 40906 ); + _DICT.put( 28120, 37777 ); + _DICT.put( 28121, 40904 ); + _DICT.put( 28126, 40898 ); + _DICT.put( 28129, 37463 ); + _DICT.put( 28132, 40905 ); + _DICT.put( 28134, 40894 ); + _DICT.put( 28136, 40900 ); + _DICT.put( 28138, 40907 ); + _DICT.put( 28139, 35066 ); + _DICT.put( 28140, 40897 ); + _DICT.put( 28142, 40908 ); + _DICT.put( 28145, 36955 ); + _DICT.put( 28146, 64324 ); + _DICT.put( 28147, 36734 ); + _DICT.put( 28149, 38307 ); + _DICT.put( 28151, 36268 ); + _DICT.put( 28152, 64323 ); + _DICT.put( 28153, 40889 ); + _DICT.put( 28154, 40903 ); + _DICT.put( 28155, 37721 ); + _DICT.put( 28156, 64325 ); + _DICT.put( 28165, 37044 ); + _DICT.put( 28167, 35465 ); + _DICT.put( 28168, 36303 ); + _DICT.put( 28169, 36802 ); + _DICT.put( 28170, 40891 ); + _DICT.put( 28171, 36705 ); + _DICT.put( 28179, 35947 ); + _DICT.put( 28181, 40890 ); + _DICT.put( 28185, 40912 ); + _DICT.put( 28186, 36749 ); + _DICT.put( 28187, 36024 ); + _DICT.put( 28189, 40927 ); + _DICT.put( 28191, 40921 ); + _DICT.put( 28192, 35732 ); + _DICT.put( 28193, 37742 ); + _DICT.put( 28195, 40916 ); + _DICT.put( 28196, 40925 ); + _DICT.put( 28197, 34989 ); + _DICT.put( 28198, 35153 ); + _DICT.put( 28199, 64328 ); + _DICT.put( 28201, 35255 ); + _DICT.put( 28203, 40918 ); + _DICT.put( 28204, 37290 ); + _DICT.put( 28205, 40909 ); + _DICT.put( 28206, 40911 ); + _DICT.put( 28207, 36192 ); + _DICT.put( 28216, 40928 ); + _DICT.put( 28217, 64326 ); + _DICT.put( 28218, 40923 ); + _DICT.put( 28220, 64329 ); + _DICT.put( 28222, 40915 ); + _DICT.put( 28227, 40922 ); + _DICT.put( 28234, 38569 ); + _DICT.put( 28237, 40920 ); + _DICT.put( 28238, 40924 ); + _DICT.put( 28246, 36046 ); + _DICT.put( 28248, 36803 ); + _DICT.put( 28251, 37464 ); + _DICT.put( 28252, 64327 ); + _DICT.put( 28255, 40914 ); + _DICT.put( 28263, 38734 ); + _DICT.put( 28267, 40917 ); + _DICT.put( 28270, 40910 ); + _DICT.put( 28271, 37778 ); + _DICT.put( 28274, 40913 ); + _DICT.put( 28278, 40919 ); + _DICT.put( 28286, 39024 ); + _DICT.put( 28287, 36540 ); + _DICT.put( 28288, 38558 ); + _DICT.put( 28290, 40929 ); + _DICT.put( 28300, 38060 ); + _DICT.put( 28303, 40941 ); + _DICT.put( 28304, 36025 ); + _DICT.put( 28310, 36736 ); + _DICT.put( 28312, 40931 ); + _DICT.put( 28316, 38829 ); + _DICT.put( 28317, 36193 ); + _DICT.put( 28319, 40944 ); + _DICT.put( 28322, 35052 ); + _DICT.put( 28325, 40942 ); + _DICT.put( 28330, 40930 ); + _DICT.put( 28335, 40936 ); + _DICT.put( 28338, 40938 ); + _DICT.put( 28342, 38766 ); + _DICT.put( 28343, 40933 ); + _DICT.put( 28346, 37709 ); + _DICT.put( 28349, 40935 ); + _DICT.put( 28351, 64330 ); + _DICT.put( 28354, 40943 ); + _DICT.put( 28356, 40937 ); + _DICT.put( 28357, 38597 ); + _DICT.put( 28361, 40932 ); + _DICT.put( 28363, 36512 ); + _DICT.put( 28364, 40956 ); + _DICT.put( 28369, 35466 ); + _DICT.put( 28371, 40934 ); + _DICT.put( 28372, 40939 ); + _DICT.put( 28373, 40940 ); + _DICT.put( 28381, 37354 ); + _DICT.put( 28382, 37336 ); + _DICT.put( 28396, 40948 ); + _DICT.put( 28399, 40954 ); + _DICT.put( 28402, 40952 ); + _DICT.put( 28404, 37704 ); + _DICT.put( 28407, 57410 ); + _DICT.put( 28408, 40949 ); + _DICT.put( 28414, 40950 ); + _DICT.put( 28415, 40926 ); + _DICT.put( 28417, 35737 ); + _DICT.put( 28418, 38233 ); + _DICT.put( 28422, 36541 ); + _DICT.put( 28425, 36247 ); + _DICT.put( 28431, 38994 ); + _DICT.put( 28433, 40946 ); + _DICT.put( 28435, 57409 ); + _DICT.put( 28436, 35209 ); + _DICT.put( 28437, 37254 ); + _DICT.put( 28448, 38041 ); + _DICT.put( 28450, 35519 ); + _DICT.put( 28451, 38904 ); + _DICT.put( 28459, 38559 ); + _DICT.put( 28460, 37584 ); + _DICT.put( 28465, 40953 ); + _DICT.put( 28466, 40955 ); + _DICT.put( 28472, 37201 ); + _DICT.put( 28478, 57408 ); + _DICT.put( 28479, 40951 ); + _DICT.put( 28481, 40945 ); + _DICT.put( 28485, 35521 ); + _DICT.put( 28500, 35977 ); + _DICT.put( 28504, 57422 ); + _DICT.put( 28507, 57417 ); + _DICT.put( 28508, 37110 ); + _DICT.put( 28511, 35459 ); + _DICT.put( 28516, 36737 ); + _DICT.put( 28518, 57426 ); + _DICT.put( 28525, 57419 ); + _DICT.put( 28526, 37546 ); + _DICT.put( 28527, 57416 ); + _DICT.put( 28528, 37591 ); + _DICT.put( 28532, 57451 ); + _DICT.put( 28536, 57413 ); + _DICT.put( 28538, 57412 ); + _DICT.put( 28540, 57421 ); + _DICT.put( 28544, 57415 ); + _DICT.put( 28545, 57414 ); + _DICT.put( 28546, 57420 ); + _DICT.put( 28548, 37023 ); + _DICT.put( 28550, 57411 ); + _DICT.put( 28552, 64331 ); + _DICT.put( 28558, 57423 ); + _DICT.put( 28561, 57424 ); + _DICT.put( 28567, 35520 ); + _DICT.put( 28577, 57429 ); + _DICT.put( 28579, 57428 ); + _DICT.put( 28580, 57430 ); + _DICT.put( 28586, 57433 ); + _DICT.put( 28593, 37730 ); + _DICT.put( 28595, 57427 ); + _DICT.put( 28597, 64332 ); + _DICT.put( 28601, 57431 ); + _DICT.put( 28608, 35971 ); + _DICT.put( 28609, 37367 ); + _DICT.put( 28610, 57425 ); + _DICT.put( 28611, 37978 ); + _DICT.put( 28614, 57432 ); + _DICT.put( 28628, 57437 ); + _DICT.put( 28629, 57435 ); + _DICT.put( 28632, 57438 ); + _DICT.put( 28635, 57441 ); + _DICT.put( 28639, 57434 ); + _DICT.put( 28640, 36234 ); + _DICT.put( 28641, 37959 ); + _DICT.put( 28644, 40887 ); + _DICT.put( 28651, 38804 ); + _DICT.put( 28652, 57436 ); + _DICT.put( 28654, 57440 ); + _DICT.put( 28655, 37363 ); + _DICT.put( 28657, 57439 ); + _DICT.put( 28659, 57418 ); + _DICT.put( 28661, 64333 ); + _DICT.put( 28662, 59529 ); + _DICT.put( 28666, 57444 ); + _DICT.put( 28670, 57448 ); + _DICT.put( 28673, 57446 ); + _DICT.put( 28677, 64334 ); + _DICT.put( 28679, 64335 ); + _DICT.put( 28681, 57442 ); + _DICT.put( 28683, 57443 ); + _DICT.put( 28687, 57447 ); + _DICT.put( 28689, 57445 ); + _DICT.put( 28693, 38253 ); + _DICT.put( 28696, 57453 ); + _DICT.put( 28698, 57450 ); + _DICT.put( 28699, 57449 ); + _DICT.put( 28701, 57452 ); + _DICT.put( 28702, 37842 ); + _DICT.put( 28703, 57454 ); + _DICT.put( 28710, 37525 ); + _DICT.put( 28711, 37355 ); + _DICT.put( 28712, 64336 ); + _DICT.put( 28716, 37027 ); + _DICT.put( 28720, 57455 ); + _DICT.put( 28722, 57457 ); + _DICT.put( 28734, 57456 ); + _DICT.put( 28748, 40947 ); + _DICT.put( 28753, 57458 ); + _DICT.put( 28760, 37861 ); + _DICT.put( 28771, 57459 ); + _DICT.put( 28779, 35278 ); + _DICT.put( 28783, 37780 ); + _DICT.put( 28784, 35396 ); + _DICT.put( 28792, 35716 ); + _DICT.put( 28796, 36572 ); + _DICT.put( 28797, 36304 ); + _DICT.put( 28805, 64337 ); + _DICT.put( 28809, 38982 ); + _DICT.put( 28810, 36998 ); + _DICT.put( 28814, 35210 ); + _DICT.put( 28818, 57461 ); + _DICT.put( 28825, 57460 ); + _DICT.put( 28843, 64338 ); + _DICT.put( 28844, 57464 ); + _DICT.put( 28845, 37465 ); + _DICT.put( 28846, 57467 ); + _DICT.put( 28847, 57462 ); + _DICT.put( 28851, 57466 ); + _DICT.put( 28856, 57465 ); + _DICT.put( 28857, 37727 ); + _DICT.put( 28858, 35031 ); + _DICT.put( 28859, 64098 ); + _DICT.put( 28872, 38899 ); + _DICT.put( 28875, 57469 ); + _DICT.put( 28879, 35143 ); + _DICT.put( 28889, 57472 ); + _DICT.put( 28893, 57470 ); + _DICT.put( 28895, 57468 ); + _DICT.put( 28913, 57463 ); + _DICT.put( 28921, 38466 ); + _DICT.put( 28925, 57474 ); + _DICT.put( 28932, 64340 ); + _DICT.put( 28937, 57473 ); + _DICT.put( 28943, 64339 ); + _DICT.put( 28948, 35211 ); + _DICT.put( 28953, 57476 ); + _DICT.put( 28954, 38320 ); + _DICT.put( 28956, 57475 ); + _DICT.put( 28961, 38579 ); + _DICT.put( 28966, 36805 ); + _DICT.put( 28982, 37202 ); + _DICT.put( 28988, 36804 ); + _DICT.put( 28998, 64342 ); + _DICT.put( 28999, 64343 ); + _DICT.put( 29001, 38905 ); + _DICT.put( 29004, 57482 ); + _DICT.put( 29006, 37111 ); + _DICT.put( 29013, 57478 ); + _DICT.put( 29014, 57483 ); + _DICT.put( 29017, 35212 ); + _DICT.put( 29020, 64341 ); + _DICT.put( 29026, 57481 ); + _DICT.put( 29028, 38017 ); + _DICT.put( 29029, 57477 ); + _DICT.put( 29030, 57480 ); + _DICT.put( 29031, 36806 ); + _DICT.put( 29033, 38095 ); + _DICT.put( 29036, 57484 ); + _DICT.put( 29038, 36559 ); + _DICT.put( 29053, 37112 ); + _DICT.put( 29060, 57487 ); + _DICT.put( 29064, 57479 ); + _DICT.put( 29066, 35910 ); + _DICT.put( 29071, 57485 ); + _DICT.put( 29076, 38767 ); + _DICT.put( 29077, 57488 ); + _DICT.put( 29081, 60068 ); + _DICT.put( 29087, 36718 ); + _DICT.put( 29096, 57489 ); + _DICT.put( 29100, 57490 ); + _DICT.put( 29105, 37965 ); + _DICT.put( 29113, 57492 ); + _DICT.put( 29118, 57493 ); + _DICT.put( 29121, 64345 ); + _DICT.put( 29123, 37970 ); + _DICT.put( 29128, 37781 ); + _DICT.put( 29129, 57495 ); + _DICT.put( 29134, 57497 ); + _DICT.put( 29136, 38867 ); + _DICT.put( 29138, 57494 ); + _DICT.put( 29140, 57496 ); + _DICT.put( 29141, 35213 ); + _DICT.put( 29143, 57491 ); + _DICT.put( 29151, 39546 ); + _DICT.put( 29152, 57498 ); + _DICT.put( 29157, 37255 ); + _DICT.put( 29158, 36439 ); + _DICT.put( 29159, 57500 ); + _DICT.put( 29164, 57499 ); + _DICT.put( 29165, 36931 ); + _DICT.put( 29166, 39383 ); + _DICT.put( 29173, 57501 ); + _DICT.put( 29177, 57503 ); + _DICT.put( 29179, 57486 ); + _DICT.put( 29180, 57502 ); + _DICT.put( 29182, 64346 ); + _DICT.put( 29183, 57504 ); + _DICT.put( 29190, 38042 ); + _DICT.put( 29197, 57505 ); + _DICT.put( 29200, 57506 ); + _DICT.put( 29211, 57507 ); + _DICT.put( 29224, 57508 ); + _DICT.put( 29226, 37596 ); + _DICT.put( 29228, 57510 ); + _DICT.put( 29229, 57509 ); + _DICT.put( 29232, 57511 ); + _DICT.put( 29234, 57512 ); + _DICT.put( 29237, 36573 ); + _DICT.put( 29238, 38275 ); + _DICT.put( 29242, 38634 ); + _DICT.put( 29243, 57513 ); + _DICT.put( 29244, 57514 ); + _DICT.put( 29245, 37237 ); + _DICT.put( 29246, 36514 ); + _DICT.put( 29247, 57515 ); + _DICT.put( 29248, 57516 ); + _DICT.put( 29254, 57517 ); + _DICT.put( 29255, 38352 ); + _DICT.put( 29256, 38085 ); + _DICT.put( 29259, 57518 ); + _DICT.put( 29260, 38006 ); + _DICT.put( 29266, 37547 ); + _DICT.put( 29272, 57519 ); + _DICT.put( 29273, 35301 ); + _DICT.put( 29275, 35725 ); + _DICT.put( 29277, 38596 ); + _DICT.put( 29279, 38580 ); + _DICT.put( 29281, 35250 ); + _DICT.put( 29282, 38995 ); + _DICT.put( 29287, 38513 ); + _DICT.put( 29289, 38312 ); + _DICT.put( 29298, 37045 ); + _DICT.put( 29300, 57520 ); + _DICT.put( 29305, 37825 ); + _DICT.put( 29309, 36001 ); + _DICT.put( 29310, 57521 ); + _DICT.put( 29312, 36306 ); + _DICT.put( 29313, 57523 ); + _DICT.put( 29314, 57522 ); + _DICT.put( 29319, 57524 ); + _DICT.put( 29330, 57525 ); + _DICT.put( 29334, 57526 ); + _DICT.put( 29344, 35677 ); + _DICT.put( 29346, 57527 ); + _DICT.put( 29351, 57528 ); + _DICT.put( 29356, 36002 ); + _DICT.put( 29359, 38086 ); + _DICT.put( 29361, 64347 ); + _DICT.put( 29362, 57530 ); + _DICT.put( 29366, 36851 ); + _DICT.put( 29369, 57529 ); + _DICT.put( 29374, 64348 ); + _DICT.put( 29378, 35766 ); + _DICT.put( 29379, 57531 ); + _DICT.put( 29380, 57533 ); + _DICT.put( 29382, 57532 ); + _DICT.put( 29390, 57534 ); + _DICT.put( 29392, 36047 ); + _DICT.put( 29394, 57535 ); + _DICT.put( 29399, 35815 ); + _DICT.put( 29401, 37215 ); + _DICT.put( 29403, 36253 ); + _DICT.put( 29408, 57537 ); + _DICT.put( 29409, 57538 ); + _DICT.put( 29410, 57536 ); + _DICT.put( 29417, 36587 ); + _DICT.put( 29420, 37830 ); + _DICT.put( 29421, 35767 ); + _DICT.put( 29431, 57540 ); + _DICT.put( 29432, 37451 ); + _DICT.put( 29433, 57539 ); + _DICT.put( 29436, 38996 ); + _DICT.put( 29437, 38018 ); + _DICT.put( 29450, 57543 ); + _DICT.put( 29462, 57545 ); + _DICT.put( 29463, 57542 ); + _DICT.put( 29467, 38610 ); + _DICT.put( 29468, 57544 ); + _DICT.put( 29469, 57546 ); + _DICT.put( 29471, 38850 ); + _DICT.put( 29476, 64349 ); + _DICT.put( 29477, 57550 ); + _DICT.put( 29481, 57549 ); + _DICT.put( 29482, 37526 ); + _DICT.put( 29483, 37964 ); + _DICT.put( 29486, 36003 ); + _DICT.put( 29487, 57548 ); + _DICT.put( 29492, 57547 ); + _DICT.put( 29494, 38736 ); + _DICT.put( 29495, 38737 ); + _DICT.put( 29502, 57551 ); + _DICT.put( 29503, 35214 ); + _DICT.put( 29508, 36246 ); + _DICT.put( 29509, 36482 ); + _DICT.put( 29518, 57552 ); + _DICT.put( 29519, 57553 ); + _DICT.put( 29527, 57555 ); + _DICT.put( 29539, 36706 ); + _DICT.put( 29544, 57557 ); + _DICT.put( 29546, 57556 ); + _DICT.put( 29552, 57558 ); + _DICT.put( 29554, 35436 ); + _DICT.put( 29557, 57560 ); + _DICT.put( 29559, 64351 ); + _DICT.put( 29560, 57559 ); + _DICT.put( 29562, 57562 ); + _DICT.put( 29563, 57561 ); + _DICT.put( 29572, 36026 ); + _DICT.put( 29575, 38822 ); + _DICT.put( 29577, 35786 ); + _DICT.put( 29579, 35236 ); + _DICT.put( 29590, 35816 ); + _DICT.put( 29609, 35551 ); + _DICT.put( 29618, 38886 ); + _DICT.put( 29619, 57564 ); + _DICT.put( 29627, 57566 ); + _DICT.put( 29629, 64352 ); + _DICT.put( 29632, 57567 ); + _DICT.put( 29634, 35279 ); + _DICT.put( 29640, 57563 ); + _DICT.put( 29641, 64353 ); + _DICT.put( 29642, 36440 ); + _DICT.put( 29645, 37567 ); + _DICT.put( 29646, 57565 ); + _DICT.put( 29650, 64356 ); + _DICT.put( 29654, 64354 ); + _DICT.put( 29662, 57570 ); + _DICT.put( 29664, 36588 ); + _DICT.put( 29667, 64355 ); + _DICT.put( 29669, 57568 ); + _DICT.put( 29674, 35933 ); + _DICT.put( 29677, 38087 ); + _DICT.put( 29678, 57569 ); + _DICT.put( 29681, 57596 ); + _DICT.put( 29685, 64358 ); + _DICT.put( 29688, 57575 ); + _DICT.put( 29694, 36027 ); + _DICT.put( 29699, 35717 ); + _DICT.put( 29701, 57572 ); + _DICT.put( 29702, 38813 ); + _DICT.put( 29703, 64357 ); + _DICT.put( 29705, 38830 ); + _DICT.put( 29730, 37364 ); + _DICT.put( 29733, 57574 ); + _DICT.put( 29734, 64359 ); + _DICT.put( 29737, 64361 ); + _DICT.put( 29738, 64360 ); + _DICT.put( 29742, 64362 ); + _DICT.put( 29746, 57576 ); + _DICT.put( 29747, 38868 ); + _DICT.put( 29748, 35797 ); + _DICT.put( 29749, 38138 ); + _DICT.put( 29750, 37993 ); + _DICT.put( 29754, 57577 ); + _DICT.put( 29759, 57579 ); + _DICT.put( 29761, 57582 ); + _DICT.put( 29781, 57578 ); + _DICT.put( 29785, 57581 ); + _DICT.put( 29786, 36072 ); + _DICT.put( 29787, 35180 ); + _DICT.put( 29788, 57583 ); + _DICT.put( 29790, 37008 ); + _DICT.put( 29791, 57580 ); + _DICT.put( 29792, 38874 ); + _DICT.put( 29794, 64363 ); + _DICT.put( 29795, 57586 ); + _DICT.put( 29796, 60066 ); + _DICT.put( 29801, 57584 ); + _DICT.put( 29802, 57587 ); + _DICT.put( 29807, 57573 ); + _DICT.put( 29808, 57585 ); + _DICT.put( 29811, 36282 ); + _DICT.put( 29814, 57588 ); + _DICT.put( 29822, 57589 ); + _DICT.put( 29827, 38814 ); + _DICT.put( 29833, 64364 ); + _DICT.put( 29835, 57590 ); + _DICT.put( 29854, 57591 ); + _DICT.put( 29855, 64365 ); + _DICT.put( 29858, 57571 ); + _DICT.put( 29863, 57592 ); + _DICT.put( 29872, 35522 ); + _DICT.put( 29885, 36515 ); + _DICT.put( 29898, 57593 ); + _DICT.put( 29903, 57594 ); + _DICT.put( 29908, 57595 ); + _DICT.put( 29916, 35162 ); + _DICT.put( 29920, 57664 ); + _DICT.put( 29922, 38234 ); + _DICT.put( 29923, 57665 ); + _DICT.put( 29926, 35490 ); + _DICT.put( 29927, 57666 ); + _DICT.put( 29929, 57667 ); + _DICT.put( 29934, 57668 ); + _DICT.put( 29936, 57670 ); + _DICT.put( 29937, 57671 ); + _DICT.put( 29938, 57669 ); + _DICT.put( 29942, 38258 ); + _DICT.put( 29943, 57673 ); + _DICT.put( 29944, 57672 ); + _DICT.put( 29953, 64366 ); + _DICT.put( 29955, 57675 ); + _DICT.put( 29956, 57674 ); + _DICT.put( 29957, 57676 ); + _DICT.put( 29964, 57677 ); + _DICT.put( 29965, 57679 ); + _DICT.put( 29966, 57678 ); + _DICT.put( 29969, 36249 ); + _DICT.put( 29971, 57681 ); + _DICT.put( 29973, 57680 ); + _DICT.put( 29976, 35523 ); + _DICT.put( 29978, 36978 ); + _DICT.put( 29980, 37723 ); + _DICT.put( 29982, 57682 ); + _DICT.put( 29983, 37046 ); + _DICT.put( 29987, 36441 ); + _DICT.put( 29989, 35225 ); + _DICT.put( 29990, 57683 ); + _DICT.put( 29992, 38768 ); + _DICT.put( 29995, 38369 ); + _DICT.put( 29996, 57684 ); + _DICT.put( 29999, 64168 ); + _DICT.put( 30000, 37731 ); + _DICT.put( 30001, 38738 ); + _DICT.put( 30002, 36194 ); + _DICT.put( 30003, 36956 ); + _DICT.put( 30007, 37482 ); + _DICT.put( 30008, 39346 ); + _DICT.put( 30010, 37548 ); + _DICT.put( 30011, 35302 ); + _DICT.put( 30012, 57685 ); + _DICT.put( 30020, 57686 ); + _DICT.put( 30022, 57691 ); + _DICT.put( 30025, 57689 ); + _DICT.put( 30026, 57688 ); + _DICT.put( 30027, 40384 ); + _DICT.put( 30028, 35397 ); + _DICT.put( 30029, 57687 ); + _DICT.put( 30031, 35032 ); + _DICT.put( 30033, 38056 ); + _DICT.put( 30036, 38088 ); + _DICT.put( 30041, 38831 ); + _DICT.put( 30042, 57692 ); + _DICT.put( 30043, 57690 ); + _DICT.put( 30044, 37499 ); + _DICT.put( 30045, 37028 ); + _DICT.put( 30048, 38057 ); + _DICT.put( 30050, 38220 ); + _DICT.put( 30052, 57694 ); + _DICT.put( 30053, 38826 ); + _DICT.put( 30054, 35948 ); + _DICT.put( 30055, 57695 ); + _DICT.put( 30057, 57693 ); + _DICT.put( 30058, 38100 ); + _DICT.put( 30059, 57696 ); + _DICT.put( 30061, 57697 ); + _DICT.put( 30063, 64367 ); + _DICT.put( 30064, 35033 ); + _DICT.put( 30067, 36852 ); + _DICT.put( 30068, 57702 ); + _DICT.put( 30070, 57699 ); + _DICT.put( 30071, 37867 ); + _DICT.put( 30072, 57698 ); + _DICT.put( 30079, 35653 ); + _DICT.put( 30082, 57705 ); + _DICT.put( 30086, 57700 ); + _DICT.put( 30087, 57701 ); + _DICT.put( 30089, 57704 ); + _DICT.put( 30090, 57703 ); + _DICT.put( 30091, 38212 ); + _DICT.put( 30094, 37217 ); + _DICT.put( 30095, 37216 ); + _DICT.put( 30097, 35678 ); + _DICT.put( 30100, 57706 ); + _DICT.put( 30106, 57707 ); + _DICT.put( 30109, 57708 ); + _DICT.put( 30115, 57710 ); + _DICT.put( 30117, 57709 ); + _DICT.put( 30123, 35189 ); + _DICT.put( 30129, 57718 ); + _DICT.put( 30130, 38118 ); + _DICT.put( 30131, 57712 ); + _DICT.put( 30133, 57714 ); + _DICT.put( 30136, 57716 ); + _DICT.put( 30137, 36957 ); + _DICT.put( 30140, 57717 ); + _DICT.put( 30141, 57715 ); + _DICT.put( 30142, 36542 ); + _DICT.put( 30146, 57711 ); + _DICT.put( 30147, 57713 ); + _DICT.put( 30149, 38241 ); + _DICT.put( 30151, 36807 ); + _DICT.put( 30154, 57720 ); + _DICT.put( 30157, 57719 ); + _DICT.put( 30162, 57721 ); + _DICT.put( 30164, 36516 ); + _DICT.put( 30165, 36269 ); + _DICT.put( 30168, 37783 ); + _DICT.put( 30169, 57722 ); + _DICT.put( 30171, 37577 ); + _DICT.put( 30174, 57724 ); + _DICT.put( 30178, 38815 ); + _DICT.put( 30179, 57723 ); + _DICT.put( 30185, 37257 ); + _DICT.put( 30192, 57730 ); + _DICT.put( 30194, 57732 ); + _DICT.put( 30195, 57733 ); + _DICT.put( 30196, 37491 ); + _DICT.put( 30202, 57731 ); + _DICT.put( 30204, 57728 ); + _DICT.put( 30206, 57725 ); + _DICT.put( 30207, 57726 ); + _DICT.put( 30209, 57729 ); + _DICT.put( 30217, 57736 ); + _DICT.put( 30219, 57734 ); + _DICT.put( 30221, 57735 ); + _DICT.put( 30239, 57737 ); + _DICT.put( 30240, 57739 ); + _DICT.put( 30241, 57740 ); + _DICT.put( 30242, 57741 ); + _DICT.put( 30244, 57742 ); + _DICT.put( 30247, 57738 ); + _DICT.put( 30256, 57744 ); + _DICT.put( 30260, 57743 ); + _DICT.put( 30267, 57745 ); + _DICT.put( 30274, 38851 ); + _DICT.put( 30278, 57748 ); + _DICT.put( 30279, 57746 ); + _DICT.put( 30280, 57747 ); + _DICT.put( 30284, 35552 ); + _DICT.put( 30290, 38652 ); + _DICT.put( 30294, 38344 ); + _DICT.put( 30296, 57750 ); + _DICT.put( 30300, 57749 ); + _DICT.put( 30305, 57751 ); + _DICT.put( 30306, 57752 ); + _DICT.put( 30311, 57756 ); + _DICT.put( 30312, 57753 ); + _DICT.put( 30313, 57754 ); + _DICT.put( 30314, 57755 ); + _DICT.put( 30316, 57757 ); + _DICT.put( 30320, 57758 ); + _DICT.put( 30322, 57759 ); + _DICT.put( 30326, 57760 ); + _DICT.put( 30328, 57761 ); + _DICT.put( 30330, 38061 ); + _DICT.put( 30331, 37743 ); + _DICT.put( 30332, 57762 ); + _DICT.put( 30333, 38034 ); + _DICT.put( 30334, 38227 ); + _DICT.put( 30336, 57763 ); + _DICT.put( 30338, 64368 ); + _DICT.put( 30339, 57764 ); + _DICT.put( 30340, 37705 ); + _DICT.put( 30342, 35398 ); + _DICT.put( 30343, 36195 ); + _DICT.put( 30344, 57765 ); + _DICT.put( 30347, 57766 ); + _DICT.put( 30350, 57767 ); + _DICT.put( 30352, 36424 ); + _DICT.put( 30355, 57769 ); + _DICT.put( 30358, 57768 ); + _DICT.put( 30361, 57770 ); + _DICT.put( 30362, 57771 ); + _DICT.put( 30363, 64371 ); + _DICT.put( 30364, 64369 ); + _DICT.put( 30366, 64370 ); + _DICT.put( 30374, 64372 ); + _DICT.put( 30382, 38119 ); + _DICT.put( 30384, 57772 ); + _DICT.put( 30388, 57773 ); + _DICT.put( 30391, 60041 ); + _DICT.put( 30392, 57774 ); + _DICT.put( 30393, 57775 ); + _DICT.put( 30394, 57776 ); + _DICT.put( 30399, 36429 ); + _DICT.put( 30402, 57777 ); + _DICT.put( 30403, 38005 ); + _DICT.put( 30406, 38526 ); + _DICT.put( 30408, 35181 ); + _DICT.put( 30410, 35190 ); + _DICT.put( 30413, 57778 ); + _DICT.put( 30418, 57780 ); + _DICT.put( 30422, 57779 ); + _DICT.put( 30423, 37776 ); + _DICT.put( 30427, 37047 ); + _DICT.put( 30428, 40792 ); + _DICT.put( 30430, 57781 ); + _DICT.put( 30431, 38591 ); + _DICT.put( 30433, 57782 ); + _DICT.put( 30435, 35524 ); + _DICT.put( 30436, 38101 ); + _DICT.put( 30437, 57783 ); + _DICT.put( 30439, 57784 ); + _DICT.put( 30442, 57785 ); + _DICT.put( 30446, 38618 ); + _DICT.put( 30450, 38611 ); + _DICT.put( 30452, 37564 ); + _DICT.put( 30456, 37258 ); + _DICT.put( 30459, 57787 ); + _DICT.put( 30462, 36738 ); + _DICT.put( 30465, 36808 ); + _DICT.put( 30468, 57790 ); + _DICT.put( 30471, 57789 ); + _DICT.put( 30472, 57788 ); + _DICT.put( 30473, 38139 ); + _DICT.put( 30475, 35525 ); + _DICT.put( 30476, 36007 ); + _DICT.put( 30491, 57796 ); + _DICT.put( 30494, 57793 ); + _DICT.put( 30495, 36958 ); + _DICT.put( 30496, 38576 ); + _DICT.put( 30500, 57792 ); + _DICT.put( 30501, 57794 ); + _DICT.put( 30502, 57795 ); + _DICT.put( 30505, 57791 ); + _DICT.put( 30519, 57797 ); + _DICT.put( 30520, 57798 ); + _DICT.put( 30522, 37549 ); + _DICT.put( 30524, 35553 ); + _DICT.put( 30528, 37509 ); + _DICT.put( 30534, 64374 ); + _DICT.put( 30535, 57799 ); + _DICT.put( 30554, 57800 ); + _DICT.put( 30555, 57803 ); + _DICT.put( 30561, 36999 ); + _DICT.put( 30563, 37826 ); + _DICT.put( 30565, 57804 ); + _DICT.put( 30566, 38514 ); + _DICT.put( 30568, 57801 ); + _DICT.put( 30571, 57802 ); + _DICT.put( 30585, 57807 ); + _DICT.put( 30590, 57806 ); + _DICT.put( 30591, 57805 ); + _DICT.put( 30603, 57809 ); + _DICT.put( 30606, 57808 ); + _DICT.put( 30609, 57810 ); + _DICT.put( 30622, 57812 ); + _DICT.put( 30624, 57811 ); + _DICT.put( 30629, 38347 ); + _DICT.put( 30636, 36725 ); + _DICT.put( 30637, 38852 ); + _DICT.put( 30640, 57813 ); + _DICT.put( 30643, 37813 ); + _DICT.put( 30646, 57814 ); + _DICT.put( 30649, 57815 ); + _DICT.put( 30651, 57819 ); + _DICT.put( 30652, 57817 ); + _DICT.put( 30653, 57818 ); + _DICT.put( 30655, 57816 ); + _DICT.put( 30663, 57820 ); + _DICT.put( 30669, 57821 ); + _DICT.put( 30679, 57822 ); + _DICT.put( 30682, 57823 ); + _DICT.put( 30683, 38581 ); + _DICT.put( 30684, 57824 ); + _DICT.put( 30690, 38638 ); + _DICT.put( 30691, 57825 ); + _DICT.put( 30693, 37485 ); + _DICT.put( 30695, 38026 ); + _DICT.put( 30697, 35817 ); + _DICT.put( 30701, 37466 ); + _DICT.put( 30702, 57826 ); + _DICT.put( 30703, 35768 ); + _DICT.put( 30707, 37070 ); + _DICT.put( 30716, 57827 ); + _DICT.put( 30722, 36283 ); + _DICT.put( 30732, 57828 ); + _DICT.put( 30738, 57829 ); + _DICT.put( 30740, 36004 ); + _DICT.put( 30741, 36307 ); + _DICT.put( 30752, 57831 ); + _DICT.put( 30753, 64376 ); + _DICT.put( 30757, 37749 ); + _DICT.put( 30758, 36308 ); + _DICT.put( 30759, 35693 ); + _DICT.put( 30770, 38467 ); + _DICT.put( 30772, 37994 ); + _DICT.put( 30778, 37750 ); + _DICT.put( 30783, 36219 ); + _DICT.put( 30789, 57833 ); + _DICT.put( 30798, 64377 ); + _DICT.put( 30813, 36809 ); + _DICT.put( 30820, 64378 ); + _DICT.put( 30827, 38832 ); + _DICT.put( 30828, 36196 ); + _DICT.put( 30831, 36005 ); + _DICT.put( 30834, 38049 ); + _DICT.put( 30836, 57835 ); + _DICT.put( 30842, 64379 ); + _DICT.put( 30844, 57837 ); + _DICT.put( 30849, 36073 ); + _DICT.put( 30854, 57836 ); + _DICT.put( 30855, 37620 ); + _DICT.put( 30860, 57839 ); + _DICT.put( 30861, 35414 ); + _DICT.put( 30862, 57834 ); + _DICT.put( 30865, 38120 ); + _DICT.put( 30867, 35151 ); + _DICT.put( 30869, 36330 ); + _DICT.put( 30871, 39025 ); + _DICT.put( 30874, 57838 ); + _DICT.put( 30883, 57840 ); + _DICT.put( 30887, 38345 ); + _DICT.put( 30889, 37079 ); + _DICT.put( 30890, 57842 ); + _DICT.put( 30895, 57843 ); + _DICT.put( 30901, 57841 ); + _DICT.put( 30906, 35437 ); + _DICT.put( 30908, 57849 ); + _DICT.put( 30910, 57848 ); + _DICT.put( 30913, 36517 ); + _DICT.put( 30917, 57850 ); + _DICT.put( 30918, 57845 ); + _DICT.put( 30922, 57851 ); + _DICT.put( 30923, 57846 ); + _DICT.put( 30928, 38102 ); + _DICT.put( 30929, 57844 ); + _DICT.put( 30932, 57847 ); + _DICT.put( 30938, 57921 ); + _DICT.put( 30951, 57920 ); + _DICT.put( 30952, 38529 ); + _DICT.put( 30956, 57852 ); + _DICT.put( 30959, 35049 ); + _DICT.put( 30964, 57923 ); + _DICT.put( 30973, 57922 ); + _DICT.put( 30977, 36810 ); + _DICT.put( 30983, 57924 ); + _DICT.put( 30990, 37218 ); + _DICT.put( 30993, 57926 ); + _DICT.put( 30994, 57925 ); + _DICT.put( 31001, 57927 ); + _DICT.put( 31014, 57830 ); + _DICT.put( 31018, 57832 ); + _DICT.put( 31019, 57929 ); + _DICT.put( 31020, 57928 ); + _DICT.put( 31024, 64380 ); + _DICT.put( 31034, 36518 ); + _DICT.put( 31036, 38887 ); + _DICT.put( 31038, 36560 ); + _DICT.put( 31040, 57930 ); + _DICT.put( 31041, 35926 ); + _DICT.put( 31047, 35679 ); + _DICT.put( 31048, 35654 ); + _DICT.put( 31049, 36483 ); + _DICT.put( 31056, 38739 ); + _DICT.put( 31059, 57936 ); + _DICT.put( 31061, 57935 ); + _DICT.put( 31062, 37219 ); + _DICT.put( 31063, 57932 ); + _DICT.put( 31066, 57934 ); + _DICT.put( 31069, 36714 ); + _DICT.put( 31070, 36959 ); + _DICT.put( 31071, 57933 ); + _DICT.put( 31072, 57931 ); + _DICT.put( 31074, 37961 ); + _DICT.put( 31077, 36811 ); + _DICT.put( 31080, 38235 ); + _DICT.put( 31085, 36309 ); + _DICT.put( 31095, 37784 ); + _DICT.put( 31098, 57937 ); + _DICT.put( 31103, 57938 ); + _DICT.put( 31104, 57960 ); + _DICT.put( 31105, 35798 ); + _DICT.put( 31108, 39004 ); + _DICT.put( 31109, 37204 ); + _DICT.put( 31114, 57939 ); + _DICT.put( 31117, 35280 ); + _DICT.put( 31118, 37621 ); + _DICT.put( 31119, 38303 ); + _DICT.put( 31124, 64385 ); + _DICT.put( 31131, 64387 ); + _DICT.put( 31133, 57940 ); + _DICT.put( 31142, 35738 ); + _DICT.put( 31143, 57941 ); + _DICT.put( 31146, 57943 ); + _DICT.put( 31150, 57944 ); + _DICT.put( 31152, 37960 ); + _DICT.put( 31155, 57945 ); + _DICT.put( 31161, 57946 ); + _DICT.put( 31162, 57947 ); + _DICT.put( 31165, 35799 ); + _DICT.put( 31166, 35281 ); + _DICT.put( 31167, 37827 ); + _DICT.put( 31168, 36679 ); + _DICT.put( 31169, 36484 ); + _DICT.put( 31177, 57948 ); + _DICT.put( 31179, 36680 ); + _DICT.put( 31185, 35272 ); + _DICT.put( 31186, 38242 ); + _DICT.put( 31189, 57949 ); + _DICT.put( 31192, 38121 ); + _DICT.put( 31199, 37220 ); + _DICT.put( 31201, 57952 ); + _DICT.put( 31203, 57953 ); + _DICT.put( 31204, 38025 ); + _DICT.put( 31206, 36960 ); + _DICT.put( 31207, 57950 ); + _DICT.put( 31209, 37505 ); + _DICT.put( 31212, 57951 ); + _DICT.put( 31216, 36812 ); + _DICT.put( 31227, 35034 ); + _DICT.put( 31232, 35656 ); + _DICT.put( 31240, 57954 ); + _DICT.put( 31243, 37622 ); + _DICT.put( 31245, 57955 ); + _DICT.put( 31246, 37061 ); + _DICT.put( 31252, 38571 ); + _DICT.put( 31255, 38210 ); + _DICT.put( 31256, 57956 ); + _DICT.put( 31257, 57957 ); + _DICT.put( 31258, 37492 ); + _DICT.put( 31260, 38853 ); + _DICT.put( 31263, 57959 ); + _DICT.put( 31264, 57958 ); + _DICT.put( 31278, 36589 ); + _DICT.put( 31281, 57961 ); + _DICT.put( 31282, 35054 ); + _DICT.put( 31287, 57964 ); + _DICT.put( 31291, 57962 ); + _DICT.put( 31292, 35282 ); + _DICT.put( 31293, 35949 ); + _DICT.put( 31294, 57963 ); + _DICT.put( 31295, 36197 ); + _DICT.put( 31296, 36242 ); + _DICT.put( 31298, 38372 ); + _DICT.put( 31299, 57965 ); + _DICT.put( 31302, 38515 ); + _DICT.put( 31305, 57967 ); + _DICT.put( 31309, 37071 ); + _DICT.put( 31310, 35182 ); + _DICT.put( 31311, 35256 ); + _DICT.put( 31312, 34986 ); + _DICT.put( 31319, 57966 ); + _DICT.put( 31329, 57968 ); + _DICT.put( 31330, 57969 ); + _DICT.put( 31331, 36853 ); + _DICT.put( 31337, 57970 ); + _DICT.put( 31339, 35438 ); + _DICT.put( 31344, 57972 ); + _DICT.put( 31348, 35978 ); + _DICT.put( 31350, 35718 ); + _DICT.put( 31353, 57973 ); + _DICT.put( 31354, 35827 ); + _DICT.put( 31357, 57974 ); + _DICT.put( 31359, 37114 ); + _DICT.put( 31361, 37835 ); + _DICT.put( 31363, 37086 ); + _DICT.put( 31364, 36339 ); + _DICT.put( 31368, 57975 ); + _DICT.put( 31378, 37506 ); + _DICT.put( 31379, 37259 ); + _DICT.put( 31381, 57977 ); + _DICT.put( 31382, 57979 ); + _DICT.put( 31383, 57976 ); + _DICT.put( 31384, 57978 ); + _DICT.put( 31391, 35905 ); + _DICT.put( 31401, 57980 ); + _DICT.put( 31402, 35909 ); + _DICT.put( 31406, 35719 ); + _DICT.put( 31407, 38769 ); + _DICT.put( 31408, 57982 ); + _DICT.put( 31414, 57984 ); + _DICT.put( 31418, 35149 ); + _DICT.put( 31423, 57987 ); + _DICT.put( 31427, 35478 ); + _DICT.put( 31428, 57986 ); + _DICT.put( 31429, 57985 ); + _DICT.put( 31431, 57989 ); + _DICT.put( 31432, 57981 ); + _DICT.put( 31434, 57990 ); + _DICT.put( 31435, 38823 ); + _DICT.put( 31437, 57991 ); + _DICT.put( 31439, 57992 ); + _DICT.put( 31441, 64388 ); + _DICT.put( 31442, 39666 ); + _DICT.put( 31443, 57994 ); + _DICT.put( 31445, 57993 ); + _DICT.put( 31449, 57995 ); + _DICT.put( 31450, 57996 ); + _DICT.put( 31452, 38835 ); + _DICT.put( 31453, 57997 ); + _DICT.put( 31455, 59629 ); + _DICT.put( 31456, 36813 ); + _DICT.put( 31457, 57998 ); + _DICT.put( 31458, 57999 ); + _DICT.put( 31459, 36726 ); + _DICT.put( 31461, 37814 ); + _DICT.put( 31462, 58000 ); + _DICT.put( 31463, 64389 ); + _DICT.put( 31466, 37447 ); + _DICT.put( 31467, 64391 ); + _DICT.put( 31469, 58001 ); + _DICT.put( 31471, 37467 ); + _DICT.put( 31472, 58002 ); + _DICT.put( 31478, 35747 ); + _DICT.put( 31480, 39262 ); + _DICT.put( 31481, 37500 ); + _DICT.put( 31482, 36529 ); + _DICT.put( 31487, 35526 ); + _DICT.put( 31490, 58003 ); + _DICT.put( 31492, 58016 ); + _DICT.put( 31494, 58006 ); + _DICT.put( 31496, 35720 ); + _DICT.put( 31498, 58005 ); + _DICT.put( 31499, 58018 ); + _DICT.put( 31503, 58004 ); + _DICT.put( 31505, 36814 ); + _DICT.put( 31512, 58008 ); + _DICT.put( 31513, 58009 ); + _DICT.put( 31515, 37706 ); + _DICT.put( 31518, 58010 ); + _DICT.put( 31520, 35453 ); + _DICT.put( 31525, 36985 ); + _DICT.put( 31526, 38276 ); + _DICT.put( 31528, 58012 ); + _DICT.put( 31532, 37350 ); + _DICT.put( 31539, 58007 ); + _DICT.put( 31541, 58011 ); + _DICT.put( 31542, 58013 ); + _DICT.put( 31545, 36345 ); + _DICT.put( 31557, 58020 ); + _DICT.put( 31558, 38221 ); + _DICT.put( 31560, 38052 ); + _DICT.put( 31561, 37785 ); + _DICT.put( 31563, 35800 ); + _DICT.put( 31564, 58019 ); + _DICT.put( 31565, 58017 ); + _DICT.put( 31567, 38067 ); + _DICT.put( 31568, 58014 ); + _DICT.put( 31569, 37501 ); + _DICT.put( 31570, 37787 ); + _DICT.put( 31572, 37786 ); + _DICT.put( 31574, 36340 ); + _DICT.put( 31581, 58038 ); + _DICT.put( 31589, 58022 ); + _DICT.put( 31591, 58024 ); + _DICT.put( 31596, 58027 ); + _DICT.put( 31598, 58028 ); + _DICT.put( 31600, 58025 ); + _DICT.put( 31601, 58026 ); + _DICT.put( 31604, 58023 ); + _DICT.put( 31605, 58021 ); + _DICT.put( 31610, 58015 ); + _DICT.put( 31622, 38349 ); + _DICT.put( 31623, 35283 ); + _DICT.put( 31627, 58035 ); + _DICT.put( 31629, 58032 ); + _DICT.put( 31631, 58037 ); + _DICT.put( 31634, 58036 ); + _DICT.put( 31636, 38035 ); + _DICT.put( 31637, 38565 ); + _DICT.put( 31639, 36442 ); + _DICT.put( 31640, 58030 ); + _DICT.put( 31641, 58039 ); + _DICT.put( 31642, 58034 ); + _DICT.put( 31644, 58033 ); + _DICT.put( 31645, 58029 ); + _DICT.put( 31646, 64392 ); + _DICT.put( 31647, 58031 ); + _DICT.put( 31649, 35527 ); + _DICT.put( 31658, 37468 ); + _DICT.put( 31661, 37115 ); + _DICT.put( 31665, 38048 ); + _DICT.put( 31668, 58044 ); + _DICT.put( 31672, 38050 ); + _DICT.put( 31680, 37087 ); + _DICT.put( 31681, 58041 ); + _DICT.put( 31684, 38093 ); + _DICT.put( 31686, 58045 ); + _DICT.put( 31687, 38353 ); + _DICT.put( 31689, 37498 ); + _DICT.put( 31691, 58040 ); + _DICT.put( 31692, 58042 ); + _DICT.put( 31695, 58043 ); + _DICT.put( 31709, 58046 ); + _DICT.put( 31712, 36546 ); + _DICT.put( 31716, 37828 ); + _DICT.put( 31717, 58051 ); + _DICT.put( 31718, 58050 ); + _DICT.put( 31721, 58047 ); + _DICT.put( 31725, 38997 ); + _DICT.put( 31731, 58056 ); + _DICT.put( 31734, 58060 ); + _DICT.put( 31735, 58057 ); + _DICT.put( 31744, 58053 ); + _DICT.put( 31751, 58054 ); + _DICT.put( 31757, 58059 ); + _DICT.put( 31761, 58048 ); + _DICT.put( 31762, 39379 ); + _DICT.put( 31763, 58055 ); + _DICT.put( 31764, 58049 ); + _DICT.put( 31767, 58058 ); + _DICT.put( 31775, 58064 ); + _DICT.put( 31777, 35528 ); + _DICT.put( 31779, 58061 ); + _DICT.put( 31783, 58062 ); + _DICT.put( 31786, 58063 ); + _DICT.put( 31787, 58066 ); + _DICT.put( 31799, 58065 ); + _DICT.put( 31800, 38132 ); + _DICT.put( 31805, 58067 ); + _DICT.put( 31806, 38906 ); + _DICT.put( 31807, 38379 ); + _DICT.put( 31808, 58072 ); + _DICT.put( 31811, 58069 ); + _DICT.put( 31820, 58068 ); + _DICT.put( 31821, 37072 ); + _DICT.put( 31823, 58071 ); + _DICT.put( 31824, 58073 ); + _DICT.put( 31828, 58070 ); + _DICT.put( 31830, 58077 ); + _DICT.put( 31832, 58074 ); + _DICT.put( 31839, 58075 ); + _DICT.put( 31840, 58052 ); + _DICT.put( 31844, 58076 ); + _DICT.put( 31845, 58078 ); + _DICT.put( 31852, 58079 ); + _DICT.put( 31859, 38340 ); + _DICT.put( 31861, 58080 ); + _DICT.put( 31870, 38624 ); + _DICT.put( 31873, 35788 ); + _DICT.put( 31874, 35912 ); + _DICT.put( 31875, 58081 ); + _DICT.put( 31881, 38322 ); + _DICT.put( 31883, 37000 ); + _DICT.put( 31885, 38574 ); + _DICT.put( 31888, 58082 ); + _DICT.put( 31890, 38833 ); + _DICT.put( 31893, 38036 ); + _DICT.put( 31895, 37221 ); + _DICT.put( 31896, 37971 ); + _DICT.put( 31899, 36716 ); + _DICT.put( 31903, 35006 ); + _DICT.put( 31905, 58087 ); + _DICT.put( 31906, 58085 ); + _DICT.put( 31908, 58083 ); + _DICT.put( 31909, 35487 ); + _DICT.put( 31911, 36815 ); + _DICT.put( 31912, 58088 ); + _DICT.put( 31915, 58086 ); + _DICT.put( 31917, 58084 ); + _DICT.put( 31918, 58092 ); + _DICT.put( 31921, 58091 ); + _DICT.put( 31922, 58090 ); + _DICT.put( 31923, 58089 ); + _DICT.put( 31929, 58093 ); + _DICT.put( 31933, 58094 ); + _DICT.put( 31934, 37048 ); + _DICT.put( 31936, 58095 ); + _DICT.put( 31938, 58097 ); + _DICT.put( 31941, 58096 ); + _DICT.put( 31946, 36048 ); + _DICT.put( 31950, 37207 ); + _DICT.put( 31954, 58099 ); + _DICT.put( 31958, 37788 ); + _DICT.put( 31960, 58098 ); + _DICT.put( 31964, 58100 ); + _DICT.put( 31966, 38323 ); + _DICT.put( 31967, 37260 ); + _DICT.put( 31968, 36198 ); + _DICT.put( 31970, 58101 ); + _DICT.put( 31975, 38854 ); + _DICT.put( 31983, 58103 ); + _DICT.put( 31986, 58104 ); + _DICT.put( 31988, 58105 ); + _DICT.put( 31990, 58106 ); + _DICT.put( 31992, 36485 ); + _DICT.put( 31994, 58107 ); + _DICT.put( 31995, 35950 ); + _DICT.put( 31998, 35722 ); + _DICT.put( 32000, 35657 ); + _DICT.put( 32002, 58176 ); + _DICT.put( 32004, 38641 ); + _DICT.put( 32005, 36199 ); + _DICT.put( 32006, 58108 ); + _DICT.put( 32010, 58179 ); + _DICT.put( 32011, 38628 ); + _DICT.put( 32013, 37979 ); + _DICT.put( 32016, 38226 ); + _DICT.put( 32020, 36739 ); + _DICT.put( 32021, 58178 ); + _DICT.put( 32023, 36561 ); + _DICT.put( 32024, 36200 ); + _DICT.put( 32025, 36486 ); + _DICT.put( 32026, 35721 ); + _DICT.put( 32027, 38324 ); + _DICT.put( 32028, 58177 ); + _DICT.put( 32032, 37222 ); + _DICT.put( 32033, 38497 ); + _DICT.put( 32034, 36341 ); + _DICT.put( 32043, 36487 ); + _DICT.put( 32044, 37595 ); + _DICT.put( 32046, 58182 ); + _DICT.put( 32047, 38877 ); + _DICT.put( 32048, 36311 ); + _DICT.put( 32050, 58183 ); + _DICT.put( 32051, 36961 ); + _DICT.put( 32053, 58185 ); + _DICT.put( 32057, 36816 ); + _DICT.put( 32058, 36270 ); + _DICT.put( 32063, 58184 ); + _DICT.put( 32066, 36681 ); + _DICT.put( 32067, 36028 ); + _DICT.put( 32068, 37223 ); + _DICT.put( 32069, 58180 ); + _DICT.put( 32070, 58186 ); + _DICT.put( 32072, 64394 ); + _DICT.put( 32075, 58181 ); + _DICT.put( 32076, 35951 ); + _DICT.put( 32078, 58189 ); + _DICT.put( 32079, 58193 ); + _DICT.put( 32080, 35979 ); + _DICT.put( 32086, 58188 ); + _DICT.put( 32091, 58197 ); + _DICT.put( 32092, 64395 ); + _DICT.put( 32094, 36201 ); + _DICT.put( 32097, 38797 ); + _DICT.put( 32098, 35002 ); + _DICT.put( 32099, 58194 ); + _DICT.put( 32102, 35723 ); + _DICT.put( 32104, 58191 ); + _DICT.put( 32110, 58192 ); + _DICT.put( 32113, 37789 ); + _DICT.put( 32114, 58190 ); + _DICT.put( 32115, 58187 ); + _DICT.put( 32117, 35399 ); + _DICT.put( 32118, 37090 ); + _DICT.put( 32121, 36006 ); + _DICT.put( 32125, 58199 ); + _DICT.put( 32137, 58196 ); + _DICT.put( 32143, 58198 ); + _DICT.put( 32147, 58195 ); + _DICT.put( 32153, 35952 ); + _DICT.put( 32154, 37297 ); + _DICT.put( 32155, 58200 ); + _DICT.put( 32156, 37262 ); + _DICT.put( 32159, 58213 ); + _DICT.put( 32160, 64397 ); + _DICT.put( 32162, 58209 ); + _DICT.put( 32163, 58203 ); + _DICT.put( 32171, 58207 ); + _DICT.put( 32172, 36600 ); + _DICT.put( 32173, 35035 ); + _DICT.put( 32174, 58202 ); + _DICT.put( 32175, 58210 ); + _DICT.put( 32176, 58214 ); + _DICT.put( 32177, 36202 ); + _DICT.put( 32178, 38612 ); + _DICT.put( 32180, 37588 ); + _DICT.put( 32181, 58204 ); + _DICT.put( 32183, 64396 ); + _DICT.put( 32184, 58212 ); + _DICT.put( 32186, 58201 ); + _DICT.put( 32187, 37469 ); + _DICT.put( 32189, 58206 ); + _DICT.put( 32190, 35003 ); + _DICT.put( 32191, 38600 ); + _DICT.put( 32199, 58205 ); + _DICT.put( 32202, 35801 ); + _DICT.put( 32203, 38122 ); + _DICT.put( 32207, 37261 ); + _DICT.put( 32209, 38862 ); + _DICT.put( 32210, 36751 ); + _DICT.put( 32213, 58254 ); + _DICT.put( 32214, 64398 ); + _DICT.put( 32216, 58215 ); + _DICT.put( 32218, 37116 ); + _DICT.put( 32220, 58211 ); + _DICT.put( 32221, 58216 ); + _DICT.put( 32222, 58218 ); + _DICT.put( 32224, 37623 ); + _DICT.put( 32225, 58221 ); + _DICT.put( 32228, 58217 ); + _DICT.put( 32232, 38354 ); + _DICT.put( 32233, 35529 ); + _DICT.put( 32236, 38601 ); + _DICT.put( 32239, 35036 ); + _DICT.put( 32242, 58220 ); + _DICT.put( 32244, 38907 ); + _DICT.put( 32251, 58219 ); + _DICT.put( 32257, 35215 ); + _DICT.put( 32260, 37866 ); + _DICT.put( 32261, 58222 ); + _DICT.put( 32265, 58229 ); + _DICT.put( 32266, 58223 ); + _DICT.put( 32267, 58230 ); + _DICT.put( 32274, 58226 ); + _DICT.put( 32283, 38043 ); + _DICT.put( 32286, 36552 ); + _DICT.put( 32287, 58228 ); + _DICT.put( 32289, 58225 ); + _DICT.put( 32290, 58231 ); + _DICT.put( 32291, 58224 ); + _DICT.put( 32294, 36707 ); + _DICT.put( 32299, 38468 ); + _DICT.put( 32302, 36715 ); + _DICT.put( 32305, 58227 ); + _DICT.put( 32306, 58240 ); + _DICT.put( 32309, 58235 ); + _DICT.put( 32311, 58238 ); + _DICT.put( 32313, 58236 ); + _DICT.put( 32314, 58241 ); + _DICT.put( 32315, 58234 ); + _DICT.put( 32317, 58208 ); + _DICT.put( 32318, 37073 ); + _DICT.put( 32321, 38089 ); + _DICT.put( 32323, 58237 ); + _DICT.put( 32326, 58232 ); + _DICT.put( 32330, 37184 ); + _DICT.put( 32331, 35953 ); + _DICT.put( 32333, 36682 ); + _DICT.put( 32338, 64399 ); + _DICT.put( 32340, 36932 ); + _DICT.put( 32341, 37205 ); + _DICT.put( 32342, 58244 ); + _DICT.put( 32345, 58246 ); + _DICT.put( 32346, 58247 ); + _DICT.put( 32349, 58243 ); + _DICT.put( 32350, 58245 ); + _DICT.put( 32358, 58233 ); + _DICT.put( 32359, 58242 ); + _DICT.put( 32361, 58250 ); + _DICT.put( 32362, 58249 ); + _DICT.put( 32365, 38554 ); + _DICT.put( 32368, 35914 ); + _DICT.put( 32377, 58248 ); + _DICT.put( 32379, 58252 ); + _DICT.put( 32380, 58251 ); + _DICT.put( 32381, 58255 ); + _DICT.put( 32383, 58257 ); + _DICT.put( 32386, 36443 ); + _DICT.put( 32387, 58253 ); + _DICT.put( 32392, 58258 ); + _DICT.put( 32393, 58259 ); + _DICT.put( 32394, 64092 ); + _DICT.put( 32396, 58260 ); + _DICT.put( 32398, 58266 ); + _DICT.put( 32399, 37722 ); + _DICT.put( 32400, 58262 ); + _DICT.put( 32402, 58261 ); + _DICT.put( 32403, 58263 ); + _DICT.put( 32404, 58264 ); + _DICT.put( 32406, 58265 ); + _DICT.put( 32411, 58267 ); + _DICT.put( 32412, 58268 ); + _DICT.put( 32566, 35530 ); + _DICT.put( 32568, 58269 ); + _DICT.put( 32570, 58270 ); + _DICT.put( 32581, 58271 ); + _DICT.put( 32583, 64400 ); + _DICT.put( 32588, 58272 ); + _DICT.put( 32589, 58273 ); + _DICT.put( 32590, 58274 ); + _DICT.put( 32592, 58275 ); + _DICT.put( 32593, 58276 ); + _DICT.put( 32596, 58278 ); + _DICT.put( 32597, 58277 ); + _DICT.put( 32600, 58279 ); + _DICT.put( 32607, 58280 ); + _DICT.put( 32608, 58281 ); + _DICT.put( 32615, 58284 ); + _DICT.put( 32616, 58282 ); + _DICT.put( 32617, 58283 ); + _DICT.put( 32618, 36319 ); + _DICT.put( 32619, 35954 ); + _DICT.put( 32622, 37493 ); + _DICT.put( 32624, 38065 ); + _DICT.put( 32626, 36752 ); + _DICT.put( 32629, 37996 ); + _DICT.put( 32631, 38123 ); + _DICT.put( 32632, 58285 ); + _DICT.put( 32633, 40171 ); + _DICT.put( 32642, 58286 ); + _DICT.put( 32643, 58288 ); + _DICT.put( 32645, 38789 ); + _DICT.put( 32646, 58287 ); + _DICT.put( 32647, 58290 ); + _DICT.put( 32648, 58289 ); + _DICT.put( 32650, 38770 ); + _DICT.put( 32652, 58291 ); + _DICT.put( 32654, 38140 ); + _DICT.put( 32660, 58292 ); + _DICT.put( 32666, 58295 ); + _DICT.put( 32669, 58294 ); + _DICT.put( 32670, 58293 ); + _DICT.put( 32673, 64401 ); + _DICT.put( 32675, 58296 ); + _DICT.put( 32676, 35921 ); + _DICT.put( 32680, 37185 ); + _DICT.put( 32681, 35680 ); + _DICT.put( 32686, 58300 ); + _DICT.put( 32687, 58297 ); + _DICT.put( 32690, 58298 ); + _DICT.put( 32694, 58301 ); + _DICT.put( 32696, 58302 ); + _DICT.put( 32697, 58299 ); + _DICT.put( 32701, 35144 ); + _DICT.put( 32705, 35237 ); + _DICT.put( 32709, 58304 ); + _DICT.put( 32710, 58305 ); + _DICT.put( 32714, 58306 ); + _DICT.put( 32716, 38786 ); + _DICT.put( 32722, 36683 ); + _DICT.put( 32724, 58308 ); + _DICT.put( 32725, 58307 ); + _DICT.put( 32736, 37001 ); + _DICT.put( 32737, 58309 ); + _DICT.put( 32742, 58310 ); + _DICT.put( 32745, 58311 ); + _DICT.put( 32747, 35555 ); + _DICT.put( 32752, 35531 ); + _DICT.put( 32755, 58312 ); + _DICT.put( 32761, 58313 ); + _DICT.put( 32763, 38524 ); + _DICT.put( 32764, 38787 ); + _DICT.put( 32768, 38771 ); + _DICT.put( 32769, 38998 ); + _DICT.put( 32771, 36204 ); + _DICT.put( 32772, 58316 ); + _DICT.put( 32773, 36562 ); + _DICT.put( 32774, 58315 ); + _DICT.put( 32779, 58317 ); + _DICT.put( 32780, 36519 ); + _DICT.put( 32784, 37327 ); + _DICT.put( 32786, 58318 ); + _DICT.put( 32789, 36203 ); + _DICT.put( 32791, 38613 ); + _DICT.put( 32792, 58319 ); + _DICT.put( 32793, 58320 ); + _DICT.put( 32796, 58321 ); + _DICT.put( 32801, 58322 ); + _DICT.put( 32808, 58323 ); + _DICT.put( 32819, 36520 ); + _DICT.put( 32822, 38635 ); + _DICT.put( 32827, 58325 ); + _DICT.put( 32829, 37470 ); + _DICT.put( 32831, 58324 ); + _DICT.put( 32838, 58327 ); + _DICT.put( 32842, 58326 ); + _DICT.put( 32850, 58328 ); + _DICT.put( 32854, 37049 ); + _DICT.put( 32856, 58329 ); + _DICT.put( 32858, 58330 ); + _DICT.put( 32862, 38327 ); + _DICT.put( 32863, 58331 ); + _DICT.put( 32865, 37263 ); + _DICT.put( 32866, 58332 ); + _DICT.put( 32872, 58333 ); + _DICT.put( 32879, 38908 ); + _DICT.put( 32880, 58336 ); + _DICT.put( 32882, 58335 ); + _DICT.put( 32883, 58334 ); + _DICT.put( 32884, 37550 ); + _DICT.put( 32886, 58337 ); + _DICT.put( 32887, 36933 ); + _DICT.put( 32889, 58338 ); + _DICT.put( 32893, 58339 ); + _DICT.put( 32894, 38999 ); + _DICT.put( 32895, 58340 ); + _DICT.put( 32900, 58341 ); + _DICT.put( 32901, 58343 ); + _DICT.put( 32902, 58342 ); + _DICT.put( 32903, 38051 ); + _DICT.put( 32905, 37879 ); + _DICT.put( 32907, 39005 ); + _DICT.put( 32908, 38055 ); + _DICT.put( 32915, 58345 ); + _DICT.put( 32918, 36817 ); + _DICT.put( 32920, 38217 ); + _DICT.put( 32922, 58346 ); + _DICT.put( 32923, 58344 ); + _DICT.put( 32925, 35532 ); + _DICT.put( 32929, 36050 ); + _DICT.put( 32930, 36488 ); + _DICT.put( 32933, 38124 ); + _DICT.put( 32937, 36008 ); + _DICT.put( 32938, 38498 ); + _DICT.put( 32940, 58349 ); + _DICT.put( 32941, 58347 ); + _DICT.put( 32943, 36205 ); + _DICT.put( 32945, 36206 ); + _DICT.put( 32946, 35047 ); + _DICT.put( 32948, 36326 ); + _DICT.put( 32954, 38008 ); + _DICT.put( 32963, 35037 ); + _DICT.put( 32964, 58354 ); + _DICT.put( 32966, 37471 ); + _DICT.put( 32972, 38007 ); + _DICT.put( 32974, 37337 ); + _DICT.put( 32982, 58356 ); + _DICT.put( 32985, 58352 ); + _DICT.put( 32986, 58355 ); + _DICT.put( 32987, 58350 ); + _DICT.put( 32989, 58353 ); + _DICT.put( 32990, 38469 ); + _DICT.put( 32993, 36051 ); + _DICT.put( 32996, 35067 ); + _DICT.put( 32997, 58351 ); + _DICT.put( 33007, 58358 ); + _DICT.put( 33009, 58359 ); + _DICT.put( 33012, 37815 ); + _DICT.put( 33016, 35769 ); + _DICT.put( 33020, 58437 ); + _DICT.put( 33021, 37980 ); + _DICT.put( 33026, 36489 ); + _DICT.put( 33029, 35770 ); + _DICT.put( 33030, 37062 ); + _DICT.put( 33031, 39013 ); + _DICT.put( 33032, 38572 ); + _DICT.put( 33033, 58357 ); + _DICT.put( 33034, 37074 ); + _DICT.put( 33050, 35698 ); + _DICT.put( 33051, 58360 ); + _DICT.put( 33059, 58362 ); + _DICT.put( 33065, 58361 ); + _DICT.put( 33071, 58363 ); + _DICT.put( 33073, 37445 ); + _DICT.put( 33075, 37981 ); + _DICT.put( 33081, 37551 ); + _DICT.put( 33086, 58434 ); + _DICT.put( 33094, 58433 ); + _DICT.put( 33099, 58364 ); + _DICT.put( 33102, 36980 ); + _DICT.put( 33104, 38277 ); + _DICT.put( 33105, 58436 ); + _DICT.put( 33107, 58435 ); + _DICT.put( 33108, 36207 ); + _DICT.put( 33109, 39026 ); + _DICT.put( 33119, 58452 ); + _DICT.put( 33125, 58440 ); + _DICT.put( 33126, 58441 ); + _DICT.put( 33131, 36590 ); + _DICT.put( 33134, 58439 ); + _DICT.put( 33136, 36248 ); + _DICT.put( 33137, 58438 ); + _DICT.put( 33140, 58442 ); + _DICT.put( 33144, 37552 ); + _DICT.put( 33145, 38304 ); + _DICT.put( 33146, 37186 ); + _DICT.put( 33151, 37338 ); + _DICT.put( 33152, 58446 ); + _DICT.put( 33154, 58447 ); + _DICT.put( 33155, 58443 ); + _DICT.put( 33160, 58444 ); + _DICT.put( 33162, 58445 ); + _DICT.put( 33167, 36208 ); + _DICT.put( 33171, 58453 ); + _DICT.put( 33173, 58449 ); + _DICT.put( 33178, 38278 ); + _DICT.put( 33180, 38540 ); + _DICT.put( 33181, 38215 ); + _DICT.put( 33184, 58448 ); + _DICT.put( 33187, 58451 ); + _DICT.put( 33188, 58450 ); + _DICT.put( 33192, 38499 ); + _DICT.put( 33193, 58454 ); + _DICT.put( 33200, 58455 ); + _DICT.put( 33203, 37206 ); + _DICT.put( 33205, 58456 ); + _DICT.put( 33208, 58458 ); + _DICT.put( 33210, 58462 ); + _DICT.put( 33213, 58459 ); + _DICT.put( 33214, 58457 ); + _DICT.put( 33215, 37982 ); + _DICT.put( 33216, 58460 ); + _DICT.put( 33218, 58461 ); + _DICT.put( 33222, 35248 ); + _DICT.put( 33224, 58468 ); + _DICT.put( 33225, 58463 ); + _DICT.put( 33229, 58464 ); + _DICT.put( 33233, 58465 ); + _DICT.put( 33235, 37279 ); + _DICT.put( 33240, 58467 ); + _DICT.put( 33241, 58466 ); + _DICT.put( 33242, 58469 ); + _DICT.put( 33247, 58470 ); + _DICT.put( 33248, 58471 ); + _DICT.put( 33251, 36962 ); + _DICT.put( 33253, 35303 ); + _DICT.put( 33255, 58472 ); + _DICT.put( 33256, 38869 ); + _DICT.put( 33258, 36521 ); + _DICT.put( 33261, 36684 ); + _DICT.put( 33267, 36490 ); + _DICT.put( 33268, 37494 ); + _DICT.put( 33274, 58473 ); + _DICT.put( 33275, 58474 ); + _DICT.put( 33276, 35152 ); + _DICT.put( 33278, 58475 ); + _DICT.put( 33281, 58476 ); + _DICT.put( 33282, 58477 ); + _DICT.put( 33285, 58478 ); + _DICT.put( 33287, 58479 ); + _DICT.put( 33288, 35771 ); + _DICT.put( 33289, 40360 ); + _DICT.put( 33290, 58480 ); + _DICT.put( 33292, 37091 ); + _DICT.put( 33293, 58481 ); + _DICT.put( 33294, 36553 ); + _DICT.put( 33296, 58482 ); + _DICT.put( 33298, 39086 ); + _DICT.put( 33302, 58483 ); + _DICT.put( 33303, 38364 ); + _DICT.put( 33304, 35546 ); + _DICT.put( 33307, 37187 ); + _DICT.put( 33308, 36727 ); + _DICT.put( 33310, 38289 ); + _DICT.put( 33311, 36685 ); + _DICT.put( 33321, 58484 ); + _DICT.put( 33322, 36209 ); + _DICT.put( 33323, 58485 ); + _DICT.put( 33324, 38090 ); + _DICT.put( 33326, 58500 ); + _DICT.put( 33331, 58487 ); + _DICT.put( 33333, 37319 ); + _DICT.put( 33334, 38037 ); + _DICT.put( 33335, 36029 ); + _DICT.put( 33336, 58486 ); + _DICT.put( 33337, 37188 ); + _DICT.put( 33344, 58488 ); + _DICT.put( 33351, 37624 ); + _DICT.put( 33368, 58490 ); + _DICT.put( 33369, 58489 ); + _DICT.put( 33370, 58492 ); + _DICT.put( 33373, 58491 ); + _DICT.put( 33375, 58493 ); + _DICT.put( 33378, 58496 ); + _DICT.put( 33380, 58494 ); + _DICT.put( 33382, 35533 ); + _DICT.put( 33384, 58497 ); + _DICT.put( 33386, 58498 ); + _DICT.put( 33387, 58499 ); + _DICT.put( 33390, 36271 ); + _DICT.put( 33391, 38855 ); + _DICT.put( 33393, 58501 ); + _DICT.put( 33394, 36934 ); + _DICT.put( 33398, 35216 ); + _DICT.put( 33399, 58502 ); + _DICT.put( 33400, 58503 ); + _DICT.put( 33406, 58504 ); + _DICT.put( 33419, 35056 ); + _DICT.put( 33421, 58505 ); + _DICT.put( 33426, 58506 ); + _DICT.put( 33433, 38279 ); + _DICT.put( 33437, 36549 ); + _DICT.put( 33439, 58508 ); + _DICT.put( 33445, 35400 ); + _DICT.put( 33446, 34992 ); + _DICT.put( 33451, 58507 ); + _DICT.put( 33452, 58510 ); + _DICT.put( 33453, 37997 ); + _DICT.put( 33455, 36963 ); + _DICT.put( 33457, 35284 ); + _DICT.put( 33459, 38470 ); + _DICT.put( 33464, 35964 ); + _DICT.put( 33465, 35802 ); + _DICT.put( 33467, 58509 ); + _DICT.put( 33469, 35304 ); + _DICT.put( 33477, 35489 ); + _DICT.put( 33489, 35217 ); + _DICT.put( 33490, 58514 ); + _DICT.put( 33491, 38888 ); + _DICT.put( 33492, 37339 ); + _DICT.put( 33495, 38243 ); + _DICT.put( 33497, 58526 ); + _DICT.put( 33499, 35285 ); + _DICT.put( 33500, 58524 ); + _DICT.put( 33502, 58522 ); + _DICT.put( 33503, 58513 ); + _DICT.put( 33505, 58511 ); + _DICT.put( 33507, 58512 ); + _DICT.put( 33509, 36577 ); + _DICT.put( 33510, 35818 ); + _DICT.put( 33511, 37527 ); + _DICT.put( 33515, 37839 ); + _DICT.put( 33521, 35184 ); + _DICT.put( 33523, 58516 ); + _DICT.put( 33524, 58515 ); + _DICT.put( 33529, 58521 ); + _DICT.put( 33530, 58517 ); + _DICT.put( 33531, 58520 ); + _DICT.put( 33537, 64403 ); + _DICT.put( 33538, 38606 ); + _DICT.put( 33539, 58519 ); + _DICT.put( 33540, 35286 ); + _DICT.put( 33541, 35485 ); + _DICT.put( 33542, 58523 ); + _DICT.put( 33545, 58525 ); + _DICT.put( 33550, 35955 ); + _DICT.put( 33558, 58529 ); + _DICT.put( 33559, 58538 ); + _DICT.put( 33560, 58539 ); + _DICT.put( 33564, 34985 ); + _DICT.put( 33571, 58546 ); + _DICT.put( 33576, 35055 ); + _DICT.put( 33579, 58537 ); + _DICT.put( 33583, 58536 ); + _DICT.put( 33585, 58531 ); + _DICT.put( 33586, 58530 ); + _DICT.put( 33588, 58528 ); + _DICT.put( 33589, 58527 ); + _DICT.put( 33590, 37507 ); + _DICT.put( 33592, 37369 ); + _DICT.put( 33593, 58533 ); + _DICT.put( 33600, 58532 ); + _DICT.put( 33605, 58535 ); + _DICT.put( 33609, 37264 ); + _DICT.put( 33610, 35956 ); + _DICT.put( 33615, 35168 ); + _DICT.put( 33616, 58534 ); + _DICT.put( 33618, 36210 ); + _DICT.put( 33624, 37265 ); + _DICT.put( 33634, 64404 ); + _DICT.put( 33651, 58552 ); + _DICT.put( 33653, 58553 ); + _DICT.put( 33655, 35287 ); + _DICT.put( 33659, 35244 ); + _DICT.put( 33660, 58550 ); + _DICT.put( 33663, 64405 ); + _DICT.put( 33669, 58540 ); + _DICT.put( 33671, 58548 ); + _DICT.put( 33673, 58555 ); + _DICT.put( 33674, 58549 ); + _DICT.put( 33678, 58547 ); + _DICT.put( 33683, 58518 ); + _DICT.put( 33686, 58545 ); + _DICT.put( 33690, 58541 ); + _DICT.put( 33694, 35534 ); + _DICT.put( 33695, 58543 ); + _DICT.put( 33696, 58554 ); + _DICT.put( 33698, 58544 ); + _DICT.put( 33704, 58556 ); + _DICT.put( 33706, 58542 ); + _DICT.put( 33707, 38044 ); + _DICT.put( 33713, 38793 ); + _DICT.put( 33717, 58551 ); + _DICT.put( 33725, 58573 ); + _DICT.put( 33729, 58565 ); + _DICT.put( 33733, 37019 ); + _DICT.put( 33735, 64406 ); + _DICT.put( 33738, 35685 ); + _DICT.put( 33740, 35803 ); + _DICT.put( 33742, 58560 ); + _DICT.put( 33747, 35289 ); + _DICT.put( 33750, 36818 ); + _DICT.put( 33752, 58563 ); + _DICT.put( 33756, 36312 ); + _DICT.put( 33759, 37744 ); + _DICT.put( 33760, 58568 ); + _DICT.put( 33769, 38380 ); + _DICT.put( 33771, 58559 ); + _DICT.put( 33775, 35288 ); + _DICT.put( 33776, 36052 ); + _DICT.put( 33777, 38216 ); + _DICT.put( 33778, 58569 ); + _DICT.put( 33780, 58557 ); + _DICT.put( 33782, 64407 ); + _DICT.put( 33783, 58566 ); + _DICT.put( 33787, 58576 ); + _DICT.put( 33789, 58561 ); + _DICT.put( 33795, 58562 ); + _DICT.put( 33796, 37816 ); + _DICT.put( 33799, 58567 ); + _DICT.put( 33803, 58564 ); + _DICT.put( 33804, 38471 ); + _DICT.put( 33805, 58570 ); + _DICT.put( 33806, 35038 ); + _DICT.put( 33811, 58558 ); + _DICT.put( 33824, 58572 ); + _DICT.put( 33826, 58571 ); + _DICT.put( 33833, 38027 ); + _DICT.put( 33834, 58578 ); + _DICT.put( 33836, 58589 ); + _DICT.put( 33841, 35486 ); + _DICT.put( 33845, 58592 ); + _DICT.put( 33848, 58574 ); + _DICT.put( 33852, 58579 ); + _DICT.put( 33853, 38798 ); + _DICT.put( 33862, 58588 ); + _DICT.put( 33864, 64408 ); + _DICT.put( 33865, 38772 ); + _DICT.put( 33870, 38824 ); + _DICT.put( 33879, 37528 ); + _DICT.put( 33883, 35467 ); + _DICT.put( 33889, 38290 ); + _DICT.put( 33890, 58594 ); + _DICT.put( 33891, 37791 ); + _DICT.put( 33894, 34991 ); + _DICT.put( 33897, 58587 ); + _DICT.put( 33899, 58583 ); + _DICT.put( 33900, 37266 ); + _DICT.put( 33901, 58577 ); + _DICT.put( 33902, 58585 ); + _DICT.put( 33903, 58590 ); + _DICT.put( 33905, 37963 ); + _DICT.put( 33909, 34984 ); + _DICT.put( 33911, 58582 ); + _DICT.put( 33913, 58591 ); + _DICT.put( 33914, 38296 ); + _DICT.put( 33922, 58586 ); + _DICT.put( 33924, 58581 ); + _DICT.put( 33931, 36819 ); + _DICT.put( 33936, 36686 ); + _DICT.put( 33940, 36522 ); + _DICT.put( 33945, 38614 ); + _DICT.put( 33948, 38246 ); + _DICT.put( 33951, 58597 ); + _DICT.put( 33953, 58606 ); + _DICT.put( 33965, 58584 ); + _DICT.put( 33970, 35479 ); + _DICT.put( 33972, 64409 ); + _DICT.put( 33976, 36854 ); + _DICT.put( 33977, 58595 ); + _DICT.put( 33979, 58600 ); + _DICT.put( 33980, 37267 ); + _DICT.put( 33983, 58596 ); + _DICT.put( 33985, 58603 ); + _DICT.put( 33988, 37502 ); + _DICT.put( 33990, 58604 ); + _DICT.put( 33993, 38773 ); + _DICT.put( 33994, 58593 ); + _DICT.put( 33995, 35415 ); + _DICT.put( 33997, 58599 ); + _DICT.put( 34000, 58602 ); + _DICT.put( 34001, 38570 ); + _DICT.put( 34006, 58605 ); + _DICT.put( 34009, 58598 ); + _DICT.put( 34010, 58601 ); + _DICT.put( 34012, 64096 ); + _DICT.put( 34028, 38472 ); + _DICT.put( 34030, 38976 ); + _DICT.put( 34036, 58609 ); + _DICT.put( 34044, 58616 ); + _DICT.put( 34047, 58608 ); + _DICT.put( 34048, 36545 ); + _DICT.put( 34054, 58575 ); + _DICT.put( 34065, 38348 ); + _DICT.put( 34067, 38560 ); + _DICT.put( 34068, 58615 ); + _DICT.put( 34069, 58614 ); + _DICT.put( 34071, 58610 ); + _DICT.put( 34072, 58611 ); + _DICT.put( 34074, 35157 ); + _DICT.put( 34079, 58613 ); + _DICT.put( 34081, 58607 ); + _DICT.put( 34086, 37587 ); + _DICT.put( 34092, 58612 ); + _DICT.put( 34093, 35068 ); + _DICT.put( 34101, 37280 ); + _DICT.put( 34109, 38337 ); + _DICT.put( 34112, 58617 ); + _DICT.put( 34113, 58688 ); + _DICT.put( 34115, 38103 ); + _DICT.put( 34120, 58620 ); + _DICT.put( 34121, 36820 ); + _DICT.put( 34122, 36551 ); + _DICT.put( 34123, 58690 ); + _DICT.put( 34126, 35772 ); + _DICT.put( 34131, 64410 ); + _DICT.put( 34133, 58691 ); + _DICT.put( 34135, 38297 ); + _DICT.put( 34136, 58619 ); + _DICT.put( 34137, 64411 ); + _DICT.put( 34138, 58580 ); + _DICT.put( 34147, 58618 ); + _DICT.put( 34152, 39022 ); + _DICT.put( 34153, 37792 ); + _DICT.put( 34154, 38291 ); + _DICT.put( 34155, 64412 ); + _DICT.put( 34157, 58698 ); + _DICT.put( 34167, 58704 ); + _DICT.put( 34174, 58705 ); + _DICT.put( 34176, 58692 ); + _DICT.put( 34180, 38038 ); + _DICT.put( 34183, 58702 ); + _DICT.put( 34184, 58694 ); + _DICT.put( 34186, 58696 ); + _DICT.put( 34192, 58706 ); + _DICT.put( 34193, 58695 ); + _DICT.put( 34196, 58699 ); + _DICT.put( 34199, 35218 ); + _DICT.put( 34201, 37859 ); + _DICT.put( 34203, 58700 ); + _DICT.put( 34204, 58703 ); + _DICT.put( 34212, 58693 ); + _DICT.put( 34214, 37189 ); + _DICT.put( 34216, 58697 ); + _DICT.put( 34217, 36422 ); + _DICT.put( 34218, 36964 ); + _DICT.put( 34219, 35919 ); + _DICT.put( 34220, 38642 ); + _DICT.put( 34222, 38647 ); + _DICT.put( 34223, 36754 ); + _DICT.put( 34224, 64414 ); + _DICT.put( 34233, 58710 ); + _DICT.put( 34234, 58708 ); + _DICT.put( 34241, 39021 ); + _DICT.put( 34249, 58707 ); + _DICT.put( 34253, 38805 ); + _DICT.put( 34255, 58709 ); + _DICT.put( 34256, 58711 ); + _DICT.put( 34261, 58712 ); + _DICT.put( 34268, 58715 ); + _DICT.put( 34269, 58713 ); + _DICT.put( 34276, 37793 ); + _DICT.put( 34277, 58714 ); + _DICT.put( 34281, 38091 ); + _DICT.put( 34282, 58701 ); + _DICT.put( 34295, 36755 ); + _DICT.put( 34297, 58716 ); + _DICT.put( 34298, 58721 ); + _DICT.put( 34299, 37268 ); + _DICT.put( 34302, 58720 ); + _DICT.put( 34306, 58689 ); + _DICT.put( 34310, 58722 ); + _DICT.put( 34311, 37224 ); + _DICT.put( 34314, 58717 ); + _DICT.put( 34315, 58719 ); + _DICT.put( 34323, 58718 ); + _DICT.put( 34326, 40784 ); + _DICT.put( 34327, 40769 ); + _DICT.put( 34330, 58724 ); + _DICT.put( 34338, 58723 ); + _DICT.put( 34349, 38806 ); + _DICT.put( 34351, 57786 ); + _DICT.put( 34352, 58725 ); + _DICT.put( 34367, 58726 ); + _DICT.put( 34381, 58727 ); + _DICT.put( 34382, 36053 ); + _DICT.put( 34384, 35699 ); + _DICT.put( 34388, 58729 ); + _DICT.put( 34389, 39292 ); + _DICT.put( 34394, 35733 ); + _DICT.put( 34396, 38840 ); + _DICT.put( 34398, 35825 ); + _DICT.put( 34399, 58730 ); + _DICT.put( 34407, 58731 ); + _DICT.put( 34411, 37518 ); + _DICT.put( 34417, 58732 ); + _DICT.put( 34425, 37880 ); + _DICT.put( 34427, 35000 ); + _DICT.put( 34442, 35297 ); + _DICT.put( 34443, 58737 ); + _DICT.put( 34444, 58738 ); + _DICT.put( 34451, 58733 ); + _DICT.put( 34453, 36444 ); + _DICT.put( 34467, 58734 ); + _DICT.put( 34468, 37985 ); + _DICT.put( 34473, 58735 ); + _DICT.put( 34474, 58736 ); + _DICT.put( 34475, 58746 ); + _DICT.put( 34479, 58740 ); + _DICT.put( 34480, 58743 ); + _DICT.put( 34486, 58739 ); + _DICT.put( 34500, 58741 ); + _DICT.put( 34502, 58742 ); + _DICT.put( 34503, 36566 ); + _DICT.put( 34505, 58744 ); + _DICT.put( 34507, 37472 ); + _DICT.put( 34509, 35957 ); + _DICT.put( 34510, 35425 ); + _DICT.put( 34516, 58747 ); + _DICT.put( 34521, 35422 ); + _DICT.put( 34523, 58753 ); + _DICT.put( 34526, 58748 ); + _DICT.put( 34527, 58752 ); + _DICT.put( 34532, 38072 ); + _DICT.put( 34537, 58749 ); + _DICT.put( 34540, 58750 ); + _DICT.put( 34541, 38247 ); + _DICT.put( 34542, 38104 ); + _DICT.put( 34543, 58754 ); + _DICT.put( 34552, 37371 ); + _DICT.put( 34553, 58764 ); + _DICT.put( 34555, 58760 ); + _DICT.put( 34558, 35305 ); + _DICT.put( 34560, 58758 ); + _DICT.put( 34562, 38473 ); + _DICT.put( 34563, 58759 ); + _DICT.put( 34566, 58756 ); + _DICT.put( 34568, 58757 ); + _DICT.put( 34569, 58762 ); + _DICT.put( 34570, 58765 ); + _DICT.put( 34573, 58763 ); + _DICT.put( 34577, 58761 ); + _DICT.put( 34578, 58755 ); + _DICT.put( 34584, 37495 ); + _DICT.put( 34586, 58772 ); + _DICT.put( 34588, 38568 ); + _DICT.put( 34597, 58770 ); + _DICT.put( 34601, 58771 ); + _DICT.put( 34612, 58766 ); + _DICT.put( 34615, 58768 ); + _DICT.put( 34619, 58769 ); + _DICT.put( 34623, 58767 ); + _DICT.put( 34633, 37092 ); + _DICT.put( 34635, 39000 ); + _DICT.put( 34636, 58776 ); + _DICT.put( 34638, 58777 ); + _DICT.put( 34643, 58783 ); + _DICT.put( 34645, 36937 ); + _DICT.put( 34647, 58779 ); + _DICT.put( 34649, 58782 ); + _DICT.put( 34655, 58774 ); + _DICT.put( 34656, 58773 ); + _DICT.put( 34659, 58784 ); + _DICT.put( 34662, 35290 ); + _DICT.put( 34664, 58780 ); + _DICT.put( 34666, 58785 ); + _DICT.put( 34670, 58781 ); + _DICT.put( 34676, 58778 ); + _DICT.put( 34678, 37553 ); + _DICT.put( 34680, 58775 ); + _DICT.put( 34687, 38024 ); + _DICT.put( 34690, 58789 ); + _DICT.put( 34701, 38746 ); + _DICT.put( 34719, 58788 ); + _DICT.put( 34722, 58787 ); + _DICT.put( 34731, 58796 ); + _DICT.put( 34735, 58790 ); + _DICT.put( 34739, 58798 ); + _DICT.put( 34746, 38790 ); + _DICT.put( 34747, 58801 ); + _DICT.put( 34749, 58792 ); + _DICT.put( 34752, 58793 ); + _DICT.put( 34756, 58797 ); + _DICT.put( 34758, 58800 ); + _DICT.put( 34759, 58799 ); + _DICT.put( 34763, 58791 ); + _DICT.put( 34768, 58794 ); + _DICT.put( 34770, 58811 ); + _DICT.put( 34784, 58804 ); + _DICT.put( 34799, 58802 ); + _DICT.put( 34802, 58803 ); + _DICT.put( 34806, 58808 ); + _DICT.put( 34807, 58809 ); + _DICT.put( 34809, 35401 ); + _DICT.put( 34811, 35681 ); + _DICT.put( 34814, 58807 ); + _DICT.put( 34821, 58786 ); + _DICT.put( 34823, 64417 ); + _DICT.put( 34829, 58806 ); + _DICT.put( 34830, 58810 ); + _DICT.put( 34831, 58805 ); + _DICT.put( 34833, 58812 ); + _DICT.put( 34837, 58814 ); + _DICT.put( 34838, 58813 ); + _DICT.put( 34849, 58816 ); + _DICT.put( 34850, 58815 ); + _DICT.put( 34851, 58745 ); + _DICT.put( 34855, 58820 ); + _DICT.put( 34865, 58817 ); + _DICT.put( 34870, 58818 ); + _DICT.put( 34873, 58819 ); + _DICT.put( 34875, 58821 ); + _DICT.put( 34880, 35980 ); + _DICT.put( 34882, 58823 ); + _DICT.put( 34884, 58822 ); + _DICT.put( 34886, 36687 ); + _DICT.put( 34892, 36211 ); + _DICT.put( 34893, 40869 ); + _DICT.put( 34898, 58824 ); + _DICT.put( 34899, 36720 ); + _DICT.put( 34903, 35416 ); + _DICT.put( 34905, 58825 ); + _DICT.put( 34907, 35185 ); + _DICT.put( 34909, 36821 ); + _DICT.put( 34910, 58826 ); + _DICT.put( 34913, 36212 ); + _DICT.put( 34914, 58827 ); + _DICT.put( 34915, 35039 ); + _DICT.put( 34920, 38236 ); + _DICT.put( 34923, 58828 ); + _DICT.put( 34928, 37002 ); + _DICT.put( 34930, 58835 ); + _DICT.put( 34933, 58832 ); + _DICT.put( 34935, 37519 ); + _DICT.put( 34941, 58833 ); + _DICT.put( 34942, 58830 ); + _DICT.put( 34943, 35804 ); + _DICT.put( 34945, 58829 ); + _DICT.put( 34946, 58836 ); + _DICT.put( 34952, 35925 ); + _DICT.put( 34955, 37340 ); + _DICT.put( 34957, 58842 ); + _DICT.put( 34962, 58838 ); + _DICT.put( 34966, 37299 ); + _DICT.put( 34967, 58837 ); + _DICT.put( 34969, 58840 ); + _DICT.put( 34974, 58831 ); + _DICT.put( 34978, 58841 ); + _DICT.put( 34980, 58843 ); + _DICT.put( 34987, 38125 ); + _DICT.put( 34990, 58839 ); + _DICT.put( 34992, 58844 ); + _DICT.put( 34993, 58846 ); + _DICT.put( 34996, 36049 ); + _DICT.put( 34997, 58834 ); + _DICT.put( 34999, 35007 ); + _DICT.put( 35007, 58845 ); + _DICT.put( 35009, 36313 ); + _DICT.put( 35010, 38900 ); + _DICT.put( 35011, 58847 ); + _DICT.put( 35012, 58848 ); + _DICT.put( 35013, 37269 ); + _DICT.put( 35023, 38816 ); + _DICT.put( 35028, 58849 ); + _DICT.put( 35029, 38740 ); + _DICT.put( 35032, 58850 ); + _DICT.put( 35033, 58851 ); + _DICT.put( 35036, 38370 ); + _DICT.put( 35037, 58852 ); + _DICT.put( 35039, 36286 ); + _DICT.put( 35041, 38817 ); + _DICT.put( 35048, 58857 ); + _DICT.put( 35058, 58858 ); + _DICT.put( 35059, 36822 ); + _DICT.put( 35060, 58856 ); + _DICT.put( 35061, 64418 ); + _DICT.put( 35064, 38791 ); + _DICT.put( 35065, 58853 ); + _DICT.put( 35068, 58855 ); + _DICT.put( 35069, 37051 ); + _DICT.put( 35070, 37022 ); + _DICT.put( 35074, 58854 ); + _DICT.put( 35076, 58859 ); + _DICT.put( 35079, 38305 ); + _DICT.put( 35082, 58861 ); + _DICT.put( 35084, 58860 ); + _DICT.put( 35088, 35468 ); + _DICT.put( 35090, 38474 ); + _DICT.put( 35091, 58862 ); + _DICT.put( 35100, 64093 ); + _DICT.put( 35101, 58874 ); + _DICT.put( 35102, 58864 ); + _DICT.put( 35109, 58865 ); + _DICT.put( 35114, 58866 ); + _DICT.put( 35115, 58867 ); + _DICT.put( 35126, 58871 ); + _DICT.put( 35128, 58872 ); + _DICT.put( 35131, 58870 ); + _DICT.put( 35137, 58868 ); + _DICT.put( 35139, 58863 ); + _DICT.put( 35140, 58869 ); + _DICT.put( 35148, 58873 ); + _DICT.put( 35149, 59573 ); + _DICT.put( 35158, 35238 ); + _DICT.put( 35166, 58876 ); + _DICT.put( 35167, 35805 ); + _DICT.put( 35168, 58875 ); + _DICT.put( 35172, 58945 ); + _DICT.put( 35174, 58944 ); + _DICT.put( 35178, 58947 ); + _DICT.put( 35181, 58946 ); + _DICT.put( 35183, 58948 ); + _DICT.put( 35186, 36688 ); + _DICT.put( 35188, 58949 ); + _DICT.put( 35191, 58950 ); + _DICT.put( 35198, 58951 ); + _DICT.put( 35199, 37052 ); + _DICT.put( 35201, 38774 ); + _DICT.put( 35203, 58952 ); + _DICT.put( 35206, 38306 ); + _DICT.put( 35207, 37989 ); + _DICT.put( 35208, 58953 ); + _DICT.put( 35210, 58954 ); + _DICT.put( 35211, 36009 ); + _DICT.put( 35215, 35659 ); + _DICT.put( 35219, 58955 ); + _DICT.put( 35222, 36491 ); + _DICT.put( 35223, 37984 ); + _DICT.put( 35224, 58956 ); + _DICT.put( 35226, 35439 ); + _DICT.put( 35233, 58957 ); + _DICT.put( 35238, 58959 ); + _DICT.put( 35239, 38807 ); + _DICT.put( 35241, 58958 ); + _DICT.put( 35242, 36965 ); + _DICT.put( 35244, 58960 ); + _DICT.put( 35247, 58961 ); + _DICT.put( 35250, 58962 ); + _DICT.put( 35251, 35535 ); + _DICT.put( 35258, 58963 ); + _DICT.put( 35261, 58964 ); + _DICT.put( 35263, 58965 ); + _DICT.put( 35264, 58966 ); + _DICT.put( 35282, 35440 ); + _DICT.put( 35290, 58967 ); + _DICT.put( 35292, 58968 ); + _DICT.put( 35293, 58969 ); + _DICT.put( 35299, 35312 ); + _DICT.put( 35302, 36935 ); + _DICT.put( 35303, 58970 ); + _DICT.put( 35316, 58971 ); + _DICT.put( 35320, 58972 ); + _DICT.put( 35328, 36030 ); + _DICT.put( 35330, 37625 ); + _DICT.put( 35331, 58973 ); + _DICT.put( 35336, 35958 ); + _DICT.put( 35338, 36981 ); + _DICT.put( 35340, 58976 ); + _DICT.put( 35342, 37794 ); + _DICT.put( 35344, 58975 ); + _DICT.put( 35346, 64419 ); + _DICT.put( 35347, 35920 ); + _DICT.put( 35350, 58974 ); + _DICT.put( 35351, 37365 ); + _DICT.put( 35352, 35660 ); + _DICT.put( 35355, 58977 ); + _DICT.put( 35357, 58978 ); + _DICT.put( 35359, 36823 ); + _DICT.put( 35363, 35981 ); + _DICT.put( 35365, 58979 ); + _DICT.put( 35370, 38475 ); + _DICT.put( 35373, 37085 ); + _DICT.put( 35377, 35734 ); + _DICT.put( 35379, 38643 ); + _DICT.put( 35380, 37225 ); + _DICT.put( 35382, 58980 ); + _DICT.put( 35383, 64420 ); + _DICT.put( 35386, 36966 ); + _DICT.put( 35387, 37520 ); + _DICT.put( 35388, 36824 ); + _DICT.put( 35393, 58981 ); + _DICT.put( 35398, 58984 ); + _DICT.put( 35400, 58985 ); + _DICT.put( 35408, 36284 ); + _DICT.put( 35409, 37312 ); + _DICT.put( 35410, 58983 ); + _DICT.put( 35412, 36825 ); + _DICT.put( 35413, 38237 ); + _DICT.put( 35419, 58982 ); + _DICT.put( 35422, 36492 ); + _DICT.put( 35424, 35186 ); + _DICT.put( 35426, 58989 ); + _DICT.put( 35427, 35959 ); + _DICT.put( 35430, 36494 ); + _DICT.put( 35433, 36493 ); + _DICT.put( 35435, 39020 ); + _DICT.put( 35436, 58988 ); + _DICT.put( 35437, 58987 ); + _DICT.put( 35438, 37190 ); + _DICT.put( 35440, 35692 ); + _DICT.put( 35441, 39010 ); + _DICT.put( 35442, 35417 ); + _DICT.put( 35443, 36826 ); + _DICT.put( 35449, 64421 ); + _DICT.put( 35452, 58986 ); + _DICT.put( 35458, 58991 ); + _DICT.put( 35460, 58992 ); + _DICT.put( 35461, 58990 ); + _DICT.put( 35463, 36054 ); + _DICT.put( 35465, 38751 ); + _DICT.put( 35468, 36495 ); + _DICT.put( 35469, 37958 ); + _DICT.put( 35473, 58995 ); + _DICT.put( 35475, 37054 ); + _DICT.put( 35477, 37473 ); + _DICT.put( 35480, 38741 ); + _DICT.put( 35482, 58998 ); + _DICT.put( 35486, 36074 ); + _DICT.put( 35488, 37053 ); + _DICT.put( 35489, 58994 ); + _DICT.put( 35491, 58999 ); + _DICT.put( 35492, 36075 ); + _DICT.put( 35493, 58996 ); + _DICT.put( 35494, 58997 ); + _DICT.put( 35495, 64422 ); + _DICT.put( 35496, 58993 ); + _DICT.put( 35500, 37088 ); + _DICT.put( 35501, 37831 ); + _DICT.put( 35504, 37454 ); + _DICT.put( 35506, 35291 ); + _DICT.put( 35513, 38126 ); + _DICT.put( 35516, 35682 ); + _DICT.put( 35518, 64423 ); + _DICT.put( 35519, 37554 ); + _DICT.put( 35522, 59002 ); + _DICT.put( 35524, 59000 ); + _DICT.put( 35527, 37483 ); + _DICT.put( 35531, 37055 ); + _DICT.put( 35532, 35536 ); + _DICT.put( 35533, 59001 ); + _DICT.put( 35535, 36986 ); + _DICT.put( 35538, 38856 ); + _DICT.put( 35542, 39007 ); + _DICT.put( 35546, 59003 ); + _DICT.put( 35547, 59015 ); + _DICT.put( 35548, 37555 ); + _DICT.put( 35550, 59014 ); + _DICT.put( 35551, 64424 ); + _DICT.put( 35552, 59011 ); + _DICT.put( 35553, 59019 ); + _DICT.put( 35554, 59012 ); + _DICT.put( 35556, 59008 ); + _DICT.put( 35558, 37626 ); + _DICT.put( 35559, 59006 ); + _DICT.put( 35563, 59004 ); + _DICT.put( 35565, 38720 ); + _DICT.put( 35566, 36496 ); + _DICT.put( 35569, 59009 ); + _DICT.put( 35571, 59005 ); + _DICT.put( 35574, 64426 ); + _DICT.put( 35575, 59013 ); + _DICT.put( 35576, 36756 ); + _DICT.put( 35578, 36031 ); + _DICT.put( 35582, 37368 ); + _DICT.put( 35584, 38500 ); + _DICT.put( 35585, 35193 ); + _DICT.put( 35586, 35040 ); + _DICT.put( 35588, 37795 ); + _DICT.put( 35591, 59017 ); + _DICT.put( 35596, 59016 ); + _DICT.put( 35598, 37860 ); + _DICT.put( 35600, 59021 ); + _DICT.put( 35604, 59010 ); + _DICT.put( 35606, 59020 ); + _DICT.put( 35607, 59022 ); + _DICT.put( 35609, 36010 ); + _DICT.put( 35610, 59018 ); + _DICT.put( 35611, 36213 ); + _DICT.put( 35613, 36563 ); + _DICT.put( 35616, 59023 ); + _DICT.put( 35617, 38775 ); + _DICT.put( 35622, 59026 ); + _DICT.put( 35624, 59029 ); + _DICT.put( 35627, 59027 ); + _DICT.put( 35628, 38228 ); + _DICT.put( 35635, 59024 ); + _DICT.put( 35641, 35806 ); + _DICT.put( 35646, 59028 ); + _DICT.put( 35649, 59030 ); + _DICT.put( 35657, 59034 ); + _DICT.put( 35660, 59031 ); + _DICT.put( 35662, 59033 ); + _DICT.put( 35663, 59032 ); + _DICT.put( 35667, 64427 ); + _DICT.put( 35670, 59035 ); + _DICT.put( 35672, 36527 ); + _DICT.put( 35674, 59037 ); + _DICT.put( 35675, 59036 ); + _DICT.put( 35676, 38280 ); + _DICT.put( 35679, 59039 ); + _DICT.put( 35686, 35960 ); + _DICT.put( 35691, 59038 ); + _DICT.put( 35692, 59040 ); + _DICT.put( 35695, 59041 ); + _DICT.put( 35696, 35683 ); + _DICT.put( 35697, 58303 ); + _DICT.put( 35698, 36855 ); + _DICT.put( 35700, 59042 ); + _DICT.put( 35703, 36076 ); + _DICT.put( 35709, 59043 ); + _DICT.put( 35711, 64428 ); + _DICT.put( 35712, 59044 ); + _DICT.put( 35715, 36445 ); + _DICT.put( 35722, 40396 ); + _DICT.put( 35724, 59045 ); + _DICT.put( 35726, 59046 ); + _DICT.put( 35728, 36689 ); + _DICT.put( 35730, 59047 ); + _DICT.put( 35731, 59048 ); + _DICT.put( 35734, 59049 ); + _DICT.put( 35737, 59050 ); + _DICT.put( 35738, 59051 ); + _DICT.put( 35895, 37450 ); + _DICT.put( 35898, 59052 ); + _DICT.put( 35903, 59054 ); + _DICT.put( 35905, 59053 ); + _DICT.put( 35910, 37796 ); + _DICT.put( 35912, 59055 ); + _DICT.put( 35914, 38476 ); + _DICT.put( 35916, 59056 ); + _DICT.put( 35918, 59057 ); + _DICT.put( 35920, 59058 ); + _DICT.put( 35925, 59059 ); + _DICT.put( 35930, 37848 ); + _DICT.put( 35937, 36827 ); + _DICT.put( 35938, 59060 ); + _DICT.put( 35946, 36235 ); + _DICT.put( 35947, 39084 ); + _DICT.put( 35948, 59061 ); + _DICT.put( 35960, 59062 ); + _DICT.put( 35961, 38238 ); + _DICT.put( 35962, 59063 ); + _DICT.put( 35964, 59071 ); + _DICT.put( 35970, 59064 ); + _DICT.put( 35973, 59066 ); + _DICT.put( 35977, 59065 ); + _DICT.put( 35978, 59067 ); + _DICT.put( 35980, 38501 ); + _DICT.put( 35981, 59068 ); + _DICT.put( 35982, 59069 ); + _DICT.put( 35988, 59070 ); + _DICT.put( 35992, 59072 ); + _DICT.put( 35997, 35404 ); + m_initialized = true; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_c.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_c.java new file mode 100644 index 0000000..b51facf --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/cp932_c.java @@ -0,0 +1,3433 @@ +/* + * cp932_c.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.bocoree + * + * jp.sourceforge.lipsync.bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.bocoree; + +import java.util.*; + +public class cp932_c { + private static HashMap _DICT = new HashMap(); + private static boolean m_initialized = false; + + public static int getMinKey() { + return 35998; + } + + public static int getMaxKey() { + return 65509; + } + + public static int get( int key ) { + if( !m_initialized ){ + init(); + } + if ( _DICT.containsKey( key ) ) { + return ((Integer) _DICT.get( key )).intValue(); + } else { + return -1; + } + } + + private static void init() { + _DICT.put( 35998, 37605 ); + _DICT.put( 36000, 38281 ); + _DICT.put( 36001, 36320 ); + _DICT.put( 36002, 36214 ); + _DICT.put( 36007, 38254 ); + _DICT.put( 36008, 35293 ); + _DICT.put( 36009, 38092 ); + _DICT.put( 36010, 59075 ); + _DICT.put( 36011, 35537 ); + _DICT.put( 36012, 37075 ); + _DICT.put( 36013, 59074 ); + _DICT.put( 36014, 59079 ); + _DICT.put( 36015, 37529 ); + _DICT.put( 36016, 38625 ); + _DICT.put( 36018, 59077 ); + _DICT.put( 36019, 59078 ); + _DICT.put( 36020, 35661 ); + _DICT.put( 36022, 59080 ); + _DICT.put( 36023, 38019 ); + _DICT.put( 36024, 37341 ); + _DICT.put( 36027, 38127 ); + _DICT.put( 36028, 37724 ); + _DICT.put( 36029, 59076 ); + _DICT.put( 36031, 38502 ); + _DICT.put( 36032, 35306 ); + _DICT.put( 36033, 59082 ); + _DICT.put( 36034, 38983 ); + _DICT.put( 36035, 37568 ); + _DICT.put( 36036, 39012 ); + _DICT.put( 36039, 36497 ); + _DICT.put( 36040, 59081 ); + _DICT.put( 36042, 37295 ); + _DICT.put( 36045, 59098 ); + _DICT.put( 36046, 37191 ); + _DICT.put( 36049, 37878 ); + _DICT.put( 36051, 38255 ); + _DICT.put( 36058, 59085 ); + _DICT.put( 36059, 36446 ); + _DICT.put( 36060, 36498 ); + _DICT.put( 36062, 36828 ); + _DICT.put( 36064, 38021 ); + _DICT.put( 36066, 36011 ); + _DICT.put( 36067, 59084 ); + _DICT.put( 36068, 59083 ); + _DICT.put( 36070, 38282 ); + _DICT.put( 36074, 36543 ); + _DICT.put( 36077, 37745 ); + _DICT.put( 36080, 64429 ); + _DICT.put( 36084, 64430 ); + _DICT.put( 36090, 59087 ); + _DICT.put( 36091, 59088 ); + _DICT.put( 36092, 36215 ); + _DICT.put( 36093, 59086 ); + _DICT.put( 36100, 59089 ); + _DICT.put( 36101, 59090 ); + _DICT.put( 36103, 59092 ); + _DICT.put( 36104, 37281 ); + _DICT.put( 36106, 59091 ); + _DICT.put( 36107, 35556 ); + _DICT.put( 36109, 59094 ); + _DICT.put( 36111, 59093 ); + _DICT.put( 36112, 59095 ); + _DICT.put( 36114, 64431 ); + _DICT.put( 36115, 59097 ); + _DICT.put( 36116, 59099 ); + _DICT.put( 36118, 59100 ); + _DICT.put( 36196, 37076 ); + _DICT.put( 36198, 36557 ); + _DICT.put( 36199, 59101 ); + _DICT.put( 36203, 35441 ); + _DICT.put( 36205, 59102 ); + _DICT.put( 36208, 37270 ); + _DICT.put( 36209, 59103 ); + _DICT.put( 36211, 59104 ); + _DICT.put( 36212, 38283 ); + _DICT.put( 36214, 64432 ); + _DICT.put( 36215, 35662 ); + _DICT.put( 36225, 59105 ); + _DICT.put( 36229, 37556 ); + _DICT.put( 36234, 35194 ); + _DICT.put( 36249, 59106 ); + _DICT.put( 36259, 36591 ); + _DICT.put( 36264, 37014 ); + _DICT.put( 36275, 37291 ); + _DICT.put( 36282, 59109 ); + _DICT.put( 36286, 59108 ); + _DICT.put( 36290, 59107 ); + _DICT.put( 36299, 59115 ); + _DICT.put( 36300, 59113 ); + _DICT.put( 36303, 59110 ); + _DICT.put( 36310, 59112 ); + _DICT.put( 36314, 59111 ); + _DICT.put( 36315, 59114 ); + _DICT.put( 36317, 35735 ); + _DICT.put( 36319, 59118 ); + _DICT.put( 36321, 37077 ); + _DICT.put( 36323, 59119 ); + _DICT.put( 36328, 36055 ); + _DICT.put( 36330, 59116 ); + _DICT.put( 36331, 59117 ); + _DICT.put( 36335, 38984 ); + _DICT.put( 36339, 37557 ); + _DICT.put( 36341, 37192 ); + _DICT.put( 36348, 59120 ); + _DICT.put( 36351, 59123 ); + _DICT.put( 36360, 59121 ); + _DICT.put( 36361, 59122 ); + _DICT.put( 36362, 38776 ); + _DICT.put( 36367, 37797 ); + _DICT.put( 36368, 59126 ); + _DICT.put( 36381, 59124 ); + _DICT.put( 36382, 59125 ); + _DICT.put( 36383, 59127 ); + _DICT.put( 36394, 59208 ); + _DICT.put( 36400, 59130 ); + _DICT.put( 36404, 59131 ); + _DICT.put( 36405, 59129 ); + _DICT.put( 36418, 59128 ); + _DICT.put( 36420, 37627 ); + _DICT.put( 36423, 59200 ); + _DICT.put( 36424, 59204 ); + _DICT.put( 36425, 59201 ); + _DICT.put( 36426, 59132 ); + _DICT.put( 36428, 59202 ); + _DICT.put( 36432, 59203 ); + _DICT.put( 36437, 59210 ); + _DICT.put( 36441, 59205 ); + _DICT.put( 36447, 37078 ); + _DICT.put( 36448, 59207 ); + _DICT.put( 36451, 59209 ); + _DICT.put( 36452, 59206 ); + _DICT.put( 36466, 59212 ); + _DICT.put( 36468, 36690 ); + _DICT.put( 36470, 59211 ); + _DICT.put( 36476, 59213 ); + _DICT.put( 36481, 59214 ); + _DICT.put( 36484, 59217 ); + _DICT.put( 36485, 59216 ); + _DICT.put( 36487, 59215 ); + _DICT.put( 36490, 59219 ); + _DICT.put( 36491, 59218 ); + _DICT.put( 36493, 38644 ); + _DICT.put( 36497, 59221 ); + _DICT.put( 36499, 59220 ); + _DICT.put( 36500, 59222 ); + _DICT.put( 36505, 59223 ); + _DICT.put( 36513, 59225 ); + _DICT.put( 36522, 59224 ); + _DICT.put( 36523, 36967 ); + _DICT.put( 36524, 59226 ); + _DICT.put( 36527, 35819 ); + _DICT.put( 36528, 59227 ); + _DICT.put( 36529, 59229 ); + _DICT.put( 36542, 59230 ); + _DICT.put( 36549, 59231 ); + _DICT.put( 36550, 59228 ); + _DICT.put( 36552, 59232 ); + _DICT.put( 36554, 36564 ); + _DICT.put( 36555, 59233 ); + _DICT.put( 36556, 35663 ); + _DICT.put( 36557, 35922 ); + _DICT.put( 36559, 64434 ); + _DICT.put( 36562, 36012 ); + _DICT.put( 36571, 59234 ); + _DICT.put( 36575, 37870 ); + _DICT.put( 36578, 37725 ); + _DICT.put( 36579, 59235 ); + _DICT.put( 36587, 59238 ); + _DICT.put( 36600, 36530 ); + _DICT.put( 36603, 59237 ); + _DICT.put( 36604, 59236 ); + _DICT.put( 36605, 35961 ); + _DICT.put( 36606, 59239 ); + _DICT.put( 36611, 35442 ); + _DICT.put( 36613, 59241 ); + _DICT.put( 36617, 36314 ); + _DICT.put( 36618, 59240 ); + _DICT.put( 36620, 59249 ); + _DICT.put( 36626, 59243 ); + _DICT.put( 36627, 59245 ); + _DICT.put( 36628, 38371 ); + _DICT.put( 36629, 59242 ); + _DICT.put( 36633, 59244 ); + _DICT.put( 36635, 59248 ); + _DICT.put( 36636, 59246 ); + _DICT.put( 36637, 35664 ); + _DICT.put( 36639, 59247 ); + _DICT.put( 36646, 59250 ); + _DICT.put( 36649, 38009 ); + _DICT.put( 36650, 38870 ); + _DICT.put( 36655, 36691 ); + _DICT.put( 36659, 59251 ); + _DICT.put( 36664, 38721 ); + _DICT.put( 36665, 59253 ); + _DICT.put( 36667, 59252 ); + _DICT.put( 36670, 59256 ); + _DICT.put( 36671, 38752 ); + _DICT.put( 36674, 59255 ); + _DICT.put( 36676, 35469 ); + _DICT.put( 36677, 59254 ); + _DICT.put( 36678, 59259 ); + _DICT.put( 36681, 59258 ); + _DICT.put( 36684, 59257 ); + _DICT.put( 36685, 37713 ); + _DICT.put( 36686, 59260 ); + _DICT.put( 36695, 59261 ); + _DICT.put( 36700, 59262 ); + _DICT.put( 36703, 36236 ); + _DICT.put( 36705, 35908 ); + _DICT.put( 36706, 59264 ); + _DICT.put( 36707, 59265 ); + _DICT.put( 36708, 59266 ); + _DICT.put( 36763, 36968 ); + _DICT.put( 36764, 59267 ); + _DICT.put( 36766, 36523 ); + _DICT.put( 36767, 59268 ); + _DICT.put( 36771, 59269 ); + _DICT.put( 36775, 39327 ); + _DICT.put( 36776, 39326 ); + _DICT.put( 36781, 59270 ); + _DICT.put( 36782, 58256 ); + _DICT.put( 36783, 59271 ); + _DICT.put( 36784, 37443 ); + _DICT.put( 36785, 36938 ); + _DICT.put( 36786, 37983 ); + _DICT.put( 36791, 59272 ); + _DICT.put( 36794, 38355 ); + _DICT.put( 36795, 37586 ); + _DICT.put( 36796, 36254 ); + _DICT.put( 36799, 37448 ); + _DICT.put( 36802, 35145 ); + _DICT.put( 36804, 38552 ); + _DICT.put( 36805, 36982 ); + _DICT.put( 36814, 35965 ); + _DICT.put( 36817, 35807 ); + _DICT.put( 36820, 38356 ); + _DICT.put( 36826, 59273 ); + _DICT.put( 36834, 59275 ); + _DICT.put( 36837, 59274 ); + _DICT.put( 36838, 35294 ); + _DICT.put( 36841, 37876 ); + _DICT.put( 36842, 59276 ); + _DICT.put( 36843, 38039 ); + _DICT.put( 36845, 37714 ); + _DICT.put( 36847, 59277 ); + _DICT.put( 36848, 36721 ); + _DICT.put( 36852, 59279 ); + _DICT.put( 36855, 38592 ); + _DICT.put( 36856, 59294 ); + _DICT.put( 36857, 59281 ); + _DICT.put( 36858, 59282 ); + _DICT.put( 36861, 37575 ); + _DICT.put( 36864, 37342 ); + _DICT.put( 36865, 37271 ); + _DICT.put( 36867, 37798 ); + _DICT.put( 36869, 59280 ); + _DICT.put( 36870, 35700 ); + _DICT.put( 36875, 59289 ); + _DICT.put( 36877, 59286 ); + _DICT.put( 36878, 59299 ); + _DICT.put( 36879, 37799 ); + _DICT.put( 36880, 37504 ); + _DICT.put( 36881, 59283 ); + _DICT.put( 36883, 37628 ); + _DICT.put( 36884, 37746 ); + _DICT.put( 36885, 59284 ); + _DICT.put( 36886, 59288 ); + _DICT.put( 36887, 36992 ); + _DICT.put( 36889, 38023 ); + _DICT.put( 36890, 37578 ); + _DICT.put( 36893, 37056 ); + _DICT.put( 36894, 59287 ); + _DICT.put( 36895, 37292 ); + _DICT.put( 36896, 37282 ); + _DICT.put( 36897, 59285 ); + _DICT.put( 36898, 34983 ); + _DICT.put( 36899, 38977 ); + _DICT.put( 36903, 59290 ); + _DICT.put( 36910, 37343 ); + _DICT.put( 36913, 36692 ); + _DICT.put( 36914, 36969 ); + _DICT.put( 36917, 59292 ); + _DICT.put( 36918, 59291 ); + _DICT.put( 36920, 35053 ); + _DICT.put( 36921, 59293 ); + _DICT.put( 36924, 38222 ); + _DICT.put( 36926, 59301 ); + _DICT.put( 36929, 37849 ); + _DICT.put( 36930, 37003 ); + _DICT.put( 36933, 37496 ); + _DICT.put( 36935, 35830 ); + _DICT.put( 36937, 59300 ); + _DICT.put( 36938, 38742 ); + _DICT.put( 36939, 35166 ); + _DICT.put( 36941, 38357 ); + _DICT.put( 36942, 35295 ); + _DICT.put( 36943, 59295 ); + _DICT.put( 36944, 59296 ); + _DICT.put( 36945, 59297 ); + _DICT.put( 36946, 59298 ); + _DICT.put( 36947, 37817 ); + _DICT.put( 36948, 37442 ); + _DICT.put( 36949, 35041 ); + _DICT.put( 36950, 59302 ); + _DICT.put( 36952, 59303 ); + _DICT.put( 36953, 60065 ); + _DICT.put( 36956, 37307 ); + _DICT.put( 36958, 59304 ); + _DICT.put( 36960, 35219 ); + _DICT.put( 36961, 37227 ); + _DICT.put( 36963, 36013 ); + _DICT.put( 36965, 38777 ); + _DICT.put( 36967, 64437 ); + _DICT.put( 36968, 59305 ); + _DICT.put( 36969, 37707 ); + _DICT.put( 36973, 37272 ); + _DICT.put( 36974, 36565 ); + _DICT.put( 36975, 59306 ); + _DICT.put( 36978, 59309 ); + _DICT.put( 36981, 36741 ); + _DICT.put( 36982, 59307 ); + _DICT.put( 36983, 37194 ); + _DICT.put( 36984, 37193 ); + _DICT.put( 36986, 35042 ); + _DICT.put( 36988, 38857 ); + _DICT.put( 36989, 59311 ); + _DICT.put( 36991, 38128 ); + _DICT.put( 36992, 59313 ); + _DICT.put( 36993, 59312 ); + _DICT.put( 36994, 59310 ); + _DICT.put( 36995, 57988 ); + _DICT.put( 36996, 35538 ); + _DICT.put( 36999, 59278 ); + _DICT.put( 37001, 59315 ); + _DICT.put( 37002, 59314 ); + _DICT.put( 37007, 59316 ); + _DICT.put( 37009, 38743 ); + _DICT.put( 37027, 37855 ); + _DICT.put( 37030, 38477 ); + _DICT.put( 37032, 59317 ); + _DICT.put( 37034, 36567 ); + _DICT.put( 37039, 59318 ); + _DICT.put( 37041, 59319 ); + _DICT.put( 37045, 59320 ); + _DICT.put( 37048, 37696 ); + _DICT.put( 37057, 35048 ); + _DICT.put( 37066, 36216 ); + _DICT.put( 37070, 39001 ); + _DICT.put( 37083, 59324 ); + _DICT.put( 37086, 64438 ); + _DICT.put( 37089, 35923 ); + _DICT.put( 37090, 59321 ); + _DICT.put( 37092, 59322 ); + _DICT.put( 37096, 38292 ); + _DICT.put( 37101, 35443 ); + _DICT.put( 37109, 38744 ); + _DICT.put( 37111, 35773 ); + _DICT.put( 37117, 37747 ); + _DICT.put( 37122, 59325 ); + _DICT.put( 37138, 59326 ); + _DICT.put( 37141, 64440 ); + _DICT.put( 37145, 59327 ); + _DICT.put( 37159, 64441 ); + _DICT.put( 37165, 37697 ); + _DICT.put( 37168, 59329 ); + _DICT.put( 37170, 59328 ); + _DICT.put( 37193, 37841 ); + _DICT.put( 37194, 59330 ); + _DICT.put( 37195, 36693 ); + _DICT.put( 37196, 36574 ); + _DICT.put( 37197, 38010 ); + _DICT.put( 37198, 37521 ); + _DICT.put( 37202, 36592 ); + _DICT.put( 37204, 37004 ); + _DICT.put( 37206, 59331 ); + _DICT.put( 37208, 59332 ); + _DICT.put( 37218, 36988 ); + _DICT.put( 37219, 59333 ); + _DICT.put( 37221, 59334 ); + _DICT.put( 37225, 59335 ); + _DICT.put( 37226, 38799 ); + _DICT.put( 37228, 36694 ); + _DICT.put( 37234, 59337 ); + _DICT.put( 37235, 59336 ); + _DICT.put( 37237, 36217 ); + _DICT.put( 37239, 36243 ); + _DICT.put( 37240, 36447 ); + _DICT.put( 37250, 59340 ); + _DICT.put( 37255, 36742 ); + _DICT.put( 37257, 59339 ); + _DICT.put( 37259, 59338 ); + _DICT.put( 37261, 37351 ); + _DICT.put( 37264, 36077 ); + _DICT.put( 37266, 37057 ); + _DICT.put( 37271, 38062 ); + _DICT.put( 37276, 36696 ); + _DICT.put( 37282, 59341 ); + _DICT.put( 37284, 36829 ); + _DICT.put( 37290, 59344 ); + _DICT.put( 37291, 59342 ); + _DICT.put( 37295, 59343 ); + _DICT.put( 37300, 59346 ); + _DICT.put( 37301, 59345 ); + _DICT.put( 37304, 36856 ); + _DICT.put( 37306, 59347 ); + _DICT.put( 37312, 59348 ); + _DICT.put( 37313, 59349 ); + _DICT.put( 37318, 38094 ); + _DICT.put( 37319, 36305 ); + _DICT.put( 37320, 36575 ); + _DICT.put( 37321, 59350 ); + _DICT.put( 37323, 59351 ); + _DICT.put( 37324, 38818 ); + _DICT.put( 37325, 36708 ); + _DICT.put( 37326, 38636 ); + _DICT.put( 37327, 38858 ); + _DICT.put( 37328, 59352 ); + _DICT.put( 37329, 35808 ); + _DICT.put( 37334, 59353 ); + _DICT.put( 37335, 64443 ); + _DICT.put( 37336, 37698 ); + _DICT.put( 37338, 64442 ); + _DICT.put( 37339, 59356 ); + _DICT.put( 37340, 35480 ); + _DICT.put( 37341, 36970 ); + _DICT.put( 37342, 64444 ); + _DICT.put( 37343, 59354 ); + _DICT.put( 37345, 59355 ); + _DICT.put( 37347, 37598 ); + _DICT.put( 37348, 64447 ); + _DICT.put( 37349, 64448 ); + _DICT.put( 37350, 38516 ); + _DICT.put( 37351, 35834 ); + _DICT.put( 37357, 64445 ); + _DICT.put( 37358, 64446 ); + _DICT.put( 37365, 59358 ); + _DICT.put( 37366, 59359 ); + _DICT.put( 37372, 59357 ); + _DICT.put( 37375, 59361 ); + _DICT.put( 37382, 64449 ); + _DICT.put( 37386, 64451 ); + _DICT.put( 37389, 37853 ); + _DICT.put( 37390, 35426 ); + _DICT.put( 37392, 64450 ); + _DICT.put( 37393, 59365 ); + _DICT.put( 37396, 59362 ); + _DICT.put( 37397, 59364 ); + _DICT.put( 37406, 59360 ); + _DICT.put( 37417, 59502 ); + _DICT.put( 37420, 59363 ); + _DICT.put( 37428, 38889 ); + _DICT.put( 37431, 36056 ); + _DICT.put( 37433, 64458 ); + _DICT.put( 37434, 64452 ); + _DICT.put( 37436, 64454 ); + _DICT.put( 37439, 59373 ); + _DICT.put( 37440, 64453 ); + _DICT.put( 37444, 37715 ); + _DICT.put( 37445, 59368 ); + _DICT.put( 37448, 59371 ); + _DICT.put( 37449, 59369 ); + _DICT.put( 37451, 59374 ); + _DICT.put( 37454, 64455 ); + _DICT.put( 37456, 59375 ); + _DICT.put( 37457, 64457 ); + _DICT.put( 37463, 59367 ); + _DICT.put( 37465, 64456 ); + _DICT.put( 37466, 59380 ); + _DICT.put( 37467, 35220 ); + _DICT.put( 37470, 59366 ); + _DICT.put( 37474, 38059 ); + _DICT.put( 37476, 59370 ); + _DICT.put( 37478, 36830 ); + _DICT.put( 37479, 64459 ); + _DICT.put( 37489, 36218 ); + _DICT.put( 37495, 64461 ); + _DICT.put( 37496, 64462 ); + _DICT.put( 37502, 38503 ); + _DICT.put( 37504, 35810 ); + _DICT.put( 37507, 36709 ); + _DICT.put( 37509, 37818 ); + _DICT.put( 37512, 64095 ); + _DICT.put( 37521, 37196 ); + _DICT.put( 37523, 59378 ); + _DICT.put( 37525, 59372 ); + _DICT.put( 37526, 59377 ); + _DICT.put( 37528, 38593 ); + _DICT.put( 37530, 37558 ); + _DICT.put( 37531, 59379 ); + _DICT.put( 37532, 59376 ); + _DICT.put( 37543, 64460 ); + _DICT.put( 37549, 37195 ); + _DICT.put( 37559, 59383 ); + _DICT.put( 37561, 59382 ); + _DICT.put( 37583, 59381 ); + _DICT.put( 37584, 64466 ); + _DICT.put( 37586, 38478 ); + _DICT.put( 37587, 64470 ); + _DICT.put( 37589, 64468 ); + _DICT.put( 37591, 64464 ); + _DICT.put( 37593, 64465 ); + _DICT.put( 37600, 64469 ); + _DICT.put( 37604, 36763 ); + _DICT.put( 37607, 64463 ); + _DICT.put( 37609, 59384 ); + _DICT.put( 37610, 38365 ); + _DICT.put( 37613, 35187 ); + _DICT.put( 37618, 38245 ); + _DICT.put( 37619, 37522 ); + _DICT.put( 37624, 35736 ); + _DICT.put( 37625, 64101 ); + _DICT.put( 37626, 59386 ); + _DICT.put( 37627, 64473 ); + _DICT.put( 37628, 36220 ); + _DICT.put( 37631, 64476 ); + _DICT.put( 37634, 64478 ); + _DICT.put( 37638, 36427 ); + _DICT.put( 37647, 59385 ); + _DICT.put( 37648, 37005 ); + _DICT.put( 37656, 37006 ); + _DICT.put( 37657, 59456 ); + _DICT.put( 37658, 59458 ); + _DICT.put( 37661, 64477 ); + _DICT.put( 37662, 64475 ); + _DICT.put( 37664, 36857 ); + _DICT.put( 37665, 64472 ); + _DICT.put( 37666, 59457 ); + _DICT.put( 37667, 59459 ); + _DICT.put( 37669, 64471 ); + _DICT.put( 37670, 35793 ); + _DICT.put( 37672, 38244 ); + _DICT.put( 37675, 36576 ); + _DICT.put( 37676, 38978 ); + _DICT.put( 37678, 59388 ); + _DICT.put( 37679, 36342 ); + _DICT.put( 37682, 39006 ); + _DICT.put( 37685, 59461 ); + _DICT.put( 37690, 59460 ); + _DICT.put( 37691, 59462 ); + _DICT.put( 37700, 59387 ); + _DICT.put( 37704, 64094 ); + _DICT.put( 37707, 37863 ); + _DICT.put( 37709, 37748 ); + _DICT.put( 37716, 37589 ); + _DICT.put( 37718, 59467 ); + _DICT.put( 37719, 64480 ); + _DICT.put( 37723, 37474 ); + _DICT.put( 37724, 59463 ); + _DICT.put( 37728, 59464 ); + _DICT.put( 37740, 35916 ); + _DICT.put( 37742, 59466 ); + _DICT.put( 37744, 64479 ); + _DICT.put( 37749, 36014 ); + _DICT.put( 37756, 59465 ); + _DICT.put( 37758, 36831 ); + _DICT.put( 37772, 35481 ); + _DICT.put( 37780, 59471 ); + _DICT.put( 37782, 36285 ); + _DICT.put( 37783, 37273 ); + _DICT.put( 37786, 37576 ); + _DICT.put( 37796, 64481 ); + _DICT.put( 37799, 35418 ); + _DICT.put( 37804, 59469 ); + _DICT.put( 37805, 59470 ); + _DICT.put( 37806, 37569 ); + _DICT.put( 37808, 59468 ); + _DICT.put( 37817, 59472 ); + _DICT.put( 37827, 59478 ); + _DICT.put( 37830, 64482 ); + _DICT.put( 37832, 59481 ); + _DICT.put( 37840, 59480 ); + _DICT.put( 37841, 37708 ); + _DICT.put( 37846, 59473 ); + _DICT.put( 37847, 59474 ); + _DICT.put( 37848, 59477 ); + _DICT.put( 37853, 59479 ); + _DICT.put( 37854, 64483 ); + _DICT.put( 37857, 35774 ); + _DICT.put( 37860, 59482 ); + _DICT.put( 37861, 59476 ); + _DICT.put( 37864, 59475 ); + _DICT.put( 37880, 64484 ); + _DICT.put( 37891, 59486 ); + _DICT.put( 37895, 59487 ); + _DICT.put( 37904, 59488 ); + _DICT.put( 37907, 59485 ); + _DICT.put( 37908, 59484 ); + _DICT.put( 37912, 36832 ); + _DICT.put( 37913, 37800 ); + _DICT.put( 37914, 59483 ); + _DICT.put( 37921, 59492 ); + _DICT.put( 37931, 59490 ); + _DICT.put( 37937, 64485 ); + _DICT.put( 37941, 59491 ); + _DICT.put( 37942, 59489 ); + _DICT.put( 37944, 37366 ); + _DICT.put( 37946, 59493 ); + _DICT.put( 37953, 59494 ); + _DICT.put( 37956, 59496 ); + _DICT.put( 37957, 64486 ); + _DICT.put( 37960, 64487 ); + _DICT.put( 37969, 35539 ); + _DICT.put( 37970, 59495 ); + _DICT.put( 37971, 38648 ); + _DICT.put( 37978, 59507 ); + _DICT.put( 37979, 59497 ); + _DICT.put( 37982, 59500 ); + _DICT.put( 37984, 59498 ); + _DICT.put( 37986, 59499 ); + _DICT.put( 37994, 59501 ); + _DICT.put( 38000, 59503 ); + _DICT.put( 38005, 59504 ); + _DICT.put( 38007, 59505 ); + _DICT.put( 38012, 59508 ); + _DICT.put( 38013, 59506 ); + _DICT.put( 38014, 59509 ); + _DICT.put( 38015, 59511 ); + _DICT.put( 38017, 59510 ); + _DICT.put( 38263, 37559 ); + _DICT.put( 38272, 38629 ); + _DICT.put( 38274, 59512 ); + _DICT.put( 38275, 37197 ); + _DICT.put( 38279, 59513 ); + _DICT.put( 38281, 38338 ); + _DICT.put( 38282, 59514 ); + _DICT.put( 38283, 35402 ); + _DICT.put( 38287, 35163 ); + _DICT.put( 38289, 35541 ); + _DICT.put( 38290, 64488 ); + _DICT.put( 38291, 35540 ); + _DICT.put( 38292, 59515 ); + _DICT.put( 38294, 59516 ); + _DICT.put( 38296, 59517 ); + _DICT.put( 38297, 59518 ); + _DICT.put( 38304, 59520 ); + _DICT.put( 38306, 35542 ); + _DICT.put( 38307, 35444 ); + _DICT.put( 38308, 36221 ); + _DICT.put( 38309, 38068 ); + _DICT.put( 38311, 59522 ); + _DICT.put( 38312, 59521 ); + _DICT.put( 38317, 59523 ); + _DICT.put( 38322, 35195 ); + _DICT.put( 38329, 59526 ); + _DICT.put( 38331, 59525 ); + _DICT.put( 38332, 59524 ); + _DICT.put( 38334, 59527 ); + _DICT.put( 38339, 59530 ); + _DICT.put( 38343, 35013 ); + _DICT.put( 38346, 59528 ); + _DICT.put( 38348, 59532 ); + _DICT.put( 38349, 59531 ); + _DICT.put( 38356, 59534 ); + _DICT.put( 38357, 59533 ); + _DICT.put( 38358, 59535 ); + _DICT.put( 38360, 37804 ); + _DICT.put( 38364, 59536 ); + _DICT.put( 38369, 59537 ); + _DICT.put( 38370, 59539 ); + _DICT.put( 38373, 59538 ); + _DICT.put( 38428, 38284 ); + _DICT.put( 38433, 59540 ); + _DICT.put( 38440, 59541 ); + _DICT.put( 38442, 36323 ); + _DICT.put( 38446, 59542 ); + _DICT.put( 38447, 59543 ); + _DICT.put( 38450, 38504 ); + _DICT.put( 38459, 37226 ); + _DICT.put( 38463, 34978 ); + _DICT.put( 38464, 37321 ); + _DICT.put( 38466, 59544 ); + _DICT.put( 38468, 38285 ); + _DICT.put( 38475, 59547 ); + _DICT.put( 38476, 59545 ); + _DICT.put( 38477, 36222 ); + _DICT.put( 38479, 59546 ); + _DICT.put( 38480, 36032 ); + _DICT.put( 38491, 38339 ); + _DICT.put( 38492, 59549 ); + _DICT.put( 38493, 59551 ); + _DICT.put( 38494, 59550 ); + _DICT.put( 38495, 59552 ); + _DICT.put( 38498, 35136 ); + _DICT.put( 38499, 36983 ); + _DICT.put( 38500, 36764 ); + _DICT.put( 38501, 35543 ); + _DICT.put( 38502, 59553 ); + _DICT.put( 38506, 38022 ); + _DICT.put( 38508, 59555 ); + _DICT.put( 38512, 35137 ); + _DICT.put( 38514, 59554 ); + _DICT.put( 38515, 37570 ); + _DICT.put( 38517, 38859 ); + _DICT.put( 38518, 37801 ); + _DICT.put( 38519, 59548 ); + _DICT.put( 38520, 38820 ); + _DICT.put( 38522, 36015 ); + _DICT.put( 38525, 38778 ); + _DICT.put( 38533, 35831 ); + _DICT.put( 38534, 38834 ); + _DICT.put( 38536, 35911 ); + _DICT.put( 38538, 37344 ); + _DICT.put( 38539, 58432 ); + _DICT.put( 38541, 59556 ); + _DICT.put( 38542, 35403 ); + _DICT.put( 38543, 37007 ); + _DICT.put( 38548, 35445 ); + _DICT.put( 38549, 59558 ); + _DICT.put( 38551, 59559 ); + _DICT.put( 38552, 59557 ); + _DICT.put( 38553, 35972 ); + _DICT.put( 38555, 36315 ); + _DICT.put( 38556, 36833 ); + _DICT.put( 38557, 64491 ); + _DICT.put( 38560, 35138 ); + _DICT.put( 38563, 38871 ); + _DICT.put( 38567, 59561 ); + _DICT.put( 38568, 59308 ); + _DICT.put( 38570, 59560 ); + _DICT.put( 38575, 64492 ); + _DICT.put( 38576, 59564 ); + _DICT.put( 38577, 59562 ); + _DICT.put( 38578, 59563 ); + _DICT.put( 38580, 59565 ); + _DICT.put( 38582, 59566 ); + _DICT.put( 38583, 38890 ); + _DICT.put( 38584, 59567 ); + _DICT.put( 38585, 59568 ); + _DICT.put( 38587, 37063 ); + _DICT.put( 38588, 38073 ); + _DICT.put( 38592, 37021 ); + _DICT.put( 38593, 35557 ); + _DICT.put( 38596, 38745 ); + _DICT.put( 38597, 35307 ); + _DICT.put( 38598, 36695 ); + _DICT.put( 38599, 36057 ); + _DICT.put( 38601, 59571 ); + _DICT.put( 38603, 59570 ); + _DICT.put( 38604, 36499 ); + _DICT.put( 38605, 59572 ); + _DICT.put( 38606, 59569 ); + _DICT.put( 38609, 36423 ); + _DICT.put( 38613, 59576 ); + _DICT.put( 38614, 58795 ); + _DICT.put( 38617, 39380 ); + _DICT.put( 38619, 37015 ); + _DICT.put( 38620, 59574 ); + _DICT.put( 38626, 38819 ); + _DICT.put( 38627, 37871 ); + _DICT.put( 38632, 35146 ); + _DICT.put( 38634, 37089 ); + _DICT.put( 38635, 36532 ); + _DICT.put( 38640, 38325 ); + _DICT.put( 38642, 35167 ); + _DICT.put( 38646, 38891 ); + _DICT.put( 38647, 38795 ); + _DICT.put( 38649, 59577 ); + _DICT.put( 38651, 37732 ); + _DICT.put( 38656, 36601 ); + _DICT.put( 38660, 59578 ); + _DICT.put( 38662, 59579 ); + _DICT.put( 38663, 36971 ); + _DICT.put( 38664, 59580 ); + _DICT.put( 38666, 38892 ); + _DICT.put( 38669, 59575 ); + _DICT.put( 38670, 59582 ); + _DICT.put( 38671, 59584 ); + _DICT.put( 38673, 59583 ); + _DICT.put( 38675, 59581 ); + _DICT.put( 38678, 59585 ); + _DICT.put( 38681, 59586 ); + _DICT.put( 38684, 37274 ); + _DICT.put( 38686, 35296 ); + _DICT.put( 38692, 59587 ); + _DICT.put( 38695, 38582 ); + _DICT.put( 38698, 59588 ); + _DICT.put( 38704, 59589 ); + _DICT.put( 38706, 38985 ); + _DICT.put( 38707, 64493 ); + _DICT.put( 38712, 40528 ); + _DICT.put( 38713, 59590 ); + _DICT.put( 38715, 64494 ); + _DICT.put( 38717, 59591 ); + _DICT.put( 38718, 59592 ); + _DICT.put( 38722, 59596 ); + _DICT.put( 38723, 64495 ); + _DICT.put( 38724, 59593 ); + _DICT.put( 38726, 59594 ); + _DICT.put( 38728, 59595 ); + _DICT.put( 38729, 59597 ); + _DICT.put( 38733, 64496 ); + _DICT.put( 38735, 64497 ); + _DICT.put( 38737, 64498 ); + _DICT.put( 38738, 37058 ); + _DICT.put( 38741, 64499 ); + _DICT.put( 38742, 38645 ); + _DICT.put( 38745, 37059 ); + _DICT.put( 38748, 59598 ); + _DICT.put( 38750, 38129 ); + _DICT.put( 38752, 59599 ); + _DICT.put( 38753, 60018 ); + _DICT.put( 38754, 38602 ); + _DICT.put( 38756, 59600 ); + _DICT.put( 38758, 59601 ); + _DICT.put( 38760, 59602 ); + _DICT.put( 38761, 35446 ); + _DICT.put( 38763, 59604 ); + _DICT.put( 38765, 36984 ); + _DICT.put( 38769, 59605 ); + _DICT.put( 38772, 35907 ); + _DICT.put( 38777, 59606 ); + _DICT.put( 38778, 59610 ); + _DICT.put( 38780, 59608 ); + _DICT.put( 38785, 59609 ); + _DICT.put( 38788, 35475 ); + _DICT.put( 38789, 59607 ); + _DICT.put( 38790, 59611 ); + _DICT.put( 38795, 59612 ); + _DICT.put( 38797, 35014 ); + _DICT.put( 38799, 59613 ); + _DICT.put( 38800, 59614 ); + _DICT.put( 38808, 36834 ); + _DICT.put( 38812, 59615 ); + _DICT.put( 38816, 35686 ); + _DICT.put( 38819, 59618 ); + _DICT.put( 38822, 59617 ); + _DICT.put( 38824, 59616 ); + _DICT.put( 38827, 59025 ); + _DICT.put( 38829, 38362 ); + _DICT.put( 38835, 59619 ); + _DICT.put( 38836, 59620 ); + _DICT.put( 38851, 59621 ); + _DICT.put( 38854, 59622 ); + _DICT.put( 38856, 59623 ); + _DICT.put( 38859, 59624 ); + _DICT.put( 38867, 35544 ); + _DICT.put( 38876, 59625 ); + _DICT.put( 38893, 59626 ); + _DICT.put( 38894, 37954 ); + _DICT.put( 38898, 59628 ); + _DICT.put( 38899, 35257 ); + _DICT.put( 38901, 59631 ); + _DICT.put( 38902, 59630 ); + _DICT.put( 38907, 35139 ); + _DICT.put( 38911, 35775 ); + _DICT.put( 38913, 38341 ); + _DICT.put( 38914, 37560 ); + _DICT.put( 38915, 36256 ); + _DICT.put( 38917, 36224 ); + _DICT.put( 38918, 36743 ); + _DICT.put( 38920, 36987 ); + _DICT.put( 38924, 59633 ); + _DICT.put( 38927, 59632 ); + _DICT.put( 38928, 38753 ); + _DICT.put( 38929, 35558 ); + _DICT.put( 38930, 38096 ); + _DICT.put( 38931, 37850 ); + _DICT.put( 38935, 37020 ); + _DICT.put( 38936, 38860 ); + _DICT.put( 38938, 35962 ); + _DICT.put( 38945, 59636 ); + _DICT.put( 38948, 59635 ); + _DICT.put( 38956, 38506 ); + _DICT.put( 38957, 37802 ); + _DICT.put( 38964, 35183 ); + _DICT.put( 38967, 59637 ); + _DICT.put( 38968, 59634 ); + _DICT.put( 38971, 38256 ); + _DICT.put( 38972, 38794 ); + _DICT.put( 38973, 59638 ); + _DICT.put( 38982, 59639 ); + _DICT.put( 38987, 59641 ); + _DICT.put( 38988, 37352 ); + _DICT.put( 38989, 35450 ); + _DICT.put( 38990, 35451 ); + _DICT.put( 38991, 59640 ); + _DICT.put( 38996, 35559 ); + _DICT.put( 38997, 36016 ); + _DICT.put( 38999, 64500 ); + _DICT.put( 39000, 35560 ); + _DICT.put( 39003, 37726 ); + _DICT.put( 39006, 38878 ); + _DICT.put( 39013, 64501 ); + _DICT.put( 39015, 36058 ); + _DICT.put( 39019, 59642 ); + _DICT.put( 39023, 59643 ); + _DICT.put( 39024, 59644 ); + _DICT.put( 39025, 59712 ); + _DICT.put( 39027, 59714 ); + _DICT.put( 39028, 59713 ); + _DICT.put( 39080, 38295 ); + _DICT.put( 39082, 59715 ); + _DICT.put( 39087, 59716 ); + _DICT.put( 39089, 59717 ); + _DICT.put( 39094, 59718 ); + _DICT.put( 39107, 59720 ); + _DICT.put( 39108, 59719 ); + _DICT.put( 39110, 59721 ); + _DICT.put( 39131, 38130 ); + _DICT.put( 39132, 58314 ); + _DICT.put( 39135, 36936 ); + _DICT.put( 39138, 35665 ); + _DICT.put( 39145, 59722 ); + _DICT.put( 39147, 59723 ); + _DICT.put( 39149, 39338 ); + _DICT.put( 39150, 40794 ); + _DICT.put( 39151, 38097 ); + _DICT.put( 39154, 35065 ); + _DICT.put( 39156, 35001 ); + _DICT.put( 39164, 36500 ); + _DICT.put( 39165, 38479 ); + _DICT.put( 39166, 36860 ); + _DICT.put( 39171, 59724 ); + _DICT.put( 39173, 38621 ); + _DICT.put( 39177, 59725 ); + _DICT.put( 39178, 38779 ); + _DICT.put( 39180, 35169 ); + _DICT.put( 39184, 36448 ); + _DICT.put( 39186, 59726 ); + _DICT.put( 39187, 35308 ); + _DICT.put( 39188, 59727 ); + _DICT.put( 39192, 59728 ); + _DICT.put( 39197, 59730 ); + _DICT.put( 39198, 59731 ); + _DICT.put( 39200, 59733 ); + _DICT.put( 39201, 59729 ); + _DICT.put( 39204, 59732 ); + _DICT.put( 39207, 64504 ); + _DICT.put( 39208, 35545 ); + _DICT.put( 39212, 59734 ); + _DICT.put( 39214, 59735 ); + _DICT.put( 39229, 59736 ); + _DICT.put( 39230, 59737 ); + _DICT.put( 39234, 59738 ); + _DICT.put( 39237, 59740 ); + _DICT.put( 39241, 59739 ); + _DICT.put( 39243, 59742 ); + _DICT.put( 39244, 59745 ); + _DICT.put( 39248, 59741 ); + _DICT.put( 39249, 59743 ); + _DICT.put( 39250, 59744 ); + _DICT.put( 39253, 59746 ); + _DICT.put( 39255, 35776 ); + _DICT.put( 39318, 36593 ); + _DICT.put( 39319, 59747 ); + _DICT.put( 39320, 59748 ); + _DICT.put( 39321, 36225 ); + _DICT.put( 39326, 64506 ); + _DICT.put( 39333, 59749 ); + _DICT.put( 39336, 35421 ); + _DICT.put( 39340, 37998 ); + _DICT.put( 39341, 59750 ); + _DICT.put( 39342, 59751 ); + _DICT.put( 39347, 37497 ); + _DICT.put( 39348, 37865 ); + _DICT.put( 39356, 59752 ); + _DICT.put( 39361, 38045 ); + _DICT.put( 39364, 37322 ); + _DICT.put( 39365, 35191 ); + _DICT.put( 39366, 35820 ); + _DICT.put( 39368, 35821 ); + _DICT.put( 39376, 37523 ); + _DICT.put( 39377, 59757 ); + _DICT.put( 39378, 35822 ); + _DICT.put( 39381, 35309 ); + _DICT.put( 39384, 59756 ); + _DICT.put( 39387, 59754 ); + _DICT.put( 39389, 59755 ); + _DICT.put( 39391, 59753 ); + _DICT.put( 39394, 59767 ); + _DICT.put( 39405, 59758 ); + _DICT.put( 39406, 59759 ); + _DICT.put( 39409, 59760 ); + _DICT.put( 39410, 59761 ); + _DICT.put( 39416, 59763 ); + _DICT.put( 39419, 59762 ); + _DICT.put( 39423, 36728 ); + _DICT.put( 39425, 59764 ); + _DICT.put( 39429, 59766 ); + _DICT.put( 39438, 35666 ); + _DICT.put( 39439, 59765 ); + _DICT.put( 39442, 37275 ); + _DICT.put( 39443, 36017 ); + _DICT.put( 39449, 59768 ); + _DICT.put( 39464, 37323 ); + _DICT.put( 39467, 59769 ); + _DICT.put( 39472, 37803 ); + _DICT.put( 39479, 59770 ); + _DICT.put( 39486, 59776 ); + _DICT.put( 39488, 59773 ); + _DICT.put( 39490, 59772 ); + _DICT.put( 39491, 59774 ); + _DICT.put( 39493, 59771 ); + _DICT.put( 39501, 59778 ); + _DICT.put( 39502, 64507 ); + _DICT.put( 39509, 59777 ); + _DICT.put( 39511, 59780 ); + _DICT.put( 39514, 35777 ); + _DICT.put( 39515, 59779 ); + _DICT.put( 39519, 59781 ); + _DICT.put( 39522, 59782 ); + _DICT.put( 39524, 59784 ); + _DICT.put( 39525, 59783 ); + _DICT.put( 39529, 59785 ); + _DICT.put( 39530, 59787 ); + _DICT.put( 39531, 59786 ); + _DICT.put( 39592, 36252 ); + _DICT.put( 39597, 59788 ); + _DICT.put( 39600, 59789 ); + _DICT.put( 39608, 35419 ); + _DICT.put( 39612, 59790 ); + _DICT.put( 39616, 59791 ); + _DICT.put( 39620, 37009 ); + _DICT.put( 39631, 59792 ); + _DICT.put( 39633, 59793 ); + _DICT.put( 39635, 59794 ); + _DICT.put( 39636, 59795 ); + _DICT.put( 39640, 36226 ); + _DICT.put( 39641, 64508 ); + _DICT.put( 39644, 64576 ); + _DICT.put( 39646, 59796 ); + _DICT.put( 39647, 59797 ); + _DICT.put( 39650, 59798 ); + _DICT.put( 39651, 59799 ); + _DICT.put( 39654, 59800 ); + _DICT.put( 39658, 38063 ); + _DICT.put( 39659, 59802 ); + _DICT.put( 39661, 38213 ); + _DICT.put( 39662, 59803 ); + _DICT.put( 39663, 59801 ); + _DICT.put( 39665, 59805 ); + _DICT.put( 39668, 59804 ); + _DICT.put( 39671, 59806 ); + _DICT.put( 39675, 59807 ); + _DICT.put( 39686, 59808 ); + _DICT.put( 39704, 59809 ); + _DICT.put( 39706, 59810 ); + _DICT.put( 39711, 59811 ); + _DICT.put( 39714, 59812 ); + _DICT.put( 39715, 59813 ); + _DICT.put( 39717, 59814 ); + _DICT.put( 39719, 59815 ); + _DICT.put( 39720, 59816 ); + _DICT.put( 39721, 59817 ); + _DICT.put( 39722, 59818 ); + _DICT.put( 39726, 59819 ); + _DICT.put( 39727, 59820 ); + _DICT.put( 39729, 40788 ); + _DICT.put( 39730, 59821 ); + _DICT.put( 39739, 58102 ); + _DICT.put( 39740, 35667 ); + _DICT.put( 39745, 35392 ); + _DICT.put( 39746, 36272 ); + _DICT.put( 39747, 59823 ); + _DICT.put( 39748, 59822 ); + _DICT.put( 39749, 38563 ); + _DICT.put( 39757, 59825 ); + _DICT.put( 39758, 59826 ); + _DICT.put( 39759, 59824 ); + _DICT.put( 39761, 59827 ); + _DICT.put( 39764, 38530 ); + _DICT.put( 39768, 59828 ); + _DICT.put( 39770, 35739 ); + _DICT.put( 39791, 38980 ); + _DICT.put( 39794, 64578 ); + _DICT.put( 39796, 59829 ); + _DICT.put( 39797, 64577 ); + _DICT.put( 39811, 59831 ); + _DICT.put( 39822, 35004 ); + _DICT.put( 39823, 64579 ); + _DICT.put( 39825, 59832 ); + _DICT.put( 39826, 38313 ); + _DICT.put( 39827, 59830 ); + _DICT.put( 39830, 59833 ); + _DICT.put( 39831, 59834 ); + _DICT.put( 39839, 59835 ); + _DICT.put( 39840, 59836 ); + _DICT.put( 39848, 59837 ); + _DICT.put( 39850, 38542 ); + _DICT.put( 39851, 36428 ); + _DICT.put( 39853, 36344 ); + _DICT.put( 39854, 37198 ); + _DICT.put( 39857, 64580 ); + _DICT.put( 39860, 59838 ); + _DICT.put( 39865, 59841 ); + _DICT.put( 39867, 64581 ); + _DICT.put( 39872, 59839 ); + _DICT.put( 39878, 59842 ); + _DICT.put( 39881, 36079 ); + _DICT.put( 39882, 59840 ); + _DICT.put( 39887, 59843 ); + _DICT.put( 39889, 59844 ); + _DICT.put( 39890, 59845 ); + _DICT.put( 39892, 59849 ); + _DICT.put( 39894, 36425 ); + _DICT.put( 39899, 37346 ); + _DICT.put( 39905, 59850 ); + _DICT.put( 39906, 59847 ); + _DICT.put( 39907, 59846 ); + _DICT.put( 39908, 59848 ); + _DICT.put( 39912, 35966 ); + _DICT.put( 39920, 59854 ); + _DICT.put( 39921, 59853 ); + _DICT.put( 39922, 59852 ); + _DICT.put( 39925, 34993 ); + _DICT.put( 39936, 64582 ); + _DICT.put( 39940, 59864 ); + _DICT.put( 39942, 59860 ); + _DICT.put( 39944, 59861 ); + _DICT.put( 39945, 59857 ); + _DICT.put( 39946, 59863 ); + _DICT.put( 39948, 59859 ); + _DICT.put( 39949, 35458 ); + _DICT.put( 39952, 39019 ); + _DICT.put( 39954, 59862 ); + _DICT.put( 39955, 59858 ); + _DICT.put( 39956, 59856 ); + _DICT.put( 39957, 59855 ); + _DICT.put( 39963, 59866 ); + _DICT.put( 39969, 59869 ); + _DICT.put( 39972, 59868 ); + _DICT.put( 39973, 59867 ); + _DICT.put( 39981, 38248 ); + _DICT.put( 39982, 59865 ); + _DICT.put( 39983, 35057 ); + _DICT.put( 39984, 59870 ); + _DICT.put( 39986, 59872 ); + _DICT.put( 39993, 35471 ); + _DICT.put( 39994, 59851 ); + _DICT.put( 39995, 35158 ); + _DICT.put( 39998, 59874 ); + _DICT.put( 40006, 59873 ); + _DICT.put( 40007, 59871 ); + _DICT.put( 40008, 37452 ); + _DICT.put( 40018, 38544 ); + _DICT.put( 40023, 38872 ); + _DICT.put( 40026, 59875 ); + _DICT.put( 40032, 59876 ); + _DICT.put( 40039, 59877 ); + _DICT.put( 40054, 59878 ); + _DICT.put( 40056, 59879 ); + _DICT.put( 40165, 37561 ); + _DICT.put( 40167, 59880 ); + _DICT.put( 40169, 38069 ); + _DICT.put( 40171, 59885 ); + _DICT.put( 40172, 59881 ); + _DICT.put( 40176, 59882 ); + _DICT.put( 40179, 38480 ); + _DICT.put( 40180, 38594 ); + _DICT.put( 40182, 37838 ); + _DICT.put( 40195, 59886 ); + _DICT.put( 40198, 59887 ); + _DICT.put( 40199, 37820 ); + _DICT.put( 40200, 59884 ); + _DICT.put( 40201, 59883 ); + _DICT.put( 40206, 35240 ); + _DICT.put( 40210, 59895 ); + _DICT.put( 40213, 59894 ); + _DICT.put( 40219, 35221 ); + _DICT.put( 40223, 59892 ); + _DICT.put( 40227, 59891 ); + _DICT.put( 40230, 59889 ); + _DICT.put( 40232, 35483 ); + _DICT.put( 40234, 59888 ); + _DICT.put( 40235, 36528 ); + _DICT.put( 40236, 35239 ); + _DICT.put( 40251, 36227 ); + _DICT.put( 40254, 59898 ); + _DICT.put( 40255, 59897 ); + _DICT.put( 40257, 59896 ); + _DICT.put( 40260, 59893 ); + _DICT.put( 40262, 59899 ); + _DICT.put( 40264, 59900 ); + _DICT.put( 40272, 59972 ); + _DICT.put( 40273, 59971 ); + _DICT.put( 40281, 59973 ); + _DICT.put( 40284, 35148 ); + _DICT.put( 40285, 59968 ); + _DICT.put( 40286, 59969 ); + _DICT.put( 40288, 36244 ); + _DICT.put( 40289, 38583 ); + _DICT.put( 40292, 59970 ); + _DICT.put( 40299, 64584 ); + _DICT.put( 40300, 38481 ); + _DICT.put( 40303, 59978 ); + _DICT.put( 40304, 64583 ); + _DICT.put( 40306, 59974 ); + _DICT.put( 40314, 59979 ); + _DICT.put( 40327, 59976 ); + _DICT.put( 40329, 59975 ); + _DICT.put( 40335, 35963 ); + _DICT.put( 40346, 59980 ); + _DICT.put( 40356, 59981 ); + _DICT.put( 40361, 59982 ); + _DICT.put( 40363, 59977 ); + _DICT.put( 40367, 59890 ); + _DICT.put( 40370, 59983 ); + _DICT.put( 40372, 37599 ); + _DICT.put( 40376, 59987 ); + _DICT.put( 40378, 59988 ); + _DICT.put( 40379, 59986 ); + _DICT.put( 40385, 59985 ); + _DICT.put( 40386, 59991 ); + _DICT.put( 40388, 59984 ); + _DICT.put( 40390, 59989 ); + _DICT.put( 40399, 59990 ); + _DICT.put( 40403, 59993 ); + _DICT.put( 40409, 59992 ); + _DICT.put( 40422, 59995 ); + _DICT.put( 40429, 59996 ); + _DICT.put( 40431, 59997 ); + _DICT.put( 40434, 39016 ); + _DICT.put( 40440, 59994 ); + _DICT.put( 40441, 37353 ); + _DICT.put( 40442, 36331 ); + _DICT.put( 40445, 59998 ); + _DICT.put( 40473, 64586 ); + _DICT.put( 40474, 59999 ); + _DICT.put( 40475, 60000 ); + _DICT.put( 40478, 60001 ); + _DICT.put( 40565, 60002 ); + _DICT.put( 40568, 36018 ); + _DICT.put( 40569, 60003 ); + _DICT.put( 40573, 60004 ); + _DICT.put( 40575, 36525 ); + _DICT.put( 40577, 60005 ); + _DICT.put( 40584, 60006 ); + _DICT.put( 40587, 60007 ); + _DICT.put( 40588, 60008 ); + _DICT.put( 40593, 60011 ); + _DICT.put( 40594, 60009 ); + _DICT.put( 40595, 39003 ); + _DICT.put( 40597, 60010 ); + _DICT.put( 40599, 38893 ); + _DICT.put( 40605, 60012 ); + _DICT.put( 40607, 38873 ); + _DICT.put( 40613, 60013 ); + _DICT.put( 40614, 38046 ); + _DICT.put( 40617, 60014 ); + _DICT.put( 40618, 60016 ); + _DICT.put( 40621, 60017 ); + _DICT.put( 40632, 60015 ); + _DICT.put( 40633, 36237 ); + _DICT.put( 40634, 38603 ); + _DICT.put( 40635, 38531 ); + _DICT.put( 40636, 39925 ); + _DICT.put( 40638, 40832 ); + _DICT.put( 40639, 38555 ); + _DICT.put( 40644, 35241 ); + _DICT.put( 40652, 60019 ); + _DICT.put( 40653, 35695 ); + _DICT.put( 40654, 60020 ); + _DICT.put( 40655, 60021 ); + _DICT.put( 40656, 60022 ); + _DICT.put( 40657, 64587 ); + _DICT.put( 40658, 36245 ); + _DICT.put( 40660, 60023 ); + _DICT.put( 40664, 57554 ); + _DICT.put( 40665, 38617 ); + _DICT.put( 40667, 37345 ); + _DICT.put( 40668, 60024 ); + _DICT.put( 40669, 60026 ); + _DICT.put( 40670, 60025 ); + _DICT.put( 40672, 60027 ); + _DICT.put( 40677, 60028 ); + _DICT.put( 40680, 60029 ); + _DICT.put( 40687, 60030 ); + _DICT.put( 40692, 60032 ); + _DICT.put( 40694, 60033 ); + _DICT.put( 40695, 60034 ); + _DICT.put( 40697, 60035 ); + _DICT.put( 40699, 60036 ); + _DICT.put( 40700, 60037 ); + _DICT.put( 40701, 60038 ); + _DICT.put( 40711, 60039 ); + _DICT.put( 40712, 60040 ); + _DICT.put( 40718, 37699 ); + _DICT.put( 40723, 36059 ); + _DICT.put( 40725, 60042 ); + _DICT.put( 40736, 37228 ); + _DICT.put( 40737, 60043 ); + _DICT.put( 40748, 60044 ); + _DICT.put( 40763, 38208 ); + _DICT.put( 40766, 60045 ); + _DICT.put( 40778, 60046 ); + _DICT.put( 40779, 57942 ); + _DICT.put( 40782, 59096 ); + _DICT.put( 40783, 59627 ); + _DICT.put( 40786, 60047 ); + _DICT.put( 40788, 60048 ); + _DICT.put( 40799, 60050 ); + _DICT.put( 40800, 60051 ); + _DICT.put( 40801, 60052 ); + _DICT.put( 40802, 38894 ); + _DICT.put( 40803, 60049 ); + _DICT.put( 40806, 60053 ); + _DICT.put( 40807, 60054 ); + _DICT.put( 40810, 60056 ); + _DICT.put( 40812, 60055 ); + _DICT.put( 40818, 60058 ); + _DICT.put( 40822, 60059 ); + _DICT.put( 40823, 60057 ); + _DICT.put( 40845, 38836 ); + _DICT.put( 40853, 60060 ); + _DICT.put( 40860, 60061 ); + _DICT.put( 40861, 57971 ); + _DICT.put( 40864, 60062 ); + _DICT.put( 57344, 61504 ); + _DICT.put( 57345, 61505 ); + _DICT.put( 57346, 61506 ); + _DICT.put( 57347, 61507 ); + _DICT.put( 57348, 61508 ); + _DICT.put( 57349, 61509 ); + _DICT.put( 57350, 61510 ); + _DICT.put( 57351, 61511 ); + _DICT.put( 57352, 61512 ); + _DICT.put( 57353, 61513 ); + _DICT.put( 57354, 61514 ); + _DICT.put( 57355, 61515 ); + _DICT.put( 57356, 61516 ); + _DICT.put( 57357, 61517 ); + _DICT.put( 57358, 61518 ); + _DICT.put( 57359, 61519 ); + _DICT.put( 57360, 61520 ); + _DICT.put( 57361, 61521 ); + _DICT.put( 57362, 61522 ); + _DICT.put( 57363, 61523 ); + _DICT.put( 57364, 61524 ); + _DICT.put( 57365, 61525 ); + _DICT.put( 57366, 61526 ); + _DICT.put( 57367, 61527 ); + _DICT.put( 57368, 61528 ); + _DICT.put( 57369, 61529 ); + _DICT.put( 57370, 61530 ); + _DICT.put( 57371, 61531 ); + _DICT.put( 57372, 61532 ); + _DICT.put( 57373, 61533 ); + _DICT.put( 57374, 61534 ); + _DICT.put( 57375, 61535 ); + _DICT.put( 57376, 61536 ); + _DICT.put( 57377, 61537 ); + _DICT.put( 57378, 61538 ); + _DICT.put( 57379, 61539 ); + _DICT.put( 57380, 61540 ); + _DICT.put( 57381, 61541 ); + _DICT.put( 57382, 61542 ); + _DICT.put( 57383, 61543 ); + _DICT.put( 57384, 61544 ); + _DICT.put( 57385, 61545 ); + _DICT.put( 57386, 61546 ); + _DICT.put( 57387, 61547 ); + _DICT.put( 57388, 61548 ); + _DICT.put( 57389, 61549 ); + _DICT.put( 57390, 61550 ); + _DICT.put( 57391, 61551 ); + _DICT.put( 57392, 61552 ); + _DICT.put( 57393, 61553 ); + _DICT.put( 57394, 61554 ); + _DICT.put( 57395, 61555 ); + _DICT.put( 57396, 61556 ); + _DICT.put( 57397, 61557 ); + _DICT.put( 57398, 61558 ); + _DICT.put( 57399, 61559 ); + _DICT.put( 57400, 61560 ); + _DICT.put( 57401, 61561 ); + _DICT.put( 57402, 61562 ); + _DICT.put( 57403, 61563 ); + _DICT.put( 57404, 61564 ); + _DICT.put( 57405, 61565 ); + _DICT.put( 57406, 61566 ); + _DICT.put( 57407, 61568 ); + _DICT.put( 57408, 61569 ); + _DICT.put( 57409, 61570 ); + _DICT.put( 57410, 61571 ); + _DICT.put( 57411, 61572 ); + _DICT.put( 57412, 61573 ); + _DICT.put( 57413, 61574 ); + _DICT.put( 57414, 61575 ); + _DICT.put( 57415, 61576 ); + _DICT.put( 57416, 61577 ); + _DICT.put( 57417, 61578 ); + _DICT.put( 57418, 61579 ); + _DICT.put( 57419, 61580 ); + _DICT.put( 57420, 61581 ); + _DICT.put( 57421, 61582 ); + _DICT.put( 57422, 61583 ); + _DICT.put( 57423, 61584 ); + _DICT.put( 57424, 61585 ); + _DICT.put( 57425, 61586 ); + _DICT.put( 57426, 61587 ); + _DICT.put( 57427, 61588 ); + _DICT.put( 57428, 61589 ); + _DICT.put( 57429, 61590 ); + _DICT.put( 57430, 61591 ); + _DICT.put( 57431, 61592 ); + _DICT.put( 57432, 61593 ); + _DICT.put( 57433, 61594 ); + _DICT.put( 57434, 61595 ); + _DICT.put( 57435, 61596 ); + _DICT.put( 57436, 61597 ); + _DICT.put( 57437, 61598 ); + _DICT.put( 57438, 61599 ); + _DICT.put( 57439, 61600 ); + _DICT.put( 57440, 61601 ); + _DICT.put( 57441, 61602 ); + _DICT.put( 57442, 61603 ); + _DICT.put( 57443, 61604 ); + _DICT.put( 57444, 61605 ); + _DICT.put( 57445, 61606 ); + _DICT.put( 57446, 61607 ); + _DICT.put( 57447, 61608 ); + _DICT.put( 57448, 61609 ); + _DICT.put( 57449, 61610 ); + _DICT.put( 57450, 61611 ); + _DICT.put( 57451, 61612 ); + _DICT.put( 57452, 61613 ); + _DICT.put( 57453, 61614 ); + _DICT.put( 57454, 61615 ); + _DICT.put( 57455, 61616 ); + _DICT.put( 57456, 61617 ); + _DICT.put( 57457, 61618 ); + _DICT.put( 57458, 61619 ); + _DICT.put( 57459, 61620 ); + _DICT.put( 57460, 61621 ); + _DICT.put( 57461, 61622 ); + _DICT.put( 57462, 61623 ); + _DICT.put( 57463, 61624 ); + _DICT.put( 57464, 61625 ); + _DICT.put( 57465, 61626 ); + _DICT.put( 57466, 61627 ); + _DICT.put( 57467, 61628 ); + _DICT.put( 57468, 61629 ); + _DICT.put( 57469, 61630 ); + _DICT.put( 57470, 61631 ); + _DICT.put( 57471, 61632 ); + _DICT.put( 57472, 61633 ); + _DICT.put( 57473, 61634 ); + _DICT.put( 57474, 61635 ); + _DICT.put( 57475, 61636 ); + _DICT.put( 57476, 61637 ); + _DICT.put( 57477, 61638 ); + _DICT.put( 57478, 61639 ); + _DICT.put( 57479, 61640 ); + _DICT.put( 57480, 61641 ); + _DICT.put( 57481, 61642 ); + _DICT.put( 57482, 61643 ); + _DICT.put( 57483, 61644 ); + _DICT.put( 57484, 61645 ); + _DICT.put( 57485, 61646 ); + _DICT.put( 57486, 61647 ); + _DICT.put( 57487, 61648 ); + _DICT.put( 57488, 61649 ); + _DICT.put( 57489, 61650 ); + _DICT.put( 57490, 61651 ); + _DICT.put( 57491, 61652 ); + _DICT.put( 57492, 61653 ); + _DICT.put( 57493, 61654 ); + _DICT.put( 57494, 61655 ); + _DICT.put( 57495, 61656 ); + _DICT.put( 57496, 61657 ); + _DICT.put( 57497, 61658 ); + _DICT.put( 57498, 61659 ); + _DICT.put( 57499, 61660 ); + _DICT.put( 57500, 61661 ); + _DICT.put( 57501, 61662 ); + _DICT.put( 57502, 61663 ); + _DICT.put( 57503, 61664 ); + _DICT.put( 57504, 61665 ); + _DICT.put( 57505, 61666 ); + _DICT.put( 57506, 61667 ); + _DICT.put( 57507, 61668 ); + _DICT.put( 57508, 61669 ); + _DICT.put( 57509, 61670 ); + _DICT.put( 57510, 61671 ); + _DICT.put( 57511, 61672 ); + _DICT.put( 57512, 61673 ); + _DICT.put( 57513, 61674 ); + _DICT.put( 57514, 61675 ); + _DICT.put( 57515, 61676 ); + _DICT.put( 57516, 61677 ); + _DICT.put( 57517, 61678 ); + _DICT.put( 57518, 61679 ); + _DICT.put( 57519, 61680 ); + _DICT.put( 57520, 61681 ); + _DICT.put( 57521, 61682 ); + _DICT.put( 57522, 61683 ); + _DICT.put( 57523, 61684 ); + _DICT.put( 57524, 61685 ); + _DICT.put( 57525, 61686 ); + _DICT.put( 57526, 61687 ); + _DICT.put( 57527, 61688 ); + _DICT.put( 57528, 61689 ); + _DICT.put( 57529, 61690 ); + _DICT.put( 57530, 61691 ); + _DICT.put( 57531, 61692 ); + _DICT.put( 57532, 61760 ); + _DICT.put( 57533, 61761 ); + _DICT.put( 57534, 61762 ); + _DICT.put( 57535, 61763 ); + _DICT.put( 57536, 61764 ); + _DICT.put( 57537, 61765 ); + _DICT.put( 57538, 61766 ); + _DICT.put( 57539, 61767 ); + _DICT.put( 57540, 61768 ); + _DICT.put( 57541, 61769 ); + _DICT.put( 57542, 61770 ); + _DICT.put( 57543, 61771 ); + _DICT.put( 57544, 61772 ); + _DICT.put( 57545, 61773 ); + _DICT.put( 57546, 61774 ); + _DICT.put( 57547, 61775 ); + _DICT.put( 57548, 61776 ); + _DICT.put( 57549, 61777 ); + _DICT.put( 57550, 61778 ); + _DICT.put( 57551, 61779 ); + _DICT.put( 57552, 61780 ); + _DICT.put( 57553, 61781 ); + _DICT.put( 57554, 61782 ); + _DICT.put( 57555, 61783 ); + _DICT.put( 57556, 61784 ); + _DICT.put( 57557, 61785 ); + _DICT.put( 57558, 61786 ); + _DICT.put( 57559, 61787 ); + _DICT.put( 57560, 61788 ); + _DICT.put( 57561, 61789 ); + _DICT.put( 57562, 61790 ); + _DICT.put( 57563, 61791 ); + _DICT.put( 57564, 61792 ); + _DICT.put( 57565, 61793 ); + _DICT.put( 57566, 61794 ); + _DICT.put( 57567, 61795 ); + _DICT.put( 57568, 61796 ); + _DICT.put( 57569, 61797 ); + _DICT.put( 57570, 61798 ); + _DICT.put( 57571, 61799 ); + _DICT.put( 57572, 61800 ); + _DICT.put( 57573, 61801 ); + _DICT.put( 57574, 61802 ); + _DICT.put( 57575, 61803 ); + _DICT.put( 57576, 61804 ); + _DICT.put( 57577, 61805 ); + _DICT.put( 57578, 61806 ); + _DICT.put( 57579, 61807 ); + _DICT.put( 57580, 61808 ); + _DICT.put( 57581, 61809 ); + _DICT.put( 57582, 61810 ); + _DICT.put( 57583, 61811 ); + _DICT.put( 57584, 61812 ); + _DICT.put( 57585, 61813 ); + _DICT.put( 57586, 61814 ); + _DICT.put( 57587, 61815 ); + _DICT.put( 57588, 61816 ); + _DICT.put( 57589, 61817 ); + _DICT.put( 57590, 61818 ); + _DICT.put( 57591, 61819 ); + _DICT.put( 57592, 61820 ); + _DICT.put( 57593, 61821 ); + _DICT.put( 57594, 61822 ); + _DICT.put( 57595, 61824 ); + _DICT.put( 57596, 61825 ); + _DICT.put( 57597, 61826 ); + _DICT.put( 57598, 61827 ); + _DICT.put( 57599, 61828 ); + _DICT.put( 57600, 61829 ); + _DICT.put( 57601, 61830 ); + _DICT.put( 57602, 61831 ); + _DICT.put( 57603, 61832 ); + _DICT.put( 57604, 61833 ); + _DICT.put( 57605, 61834 ); + _DICT.put( 57606, 61835 ); + _DICT.put( 57607, 61836 ); + _DICT.put( 57608, 61837 ); + _DICT.put( 57609, 61838 ); + _DICT.put( 57610, 61839 ); + _DICT.put( 57611, 61840 ); + _DICT.put( 57612, 61841 ); + _DICT.put( 57613, 61842 ); + _DICT.put( 57614, 61843 ); + _DICT.put( 57615, 61844 ); + _DICT.put( 57616, 61845 ); + _DICT.put( 57617, 61846 ); + _DICT.put( 57618, 61847 ); + _DICT.put( 57619, 61848 ); + _DICT.put( 57620, 61849 ); + _DICT.put( 57621, 61850 ); + _DICT.put( 57622, 61851 ); + _DICT.put( 57623, 61852 ); + _DICT.put( 57624, 61853 ); + _DICT.put( 57625, 61854 ); + _DICT.put( 57626, 61855 ); + _DICT.put( 57627, 61856 ); + _DICT.put( 57628, 61857 ); + _DICT.put( 57629, 61858 ); + _DICT.put( 57630, 61859 ); + _DICT.put( 57631, 61860 ); + _DICT.put( 57632, 61861 ); + _DICT.put( 57633, 61862 ); + _DICT.put( 57634, 61863 ); + _DICT.put( 57635, 61864 ); + _DICT.put( 57636, 61865 ); + _DICT.put( 57637, 61866 ); + _DICT.put( 57638, 61867 ); + _DICT.put( 57639, 61868 ); + _DICT.put( 57640, 61869 ); + _DICT.put( 57641, 61870 ); + _DICT.put( 57642, 61871 ); + _DICT.put( 57643, 61872 ); + _DICT.put( 57644, 61873 ); + _DICT.put( 57645, 61874 ); + _DICT.put( 57646, 61875 ); + _DICT.put( 57647, 61876 ); + _DICT.put( 57648, 61877 ); + _DICT.put( 57649, 61878 ); + _DICT.put( 57650, 61879 ); + _DICT.put( 57651, 61880 ); + _DICT.put( 57652, 61881 ); + _DICT.put( 57653, 61882 ); + _DICT.put( 57654, 61883 ); + _DICT.put( 57655, 61884 ); + _DICT.put( 57656, 61885 ); + _DICT.put( 57657, 61886 ); + _DICT.put( 57658, 61887 ); + _DICT.put( 57659, 61888 ); + _DICT.put( 57660, 61889 ); + _DICT.put( 57661, 61890 ); + _DICT.put( 57662, 61891 ); + _DICT.put( 57663, 61892 ); + _DICT.put( 57664, 61893 ); + _DICT.put( 57665, 61894 ); + _DICT.put( 57666, 61895 ); + _DICT.put( 57667, 61896 ); + _DICT.put( 57668, 61897 ); + _DICT.put( 57669, 61898 ); + _DICT.put( 57670, 61899 ); + _DICT.put( 57671, 61900 ); + _DICT.put( 57672, 61901 ); + _DICT.put( 57673, 61902 ); + _DICT.put( 57674, 61903 ); + _DICT.put( 57675, 61904 ); + _DICT.put( 57676, 61905 ); + _DICT.put( 57677, 61906 ); + _DICT.put( 57678, 61907 ); + _DICT.put( 57679, 61908 ); + _DICT.put( 57680, 61909 ); + _DICT.put( 57681, 61910 ); + _DICT.put( 57682, 61911 ); + _DICT.put( 57683, 61912 ); + _DICT.put( 57684, 61913 ); + _DICT.put( 57685, 61914 ); + _DICT.put( 57686, 61915 ); + _DICT.put( 57687, 61916 ); + _DICT.put( 57688, 61917 ); + _DICT.put( 57689, 61918 ); + _DICT.put( 57690, 61919 ); + _DICT.put( 57691, 61920 ); + _DICT.put( 57692, 61921 ); + _DICT.put( 57693, 61922 ); + _DICT.put( 57694, 61923 ); + _DICT.put( 57695, 61924 ); + _DICT.put( 57696, 61925 ); + _DICT.put( 57697, 61926 ); + _DICT.put( 57698, 61927 ); + _DICT.put( 57699, 61928 ); + _DICT.put( 57700, 61929 ); + _DICT.put( 57701, 61930 ); + _DICT.put( 57702, 61931 ); + _DICT.put( 57703, 61932 ); + _DICT.put( 57704, 61933 ); + _DICT.put( 57705, 61934 ); + _DICT.put( 57706, 61935 ); + _DICT.put( 57707, 61936 ); + _DICT.put( 57708, 61937 ); + _DICT.put( 57709, 61938 ); + _DICT.put( 57710, 61939 ); + _DICT.put( 57711, 61940 ); + _DICT.put( 57712, 61941 ); + _DICT.put( 57713, 61942 ); + _DICT.put( 57714, 61943 ); + _DICT.put( 57715, 61944 ); + _DICT.put( 57716, 61945 ); + _DICT.put( 57717, 61946 ); + _DICT.put( 57718, 61947 ); + _DICT.put( 57719, 61948 ); + _DICT.put( 57720, 62016 ); + _DICT.put( 57721, 62017 ); + _DICT.put( 57722, 62018 ); + _DICT.put( 57723, 62019 ); + _DICT.put( 57724, 62020 ); + _DICT.put( 57725, 62021 ); + _DICT.put( 57726, 62022 ); + _DICT.put( 57727, 62023 ); + _DICT.put( 57728, 62024 ); + _DICT.put( 57729, 62025 ); + _DICT.put( 57730, 62026 ); + _DICT.put( 57731, 62027 ); + _DICT.put( 57732, 62028 ); + _DICT.put( 57733, 62029 ); + _DICT.put( 57734, 62030 ); + _DICT.put( 57735, 62031 ); + _DICT.put( 57736, 62032 ); + _DICT.put( 57737, 62033 ); + _DICT.put( 57738, 62034 ); + _DICT.put( 57739, 62035 ); + _DICT.put( 57740, 62036 ); + _DICT.put( 57741, 62037 ); + _DICT.put( 57742, 62038 ); + _DICT.put( 57743, 62039 ); + _DICT.put( 57744, 62040 ); + _DICT.put( 57745, 62041 ); + _DICT.put( 57746, 62042 ); + _DICT.put( 57747, 62043 ); + _DICT.put( 57748, 62044 ); + _DICT.put( 57749, 62045 ); + _DICT.put( 57750, 62046 ); + _DICT.put( 57751, 62047 ); + _DICT.put( 57752, 62048 ); + _DICT.put( 57753, 62049 ); + _DICT.put( 57754, 62050 ); + _DICT.put( 57755, 62051 ); + _DICT.put( 57756, 62052 ); + _DICT.put( 57757, 62053 ); + _DICT.put( 57758, 62054 ); + _DICT.put( 57759, 62055 ); + _DICT.put( 57760, 62056 ); + _DICT.put( 57761, 62057 ); + _DICT.put( 57762, 62058 ); + _DICT.put( 57763, 62059 ); + _DICT.put( 57764, 62060 ); + _DICT.put( 57765, 62061 ); + _DICT.put( 57766, 62062 ); + _DICT.put( 57767, 62063 ); + _DICT.put( 57768, 62064 ); + _DICT.put( 57769, 62065 ); + _DICT.put( 57770, 62066 ); + _DICT.put( 57771, 62067 ); + _DICT.put( 57772, 62068 ); + _DICT.put( 57773, 62069 ); + _DICT.put( 57774, 62070 ); + _DICT.put( 57775, 62071 ); + _DICT.put( 57776, 62072 ); + _DICT.put( 57777, 62073 ); + _DICT.put( 57778, 62074 ); + _DICT.put( 57779, 62075 ); + _DICT.put( 57780, 62076 ); + _DICT.put( 57781, 62077 ); + _DICT.put( 57782, 62078 ); + _DICT.put( 57783, 62080 ); + _DICT.put( 57784, 62081 ); + _DICT.put( 57785, 62082 ); + _DICT.put( 57786, 62083 ); + _DICT.put( 57787, 62084 ); + _DICT.put( 57788, 62085 ); + _DICT.put( 57789, 62086 ); + _DICT.put( 57790, 62087 ); + _DICT.put( 57791, 62088 ); + _DICT.put( 57792, 62089 ); + _DICT.put( 57793, 62090 ); + _DICT.put( 57794, 62091 ); + _DICT.put( 57795, 62092 ); + _DICT.put( 57796, 62093 ); + _DICT.put( 57797, 62094 ); + _DICT.put( 57798, 62095 ); + _DICT.put( 57799, 62096 ); + _DICT.put( 57800, 62097 ); + _DICT.put( 57801, 62098 ); + _DICT.put( 57802, 62099 ); + _DICT.put( 57803, 62100 ); + _DICT.put( 57804, 62101 ); + _DICT.put( 57805, 62102 ); + _DICT.put( 57806, 62103 ); + _DICT.put( 57807, 62104 ); + _DICT.put( 57808, 62105 ); + _DICT.put( 57809, 62106 ); + _DICT.put( 57810, 62107 ); + _DICT.put( 57811, 62108 ); + _DICT.put( 57812, 62109 ); + _DICT.put( 57813, 62110 ); + _DICT.put( 57814, 62111 ); + _DICT.put( 57815, 62112 ); + _DICT.put( 57816, 62113 ); + _DICT.put( 57817, 62114 ); + _DICT.put( 57818, 62115 ); + _DICT.put( 57819, 62116 ); + _DICT.put( 57820, 62117 ); + _DICT.put( 57821, 62118 ); + _DICT.put( 57822, 62119 ); + _DICT.put( 57823, 62120 ); + _DICT.put( 57824, 62121 ); + _DICT.put( 57825, 62122 ); + _DICT.put( 57826, 62123 ); + _DICT.put( 57827, 62124 ); + _DICT.put( 57828, 62125 ); + _DICT.put( 57829, 62126 ); + _DICT.put( 57830, 62127 ); + _DICT.put( 57831, 62128 ); + _DICT.put( 57832, 62129 ); + _DICT.put( 57833, 62130 ); + _DICT.put( 57834, 62131 ); + _DICT.put( 57835, 62132 ); + _DICT.put( 57836, 62133 ); + _DICT.put( 57837, 62134 ); + _DICT.put( 57838, 62135 ); + _DICT.put( 57839, 62136 ); + _DICT.put( 57840, 62137 ); + _DICT.put( 57841, 62138 ); + _DICT.put( 57842, 62139 ); + _DICT.put( 57843, 62140 ); + _DICT.put( 57844, 62141 ); + _DICT.put( 57845, 62142 ); + _DICT.put( 57846, 62143 ); + _DICT.put( 57847, 62144 ); + _DICT.put( 57848, 62145 ); + _DICT.put( 57849, 62146 ); + _DICT.put( 57850, 62147 ); + _DICT.put( 57851, 62148 ); + _DICT.put( 57852, 62149 ); + _DICT.put( 57853, 62150 ); + _DICT.put( 57854, 62151 ); + _DICT.put( 57855, 62152 ); + _DICT.put( 57856, 62153 ); + _DICT.put( 57857, 62154 ); + _DICT.put( 57858, 62155 ); + _DICT.put( 57859, 62156 ); + _DICT.put( 57860, 62157 ); + _DICT.put( 57861, 62158 ); + _DICT.put( 57862, 62159 ); + _DICT.put( 57863, 62160 ); + _DICT.put( 57864, 62161 ); + _DICT.put( 57865, 62162 ); + _DICT.put( 57866, 62163 ); + _DICT.put( 57867, 62164 ); + _DICT.put( 57868, 62165 ); + _DICT.put( 57869, 62166 ); + _DICT.put( 57870, 62167 ); + _DICT.put( 57871, 62168 ); + _DICT.put( 57872, 62169 ); + _DICT.put( 57873, 62170 ); + _DICT.put( 57874, 62171 ); + _DICT.put( 57875, 62172 ); + _DICT.put( 57876, 62173 ); + _DICT.put( 57877, 62174 ); + _DICT.put( 57878, 62175 ); + _DICT.put( 57879, 62176 ); + _DICT.put( 57880, 62177 ); + _DICT.put( 57881, 62178 ); + _DICT.put( 57882, 62179 ); + _DICT.put( 57883, 62180 ); + _DICT.put( 57884, 62181 ); + _DICT.put( 57885, 62182 ); + _DICT.put( 57886, 62183 ); + _DICT.put( 57887, 62184 ); + _DICT.put( 57888, 62185 ); + _DICT.put( 57889, 62186 ); + _DICT.put( 57890, 62187 ); + _DICT.put( 57891, 62188 ); + _DICT.put( 57892, 62189 ); + _DICT.put( 57893, 62190 ); + _DICT.put( 57894, 62191 ); + _DICT.put( 57895, 62192 ); + _DICT.put( 57896, 62193 ); + _DICT.put( 57897, 62194 ); + _DICT.put( 57898, 62195 ); + _DICT.put( 57899, 62196 ); + _DICT.put( 57900, 62197 ); + _DICT.put( 57901, 62198 ); + _DICT.put( 57902, 62199 ); + _DICT.put( 57903, 62200 ); + _DICT.put( 57904, 62201 ); + _DICT.put( 57905, 62202 ); + _DICT.put( 57906, 62203 ); + _DICT.put( 57907, 62204 ); + _DICT.put( 57908, 62272 ); + _DICT.put( 57909, 62273 ); + _DICT.put( 57910, 62274 ); + _DICT.put( 57911, 62275 ); + _DICT.put( 57912, 62276 ); + _DICT.put( 57913, 62277 ); + _DICT.put( 57914, 62278 ); + _DICT.put( 57915, 62279 ); + _DICT.put( 57916, 62280 ); + _DICT.put( 57917, 62281 ); + _DICT.put( 57918, 62282 ); + _DICT.put( 57919, 62283 ); + _DICT.put( 57920, 62284 ); + _DICT.put( 57921, 62285 ); + _DICT.put( 57922, 62286 ); + _DICT.put( 57923, 62287 ); + _DICT.put( 57924, 62288 ); + _DICT.put( 57925, 62289 ); + _DICT.put( 57926, 62290 ); + _DICT.put( 57927, 62291 ); + _DICT.put( 57928, 62292 ); + _DICT.put( 57929, 62293 ); + _DICT.put( 57930, 62294 ); + _DICT.put( 57931, 62295 ); + _DICT.put( 57932, 62296 ); + _DICT.put( 57933, 62297 ); + _DICT.put( 57934, 62298 ); + _DICT.put( 57935, 62299 ); + _DICT.put( 57936, 62300 ); + _DICT.put( 57937, 62301 ); + _DICT.put( 57938, 62302 ); + _DICT.put( 57939, 62303 ); + _DICT.put( 57940, 62304 ); + _DICT.put( 57941, 62305 ); + _DICT.put( 57942, 62306 ); + _DICT.put( 57943, 62307 ); + _DICT.put( 57944, 62308 ); + _DICT.put( 57945, 62309 ); + _DICT.put( 57946, 62310 ); + _DICT.put( 57947, 62311 ); + _DICT.put( 57948, 62312 ); + _DICT.put( 57949, 62313 ); + _DICT.put( 57950, 62314 ); + _DICT.put( 57951, 62315 ); + _DICT.put( 57952, 62316 ); + _DICT.put( 57953, 62317 ); + _DICT.put( 57954, 62318 ); + _DICT.put( 57955, 62319 ); + _DICT.put( 57956, 62320 ); + _DICT.put( 57957, 62321 ); + _DICT.put( 57958, 62322 ); + _DICT.put( 57959, 62323 ); + _DICT.put( 57960, 62324 ); + _DICT.put( 57961, 62325 ); + _DICT.put( 57962, 62326 ); + _DICT.put( 57963, 62327 ); + _DICT.put( 57964, 62328 ); + _DICT.put( 57965, 62329 ); + _DICT.put( 57966, 62330 ); + _DICT.put( 57967, 62331 ); + _DICT.put( 57968, 62332 ); + _DICT.put( 57969, 62333 ); + _DICT.put( 57970, 62334 ); + _DICT.put( 57971, 62336 ); + _DICT.put( 57972, 62337 ); + _DICT.put( 57973, 62338 ); + _DICT.put( 57974, 62339 ); + _DICT.put( 57975, 62340 ); + _DICT.put( 57976, 62341 ); + _DICT.put( 57977, 62342 ); + _DICT.put( 57978, 62343 ); + _DICT.put( 57979, 62344 ); + _DICT.put( 57980, 62345 ); + _DICT.put( 57981, 62346 ); + _DICT.put( 57982, 62347 ); + _DICT.put( 57983, 62348 ); + _DICT.put( 57984, 62349 ); + _DICT.put( 57985, 62350 ); + _DICT.put( 57986, 62351 ); + _DICT.put( 57987, 62352 ); + _DICT.put( 57988, 62353 ); + _DICT.put( 57989, 62354 ); + _DICT.put( 57990, 62355 ); + _DICT.put( 57991, 62356 ); + _DICT.put( 57992, 62357 ); + _DICT.put( 57993, 62358 ); + _DICT.put( 57994, 62359 ); + _DICT.put( 57995, 62360 ); + _DICT.put( 57996, 62361 ); + _DICT.put( 57997, 62362 ); + _DICT.put( 57998, 62363 ); + _DICT.put( 57999, 62364 ); + _DICT.put( 58000, 62365 ); + _DICT.put( 58001, 62366 ); + _DICT.put( 58002, 62367 ); + _DICT.put( 58003, 62368 ); + _DICT.put( 58004, 62369 ); + _DICT.put( 58005, 62370 ); + _DICT.put( 58006, 62371 ); + _DICT.put( 58007, 62372 ); + _DICT.put( 58008, 62373 ); + _DICT.put( 58009, 62374 ); + _DICT.put( 58010, 62375 ); + _DICT.put( 58011, 62376 ); + _DICT.put( 58012, 62377 ); + _DICT.put( 58013, 62378 ); + _DICT.put( 58014, 62379 ); + _DICT.put( 58015, 62380 ); + _DICT.put( 58016, 62381 ); + _DICT.put( 58017, 62382 ); + _DICT.put( 58018, 62383 ); + _DICT.put( 58019, 62384 ); + _DICT.put( 58020, 62385 ); + _DICT.put( 58021, 62386 ); + _DICT.put( 58022, 62387 ); + _DICT.put( 58023, 62388 ); + _DICT.put( 58024, 62389 ); + _DICT.put( 58025, 62390 ); + _DICT.put( 58026, 62391 ); + _DICT.put( 58027, 62392 ); + _DICT.put( 58028, 62393 ); + _DICT.put( 58029, 62394 ); + _DICT.put( 58030, 62395 ); + _DICT.put( 58031, 62396 ); + _DICT.put( 58032, 62397 ); + _DICT.put( 58033, 62398 ); + _DICT.put( 58034, 62399 ); + _DICT.put( 58035, 62400 ); + _DICT.put( 58036, 62401 ); + _DICT.put( 58037, 62402 ); + _DICT.put( 58038, 62403 ); + _DICT.put( 58039, 62404 ); + _DICT.put( 58040, 62405 ); + _DICT.put( 58041, 62406 ); + _DICT.put( 58042, 62407 ); + _DICT.put( 58043, 62408 ); + _DICT.put( 58044, 62409 ); + _DICT.put( 58045, 62410 ); + _DICT.put( 58046, 62411 ); + _DICT.put( 58047, 62412 ); + _DICT.put( 58048, 62413 ); + _DICT.put( 58049, 62414 ); + _DICT.put( 58050, 62415 ); + _DICT.put( 58051, 62416 ); + _DICT.put( 58052, 62417 ); + _DICT.put( 58053, 62418 ); + _DICT.put( 58054, 62419 ); + _DICT.put( 58055, 62420 ); + _DICT.put( 58056, 62421 ); + _DICT.put( 58057, 62422 ); + _DICT.put( 58058, 62423 ); + _DICT.put( 58059, 62424 ); + _DICT.put( 58060, 62425 ); + _DICT.put( 58061, 62426 ); + _DICT.put( 58062, 62427 ); + _DICT.put( 58063, 62428 ); + _DICT.put( 58064, 62429 ); + _DICT.put( 58065, 62430 ); + _DICT.put( 58066, 62431 ); + _DICT.put( 58067, 62432 ); + _DICT.put( 58068, 62433 ); + _DICT.put( 58069, 62434 ); + _DICT.put( 58070, 62435 ); + _DICT.put( 58071, 62436 ); + _DICT.put( 58072, 62437 ); + _DICT.put( 58073, 62438 ); + _DICT.put( 58074, 62439 ); + _DICT.put( 58075, 62440 ); + _DICT.put( 58076, 62441 ); + _DICT.put( 58077, 62442 ); + _DICT.put( 58078, 62443 ); + _DICT.put( 58079, 62444 ); + _DICT.put( 58080, 62445 ); + _DICT.put( 58081, 62446 ); + _DICT.put( 58082, 62447 ); + _DICT.put( 58083, 62448 ); + _DICT.put( 58084, 62449 ); + _DICT.put( 58085, 62450 ); + _DICT.put( 58086, 62451 ); + _DICT.put( 58087, 62452 ); + _DICT.put( 58088, 62453 ); + _DICT.put( 58089, 62454 ); + _DICT.put( 58090, 62455 ); + _DICT.put( 58091, 62456 ); + _DICT.put( 58092, 62457 ); + _DICT.put( 58093, 62458 ); + _DICT.put( 58094, 62459 ); + _DICT.put( 58095, 62460 ); + _DICT.put( 58096, 62528 ); + _DICT.put( 58097, 62529 ); + _DICT.put( 58098, 62530 ); + _DICT.put( 58099, 62531 ); + _DICT.put( 58100, 62532 ); + _DICT.put( 58101, 62533 ); + _DICT.put( 58102, 62534 ); + _DICT.put( 58103, 62535 ); + _DICT.put( 58104, 62536 ); + _DICT.put( 58105, 62537 ); + _DICT.put( 58106, 62538 ); + _DICT.put( 58107, 62539 ); + _DICT.put( 58108, 62540 ); + _DICT.put( 58109, 62541 ); + _DICT.put( 58110, 62542 ); + _DICT.put( 58111, 62543 ); + _DICT.put( 58112, 62544 ); + _DICT.put( 58113, 62545 ); + _DICT.put( 58114, 62546 ); + _DICT.put( 58115, 62547 ); + _DICT.put( 58116, 62548 ); + _DICT.put( 58117, 62549 ); + _DICT.put( 58118, 62550 ); + _DICT.put( 58119, 62551 ); + _DICT.put( 58120, 62552 ); + _DICT.put( 58121, 62553 ); + _DICT.put( 58122, 62554 ); + _DICT.put( 58123, 62555 ); + _DICT.put( 58124, 62556 ); + _DICT.put( 58125, 62557 ); + _DICT.put( 58126, 62558 ); + _DICT.put( 58127, 62559 ); + _DICT.put( 58128, 62560 ); + _DICT.put( 58129, 62561 ); + _DICT.put( 58130, 62562 ); + _DICT.put( 58131, 62563 ); + _DICT.put( 58132, 62564 ); + _DICT.put( 58133, 62565 ); + _DICT.put( 58134, 62566 ); + _DICT.put( 58135, 62567 ); + _DICT.put( 58136, 62568 ); + _DICT.put( 58137, 62569 ); + _DICT.put( 58138, 62570 ); + _DICT.put( 58139, 62571 ); + _DICT.put( 58140, 62572 ); + _DICT.put( 58141, 62573 ); + _DICT.put( 58142, 62574 ); + _DICT.put( 58143, 62575 ); + _DICT.put( 58144, 62576 ); + _DICT.put( 58145, 62577 ); + _DICT.put( 58146, 62578 ); + _DICT.put( 58147, 62579 ); + _DICT.put( 58148, 62580 ); + _DICT.put( 58149, 62581 ); + _DICT.put( 58150, 62582 ); + _DICT.put( 58151, 62583 ); + _DICT.put( 58152, 62584 ); + _DICT.put( 58153, 62585 ); + _DICT.put( 58154, 62586 ); + _DICT.put( 58155, 62587 ); + _DICT.put( 58156, 62588 ); + _DICT.put( 58157, 62589 ); + _DICT.put( 58158, 62590 ); + _DICT.put( 58159, 62592 ); + _DICT.put( 58160, 62593 ); + _DICT.put( 58161, 62594 ); + _DICT.put( 58162, 62595 ); + _DICT.put( 58163, 62596 ); + _DICT.put( 58164, 62597 ); + _DICT.put( 58165, 62598 ); + _DICT.put( 58166, 62599 ); + _DICT.put( 58167, 62600 ); + _DICT.put( 58168, 62601 ); + _DICT.put( 58169, 62602 ); + _DICT.put( 58170, 62603 ); + _DICT.put( 58171, 62604 ); + _DICT.put( 58172, 62605 ); + _DICT.put( 58173, 62606 ); + _DICT.put( 58174, 62607 ); + _DICT.put( 58175, 62608 ); + _DICT.put( 58176, 62609 ); + _DICT.put( 58177, 62610 ); + _DICT.put( 58178, 62611 ); + _DICT.put( 58179, 62612 ); + _DICT.put( 58180, 62613 ); + _DICT.put( 58181, 62614 ); + _DICT.put( 58182, 62615 ); + _DICT.put( 58183, 62616 ); + _DICT.put( 58184, 62617 ); + _DICT.put( 58185, 62618 ); + _DICT.put( 58186, 62619 ); + _DICT.put( 58187, 62620 ); + _DICT.put( 58188, 62621 ); + _DICT.put( 58189, 62622 ); + _DICT.put( 58190, 62623 ); + _DICT.put( 58191, 62624 ); + _DICT.put( 58192, 62625 ); + _DICT.put( 58193, 62626 ); + _DICT.put( 58194, 62627 ); + _DICT.put( 58195, 62628 ); + _DICT.put( 58196, 62629 ); + _DICT.put( 58197, 62630 ); + _DICT.put( 58198, 62631 ); + _DICT.put( 58199, 62632 ); + _DICT.put( 58200, 62633 ); + _DICT.put( 58201, 62634 ); + _DICT.put( 58202, 62635 ); + _DICT.put( 58203, 62636 ); + _DICT.put( 58204, 62637 ); + _DICT.put( 58205, 62638 ); + _DICT.put( 58206, 62639 ); + _DICT.put( 58207, 62640 ); + _DICT.put( 58208, 62641 ); + _DICT.put( 58209, 62642 ); + _DICT.put( 58210, 62643 ); + _DICT.put( 58211, 62644 ); + _DICT.put( 58212, 62645 ); + _DICT.put( 58213, 62646 ); + _DICT.put( 58214, 62647 ); + _DICT.put( 58215, 62648 ); + _DICT.put( 58216, 62649 ); + _DICT.put( 58217, 62650 ); + _DICT.put( 58218, 62651 ); + _DICT.put( 58219, 62652 ); + _DICT.put( 58220, 62653 ); + _DICT.put( 58221, 62654 ); + _DICT.put( 58222, 62655 ); + _DICT.put( 58223, 62656 ); + _DICT.put( 58224, 62657 ); + _DICT.put( 58225, 62658 ); + _DICT.put( 58226, 62659 ); + _DICT.put( 58227, 62660 ); + _DICT.put( 58228, 62661 ); + _DICT.put( 58229, 62662 ); + _DICT.put( 58230, 62663 ); + _DICT.put( 58231, 62664 ); + _DICT.put( 58232, 62665 ); + _DICT.put( 58233, 62666 ); + _DICT.put( 58234, 62667 ); + _DICT.put( 58235, 62668 ); + _DICT.put( 58236, 62669 ); + _DICT.put( 58237, 62670 ); + _DICT.put( 58238, 62671 ); + _DICT.put( 58239, 62672 ); + _DICT.put( 58240, 62673 ); + _DICT.put( 58241, 62674 ); + _DICT.put( 58242, 62675 ); + _DICT.put( 58243, 62676 ); + _DICT.put( 58244, 62677 ); + _DICT.put( 58245, 62678 ); + _DICT.put( 58246, 62679 ); + _DICT.put( 58247, 62680 ); + _DICT.put( 58248, 62681 ); + _DICT.put( 58249, 62682 ); + _DICT.put( 58250, 62683 ); + _DICT.put( 58251, 62684 ); + _DICT.put( 58252, 62685 ); + _DICT.put( 58253, 62686 ); + _DICT.put( 58254, 62687 ); + _DICT.put( 58255, 62688 ); + _DICT.put( 58256, 62689 ); + _DICT.put( 58257, 62690 ); + _DICT.put( 58258, 62691 ); + _DICT.put( 58259, 62692 ); + _DICT.put( 58260, 62693 ); + _DICT.put( 58261, 62694 ); + _DICT.put( 58262, 62695 ); + _DICT.put( 58263, 62696 ); + _DICT.put( 58264, 62697 ); + _DICT.put( 58265, 62698 ); + _DICT.put( 58266, 62699 ); + _DICT.put( 58267, 62700 ); + _DICT.put( 58268, 62701 ); + _DICT.put( 58269, 62702 ); + _DICT.put( 58270, 62703 ); + _DICT.put( 58271, 62704 ); + _DICT.put( 58272, 62705 ); + _DICT.put( 58273, 62706 ); + _DICT.put( 58274, 62707 ); + _DICT.put( 58275, 62708 ); + _DICT.put( 58276, 62709 ); + _DICT.put( 58277, 62710 ); + _DICT.put( 58278, 62711 ); + _DICT.put( 58279, 62712 ); + _DICT.put( 58280, 62713 ); + _DICT.put( 58281, 62714 ); + _DICT.put( 58282, 62715 ); + _DICT.put( 58283, 62716 ); + _DICT.put( 58284, 62784 ); + _DICT.put( 58285, 62785 ); + _DICT.put( 58286, 62786 ); + _DICT.put( 58287, 62787 ); + _DICT.put( 58288, 62788 ); + _DICT.put( 58289, 62789 ); + _DICT.put( 58290, 62790 ); + _DICT.put( 58291, 62791 ); + _DICT.put( 58292, 62792 ); + _DICT.put( 58293, 62793 ); + _DICT.put( 58294, 62794 ); + _DICT.put( 58295, 62795 ); + _DICT.put( 58296, 62796 ); + _DICT.put( 58297, 62797 ); + _DICT.put( 58298, 62798 ); + _DICT.put( 58299, 62799 ); + _DICT.put( 58300, 62800 ); + _DICT.put( 58301, 62801 ); + _DICT.put( 58302, 62802 ); + _DICT.put( 58303, 62803 ); + _DICT.put( 58304, 62804 ); + _DICT.put( 58305, 62805 ); + _DICT.put( 58306, 62806 ); + _DICT.put( 58307, 62807 ); + _DICT.put( 58308, 62808 ); + _DICT.put( 58309, 62809 ); + _DICT.put( 58310, 62810 ); + _DICT.put( 58311, 62811 ); + _DICT.put( 58312, 62812 ); + _DICT.put( 58313, 62813 ); + _DICT.put( 58314, 62814 ); + _DICT.put( 58315, 62815 ); + _DICT.put( 58316, 62816 ); + _DICT.put( 58317, 62817 ); + _DICT.put( 58318, 62818 ); + _DICT.put( 58319, 62819 ); + _DICT.put( 58320, 62820 ); + _DICT.put( 58321, 62821 ); + _DICT.put( 58322, 62822 ); + _DICT.put( 58323, 62823 ); + _DICT.put( 58324, 62824 ); + _DICT.put( 58325, 62825 ); + _DICT.put( 58326, 62826 ); + _DICT.put( 58327, 62827 ); + _DICT.put( 58328, 62828 ); + _DICT.put( 58329, 62829 ); + _DICT.put( 58330, 62830 ); + _DICT.put( 58331, 62831 ); + _DICT.put( 58332, 62832 ); + _DICT.put( 58333, 62833 ); + _DICT.put( 58334, 62834 ); + _DICT.put( 58335, 62835 ); + _DICT.put( 58336, 62836 ); + _DICT.put( 58337, 62837 ); + _DICT.put( 58338, 62838 ); + _DICT.put( 58339, 62839 ); + _DICT.put( 58340, 62840 ); + _DICT.put( 58341, 62841 ); + _DICT.put( 58342, 62842 ); + _DICT.put( 58343, 62843 ); + _DICT.put( 58344, 62844 ); + _DICT.put( 58345, 62845 ); + _DICT.put( 58346, 62846 ); + _DICT.put( 58347, 62848 ); + _DICT.put( 58348, 62849 ); + _DICT.put( 58349, 62850 ); + _DICT.put( 58350, 62851 ); + _DICT.put( 58351, 62852 ); + _DICT.put( 58352, 62853 ); + _DICT.put( 58353, 62854 ); + _DICT.put( 58354, 62855 ); + _DICT.put( 58355, 62856 ); + _DICT.put( 58356, 62857 ); + _DICT.put( 58357, 62858 ); + _DICT.put( 58358, 62859 ); + _DICT.put( 58359, 62860 ); + _DICT.put( 58360, 62861 ); + _DICT.put( 58361, 62862 ); + _DICT.put( 58362, 62863 ); + _DICT.put( 58363, 62864 ); + _DICT.put( 58364, 62865 ); + _DICT.put( 58365, 62866 ); + _DICT.put( 58366, 62867 ); + _DICT.put( 58367, 62868 ); + _DICT.put( 58368, 62869 ); + _DICT.put( 58369, 62870 ); + _DICT.put( 58370, 62871 ); + _DICT.put( 58371, 62872 ); + _DICT.put( 58372, 62873 ); + _DICT.put( 58373, 62874 ); + _DICT.put( 58374, 62875 ); + _DICT.put( 58375, 62876 ); + _DICT.put( 58376, 62877 ); + _DICT.put( 58377, 62878 ); + _DICT.put( 58378, 62879 ); + _DICT.put( 58379, 62880 ); + _DICT.put( 58380, 62881 ); + _DICT.put( 58381, 62882 ); + _DICT.put( 58382, 62883 ); + _DICT.put( 58383, 62884 ); + _DICT.put( 58384, 62885 ); + _DICT.put( 58385, 62886 ); + _DICT.put( 58386, 62887 ); + _DICT.put( 58387, 62888 ); + _DICT.put( 58388, 62889 ); + _DICT.put( 58389, 62890 ); + _DICT.put( 58390, 62891 ); + _DICT.put( 58391, 62892 ); + _DICT.put( 58392, 62893 ); + _DICT.put( 58393, 62894 ); + _DICT.put( 58394, 62895 ); + _DICT.put( 58395, 62896 ); + _DICT.put( 58396, 62897 ); + _DICT.put( 58397, 62898 ); + _DICT.put( 58398, 62899 ); + _DICT.put( 58399, 62900 ); + _DICT.put( 58400, 62901 ); + _DICT.put( 58401, 62902 ); + _DICT.put( 58402, 62903 ); + _DICT.put( 58403, 62904 ); + _DICT.put( 58404, 62905 ); + _DICT.put( 58405, 62906 ); + _DICT.put( 58406, 62907 ); + _DICT.put( 58407, 62908 ); + _DICT.put( 58408, 62909 ); + _DICT.put( 58409, 62910 ); + _DICT.put( 58410, 62911 ); + _DICT.put( 58411, 62912 ); + _DICT.put( 58412, 62913 ); + _DICT.put( 58413, 62914 ); + _DICT.put( 58414, 62915 ); + _DICT.put( 58415, 62916 ); + _DICT.put( 58416, 62917 ); + _DICT.put( 58417, 62918 ); + _DICT.put( 58418, 62919 ); + _DICT.put( 58419, 62920 ); + _DICT.put( 58420, 62921 ); + _DICT.put( 58421, 62922 ); + _DICT.put( 58422, 62923 ); + _DICT.put( 58423, 62924 ); + _DICT.put( 58424, 62925 ); + _DICT.put( 58425, 62926 ); + _DICT.put( 58426, 62927 ); + _DICT.put( 58427, 62928 ); + _DICT.put( 58428, 62929 ); + _DICT.put( 58429, 62930 ); + _DICT.put( 58430, 62931 ); + _DICT.put( 58431, 62932 ); + _DICT.put( 58432, 62933 ); + _DICT.put( 58433, 62934 ); + _DICT.put( 58434, 62935 ); + _DICT.put( 58435, 62936 ); + _DICT.put( 58436, 62937 ); + _DICT.put( 58437, 62938 ); + _DICT.put( 58438, 62939 ); + _DICT.put( 58439, 62940 ); + _DICT.put( 58440, 62941 ); + _DICT.put( 58441, 62942 ); + _DICT.put( 58442, 62943 ); + _DICT.put( 58443, 62944 ); + _DICT.put( 58444, 62945 ); + _DICT.put( 58445, 62946 ); + _DICT.put( 58446, 62947 ); + _DICT.put( 58447, 62948 ); + _DICT.put( 58448, 62949 ); + _DICT.put( 58449, 62950 ); + _DICT.put( 58450, 62951 ); + _DICT.put( 58451, 62952 ); + _DICT.put( 58452, 62953 ); + _DICT.put( 58453, 62954 ); + _DICT.put( 58454, 62955 ); + _DICT.put( 58455, 62956 ); + _DICT.put( 58456, 62957 ); + _DICT.put( 58457, 62958 ); + _DICT.put( 58458, 62959 ); + _DICT.put( 58459, 62960 ); + _DICT.put( 58460, 62961 ); + _DICT.put( 58461, 62962 ); + _DICT.put( 58462, 62963 ); + _DICT.put( 58463, 62964 ); + _DICT.put( 58464, 62965 ); + _DICT.put( 58465, 62966 ); + _DICT.put( 58466, 62967 ); + _DICT.put( 58467, 62968 ); + _DICT.put( 58468, 62969 ); + _DICT.put( 58469, 62970 ); + _DICT.put( 58470, 62971 ); + _DICT.put( 58471, 62972 ); + _DICT.put( 58472, 63040 ); + _DICT.put( 58473, 63041 ); + _DICT.put( 58474, 63042 ); + _DICT.put( 58475, 63043 ); + _DICT.put( 58476, 63044 ); + _DICT.put( 58477, 63045 ); + _DICT.put( 58478, 63046 ); + _DICT.put( 58479, 63047 ); + _DICT.put( 58480, 63048 ); + _DICT.put( 58481, 63049 ); + _DICT.put( 58482, 63050 ); + _DICT.put( 58483, 63051 ); + _DICT.put( 58484, 63052 ); + _DICT.put( 58485, 63053 ); + _DICT.put( 58486, 63054 ); + _DICT.put( 58487, 63055 ); + _DICT.put( 58488, 63056 ); + _DICT.put( 58489, 63057 ); + _DICT.put( 58490, 63058 ); + _DICT.put( 58491, 63059 ); + _DICT.put( 58492, 63060 ); + _DICT.put( 58493, 63061 ); + _DICT.put( 58494, 63062 ); + _DICT.put( 58495, 63063 ); + _DICT.put( 58496, 63064 ); + _DICT.put( 58497, 63065 ); + _DICT.put( 58498, 63066 ); + _DICT.put( 58499, 63067 ); + _DICT.put( 58500, 63068 ); + _DICT.put( 58501, 63069 ); + _DICT.put( 58502, 63070 ); + _DICT.put( 58503, 63071 ); + _DICT.put( 58504, 63072 ); + _DICT.put( 58505, 63073 ); + _DICT.put( 58506, 63074 ); + _DICT.put( 58507, 63075 ); + _DICT.put( 58508, 63076 ); + _DICT.put( 58509, 63077 ); + _DICT.put( 58510, 63078 ); + _DICT.put( 58511, 63079 ); + _DICT.put( 58512, 63080 ); + _DICT.put( 58513, 63081 ); + _DICT.put( 58514, 63082 ); + _DICT.put( 58515, 63083 ); + _DICT.put( 58516, 63084 ); + _DICT.put( 58517, 63085 ); + _DICT.put( 58518, 63086 ); + _DICT.put( 58519, 63087 ); + _DICT.put( 58520, 63088 ); + _DICT.put( 58521, 63089 ); + _DICT.put( 58522, 63090 ); + _DICT.put( 58523, 63091 ); + _DICT.put( 58524, 63092 ); + _DICT.put( 58525, 63093 ); + _DICT.put( 58526, 63094 ); + _DICT.put( 58527, 63095 ); + _DICT.put( 58528, 63096 ); + _DICT.put( 58529, 63097 ); + _DICT.put( 58530, 63098 ); + _DICT.put( 58531, 63099 ); + _DICT.put( 58532, 63100 ); + _DICT.put( 58533, 63101 ); + _DICT.put( 58534, 63102 ); + _DICT.put( 58535, 63104 ); + _DICT.put( 58536, 63105 ); + _DICT.put( 58537, 63106 ); + _DICT.put( 58538, 63107 ); + _DICT.put( 58539, 63108 ); + _DICT.put( 58540, 63109 ); + _DICT.put( 58541, 63110 ); + _DICT.put( 58542, 63111 ); + _DICT.put( 58543, 63112 ); + _DICT.put( 58544, 63113 ); + _DICT.put( 58545, 63114 ); + _DICT.put( 58546, 63115 ); + _DICT.put( 58547, 63116 ); + _DICT.put( 58548, 63117 ); + _DICT.put( 58549, 63118 ); + _DICT.put( 58550, 63119 ); + _DICT.put( 58551, 63120 ); + _DICT.put( 58552, 63121 ); + _DICT.put( 58553, 63122 ); + _DICT.put( 58554, 63123 ); + _DICT.put( 58555, 63124 ); + _DICT.put( 58556, 63125 ); + _DICT.put( 58557, 63126 ); + _DICT.put( 58558, 63127 ); + _DICT.put( 58559, 63128 ); + _DICT.put( 58560, 63129 ); + _DICT.put( 58561, 63130 ); + _DICT.put( 58562, 63131 ); + _DICT.put( 58563, 63132 ); + _DICT.put( 58564, 63133 ); + _DICT.put( 58565, 63134 ); + _DICT.put( 58566, 63135 ); + _DICT.put( 58567, 63136 ); + _DICT.put( 58568, 63137 ); + _DICT.put( 58569, 63138 ); + _DICT.put( 58570, 63139 ); + _DICT.put( 58571, 63140 ); + _DICT.put( 58572, 63141 ); + _DICT.put( 58573, 63142 ); + _DICT.put( 58574, 63143 ); + _DICT.put( 58575, 63144 ); + _DICT.put( 58576, 63145 ); + _DICT.put( 58577, 63146 ); + _DICT.put( 58578, 63147 ); + _DICT.put( 58579, 63148 ); + _DICT.put( 58580, 63149 ); + _DICT.put( 58581, 63150 ); + _DICT.put( 58582, 63151 ); + _DICT.put( 58583, 63152 ); + _DICT.put( 58584, 63153 ); + _DICT.put( 58585, 63154 ); + _DICT.put( 58586, 63155 ); + _DICT.put( 58587, 63156 ); + _DICT.put( 58588, 63157 ); + _DICT.put( 58589, 63158 ); + _DICT.put( 58590, 63159 ); + _DICT.put( 58591, 63160 ); + _DICT.put( 58592, 63161 ); + _DICT.put( 58593, 63162 ); + _DICT.put( 58594, 63163 ); + _DICT.put( 58595, 63164 ); + _DICT.put( 58596, 63165 ); + _DICT.put( 58597, 63166 ); + _DICT.put( 58598, 63167 ); + _DICT.put( 58599, 63168 ); + _DICT.put( 58600, 63169 ); + _DICT.put( 58601, 63170 ); + _DICT.put( 58602, 63171 ); + _DICT.put( 58603, 63172 ); + _DICT.put( 58604, 63173 ); + _DICT.put( 58605, 63174 ); + _DICT.put( 58606, 63175 ); + _DICT.put( 58607, 63176 ); + _DICT.put( 58608, 63177 ); + _DICT.put( 58609, 63178 ); + _DICT.put( 58610, 63179 ); + _DICT.put( 58611, 63180 ); + _DICT.put( 58612, 63181 ); + _DICT.put( 58613, 63182 ); + _DICT.put( 58614, 63183 ); + _DICT.put( 58615, 63184 ); + _DICT.put( 58616, 63185 ); + _DICT.put( 58617, 63186 ); + _DICT.put( 58618, 63187 ); + _DICT.put( 58619, 63188 ); + _DICT.put( 58620, 63189 ); + _DICT.put( 58621, 63190 ); + _DICT.put( 58622, 63191 ); + _DICT.put( 58623, 63192 ); + _DICT.put( 58624, 63193 ); + _DICT.put( 58625, 63194 ); + _DICT.put( 58626, 63195 ); + _DICT.put( 58627, 63196 ); + _DICT.put( 58628, 63197 ); + _DICT.put( 58629, 63198 ); + _DICT.put( 58630, 63199 ); + _DICT.put( 58631, 63200 ); + _DICT.put( 58632, 63201 ); + _DICT.put( 58633, 63202 ); + _DICT.put( 58634, 63203 ); + _DICT.put( 58635, 63204 ); + _DICT.put( 58636, 63205 ); + _DICT.put( 58637, 63206 ); + _DICT.put( 58638, 63207 ); + _DICT.put( 58639, 63208 ); + _DICT.put( 58640, 63209 ); + _DICT.put( 58641, 63210 ); + _DICT.put( 58642, 63211 ); + _DICT.put( 58643, 63212 ); + _DICT.put( 58644, 63213 ); + _DICT.put( 58645, 63214 ); + _DICT.put( 58646, 63215 ); + _DICT.put( 58647, 63216 ); + _DICT.put( 58648, 63217 ); + _DICT.put( 58649, 63218 ); + _DICT.put( 58650, 63219 ); + _DICT.put( 58651, 63220 ); + _DICT.put( 58652, 63221 ); + _DICT.put( 58653, 63222 ); + _DICT.put( 58654, 63223 ); + _DICT.put( 58655, 63224 ); + _DICT.put( 58656, 63225 ); + _DICT.put( 58657, 63226 ); + _DICT.put( 58658, 63227 ); + _DICT.put( 58659, 63228 ); + _DICT.put( 58660, 63296 ); + _DICT.put( 58661, 63297 ); + _DICT.put( 58662, 63298 ); + _DICT.put( 58663, 63299 ); + _DICT.put( 58664, 63300 ); + _DICT.put( 58665, 63301 ); + _DICT.put( 58666, 63302 ); + _DICT.put( 58667, 63303 ); + _DICT.put( 58668, 63304 ); + _DICT.put( 58669, 63305 ); + _DICT.put( 58670, 63306 ); + _DICT.put( 58671, 63307 ); + _DICT.put( 58672, 63308 ); + _DICT.put( 58673, 63309 ); + _DICT.put( 58674, 63310 ); + _DICT.put( 58675, 63311 ); + _DICT.put( 58676, 63312 ); + _DICT.put( 58677, 63313 ); + _DICT.put( 58678, 63314 ); + _DICT.put( 58679, 63315 ); + _DICT.put( 58680, 63316 ); + _DICT.put( 58681, 63317 ); + _DICT.put( 58682, 63318 ); + _DICT.put( 58683, 63319 ); + _DICT.put( 58684, 63320 ); + _DICT.put( 58685, 63321 ); + _DICT.put( 58686, 63322 ); + _DICT.put( 58687, 63323 ); + _DICT.put( 58688, 63324 ); + _DICT.put( 58689, 63325 ); + _DICT.put( 58690, 63326 ); + _DICT.put( 58691, 63327 ); + _DICT.put( 58692, 63328 ); + _DICT.put( 58693, 63329 ); + _DICT.put( 58694, 63330 ); + _DICT.put( 58695, 63331 ); + _DICT.put( 58696, 63332 ); + _DICT.put( 58697, 63333 ); + _DICT.put( 58698, 63334 ); + _DICT.put( 58699, 63335 ); + _DICT.put( 58700, 63336 ); + _DICT.put( 58701, 63337 ); + _DICT.put( 58702, 63338 ); + _DICT.put( 58703, 63339 ); + _DICT.put( 58704, 63340 ); + _DICT.put( 58705, 63341 ); + _DICT.put( 58706, 63342 ); + _DICT.put( 58707, 63343 ); + _DICT.put( 58708, 63344 ); + _DICT.put( 58709, 63345 ); + _DICT.put( 58710, 63346 ); + _DICT.put( 58711, 63347 ); + _DICT.put( 58712, 63348 ); + _DICT.put( 58713, 63349 ); + _DICT.put( 58714, 63350 ); + _DICT.put( 58715, 63351 ); + _DICT.put( 58716, 63352 ); + _DICT.put( 58717, 63353 ); + _DICT.put( 58718, 63354 ); + _DICT.put( 58719, 63355 ); + _DICT.put( 58720, 63356 ); + _DICT.put( 58721, 63357 ); + _DICT.put( 58722, 63358 ); + _DICT.put( 58723, 63360 ); + _DICT.put( 58724, 63361 ); + _DICT.put( 58725, 63362 ); + _DICT.put( 58726, 63363 ); + _DICT.put( 58727, 63364 ); + _DICT.put( 58728, 63365 ); + _DICT.put( 58729, 63366 ); + _DICT.put( 58730, 63367 ); + _DICT.put( 58731, 63368 ); + _DICT.put( 58732, 63369 ); + _DICT.put( 58733, 63370 ); + _DICT.put( 58734, 63371 ); + _DICT.put( 58735, 63372 ); + _DICT.put( 58736, 63373 ); + _DICT.put( 58737, 63374 ); + _DICT.put( 58738, 63375 ); + _DICT.put( 58739, 63376 ); + _DICT.put( 58740, 63377 ); + _DICT.put( 58741, 63378 ); + _DICT.put( 58742, 63379 ); + _DICT.put( 58743, 63380 ); + _DICT.put( 58744, 63381 ); + _DICT.put( 58745, 63382 ); + _DICT.put( 58746, 63383 ); + _DICT.put( 58747, 63384 ); + _DICT.put( 58748, 63385 ); + _DICT.put( 58749, 63386 ); + _DICT.put( 58750, 63387 ); + _DICT.put( 58751, 63388 ); + _DICT.put( 58752, 63389 ); + _DICT.put( 58753, 63390 ); + _DICT.put( 58754, 63391 ); + _DICT.put( 58755, 63392 ); + _DICT.put( 58756, 63393 ); + _DICT.put( 58757, 63394 ); + _DICT.put( 58758, 63395 ); + _DICT.put( 58759, 63396 ); + _DICT.put( 58760, 63397 ); + _DICT.put( 58761, 63398 ); + _DICT.put( 58762, 63399 ); + _DICT.put( 58763, 63400 ); + _DICT.put( 58764, 63401 ); + _DICT.put( 58765, 63402 ); + _DICT.put( 58766, 63403 ); + _DICT.put( 58767, 63404 ); + _DICT.put( 58768, 63405 ); + _DICT.put( 58769, 63406 ); + _DICT.put( 58770, 63407 ); + _DICT.put( 58771, 63408 ); + _DICT.put( 58772, 63409 ); + _DICT.put( 58773, 63410 ); + _DICT.put( 58774, 63411 ); + _DICT.put( 58775, 63412 ); + _DICT.put( 58776, 63413 ); + _DICT.put( 58777, 63414 ); + _DICT.put( 58778, 63415 ); + _DICT.put( 58779, 63416 ); + _DICT.put( 58780, 63417 ); + _DICT.put( 58781, 63418 ); + _DICT.put( 58782, 63419 ); + _DICT.put( 58783, 63420 ); + _DICT.put( 58784, 63421 ); + _DICT.put( 58785, 63422 ); + _DICT.put( 58786, 63423 ); + _DICT.put( 58787, 63424 ); + _DICT.put( 58788, 63425 ); + _DICT.put( 58789, 63426 ); + _DICT.put( 58790, 63427 ); + _DICT.put( 58791, 63428 ); + _DICT.put( 58792, 63429 ); + _DICT.put( 58793, 63430 ); + _DICT.put( 58794, 63431 ); + _DICT.put( 58795, 63432 ); + _DICT.put( 58796, 63433 ); + _DICT.put( 58797, 63434 ); + _DICT.put( 58798, 63435 ); + _DICT.put( 58799, 63436 ); + _DICT.put( 58800, 63437 ); + _DICT.put( 58801, 63438 ); + _DICT.put( 58802, 63439 ); + _DICT.put( 58803, 63440 ); + _DICT.put( 58804, 63441 ); + _DICT.put( 58805, 63442 ); + _DICT.put( 58806, 63443 ); + _DICT.put( 58807, 63444 ); + _DICT.put( 58808, 63445 ); + _DICT.put( 58809, 63446 ); + _DICT.put( 58810, 63447 ); + _DICT.put( 58811, 63448 ); + _DICT.put( 58812, 63449 ); + _DICT.put( 58813, 63450 ); + _DICT.put( 58814, 63451 ); + _DICT.put( 58815, 63452 ); + _DICT.put( 58816, 63453 ); + _DICT.put( 58817, 63454 ); + _DICT.put( 58818, 63455 ); + _DICT.put( 58819, 63456 ); + _DICT.put( 58820, 63457 ); + _DICT.put( 58821, 63458 ); + _DICT.put( 58822, 63459 ); + _DICT.put( 58823, 63460 ); + _DICT.put( 58824, 63461 ); + _DICT.put( 58825, 63462 ); + _DICT.put( 58826, 63463 ); + _DICT.put( 58827, 63464 ); + _DICT.put( 58828, 63465 ); + _DICT.put( 58829, 63466 ); + _DICT.put( 58830, 63467 ); + _DICT.put( 58831, 63468 ); + _DICT.put( 58832, 63469 ); + _DICT.put( 58833, 63470 ); + _DICT.put( 58834, 63471 ); + _DICT.put( 58835, 63472 ); + _DICT.put( 58836, 63473 ); + _DICT.put( 58837, 63474 ); + _DICT.put( 58838, 63475 ); + _DICT.put( 58839, 63476 ); + _DICT.put( 58840, 63477 ); + _DICT.put( 58841, 63478 ); + _DICT.put( 58842, 63479 ); + _DICT.put( 58843, 63480 ); + _DICT.put( 58844, 63481 ); + _DICT.put( 58845, 63482 ); + _DICT.put( 58846, 63483 ); + _DICT.put( 58847, 63484 ); + _DICT.put( 58848, 63552 ); + _DICT.put( 58849, 63553 ); + _DICT.put( 58850, 63554 ); + _DICT.put( 58851, 63555 ); + _DICT.put( 58852, 63556 ); + _DICT.put( 58853, 63557 ); + _DICT.put( 58854, 63558 ); + _DICT.put( 58855, 63559 ); + _DICT.put( 58856, 63560 ); + _DICT.put( 58857, 63561 ); + _DICT.put( 58858, 63562 ); + _DICT.put( 58859, 63563 ); + _DICT.put( 58860, 63564 ); + _DICT.put( 58861, 63565 ); + _DICT.put( 58862, 63566 ); + _DICT.put( 58863, 63567 ); + _DICT.put( 58864, 63568 ); + _DICT.put( 58865, 63569 ); + _DICT.put( 58866, 63570 ); + _DICT.put( 58867, 63571 ); + _DICT.put( 58868, 63572 ); + _DICT.put( 58869, 63573 ); + _DICT.put( 58870, 63574 ); + _DICT.put( 58871, 63575 ); + _DICT.put( 58872, 63576 ); + _DICT.put( 58873, 63577 ); + _DICT.put( 58874, 63578 ); + _DICT.put( 58875, 63579 ); + _DICT.put( 58876, 63580 ); + _DICT.put( 58877, 63581 ); + _DICT.put( 58878, 63582 ); + _DICT.put( 58879, 63583 ); + _DICT.put( 58880, 63584 ); + _DICT.put( 58881, 63585 ); + _DICT.put( 58882, 63586 ); + _DICT.put( 58883, 63587 ); + _DICT.put( 58884, 63588 ); + _DICT.put( 58885, 63589 ); + _DICT.put( 58886, 63590 ); + _DICT.put( 58887, 63591 ); + _DICT.put( 58888, 63592 ); + _DICT.put( 58889, 63593 ); + _DICT.put( 58890, 63594 ); + _DICT.put( 58891, 63595 ); + _DICT.put( 58892, 63596 ); + _DICT.put( 58893, 63597 ); + _DICT.put( 58894, 63598 ); + _DICT.put( 58895, 63599 ); + _DICT.put( 58896, 63600 ); + _DICT.put( 58897, 63601 ); + _DICT.put( 58898, 63602 ); + _DICT.put( 58899, 63603 ); + _DICT.put( 58900, 63604 ); + _DICT.put( 58901, 63605 ); + _DICT.put( 58902, 63606 ); + _DICT.put( 58903, 63607 ); + _DICT.put( 58904, 63608 ); + _DICT.put( 58905, 63609 ); + _DICT.put( 58906, 63610 ); + _DICT.put( 58907, 63611 ); + _DICT.put( 58908, 63612 ); + _DICT.put( 58909, 63613 ); + _DICT.put( 58910, 63614 ); + _DICT.put( 58911, 63616 ); + _DICT.put( 58912, 63617 ); + _DICT.put( 58913, 63618 ); + _DICT.put( 58914, 63619 ); + _DICT.put( 58915, 63620 ); + _DICT.put( 58916, 63621 ); + _DICT.put( 58917, 63622 ); + _DICT.put( 58918, 63623 ); + _DICT.put( 58919, 63624 ); + _DICT.put( 58920, 63625 ); + _DICT.put( 58921, 63626 ); + _DICT.put( 58922, 63627 ); + _DICT.put( 58923, 63628 ); + _DICT.put( 58924, 63629 ); + _DICT.put( 58925, 63630 ); + _DICT.put( 58926, 63631 ); + _DICT.put( 58927, 63632 ); + _DICT.put( 58928, 63633 ); + _DICT.put( 58929, 63634 ); + _DICT.put( 58930, 63635 ); + _DICT.put( 58931, 63636 ); + _DICT.put( 58932, 63637 ); + _DICT.put( 58933, 63638 ); + _DICT.put( 58934, 63639 ); + _DICT.put( 58935, 63640 ); + _DICT.put( 58936, 63641 ); + _DICT.put( 58937, 63642 ); + _DICT.put( 58938, 63643 ); + _DICT.put( 58939, 63644 ); + _DICT.put( 58940, 63645 ); + _DICT.put( 58941, 63646 ); + _DICT.put( 58942, 63647 ); + _DICT.put( 58943, 63648 ); + _DICT.put( 58944, 63649 ); + _DICT.put( 58945, 63650 ); + _DICT.put( 58946, 63651 ); + _DICT.put( 58947, 63652 ); + _DICT.put( 58948, 63653 ); + _DICT.put( 58949, 63654 ); + _DICT.put( 58950, 63655 ); + _DICT.put( 58951, 63656 ); + _DICT.put( 58952, 63657 ); + _DICT.put( 58953, 63658 ); + _DICT.put( 58954, 63659 ); + _DICT.put( 58955, 63660 ); + _DICT.put( 58956, 63661 ); + _DICT.put( 58957, 63662 ); + _DICT.put( 58958, 63663 ); + _DICT.put( 58959, 63664 ); + _DICT.put( 58960, 63665 ); + _DICT.put( 58961, 63666 ); + _DICT.put( 58962, 63667 ); + _DICT.put( 58963, 63668 ); + _DICT.put( 58964, 63669 ); + _DICT.put( 58965, 63670 ); + _DICT.put( 58966, 63671 ); + _DICT.put( 58967, 63672 ); + _DICT.put( 58968, 63673 ); + _DICT.put( 58969, 63674 ); + _DICT.put( 58970, 63675 ); + _DICT.put( 58971, 63676 ); + _DICT.put( 58972, 63677 ); + _DICT.put( 58973, 63678 ); + _DICT.put( 58974, 63679 ); + _DICT.put( 58975, 63680 ); + _DICT.put( 58976, 63681 ); + _DICT.put( 58977, 63682 ); + _DICT.put( 58978, 63683 ); + _DICT.put( 58979, 63684 ); + _DICT.put( 58980, 63685 ); + _DICT.put( 58981, 63686 ); + _DICT.put( 58982, 63687 ); + _DICT.put( 58983, 63688 ); + _DICT.put( 58984, 63689 ); + _DICT.put( 58985, 63690 ); + _DICT.put( 58986, 63691 ); + _DICT.put( 58987, 63692 ); + _DICT.put( 58988, 63693 ); + _DICT.put( 58989, 63694 ); + _DICT.put( 58990, 63695 ); + _DICT.put( 58991, 63696 ); + _DICT.put( 58992, 63697 ); + _DICT.put( 58993, 63698 ); + _DICT.put( 58994, 63699 ); + _DICT.put( 58995, 63700 ); + _DICT.put( 58996, 63701 ); + _DICT.put( 58997, 63702 ); + _DICT.put( 58998, 63703 ); + _DICT.put( 58999, 63704 ); + _DICT.put( 59000, 63705 ); + _DICT.put( 59001, 63706 ); + _DICT.put( 59002, 63707 ); + _DICT.put( 59003, 63708 ); + _DICT.put( 59004, 63709 ); + _DICT.put( 59005, 63710 ); + _DICT.put( 59006, 63711 ); + _DICT.put( 59007, 63712 ); + _DICT.put( 59008, 63713 ); + _DICT.put( 59009, 63714 ); + _DICT.put( 59010, 63715 ); + _DICT.put( 59011, 63716 ); + _DICT.put( 59012, 63717 ); + _DICT.put( 59013, 63718 ); + _DICT.put( 59014, 63719 ); + _DICT.put( 59015, 63720 ); + _DICT.put( 59016, 63721 ); + _DICT.put( 59017, 63722 ); + _DICT.put( 59018, 63723 ); + _DICT.put( 59019, 63724 ); + _DICT.put( 59020, 63725 ); + _DICT.put( 59021, 63726 ); + _DICT.put( 59022, 63727 ); + _DICT.put( 59023, 63728 ); + _DICT.put( 59024, 63729 ); + _DICT.put( 59025, 63730 ); + _DICT.put( 59026, 63731 ); + _DICT.put( 59027, 63732 ); + _DICT.put( 59028, 63733 ); + _DICT.put( 59029, 63734 ); + _DICT.put( 59030, 63735 ); + _DICT.put( 59031, 63736 ); + _DICT.put( 59032, 63737 ); + _DICT.put( 59033, 63738 ); + _DICT.put( 59034, 63739 ); + _DICT.put( 59035, 63740 ); + _DICT.put( 59036, 63808 ); + _DICT.put( 59037, 63809 ); + _DICT.put( 59038, 63810 ); + _DICT.put( 59039, 63811 ); + _DICT.put( 59040, 63812 ); + _DICT.put( 59041, 63813 ); + _DICT.put( 59042, 63814 ); + _DICT.put( 59043, 63815 ); + _DICT.put( 59044, 63816 ); + _DICT.put( 59045, 63817 ); + _DICT.put( 59046, 63818 ); + _DICT.put( 59047, 63819 ); + _DICT.put( 59048, 63820 ); + _DICT.put( 59049, 63821 ); + _DICT.put( 59050, 63822 ); + _DICT.put( 59051, 63823 ); + _DICT.put( 59052, 63824 ); + _DICT.put( 59053, 63825 ); + _DICT.put( 59054, 63826 ); + _DICT.put( 59055, 63827 ); + _DICT.put( 59056, 63828 ); + _DICT.put( 59057, 63829 ); + _DICT.put( 59058, 63830 ); + _DICT.put( 59059, 63831 ); + _DICT.put( 59060, 63832 ); + _DICT.put( 59061, 63833 ); + _DICT.put( 59062, 63834 ); + _DICT.put( 59063, 63835 ); + _DICT.put( 59064, 63836 ); + _DICT.put( 59065, 63837 ); + _DICT.put( 59066, 63838 ); + _DICT.put( 59067, 63839 ); + _DICT.put( 59068, 63840 ); + _DICT.put( 59069, 63841 ); + _DICT.put( 59070, 63842 ); + _DICT.put( 59071, 63843 ); + _DICT.put( 59072, 63844 ); + _DICT.put( 59073, 63845 ); + _DICT.put( 59074, 63846 ); + _DICT.put( 59075, 63847 ); + _DICT.put( 59076, 63848 ); + _DICT.put( 59077, 63849 ); + _DICT.put( 59078, 63850 ); + _DICT.put( 59079, 63851 ); + _DICT.put( 59080, 63852 ); + _DICT.put( 59081, 63853 ); + _DICT.put( 59082, 63854 ); + _DICT.put( 59083, 63855 ); + _DICT.put( 59084, 63856 ); + _DICT.put( 59085, 63857 ); + _DICT.put( 59086, 63858 ); + _DICT.put( 59087, 63859 ); + _DICT.put( 59088, 63860 ); + _DICT.put( 59089, 63861 ); + _DICT.put( 59090, 63862 ); + _DICT.put( 59091, 63863 ); + _DICT.put( 59092, 63864 ); + _DICT.put( 59093, 63865 ); + _DICT.put( 59094, 63866 ); + _DICT.put( 59095, 63867 ); + _DICT.put( 59096, 63868 ); + _DICT.put( 59097, 63869 ); + _DICT.put( 59098, 63870 ); + _DICT.put( 59099, 63872 ); + _DICT.put( 59100, 63873 ); + _DICT.put( 59101, 63874 ); + _DICT.put( 59102, 63875 ); + _DICT.put( 59103, 63876 ); + _DICT.put( 59104, 63877 ); + _DICT.put( 59105, 63878 ); + _DICT.put( 59106, 63879 ); + _DICT.put( 59107, 63880 ); + _DICT.put( 59108, 63881 ); + _DICT.put( 59109, 63882 ); + _DICT.put( 59110, 63883 ); + _DICT.put( 59111, 63884 ); + _DICT.put( 59112, 63885 ); + _DICT.put( 59113, 63886 ); + _DICT.put( 59114, 63887 ); + _DICT.put( 59115, 63888 ); + _DICT.put( 59116, 63889 ); + _DICT.put( 59117, 63890 ); + _DICT.put( 59118, 63891 ); + _DICT.put( 59119, 63892 ); + _DICT.put( 59120, 63893 ); + _DICT.put( 59121, 63894 ); + _DICT.put( 59122, 63895 ); + _DICT.put( 59123, 63896 ); + _DICT.put( 59124, 63897 ); + _DICT.put( 59125, 63898 ); + _DICT.put( 59126, 63899 ); + _DICT.put( 59127, 63900 ); + _DICT.put( 59128, 63901 ); + _DICT.put( 59129, 63902 ); + _DICT.put( 59130, 63903 ); + _DICT.put( 59131, 63904 ); + _DICT.put( 59132, 63905 ); + _DICT.put( 59133, 63906 ); + _DICT.put( 59134, 63907 ); + _DICT.put( 59135, 63908 ); + _DICT.put( 59136, 63909 ); + _DICT.put( 59137, 63910 ); + _DICT.put( 59138, 63911 ); + _DICT.put( 59139, 63912 ); + _DICT.put( 59140, 63913 ); + _DICT.put( 59141, 63914 ); + _DICT.put( 59142, 63915 ); + _DICT.put( 59143, 63916 ); + _DICT.put( 59144, 63917 ); + _DICT.put( 59145, 63918 ); + _DICT.put( 59146, 63919 ); + _DICT.put( 59147, 63920 ); + _DICT.put( 59148, 63921 ); + _DICT.put( 59149, 63922 ); + _DICT.put( 59150, 63923 ); + _DICT.put( 59151, 63924 ); + _DICT.put( 59152, 63925 ); + _DICT.put( 59153, 63926 ); + _DICT.put( 59154, 63927 ); + _DICT.put( 59155, 63928 ); + _DICT.put( 59156, 63929 ); + _DICT.put( 59157, 63930 ); + _DICT.put( 59158, 63931 ); + _DICT.put( 59159, 63932 ); + _DICT.put( 59160, 63933 ); + _DICT.put( 59161, 63934 ); + _DICT.put( 59162, 63935 ); + _DICT.put( 59163, 63936 ); + _DICT.put( 59164, 63937 ); + _DICT.put( 59165, 63938 ); + _DICT.put( 59166, 63939 ); + _DICT.put( 59167, 63940 ); + _DICT.put( 59168, 63941 ); + _DICT.put( 59169, 63942 ); + _DICT.put( 59170, 63943 ); + _DICT.put( 59171, 63944 ); + _DICT.put( 59172, 63945 ); + _DICT.put( 59173, 63946 ); + _DICT.put( 59174, 63947 ); + _DICT.put( 59175, 63948 ); + _DICT.put( 59176, 63949 ); + _DICT.put( 59177, 63950 ); + _DICT.put( 59178, 63951 ); + _DICT.put( 59179, 63952 ); + _DICT.put( 59180, 63953 ); + _DICT.put( 59181, 63954 ); + _DICT.put( 59182, 63955 ); + _DICT.put( 59183, 63956 ); + _DICT.put( 59184, 63957 ); + _DICT.put( 59185, 63958 ); + _DICT.put( 59186, 63959 ); + _DICT.put( 59187, 63960 ); + _DICT.put( 59188, 63961 ); + _DICT.put( 59189, 63962 ); + _DICT.put( 59190, 63963 ); + _DICT.put( 59191, 63964 ); + _DICT.put( 59192, 63965 ); + _DICT.put( 59193, 63966 ); + _DICT.put( 59194, 63967 ); + _DICT.put( 59195, 63968 ); + _DICT.put( 59196, 63969 ); + _DICT.put( 59197, 63970 ); + _DICT.put( 59198, 63971 ); + _DICT.put( 59199, 63972 ); + _DICT.put( 59200, 63973 ); + _DICT.put( 59201, 63974 ); + _DICT.put( 59202, 63975 ); + _DICT.put( 59203, 63976 ); + _DICT.put( 59204, 63977 ); + _DICT.put( 59205, 63978 ); + _DICT.put( 59206, 63979 ); + _DICT.put( 59207, 63980 ); + _DICT.put( 59208, 63981 ); + _DICT.put( 59209, 63982 ); + _DICT.put( 59210, 63983 ); + _DICT.put( 59211, 63984 ); + _DICT.put( 59212, 63985 ); + _DICT.put( 59213, 63986 ); + _DICT.put( 59214, 63987 ); + _DICT.put( 59215, 63988 ); + _DICT.put( 59216, 63989 ); + _DICT.put( 59217, 63990 ); + _DICT.put( 59218, 63991 ); + _DICT.put( 59219, 63992 ); + _DICT.put( 59220, 63993 ); + _DICT.put( 59221, 63994 ); + _DICT.put( 59222, 63995 ); + _DICT.put( 59223, 63996 ); + _DICT.put( 63728, 160 ); + _DICT.put( 63729, 253 ); + _DICT.put( 63730, 254 ); + _DICT.put( 63731, 255 ); + _DICT.put( 63785, 64224 ); + _DICT.put( 63964, 64489 ); + _DICT.put( 64014, 64144 ); + _DICT.put( 64015, 64155 ); + _DICT.put( 64016, 64156 ); + _DICT.put( 64017, 64177 ); + _DICT.put( 64018, 64216 ); + _DICT.put( 64019, 64232 ); + _DICT.put( 64020, 64234 ); + _DICT.put( 64021, 64344 ); + _DICT.put( 64022, 64350 ); + _DICT.put( 64023, 64373 ); + _DICT.put( 64024, 64381 ); + _DICT.put( 64025, 64382 ); + _DICT.put( 64026, 64384 ); + _DICT.put( 64027, 64386 ); + _DICT.put( 64028, 64390 ); + _DICT.put( 64029, 64393 ); + _DICT.put( 64030, 64402 ); + _DICT.put( 64031, 64413 ); + _DICT.put( 64032, 64415 ); + _DICT.put( 64033, 64416 ); + _DICT.put( 64034, 64425 ); + _DICT.put( 64035, 64433 ); + _DICT.put( 64036, 64435 ); + _DICT.put( 64037, 64436 ); + _DICT.put( 64038, 64439 ); + _DICT.put( 64039, 64467 ); + _DICT.put( 64040, 64474 ); + _DICT.put( 64041, 64490 ); + _DICT.put( 64042, 64502 ); + _DICT.put( 64043, 64503 ); + _DICT.put( 64044, 64505 ); + _DICT.put( 64045, 64585 ); + _DICT.put( 65281, 33097 ); + _DICT.put( 65282, 64087 ); + _DICT.put( 65283, 33172 ); + _DICT.put( 65284, 33168 ); + _DICT.put( 65285, 33171 ); + _DICT.put( 65286, 33173 ); + _DICT.put( 65287, 64086 ); + _DICT.put( 65288, 33129 ); + _DICT.put( 65289, 33130 ); + _DICT.put( 65290, 33174 ); + _DICT.put( 65291, 33147 ); + _DICT.put( 65292, 33091 ); + _DICT.put( 65293, 33148 ); + _DICT.put( 65294, 33092 ); + _DICT.put( 65295, 33118 ); + _DICT.put( 65296, 33359 ); + _DICT.put( 65297, 33360 ); + _DICT.put( 65298, 33361 ); + _DICT.put( 65299, 33362 ); + _DICT.put( 65300, 33363 ); + _DICT.put( 65301, 33364 ); + _DICT.put( 65302, 33365 ); + _DICT.put( 65303, 33366 ); + _DICT.put( 65304, 33367 ); + _DICT.put( 65305, 33368 ); + _DICT.put( 65306, 33094 ); + _DICT.put( 65307, 33095 ); + _DICT.put( 65308, 33155 ); + _DICT.put( 65309, 33153 ); + _DICT.put( 65310, 33156 ); + _DICT.put( 65311, 33096 ); + _DICT.put( 65312, 33175 ); + _DICT.put( 65313, 33376 ); + _DICT.put( 65314, 33377 ); + _DICT.put( 65315, 33378 ); + _DICT.put( 65316, 33379 ); + _DICT.put( 65317, 33380 ); + _DICT.put( 65318, 33381 ); + _DICT.put( 65319, 33382 ); + _DICT.put( 65320, 33383 ); + _DICT.put( 65321, 33384 ); + _DICT.put( 65322, 33385 ); + _DICT.put( 65323, 33386 ); + _DICT.put( 65324, 33387 ); + _DICT.put( 65325, 33388 ); + _DICT.put( 65326, 33389 ); + _DICT.put( 65327, 33390 ); + _DICT.put( 65328, 33391 ); + _DICT.put( 65329, 33392 ); + _DICT.put( 65330, 33393 ); + _DICT.put( 65331, 33394 ); + _DICT.put( 65332, 33395 ); + _DICT.put( 65333, 33396 ); + _DICT.put( 65334, 33397 ); + _DICT.put( 65335, 33398 ); + _DICT.put( 65336, 33399 ); + _DICT.put( 65337, 33400 ); + _DICT.put( 65338, 33401 ); + _DICT.put( 65339, 33133 ); + _DICT.put( 65340, 33119 ); + _DICT.put( 65341, 33134 ); + _DICT.put( 65342, 33103 ); + _DICT.put( 65343, 33105 ); + _DICT.put( 65344, 33101 ); + _DICT.put( 65345, 33409 ); + _DICT.put( 65346, 33410 ); + _DICT.put( 65347, 33411 ); + _DICT.put( 65348, 33412 ); + _DICT.put( 65349, 33413 ); + _DICT.put( 65350, 33414 ); + _DICT.put( 65351, 33415 ); + _DICT.put( 65352, 33416 ); + _DICT.put( 65353, 33417 ); + _DICT.put( 65354, 33418 ); + _DICT.put( 65355, 33419 ); + _DICT.put( 65356, 33420 ); + _DICT.put( 65357, 33421 ); + _DICT.put( 65358, 33422 ); + _DICT.put( 65359, 33423 ); + _DICT.put( 65360, 33424 ); + _DICT.put( 65361, 33425 ); + _DICT.put( 65362, 33426 ); + _DICT.put( 65363, 33427 ); + _DICT.put( 65364, 33428 ); + _DICT.put( 65365, 33429 ); + _DICT.put( 65366, 33430 ); + _DICT.put( 65367, 33431 ); + _DICT.put( 65368, 33432 ); + _DICT.put( 65369, 33433 ); + _DICT.put( 65370, 33434 ); + _DICT.put( 65371, 33135 ); + _DICT.put( 65372, 33122 ); + _DICT.put( 65373, 33136 ); + _DICT.put( 65374, 33120 ); + _DICT.put( 65377, 161 ); + _DICT.put( 65378, 162 ); + _DICT.put( 65379, 163 ); + _DICT.put( 65380, 164 ); + _DICT.put( 65381, 165 ); + _DICT.put( 65382, 166 ); + _DICT.put( 65383, 167 ); + _DICT.put( 65384, 168 ); + _DICT.put( 65385, 169 ); + _DICT.put( 65386, 170 ); + _DICT.put( 65387, 171 ); + _DICT.put( 65388, 172 ); + _DICT.put( 65389, 173 ); + _DICT.put( 65390, 174 ); + _DICT.put( 65391, 175 ); + _DICT.put( 65392, 176 ); + _DICT.put( 65393, 177 ); + _DICT.put( 65394, 178 ); + _DICT.put( 65395, 179 ); + _DICT.put( 65396, 180 ); + _DICT.put( 65397, 181 ); + _DICT.put( 65398, 182 ); + _DICT.put( 65399, 183 ); + _DICT.put( 65400, 184 ); + _DICT.put( 65401, 185 ); + _DICT.put( 65402, 186 ); + _DICT.put( 65403, 187 ); + _DICT.put( 65404, 188 ); + _DICT.put( 65405, 189 ); + _DICT.put( 65406, 190 ); + _DICT.put( 65407, 191 ); + _DICT.put( 65408, 192 ); + _DICT.put( 65409, 193 ); + _DICT.put( 65410, 194 ); + _DICT.put( 65411, 195 ); + _DICT.put( 65412, 196 ); + _DICT.put( 65413, 197 ); + _DICT.put( 65414, 198 ); + _DICT.put( 65415, 199 ); + _DICT.put( 65416, 200 ); + _DICT.put( 65417, 201 ); + _DICT.put( 65418, 202 ); + _DICT.put( 65419, 203 ); + _DICT.put( 65420, 204 ); + _DICT.put( 65421, 205 ); + _DICT.put( 65422, 206 ); + _DICT.put( 65423, 207 ); + _DICT.put( 65424, 208 ); + _DICT.put( 65425, 209 ); + _DICT.put( 65426, 210 ); + _DICT.put( 65427, 211 ); + _DICT.put( 65428, 212 ); + _DICT.put( 65429, 213 ); + _DICT.put( 65430, 214 ); + _DICT.put( 65431, 215 ); + _DICT.put( 65432, 216 ); + _DICT.put( 65433, 217 ); + _DICT.put( 65434, 218 ); + _DICT.put( 65435, 219 ); + _DICT.put( 65436, 220 ); + _DICT.put( 65437, 221 ); + _DICT.put( 65438, 222 ); + _DICT.put( 65439, 223 ); + _DICT.put( 65504, 33169 ); + _DICT.put( 65505, 33170 ); + _DICT.put( 65506, 33226 ); + _DICT.put( 65507, 33104 ); + _DICT.put( 65508, 64085 ); + _DICT.put( 65509, 33167 ); + m_initialized = true; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/math.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/math.java new file mode 100644 index 0000000..b2dcdd9 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/bocoree/math.java @@ -0,0 +1,340 @@ +/* + * math.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.bocoree. + * + * jp.sourceforge.lipsync.bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.bocoree; + +public class math { + private static final double _PI2 = 2.0 * Math.PI; + private static final double _PI4 = 4.0 * Math.PI; + private static final double _PI6 = 6.0 * Math.PI; + private static final double _PI8 = 8.0 * Math.PI; + + public enum WindowFunctionType { + Hamming, + rectangular, + Gauss, + Hann, + Blackman, + Bartlett, + Nuttall, + Blackman_Harris, + Blackman_Nattall, + flap_top, + Parzen, + Akaike, + Welch, + Kaiser, + } + + public static double window_func(WindowFunctionType type, double x) throws Exception { + switch ( type ) { + case Akaike: + return wnd_akaike(x); + case Bartlett: + return wnd_bartlett(x); + case Blackman: + return wnd_blackman(x); + case Blackman_Harris: + return wnd_blackman_harris(x); + case Blackman_Nattall: + return wnd_blackman_nattall(x); + case flap_top: + return wnd_flap_top(x); + case Gauss: + throw new Exception("too few argument for Gauss window function"); + case Hamming: + return wnd_hamming(x); + case Hann: + return wnd_hann(x); + case Kaiser: + throw new Exception("too few argument for Kaiser window function"); + case Nuttall: + return wnd_nuttall(x); + case Parzen: + return wnd_parzen(x); + case rectangular: + return wnd_rectangular(x); + case Welch: + return wnd_welch(x); + } + return 0.0; + } + + public static double window_func(WindowFunctionType type, double x, double[] param) { + switch ( type ) { + case Akaike: + return wnd_akaike(x); + case Bartlett: + return wnd_bartlett(x); + case Blackman: + return wnd_blackman(x); + case Blackman_Harris: + return wnd_blackman_harris(x); + case Blackman_Nattall: + return wnd_blackman_nattall(x); + case flap_top: + return wnd_flap_top(x); + case Gauss: + return wnd_gauss(x, param[0]); + case Hamming: + return wnd_hamming(x); + case Hann: + return wnd_hann(x); + case Kaiser: + return wnd_kaiser(x, param[0]); + case Nuttall: + return wnd_nuttall(x); + case Parzen: + return wnd_parzen(x); + case rectangular: + return wnd_rectangular(x); + case Welch: + return wnd_welch(x); + } + return 0.0; + } + + /** + * カイザー窓 + * @param x + * @param alpha + * @return + */ + public static double wnd_kaiser(double x, double alpha) { + if ( 0.0 <= x && x <= 1.0 ) { + double t = 2.0 * x - 1.0; + return besi0(Math.PI * alpha * Math.sqrt(1.0 - t * t)) / besi0(Math.PI * alpha); + } else { + return 0.0; + } + } + + /** + * ウェルチ窓 + * @param x + * @return + */ + public static double wnd_welch(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 4.0 * x * (1.0 - x); + } else { + return 0.0; + } + } + + /** + * 赤池窓 + * @param x + * @return + */ + public static double wnd_akaike(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.625 - 0.5 * Math.cos(_PI2 * x) - 0.125 * Math.cos(_PI4 * x); + } else { + return 0.0; + } + } + + /** + * パルザン窓 + * @param x + * @return + */ + public static double wnd_parzen(double x) { + double x0 = Math.abs(x); + if ( x0 <= 1.0 ) { + return (0.75 * x0 - 1.5) * x0 * x0 + 1.0; + } else { + x0 = 2.0 - x0; + return 0.25 * x0 * x0 * x0; + } + } + + /** + * フラット・トップ窓 + * @param x + * @return + */ + public static double wnd_flap_top(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0 - 1.93 * Math.cos(_PI2 * x) + 1.29 * Math.cos(_PI4 * x) - 0.388 * Math.cos(_PI6 * x) + 0.032 * Math.cos(_PI8 * x); + } else { + return 0.0; + } + } + + /** + * ブラックマン‐ナットール窓 + * @param x + * @return + */ + public static double wnd_blackman_nattall(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.3635819 - 0.4891775 * Math.cos(_PI2 * x) + 0.1365995 * Math.cos(_PI4 * x) - 0.0106411 * Math.cos(_PI6 * x); + } else { + return 0.0; + } + } + + /** + * ブラックマン‐ハリス窓 + * @param x + * @return + */ + public static double wnd_blackman_harris(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.35875 - 0.48829 * Math.cos(_PI2 * x) + 0.14128 * Math.cos(_PI4 * x) - 0.01168 * Math.cos(_PI6 * x); + } else { + return 0.0; + } + } + + /** + * ナットール窓 + * @param x + * @return + */ + public static double wnd_nuttall(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.355768 - 0.487396 * Math.cos(_PI2 * x) + 0.144232 * Math.cos(_PI4 * x) - 0.012604 * Math.cos(_PI6 * x); + } else { + return 0.0; + } + } + + /** + * バートレット窓 + * @param x + * @return + */ + public static double wnd_bartlett(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0 - 2.0 * Math.abs(x - 0.5); + } else { + return 0.0; + } + } + + /** + * ブラックマン窓 + * @param x + * @return + */ + public static double wnd_blackman(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.42 - 0.5 * Math.cos(_PI2 * x) + 0.08 * Math.cos(_PI4 * x); + } else { + return 0.0; + } + } + + /** + * ハン窓 + * @param x + * @return + */ + public static double wnd_hann(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.5 - 0.5 * Math.cos(_PI2 * x); + } else { + return 0.0; + } + } + + /** + * ガウス窓 + * @param x + * @param sigma + * @return + */ + public static double wnd_gauss(double x, double sigma) { + return Math.exp(-x * x / (sigma * sigma)); + } + + /** + * 矩形窓 + * @param x + * @return + */ + public static double wnd_rectangular(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0; + } else { + return 0.0; + } + } + + /** + * ハミング窓 + * @param x + * @return + */ + public static double wnd_hamming(double x) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.54 - 0.46 * Math.cos(_PI2 * x); + } else { + return 0.0; + } + } + + /** + * 第1種ベッセル関数 + * @param x + * @return + */ + public static double besi0(double x) { + int i; + double w, wx375; + double[] a = {1.0, 3.5156229, 3.0899424, + 1.2067492, 0.2659732, 0.0360768 + }; + double[] b = {0.39894228, 0.013285917, 0.002253187, + -0.001575649, 0.009162808, -0.020577063, + 0.026355372, -0.016476329 + }; + if ( x < 0.0 ) { + return 0.0; + } + if ( x <= 3.75 ) { + wx375 = x * x / 14.0625; + w = 0.0045813; + for ( i = 5; i >= 0; i-- ) { + w = w * wx375 + a[i]; + } + return w; + } + wx375 = 3.75 / x; + w = 0.003923767; + for ( i = 7; i >= 0; i-- ) { + w = w * wx375 + b[i]; + } + return w / Math.sqrt(x) * Math.exp(x); + } + + /** + * 補誤差関数 + * @param x + * @return + */ + public static double erfcc(double x) { + double t, z, res; + z = Math.abs(x); + t = 1.0 / (1.0 + 0.5 * z); + res = t * Math.exp(-z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196 + t * (0.09678418 + t * (-0.18628806 + t * (0.27886807 + t * (-1.13520398 + t * (1.48851587 + t * (-0.82215223 + t * 0.17087277))))))))); + if ( x < 0.0 ) { + res = 2.0 - res; + } + return res; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/BPPair.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/BPPair.java new file mode 100644 index 0000000..67a13af --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/BPPair.java @@ -0,0 +1,58 @@ +/* + * BPPair.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class BPPair implements Comparable { + //private int m_clock; + public int Clock; + //private int m_value; + public int Value; + + public int compareTo( Object arg_item ) { + if ( !arg_item.getClass().equals( BPPair.class.getClass() ) ) { + return 0; + } + BPPair item = (BPPair)arg_item; + if ( Clock > item.Clock ) { + return 1; + } else if ( Clock < item.Clock ) { + return -1; + } else { + return 0; + } + } + + + /*public property int Clock { + get { + return m_clock; + } + set { + m_clock = value; + } + };*/ + /*public property int Value { + get { + return m_value; + } + set { + m_value = value; + } + };*/ + public BPPair( int clock, int value ) { + Clock = clock; + Value = value; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/IconHandle.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/IconHandle.java new file mode 100644 index 0000000..b210aed --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/IconHandle.java @@ -0,0 +1,88 @@ +/* + * IconHandle.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class IconHandle extends VsqHandle implements Cloneable { + public Object clone() { + IconHandle ret = new IconHandle(); + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Index = Index; + ret.Language = Language; + ret.Length = Length; + ret.Original = Original; + ret.Program = Program; + ret.Type = Type; + return ret; + } + + + /*public property int Program { + get { + return m_program; + } + set { + m_program = value; + } + };*/ + /*public property int Language { + get { + return m_language; + } + set { + m_language = value; + } + };*/ + /*public property int Length { + get { + return m_length; + } + set { + m_length = value; + } + };*/ + /*public property String Caption { + get { + return m_caption; + } + set { + m_caption = value; + } + };*/ + /*public property String IconID { + get { + return m_icon_id; + } + set { + m_icon_id = value; + } + };*/ + /*public property String IDS { + get { + return m_ids; + } + set { + m_ids = value; + } + };*/ + /*public property int Original { + get { + return m_original; + } + set { + m_original = value; + } + };*/ +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/KeyValuePair.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/KeyValuePair.java new file mode 100644 index 0000000..2b61681 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/KeyValuePair.java @@ -0,0 +1,28 @@ +/* + * KeyValuePair.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public class KeyValuePair { + public K Key; + public V Value; + + public KeyValuePair( K key, V value ) { + Key = key; + Value = value; + } +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/Lyric.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/Lyric.java new file mode 100644 index 0000000..c39b1f3 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/Lyric.java @@ -0,0 +1,365 @@ +/* + * Lyric.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import jp.sourceforge.lipsync.bocoree.*; + +/** + * VsqHandleに格納される歌詞の情報を扱うクラス。 + */ +public class Lyric { + //private String m_phrase; + public String Phrase; + private String[] m_phonetic_symbol; + //private float UnknownFloat; + public float UnknownFloat; + private int[] m_consonant_adjustment; + private boolean m_protected; + public boolean PhoneticSymbolProtected; + + /*public proprety boolean PhoneticSymbolProtected { + get { + return m_protected; + } + set { + m_protected = value; + } + };*/ + /*public property float UnknownFloat { + get { + return UnknownFloat; + } + set { + UnknownFloat = value; + } + };*/ + public int[] getConsonantAdjustment() { + return m_consonant_adjustment; + } + + /** + * このオブジェクトの簡易コピーを取得します。 + * @returns このインスタンスの簡易コピー + */ + public Lyric clone() { + Lyric result = new Lyric(); + result.Phrase = this.Phrase; + result.m_phonetic_symbol = (String[]) this.m_phonetic_symbol.clone(); + result.UnknownFloat = this.UnknownFloat; + result.m_consonant_adjustment = (int[]) this.m_consonant_adjustment.clone(); + result.m_protected = m_protected; + return result; + } + + /** + * 歌詞、発音記号を指定したコンストラクタ + * @param phrase 歌詞 + * @param phonetic_symbol 発音記号 + */ + public Lyric( String phrase, String phonetic_symbol ) { + Phrase = phrase; + setPhoneticSymbol( phonetic_symbol ); + UnknownFloat = 0.000000f; + } + + private Lyric() { + } + + + /*// + /// この歌詞のフレーズを取得または設定します。 + /// + public proprety String Phrase { + get { + return m_phrase; + } + set { + m_phrase = value; + } + };*/ + /// + /// この歌詞の発音記号を取得または設定します。 + /// + public String getPhoneticSymbol() { + String ret = m_phonetic_symbol[0]; + for ( int i = 1; i < m_phonetic_symbol.length; i++ ) { + ret += " " + m_phonetic_symbol[i]; + } + return ret; + } + + public void setPhoneticSymbol( String value ) { + String s = value.replace( " ", " " ); + m_phonetic_symbol = s.split( " ", 16 ); + for ( int i = 0; i < m_phonetic_symbol.length; i++ ) { + m_phonetic_symbol[i] = m_phonetic_symbol[i].replace( "\\\\", "\\" ); + } + m_consonant_adjustment = new int[m_phonetic_symbol.length]; + for ( int i = 0; i < m_phonetic_symbol.length; i++ ) { + if ( VsqPhoneticSymbol.IsConsonant( m_phonetic_symbol[i] ) ) { + m_consonant_adjustment[i] = 64; + } else { + m_consonant_adjustment[i] = 0; + } + } + } + + public String[] getPhoneticSymbolList() { + String[] ret = new String[m_phonetic_symbol.length]; + for ( int i = 0; i < m_phonetic_symbol.length; i++ ) { + ret[i] = m_phonetic_symbol[i]; + } + return ret; + } + + +/// +/// 文字列からのコンストラクタ +/// +/// 生成元の文字列 + public Lyric( String _line ) { + if ( _line.length() <= 0 ) { + Phrase = "a"; + setPhoneticSymbol( "a" ); + UnknownFloat = 1.0f; + m_protected = false; + } else { + String[] spl = _line.split( "," ); + int c_length = spl.length - 3; + if ( spl.length < 4 ) { + Phrase = "a"; + setPhoneticSymbol( "a" ); + UnknownFloat = 0.0f; + m_protected = false; + } else { + Phrase = decode( spl[0] ); + setPhoneticSymbol( decode( spl[1] ) ); + UnknownFloat = Float.valueOf( spl[2] ); + m_protected = (spl[spl.length - 1] == "0") ? false : true; + } + + } + } + + + /// + /// mIndexOfのテストメソッド。search, valueをいろいろ変えてテストする事。 + /// + /// + public static boolean test_mIndexOf() { + byte[] search = { 0, 12, 3, 5, 16, 34 }; + byte[] value = { 16, 34 }; + if ( mIndexOf( search, value ) == 4 ) { + return true; + } else { + return false; + } + + } + + + /// + /// バイト並びsearchの中に含まれるバイト並びvalueの位置を探します。 + /// + /// 検索対象のバイト並び + /// 検索するバイト並び + /// valueが見つかればそのインデックスを、見つからなければ-1を返します + private static int mIndexOf( byte[] search, byte[] value ) { + int i, j; + int search_length = search.length; + int value_length = value.length; + + // 検索するバイト並びが、検索対象のバイト並びより長いとき。 + // 見つかるわけない + if ( value_length > search_length ) { + return -1; + } + + // i : 検索の基点 + for ( i = 0; i <= search_length - value_length; i++ ) { + boolean failed = false; + for ( j = 0; j < value_length; j++ ) { + if ( search[i + j] != value[j] ) { + failed = true; + break; + } + } + if ( !failed ) { + return i; + } + } + return -1; + } + + /** + * エスケープされた\"や、\x**を復帰させます + * @param _String デコード対象の文字列 + * @returns デコード後の文字列 + */ + public static String decode( String _String ) { + String result = _String; + result = result.replace( "\\\"", "" ); + //Encoding sjis = Encoding.GetEncoding( 932 ); + //Encoding sjis = Encoding.GetEncoding( "Shift_JIS" ); + byte[] str = result.getBytes(); + + //Console.WriteLine( "Lyric.decode; sjis.GetString( str )=" + sjis.GetString( str ) ); + byte[] x16 = "\\x".getBytes(); + int index = mIndexOf( str, x16 ); + while ( index >= 0 ) { + //Console.WriteLine( "Lyric.decode; index=" + index ); + byte[] chr_byte = new byte[2]; + chr_byte[0] = str[index + 2]; + chr_byte[1] = str[index + 3]; + String chr; + try { + chr = new String( chr_byte, "UTF-8" ); + } catch ( Exception e ) { + chr = ""; + } + //Console.WriteLine( "Lyric.decode; chr=" + chr ); + int chrcode = Integer.parseInt( chr, 16 ); + str[index] = (byte) chrcode; + for ( int i = index + 4; i < str.length; i++ ) { + str[i - 3] = str[i]; + } + + int length = str.length - 3; + byte[] new_str = new byte[length]; + for ( int i = 0; i < length; i++ ) { + new_str[i] = str[i]; + } + str = new_str; + index = mIndexOf( str, x16 ); + } + //return sjis.GetString( str ); + return cp932.convert( str ); + } + + +/// +/// 与えられた文字列の中の2バイト文字を\x**の形式にエンコードします。 +/// +/// エンコード対象 +/// エンコードした文字列 + public static char[] encode( String item ) { + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] bytea = cp932.convert( item );// sjis.GetBytes( item ); + + String result = ""; + for ( int i = 0; i < + bytea.length; i++ ) { + if ( isprint( (char) bytea[i] ) ) { + result += (char) bytea[i]; + } else { + int a = bytea[i]; + result += "\\x" + Integer.toHexString( (int) bytea[i] ); + } + + } + char[] res = result.toCharArray(); + return res; + } + + +/// +/// 与えられた文字列をShift_JISとみなし、byte[]に変換しさらにchar[]に変換したもの返します +/// +/// 変換元の文字列 +/// 変換後のchar[] + public static char[] encodeEx( String item ) { + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] dat = cp932.convert( item );// sjis.GetBytes( item ); + + char[] result = new char[dat.length]; + for ( int i = 0; i < dat.length; i++ ) { + result[i] = (char) dat[i]; + } + + return result; + } + + +/// +/// このインスタンスを文字列に変換します +/// +/// 2バイト文字をエンコードするか否かを指定するフラグ +/// 変換後の文字列 + public String toString( boolean a_encode ) { + String result; + if ( a_encode ) { + String njp = new String( encode( this.Phrase ) ); + result = "\"" + njp + "\",\"" + getPhoneticSymbol() + "\"," + String.format( "0.000000", UnknownFloat ); + } else { + result = "\""; + //Encoding sjis = Encoding.GetEncoding( 932 ); + byte[] dat = cp932.convert( this.Phrase );// sjis.GetBytes( this.Phrase ); + + for ( int i = 0; i < dat.length; i++ ) { + result += (char) dat[i]; + } + result += "\",\"" + getPhoneticSymbol() + "\"," + String.format( "0.000000", UnknownFloat ); + result = result.replace( "\\\\", "\\" ); + } + for ( int i = 0; i < m_consonant_adjustment.length; i++ ) { + result += "," + m_consonant_adjustment[i]; + } + + if ( m_protected ) { + result += ",1"; + } else { + result += ",0"; + } + + return result; + } + + +/// +/// 文字がプリント出力可能かどうかを判定します +/// +/// +/// + private static boolean isprint( char ch ) { + if ( 32 <= (int) ch && (int) ch <= 126 ) { + return true; + } else { + return false; + } + + } + + + /// + /// Lyricインスタンスを構築するテストを行います + /// + /// テストに成功すればtrue、そうでなければfalseを返します + public static boolean test() { + + String line = "\\\"\\x82\\xe7\\\",\\\"4 a\\\",1.000000,64,1,1"; + //Console.WriteLine( "Lyric.test; line=" + line ); + Lyric lyric = new Lyric( line ); + if ( lyric.Phrase == "ら" && + lyric.getPhoneticSymbol() == "4 a" && + lyric.UnknownFloat == 1.0 && + lyric.m_consonant_adjustment[0] == 64 && + lyric.m_consonant_adjustment[1] == 1 && + lyric.m_consonant_adjustment[2] == 1 ) { + return true; + } else { + return false; + } + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/LyricHandle.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/LyricHandle.java new file mode 100644 index 0000000..857e1ad --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/LyricHandle.java @@ -0,0 +1,47 @@ +/* + * LyricHandle.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class LyricHandle extends VsqHandle implements Cloneable { + public LyricHandle() { + } + + + /// + /// type = Lyric用のhandleのコンストラクタ + /// + /// 歌詞 + /// 発音記号 + public LyricHandle( String phrase, String phonetic_symbol ) { + Type = VsqHandleType.Lyric; + L0 = new Lyric( phrase, phonetic_symbol ); + } + + /*public property Lyric L0 { + get { + return m_lyric; + } + set { + m_lyric = value; + } + }*/ + public Object clone() { + LyricHandle ret = new LyricHandle(); + ret.Type = Type; + ret.Index = Index; + ret.L0 = (Lyric)L0.clone(); + return ret; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEvent.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEvent.java new file mode 100644 index 0000000..f059d23 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEvent.java @@ -0,0 +1,122 @@ +/* + * MidiEvent.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class MidiEvent implements Comparable, Cloneable { + public int index; + public MidiEventType type; + public int[] intValue; + public String stringValue; + public byte[] byteValue; + + public static MidiEvent TempoChange( int clock, int tempo ) { + MidiEvent res = new MidiEvent(); + res.index = clock; + res.type = MidiEventType.tempo; + res.intValue = new int[1]; + res.intValue[0] = tempo; + return res; + } + + public static MidiEvent TimeSig( int clock, int numerator, int denominator ) { + MidiEvent res = new MidiEvent(); + res.index = clock; + res.type = MidiEventType.time_signal; + res.intValue = new int[2]; + res.intValue[0] = numerator; + res.intValue[1] = denominator; + return res; + } + + public Object clone() { + MidiEvent res = new MidiEvent(); + res.index = index; + res.type = type; + if ( intValue != null ) { + res.intValue = new int[intValue.length]; + for ( int i = 0; i < intValue.length; i++ ) { + res.intValue[i] = intValue[i]; + } + } + res.stringValue = stringValue; + if ( byteValue != null ) { + res.byteValue = new byte[byteValue.length]; + for ( int i = 0; i < byteValue.length; i++ ) { + res.byteValue[i] = byteValue[i]; + } + } + return res; + } + + public int compareTo( MidiEvent obj ) { + return this.index - obj.index; + } + + public boolean Equals( MidiEvent obj ) { + if ( this.index == obj.index ) { + return true; + } else { + return false; + } + } + + private MidiEvent() { + } + + /** + * かきかけ。メタテキスト以外のmidiイベントを取り扱う。 + * @param line + */ + public MidiEvent( String line ) { + index = -1; + type = MidiEventType.unknown; + //intValue = new int[1]; + //intValue[0] = -9000; + stringValue = ""; + byteValue = null; + + String[] spl = line.split( " " ); + index = Integer.parseInt( spl[0] ); + if ( spl[1].equals( "Tempo" ) ) { + type = MidiEventType.tempo; + intValue = new int[1]; + intValue[0] = Integer.parseInt( spl[2] ); + } else if ( spl[1].equals( "TimeSig" ) ) { + type = MidiEventType.time_signal; + intValue = new int[4]; + String[] spl2 = spl[2].split( "/" ); + intValue[0] = Integer.parseInt( spl2[0] ); + intValue[1] = Integer.parseInt( spl2[1] ); + intValue[2] = Integer.parseInt( spl[3] ); + intValue[3] = Integer.parseInt( spl[4] ); + } else if ( spl[1].equals( "Par" ) ) { + type = MidiEventType.parameter; + intValue = new int[3]; + String[] spl3 = spl[2].split( "=" ); + intValue[0] = Integer.parseInt( spl3[1] ); + spl3 = spl[3].split( "=" ); + intValue[1] = Integer.parseInt( spl3[1] ); + spl3 = spl[4].split( "=" ); + intValue[2] = Integer.parseInt( spl3[1] ); + } else { + type = MidiEventType.unknown; + stringValue = spl[2]; + for ( int i = 1; i < spl.length; i++ ) { + stringValue += " " + spl[i]; + } + } + + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEventType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEventType.java new file mode 100644 index 0000000..af27baa --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiEventType.java @@ -0,0 +1,71 @@ +/* + * MidiEvent.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public enum MidiEventType { + /// + /// channel = 0~15の値 + /// + channel, + /// + /// note = 0~127の値 + /// + note, + /// + /// dtime = 0~268,435,455 (0x0FFFFFFF)の値 + /// + dtime, + /// + /// velocity = 0~127の値 + /// + velocity, + /// + /// patch = 0~127の値 + /// + patch, + /// + /// sequence = 0-65,535 (0xFFFF)の値 + /// + sequence, + /// + /// text = 0byte以上のASCII文字列 + /// + text, + /// + /// raw = 0byte以上のバイナリデータの文字列 + /// + raw, + /// + /// pitch_wheel = -8192~8191 (0x1FFF)の値 + /// + pitch_wheel, + /// + /// song_pos = 0~16,383 (0x3FFF)の値 + /// + song_pos, + /// + /// song_number = 0~127の値 + /// + song_number, + /// + /// tempo = マイクロ秒, 0~16,777,215 (0x00FFFFFF)の値 + /// + tempo, + time_signal, + unknown, + /// + /// 勝手に追加。スイマセン + /// + parameter, +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiFile.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiFile.java new file mode 100644 index 0000000..c9f7bae --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/MidiFile.java @@ -0,0 +1,1636 @@ +/* + * NrpnData.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.io.*; + class MidiFile { + /* MIDI status commands most significant bit is 1 */ + final int note_off = 0x80; + final int note_on = 0x90; + final int poly_aftertouch = 0xa0; + final int control_change = 0xb0; + final int program_chng = 0xc0; + final int channel_aftertouch = 0xd0; + final int pitch_wheel = 0xe0; + final int system_exclusive = 0xf0; + final int delay_packet = 1111; + + /* 7 bit controllers */ + final int damper_pedal = 0x40; + final int portamento = 0x41; + final int sostenuto = 0x42; + final int soft_pedal = 0x43; + final int general_4 = 0x44; + final int hold_2 = 0x45; + final int general_5 = 0x50; + final int general_6 = 0x51; + final int general_7 = 0x52; + final int general_8 = 0x53; + final int tremolo_depth = 0x5c; + final int chorus_depth = 0x5d; + final int detune = 0x5e; + final int phaser_depth = 0x5f; + + /* parameter values */ + final int data_inc = 0x60; + final int data_dec = 0x61; + + /* parameter selection */ + final int non_reg_lsb = 0x62; + final int non_reg_msb = 0x63; + final int reg_lsb = 0x64; + final int reg_msb = 0x65; + + /* Standard MIDI Files meta event definitions */ + final int meta_event = 0xFF; + final int sequence_number = 0x00; + final int text_event = 0x01; + final int copyright_notice = 0x02; + final int sequence_name = 0x03; + final int instrument_name = 0x04; + final int lyric = 0x05; + final int marker = 0x06; + final int cue_point = 0x07; + final int channel_prefix = 0x20; + final int end_of_track = 0x2f; + final int set_tempo = 0x51; + final int smpte_offset = 0x54; + final int time_signature = 0x58; + final int key_signature = 0x59; + final int sequencer_specific = 0x7f; + + /* Manufacturer's ID number */ + final int Seq_Circuits = 0x01; /* Sequential Circuits Inc. */ + final int Big_Briar = 0x02; /* Big Briar Inc. */ + final int Octave = 0x03; /* Octave/Plateau */ + final int Moog = 0x04; /* Moog Music */ + final int Passport = 0x05; /* Passport Designs */ + final int Lexicon = 0x06; /* Lexicon */ + final int Tempi = 0x20; /* Bon Tempi */ + final int Siel = 0x21; /* S.I.E.L. */ + final int Kawai = 0x41; + final int Roland = 0x42; + final int Korg = 0x42; + final int Yamaha = 0x43; + + /* miscellaneous definitions */ + final long MThd = 0x4d546864L; + final long MTrk = 0x4d54726bL; + + final int MTHD = 256; + final int MTRK = 257; + final int TRKEND = 258; + + final int ON = note_on;//#define ON note_on + final int OFF = note_off; + final int POPR = poly_aftertouch; + final int PAR = control_change; + final int PB = pitch_wheel; + final int PRCH = program_chng; + final int CHPR = channel_aftertouch; + final int SYSEX = system_exclusive; + + final int ARB = 259; + final int MINOR = 260; + final int MAJOR = 261; + + final int CH = 262; + final int NOTE = 263; + final int VAL = 264; + final int CON = 265; + final int PROG = 266; + + static final int INT = 267; + static final int STRING = 268; + final int STRESC = 269; + final int ERR = 270; + final int NOTEVAL = 271; + final int EOL = 272; + + final int META = 273; + final int SEQSPEC = (META + 1 + sequencer_specific); + final int TEXT = (META + 1 + text_event); + final int COPYRIGHT = (META + 1 + copyright_notice); + final int SEQNAME = (META + 1 + sequence_name); + final int INSTRNAME = (META + 1 + instrument_name); + final int LYRIC = (META + 1 + lyric); + final int MARKER = (META + 1 + marker); + final int CUE = (META + 1 + cue_point); + final int SEQNR = (META + 1 + sequence_number); + final int KEYSIG = (META + 1 + key_signature); + final int TEMPO = (META + 1 + set_tempo); + final int TIMESIG = (META + 1 + time_signature); + final int SMPTE = (META + 1 + smpte_offset); + + private final int EOF = -1; + private RandomAccessFile F = null; + //private StreamWriter sw = null; + private StringBuilder sb = null; + //private StreamReader yyin = null; + + private final int FALSE = 0; + private final int TRUE = 1; + + static int err_cont = 0; + + private int fold = 0; /* fold long lines */ + private int notes = 0; /* print notes as a-g */ + private int times = 0; /* print times as Measure/beat/click */ + private static int Measure, M0, Beat, Clicks; + private int TrksToDo = 1; + private int TrkNr; + private static long T0; + static char[] buffer = new char[] { }; + static int bufsiz = 0, buflen; + + private static String note = "n"; + private static String vol = "v"; + private static String con = "c"; + private static String val = "v"; + private static String prog = "p"; + + private static String PolyPr = "PoPr"; + private static String Param = "Par"; + private static String ProgCh = "PrCh"; + private static String ChanPr = "ChPr"; + + static int Format, Ntrks; + + private long Mf_currtime; + private int Mf_nomerge; + private long Mf_toberead; + private String Msgbuff; + private int Msgindex; + + //wtrackDelegate Mf_wtrack = null; + //wtrackDelegate Mf_wtempotrack = null; + //putcDelegate Mf_putc = null; + static long Mf_numbyteswritten = 0L; + + /*extern */ + static long yyval; + /*extern */ + static int eol_seen; + /*extern */ + static int lineno; + /*extern */ + static int yyleng; + /*extern */ + static String yytext; + /*extern */ + static int do_hex; + /*extern */ + static int Mf_RunStat; + + static int laststat; /* last status code */ + static int lastmeta; /* last meta event type */ + + static char[] data = new char[5];//changed to static + static int chan;//staticに変更 + + private int m_nrpn_msb, m_nrpn_lsb; + + public String ReadToEnd() { + return sb.toString(); + } + + + public MidiFile( String smf_path/*, String text_path, Mode mode*/ ) { + //if ( mode == Mode.Read ) { + F = new RandomAccessFile( smf_path, "r" ); + //sw = new StreamWriter( text_path ); + sb = new StringBuilder(); + Mf_toberead = 0L; + Mf_currtime = 0L; + Mf_nomerge = 0; + Mf_nomerge = 1; + TrkNr = 0; + Measure = 4; + Beat = 0x60; + Clicks = 0x60; + T0 = 0L; + M0 = 0; + readheader(); + while ( readtrack() != 0 ) { + } + //sw.Close(); + /*} else if ( mode == Mode.Write ) { + yyin = new StreamReader( text_path ); + F = new FileStream( smf_path, FileMode.Create, FileAccess.Write ); + Mf_putc = fileputc; + Mf_wtrack = mywritetrack; + TrkNr = 0; + Measure = 4; + Beat = 96; + Clicks = 96; + M0 = 0; + T0 = 0; + translate(); + F.Close(); + yyin.Close(); + }*/ + } + + public void close() { + if ( F != null ) { + F.close(); + } + } + + // region t2mf + + int getbyte( String mess ) { + //char ermesg[100]; + getint( mess ); + if ( yyval < 0 || yyval > 127 ) { + String ermesg = "Wrong value (" + yyval + ") for " + mess;// sprintf (ermesg, "Wrong value (%ld) for %s", yyval, mess); + error( ermesg ); + yyval = 0; + } + return (int)yyval; + } + + + static void gethex() { + int c; + buflen = 0; + do_hex = 1; + c = yylex(); + if ( c == STRING ) { + /* Note: yytext includes the trailing, but not the starting quote */ + int i = 0; + if ( yyleng - 1 > bufsiz ) { + bufsiz = yyleng - 1; + if ( buffer != null ) { + buffer = realloc( buffer, bufsiz ); + } else { + buffer = malloc( bufsiz ); + } + /*if ( !buffer ){//buffer == TRUE => buffer != FALSE -> buffer != 0 + error( "Out of memory" ); + }さくじょしました。。*/ + } + while ( i < yyleng - 1 ) { + c = yytext[i++]; + rescan: + if ( c == '\\' ) { + switch ( c = yytext[i++] ) { + case '0': + c = '\0'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'x': + //yytext[i]の位置の文字が16進数で使われる文字じゃないとき + try { + Int32.Parse( "" + yytext[i] ); + c = yytext[i]; + } catch(Exception ex ) { + prs_error( "Illegal \\x in String" ); + } + /*if ( sscanf( yytext + i, "%2x", &c ) != 1 ) + prs_error( "Illegal \\x in String" );*/ + i += 2; + break; + case '\r': + case '\n': + c = yytext.charAt( i++ ); + while ( c == ' ' || c == '\t' || c == '\r' || c == '\n' ){ + /* skip whitespace */ + c = yytext.charAt( i++ ); + } + goto rescan; /* sorry EWD :=) */ + } + } + buffer[buflen++] = (char)c; + } + } else if ( c == INT ) { + do { + if ( buflen >= bufsiz ) { + bufsiz += 128; + if ( buffer != null ) {// buffer == TRUE -> buffer != FALSE => buffer != 0 + buffer = realloc( buffer, bufsiz ); + } else { + buffer = malloc( bufsiz ); + } + /*if ( !buffer ) { + error( "Out of memory" ); + }削除しました。。*/ + } + /* This test not applicable for sysex + if (yyval < 0 || yyval > 127) + error ("Illegal hex value"); */ + buffer[buflen++] = (char)yyval; + c = yylex(); + } while ( c == INT ); + if ( c != EOL ) + prs_error( "Unknown hex input" ); + } else + prs_error( "String or hex input expected" ); + } + + + static int yylex() { + // TODO: THIS IS DUMY!! + return 0; + } + + static void prs_error( String s ) {//static二変更j + int c = 0; + int count; + int ln = (eol_seen != FALSE ? lineno - 1 : lineno); + Console.WriteLine( ln + ": " + s );// fprintf( stderr, "%d: %s\n", ln, s ); + if ( yyleng > 0 && yytext != "\n" ) { + Console.WriteLine( "*** " + yyleng + " " + yytext + " ***" );//fprintf( stderr, "*** %*s ***\n", yyleng, yytext ); + } + count = 0; + while ( count < 100 && (c = yylex()) != EOL && c != EOF ) { + count++/* skip rest of line */; + } + if ( c == EOF ) { + Environment.Exit( 1 );// exit( 1 ); + } + if ( err_cont != FALSE ) { + //longjmp( erjump, 1 ); + throw new Exception( s ); + } + } + + + static char[] realloc( char[] source, int size ) { + char[] result = new char[size]; + for ( int i = 0; i < size; i++ ) { + if ( i < source.Length ) { + result[i] = source[i]; + } else { + break; + } + } + return result; + } + + + static char[] malloc( int size ) { + return new char[size]; + } + + + static void checkeol() { + if ( eol_seen != FALSE ) { + return; + } + if ( yylex() != EOL ) { + prs_error( "Garbage deleted" ); + while ( eol_seen == FALSE/*!eol_seen*/ ) { + yylex(); /* skip rest of line */ + } + } + } + + private void translate() { + if ( yylex() == MTHD ) { + Format = getint( "MFile format" ); + Ntrks = getint( "MFile #tracks" ); + Clicks = getint( "MFile Clicks" ); + if ( Clicks < 0 ) { + Clicks = (Clicks & 0xff) << 8 | getint( "MFile SMPTE division" ); + } + checkeol(); + mfwrite( Format, Ntrks, Clicks, F ); + } else { + Console.WriteLine( "Missing MFile - can't continue\n" ); + Environment.Exit( 1 ); + } + } + + + private void mfwrite( int format, int ntracks, int division, RandomAccessFile fp ) { + int i; + //void mf_w_track_chunk(), mf_w_header_chunk(); + + if ( Mf_putc == null/*NULLFUNC*/ ) { + mferror( "mfmf_write() called without setting Mf_putc" ); + } + + if ( Mf_wtrack == null/*NULLFUNC*/ ) { + mferror( "mfmf_write() called without setting Mf_mf_writetrack" ); + } + + /* every MIDI file starts with a header */ + mf_w_header_chunk( format, ntracks, division ); + + /* In format 1 files, the first track is a tempo map */ + if ( format == 1 && (Mf_wtempotrack != null) ) { + mf_w_track_chunk( -1, fp, Mf_wtempotrack ); + ntracks--; + } + + /* The rest of the file is a series of tracks */ + for ( i = 0; i < ntracks; i++ ) { + mf_w_track_chunk( i, fp, Mf_wtrack ); + } + } + + + void mf_w_header_chunk( int format, int ntracks, int division ) { + ulong ident, length; + //void write16bit(),write32bit(); + + ident = MThd; /* Head chunk identifier */ + length = 6; /* Chunk length */ + + /* individual bytes of the header must be written separately + to preserve byte order across cpu types :-( */ + write32bit( ident ); + write32bit( length ); + write16bit( format ); + write16bit( ntracks ); + write16bit( division ); + } /* end gen_header_chunk() */ + + + //Delegate int wtrackDelegate(); + //delegate int putcDelegate( int c ); + + private void mf_w_track_chunk( int which_track, RandomAccessFile fp, wtrackDelegate wtrack /* int (*wtrack) wtrack*/) { + ulong trkhdr, trklength; + long offset, place_marker; + //void write16bit(),write32bit(); + + trkhdr = MTrk; + trklength = 0; + + /* Remember where the length was written, because we don't + know how long it will be until we've finished writing */ + offset = fp.Position;//ftell( fp ); + /* Write the track chunk header */ + write32bit( trkhdr ); + write32bit( trklength ); + + Mf_numbyteswritten = 0L; /* the header's length doesn't count */ + laststat = 0; + + /* Note: this calls Mf_writetempotrack with an unused parameter (-1) + But this is innocent */ + + wtrack();//引数無くていいんかな。。。 (*wtrack)( which_track ); + + if ( laststat != meta_event || lastmeta != end_of_track ) { + /* mf_write End of track meta event */ + eputc( 0 ); + eputc( meta_event ); + eputc( end_of_track ); + eputc( 0 ); + } + + laststat = 0; + + /* It's impossible to know how long the track chunk will be beforehand, + so the position of the track length data is kept so that it can + be written after the chunk has been generated */ + place_marker = fp.Position;// ftell( fp ); + + /* This method turned out not to be portable because the + parameter returned from ftell is not guaranteed to be + in bytes on every machine */ + /* track.length = place_marker - offset - (long) sizeof(track); */ + + + fp.seek( offset ); + + trklength = Mf_numbyteswritten; + + /* Re-mf_write the track chunk header with right length */ + write32bit( trkhdr ); + write32bit( trklength ); + + fp.seek( place_marker );// fseek( fp, place_marker, 0 ); + } + + private void write32bit( long data ) { + eputc( (int)((data >> 24) & 0xff) ); + eputc( (int)((data >> 16) & 0xff) ); + eputc( (int)((data >> 8) & 0xff) ); + eputc( (int)(data & 0xff) ); + } + + + void write16bit( int data ) { + eputc( (int)((data & 0xff00) >> 8) ); + eputc( (int)(data & 0xff) ); + } + + + private int eputc( int c )/*unsigned char c*/{ + if ( Mf_putc == null )/* == NULLFUNC*/ { + mferror( "Mf_putc undefined" ); + return (-1); + } + + //return_val = (*Mf_putc)( c ); + int return_val = Mf_putc( c ); + + if ( return_val == EOF ) { + mferror( "error writing" ); + } + + Mf_numbyteswritten++; + return (return_val); + } + + + static void checkchan() { + if ( yylex() != CH || yylex() != INT ) { + syntax(); + } + if ( yyval < 1 || yyval > 16 ) { + error( "Chan must be between 1 and 16" ); + } + chan = (int)yyval - 1; + } + + + static void checknote() { + int c = 0; + if ( yylex() != NOTE || ((c = yylex()) != INT && c != NOTEVAL) ) { + syntax(); + } + if ( c == NOTEVAL ) { + /*static */ + int[] notes = new int[]{ + 9, /* a */ + 11, /* b */ + 0, /* c */ + 2, /* d */ + 4, /* e */ + 5, /* f */ + 7 /* g */ + }; + + //char* p = yytext; + String p = yytext; + int index = 0; + c = p[index];//*p++; + if ( Char.IsUpper( (char)c )/* isupper( c )*/ ) { + String temp = c + ""; + temp = temp.ToLower(); + c = (int)temp[0];//tolower( c ); + } + yyval = notes[c - 'a']; + switch ( p[index]/**p*/ ) { + case '#': + case '+': + yyval++; + //p++; + index++; + break; + case 'b': + case 'B': + case '-': + yyval--; + //p++; + index++; + break; + } + yyval += 12 * Intger.parseInt( p );//atoi( p ); + } + if ( yyval < 0 || yyval > 127 ) + error( "Note must be between 0 and 127" ); + data[0] = (char)yyval; + } + + + static void syntax() {//staticに変更した + prs_error( "Syntax error" ); + } + + + static void checkval() { + if ( yylex() != VAL || yylex() != INT ) + syntax(); + if ( yyval < 0 || yyval > 127 ) + error( "Value must be between 0 and 127" ); + data[1] = (char)yyval; + } + + + static void splitval() { + if ( yylex() != VAL || yylex() != INT ) + syntax(); + if ( yyval < 0 || yyval > 16383 ) + error( "Value must be between 0 and 16383" ); + data[0] = (char)(yyval % 128); + data[1] = (char)(yyval / 128); + } + + + static void get16val() { + if ( yylex() != VAL || yylex() != INT ) + syntax(); + if ( yyval < 0 || yyval > 65535 ) + error( "Value must be between 0 and 65535" ); + data[0] = (char)((yyval >> 8) & 0xff); + data[1] = (char)(yyval & 0xff); + } + + + static void checkcon() { + if ( yylex() != CON || yylex() != INT ) + syntax(); + if ( yyval < 0 || yyval > 127 ) + error( "Controller must be between 0 and 127" ); + data[0] = (char)yyval; + } + + + void WriteVarLen( long value ) { + long buffer; + + buffer = value & 0x7f; + while ( (value >>= 7) > 0 ) { + buffer <<= 8; + buffer |= 0x80; + buffer += (value & 0x7f); + } + while ( true/*1*/ ) { + eputc( (int)(buffer & 0xff) ); + + if ( (buffer & 0x80) != FALSE ) + buffer >>= 8; + else + return; + } + }/* end of WriteVarLen */ + + + int mf_w_midi_event( long delta_time, int type, int chan, char[] data, long size ) { + //int i; + /*unsigned */ + char c; + + WriteVarLen( delta_time ); + + /* all MIDI events start with the type in the first four bits, + and the channel in the lower four bits */ + c = (char)(type | chan); + + if ( chan > 15 ) { + //perror( "error: MIDI channel greater than 16\n" ); + Console.Error.WriteLine( "error: MIDI channel greater than 16" ); + } + + if ( Mf_RunStat == FALSE || laststat != c ) + eputc( c ); + + laststat = c; + + /* write out the data bytes */ + for ( ulong i = 0; i < size; i++ ) { + eputc( (int)(data[i]) ); + } + + return (int)size; + } /* end mf_write MIDI event */ + + + int mf_w_meta_event( long delta_time, int type, char[] data, long size ) { + //int i; + + WriteVarLen( delta_time ); + + /* This marks the fact we're writing a meta-event */ + eputc( meta_event ); + laststat = meta_event; + + /* The type of meta event */ + eputc( (int)type ); + lastmeta = (int)type; + + /* The length of the data bytes to follow */ + WriteVarLen( size ); + + for ( ulong i = 0; i < size; i++ ) { + if ( eputc( data[i] ) != data[i] ) { + return (-1); + } + } + return (int)size; + } /* end mf_w_meta_event */ + + + static void checkprog() { + if ( yylex() != PROG || yylex() != INT ) + syntax(); + if ( yyval < 0 || yyval > 127 ) + error( "Program number must be between 0 and 127" ); + data[0] = (char)yyval; + } + + + int mf_w_sysex_event(long delta_time, char[] data, long size ) { + //int i; + + WriteVarLen( delta_time ); + + /* The type of sysex event */ + eputc( data[0] );//eputc( *data ); + laststat = 0; + + /* The length of the data bytes to follow */ + WriteVarLen( size - 1 ); + + for ( ulong i = 1; i < size; i++ ) { + if ( eputc( data[i] ) != data[i] ) + return (-1); + } + return (int)size; + } /* end mf_w_sysex_event */ + + + void mf_w_tempo( long delta_time, long tempo ) { + /* Write tempo */ + /* all tempos are written as 120 beats/minute, */ + /* expressed in microseconds/quarter note */ + + WriteVarLen( delta_time ); + + eputc( meta_event ); + laststat = meta_event; + eputc( set_tempo ); + + eputc( 3 ); + eputc( (int)(0xff & (tempo >> 16)) ); + eputc( (int)(0xff & (tempo >> 8)) ); + eputc( (int)(0xff & tempo) ); + } + + + int mywritetrack() { + int opcode, c; + long currtime = 0; + long newtime, delta; + int i, k; + + while ( (opcode = yylex()) == EOL ) + ; + if ( opcode != MTRK ) + prs_error( "Missing MTrk" ); + checkeol(); + while ( true/*1*/ ) { + err_cont = 1; + //setjmp( erjump ); + try { + switch ( yylex() ) { + case MTRK: + prs_error( "Unexpected MTrk" ); + continue; + case EOF: + err_cont = 0; + error( "Unexpected EOF" ); + return -1; + case TRKEND: + err_cont = 0; + checkeol(); + return 1; + case INT: + newtime = yyval; + if ( (opcode = yylex()) == '/' ) { + if ( yylex() != INT ) + prs_error( "Illegal time value" ); + newtime = (newtime - M0) * Measure + yyval; + if ( yylex() != '/' || yylex() != INT ) + prs_error( "Illegal time value" ); + newtime = T0 + newtime * Beat + yyval; + opcode = yylex(); + } + delta = newtime - currtime; + switch ( opcode ) { + case ON: + case OFF: + case POPR: + checkchan(); + checknote(); + checkval(); + mf_w_midi_event( (ulong)delta, (uint)opcode, (uint)chan, data, (char)2L ); + break; + + case PAR: + checkchan(); + checkcon(); + checkval(); + mf_w_midi_event( (ulong)delta, (uint)opcode, (uint)chan, data, (char)2L ); + break; + + case PB: + checkchan(); + splitval(); + mf_w_midi_event( (ulong)delta, (uint)opcode, (uint)chan, data, (char)2L ); + break; + + case PRCH: + checkchan(); + checkprog(); + mf_w_midi_event( (ulong)delta, (uint)opcode, (uint)chan, data, (char)1L ); + break; + + case CHPR: + checkchan(); + checkval(); + data[0] = data[1]; + mf_w_midi_event( (ulong)delta, (uint)opcode, (uint)chan, data, (char)1L ); + break; + + case SYSEX: + case ARB: + gethex(); + mf_w_sysex_event( (ulong)delta, buffer, (ulong)buflen ); + break; + + case TEMPO: + if ( yylex() != INT ) + syntax(); + mf_w_tempo( (ulong)delta, (ulong)yyval ); + break; + + case TIMESIG: { + int nn, denom, cc, bb; + if ( yylex() != INT || yylex() != '/' ) + syntax(); + nn = (int)yyval; + denom = getbyte( "Denom" ); + cc = getbyte( "clocks per click" ); + bb = getbyte( "32nd notes per 24 clocks" ); + for ( i = 0, k = 1; k < denom; i++, k <<= 1 ) + ; + if ( k != denom ) + error( "Illegal TimeSig" ); + data[0] = (char)nn; + data[1] = (char)i; + data[2] = (char)cc; + data[3] = (char)bb; + M0 += (int)((newtime - T0) / (Beat * Measure)); + T0 = newtime; + Measure = nn; + Beat = 4 * Clicks / denom; + mf_w_meta_event( (ulong)delta, time_signature, data, 4L ); + } + break; + + case SMPTE: + for ( i = 0; i < 5; i++ ) { + data[i] = (char)getbyte( "SMPTE" ); + } + mf_w_meta_event( (ulong)delta, smpte_offset, data, 5L ); + break; + + case KEYSIG: + data[0] = (char)getint( "Keysig" ); + if ( data[0] < -7 || data[0] > 7 ) + error( "Key Sig must be between -7 and 7" ); + if ( (c = yylex()) != MINOR && c != MAJOR ) { + syntax(); + } + if ( c == MINOR ) { + data[1] = (char)TRUE;//(c == MINOR); + } else { + data[1] = (char)FALSE; + } + mf_w_meta_event( (ulong)delta, key_signature, data, 2L ); + break; + + case SEQNR: + //get16val( "SeqNr" ); + get16val();// + mf_w_meta_event( (ulong)delta, sequence_number, data, 2L ); + break; + + case META: { + int type = yylex(); + switch ( type ) { + case TRKEND: + type = end_of_track; + break; + case TEXT: + case COPYRIGHT: + case SEQNAME: + case INSTRNAME: + case LYRIC: + case MARKER: + case CUE: + type -= (META + 1); + break; + case INT: + type = (int)yyval; + break; + default: + prs_error( "Illegal Meta type" ); + break; + } + if ( type == end_of_track ) + buflen = 0; + else + gethex(); + mf_w_meta_event( (ulong)delta, (uint)type, buffer, (ulong)buflen ); + break; + } + case SEQSPEC: + gethex(); + mf_w_meta_event( (ulong)delta, sequencer_specific, buffer, (ulong)buflen ); + break; + default: + prs_error( "Unknown input" ); + break; + } + currtime = newtime; + break; + case EOL: + break; + default: + prs_error( "Unknown input" ); + break; + } + } catch (Exception ex ) { + continue; + } + checkeol(); + } + } + + + static int getint( String mess ) {//changed to static + //char[] ermesg = new char[100]; + if ( yylex() != INT ) { + String ermesg = "Integer expected for " + mess;//sprintf( ermesg, "Integer expected for %s", mess ); + error( ermesg ); + yyval = 0; + } + return (int)yyval; + } + + + int fileputc( int c ) { + //return putc(c, F); + F.WriteByte( (byte)c ); + return 0; + } + + + // Functions to be called while processing the MIDI file. + + private int getc() { + try { + int res; + res = F.ReadByte(); + return res; + } catch ( Exception e ) { + Console.Error.WriteLine( e.StackTrace ); + return EOF; + } + } + + private static void error( String s ) {//static二変更 + /*if ( TrksToDo <= 0 ) { + Console.Error.WriteLine( "Error: Garbage at end" ); + } else { + Console.Error.WriteLine( "Error: " + s ); + }*/ + } + + + private void header( int format, int ntrks, int division ) { + if ( (division & 0x8000) != FALSE ) { + // SMPTE + times = 0; /* Can't do beats */ + sb.append( "MFile " + format + " " + ntrks + " " + (-((-(division >> 8)) & 0xff)) + " " + (division & 0xff) + "\n" ); + } else { + sb.append( "MFile " + format + " " + ntrks + " " + division + "\n" ); + } + //Console.Writef("MFile %d %d %d\n",format,ntrks,division); + if ( format > 2 ) { + //fprintf(stderr, "Can't deal with format %d files\n", format); + Console.Error.WriteLine( "Can't deal with format " + format + " files" ); + //Console.Writef("Can't deal with format %d files\n", format); + //System.Environment.Exit( 1 ); + return; + } + Beat = Clicks = division; + TrksToDo = ntrks; + } + + private void starttrack() { + //sw.WriteLine( "MTrk" ); + sb.append( "MTrk\n" ); + TrkNr++; + } + + private void endtrack() { + //sw.WriteLine( "TrkEnd" ); + sb.append( "TrkEnd\n" ); + --TrksToDo; + } + + private void on( int chan, int pitch, int v ) { + prtime(); + //sw.WriteLine( "On ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + vol + "=" + v ); + sb.append( "On ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + vol + "=" + v + "\n" ); + } + + private void off( int chan, int pitch, int v ) { + prtime(); + //sw.WriteLine( "Off ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + vol + "=" + v ); + sb.append( "Off ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + vol + "=" + v + "\n" ); + } + + private void pressure( int chan, int pitch, int press ) { + prtime(); + //sw.WriteLine( PolyPr + " ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + val + "=" + press ); + sb.append( PolyPr + " ch=" + (chan + 1) + " " + note + "=" + mknote( pitch ) + " " + val + "=" + press + "\n" ); + } + + class Comment { + public int Index; + public String Msb; + public String Lsb; + public Comment( int index, String msb, String lsb ) { + Index = index; + Msb = msb; + Lsb = lsb; + } + } + + private void parameter( int chan, int control, int value ) { + prtime(); + //sw.WriteLine( Param + " ch=" + (chan + 1) + " " + con + "=" + control + " " + val + "=" + value ); + sb.append( Param + " ch=" + (chan + 1) + " " + con + "=" + control + " " + val + "=" + value + "\n" ); + } + + private void pitchbend( int chan, int lsb, int msb ) { + prtime(); + //sw.WriteLine( "Pb ch=" + (chan + 1) + " " + val + "=" + (128 * msb + lsb) ); + sb.append( "Pb ch=" + (chan + 1) + " " + val + "=" + (128 * msb + lsb) + "\n" ); + } + + private void program( int chan, int program ) { + prtime(); + //sw.WriteLine( ProgCh + " ch=" + (chan + 1) + " " + prog + "=" + program ); + sb.append( ProgCh + " ch=" + (chan + 1) + " " + prog + "=" + program + "\n" ); + } + + private void chanpressure( int chan, int press ) { + prtime(); + //sw.WriteLine( ChanPr + " ch=" + (chan + 1) + " " + val + "=" + press ); + sb.append( ChanPr + " ch=" + (chan + 1) + " " + val + "=" + press + "\n" ); + } + + private void sysex() { + sysex( msgleng(), msg() ); + } + private void sysex( int leng, String mess ) { + prtime(); + //sw.Write( "SysEx" ); + sb.append( "SysEx" ); + prhex( mess, leng ); + } + + private void arbitrary( int leng, String mess ) { + prtime(); + //sw.Write( "Arb" ); + sb.append( "Arb" ); + prhex( mess, leng ); + } + + private void metamisc( int type, int leng, String mess ) { + prtime(); + //sw.Write( "Meta 0x" + Convert.ToString( type, 16 ) ); + sb.append( "Meta 0x" + Convert.ToString( type, 16 ) ); + prhex( mess, leng ); + } + + private void seqnum( int num ) { + prtime(); + //sw.WriteLine( "SeqNr " + num ); + sb.append( "SeqNr " + num + "\n" ); + } + + private void eot() { + prtime(); + //sw.WriteLine( "Meta TrkEnd" ); + sb.append( "Meta TrkEnd\n" ); + } + + private void smpte( int hr, int mn, int se, int fr, int ff ) { + prtime(); + //sw.WriteLine( "SMPTE " + hr + " " + mn + " " + se + " " + fr + " " + ff ); + sb.append( "SMPTE " + hr + " " + mn + " " + se + " " + fr + " " + ff + "\n" ); + } + + private void tempo( long tempo ) { + prtime(); + //sw.WriteLine( "Tempo " + tempo ); + sb.append( "Tempo " + tempo +"\n" ); + } + + private void timesig( int nn, int dd, int cc, int bb ) { + int denom = 1; + while ( dd-- > 0 ) { + denom *= 2; + } + prtime(); + //sw.WriteLine( "TimeSig " + nn + "/" + denom + " " + cc + " " + bb ); + sb.append( "TimeSig " + nn + "/" + denom + " " + cc + " " + bb + "\n" ); + M0 += (int)(Mf_currtime - T0) / (Beat * Measure); + T0 = Mf_currtime; + Measure = nn; + Beat = 4 * Clicks / denom; + } + + private void keysig( int sf, int mi ) { + prtime(); + if ( mi != FALSE ) { + //sw.WriteLine( "KeySig " + sf + " " + "minor" ); + sb.append( "KeySig " + sf + " " + "minor\n" ); + } else { + //sw.WriteLine( "KeySig " + sf + " " + "major" ); + sb.append( "KeySig " + sf + " " + "major\n" ); + } + } + + private void sqspecific( int leng, String mess ) { + prtime(); + //sw.Write( "SeqSpec" ); + sb.append( "SeqSpec" ); + prhex( mess, leng ); + } + + private void text( int type, int leng, String mess ) { + String[] ttype = { + "", + "Text", /* type=0x01 */ + "Copyright", /* type=0x02 */ + "TrkName", + "InstrName", /* ... */ + "Lyric", + "Marker", + "Cue", /* type=0x07 */ + "Unrec" + }; + + int unrecognized = ttype.Length - 1; + + prtime(); + if ( type < 1 || type > unrecognized ) { + //sw.Write( "Meta 0x" + Convert.ToString( type, 16 ) ); + sb.append( "Meta 0x" + Convert.ToString( type, 16 ) ); + prtext( mess, leng ); + } else if ( type == 3 && TrkNr == 1 ) { + //sw.Write( "Meta SeqName " ); + sb.append( "Meta SeqName " ); + prtext( mess, leng ); + } else { + //sw.Write( "Meta " + ttype[type] + " " ); + sb.append( "Meta " + ttype[type] + " " ); + prtext( mess, leng ); + } + } + + + // support functions for mf2t + + private void prtime() { + if ( times != FALSE ) { + long m = (Mf_currtime - T0) / Beat; + //sw.Write( "" + (m / Measure + M0) + ":" + (m % Measure) + ":" + ((Mf_currtime - T0) % Beat) + " " ); + sb.append( "" + (m / Measure + M0) + ":" + (m % Measure) + ":" + ((Mf_currtime - T0) % Beat) + " " ); + } else { + //sw.Write( "" + Mf_currtime + " " ); + sb.append( "" + Mf_currtime + " " ); + } + } + + private void prtext( String p, int leng ) { + //Console.Error.WriteLine( "prtext" ); + int n; + char c; + int pos = 25; + //int index = -1; + //sw.Write( "\"" ); + sb.append( "\"" ); + for ( n = 0; n < leng; n++ ) { + //index++; + char[] t = p.substring( n, n + 1 ).toCharArray(); + c = t[0]; + if ( fold != FALSE && (pos >= fold) ) { + //sw.Write( "\\" + Environment.NewLine + "\t" );//"\\\n\t"); + sb.append( "\\" + "\n" + "\t" ); + pos = 13; /* tab + \xab + \ */ + if ( c == ' ' || c == '\t' ) { + //sw.Write( "\\" ); + sb.append( "\\" ); + ++pos; + } + } + switch ( c ) { + case '\\': + case '"': + //sw.Write( "\\" + c ); + sb.append( "\\" + c ); + pos += 2; + break; + case '\r': + //sw.Write( "\\r" ); + sb.append( "\\r" ); + pos += 2; + break; + case '\n': + //sw.Write( "\\n" ); + sb.append( "\\n" ); + pos += 2; + break; + case '\0': + //sw.Write( "\\-" ); + sb.append( "\\-" ); + pos += 2; + break; + default: + if ( isprint( c ) ) { + //sw.Write( c.ToString() ); + sb.append( c.ToString() ); + ++pos; + } else { + //sw.Write( "\\x" + Convert.ToString( (int)c, 16 ) ); + sb.append( "\\x" + Convert.ToString( (int)c, 16 ) ); + pos += 4; + } + break; + } + //Console.Error.WriteLine( "in for loop" ); + } + //Console.Error.WriteLine( "buffer=" + buffer ); + //sw.WriteLine( "\"" ); + sb.append( "\"\n" ); + } + + private String mknote( int pitch ) { + String[] Notes = { "c", "c#", "d", "d#", "e", "f", "f#", "g", "g#", "a", "a#", "b" }; + if ( notes != FALSE ) { + return Notes[pitch % 12] + pitch / 12; + } else { + return "" + pitch; + } + } + + private int msgleng() { + return Msgindex; + } + + + private String msg() { + return Msgbuff; + } + + private void prhex( String p, int leng ) { + int n; + int pos = 25; + + int index = -1; + for ( n = 0; n < leng; n++, index++ ) { + if ( fold != FALSE && (pos) >= fold ) { + //sw.Write( "\\" + Environment.NewLine + "\t" + Convert.ToString( (int)char.Parse( p.SubString( index, 1 ) ), 16 ) ); + sb.append( "\\" + "\n" + "\t" + Convert.ToString( (int)char.Parse( p.SubString( index, 1 ) ), 16 ) ); + pos = 14; /* tab + ab + " ab" + \ */ + } else { + //sw.Write( " " + Convert.ToString( (int)char.Parse( p.SubString( index, 1 ) ), 16 ) ); + sb.append( " " + Convert.ToString( (int)char.Parse( p.SubString( index, 1 ) ), 16 ) ); + pos += 3; + } + } + //sw.WriteLine( "" ); + sb.append( "\n" ); + } + + private static boolean isprint( char ch ) { + if ( 32 <= (int)ch && (int)ch <= 126 ) { + return true; + } else { + return false; + } + } + + private void readheader() { + if ( readmt( "MThd" ) != -1 ) { + Mf_toberead = read32bit(); + int format = read16bit(); + int ntrks = read16bit(); + int division = read16bit(); + header( format, ntrks, division ); + while ( Mf_toberead > 0L ) { + egetc(); + } + } + } + + private int readtrack() { + int[] ttype = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0 }; + int num2 = 0; + int num4 = 0; + int num5 = 0; + int status = 0; + if ( readmt( "MTrk" ) == -1 ) { + return 0; + } + Mf_toberead = read32bit(); + Mf_currtime = 0L; + starttrack(); + while ( Mf_toberead > 0L ) { + long unrecognized; + Mf_currtime += readvarinum(); + int c = egetc(); + if ( (num4 != 0) && (c != 0xf7) ) { + mferror( "didn't find expected continuation of a sysex" ); + } + if ( (c & 0x80) == 0 ) { + if ( status == 0 ) { + mferror( "unexpected running status" ); + } + num5 = 1; + num2 = c; + c = status; + } else if ( c < 240 ) { + status = c; + num5 = 0; + } + int num7 = ttype[(c >> 4) & 15]; + if ( num7 != 0 ) { + if ( num5 == 0 ) { + num2 = egetc(); + } + chanmessage( status, num2, (num7 <= 1) ? 0 : egetc() ); + continue; + } + switch ( c ) { + case 0xff: { + int type = egetc(); + unrecognized = (Mf_toberead - readvarinum()) - 1L; + msginit(); + while ( Mf_toberead > unrecognized ) { + msgadd( egetc() ); + } + metaevent( type ); + continue; + } + case 240: { + unrecognized = Mf_toberead - readvarinum(); + msginit(); + msgadd( 240 ); + while ( Mf_toberead > unrecognized ) { + msgadd( c = egetc() ); + } + if ( (c != 0xf7) && (Mf_nomerge != 0) ) { + break; + } + sysex(); + continue; + } + case 0xf7: { + unrecognized = Mf_toberead - readvarinum(); + if ( num4 == 0 ) { + msginit(); + } + while ( Mf_toberead > unrecognized ) { + msgadd( c = egetc() ); + } + if ( num4 == 0 ) { + arbitrary( msgleng(), msg() ); + } else if ( c == 0xf7 ) { + sysex(); + num4 = 0; + } + continue; + } + default: + goto Label_0260; + } + num4 = 1; + continue; + Label_0260: + badbyte( c ); + } + endtrack(); + //Console.Write( buffer ); + return 1; + } + + private int readmt( String s ) { + String res = s; + int num2 = 4; + int[] e = new int[num2]; + e[0] = getc(); + e[1] = getc(); + e[2] = getc(); + e[3] = getc(); + for ( int i = 0; i < 4; i++ ) { + if ( e[i] != char.Parse( res.SubString( i, 1 ) ) ) { + mferror( "expecting " + s ); + } + } + return e[3]; + } + + private void mferror( String s ) { + error( s ); + //System.Environment.Exit( 1 ); + } + + private int read16bit() { + int num = egetc(); + int num2 = egetc(); + return to16bit( num, num2 ); + } + + + private long read32bit() { + int num = egetc(); + int num2 = egetc(); + int num3 = egetc(); + int num4 = egetc(); + return to32bit( num, num2, num3, num4 ); + } + + + private int egetc() { + int num = getc(); + if ( num == EOF ) { + mferror( "premature EOF" ); + } + Mf_toberead -= 1L; + return num; + } + + private long readvarinum() { + int num2 = egetc(); + long num = num2; + if ( (num2 & 0x80) != 0 ) { + num &= 0x7fL; + do { + num2 = egetc(); + num = (num << 7) + (num2 & 0x7f); + } while ( (num2 & 0x80) != 0 ); + } + return num; + } + + private void chanmessage( int status, int c1, int c2 ) { + int chan = status & 15; + switch ( (status & 240) ) { + case 0x80: + off( chan, c1, c2 ); + break; + + case 0x90: + on( chan, c1, c2 ); + break; + + case 160: + pressure( chan, c1, c2 ); + break; + + case 0xb0: + parameter( chan, c1, c2 ); + break; + + case 0xe0: + pitchbend( chan, c1, c2 ); + break; + + case 0xc0: + program( chan, c1 ); + break; + + case 0xd0: + chanpressure( chan, c1 ); + break; + } + } + + private void msginit() { + Msgindex = 0; + Msgbuff = ""; + } + + private void msgadd( int c ) { + Msgbuff = Msgbuff + (char)c; + Msgindex++; + } + + private void metaevent( int type ) { + int leng = msgleng(); + String m = msg(); + switch ( type ) { + case 0: + seqnum( to16bit( + (int)char.Parse( m.SubString( 0, 1 ) ), + (int)char.Parse( m.SubString( 1, 1 ) ) ) + ); + break; + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + text( type, leng, m ); + break; + + case 0x2f: + eot(); + break; + + case 0x51: + tempo( to32bit( + 0, + (int)char.Parse( m.SubString( 0, 1 ) ), + (int)char.Parse( m.SubString( 1, 1 ) ), + (int)char.Parse( m.SubString( 2, 1 ) ) ) + ); + break; + + case 0x54: + smpte( + (int)char.Parse( m.SubString( 0, 1 ) ), + (int)char.Parse( m.SubString( 1, 1 ) ), + (int)char.Parse( m.SubString( 2, 1 ) ), + (int)char.Parse( m.SubString( 3, 1 ) ), + (int)char.Parse( m.SubString( 4, 1 ) ) + ); + break; + + case 0x58: + timesig( + (int)char.Parse( m.SubString( 0, 1 ) ), + (int)char.Parse( m.SubString( 1, 1 ) ), + (int)char.Parse( m.SubString( 2, 1 ) ), + (int)char.Parse( m.SubString( 3, 1 ) ) + ); + break; + + case 0x59: + keysig( + (int)char.Parse( m.SubString( 0, 1 ) ), + (int)char.Parse( m.SubString( 1, 1 ) ) + ); + break; + + case 0x7f: + sqspecific( leng, m ); + break; + + default: + metamisc( type, leng, m ); + break; + } + } + + private void badbyte( int c ) { + mferror( "unexpected byte: " + c ); + } + + private static int to16bit( int c1, int c2 ) { + return (((c1 & 0xff) << 8) + (c2 & 0xff)); + } + + + private static long to32bit( int c1, int c2, int c3, int c4 ) { + long num = 0L; + num = c1 & 0xff; + num = (num << 8) + (c2 & 0xff); + num = (num << 8) + (c3 & 0xff); + return ((num << 8) + (c4 & 0xff)); + } + } diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/NrpnData.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/NrpnData.java new file mode 100644 index 0000000..72a4b20 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/NrpnData.java @@ -0,0 +1,49 @@ +/* + * NrpnData.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class NrpnData { + //private int m_clock; + public int Clock; + //private byte m_parameter; + public byte Parameter; + //private byte m_value; + public byte Value; + + public NrpnData( int clock, byte parameter, byte value ) { + Clock = clock; + Parameter = parameter; + Value = value; + } + + + /*public property int Clock { + get { + return m_clock; + } + };*/ + /*public property byte Parameter { + get { + return m_parameter; + } + };*/ + /*public property byte Value { + get { + return m_value; + } + set { + m_value = value; + } + };*/ +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SMFReader.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SMFReader.java new file mode 100644 index 0000000..58bf4d7 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SMFReader.java @@ -0,0 +1,50 @@ +/* + * SMFReader.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; +import java.util.*; +/// + /// SMFファイルを解析し、テキストファイル形式のデータに変換します + /// + public class SMFReader { + //private StreamReader sr = null; + + private MidiFile m_midi = null; + //private String _result = ""; + private Vector m_lines; + + /// + /// デフォルトコンストラクタ。コンストラクトと同時に解析を行い、指定されたファイルに結果を格納します。 + /// + /// 解析対象のファイルへのパス + public SMFReader( String _path ) { + //_result = Path.GetTempFileName(); + m_midi = new MidiFile( _path );//, _result, Mode.Read ); + //sr = new StreamReader( _result ); + m_lines = new Vector(); + String[] splitted = m_midi.ReadToEnd().split( "\n" ); + for( int i = 0; i < splitted.length; i++ ){ + String spl = splitted[i]; + m_lines.add( spl ); + } + } + + public void dispose() { + m_midi.close(); + } + + public Vector getLines() { + return m_lines; + } + +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SingerConfig.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SingerConfig.java new file mode 100644 index 0000000..0121f2c --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/SingerConfig.java @@ -0,0 +1,327 @@ +/* + * SingerConfig.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +import java.io.*; +import jp.sourceforge.lipsync.bocoree.*; + +public class SingerConfig { + public String ID = "VOCALOID:VIRTUAL:VOICE"; + public String FORMAT = "2.0.0.0"; + public String VOICEIDSTR = ""; + public String VOICENAME = "Miku"; + public int Breathiness = 0; + public int Brightness = 0; + public int Clearness = 0; + public int Opening = 0; + public int GenderFactor = 0; + public int Original = 0; + + public static void decode_vvd_bytes( Vector dat ) { + for ( int i = 0; i < dat.size(); i++ ) { + byte b = (Byte)dat.get( i ); + byte M = (byte)(b >> 4); + byte L = (byte)(b - (M << 4)); + byte newM = endecode_vvd_m( M ); + byte newL = endecode_vvd_l( L ); + dat.set( i, (byte)((newM << 4) | newL) ); + } + } + + private static byte endecode_vvd_l( byte value ) { + switch ( value ) { + case 0x0: + return 0xa; + case 0x1: + return 0xb; + case 0x2: + return 0x8; + case 0x3: + return 0x9; + case 0x4: + return 0xe; + case 0x5: + return 0xf; + case 0x6: + return 0xc; + case 0x7: + return 0xd; + case 0x8: + return 0x2; + case 0x9: + return 0x3; + case 0xa: + return 0x0; + case 0xb: + return 0x1; + case 0xc: + return 0x6; + case 0xd: + return 0x7; + case 0xe: + return 0x4; + case 0xf: + return 0x5; + } + return 0x0; + } + + private static byte endecode_vvd_m( byte value ) { + switch ( value ) { + case 0x0: + return 0x1; + case 0x1: + return 0x0; + case 0x2: + return 0x3; + case 0x3: + return 0x2; + case 0x4: + return 0x5; + case 0x5: + return 0x4; + case 0x6: + return 0x7; + case 0x7: + return 0x6; + case 0x8: + return 0x9; + case 0x9: + return 0x8; + case 0xa: + return 0xb; + case 0xb: + return 0xa; + case 0xc: + return 0xd; + case 0xd: + return 0xc; + case 0xe: + return 0xf; + case 0xf: + return 0xe; + } + return 0x0; + } + + public SingerConfig( String file, int original ) throws FileNotFoundException, IOException { + Original = original; + FileInputStream fs = new FileInputStream( file ); + File f = new File( file ); + int length = (int)f.length(); + byte[] tdat = new byte[length]; + fs.read( tdat, 0, length ); + Vector dat = new Vector(); + decode_vvd_bytes( dat ); + for ( int i = 0; i < dat.size() - 1; i++ ) { + tdat[i] = (Byte)dat.get( i ); + } + for ( int i = 0; i < tdat.length - 1; i++ ) { + byte b = tdat[i]; + if ( b == 0x17 && b == 0x10 ) { + tdat[i] = 0x0d; + tdat[i + 1] = 0x0a; + } + } + String str = cp932.convert( tdat ); + String crlf = Character.toString( (char)0x0d ) + Character.toString( (char)0x0a ); + String[] spl = str.split( crlf ); + + for ( int i = 0; i < spl.length; i++ ) { + String s = spl[i]; + int first = s.indexOf( '"' ); + int first_end = get_quated_String( s, first ); + int second = s.indexOf( '"', first_end + 1 ); + int second_end = get_quated_String( s, second ); + char[] chs = s.toCharArray(); + String id = new String( chs, first, first_end - first + 1 ); + String value = new String( chs, second, second_end - second + 1 ); + id = id.substring( 1, id.length() - 2 ); + value = value.substring( 1, value.length() - 2 ); + value = value.replace( "\\\"", "\"" ); + if ( id.equals( "ID" ) ) { + ID = value; + } else if ( id.equals( "FORMAT" ) ) { + FORMAT = value; + } else if ( id.equals( "VOICEIDSTR" ) ) { + VOICEIDSTR = value; + } else if ( id.equals( "VOICENAME" ) ) { + VOICENAME = value; + } else if ( id.equals( "Breathiness" ) ) { + try { + Breathiness = Integer.parseInt( value ); + } catch ( Exception e ) { + } + } else if ( id.equals( "Brightness" ) ) { + try { + Brightness = Integer.parseInt( value ); + } catch ( Exception e ) { + } + } else if ( id.equals( "Clearness" ) ) { + try { + Clearness = Integer.parseInt( value ); + } catch ( Exception e ) { + } + } else if ( id.equals( "Opening" ) ) { + try { + Opening = Integer.parseInt( value ); + } catch ( Exception e ) { + } + } else if ( id.equals( "Gender:Factor" ) ) { + try { + GenderFactor = Integer.parseInt( value ); + } catch ( Exception e ) { + } + } + } + } + + +/// +/// 位置positionにある'"'から,次に現れる'"'の位置を調べる.エスケープされた\"はスキップされる.'"'が見つからなかった場合-1を返す +/// +/// +/// +/// + private static int get_quated_String( String s, int position ) { + if ( position < 0 ) { + return -1; + } + + char[] chs = s.toCharArray(); + if ( position >= chs.length ) { + return -1; + } + + if ( chs[position] != '"' ) { + return -1; + } + + int end = -1; + for ( int i = position + 1; i < + chs.length; i++ ) { + if ( chs[i] == '"' && chs[i - 1] != '\\' ) { + end = i; + break; + } + } + return end; + } + + // ここ注意!! + public String[] toStringEx() { + Vector ret = new Vector(); + ret.add( "\"ID\":=:\"" + ID + "\"" ); + ret.add( "\"FORMAT\":=:\"" + FORMAT + "\"" ); + ret.add( "\"VOICEIDSTR\":=:\"" + VOICEIDSTR + "\"" ); + ret.add( "\"VOICENAME\":=:\"" + VOICENAME.replace( "\"", "\\\"" ) + "\"" ); + ret.add( "\"Breathiness\":=:\"" + Breathiness + "\"" ); + ret.add( "\"Brightness\":=:\"" + Brightness + "\"" ); + ret.add( "\"Clearness\":=:\"" + Clearness + "\"" ); + ret.add( "\"Opening\":=:\"" + Opening + "\"" ); + ret.add( "\"Gender:Factor\":=:\"" + GenderFactor + "\"" ); + return ret.toArray( new String[]{} ); + } + + /*public property int Original { + get { + return m_original; + } + set { + m_original = value; + } + };*/ + + /*public property String ID { + get { + return m_id; + } + set { + m_id = value; + } + };*/ + + /*public property String FORMAT { + get { + return m_format; + } + set { + m_format = value; + } + };*/ + + /*public property String VOICEIDSTR { + get { + return m_voiceidstr; + } + set { + m_voiceidstr = value; + } + };*/ + + /*public proprety String VOICENAME { + get { + return m_voicename; + } + set { + m_voicename = value; + } + };*/ + + /*public property int Breathiness { + get { + return m_breathiness; + } + set { + m_breathiness = value; + } + };*/ + + /*public property int Brightness { + get { + return m_brightness; + } + set { + m_brightness = value; + } + };*/ + + /*public property int Clearness { + get { + return m_clearness; + } + set { + m_clearness = value; + } + };*/ + + /*public proprety int Opening { + get { + return m_opening; + } + set { + m_opening = value; + } + };*/ + + /*public property int GenderFactor { + get { + return m_gender_factor; + } + set { + m_gender_factor = value; + } + };*/ +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TempoTableEntry.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TempoTableEntry.java new file mode 100644 index 0000000..0ae83a5 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TempoTableEntry.java @@ -0,0 +1,70 @@ +/* + * BPPair.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class TempoTableEntry implements Comparable, Cloneable { + //private int m_clock; + public int Clock; + //private int m_tempo; + public int Tempo; + //private double m_time; + public double Time; + + /*public property int Tempo { + get { + return m_tempo; + } + set { + m_tempo = value; + } + };*/ + /*public property double Time { + get { + return m_time; + } + set { + m_time = value; + } + };*/ + /*public property int Clock { + get { + return m_clock; + } + set { + m_clock = value; + } + };*/ + public Object clone() { + return new TempoTableEntry( Clock, Tempo, Time ); + } + + public TempoTableEntry( int _index, int _tempo, double _time ) { + this.Clock = _index; + this.Tempo = _tempo; + this.Time = _time; + } + + public int compareTo( TempoTableEntry entry ) { + return this.Clock - entry.Clock; + } + + public boolean equals( TempoTableEntry entry ) { + if ( this.Clock == entry.Clock ) { + return true; + } else { + return false; + } + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextMemoryStream.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextMemoryStream.java new file mode 100644 index 0000000..bcec866 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextMemoryStream.java @@ -0,0 +1,112 @@ +/* + * TextMemoryStream.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.io.*; +import java.util.*; + +/** + * + * @author kbinani + */ +public class TextMemoryStream { + StringBuilder m_ms = null; + int m_position; + + /// + /// + /// + /// + public void write( String value ) { + m_ms.append( value ); + m_position = m_ms.length(); + } + + public void rewind() { + m_position = 0; + } + + public void writeLine( String s ) { + m_ms.append( s + "\n" ); + } + + public void close() { + if ( m_ms != null ) { + m_ms = null; + } + } + + public int peek() { + if ( m_position >= m_ms.length() ) { + return -1; + } else { + return (int)m_ms.charAt( m_position ); + } + } + + private int readByte() { + if ( m_position >= m_ms.length() ) { + return -1; + } else { + m_position++; + return (int)m_ms.charAt( m_position ); + } + } + + public String readLine() { + int ret; + ret = readByte(); + ArrayList buffer = new ArrayList(); + while ( ret >= 0 ) { + char ch = (char)ret; + if ( ch == '\n' ) { + int next; + long current = m_position; //0x0Dを検出した直後のストリームの位置 + + break; + } + buffer.add( ch ); + ret = readByte(); + } + String ans = ""; + for ( int i = 0; i < buffer.size(); i++ ) { + ans += buffer.get( i ); + } + return ans; + } + + public void dispose() { + close(); + } + + public TextMemoryStream( String path, String encoding ) throws Exception { + m_ms = new StringBuilder(); + File f = new File( path ); + if ( f.exists() ) { + FileReader fis = new FileReader( f ); + BufferedReader br = new BufferedReader( fis ); + while ( br.ready() ) { + String line = br.readLine(); + m_ms.append( line + "\n" ); + } + } + m_position = 0; + } + + public TextMemoryStream() { + m_ms = new StringBuilder(); + m_position = 0; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextResult.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextResult.java new file mode 100644 index 0000000..bba9c89 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TextResult.java @@ -0,0 +1,43 @@ +/* + * TextResult.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public class TextResult { + private String m_value; + + /** + * + * @param value + */ + public TextResult( String value ) { + m_value = value; + } + + /** + * + * @return + */ + public String get() { + return m_value; + } + + public void set( String value ) { + m_value = value; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TimeSigTableEntry.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TimeSigTableEntry.java new file mode 100644 index 0000000..eaabcb2 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/TimeSigTableEntry.java @@ -0,0 +1,90 @@ +/* + * BPPair.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class TimeSigTableEntry implements Comparable, Cloneable { + //int m_clock; + public int Clock; + //int m_numerator; + public int Numerator; + //int m_denominator; + public int Denominator; + //int m_bar_count; + public int BarCount; + + public Object clone() { + return new TimeSigTableEntry( Clock, Numerator, Denominator, BarCount ); + } + + public int compareTo( TimeSigTableEntry item ) { + return this.BarCount - item.BarCount; + } + + + /*// + /// クロック数 + /// + public property int Clock { + get { + return m_clock; + } + set { + m_clock = value; + } + };*/ + /*// + /// 拍子の分母 + /// + public property int Numerator { + get { + return m_numerator; + } + set { + m_numerator = value; + } + };*/ + /*// + /// 拍子の分母 + /// + public property int Denominator { + get { + return m_denominator; + } + set { + m_denominator = value; + } + };*/ + /*// + /// Clockの時点で何小節目かを取得します。 + /// + public property int BarCount { + get { + return m_bar_count; + } + set { + m_bar_count = value; + } + };*/ + public TimeSigTableEntry( + int clock, + int numerator, + int denominator, + int bar_count ) { + Clock = clock; + Numerator = numerator; + Denominator = denominator; + BarCount = bar_count; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoHandle.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoHandle.java new file mode 100644 index 0000000..7f94723 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoHandle.java @@ -0,0 +1,156 @@ +/* + * VibratoHandle.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public class VibratoHandle extends VsqHandle implements Cloneable { + public Object clone() { + VibratoHandle result = new VibratoHandle(); + result.Type = Type; + result.Index = Index; + result.IconID = IconID; + result.IDS = this.IDS; + result.Original = this.Original; + result.Caption = this.Caption; + result.Length = this.Length; + result.StartDepth = this.StartDepth; + result.DepthBPNum = this.DepthBPNum; + if ( DepthBPX != null ) { + result.DepthBPX = (float[])this.DepthBPX.clone(); + } + if ( DepthBPY != null ) { + result.DepthBPY = (int[])this.DepthBPY.clone(); + } + result.StartRate = this.StartRate; + result.RateBPNum = this.RateBPNum; + if ( this.RateBPX != null ) { + result.RateBPX = (float[])this.RateBPX.clone(); + } + if ( this.RateBPY != null ) { + result.RateBPY = (int[])this.RateBPY.clone(); + } + return result; + } + + + /*public int Original { + get { + return m_original; + } + set { + m_original = value; + } + }*/ + /*public int Length { + get { + return m_length; + } + set { + m_length = value; + } + }*/ + /*public string Caption { + get { + return m_caption; + } + set { + m_caption = value; + } + }*/ + /*public property String IDS { + get { + return m_ids; + } + set { + m_ids = value; + } + };*/ + /*public string IconID { + get { + return m_icon_id; + } + set { + m_icon_id = value; + } + }*/ + + /*public int StartDepth { + get { + return m_start_depth; + } + set { + m_start_depth = value; + } + }*/ + /*public int StartRate { + get { + return m_start_rate; + } + set { + m_start_rate = value; + } + }*/ + /*public int DepthBPNum { + get { + return m_depth_bp_num; + } + set { + m_depth_bp_num = value; + } + }*/ + /*public property int RateBPNum { + get { + return m_rate_bp_num; + } + set { + m_rate_bp_num = value; + } + };*/ + /*public property float[] DepthBPX { + get { + return m_depth_bp_x; + } + set { + m_depth_bp_x = value; + } + };*/ + /*public property int[] DepthBPY { + get { + return m_depth_bp_y; + } + set { + m_depth_bp_y = value; + } + };*/ + /*public property float[] RateBPX { + get { + return m_rate_bp_x; + } + set { + m_rate_bp_x = value; + } + };*/ + + /*public property int[] RateBPY { + get { + return m_rate_bp_y; + } + set { + m_rate_bp_y = value; + } + };*/ +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoType.java new file mode 100644 index 0000000..255c113 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoType.java @@ -0,0 +1,33 @@ +/* + * VibratoType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + + public enum VibratoType{ + NormalType1, + NormalType2, + NormalType3, + NormalType4, + ExtremeType1, + ExtremeType2, + ExtremeType3, + ExtremeType4, + FastType1, + FastType2, + FastType3, + FastType4, + SlightType1, + SlightType2, + SlightType3, + SlightType4, + } \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoTypeUtil.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoTypeUtil.java new file mode 100644 index 0000000..ff1e341 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VibratoTypeUtil.java @@ -0,0 +1,253 @@ +/* + * VibratoType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public class VibratoTypeUtil { + public static VibratoType FromIconID( String icon_id ) { + if ( icon_id.equals( "$04040001" ) ) { + return VibratoType.NormalType1; + } else if ( icon_id.equals( "$04040002" ) ) { + return VibratoType.NormalType2; + } else if ( icon_id.equals( "$04040003" ) ) { + return VibratoType.NormalType3; + } else if ( icon_id.equals( "$0400004" ) ) { + return VibratoType.NormalType4; + } else if ( icon_id.equals( "$04040005" ) ) { + return VibratoType.ExtremeType1; + } else if ( icon_id.equals( "$04040006" ) ) { + return VibratoType.ExtremeType2; + } else if ( icon_id.equals( "$04040007" ) ) { + return VibratoType.ExtremeType3; + } else if ( icon_id.equals( "$04040008" ) ) { + return VibratoType.ExtremeType4; + } else if ( icon_id.equals( "$04040009" ) ) { + return VibratoType.FastType1; + } else if ( icon_id.equals( "$0404000a" ) ) { + return VibratoType.FastType2; + } else if ( icon_id.equals( "$0404000b" ) ) { + return VibratoType.FastType3; + } else if ( icon_id.equals( "$0404000c" ) ) { + return VibratoType.FastType4; + } else if ( icon_id.equals( "$0404000d" ) ) { + return VibratoType.SlightType1; + } else if ( icon_id.equals( "$0404000e" ) ) { + return VibratoType.SlightType2; + } else if ( icon_id.equals( "$0404000f" ) ) { + return VibratoType.SlightType3; + } else if ( icon_id.equals( "$04040010" ) ) { + return VibratoType.SlightType4; + } + + return VibratoType.NormalType1; + } + + public static String GetIconID( VibratoType type ) { + switch ( type ) { + case NormalType1: + return "$04040001"; + case NormalType2: + return "$04040002"; + case NormalType3: + return "$04040003"; + case NormalType4: + return "$0400004"; + case ExtremeType1: + return "$04040005"; + case ExtremeType2: + return "$04040006"; + case ExtremeType3: + return "$04040007"; + case ExtremeType4: + return "$04040008"; + case FastType1: + return "$04040009"; + case FastType2: + return "$0404000a"; + case FastType3: + return "$0404000b"; + case FastType4: + return "$0404000c"; + case SlightType1: + return "$0404000d"; + case SlightType2: + return "$0404000e"; + case SlightType3: + return "$0404000f"; + case SlightType4: + return "$04040010"; + } + return ""; + } + + public static VibratoHandle GetDefaultVibratoHandle( VibratoType type, int vibrato_clocks ) { + VibratoHandle res = new VibratoHandle(); + res.Type = VsqHandleType.Vibrato; + res.Length = vibrato_clocks; + res.Original = 1; + res.DepthBPNum = 0; + res.RateBPNum = 0; + res.Caption = toString( type ); + res.IconID = GetIconID( type ); + switch ( type ) { + case NormalType1: + res.IDS = "normal"; + res.StartDepth = 64; + res.StartRate = 50; + break; + case NormalType2: + res.IDS = "normal"; + res.StartDepth = 40; + res.StartRate = 40; + break; + case NormalType3: + res.IDS = "normal"; + res.StartDepth = 127; + res.StartRate = 50; + break; + case NormalType4: + res.IDS = "normal"; + res.StartDepth = 64; + res.DepthBPNum = 57; + res.DepthBPX = new float[]{ 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }; + res.DepthBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + res.StartRate = 50; + res.RateBPNum = 52; + res.RateBPX = new float[]{ 0.600000f, 0.612500f, 0.616400f, 0.621100f, 0.628900f, 0.633600f, 0.637500f, 0.641400f, 0.653900f, 0.658600f, 0.662500f, 0.666400f, 0.675000f, 0.683600f, 0.687500f, 0.691400f, 0.700000f, 0.703900f, 0.708600f, 0.712500f, 0.725000f, 0.728900f, 0.732800f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.771100f, 0.775000f, 0.778900f, 0.783600f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.816400f, 0.821100f, 0.828900f, 0.833600f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.866400f, 0.871100f, 0.875000f, 0.878900f, 0.887500f, 0.891400f, 0.900000f, 1.000000f }; + res.RateBPY = new int[]{ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + break; + case ExtremeType1: + res.IDS = "extreme"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case ExtremeType2: + res.IDS = "extreme"; + res.StartDepth = 32; + res.StartRate = 32; + break; + case ExtremeType3: + res.IDS = "extreme"; + res.StartDepth = 100; + res.StartRate = 50; + break; + case ExtremeType4: + res.IDS = "extreme"; + res.StartDepth = 64; + res.DepthBPNum = 57; + res.DepthBPX = new float[]{ 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }; + res.DepthBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + res.StartRate = 64; + res.RateBPNum = 57; + res.RateBPX = new float[]{ 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }; + res.RateBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + break; + case FastType1: + res.IDS = "fast"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case FastType2: + res.IDS = "fast"; + res.StartDepth = 40; + res.StartRate = 50; + break; + case FastType3: + res.IDS = "fast"; + res.StartDepth = 80; + res.StartRate = 70; + break; + case FastType4: + res.IDS = "fast"; + res.StartDepth = 64; + res.DepthBPNum = 57; + res.DepthBPX = new float[]{ 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }; + res.DepthBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + res.StartRate = 64; + res.RateBPNum = 57; + res.RateBPX = new float[]{ 0.603900f, 0.612500f, 0.616400f, 0.621100f, 0.625000f, 0.633600f, 0.637500f, 0.641400f, 0.646100f, 0.653900f, 0.658600f, 0.666400f, 0.670300f, 0.675000f, 0.678900f, 0.683600f, 0.691400f, 0.696100f, 0.703900f, 0.708600f, 0.712500f, 0.716400f, 0.721100f, 0.725000f, 0.728900f, 0.737500f, 0.746100f, 0.750000f, 0.758600f, 0.762500f, 0.766400f, 0.771100f, 0.775000f, 0.783600f, 0.791400f, 0.795300f, 0.800000f, 0.803900f, 0.808600f, 0.812500f, 0.821100f, 0.828900f, 0.837500f, 0.841400f, 0.846100f, 0.850000f, 0.853900f, 0.862500f, 0.866400f, 0.875000f, 0.878900f, 0.883600f, 0.887500f, 0.891400f, 0.896100f, 0.900000f, 1.000000f }; + res.RateBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + break; + case SlightType1: + res.IDS = "slight"; + res.StartDepth = 64; + res.StartRate = 64; + break; + case SlightType2: + res.IDS = "slight"; + res.StartDepth = 40; + res.StartRate = 64; + break; + case SlightType3: + res.IDS = "slight"; + res.StartDepth = 72; + res.StartRate = 64; + break; + case SlightType4: + res.IDS = "slight"; + res.StartDepth = 64; + res.DepthBPNum = 57; + res.DepthBPX = new float[]{ 0.604300f, 0.612500f, 0.616800f, 0.620700f, 0.625000f, 0.633200f, 0.637500f, 0.641800f, 0.645700f, 0.654300f, 0.658200f, 0.666800f, 0.670700f, 0.675000f, 0.679300f, 0.683200f, 0.691800f, 0.695700f, 0.704300f, 0.708200f, 0.712500f, 0.716800f, 0.720700f, 0.725000f, 0.729300f, 0.737500f, 0.745700f, 0.750000f, 0.758200f, 0.762500f, 0.766800f, 0.770700f, 0.775000f, 0.783200f, 0.791800f, 0.795700f, 0.800000f, 0.804300f, 0.808200f, 0.812500f, 0.820700f, 0.829300f, 0.837500f, 0.841800f, 0.845700f, 0.850000f, 0.854300f, 0.862500f, 0.866800f, 0.875000f, 0.879300f, 0.883200f, 0.887500f, 0.891800f, 0.895700f, 0.900000f, 1.000000f }; + res.DepthBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + res.StartRate = 64; + res.RateBPNum = 57; + res.RateBPX = new float[]{ 0.604300f, 0.612500f, 0.616800f, 0.620700f, 0.625000f, 0.633200f, 0.637500f, 0.641800f, 0.645700f, 0.654300f, 0.658200f, 0.666800f, 0.670700f, 0.675000f, 0.679300f, 0.683200f, 0.691800f, 0.695700f, 0.704300f, 0.708200f, 0.712500f, 0.716800f, 0.720700f, 0.725000f, 0.729300f, 0.737500f, 0.745700f, 0.750000f, 0.758200f, 0.762500f, 0.766800f, 0.770700f, 0.775000f, 0.783200f, 0.791800f, 0.795700f, 0.800000f, 0.804300f, 0.808200f, 0.812500f, 0.820700f, 0.829300f, 0.837500f, 0.841800f, 0.845700f, 0.850000f, 0.854300f, 0.862500f, 0.866800f, 0.875000f, 0.879300f, 0.883200f, 0.887500f, 0.891800f, 0.895700f, 0.900000f, 1.000000f }; + res.RateBPY = new int[]{ 64, 63, 62, 61, 59, 58, 57, 56, 55, 54, 52, 51, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 35, 34, 32, 31, 30, 29, 28, 27, 25, 24, 23, 22, 21, 20, 19, 17, 15, 14, 13, 12, 11, 10, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0 }; + break; + } + return res; + } + + public static String toString( VibratoType value ) { + switch ( value ) { + case NormalType1: + return "[Normal] Type 1"; + case NormalType2: + return "[Normal] Type 2"; + case NormalType3: + return "[Normal] Type 3"; + case NormalType4: + return "[Normal] Type 4"; + case ExtremeType1: + return "[Extreme] Type 1"; + case ExtremeType2: + return "[Extreme] Type 2"; + case ExtremeType3: + return "[Extreme] Type 3"; + case ExtremeType4: + return "[Extreme] Type 4"; + case FastType1: + return "[Fast] Type 1"; + case FastType2: + return "[Fast] Type 2"; + case FastType3: + return "[Fast] Type 3"; + case FastType4: + return "[Fast] Type 4"; + case SlightType1: + return "[Slight] Type 1"; + case SlightType2: + return "[Slight] Type 2"; + case SlightType3: + return "[Slight] Type 3"; + case SlightType4: + return "[Slight] Type 4"; + } + return ""; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBPList.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBPList.java new file mode 100644 index 0000000..3f49b36 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBPList.java @@ -0,0 +1,203 @@ +/* + * VsqBPList.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +import java.io.*; + +/** + * ~BPListのデータ部分を取り扱うためのクラス。 + *@author kbinani + */ +public class VsqBPList implements Cloneable { + TreeMap _list = new TreeMap(); + int _default = 0; + int _maximum = 127; + int _minimum = 0; + + public Object clone() { + VsqBPList res = new VsqBPList( _default, _minimum, _maximum ); + Set enumerator = _list.keySet(); + for ( Iterator itr = enumerator.iterator(); itr.hasNext();) { + Integer key = (Integer)itr.next(); + res._list.put( key, _list.get( key ) ); + } + return res; + } + + /** + * コンストラクタ。デフォルト値はココで指定する。 + * @param default_value + */ + public VsqBPList( int default_value, int minimum, int maximum ) { + _default = default_value; + _maximum = maximum; + _minimum = minimum; + } + + /** + * このリストに設定された最大値を取得します。 + */ + public int getMaximum() { + return _maximum; + } + + /** + * このリストに設定された最小値を取得します + /* + public int getMinimum() { + return _minimum; + } + + + /* // + /// _listへのアクセッサ + /// + public SortedList List { + get { + return _list; + } + }*/ + public Set keyClockSet() { + return _list.keySet(); + } + + + public Iterator keyClockIterator(){ + return _list.keySet().iterator(); + } + + public void remove( int clock ) { + if ( _list.containsKey( clock ) ) { + _list.remove( clock ); + } + } + + public boolean containsKey( int clock ) { + return _list.containsKey( clock ); + } + + public int size() { + return _list.size(); + } + + public void clear() { + _list.clear(); + } + + /** + * 新しいデータ点を追加します。 + * + * @param clock + * @param value + */ + public void add( int clock, int value ) { + _list.put( clock, value ); + } + + public int get( int clock ) { + if ( _list.size() == 0 ) { + return _default; + } else { + if ( _list.containsKey( clock ) ) { + return _list.get( clock ); + } else { + int index = 0; + int prev = 0; + for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) { + Integer key = (Integer)itr.next(); + if ( clock < key ) { + index = prev; + break; + } + prev = key; + } + if ( _list.containsKey( index ) ) { + return _list.get( index ); + } else { + return _default; + } + } + } + } + + /** + * このBPListのデフォルト値を取得します + */ + public int getDefault() { + return _default; + } + + /** + * このBPListの内容をテキストファイルに書き出します + * + * @param writer + */ + public void print( BufferedWriter writer ) throws IOException { + boolean first = true; + for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) { + Integer key = (Integer)itr.next(); + int val = _list.get( key ); + if ( first ) { + writer.write( key + "=" + val + "\n" ); + first = false; + } else { + writer.write( key + "=" + val + "\n" ); + } + } + } + + /** + * このBPListの内容をテキストファイルに書き出します + * + * @param writer + */ + public void print( TextMemoryStream writer, int start, String header ) { + boolean first = true; + for ( Iterator itr = _list.keySet().iterator(); itr.hasNext();) { + Integer key = (Integer)itr.next(); + if ( start <= key ) { + if ( first ) { + writer.writeLine( header ); + first = false; + } + int val = _list.get( key ); + writer.writeLine( key + "=" + val ); + } + } + } + + /** + * テキストファイルからデータ点を読込み、現在のリストに追加します + * + * @param reader + * @returns + */ + public String readFrom( TextMemoryStream reader ) { + String last_line = reader.readLine(); + while ( !last_line.startsWith( "[" ) ) { + String[] spl = last_line.split( "=" ); + int i1 = Integer.parseInt( spl[0] ); + int i2 = Integer.parseInt( spl[1] ); + _list.put( i1, i2 ); + if ( reader.peek() < 0 ) { + break; + } else { + last_line = reader.readLine(); + } + } + return last_line; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineEnumeration.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineEnumeration.java new file mode 100644 index 0000000..f3a692b --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineEnumeration.java @@ -0,0 +1,126 @@ +/* + * VsqBarLineEnumeration.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + +/** + * + * @author kbinani + */ +public class VsqBarLineEnumeration implements Enumeration { + Vector TimeSigTable; + int end_clock; + int m_index = 0; + int m_last_clock = -1; + + public VsqBarLineEnumeration( Vector time_sig_table, int t_end_clock ) { + TimeSigTable = time_sig_table; + end_clock = t_end_clock; + m_index = 0; + m_last_clock = -1; + } + + public boolean hasMoreElements() { + if ( m_last_clock < 0 ) { + return true; + } + for ( int i = m_index; i < TimeSigTable.size(); i++ ) { + int denominator = TimeSigTable.get( i ).Denominator; + int numerator = TimeSigTable.get( i ).Numerator; + int local_clock = TimeSigTable.get( i ).Clock; + int bar_count = TimeSigTable.get( i ).BarCount; + int clock_step = 480 * 4 / denominator; + int mod = clock_step * numerator; + int bar_counter = bar_count - 1; + int t_end = end_clock; + if ( i + 1 < TimeSigTable.size() ) { + t_end = TimeSigTable.get( i + 1 ).Clock; + } + int t_start = m_last_clock + clock_step; + for ( int clock = t_start; clock < t_end; clock += clock_step ) { + if ( (clock - local_clock) % mod == 0 ) { + bar_counter++; + return true; + } else { + return true; + } + } + } + return false; + } + + public Object nextElement() { + if ( m_last_clock < 0 ) { + m_last_clock = 0; + return new VsqBarLineType( 0, true, TimeSigTable.get( 0 ).Denominator, TimeSigTable.get( 0 ).Numerator, 0 ); + } + int last = m_index; + for ( m_index = last; m_index < TimeSigTable.size(); m_index++ ) { + int denominator = TimeSigTable.get( m_index ).Denominator; + int numerator = TimeSigTable.get( m_index ).Numerator; + int local_clock = TimeSigTable.get( m_index ).Clock; + int bar_count = TimeSigTable.get( m_index ).BarCount; + int clock_step = 480 * 4 / denominator; + int mod = clock_step * numerator; + int bar_counter = bar_count - 1; + int t_end = end_clock; + if ( m_index + 1 < TimeSigTable.size() ) { + t_end = TimeSigTable.get( m_index + 1 ).Clock; + } + int t_start = m_last_clock + clock_step; + for ( int clock = t_start; clock < t_end; clock += clock_step ) { + if ( (clock - local_clock) % mod == 0 ) { + bar_counter++; + m_last_clock = clock; + return new VsqBarLineType( clock, true, denominator, numerator, bar_counter ); + } else { + m_last_clock = clock; + return new VsqBarLineType( clock, false, denominator, numerator, bar_counter ); + } + } + } + return null; + } + + + /*private Object imp_nextElement() { + int local_denominator; + int local_numerator; + int local_clock; + int local_bar_count; + int clock_step; + for ( int i = 0; i < TimeSigTable.size(); i++ ) { + local_denominator = TimeSigTable.get( i ).Denominator; + local_numerator = TimeSigTable.get( i ).Numerator; + local_clock = TimeSigTable.get( i ).Clock; + local_bar_count = TimeSigTable.get( i ).BarCount; + clock_step = 480 * 4 / local_denominator; + int mod = clock_step * local_numerator; + int bar_counter = local_bar_count - 1; + int t_end = end_clock; + if ( i + 1 < TimeSigTable.size() ) { + t_end = TimeSigTable.get( i + 1 ).Clock; + } + for ( int clock = local_clock; clock < t_end; clock += clock_step ) { + if ( (clock - local_clock) % mod == 0 ) { + bar_counter++; + return new VsqBarLineType( clock, true, local_denominator, local_numerator, bar_counter ); + } else { + return new VsqBarLineType( clock, false, local_denominator, local_numerator, bar_counter ); + } + } + } + }*/ +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineType.java new file mode 100644 index 0000000..2c63f63 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqBarLineType.java @@ -0,0 +1,56 @@ +/* + * VibratoType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class VsqBarLineType { + public int Clock = 0; + public boolean IsSeparator = true; + public int Denominator; + public int Numerator; + public int BarCount; + + /*public property int BarCount { + get { + return m_bar_count; + } + };*/ + /*public property int LocalDenominator { + get { + return m_denominator; + } + };*/ + /*public property int LocalNumerator { + get { + return m_numerator; + } + };*/ + /*public property int Clock { + get { + return m_clock; + } + };*/ + /*public boolean property IsSeparator { + get { + return m_is_separator; + } + };*/ + public VsqBarLineType( int clock, boolean is_separator, int denominator, int numerator, int bar_count ) { + Clock = clock; + IsSeparator = is_separator; + Denominator = denominator; + Numerator = numerator; + BarCount = bar_count; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommand.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommand.java new file mode 100644 index 0000000..fe3073e --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommand.java @@ -0,0 +1,44 @@ +/* + * VsqCommand.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +/// +/// +/// + +public class VsqCommand { + public VsqCommandType Type; + /** + * コマンドの処理内容を保持します。Args具体的な内容は、処理するクラスごとに異なります + */ + public Object[] Args; + /** + * 後続するコマンド + */ + public Vector Children = new Vector(); + /** + * このコマンドの親 + */ + public VsqCommand Parent = null; + + /** + * VsqCommandは各クラスのGenerateCommandからコンストラクトしなければならない。 + * なので、無引数のコンストラクタを隠蔽するためのもの。 + */ + protected VsqCommand() { + //throw new Exception( "このコンストラクトは呼び出しちゃいけませんよ" ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommandType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommandType.java new file mode 100644 index 0000000..bd1d0e3 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommandType.java @@ -0,0 +1,45 @@ +/* + * VsqCommandType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public enum VsqCommandType { + Root, + ChangePreMeasure, + EventAdd, + EventDelete, + EventChangeClock, + EventChangeLyric, + EventChangeNote, + EventChangeClockAndNote, + TrackEditCurve, + TrackEditCurveRange, + EventChangeVelocity, + EventChangeLength, + EventChangeClockAndLength, + EventChangeIDContaints, + EventChangeClockAndIDContaints, + TrackChangeName, + AddTrack, + DeleteTrack, + EventChangeClockAndIDContaintsRange, + EventDeleteRange, + EventAddRange, + UpdateTempo, + UpdateTempoRange, + UpdateTimesig, + UpdateTimesigRange, + EventChangeIDContaintsRange, + TrackReplace, + Replace, +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommon.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommon.java new file mode 100644 index 0000000..55fdb4b --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCommon.java @@ -0,0 +1,103 @@ +/* + * VsqCommon.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.awt.*; + +/** + * vsqファイルのメタテキストの[Common]セクションに記録される内容を取り扱う + * @author kbinani + */ +public class VsqCommon implements Cloneable { + public String m_version; + public String m_name; + public String m_color; + public int m_dynamics_mode; + public int m_play_mode; + + public Object clone() { + String[] spl = m_color.split( ",", 3 ); + int r = Integer.parseInt( spl[0] ); + int g = Integer.parseInt( spl[1] ); + int b = Integer.parseInt( spl[2] ); + Color color = new Color( r, g, b ); + VsqCommon res = new VsqCommon( m_name, color, m_dynamics_mode, m_play_mode ); + res.m_version = m_version; + return res; + } + + /** + * 各パラメータを指定したコンストラクタ + * @param name トラック名 + * @param color Color値(意味は不明) + * @param dynamics_mode DynamicsMode(デフォルトは1) + * @param play_mode PlayMode(デフォルトは1) + */ + public VsqCommon( String name, Color color, int dynamics_mode, int play_mode ) { + m_version = "DSB301"; + m_name = name; + m_color = color.getRed() + "," + color.getGreen() + "," + color.getBlue(); + m_dynamics_mode = dynamics_mode; + m_play_mode = play_mode; + } + + /** + * MetaTextのテキストファイルからのコンストラクタ + * @param sr 読み込むテキストファイル + * @param last_line 読み込んだ最後の行が返される + */ + public VsqCommon( TextMemoryStream sr, TextResult last_line ) { + m_version = ""; + m_name = ""; + m_color = "0,0,0"; + m_dynamics_mode = 0; + m_play_mode = 0; + last_line.set( sr.readLine() ); + String[] spl; + while ( !last_line.get().startsWith( "[" ) ) { + spl = last_line.get().split( "=" ); + if ( spl[0].equals( "Version" ) ) { + this.m_version = spl[1]; + } else if ( spl[0].equals( "Name" ) ) { + this.m_name = spl[1]; + break; + } else if ( spl[0].equals( "Color" ) ) { + this.m_color = spl[1]; + } else if ( spl[0].equals( "DynamicsMode" ) ) { + this.m_dynamics_mode = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "PlayMode" ) ) { + this.m_play_mode = Integer.parseInt( spl[1] ); + } + if ( sr.peek() < 0 ) { + break; + } + last_line.set( sr.readLine() ); + } + } + + /** + * インスタンスの内容をテキストファイルに出力します + * + * @param sw 出力先 + */ + public void write( TextMemoryStream sw ) { + sw.writeLine( "[Common]" ); + sw.writeLine( "Version=" + m_version ); + sw.writeLine( "Name=" + m_name ); + sw.writeLine( "Color=" + m_color ); + sw.writeLine( "DynamicsMode=" + m_dynamics_mode ); + sw.writeLine( "PlayMode=" + this.m_play_mode ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCurveType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCurveType.java new file mode 100644 index 0000000..4df360a --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqCurveType.java @@ -0,0 +1,60 @@ +/* + * VsqCurveType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; +/// +/// vsqファイルで編集可能なカーブ・プロパティの種類 +/// + +public enum VsqCurveType { + /// + /// ベロシティ + /// + VEL, + /// + /// ダイナミクス 64 + /// + DYN, + /// + /// ブレシネス 0 + /// + BRE, + /// + /// ブライトネス 64 + /// + BRI, + /// + /// クリアネス 0 + /// + CLE, + /// + /// オープニング 127 + /// + OPE, + /// + /// ジェンダーファクター 64 + /// + GEN, + /// + /// ポルタメントタイミング 64 + /// + POR, + /// + /// ピッチベンド 0 + /// + PIT, + /// + /// ピッチベンドセンシティビティ 2 + /// + PBS, +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEvent.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEvent.java new file mode 100644 index 0000000..b2bfe83 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEvent.java @@ -0,0 +1,110 @@ +/* + * VsqEvent.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * vsqファイルのメタテキスト内に記述されるイベント。 + */ +public class VsqEvent implements Comparable, Cloneable { + //int m_internal_id; + /** + * 内部で使用するインスタンス固有のID
+ * for furutre implement:
+     *    public property int InternalID {
+     *       get {
+     *            return m_internal_id;
+     *       }
+     *       set {
+     *           m_internal_id = value;
+     *       }
+     *   };
+ */ + public int InternalID; + //int m_clock; + public int Clock; + //VsqID m_id; + public VsqID ID; + + /** + * このオブジェクトのコピーを作成します + * @returns> + */ + public Object clone() { + VsqEvent ret = new VsqEvent( Clock, ID ); + ret.InternalID = InternalID; + return ret; + } + + + /* // + /// このイベントが発生するクロック。 + /// + public property int Clock { + get { + return m_clock; + } + set { + m_clock = value; + } + };*/ + + /* // + /// 発生するイベントの内容を表したID + /// + public property VsqID ID { + get { + return m_id; + } + set { + m_id = value; + } + };*/ + public int compareTo( VsqEvent item ) { + int ret = this.Clock - item.Clock; + if ( ret == 0 ) { + if ( this.ID != null && item.ID != null ) { + if ( this.ID == item.ID ) { + return 0; + } else { + if ( this.ID.type == VsqIDType.Singer ) { + return -1; + } else if ( item.ID.type == VsqIDType.Anote ) { + return 1; + } + } + } else { + return ret; + } + } else { + return ret; + } + return 0; + } + + public VsqEvent( String line ) { + String[] spl = line.split( "=" ); + Clock = Integer.parseInt( spl[0] ); + if ( spl[1].equals( "EOS" ) ) { + ID = VsqID.EOS; + } + } + + public VsqEvent( int clock, VsqID id /*, int internal_id*/ ) { + Clock = clock; + ID = (VsqID)id.clone(); + //InternalID = internal_id; + InternalID = 0; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIterator.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIterator.java new file mode 100644 index 0000000..0fe49af --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIterator.java @@ -0,0 +1,84 @@ +/* + * VsqEventIterator.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + +/** + * + * @author kbinani + */ +public class VsqEventIterator implements Iterator { + private Vector m_list; + private int m_index = 0; + private VsqEventIteratorMode m_mode; + + public VsqEventIterator( Vector list, VsqEventIteratorMode mode ) { + m_list = list; + m_index = 0; + m_mode = mode; + } + + public void remove() { + m_list.remove( m_index ); + } + + public Object next() { + int last = m_index; + for ( m_index = last; m_index < m_list.size(); m_index++ ) { + VsqEvent ret = m_list.get( m_index ); + if ( m_mode == VsqEventIteratorMode.All ) { + return ret; + } else if ( m_mode == VsqEventIteratorMode.Anote ) { + if ( ret.ID.type == VsqIDType.Anote ) { + return ret; + } else { + continue; + } + } else if ( m_mode == VsqEventIteratorMode.Singer ) { + if ( ret.ID.type == VsqIDType.Singer ) { + return ret; + } else { + continue; + } + } + } + return null; + } + + public boolean hasNext() { + if ( m_mode == VsqEventIteratorMode.All ) { + return (m_index + 1 < m_list.size()); + } else { + for ( int i = m_index; i < m_list.size(); i++ ) { + VsqEvent ret = m_list.get( i ); + if ( m_mode == VsqEventIteratorMode.Anote ) { + if ( ret.ID.type == VsqIDType.Anote ) { + return true; + } else { + continue; + } + } else if ( m_mode == VsqEventIteratorMode.Singer ) { + if ( ret.ID.type == VsqIDType.Singer ) { + return true; + } else { + continue; + } + } + } + return false; + } + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIteratorMode.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIteratorMode.java new file mode 100644 index 0000000..38e488f --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventIteratorMode.java @@ -0,0 +1,24 @@ +/* + * VsqEventIterator.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public enum VsqEventIteratorMode { + Anote, + Singer, + All, +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventList.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventList.java new file mode 100644 index 0000000..e72adf8 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqEventList.java @@ -0,0 +1,97 @@ +/* + * VsqEventList.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + +/// +/// 固有ID付きのVsqEventのリストを取り扱う +/// +public class VsqEventList { + private Vector m_list; + private Vector m_ids; + + /// + /// コンストラクタ + /// + public VsqEventList() { + m_list = new Vector(); + m_ids = new Vector(); + } + + public VsqEventIterator iterator( VsqEventIteratorMode mode ) { + return new VsqEventIterator( m_list, mode ); + } + + public VsqEventIterator iterator(){ + return iterator( VsqEventIteratorMode.All ); + } + + public void add( VsqEvent item ) { + int new_id = GetNextId( 0 ); + item.InternalID = new_id; + m_list.add( item ); + m_ids.add( new_id ); + boolean changed = true; + while ( changed ) { + changed = false; + for ( int i = 0; i < m_list.size() - 1; i++ ) { + if ( m_list.get( i ).compareTo( m_list.get( i + 1 ) ) > 0 ) { + VsqEvent t = (VsqEvent)m_list.get( i ).clone(); + m_list.set( i, m_list.get( i + 1 ) ); + m_list.set( i + 1, t ); + changed = true; + } + } + } + for ( int i = 0; i < m_list.size(); i++ ) { + m_ids.set( i, m_list.get( i ).InternalID ); + } + } + + public void removeAt( int index ) { + m_list.remove( index ); + m_ids.remove( index ); + } + + private int GetNextId( int next ) { + int index = -1; + Vector current = new Vector( m_ids ); + int nfound = 0; + while ( true ) { + index++; + if ( !current.contains( index ) ) { + nfound++; + if ( nfound == next + 1 ) { + return index; + } else { + current.add( index ); + } + } + } + } + + public int size() { + return m_list.size(); + } + + public VsqEvent get( int index ) { + return m_list.get( index ); + } + + public void set( int index, VsqEvent value ) { + m_list.add( index, value ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqFile.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqFile.java new file mode 100644 index 0000000..0797ead --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqFile.java @@ -0,0 +1,2584 @@ +/* + * VsqEventList.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +import java.io.*; +import java.text.*; +import java.nio.*; + +public class VsqFile implements Cloneable { + Vector m_tracks; + Vector m_tempo_table; + Vector m_timesig_table; + int m_tpq; + /** + * 曲の長さを取得します。(クロック(4分音符は480クロック))
+     * public property long TotalClocks {
+     *     get {
+     *         return TotalClocks;
+     *     }
+     *     set {
+     *         TotalClocks = value;
+     *     }
+     * };
+ */ + public long TotalClocks = 0; + int m_base_tempo; + /** + *
public VsqMaster Master {
+     *     get {
+     *         return m_master;
+     *     }
+     *     set {
+     *         m_master = value;
+     *     }
+     * };
+ */ + public VsqMaster Master; // VsqMaster, VsqMixerは通常,最初の非Master Trackに記述されるが,可搬性のため, + + /** + * + *
public VsqMixer Mixer {
+     *   get {
+     *       return m_mixer;
+     *   }
+     *   set {
+     *       m_mixer = value;
+     *   }
+     *};
+ */ + public VsqMixer Mixer; // ここではVsqFileに直属するものとして取り扱う. + + int m_premeasure_clocks; + static byte[] _MTRK = new byte[] {0x4d, 0x54, 0x72, 0x6b}; + static byte[] _MTHD = new byte[] {0x4d, 0x54, 0x68, 0x64}; + static byte[] _MASTER_TRACK = new byte[] {0x4D, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x54, 0x72, 0x61, 0x63, 0x6B,}; + + public VsqCommand Execute( VsqCommand command ) { + VsqCommandType type = command.Type; + if ( type == VsqCommandType.ChangePreMeasure ) { + VsqCommand ret = GCommandChangePreMeasure( Master.PreMeasure ); + int value = (Integer)command.Args[0]; + Master.PreMeasure = value; + updateTimesigInfo(); + return ret; + } else if ( type == VsqCommandType.AddTrack ) { + VsqTrack track = (VsqTrack)command.Args[0]; + VsqMixerEntry mixer = (VsqMixerEntry)command.Args[1]; + int position = (Integer)command.Args[2]; + VsqCommand ret = GCommandDeleteTrack( position ); + if ( m_tracks.size() <= 17 ) { + m_tracks.insertElementAt( (VsqTrack)track.clone(),position ); + Mixer.Slave.add( (VsqMixerEntry)mixer.clone() ); + //Mixer.m_tracks = Mixer.Slave.Count; + return ret; + } else { + return null; + } + } else if ( type == VsqCommandType.DeleteTrack ) { + int track = (Integer)command.Args[0]; + VsqCommand ret = GCommandAddTrack( m_tracks.get( track), Mixer.Slave.get(track - 1), track ); + m_tracks.removeElementAt( track ); + Mixer.Slave.removeElementAt( track - 1 ); + updateTotalClocks(); + return ret; + } else if ( type == VsqCommandType.UpdateTempo ) { + int clock = (Integer)command.Args[0]; + int tempo = (Integer)command.Args[1]; + int new_clock = (Integer)command.Args[2]; + + int index = -1; + for ( int i = 0; i < m_tempo_table.size(); i++ ) { + if ( m_tempo_table.get( i ).Clock == clock ) { + index = i; + break; + } + } + VsqCommand ret = null; + if ( index >= 0 ) { + if ( tempo <= 0 ) { + ret = GCommandUpdateTempo( clock, clock, m_tempo_table.get( index ).Tempo ); + m_tempo_table.removeElementAt( index ); + } else { + ret = GCommandUpdateTempo( new_clock, clock, m_tempo_table.get( index ).Tempo ); + m_tempo_table.get( index ).Tempo = tempo; + m_tempo_table.get( index ).Clock = new_clock; + } + } else { + ret = GCommandUpdateTempo( clock, clock, -1 ); + m_tempo_table.add( new TempoTableEntry( new_clock, tempo, 0.0 ) ); + } + updateTempoInfo(); + updateTotalClocks(); + + // 編集領域を更新 + int affected_clock = Math.min( clock, new_clock ); + for ( int i = 1; i < m_tracks.size(); i++ ) { + if ( affected_clock < m_tracks.get( i ).getEditedStart() ) { + m_tracks.get( i ).setEditedStart( affected_clock ); + } + m_tracks.get( i ).setEditedEnd((int)TotalClocks ); + } + return ret; + } else if ( type == VsqCommandType.UpdateTempoRange ) { + int[] clocks = (int[])command.Args[0]; + int[] tempos = (int[])command.Args[1]; + int[] new_clocks = (int[])command.Args[2]; + int[] new_tempos = new int[tempos.length]; + int affected_clock = Integer.MAX_VALUE; + for ( int i = 0; i < clocks.length; i++ ) { + int index = -1; + affected_clock = Math.min( affected_clock, clocks[i] ); + affected_clock = Math.min( affected_clock, new_clocks[i] ); + for ( int j = 0; j < m_tempo_table.size(); j++ ) { + if ( m_tempo_table.get( j ).Clock == clocks[i] ) { + index = j; + break; + } + } + if ( index >= 0 ) { + new_tempos[i] = m_tempo_table.get( index ).Tempo; + if ( tempos[i] <= 0 ) { + m_tempo_table.removeElementAt( index ); + } else { + m_tempo_table.get( index ).Tempo = tempos[i]; + m_tempo_table.get( index ).Clock = new_clocks[i]; + } + } else { + new_tempos[i] = -1; + m_tempo_table.add( new TempoTableEntry( new_clocks[i], tempos[i], 0.0 ) ); + } + } + updateTempoInfo(); + updateTotalClocks(); + for ( int i = 1; i < m_tracks.size(); i++ ) { + if ( affected_clock < m_tracks.get( i ).getEditedStart() ) { + m_tracks.get( i ).setEditedStart( affected_clock ); + } + m_tracks.get( i ).setEditedEnd( (int)TotalClocks ); + } + return GCommandUpdateTempoRange( new_clocks, clocks, new_tempos ); + } else if ( type == VsqCommandType.UpdateTimesig ) { + int barcount = (Integer)command.Args[0]; + int numerator = (Integer)command.Args[1]; + int denominator = (Integer)command.Args[2]; + int new_barcount = (Integer)command.Args[3]; + int index = -1; + for ( int i = 0; i < m_timesig_table.size(); i++ ) { + if ( barcount == m_timesig_table.get( i ).BarCount ) { + index = i; + break; + } + } + VsqCommand ret = null; + if ( index >= 0 ) { + if ( numerator <= 0 ) { + ret = GCommandUpdateTimesig( barcount, barcount, m_timesig_table.get( index ).Numerator, m_timesig_table.get( index ).Denominator ); + m_timesig_table.removeElementAt( index ); + } else { + ret = GCommandUpdateTimesig( new_barcount, barcount, m_timesig_table.get( index ).Numerator, m_timesig_table.get( index ).Denominator ); + m_timesig_table.get( index ).BarCount = new_barcount; + m_timesig_table.get( index ).Numerator = numerator; + m_timesig_table.get( index ).Denominator = denominator; + } + } else { + ret = GCommandUpdateTimesig( new_barcount, new_barcount, -1, -1 ); + m_timesig_table.add( new TimeSigTableEntry( 0, numerator, denominator, new_barcount ) ); + } + updateTimesigInfo(); + updateTotalClocks(); + return ret; + } else if ( type == VsqCommandType.UpdateTimesigRange ) { + int[] barcounts = (int[])command.Args[0]; + int[] numerators = (int[])command.Args[1]; + int[] denominators = (int[])command.Args[2]; + int[] new_barcounts = (int[])command.Args[3]; + int[] new_numerators = new int[numerators.length]; + int[] new_denominators = new int[denominators.length]; + for ( int i = 0; i < barcounts.length; i++ ) { + int index = -1; + for ( int j = 0; j < m_timesig_table.size(); j++ ) { + if ( m_timesig_table.get(j).BarCount == barcounts[i] ) { + index = j; + break; + } + } + if ( index >= 0 ) { + new_numerators[i] = m_timesig_table.get( index ).Numerator; + new_denominators[i] = m_timesig_table.get( index ).Denominator; + if ( numerators[i] <= 0 ) { + m_timesig_table.removeElementAt( index ); + } else { + m_timesig_table.get( index ).BarCount = new_barcounts[i]; + m_timesig_table.get( index ).Numerator = numerators[i]; + m_timesig_table.get( index ).Denominator = denominators[i]; + } + } else { + new_numerators[i] = -1; + new_denominators[i] = -1; + m_timesig_table.add( new TimeSigTableEntry( 0, numerators[i], denominators[i], new_barcounts[i] ) ); + } + } + updateTimesigInfo(); + updateTotalClocks(); + return GCommandUpdateTimesigRange( new_barcounts, barcounts, new_numerators, new_denominators ); + } else if ( type == VsqCommandType.Replace ) { + VsqFile vsq = (VsqFile)command.Args[0]; + VsqFile inv = (VsqFile)this.clone(); + m_tracks.clear(); + for ( int i = 0; i < vsq.m_tracks.size(); i++ ) { + m_tracks.add( (VsqTrack)vsq.m_tracks.get( i ).clone() ); + } + m_tempo_table.clear(); + for ( int i = 0; i < vsq.m_tempo_table.size(); i++ ) { + m_tempo_table.add( (TempoTableEntry)vsq.m_tempo_table.get( i ).clone() ); + } + m_timesig_table.clear(); + for ( int i = 0; i < vsq.m_timesig_table.size(); i++ ) { + m_timesig_table.add( (TimeSigTableEntry)vsq.m_timesig_table.get( i ).clone() ); + } + m_tpq = vsq.m_tpq; + TotalClocks = vsq.TotalClocks; + m_base_tempo = vsq.m_base_tempo; + Master = (VsqMaster)vsq.Master.clone(); + Mixer = (VsqMixer)vsq.Mixer.clone(); + m_premeasure_clocks = vsq.m_premeasure_clocks; + updateTotalClocks(); + return GCommandReplace( inv ); + } else if ( type == VsqCommandType.EventAdd ) { + int track = (Integer)command.Args[0]; + VsqEvent item = (VsqEvent)command.Args[1]; + //int key = this.m_tracks.get( track ).GetNextId( 0 ); + //item.InternalID = key; + m_tracks.get( track ).getEvents().add( item ); + VsqCommand ret = GCommandEventDelete( track, item.InternalID ); + //this.m_tracks.get( track ).Events.Sort(); + updateTotalClocks(); + if ( item.Clock < m_tracks.get(track).getEditedStart() ) { + m_tracks.get( track).setEditedStart( item.Clock); + } + if ( m_tracks.get(track).getEditedEnd() < item.Clock + item.ID.Length ) { + m_tracks.get( track ).setEditedEnd( item.Clock + item.ID.Length ); + } + return ret; + } else if ( type == VsqCommandType.EventAddRange ) { + int track = (Integer)command.Args[0]; + VsqEvent[] items = (VsqEvent[])command.Args[1]; + Vector inv_ids = new Vector(); + int min_clock = (int)TotalClocks; + int max_clock = 0; + for ( int i = 0; i < items.length; i++ ) { + VsqEvent item = (VsqEvent)items[i].clone(); + min_clock = Math.min( min_clock, item.Clock ); + max_clock = Math.max( max_clock, item.Clock + item.ID.Length ); + //int key = m_tracks.get( track ).GetNextId( i ); + //item.InternalID = key; + m_tracks.get( track ).getEvents().add( item ); + inv_ids.add( item.InternalID ); + } + //m_tracks.get( track ).Events.Sort(); + updateTotalClocks(); + if ( min_clock < m_tracks.get( track ).getEditedStart() ) { + m_tracks.get( track ).setEditedStart( min_clock ); + } + if ( m_tracks.get( track ).getEditedEnd() < max_clock ) { + m_tracks.get( track ).setEditedEnd( max_clock ); + } + int count = inv_ids.size(); + int[] inv_ids_arr = new int[count]; + for( int i = 0; i < count; i++ ){ + inv_ids_arr[i] = inv_ids.get( i ); + } + return GCommandEventDeleteRange( track, inv_ids_arr ); + } else if ( type == VsqCommandType.EventDelete ) { + int internal_id = (Integer)command.Args[0]; + int track = (Integer)command.Args[1]; + VsqEvent[] original = new VsqEvent[1]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + original[0] = (VsqEvent)item.clone(); + break; + } + } + if ( original[0].Clock < m_tracks.get( track ).getEditedStart() ) { + m_tracks.get( track ).setEditedStart( original[0].Clock ); + } + if ( m_tracks.get( track ).getEditedEnd() < original[0].Clock + original[0].ID.Length ) { + m_tracks.get( track ).setEditedEnd(original[0].Clock + original[0].ID.Length); + } + VsqCommand ret = GCommandEventAddRange( track, original ); + for ( int i = 0; i < this.m_tracks.get( track ).getEvents().size(); i++ ) { + if ( this.m_tracks.get( track ).getEvents().get( i ).InternalID == internal_id ) { + m_tracks.get( track ).getEvents().removeAt( i ); + break; + } + } + updateTotalClocks(); + return ret; + } else if ( type == VsqCommandType.EventDeleteRange ) { + int[] internal_ids = (int[])command.Args[0]; + int track = (Integer)command.Args[1]; + Vector inv = new Vector(); + int min_clock = Integer.MAX_VALUE; + int max_clock = Integer.MIN_VALUE; + for ( int j = 0; j < internal_ids.length; j++ ) { + for ( int i = 0; i < m_tracks.get( track ).getEvents().size(); i++ ) { + if ( internal_ids[j] == m_tracks.get( track ).getEvents().get( i ).InternalID ) { + inv.add( (VsqEvent)m_tracks.get( track ).getEvents().get( i ).clone() ); + min_clock = Math.min( min_clock, m_tracks.get( track ).getEvents().get( i ).Clock ); + max_clock = Math.max( max_clock, m_tracks.get( track ).getEvents().get( i ).Clock + m_tracks.get( track ).getEvents().get( i ).ID.Length ); + m_tracks.get( track ).getEvents().removeAt( i ); + break; + } + } + } + updateTotalClocks(); + m_tracks.get( track ).setEditedStart(min_clock); + m_tracks.get( track ).setEditedEnd(max_clock ); + VsqEvent[] inv_arr = new VsqEvent[inv.size()]; + for( int i = 0; i < inv.size(); i++ ){ + inv_arr[i] = inv.get(i ); + } + return GCommandEventAddRange( track, inv_arr ); + } else if ( type == VsqCommandType.EventChangeClock ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int value = (Integer)command.Args[2]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeClock( track, internal_id, item.Clock ); + int min = Math.min( item.Clock, value ); + int max = Math.max( item.Clock + item.ID.Length, value + item.ID.Length ); + m_tracks.get( track ).setEditedStart(min); + m_tracks.get( track ).setEditedEnd(max); + item.Clock = value; + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeLyric ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + String phrase = (String)command.Args[2]; + String phonetic_symbol = (String)command.Args[3]; + boolean protect_symbol = (Boolean)command.Args[4]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + if ( item.ID.type == VsqIDType.Anote ) { + VsqCommand ret = GCommandEventChangeLyric( track, internal_id, item.ID.LyricHandle.L0.Phrase, item.ID.LyricHandle.L0.getPhoneticSymbol(), item.ID.LyricHandle.L0.PhoneticSymbolProtected ); + item.ID.LyricHandle.L0.Phrase = phrase; + item.ID.LyricHandle.L0.setPhoneticSymbol( phonetic_symbol ); + item.ID.LyricHandle.L0.PhoneticSymbolProtected = protect_symbol; + m_tracks.get( track ).setEditedStart(item.Clock); + m_tracks.get( track ).setEditedEnd(item.Clock + item.ID.Length); + updateTotalClocks(); + return ret; + } + } + } + return null; + } else if ( type == VsqCommandType.EventChangeNote ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int note = (Integer)command.Args[2]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeNote( track, internal_id, item.ID.Note ); + item.ID.Note = note; + updateTotalClocks(); + m_tracks.get( track ).setEditedStart(item.Clock); + m_tracks.get( track ).setEditedEnd(item.Clock + item.ID.Length); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeClockAndNote ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int clock = (Integer)command.Args[2]; + int note = (Integer)command.Args[3]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeClockAndNote( track, internal_id, item.Clock, item.ID.Note ); + int min = Math.min( item.Clock, clock ); + int max = Math.max( item.Clock + item.ID.Length, clock + item.ID.Length ); + m_tracks.get( track ).setEditedStart( min ); + m_tracks.get( track ).setEditedEnd( max ); + item.Clock = clock; + item.ID.Note = note; + //this.m_tracks.get( track ).Events.Sort(); + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.TrackEditCurve ) { + int track = (Integer)command.Args[0]; + VsqCurveType curve = (VsqCurveType)command.Args[1]; + Vector com = (Vector)command.Args[2]; + //SortedList list = m_tracks.get( track )[curve].Vector; + + VsqCommand inv = null; + Vector edit = new Vector(); + if ( com != null ) { + if ( com.size() > 0 ) { + int start_clock = com.get(0).Clock; + int end_clock = com.get(0).Clock; + for ( Iterator itr = com.iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + start_clock = Math.min( start_clock, item.Clock ); + end_clock = Math.max( end_clock, item.Clock ); + } + m_tracks.get( track ).setEditedStart( start_clock ); + m_tracks.get( track ).setEditedEnd( end_clock ); + int start_value = m_tracks.get( track ).getVsqBPList(curve).get( start_clock); + int end_value = m_tracks.get( track ).getVsqBPList(curve).get(end_clock); + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + edit.add( new BPPair( clock, m_tracks.get( track ).getVsqBPList(curve).get(clock) ) ); + } + } + boolean start_found = false; + boolean end_found = false; + for ( int i = 0; i < edit.size(); i++ ) { + if ( edit.get( i ).Clock == start_clock ) { + start_found = true; + edit.get( i ).Value = start_value; + if ( start_found && end_found ) { + break; + } + } + if ( edit.get( i ).Clock == end_clock ) { + end_found = true; + edit.get( i ).Value = end_value; + if ( start_found && end_found ) { + break; + } + } + } + if ( !start_found ) { + edit.add( new BPPair( start_clock, start_value ) ); + } + if ( !end_found ) { + edit.add( new BPPair( end_clock, end_value ) ); + } + + // 並べ替え + Collections.sort( edit ); + inv = GCommandTrackEditCurve( track, curve, edit ); + } else if ( com.size() == 0 ) { + inv = GCommandTrackEditCurve( track, curve, new Vector() ); + } + } + + updateTotalClocks(); + if ( com.size() == 0 ) { + return inv; + } else if ( com.size() == 1 ) { + boolean found = false; + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( clock == com.get(0).Clock ) { + found = true; + m_tracks.get( track ).getVsqBPList(curve).add( clock, com.get(0).Value ); + break; + } + } + if ( !found ) { + m_tracks.get( track ).getVsqBPList(curve).add( com.get(0).Clock, com.get(0).Value ); + } + } else { + int start_clock = com.get(0).Clock; + int end_clock = com.get(com.size() - 1).Clock; + boolean removed = true; + while ( removed ) { + removed = false; + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + m_tracks.get( track ).getVsqBPList(curve).remove( clock ); + removed = true; + break; + } + } + } + for ( Iterator itr = com.iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + m_tracks.get( track ).getVsqBPList(curve).add( item.Clock, item.Value ); + } + } + return inv; + } else if ( type == VsqCommandType.TrackEditCurveRange ) { + int track = (Integer)command.Args[0]; + VsqCurveType[] curves = (VsqCurveType[])command.Args[1]; + Vector[] coms = (Vector[])command.Args[2]; + Vector> inv_coms = new Vector>( curves.length ); + VsqCommand inv = null; + + for ( int k = 0; k < curves.length; k++ ) { + VsqCurveType curve = curves[k]; + Vector com = coms[k]; + //SortedList list = m_tracks.get( track )[curve].Vector; + Vector edit = new Vector(); + if ( com != null ) { + if ( com.size() > 0 ) { + int start_clock = com.get(0).Clock; + int end_clock = com.get(0).Clock; + for ( Iterator itr = com.iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + start_clock = Math.min( start_clock, item.Clock ); + end_clock = Math.max( end_clock, item.Clock ); + } + m_tracks.get( track ).setEditedStart( start_clock); + m_tracks.get( track ).setEditedEnd( end_clock); + int start_value = m_tracks.get( track ).getVsqBPList(curve).get(start_clock); + int end_value = m_tracks.get( track ).getVsqBPList(curve).get(end_clock); + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + edit.add( new BPPair( clock, m_tracks.get( track ).getVsqBPList(curve).get(clock) ) ); + } + } + boolean start_found = false; + boolean end_found = false; + for ( int i = 0; i < edit.size(); i++ ) { + if ( edit.get( i ).Clock == start_clock ) { + start_found = true; + edit.get( i ).Value = start_value; + if ( start_found && end_found ) { + break; + } + } + if ( edit.get( i ).Clock == end_clock ) { + end_found = true; + edit.get( i ).Value = end_value; + if ( start_found && end_found ) { + break; + } + } + } + if ( !start_found ) { + edit.add( new BPPair( start_clock, start_value ) ); + } + if ( !end_found ) { + edit.add( new BPPair( end_clock, end_value ) ); + } + + // 並べ替え + Collections.sort( edit); + inv_coms.set( k, edit ); + //inv = GCommandTrackEditCurve( track, curve, edit ); + } else if ( com.size() == 0 ) { + //inv = GCommandTrackEditCurve( track, curve, new Vector() ); + inv_coms.set( k, new Vector() ); + } + } + + updateTotalClocks(); + if ( com.size() == 0 ) { + return inv; + } else if ( com.size() == 1 ) { + boolean found = false; + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( clock == com.get(0).Clock ) { + found = true; + m_tracks.get( track ).getVsqBPList(curve).add( clock, com.get(0).Value ); + break; + } + } + if ( !found ) { + m_tracks.get( track ).getVsqBPList(curve).add( com.get(0).Clock, com.get(0).Value ); + } + } else { + int start_clock = com.get(0).Clock; + int end_clock = com.get(com.size() - 1).Clock; + boolean removed = true; + while ( removed ) { + removed = false; + for ( Iterator itr = m_tracks.get( track ).getVsqBPList( curve ).keyClockIterator(); itr.hasNext();) { + int clock = (Integer)itr.next(); + if ( start_clock <= clock && clock <= end_clock ) { + m_tracks.get( track ).getVsqBPList(curve).remove( clock ); + removed = true; + break; + } + } + } + for ( Iterator itr = com.iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + m_tracks.get( track ).getVsqBPList(curve).add( item.Clock, item.Value ); + } + } + } + return GCommandTrackEditCurveRange( track, curves, inv_coms ); + } else if ( type == VsqCommandType.EventChangeVelocity ) { + int track = (Integer)command.Args[0]; + Vector> veloc = (Vector>)command.Args[1]; + Vector> inv = new Vector>(); + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent ev = (VsqEvent)itr.next(); + for ( Iterator itr2 = veloc.iterator(); itr2.hasNext();) { + KeyValuePair add = (KeyValuePair)itr2.next(); + if ( ev.InternalID == add.Key ) { + inv.add( new KeyValuePair( ev.InternalID, ev.ID.Dynamics ) ); + ev.ID.Dynamics = add.Value; + m_tracks.get( track ).setEditedStart( ev.Clock ); + m_tracks.get( track ).setEditedEnd( ev.Clock + ev.ID.Length ); + break; + } + } + } + return GCommandEventChangeVelocity( track, inv ); + } else if ( type == VsqCommandType.EventChangeLength ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int new_length = (Integer)command.Args[2]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeLength( track, internal_id, item.ID.Length ); + m_tracks.get( track ).setEditedStart( item.Clock ); + int max = Math.max( item.Clock + item.ID.Length, item.Clock + new_length ); + m_tracks.get( track ).setEditedEnd( max ); + item.ID.Length = new_length; + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeClockAndLength ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int new_clock = (Integer)command.Args[2]; + int new_length = (Integer)command.Args[3]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeClockAndLength( track, internal_id, item.Clock, item.ID.Length ); + int min = Math.min( item.Clock, new_clock ); + int max_length = Math.max( item.ID.Length, new_length ); + int max = Math.max( item.Clock + max_length, new_clock + max_length ); + m_tracks.get( track ).setEditedStart( min ); + m_tracks.get( track ).setEditedEnd( max ); + item.ID.Length = new_length; + item.Clock = new_clock; + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeIDContaints ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + VsqID value = (VsqID)command.Args[2]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeIDContaints( track, internal_id, item.ID ); + int max_length = Math.max( item.ID.Length, value.Length ); + m_tracks.get( track ).setEditedStart( item.Clock ); + m_tracks.get( track ).setEditedEnd( item.Clock + max_length ); + item.ID = (VsqID)value.clone(); + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeIDContaintsRange ) { + int track = (Integer)command.Args[0]; + int[] internal_ids = (int[])command.Args[1]; + VsqID[] values = (VsqID[])command.Args[2]; + VsqID[] inv_values = new VsqID[values.length]; + for ( int i = 0; i < internal_ids.length; i++ ) { + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_ids[i] ) { + inv_values[i] = (VsqID)item.ID.clone(); + int max_length = Math.max( item.ID.Length, values[i].Length ); + m_tracks.get( track ).setEditedStart( item.Clock ); + m_tracks.get( track ).setEditedEnd( item.Clock + max_length ); + item.ID = (VsqID)values[i].clone(); + break; + } + } + } + updateTotalClocks(); + return GCommandEventChangeIDContaintsRange( track, internal_ids, inv_values ); + } else if ( type == VsqCommandType.EventChangeClockAndIDContaints ) { + int track = (Integer)command.Args[0]; + int internal_id = (Integer)command.Args[1]; + int new_clock = (Integer)command.Args[2]; + VsqID value = (VsqID)command.Args[3]; + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_id ) { + VsqCommand ret = GCommandEventChangeClockAndIDContaints( track, internal_id, item.Clock, item.ID ); + int max_length = Math.max( item.ID.Length, value.Length ); + int min = Math.min( item.Clock, new_clock ); + int max = Math.max( item.Clock + max_length, new_clock + max_length ); + item.ID = (VsqID)value.clone(); + item.Clock = new_clock; + m_tracks.get( track ).setEditedStart( min ); + m_tracks.get( track ).setEditedEnd( max ); + updateTotalClocks(); + return ret; + } + } + return null; + } else if ( type == VsqCommandType.EventChangeClockAndIDContaintsRange ) { + int track = (Integer)command.Args[0]; + int[] internal_ids = (int[])command.Args[1]; + int[] clocks = (int[])command.Args[2]; + VsqID[] values = (VsqID[])command.Args[3]; + Vector inv_id = new Vector(); + Vector inv_clock = new Vector(); + for ( int i = 0; i < internal_ids.length; i++ ) { + for ( Iterator itr = m_tracks.get( track ).getEvents().iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.InternalID == internal_ids[i] ) { + inv_id.add( (VsqID)item.ID.clone() ); + inv_clock.add( item.Clock ); + int max_length = Math.max( item.ID.Length, values[i].Length ); + int min = Math.min( item.Clock, clocks[i] ); + int max = Math.max( item.Clock + max_length, clocks[i] + max_length ); + m_tracks.get( track ).setEditedStart( min ); + m_tracks.get( track ).setEditedEnd( max ); + item.ID = (VsqID)values[i].clone(); + item.Clock = clocks[i]; + break; + } + } + } + updateTotalClocks(); + int[] inv_clock_arr = new int[inv_clock.size()]; + for( int i = 0; i < inv_clock.size(); i++ ){ + inv_clock_arr[i] = inv_clock.get( i); + } + VsqID[] inv_id_arr = new VsqID[inv_id.size()]; + for( int i = 0; i < inv_id.size(); i++ ){ + inv_id_arr[i] = inv_id.get(i); + } + return GCommandEventChangeClockAndIDContaintsRange( + track, + internal_ids, + inv_clock_arr, + inv_id_arr ); + } else if ( type == VsqCommandType.TrackChangeName ) { + int track = (Integer)command.Args[0]; + String new_name = (String)command.Args[1]; + VsqCommand ret = GCommandTrackChangeName( track, m_tracks.get( track ).getName() ); + m_tracks.get( track ).setName( new_name ); + return ret; + } else if ( type == VsqCommandType.TrackReplace ) { + int track = (Integer)command.Args[0]; + VsqTrack item = (VsqTrack)command.Args[1]; + VsqCommand ret = GCommandTrackReplace( track, (VsqTrack)m_tracks.get( track ).clone() ); + m_tracks.set( track, item ); + updateTotalClocks(); + return ret; + } + + return null; + } + + public static VsqCommand GCommandRoot() { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.Root; + command.Args = null; + return command; + } + + public static VsqCommand GCommandReplace( VsqFile vsq ) { + VsqCommand command = new VsqCommand(); + command.Args = new Object[1]; + command.Type = VsqCommandType.Replace; + command.Args[0] = (VsqFile)vsq.clone(); + return command; + } + + public static VsqCommand GCommandTrackReplace( int track, VsqTrack item ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackReplace; + command.Args = new Object[2]; + command.Args[0] = track; + command.Args[1] = (VsqTrack)item.clone(); + return command; + } + + public static VsqCommand GCommandUpdateTimesig( int bar_count, int new_barcount, int numerator, int denominator ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTimesig; + command.Args = new Object[4]; + command.Args[0] = bar_count; + command.Args[1] = numerator; + command.Args[2] = denominator; + command.Args[3] = new_barcount; + return command; + } + + public static VsqCommand GCommandUpdateTimesigRange( int[] bar_counts, int[] new_barcounts, int[] numerators, int[] denominators ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTimesigRange; + command.Args = new Object[4]; + command.Args[0] = (int[])bar_counts.clone(); + command.Args[1] = (int[])numerators.clone(); + command.Args[2] = (int[])denominators.clone(); + command.Args[3] = (int[])new_barcounts.clone(); + return command; + } + + public static VsqCommand GCommandUpdateTempoRange( int[] clocks, int[] new_clocks, int[] tempos ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTempoRange; + command.Args = new Object[3]; + command.Args[0] = (int[])clocks.clone(); + command.Args[1] = (int[])tempos.clone(); + command.Args[2] = (int[])new_clocks.clone(); + return command; + } + + public static VsqCommand GCommandUpdateTempo( int clock, int new_clock, int tempo ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.UpdateTempo; + command.Args = new Object[3]; + command.Args[0] = clock; + command.Args[1] = tempo; + command.Args[2] = new_clock; + return command; + } + + public static VsqCommand GCommandChangePreMeasure( int pre_measure ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.ChangePreMeasure; + command.Args = new Object[1]; + command.Args[0] = pre_measure; + return command; + } + + public static VsqCommand GCommandDeleteTrack( int track ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.DeleteTrack; + command.Args = new Object[1]; + command.Args[0] = track; + return command; + } + + + /// + /// トラックを追加するコマンドを発行します.trackはClone()して渡さなくてもよい + /// + /// + /// + public static VsqCommand GCommandAddTrack( VsqTrack track, VsqMixerEntry mixer, int position ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.AddTrack; + command.Args = new Object[5]; + command.Args[0] = track; + command.Args[1] = mixer; + command.Args[2] = position; + return command; + } + + + /// + /// トラック名を変更するコマンドを作成します + /// + /// + /// + /// + public static VsqCommand GCommandTrackChangeName( int track, String new_name ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackChangeName; + command.Args = new Object[2]; + command.Args[0] = track; + command.Args[1] = new_name; + return command; + } + + + /// + /// VsqIDとClockを同時に変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeClockAndIDContaintsRange( int track, int[] internal_ids, int[] clocks, VsqID[] values ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndIDContaintsRange; + int count = internal_ids.length; + command.Args = new Object[4]; + command.Args[0] = track; + command.Args[1] = (int[])internal_ids.clone(); + command.Args[2] = (int[])clocks.clone(); + command.Args[3] = (VsqID[])values.clone(); + return command; + } + + + /// + /// VsqIDとClockを同時に変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeClockAndIDContaints( int track, int internal_id, int clock, VsqID value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndIDContaints; + command.Args = new Object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = clock; + command.Args[3] = (VsqID)value.clone(); + return command; + } + + + /// + /// VsqIDの内容を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeIDContaintsRange( int track, int[] internal_ids, VsqID[] values ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeIDContaintsRange; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = (int[])internal_ids.clone(); + VsqID[] list = new VsqID[values.length]; + for ( int i = 0; i < values.length; i++ ) { + list[i] = (VsqID)values[i].clone(); + } + command.Args[2] = list; + return command; + } + + + /// + /// VsqIDの内容を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeIDContaints( int track, int internal_id, VsqID value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeIDContaints; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = (VsqID)value.clone(); + return command; + } + + + /// + /// ノートの長さを変更するコマンドを発行します + /// + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeClockAndLength( int track, int internal_id, int new_clock, int new_length ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndLength; + command.Args = new Object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = new_clock; + command.Args[3] = new_length; + return command; + } + + + /// + /// ノートの長さを変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeLength( int track, int internal_id, int new_length ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeLength; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = new_length; + return command; + } + + + /// + /// 指定したトラックの,音符のベロシティ(VEL)を変更するコマンドを発行します. + /// リストvelocityには,音符を指定するInteralIDと,変更したいベロシティの値のペアを登録します + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeVelocity( int track, Vector> velocity ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeVelocity; + command.Args = new Object[2]; + command.Args[0] = track; + Vector> list = new Vector>(); + for ( Iterator itr = velocity.iterator(); itr.hasNext();) { + KeyValuePair item = (KeyValuePair)itr.next(); + list.add( new KeyValuePair( item.Key, item.Value ) ); + } + command.Args[1] = list; + return command; + } + + + /// + /// vsqファイルのカーブを編集するコマンドを発行します. + /// + /// + /// + /// + /// + public static VsqCommand GCommandTrackEditCurve( int track, VsqCurveType target, Vector edit ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackEditCurve; + command.Args = new Object[5]; + command.Args[0] = track; + command.Args[1] = target; + Vector copied = new Vector(); + for ( Iterator itr = edit.iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + copied.add( item ); + } + command.Args[2] = copied; + return command; + } + + public static VsqCommand GCommandTrackEditCurveRange( int track, VsqCurveType[] targets, Vector> edits ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.TrackEditCurveRange; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = (VsqCurveType[])targets.clone(); + Vector> cpy = new Vector>(targets.length); + for ( int i = 0; i < edits.size(); i++ ) { + Vector copied = new Vector(); + for ( Iterator itr = edits.get(i).iterator(); itr.hasNext();) { + BPPair item = (BPPair)itr.next(); + copied.add( new BPPair( item.Clock, item.Value ) ); + } + cpy.set( i, copied ); + } + command.Args[2] = cpy; + return command; + } + + /// + /// 特定位置のイベントの歌詞と発音記号を変更するコマンドを発行します。 + /// + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeLyric( int track, int internal_id, String phrase, String phonetic_symbol, boolean protect_symbol ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeLyric; + command.Args = new Object[5]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = phrase; + command.Args[3] = phonetic_symbol; + command.Args[4] = protect_symbol; + return command; + } + + + /// + /// ノートのクロック位置を変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeClock( int track, int internal_id, int value ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClock; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = value; + return command; + } + + public static VsqCommand GCommandEventDeleteRange( int track, int[] internal_ids ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventDeleteRange; + command.Args = new Object[2]; + command.Args[0] = (int[])internal_ids.clone(); + command.Args[1] = track; + return command; + } + + + /// + /// ノートを削除するコマンドを発行します + /// + /// + /// + public static VsqCommand GCommandEventDelete( int track, int internal_id ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventDelete; + command.Args = new Object[2]; + command.Args[1] = track; + command.Args[0] = internal_id; + return command; + } + + public static VsqCommand GCommandEventAddRange( int track, VsqEvent[] items ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventAddRange; + command.Args = new Object[2]; + command.Args[0] = track; + command.Args[1] = (VsqEvent[])items.clone(); + return command; + } + + + /// + /// ノートを追加するコマンドを発行します。 + /// + /// + /// + /// + public static VsqCommand GCommandEventAdd( int track, VsqEvent item ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventAdd; + command.Args = new Object[2]; + command.Args[0] = track; + command.Args[1] = (VsqEvent)item.clone(); + return command; + } + + + /// + /// ノートの音程を変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeNote( int track, int internal_id, int note ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeNote; + command.Args = new Object[3]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = note; + return command; + } + + + /// + /// ノートの音程とクロックを変更するコマンドを発行します + /// + /// + /// + /// + /// + public static VsqCommand GCommandEventChangeClockAndNote( int track, int internal_id, int clock, int note ) { + VsqCommand command = new VsqCommand(); + command.Type = VsqCommandType.EventChangeClockAndNote; + command.Args = new Object[4]; + command.Args[0] = track; + command.Args[1] = internal_id; + command.Args[2] = clock; + command.Args[3] = note; + return command; + } + + public Object clone() { + VsqFile ret = new VsqFile(); + ret.m_tracks = new Vector(); + for ( int i = 0; i < m_tracks.size(); i++ ) { + ret.m_tracks.add( (VsqTrack)m_tracks.get( i ).clone() ); + } + ret.m_tempo_table = new Vector(); + for ( int i = 0; i < m_tempo_table.size(); i++ ) { + ret.m_tempo_table.add( (TempoTableEntry)m_tempo_table.get( i ).clone() ); + } + ret.m_timesig_table = new Vector(); + for ( int i = 0; i < m_timesig_table.size(); i++ ) { + ret.m_timesig_table.add( (TimeSigTableEntry)m_timesig_table.get( i ).clone() ); + } + ret.m_tpq = m_tpq; + ret.TotalClocks = TotalClocks; + ret.m_base_tempo = m_base_tempo; + ret.Master = (VsqMaster)Master.clone(); + ret.Mixer = (VsqMixer)Mixer.clone(); + ret.m_premeasure_clocks = m_premeasure_clocks; + return ret; + } + + private VsqFile() { + VsqUtil.LoadSingerConfigs(); + } + + + /// + /// 小節の区切りを順次返すEnumerator。 + /// + /// + public Iterator getVsqBarLineIterator( int end_clock ) { + } + + + /// + /// 基本テンポ値を取得します + /// + public int getBaseTempo() { + return m_base_tempo; + } + + + /// + /// プリメジャー値を取得または設定します。 + /// + public int getPreMeasure() { + //return m_tracks[1].MetaText.master.PreMeasure; + return Master.PreMeasure; + } + + public int getPreMeasureClocks() { + return m_premeasure_clocks; + } + + + /// + /// プリメジャーの長さ(クロック)を計算します。 + /// + private int GetPreMeasureInClock() { + int pre_measure = Master.PreMeasure; + int last_bar_count = m_timesig_table.get(0).BarCount; + int last_clock = m_timesig_table.get( 0).Clock; + int last_denominator = m_timesig_table.get(0).Denominator; + int last_numerator = m_timesig_table.get(0).Numerator; + for ( int i = 1; i < m_timesig_table.size(); i++ ) { + if ( m_timesig_table.get( i ).BarCount >= pre_measure ) { + break; + } else { + last_bar_count = m_timesig_table.get( i ).BarCount; + last_clock = m_timesig_table.get( i ).Clock; + last_denominator = m_timesig_table.get( i ).Denominator; + last_numerator = m_timesig_table.get( i ).Numerator; + } + } + + int remained = pre_measure - last_bar_count;//プリメジャーの終わりまでの残り小節数 + + return last_clock + remained * last_numerator * 480 * 4 / last_denominator; + } + + + /// + /// 指定したクロックにおける、clock=0からの演奏経過時間(sec) + /// + /// + /// + public double SecFromClock( int clock ) { + for ( int i = m_tempo_table.size() - 1; i >= 0; i-- ) { + if ( m_tempo_table.get( i ).Clock < clock ) { + double init = m_tempo_table.get( i ).Time; + int dclock = clock - m_tempo_table.get( i ).Clock; + double sec_per_clock1 = m_tempo_table.get( i ).Tempo * 1e-6 / 480.0; + return init + dclock * sec_per_clock1; + } + } + + double sec_per_clock = m_base_tempo * 1e-6 / 480.0; + return clock * sec_per_clock; + } + + + /// + /// 指定した時刻における、クロックを取得します + /// + /// + /// + public float ClockFromSec( float time ) { + // timeにおけるテンポを取得 + int tempo = m_base_tempo; + float base_clock = 0; + float base_time = 0f; + if ( m_tempo_table.size() == 0 ) { + tempo = m_base_tempo; + base_clock = 0; + base_time = 0f; + } else if ( m_tempo_table.size() == 1 ) { + tempo = m_tempo_table.get(0).Tempo; + base_clock = m_tempo_table.get(0).Clock; + base_time = (float)m_tempo_table.get(0).Time; + } else { + for ( int i = m_tempo_table.size() - 1; i >= 0; i-- ) { + if ( m_tempo_table.get( i ).Time < time ) { + return m_tempo_table.get( i ).Clock + (time - (float)m_tempo_table.get( i ).Time) * m_tpq * 1000000.0f / (float)m_tempo_table.get( i ).Tempo; + } + } + } + float dt = time - base_time; + return base_clock + dt * m_tpq * 1000000.0f / (float)tempo; + } + + + /// + /// 指定したクロックにおける拍子を取得します + /// + /// + /// + /// + public void getTimesigAt( int clock, Integer numerator, Integer denominator ) { + int index = 0; + for ( int i = m_timesig_table.size() - 1; i >= 0; i-- ) { + index = i; + if ( m_timesig_table.get( i ).Clock <= clock ) { + break; + } + } + numerator = m_timesig_table.get( index ).Numerator; + denominator = m_timesig_table.get( index ).Denominator; + } + + + /// + /// 指定したクロックにおけるテンポを取得します。 + /// + /// + /// + public int getTempoAt( int clock ) { + int index = 0; + for ( int i = m_tempo_table.size() - 1; i >= 0; i-- ) { + index = i; + if ( m_tempo_table.get( i ).Clock <= clock ) { + break; + } + } + return m_tempo_table.get( index ).Tempo; + } + + + /// + /// 指定した小節の開始クロックを調べます。ここで使用する小節数は、プリメジャーを考慮しない。即ち、曲頭の小節が0である。 + /// + /// + /// + public int getClockFromBarCount( int bar_count ) { + int index = 0; + for ( int i = m_timesig_table.size() - 1; i >= 0; i-- ) { + index = i; + if ( m_timesig_table.get( i ).BarCount <= bar_count ) { + break; + } + } + int numerator = m_timesig_table.get( index ).Numerator; + int denominator = m_timesig_table.get( index ).Denominator; + int init_clock = m_timesig_table.get( index ).Clock; + int init_bar_count = m_timesig_table.get( index ).BarCount; + int clock_per_bar = numerator * 480 * 4 / denominator; + return init_clock + (bar_count - init_bar_count) * clock_per_bar; + } + + + /// + /// 指定したクロックが、曲頭から何小節目に属しているかを調べます。ここで使用する小節数は、プリメジャーを考慮しない。即ち、曲頭の小節が0である。 + /// + /// + /// + public int getBarCountFromClock( int clock ) { + int index = 0; + for ( int i = m_timesig_table.size() - 1; i >= 0; i-- ) { + index = i; + if ( m_timesig_table.get( i ).Clock <= clock ) { + break; + } + } + int bar_count = 0; + if ( index >= 0 ) { + int last_clock = m_timesig_table.get( index ).Clock; + int t_bar_count = m_timesig_table.get( index ).BarCount; + int numerator = m_timesig_table.get( index ).Numerator; + int denominator = m_timesig_table.get( index ).Denominator; + int clock_per_bar = numerator * 480 * 4 / denominator; + bar_count = t_bar_count + (clock - last_clock) / clock_per_bar; + } + return bar_count; + } + + public int getTickPerQuarter() { + return m_tpq; + } + + public Vector getTempoTable() { + return m_tempo_table; + } + + public Vector getm_timesig_table() { + return m_timesig_table; + } + + public VsqTrack getTracks( int track ) { + return m_tracks.get( track ); + } + + public void dispose() { + if ( m_tracks != null ) { + m_tracks.clear(); + } + if ( m_tempo_table != null ) { + m_tempo_table.clear(); + } + m_tracks = null; + m_tempo_table = null; + } + + + /// + /// 空のvsqファイルを構築します + /// + /// + /// + /// + /// + public VsqFile( int default_singer_program_change, int pre_measure, int numerator, int denominator, int tempo ) { + VsqUtil.LoadSingerConfigs(); + TotalClocks = (long)(pre_measure * 480 * 4 / denominator * numerator); + m_tpq = 480; + + m_tracks = new Vector(); + m_tracks.add( new VsqTrack( tempo, numerator, denominator ) ); + String singer = "Miku"; + SingerConfig sc = VsqUtil.GetSingerInfo( default_singer_program_change ); + if ( sc != null ) { + singer = sc.VOICENAME; + } + m_tracks.add( new VsqTrack( "Voice1", singer ) ); + Master = new VsqMaster( pre_measure ); + + Mixer = new VsqMixer( 0, 0, 0, 0 ); + Mixer.Slave.add( new VsqMixerEntry( 0, 0, 0, 0 ) ); +// m_mixer.Slave.Add( new VsqMixerEntry( 0, 0, 0, 0 ) ); + //m_mixer.m_tracks = 1; + m_timesig_table = new Vector(); + m_timesig_table.add( new TimeSigTableEntry( 0, numerator, denominator, 0 ) ); + m_tempo_table = new Vector(); + m_tempo_table.add( new TempoTableEntry( 0, tempo, 0.0 ) ); + m_base_tempo = tempo; + m_premeasure_clocks = GetPreMeasureInClock(); + } + + + /// + /// vsqファイルからのコンストラクタ + /// + /// + public VsqFile( String _fpath ) { + VsqUtil.LoadSingerConfigs(); + m_tempo_table = new Vector(); + m_timesig_table = new Vector(); + m_tpq = 480; + //tpq_sec = 480.0 * 1000000.0; + + // SMFをコンバートしたテキストファイルを作成 + TextMemoryStream tms = new TextMemoryStream(); + SMFReader reader = new SMFReader( _fpath ); + String[] lines0 = reader.Lines; + for ( int i = 0; i < lines0.length; i++ ) { + String line = lines0[i]; + tms.writeLine( line ); + } + + // テキストファイルから、トラックごとに切り分け + tms.rewind(); + m_tracks = new Vector(); + + // ヘッダからトラック数、TPQを取得 + String[] spl = tms.readLine().split( " " ); + int trackNum = Integer.parseInt( spl[2] ); + m_tpq = Integer.parseInt( spl[3] ); + //tpq_sec = TickPerQuarter * 1000000.0; + for ( int i = 0; i < trackNum; i++ ) { + Vector lines = new Vector(); + String line; + while ( (line = tms.readLine()) != null ) { + if ( line.startsWith( "TrkEnd" ) ) { + break; + } + if ( line != "MTrk" ) { + lines.add( line ); + } + } + m_tracks.add( new VsqTrack( lines ) ); + } + + Master = (VsqMaster)m_tracks.get(1).getMaster().clone(); + Mixer = (VsqMixer)m_tracks.get(1).getMixer().clone(); + m_tracks.get(1).setMaster(null); + m_tracks.get(1).setMixer(null); + + int master_track = -1; + for ( int i = 0; i < m_tracks.size(); i++ ) { + if ( m_tracks.get( i ).getName().equals("Master Track") ) { + master_track = i; + break; + } + } + + int prev_tempo; + int prev_index; + double prev_time; + if ( master_track >= 0 ) { + //TempoListの作成 + Vector midi_event = m_tracks.get( master_track ).getTempoList(); + // とりあえずtempo_tableに格納 + prev_tempo = midi_event.get(0).intValue[0]; + m_base_tempo = prev_tempo; + prev_index = 0; + m_tempo_table.add( new TempoTableEntry( midi_event.get(0).index, midi_event.get(0).intValue[0], 0.0 ) ); + double thistime; + prev_time = 0.0; + for ( int j = 1; j < midi_event.size(); j++ ) { + int current_tempo = midi_event.get(j).intValue[0]; + int current_index = midi_event.get(j).index; + thistime = prev_time + (double)(prev_tempo) * (double)(current_index - prev_index) / (m_tpq * 1000000.0); + m_tempo_table.add( new TempoTableEntry( current_index, current_tempo, thistime ) ); + prev_tempo = current_tempo; + prev_index = current_index; + prev_time = thistime; + } + Collections.sort( m_tempo_table ); + + // m_timesig_tableの作成 + Vector time_sigs = m_tracks.get(master_track).getTimeSigList(); + m_timesig_table.add( new TimeSigTableEntry( 0, time_sigs.get(0).intValue[0], time_sigs.get(0).intValue[1], 0 ) ); + for ( int j = 1; j < time_sigs.size(); j++ ) { + int numerator = m_timesig_table.get(j - 1).Numerator; + int denominator = m_timesig_table.get(j - 1).Denominator; + int clock = m_timesig_table.get(j - 1).Clock; + int bar_count = m_timesig_table.get(j - 1).BarCount; + + int dif = 480 * 4 / denominator * numerator;//1小節が何クロックか? + + bar_count += (time_sigs.get(j).index - clock) / dif; + m_timesig_table.add( new TimeSigTableEntry( time_sigs.get(j).index, time_sigs.get(j).intValue[0], time_sigs.get(j).intValue[1], bar_count ) ); + } + + + + // 曲の長さを計算 + updateTempoInfo(); + updateTimesigInfo(); + m_premeasure_clocks = GetPreMeasureInClock(); + updateTotalClocks(); + } + } + + + /// + /// m_timesig_tableの[*].Clockの部分を更新します + /// + public void updateTimesigInfo() { + if ( m_timesig_table.get(0).Clock != 0 ) { + throw new Exception( "initial timesig does not found" ); + } + m_timesig_table.get(0).Clock = 0; + Collections.sort(m_timesig_table); + for ( int j = 1; j < m_timesig_table.size(); j++ ) { + int numerator = m_timesig_table.get(j - 1).Numerator; + int denominator = m_timesig_table.get(j - 1).Denominator; + int clock = m_timesig_table.get(j - 1).Clock; + int bar_count = m_timesig_table.get(j - 1).BarCount; + int dif = 480 * 4 / denominator * numerator;//1小節が何クロックか? + + clock += (m_timesig_table.get(j).BarCount - bar_count) * dif; + m_timesig_table.get(j).Clock = clock; + } + m_premeasure_clocks = GetPreMeasureInClock(); + + } + + + /// + /// TempoTableの[*].Timeの部分を更新します + /// + public void updateTempoInfo() { + if ( m_tempo_table.size() == 0 ) { + m_tempo_table.add( new TempoTableEntry( 0, getBaseTempo(), 0.0 ) ); + } + Collections.sort( m_tempo_table); + if ( m_tempo_table.get(0).Clock != 0 ) { + m_tempo_table.get(0).Time = (double)getBaseTempo() * (double)m_tempo_table.get(0).Clock / (getTickPerQuarter() * 1000000.0); + } else { + m_tempo_table.get(0).Time = 0.0; + } + double prev_time = m_tempo_table.get(0).Time; + int prev_clock = m_tempo_table.get(0).Clock; + int prev_tempo = m_tempo_table.get(0).Tempo; + double inv_tpq_sec = 1.0 / (getTickPerQuarter() * 1000000.0); + for ( int i = 1; i < m_tempo_table.size(); i++ ) { + m_tempo_table.get( i ).Time = prev_time + (double)prev_tempo * (double)(m_tempo_table.get( i ).Clock - prev_clock) * inv_tpq_sec; + prev_time = m_tempo_table.get( i ).Time; + prev_tempo = m_tempo_table.get( i ).Tempo; + prev_clock = m_tempo_table.get( i ).Clock; + } + } + + + /// + /// VsqFile.Executeの実行直後などに、m_total_clocksの値を更新する + /// + public void updateTotalClocks() { + long max = m_premeasure_clocks; + for ( int i = 1; i < m_tracks.size(); i++ ) { + VsqTrack track = m_tracks.get( i ); + for ( Iterator itr = track.getEvents().iterator(); itr.hasNext();) { + VsqEvent ve = (VsqEvent)itr.next(); + max = Math.max( max, (long)(ve.Clock + ve.ID.Length) ); + } + VsqCurveType[] values = VsqCurveType.values(); + for ( int j = 0; j < values.length; j++ ) { + VsqCurveType vct = values[j]; + if ( vct == VsqCurveType.VEL ) { + continue; + } + if ( track.getVsqBPList( vct).size() > 0 ) { + Set keys_list = track.getVsqBPList( vct ).keyClockSet(); + long last_key = 0; + for( Iterator itr = keys_list.iterator(); itr.hasNext(); ){ + last_key = Math.max( last_key, (Integer)itr.next() ); + } + max = Math.max( max, last_key ); + } + } + } + TotalClocks = max; + } + + + /// + /// 曲の長さを取得する。(sec) + /// + public double getTotalSec() { + return SecFromClock( (int)TotalClocks ); + } + + + /// + /// 指定された番号のトラックに含まれる歌詞を指定されたファイルに出力します + /// + /// + /// + public void printLyricTable( int track, String fpath ) { + BufferedWriter sw = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( fpath) ) ); + for ( int i = 0; i < m_tracks.get( track ).getEvents().size(); i++ ) { + int Length; + // timesignal + int time_signal = m_tracks.get( track ).getEvents().get( i ).Clock; + // イベントで指定されたIDがLyricであった場合 + if ( m_tracks.get( track ).getEvents().get( i ).ID.type == VsqIDType.Anote ) { + // 発音長を取得 + Length = m_tracks.get( track ).getEvents().get( i ).ID.Length; + + // tempo_tableから、発音開始時のtempoを取得 + int last = m_tempo_table.size() - 1; + int tempo = m_tempo_table.get(last).Tempo; + int prev_index = m_tempo_table.get(last).Clock; + double prev_time = m_tempo_table.get(last).Time; + for ( int j = 1; j < m_tempo_table.size(); j++ ) { + if ( m_tempo_table.get(j).Clock > time_signal ) { + tempo = m_tempo_table.get(j - 1).Tempo; + prev_index = m_tempo_table.get(j - 1).Clock; + prev_time = m_tempo_table.get(j - 1).Time; + break; + } + } + int current_index = m_tracks.get( track ).getEvents().get( i ).Clock; + double start_time = prev_time + (double)(current_index - prev_index) * (double)tempo / (m_tpq * 1000000.0); + // TODO: 単純に + Lengthしただけではまずいはず。要検討 + double end_time = start_time + ((double)Length) * ((double)tempo) / (m_tpq * 1000000.0); + DecimalFormat df = new DecimalFormat("0.000000" ); + sw.write( m_tracks.get( track ).getEvents().get( i ).Clock + "," + + df.format( start_time) + "," + + df.format( end_time) + "," + + m_tracks.get( track ).getEvents().get( i ).ID.LyricHandle.L0.Phrase + "," + + m_tracks.get( track ).getEvents().get( i ).ID.LyricHandle.L0.getPhoneticSymbol() + "\n" ); + } + + } + + } + + private void printTrack( VsqTrack item, RandomAccessFile fs, int msPreSend ) { + //VsqTrack item = m_tracks.get( track ); + String _NL = "" + (char)0x0a; + //ヘッダ + fs.write( _MTRK, 0, 4 ); + //データ長。とりあえず0 + fs.write( new byte[] {0x00, 0x00, 0x00, 0x00}, 0, 4 ); + long first_position = fs.getFilePointer(); + //トラック名 + writeFlexibleLengthUnsignedLong( fs, 0x00 );//デルタタイム + + fs.write( 0xff );//ステータスタイプ + + fs.write( 0x03 );//イベントタイプSequence/Track Name + + char[] seq_name = Lyric.encode( item.getName() ); + writeFlexibleLengthUnsignedLong( fs, (long)seq_name.length );//seq_nameの文字数 + + writeCharArray( fs, seq_name ); + //Meta Textを準備 + TextMemoryStream sr = new TextMemoryStream(); + item.printMetaText( sr, false, TotalClocks + 120, GetPreMeasureInClock() ); + sr.rewind(); + int line_count = -1; + String tmp = ""; + if ( sr.peek() >= 0 ) { + tmp = sr.readLine(); + char[] line_char; + String line = ""; + while ( sr.peek() >= 0 ) { + line = sr.readLine(); + tmp += _NL + line; + while ( (tmp + getLinePrefix( line_count )).length() >= 127 ) { + line_count++; + tmp = getLinePrefix( line_count ) + tmp; + String work = tmp.substring( 0, 127 ); + tmp = tmp.substring( 127 ); + line_char = work.toCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.write( 0xff );//ステータスタイプ + + fs.write( 0x01 );//イベントタイプMeta Text + + writeFlexibleLengthUnsignedLong( fs, (long)line_char.length );//データ長 + + writeCharArray( fs, line_char );//メタテキスト本体 + + } + } + // 残りを出力 + line_count++; + tmp = getLinePrefix( line_count ) + tmp + _NL; + while ( tmp.length() > 127 ) { + String work = tmp.substring( 0, 127 ); + tmp = tmp.substring( 127 ); + line_char = work.toCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.write( 0xff ); + fs.write( 0x01 ); + writeFlexibleLengthUnsignedLong( fs, line_char.length ); + writeCharArray( fs, line_char ); + line_count++; + tmp = getLinePrefix( line_count ); + } + line_char = tmp.toCharArray(); + writeFlexibleLengthUnsignedLong( fs, 0x00 ); + fs.write( 0xff ); + fs.write( 0x01 ); + writeFlexibleLengthUnsignedLong( fs, (long)line_char.length ); + writeCharArray( fs, line_char ); + } + + + int last = 0; + VsqNrpn[] data = generateNRPN( item, msPreSend ); + + NrpnData[] nrpns = VsqNrpn.convert( data ); + for ( int i = 0; i < nrpns.length; i++ ) { + writeFlexibleLengthUnsignedLong( fs, (long)(nrpns[i].Clock - last) ); + fs.write( 0xb0 ); + fs.write( nrpns[i].Parameter ); + fs.write( nrpns[i].Value ); + last = nrpns[i].Clock; + } + + //トラックエンド + VsqEvent last_event = item.getEvents().get(item.getEvents().size() - 1); + int last_clock = last_event.Clock + last_event.ID.Length; + writeFlexibleLengthUnsignedLong( fs, (long)last_clock ); + fs.write( 0xff ); + fs.write( 0xf2 ); + fs.write( 0x00 ); + long pos = fs.getFilePointer(); + fs.seek( first_position - 4 ); + writeUnsignedInt( fs, pos - first_position ); + fs.seek( pos ); + } + + + /// + /// 指定したクロックにおけるプリセンド・クロックを取得します + /// + /// + /// + /// + public int getPresendClockAt( int clock, int msPreSend ) { + double clock_msec = SecFromClock( clock ) * 1000.0; + float draft_clock_sec = (float)(clock_msec - msPreSend) / 1000.0f; + int draft_clock = (int)Math.floor( ClockFromSec( draft_clock_sec ) ); + return clock - draft_clock; + } + + + /// + /// 指定したトラックから、Expression(DYN)のNRPNリストを作成します + /// + /// + /// + /// + public VsqNrpn[] generateExpressionNRPN( VsqTrack track, int msPreSend ) { + return generateExpressionNRPN( track, msPreSend, 0, (int)TotalClocks, 0 ); + } + + public VsqNrpn[] generateExpressionNRPN( VsqTrack track, int msPreSend, int clStart, int clEnd, int t_temp_premeasure ) { + Vector ret = new Vector(); + //SortedList list = track[VsqCurveType.DYN].Vector; + int count = track.getVsqBPList( VsqCurveType.DYN ).size(); + Byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ); + int start_clock = clStart < m_premeasure_clocks ? m_premeasure_clocks : clStart; + int start_value = track.getVsqBPList(VsqCurveType.DYN).get(start_clock); + VsqNrpn add0 = new VsqNrpn( start_clock - getPresendClockAt( start_clock, msPreSend ) - clStart + t_temp_premeasure, 0x6300, (byte)0x00, (byte)0x00 ); + add0.append( 0x6301, delay0, delay1 ); + add0.append( 0x6302, (byte)start_value ); + ret.add( add0 ); + Integer[] keys = track.getVsqBPList(VsqCurveType.DYN).keyClockSet().toArray( new Integer[0] ); + for ( int i = 1; i < keys.length; i++ ) { + if ( keys[i] > clEnd ) { + break; + } + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i] - getPresendClockAt( keys[i], msPreSend ) - clStart + t_temp_premeasure, 0x6302, (byte)track.getVsqBPList(VsqCurveType.DYN).get(keys[i]) ); + ret.add( add ); + } + } + return ret.toArray( new VsqNrpn[0] ); + } + + + /// + /// 先頭に記録されるNRPNを作成します + /// + /// + public static VsqNrpn generateHeaderNRPN() { + VsqNrpn ret = new VsqNrpn( 0, 0x6000, (byte)0x00, (byte)0x00 ); // 0x00 (NRPN 0x6000 BNK device number = 0x00) + + ret.append( 0x6001, (byte)0x00, (byte)0x00 ); // 0x00 (NRPN 0x6001 BNK DELAY delay = 0x0000) + //ret.append( 0x6002, 0x00 ); // 0x00 (NRPN 0x6002 LANGUAGE TYPE language type = 0x00) + //ret.append( 0x5302, 0x00 ); // 0x00 (NRPN 0x5302 VOICE TYPE voice type = 0x00) + + return ret; + } + + public VsqNrpn[] generateSingerNRPN( VsqEvent ve, int msPreSend, int clShift ) { + int clock = ve.Clock; + + double clock_msec = SecFromClock( clock ) * 1000.0; + + int ttempo = getTempoAt( clock ); + double tempo = 6e7 / ttempo; + //double sStart = SecFromClock( ve.Clock ); + double msEnd = SecFromClock( ve.Clock + ve.ID.Length ) * 1000.0; + int duration = (int)Math.ceil( msEnd - clock_msec ); + Byte duration0, duration1; + getMsbAndLsb( duration, duration0, duration1 ); + Byte delay0, delay1; + getMsbAndLsb( (int)msPreSend, delay0, delay1 ); + Vector ret = new Vector(); + + VsqNrpn add = new VsqNrpn( clock - getPresendClockAt( clock, msPreSend ) - clShift, 0x6002, (byte)ve.ID.IconHandle.Language ); + add.append( 0x5302, (byte)ve.ID.IconHandle.Program ); + return new VsqNrpn[] {add}; + } + + + /// + /// 指定したVsqEventを表現するNRPNを作成します + /// + /// + /// + /// + /// + public VsqNrpn[] generateNoteNRPN( VsqEvent ve, int msPreSend, byte note_loc ) { + return generateNoteNRPN( ve, msPreSend, note_loc, 0 ); + } + + public VsqNrpn[] generateNoteNRPN( VsqEvent ve, int msPreSend, byte note_loc, int clShift ) { + int clock = ve.Clock; + + double clock_msec = SecFromClock( clock ) * 1000.0; + + int ttempo = getTempoAt( clock ); + double tempo = 6e7 / ttempo; + //double sStart = SecFromClock( ve.Clock ); + double msEnd = SecFromClock( ve.Clock + ve.ID.Length ) * 1000.0; + int duration = (int)Math.ceil( msEnd - clock_msec ); + + Byte duration0, duration1; + getMsbAndLsb( duration, duration0, duration1 ); + Byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ); + Vector ret = new Vector(); + + VsqNrpn add = new VsqNrpn( clock - getPresendClockAt( clock, msPreSend ) - clShift, 0x5001, delay0, delay1 ); + add.append( 0x5002, (byte)ve.ID.Note ); // Note number + + add.append( 0x5003, (byte)ve.ID.Dynamics ); // Velocity + + add.append( 0x5004, duration0, duration1 ); // Note duration(LSB) + + add.append( 0x5005, note_loc ); // Note Location + + if ( ve.ID.VibratoHandle != null ) { + add.append( 0x500c, (byte)0x00, (byte)0x00 ); + int vibrato_type = VibratoTypeUtil.FromIconID( ve.ID.VibratoHandle.IconID ).ordinal(); + int note_length = ve.ID.Length; + int vibrato_delay = ve.ID.VibratoDelay; + byte bVibratoDuration = (byte)((float)(note_length - vibrato_delay) / (float)note_length * 127); + byte bVibratoDelay = (byte)(0x7f - bVibratoDuration); + add.append( 0x500d, (byte)vibrato_type, bVibratoDuration ); + add.append( 0x500e, bVibratoDelay ); + } + + String[] spl = ve.ID.LyricHandle.L0.getPhoneticSymbolList(); + String s = ""; + for ( int j = 0; j < spl.length; j++ ) { + s += spl[j]; + } + char[] symbols = s.toCharArray(); + add.append( 0x5012, (byte)symbols.length );// 0x12(Number of phonetic symbols in bytes) + + int count = -1; + for ( int j = 0; j < spl.length; j++ ) { + char[] chars = spl[j].toCharArray(); + for ( int k = 0; k < chars.length; k++ ) { + count++; + if ( k == 0 ) { + add.append( ((0x50 << 8) | (byte)(0x13 + count)), (byte)chars[k], (byte)ve.ID.LyricHandle.L0.getConsonantAdjustment()[j] ); // Phonetic symbol j + + } else { + add.append( (0x50 << 8) | (byte)(0x13 + count), (byte)chars[k] ); // Phonetic symbol j + + } + } + } + add.append( 0x504f, (byte)0x7f ); // End of phonetic symbols + + add.append( 0x5050, (byte)0x04 );// 0x50(v1mean) + + add.append( 0x5051, (byte)0x08 );// 0x51(d1mean) + + add.append( 0x5052, (byte)0x14 );// 0x52(d1meanFirstNote) + + add.append( 0x5053, (byte)0x1c );// 0x53(d2mean) + + add.append( 0x5054, (byte)0x18 );// 0x54(d4mean) + + add.append( 0x5055, (byte)0x0a ); // 055(pMeanOnsetFirstNote) + + add.append( 0x5056, (byte)0x0c ); // 0x56(vMeanNoteTransition) + + add.append( 0x5057, (byte)0x0c );// 0x57(pMeanEndingNote) + + add.append( 0x5058, (byte)ve.ID.PMbPortamentoUse );// 0x58(AddScoopToUpInternals&AddPortamentoToDownIntervals) + + add.append( 0x5059, (byte)0x32 );// 0x59(changeAfterPeak) + + add.append( 0x505a, (byte)0x32 );// 0x5a(Accent) + + add.append( 0x507f, (byte)0x7f );// 0x7f(Note message continuation) + + ret.add( add ); + return ret.toArray(new VsqNrpn[0]); + } + + + /// + /// 指定したトラックのデータから、NRPNのリストを作成します + /// + /// + /// + /// + public VsqNrpn[] generateNRPN( VsqTrack track, int msPreSend ) { + return generateNRPN( track, msPreSend, 0, (int)TotalClocks, 0 ); + } + + public VsqNrpn[] generateNRPN( VsqTrack track, int msPreSend, int clStart, int clEnd, int t_temp_premeasure ) { + Vector list = new Vector(); + list.add( generateHeaderNRPN() ); + + int count = track.getEvents().size(); + int note_start = 0; + int note_end = track.getEvents().size() - 1; + for ( int i = 0; i < track.getEvents().size(); i++ ) { + if ( clStart <= track.getEvents().get( i ).Clock ) { + note_start = i; + break; + } + note_start = i; + } + for ( int i = track.getEvents().size() - 1; i >= 0; i-- ) { + if ( track.getEvents().get( i ).Clock <= clEnd ) { + note_end = i; + break; + } + } + + // 最初の歌手を決める + int singer_event = -1; + for ( int i = note_start; i >= 0; i-- ) { + if ( track.getEvents().get( i ).ID.type == VsqIDType.Singer ) { + singer_event = i; + break; + } + } + if ( singer_event >= 0 ) { //見つかった場合 + Collections.addAll( list, generateSingerNRPN( track.getEvents().get(singer_event), 0, 0 ) ); + } else { //多分ありえないと思うが、歌手が不明の場合。 + + list.add( new VsqNrpn( 0, 0x6002, (byte)0 ) ); + list.add( new VsqNrpn( 0, 0x5302, (byte)0 ) ); + } + + for ( int i = note_start; i <= note_end; i++ ) { + byte note_loc = 0x00; + if ( i == note_start ) { + if ( i == note_end ) { + note_loc = 0x03; + } else { + note_loc = 0x01; + } + } else if ( i == note_end ) { + note_loc = 0x02; + } + + if ( track.getEvents().get( i ).ID.type == VsqIDType.Anote ) { + Collections.addAll( list, generateNoteNRPN( + track.getEvents().get( i ), + msPreSend, + note_loc, + clStart - t_temp_premeasure ) ); + Collections.addAll( list, generateVibratoNRPN( + track.getEvents().get( i ), + msPreSend, + clStart - t_temp_premeasure ) ); + } else if ( track.getEvents().get( i ).ID.type == VsqIDType.Singer ) { + if ( i > note_start ) { + Collections.addAll( list, generateSingerNRPN( track.getEvents().get( i ), msPreSend, clStart - t_temp_premeasure ) ); + } + } + } + Collections.addAll( list, generateVoiceChangeParameterNRPN( track, msPreSend, clStart, clEnd, t_temp_premeasure ) ); + Collections.addAll( list, generateExpressionNRPN( track, msPreSend, clStart, clEnd, t_temp_premeasure ) ); + Collections.addAll( list, generatePitchBendNRPN( track, msPreSend, clStart, clEnd, t_temp_premeasure ) ); + Collections.addAll( list, generatePitchBendSensitivityNRPN( track, msPreSend, clStart, clEnd, t_temp_premeasure ) ); + + Collections.sort( list ); + Vector merged = new Vector(); + for ( int i = 0; i < list.size(); i++ ) { + Collections.addAll( merged, list.get( i ).expand() ); + } + return merged.toArray( new VsqNrpn[0]); + } + + + /// + /// 指定したトラックから、PitchBendのNRPNを作成します + /// + /// + /// + /// + public VsqNrpn[] generatePitchBendNRPN( VsqTrack track, int msPreSend ) { + return generatePitchBendNRPN( track, msPreSend, 0, (int)TotalClocks, 0 ); + } + + public VsqNrpn[] generatePitchBendNRPN( VsqTrack track, int msPreSend, int clStart, int clEnd, int t_pre_measure ) { + Vector ret = new Vector(); + //SortedList list = track[VsqCurveType.PIT].Vector; + Integer[] keys = track.getVsqBPList(VsqCurveType.PIT).keyClockSet().toArray( new Integer[0]); + int count = keys.length; + byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ); + int start_clock = clStart < m_premeasure_clocks ? m_premeasure_clocks : clStart; + VsqNrpn add0 = new VsqNrpn( start_clock - getPresendClockAt( start_clock, msPreSend ) - clStart + t_pre_measure, 0x5400, (byte)0x00, (byte)0x00 ); + add0.append( 0x5401, delay0, delay1 ); + + int start_value = track.getVsqBPList(VsqCurveType.PIT).get(start_clock) + 0x2000; + byte start_value0, start_value1; + getMsbAndLsb( start_value, start_value0, start_value1 ); + add0.append( 0x5402, start_value0, start_value1 ); + ret.add( add0 ); + + for ( int i = 1; i < keys.length; i++ ) { + if ( keys[i] > clEnd ) { + break; + } + if ( keys[i] > start_clock ) { + int value = track.getVsqBPList(VsqCurveType.PIT).get(keys[i])+ 0x2000; + byte value0, value1; + getMsbAndLsb( value, value0, value1 ); + VsqNrpn add = new VsqNrpn( keys[i] - getPresendClockAt( keys[i], msPreSend ) - clStart + t_pre_measure, 0x5402, value0, value1 ); + ret.add( add ); + } + } + return ret.toArray(new VsqNrpn[0]); + } + + + /// + /// 指定したトラックからPitchBendSensitivityのNRPNを作成します + /// + /// + /// + /// + public VsqNrpn[] generatePitchBendSensitivityNRPN( VsqTrack track, int msPreSend ) { + return generatePitchBendSensitivityNRPN( track, msPreSend, 0, (int)TotalClocks, 0 ); + } + + public VsqNrpn[] generatePitchBendSensitivityNRPN( VsqTrack track, int msPreSend, int clStart, int clEnd, int t_pre_measure ) { + Vector ret = new Vector(); + //SortedList list = track[VsqCurveType.PBS].Vector; + Integer[] keys = track.getVsqBPList(VsqCurveType.PBS).keyClockSet().toArray(new Integer[0]); + int count = keys.length; + Byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ) ; + int start_clock = clStart < m_premeasure_clocks ? m_premeasure_clocks : clStart; + int start_value = track.getVsqBPList(VsqCurveType.PBS).get( start_clock); + VsqNrpn add0 = new VsqNrpn( start_clock - getPresendClockAt( start_clock, msPreSend ) - clStart + t_pre_measure, 0x6700, (byte)0x00, (byte)0x00 ); + add0.append( 0x6701, delay0, delay1 ); + add0.append( 0x6702, (byte)start_value, (byte)0x00 ); + ret.add( add0 ); + for ( int i = 1; i < keys.length; i++ ) { + if ( keys[i] > clEnd ) { + break; + } + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i]- getPresendClockAt( keys[i], msPreSend ) - clStart + t_pre_measure, 0x6702, (byte)track.getVsqBPList(VsqCurveType.PBS).get(keys[i]), (byte)0x00 ); + ret.add( add ); + } + } + return ret.toArray( new VsqNrpn[0]); + } + + public VsqNrpn[] generateVibratoNRPN( VsqEvent ve, int msPreSend ) { + return generateVibratoNRPN( ve, msPreSend, 0 ); + } + + public VsqNrpn[] generateVibratoNRPN( VsqEvent ve, int msPreSend, int clShift ) { + Vector ret = new Vector(); + if ( ve.ID.VibratoHandle != null ) { + int vclock = ve.Clock + ve.ID.VibratoDelay; + Byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ) ; + VsqNrpn add2 = new VsqNrpn( vclock - getPresendClockAt( vclock, msPreSend ) - clShift, 0x6500, (byte)0x00, (byte)0x00 ); + add2.append( 0x6501, delay0, delay1 ); + add2.append( 0x6502, (byte)ve.ID.VibratoHandle.StartDepth ); + add2.append( 0x6402, (byte)ve.ID.VibratoHandle.StartRate ); + ret.add( add2 ); + int vlength = ve.Clock + ve.ID.Length - ve.ID.VibratoDelay; + if ( ve.ID.VibratoHandle.RateBPNum > 0 ) { + for ( int i = 0; i < ve.ID.VibratoHandle.RateBPX.length; i++ ) { + float percent = ve.ID.VibratoHandle.RateBPX[i]; + int cl = vclock + (int)(percent * vlength); + ret.add( new VsqNrpn( cl, 0x6402, (byte)ve.ID.VibratoHandle.RateBPY[i] ) ); + } + } + if ( ve.ID.VibratoHandle.DepthBPNum > 0 ) { + for ( int i = 0; i < ve.ID.VibratoHandle.DepthBPX.length; i++ ) { + float percent = ve.ID.VibratoHandle.DepthBPX[i]; + int cl = vclock + (int)(percent * vlength); + ret.add( new VsqNrpn( cl, 0x6502, (byte)ve.ID.VibratoHandle.DepthBPY[i] ) ); + } + } + } + Collections.sort( ret ); + return ret.toArray(new VsqNrpn[0]); + } + + + /// + /// 指定したトラックから、VoiceChangeParameterのNRPNのリストを作成します + /// + /// + /// + /// + public VsqNrpn[] generateVoiceChangeParameterNRPN( VsqTrack track, int msPreSend ) { + return generateVoiceChangeParameterNRPN( track, msPreSend, 0, (int)TotalClocks, 0 ); + } + + public VsqNrpn[] generateVoiceChangeParameterNRPN( VsqTrack track, int msPreSend, int clStart, int clEnd, int t_pre_measure ) { + int premeasure_clock = m_premeasure_clocks; + byte delay0, delay1; + getMsbAndLsb( msPreSend, delay0, delay1 ); + Vector < VsqNrpn + > res = new Vector(); + int start_clock = (clStart < premeasure_clock) ? premeasure_clock : clStart; + VsqNrpn ret = new VsqNrpn( start_clock - getPresendClockAt( start_clock, msPreSend ) - clStart + t_pre_measure, 0x5500, (byte)0x00, (byte)0x00 ); + + ret.append( 0x5501, delay0, delay1 ); // Voice Change Parameter delay + + ret.append( 0x5502, (byte)0x31 ); // BRE + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.BRE).get(start_clock) ); + + ret.append( 0x5502, (byte)0x32 ); // BRI + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.BRI).get(start_clock) ); + + ret.append( 0x5502, (byte)0x33 ); // CLE + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.CLE).get(start_clock) ); + + ret.append( 0x5502, (byte)0x34 ); // POR + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.POR).get(start_clock) ); + + ret.append( 0x5502, (byte)0x35 ); // OPE + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.OPE).get(start_clock) ); + + ret.append( 0x5502, (byte)0x70 ); // GEN + + ret.append( 0x5503, (byte)track.getVsqBPList(VsqCurveType.GEN).get(start_clock) ); + res.add( ret ); + + VsqCurveType[] values = VsqCurveType.values(); + for( int j = 0; j < values.length; j++ ){ + VsqCurveType vct = values[j]; + byte lsb = 0x31; + switch ( vct ) { + case DYN: + case PBS: + case PIT: + case VEL: + continue; + case BRE: + lsb = 0x31; + break; + case BRI: + lsb = 0x32; + break; + case CLE: + lsb = 0x33; + break; + case POR: + lsb = 0x34; + break; + case OPE: + lsb = 0x35; + break; + case GEN: + lsb = 0x70; + break; + } + //SortedList list = track[vct].Vector; + Integer[] keys = track.getVsqBPList(vct).keyClockSet().toArray( new Integer[0]); + for ( int i = 0; i < keys.length; i++ ) { + if ( keys[i] > clEnd ) { + break; + } + if ( keys[i] > start_clock ) { + VsqNrpn add = new VsqNrpn( keys[i] - getPresendClockAt( keys[i], msPreSend ) - clStart + t_pre_measure, 0x5502, lsb ); + add.append( 0x5503, (byte)track.getVsqBPList(vct).get(keys[i]) ); + res.add( add ); + } + } + } + + return res.toArray( new VsqNrpn[0]); + } + + private static void getMsbAndLsb( int value, Byte msb,Byte lsb ) { + msb = (byte)(value >> 7); + lsb = (byte)(value - (msb << 7)); + } + + + /// + /// ファイルにこのVsqFileインスタンスの中身を出力します。 + /// + /// + /// プリセンドタイム(msec) + public void write( String file, int msPreSend ) { + int last_clock = 0; + for ( int track = 1; track < m_tracks.size(); track++ ) { + if ( m_tracks.get( track ).getEvents().size() > 0 ) { + int index = m_tracks.get( track ).getEvents().size() - 1; + VsqEvent last = m_tracks.get( track ).getEvents().get( index ); + last_clock = Math.max( last_clock, last.Clock + last.ID.Length ); + } + } + + //int delay = DelayFromPreSend( pre_send ); + RandomAccessFile fs = new RandomAccessFile( file, "rw" ); + long first_position;//チャンクの先頭のファイル位置 + + // ヘッダ + //チャンクタイプ + fs.write( _MTHD, 0, 4 ); + //データ長 + fs.writeByte( 0x00 ); + fs.writeByte( 0x00 ); + fs.writeByte( 0x00 ); + fs.writeByte( 0x06 ); + //フォーマット + fs.writeByte( 0x00 ); + fs.writeByte( 0x01 ); + //トラック数 + writeUnsignedShort( fs, this.m_tracks.size() ); + //時間単位 + fs.writeByte( 0x01 ); + fs.writeByte( 0xe0 ); + + // Master Track + //チャンクタイプ + fs.write( _MTRK, 0, 4 ); + //データ長。とりあえず0を入れておく + fs.write( new byte[] { 0x00, 0x00, 0x00, 0x00 }, 0, 4 ); + first_position = fs.getFilePointer(); + //トラック名 + writeFlexibleLengthUnsignedLong( fs, 0 );//デルタタイム + fs.writeByte( 0xff );//ステータスタイプ + fs.writeByte( 0x03 );//イベントタイプSequence/Track Name + fs.writeByte( (byte)_MASTER_TRACK.length );//トラック名の文字数。これは固定 + fs.write( _MASTER_TRACK, 0, _MASTER_TRACK.length ); + + Vector events = new Vector(); + for (int i = 0; i < this.m_timesig_table.size(); i++ ){ + TimeSigTableEntry entry = m_timesig_table.get( i ); + events.add( MidiEvent.TimeSig( entry.Clock, entry.Numerator, entry.Denominator ) ); + last_clock = Math.max( last_clock, entry.Clock ); + } + for( int i = 0; i < m_tempo_table.size(); i++ ){ + TempoTableEntry entry = m_tempo_table.get( i ); + events.add( MidiEvent.TempoChange( entry.Clock, entry.Tempo ) ); + last_clock = Math.max( last_clock, entry.Clock ); + } + Collections.sort( events); + int last = 0; + for( int i = 0; i < events.size(); i++ ){ + MidiEvent item = events.get( i ); + switch ( item.type ) { + case tempo: + writeFlexibleLengthUnsignedLong( fs, item.index - last) ; + last = item.index; + fs.writeByte( 0xff ); + fs.writeByte( 0x51 ); + fs.writeByte( 0x03 ); + writeTempo( fs, item.intValue[0] ); + break; + case time_signal: + int num = item.intValue[0]; + int den = item.intValue[1]; + writeFlexibleLengthUnsignedLong( fs, item.index - last ); + last = item.index; + fs.writeByte( 0xff ); + fs.writeByte( 0x58 );//イベントタイプTime Signature + fs.writeByte( 0x04 );//データ長 + fs.writeByte( (byte)num );//分子 + fs.writeByte( (byte)(Math.log( den ) / Math.log( 2.0 ) ) );//分母の2の負のべき乗数 + fs.writeByte( 0x18 ); + fs.writeByte( 0x08 ); + break; + } + } + + //WriteFlexibleLengthUnsignedLong( fs, (ulong)(last_clock + 120 - last) ); + writeFlexibleLengthUnsignedLong( fs, 0 ); + fs.writeByte( 0xff ); + fs.writeByte( 0x2f );//イベントタイプEnd of Track + fs.writeByte( 0x00 ); + long pos = fs.getFilePointer(); + fs.seek( first_position - 4); + writeUnsignedInt( fs, pos - first_position); + fs.seek( pos); + + // トラック + VsqTrack t_track = (VsqTrack)m_tracks.get( 1).clone(); + t_track.setMaster( (VsqMaster)Master.clone() ); + t_track.setMixer( (VsqMixer)Mixer.clone() ); + printTrack( t_track, fs, msPreSend ); + for ( int track = 2; track < m_tracks.size(); track++ ) { + printTrack( m_tracks.get( track ), fs, msPreSend ); + } + } + + public void write( String file ) { + write( file, 500 ); + } + + + /// + /// メタテキストの行番号から、各行先頭のプレフィクス文字列("DM:0123:"等)を作成します + /// + /// + /// + public static String getLinePrefix( int count ) { + int digits = howManyDigits( count ); + int c = (digits - 1) / 4 + 1; + String format = ""; + for ( int i = 0; i < c; i++ ) { + format += "0000"; + } + DecimalFormat df = new DecimalFormat( format ); + return "DM:" + df.format( count ) + ":"; + } + + + /// + /// 数numberの桁数を調べます。(10進数のみ) + /// + /// + /// + private static int howManyDigits( int number ) { + int val; + if ( number > 0 ) { + val = number; + } else { + val = -number; + } + int i = 1; + int digits = 1; + while ( true ) { + i++; + digits *= 10; + if ( val < digits ) { + return i - 1; + } + } + } + + + /// + /// char[]を書き込む。 + /// + /// + /// + public void writeCharArray( RandomAccessFile fs, char[] item ) { + for ( int i = 0; i < item.length; i++ ) { + fs.writeByte( (byte)item[i] ); + } + } + + + /// + /// テンポ値をビッグエンディアンで書き込みます。 + /// テンポは3バイトで記入されるので、別関数を用意した。 + /// + /// + /// + public void writeTempo( RandomAccessFile fs, long tempo ) { + byte[] dat = new byte[3]; + ByteBuffer.wrap( dat ).order( ByteOrder.nativeOrder() ).putLong( tempo ); + fs.write( dat ); + } + + + /// + /// ushort値をビッグエンディアンでfsに書き込みます + /// + /// + public void writeUnsignedShort( RandomAccessFile fs, int data ) { + byte[] dat = new byte[2]; + ByteBuffer.wrap( dat ).order( ByteOrder.nativeOrder() ).putInt( data ); + fs.write( dat ); + } + + + /// + /// uint値をビッグエンディアンでfsに書き込みます + /// + /// + public void writeUnsignedInt( RandomAccessFile fs, long data ) { + byte[] dat = new byte[4]; + ByteBuffer.wrap( dat ).order( ByteOrder.nativeOrder() ).putLong( data ); + fs.write( dat ); + } + + + /// + /// SMFの可変長数値表現を使って、ulongをbyte[]に変換します + /// + /// + /// + public static byte[] getBytesFlexibleLengthUnsignedLong( long number ) { + boolean[] bits = new boolean[64]; + long val = 0x1; + bits[0] = (number & val) == val; + for ( int i = 1; i < 64; i++ ) { + val = val << 1; + bits[i] = (number & val) == val; + } + int first = 0; + for ( int i = 63; i >= 0; i-- ) { + if ( bits[i] ) { + first = i; + break; + } + } + // 何バイト必要か? + int bytes = first / 7 + 1; + byte[] ret = new byte[bytes]; + for ( int i = 1; i <= bytes; i++ ) { + int num = 0; + int count = 0x80; + for ( int j = (bytes - i + 1) * 7 - 1; j >= (bytes - i + 1) * 7 - 6 - 1; j-- ) { + count = count >> 1; + if ( bits[j] ) { + num += count; + } + } + if ( i != bytes ) { + num += 0x80; + } + ret[i - 1] = (byte)num; + } + return ret; + } + + + /// + /// 整数を書き込む。フォーマットはSMFの可変長数値表現。 + /// + /// + /// + public static void writeFlexibleLengthUnsignedLong( RandomAccessFile fs, long number ) { + byte[] bytes = getBytesFlexibleLengthUnsignedLong( number ); + fs.write( bytes, 0, bytes.length ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandle.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandle.java new file mode 100644 index 0000000..f0a2b54 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandle.java @@ -0,0 +1,391 @@ +/* + * VsqHandle.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.io.*; +import java.text.*; + +/// +/// ハンドルを取り扱います。ハンドルにはLyricHandle、VibratoHandleおよびIconHandleがある +/// +public class VsqHandle { + public VsqHandleType Type; + public int Index; + /*protected String m_icon_id; + protected String m_ids; + protected Lyric m_lyric; + protected int m_original; + protected String m_caption; + protected int m_length; + protected int m_start_depth; + protected int DepthBPNum; + protected float[] DepthBPX; + protected int[] DepthBPY; + protected int m_start_rate; + protected int RateBPNum; + protected float[] RateBPX; + protected int[] RateBPY; + protected int m_language; + protected int m_program;*/ + public String IconID; + public String IDS; + public Lyric L0; + public int Original; + public String Caption; + public int Length; + public int StartDepth; + public int DepthBPNum; + public float[] DepthBPX; + public int[] DepthBPY; + public int StartRate; + public int RateBPNum; + public float[] RateBPX; + public int[] RateBPY; + public int Language; + public int Program; + + public LyricHandle ConvertToLyricHandle() { + LyricHandle ret = new LyricHandle(); + ret.L0 = (Lyric)L0.clone(); + ret.Type = Type;//m_type; + + ret.Index = Index;// m_index; + + return ret; + } + + public VibratoHandle ConvertToVibratoHandle() { + VibratoHandle ret = new VibratoHandle(); + ret.Type = Type; + ret.Index = Index; + ret.Caption = Caption; + ret.DepthBPNum = DepthBPNum; + ret.DepthBPX = DepthBPX; + ret.DepthBPY = DepthBPY; + ; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Length = Length; + ret.Original = Original; + ret.RateBPNum = RateBPNum; + ret.RateBPX = RateBPX; + ret.RateBPY = RateBPY; + ret.StartDepth = StartDepth; + ret.StartRate = StartRate; + return ret; + } + + public IconHandle ConvertToIconHandle() { + IconHandle ret = new IconHandle(); + ret.Type = Type; + ret.Index = Index; + ret.Caption = Caption; + ret.IconID = IconID; + ret.IDS = IDS; + ret.Language = Language; + ret.Length = Length; + ret.Original = Original; + ret.Program = Program; + return ret; + } + + + /*public VsqHandleType Type { + get { + return m_type; + } + set { + m_type = value; + } + } + + + public int Index { + get { + return m_index; + } + set { + m_index = value; + } + }*/ + /*// + /// このインスタンスの簡易コピーを取得します。 + /// + /// + public object Clone() { + VsqHandle result = new VsqHandle(); + result.m_type = m_type; + result.m_index = m_index; + result.m_icon_id = m_icon_id; + result.IDS = this.IDS; + if ( this.L0 != null ) { + result.L0 = this.L0.Clone(); + } + result.Original = this.Original; + result.Caption = this.Caption; + result.Length = this.Length; + result.StartDepth = this.StartDepth; + result.DepthBPNum = this.DepthBPNum; + if ( this.DepthBPX != null ) { + result.DepthBPX = (float[])this.DepthBPX.Clone(); + } + if ( this.DepthBPY != null ) { + result.DepthBPY = (int[])this.DepthBPY.Clone(); + } + result.StartRate = this.StartRate; + result.RateBPNum = this.RateBPNum; + if ( this.RateBPX != null ) { + result.RateBPX = (float[])this.RateBPX.Clone(); + } + if ( this.RateBPY != null ) { + result.RateBPY = (int[])this.RateBPY.Clone(); + } + result.Language = this.Language; + result.Program = this.Program; + return result; + }*/ + public VsqHandle() { + } + + /// + /// インスタンスをストリームに書き込みます。 + /// encode=trueの場合、2バイト文字をエンコードして出力します。 + /// + /// 書き込み対象 + /// 2バイト文字をエンコードするか否かを指定するフラグ + public void write( TextMemoryStream sw, boolean encode ) { + sw.writeLine( this.toString( encode ) ); + } + + + /// + /// FileStreamから読み込みながらコンストラクト + /// + /// 読み込み対象 + public VsqHandle( TextMemoryStream sr, int value, TextResult last_line ) { + this.Index = value; + String[] spl; + String[] spl2; + + // default値で梅 + this.Type = VsqHandleType.Vibrato; + IconID = ""; + IDS = "normal"; + L0 = new Lyric( "" ); + Original = 0; + Caption = ""; + Length = 0; + StartDepth = 0; + DepthBPNum = 0; + DepthBPX = null; + DepthBPY = null; + StartRate = 0; + RateBPNum = 0; + RateBPX = null; + RateBPY = null; + Language = 0; + Program = 0; + + String tmpDepthBPX = ""; + String tmpDepthBPY = ""; + String tmpRateBPX = ""; + String tmpRateBPY = ""; + + // "["にぶち当たるまで読込む + last_line.set( sr.readLine() ); + while ( !last_line.get().startsWith( "[" ) ) { + spl = last_line.get().split( "=" ); + if ( spl[0].equals( "Language" ) ) { + Language = Integer.parseInt( spl[1] ); + } else if ( spl[0].endsWith( "Program" ) ) { + Program = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "IconID" ) ) { + IconID = spl[1]; + } else if ( spl[0].equals( "IDS" ) ) { + IDS = spl[1]; + } else if ( spl[0].equals( "Original" ) ) { + Original = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "Caption" ) ) { + Caption = spl[1]; + for ( int i = 2; i < spl.length; i++ ) { + Caption += "=" + spl[i]; + } + } else if ( spl[0].equals( "Length" ) ) { + Length = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "StartDepth" ) ) { + StartDepth = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "DepthBPNum" ) ) { + DepthBPNum = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "DepthBPX" ) ) { + tmpDepthBPX = spl[1]; + } else if ( spl[0].equals( "DepthBPY" ) ) { + tmpDepthBPY = spl[1]; + } else if ( spl[0].equals( "StartRate" ) ) { + StartRate = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "RateBPNum" ) ) { + RateBPNum = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "RateBPX" ) ) { + tmpRateBPX = spl[1]; + } else if ( spl[0].equals( "RateBPY" ) ) { + tmpRateBPY = spl[1]; + } else if ( spl[0].equals( "L0" ) ) { + Type = VsqHandleType.Lyric; + L0 = new Lyric( spl[1] ); + } + if ( sr.peek() < 0 ) { + break; + } + last_line.set( sr.readLine() ); + } + if ( IDS != "normal" ) { + Type = VsqHandleType.Singer; + } else if ( IconID != "" ) { + Type = VsqHandleType.Vibrato; + } else { + Type = VsqHandleType.Lyric; + } + + // RateBPX, RateBPYの設定 + if ( this.Type == VsqHandleType.Vibrato ) { + if ( RateBPNum > 0 ) { + RateBPX = new float[RateBPNum]; + spl2 = tmpRateBPX.split( "," ); + for ( int i = 0; i < RateBPNum; i++ ) { + RateBPX[i] = Float.parseFloat( spl2[i] ); + } + + RateBPY = new int[RateBPNum]; + spl2 = tmpRateBPY.split( "," ); + for ( int i = 0; i < RateBPNum; i++ ) { + RateBPY[i] = Integer.parseInt( spl2[i] ); + } + } else { + RateBPX = null; + RateBPY = null; + } + + // DepthBPX, DepthBPYの設定 + if ( DepthBPNum > 0 ) { + DepthBPX = new float[DepthBPNum]; + spl2 = tmpDepthBPX.split( "," ); + for ( int i = 0; i < DepthBPNum; i++ ) { + DepthBPX[i] = Float.parseFloat( spl2[i] ); + } + + DepthBPY = new int[DepthBPNum]; + spl2 = tmpDepthBPY.split( "," ); + for ( int i = 0; i < DepthBPNum; i++ ) { + DepthBPY[i] = Integer.parseInt( spl2[i] ); + } + } else { + DepthBPX = null; + DepthBPY = null; + } + } + + } + + /// + /// ハンドル指定子(例えば"h#0123"という文字列)からハンドル番号を取得します + /// + /// ハンドル指定子 + /// ハンドル番号 + public static int HandleIndexFromString( String _String ) { + String[] spl = _String.split( "#" ); + return Integer.parseInt( spl[1] ); + } + + + /// + /// インスタンスをテキストファイルに出力します + /// + /// 出力先 + public void Print( java.io.BufferedWriter sw ) throws IOException { + String result = this.toString(); + sw.write( result + "\n" ); + } + + + /// + /// インスタンスをコンソール画面に出力します + /// + private void Print() { + String result = this.toString(); + System.out.println( result ); + } + + + /// + /// インスタンスを文字列に変換します + /// + /// 2バイト文字をエンコードするか否かを指定するフラグ + /// インスタンスを変換した文字列 + public String toString( boolean encode ) { + String result = ""; + result += "[h#" + (new DecimalFormat( "0000" )).format( Index ) + "]"; + switch ( Type ) { + case Lyric: + result += "\nL0=" + L0.toString( encode ); + break; + case Vibrato: + DecimalFormat df = new DecimalFormat( "0.000000" ); + result += "\nIconID=" + IconID + "\n"; + result += "IDS=" + IDS + "\n"; + result += "Original=" + Original + "\n"; + result += "Caption=" + Caption + "\n"; + result += "Length=" + Length + "\n"; + result += "StartDepth=" + StartDepth + "\n"; + result += "DepthBPNum=" + DepthBPNum + "\n"; + if ( DepthBPNum > 0 ) { + result += "DepthBPX=" + df.format( DepthBPX[0] ); + for ( int i = 1; i < DepthBPNum; i++ ) { + result += "," + df.format( DepthBPX[i] ); + } + result += "\n" + "DepthBPY=" + DepthBPY[0]; + for ( int i = 1; i < DepthBPNum; i++ ) { + result += "," + DepthBPY[i]; + } + result += "\n"; + } + result += "StartRate=" + StartRate + "\n"; + result += "RateBPNum=" + RateBPNum; + if ( RateBPNum > 0 ) { + result += "\n" + "RateBPX=" + df.format( RateBPX[0] ); + for ( int i = 1; i < RateBPNum; i++ ) { + result += "," + df.format( RateBPX[i] ); + } + result += "\n" + "RateBPY=" + RateBPY[0]; + for ( int i = 1; i < RateBPNum; i++ ) { + result += "," + RateBPY[i]; + } + } + break; + case Singer: + result += "\n" + "IconID=" + IconID + "\n"; + result += "IDS=" + IDS + "\n"; + result += "Original=" + Original + "\n"; + result += "Caption=" + Caption + "\n"; + result += "Length=" + Length + "\n"; + result += "Language=" + Language + "\n"; + result += "Program=" + Program; + break; + default: + break; + } + return result; + + } + +} + diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandleType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandleType.java new file mode 100644 index 0000000..fcee3f0 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqHandleType.java @@ -0,0 +1,24 @@ +/* + * VibratoHandleType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public enum VsqHandleType { + Lyric, + Vibrato, + Singer +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqID.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqID.java new file mode 100644 index 0000000..11b5c5b --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqID.java @@ -0,0 +1,209 @@ +/* + * VsqID.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.text.*; +/// +/// メタテキストに埋め込まれるIDを表すクラス。 +/// + +public class VsqID implements Cloneable { + public int value; + public VsqIDType type; + public int IconHandle_index; + public IconHandle IconHandle; + public int Length; + public int Note; + public int Dynamics; + public int PMBendDepth; + public int PMBendLength; + public int PMbPortamentoUse; + public int DEMdecGainRate; + public int DEMaccent; + public int LyricHandle_index; + public LyricHandle LyricHandle; + public int VibratoHandle_index; + public VibratoHandle VibratoHandle; + public int VibratoDelay; + public static VsqID EOS = new VsqID( -1 ); + + /// + /// このインスタンスの簡易コピーを取得します。 + /// + /// このインスタンスの簡易コピー + public Object clone() { + VsqID result = new VsqID( this.value ); + result.type = this.type; + if ( this.IconHandle != null ) { + result.IconHandle = (IconHandle)this.IconHandle.clone(); + } + result.Length = this.Length; + result.Note = this.Note; + result.Dynamics = this.Dynamics; + result.PMBendDepth = this.PMBendDepth; + result.PMBendLength = this.PMBendLength; + result.PMbPortamentoUse = this.PMbPortamentoUse; + result.DEMdecGainRate = this.DEMdecGainRate; + result.DEMaccent = this.DEMaccent; + if ( this.LyricHandle != null ) { + result.LyricHandle = (LyricHandle)this.LyricHandle.clone(); + } + if ( this.VibratoHandle != null ) { + result.VibratoHandle = (VibratoHandle)this.VibratoHandle.clone(); + } + result.VibratoDelay = this.VibratoDelay; + return result; + } + + + /// + /// IDの番号(ID#****の****)を指定したコンストラクタ。 + /// + /// IDの番号 + public VsqID( int a_value ) { + value = a_value; + } + + + /// + /// テキストファイルからのコンストラクタ + /// + /// 読み込み対象 + /// + /// 読み込んだ最後の行が返されます + public VsqID( TextMemoryStream sr, int value, TextResult last_line ) { + String[] spl; + this.value = value; + this.type = VsqIDType.Unknown; + this.IconHandle_index = -2; + this.LyricHandle_index = -1; + this.VibratoHandle_index = -1; + this.Length = 0; + this.Note = 0; + this.Dynamics = 0; + this.PMBendDepth = 0; + this.PMBendLength = 0; + this.PMbPortamentoUse = 0; + this.DEMdecGainRate = 0; + this.DEMaccent = 0; + //this.LyricHandle_index = -2; + //this.VibratoHandle_index = -2; + this.VibratoDelay = 0; + last_line.set( sr.readLine() ); + while ( !last_line.get().startsWith( "[" ) ) { + spl = last_line.get().split( "=" ); + if ( spl[0].equals( "Type" ) ) { + if ( spl[1].equals( "Anote" ) ) { + type = VsqIDType.Anote; + } else if ( spl[1].equals( "Singer" ) ) { + type = VsqIDType.Singer; + } else { + type = VsqIDType.Unknown; + } + } else if ( spl[0].equals( "Length" ) ) { + this.Length = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "Note#" ) ) { + this.Note = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "Dynamics" ) ) { + this.Dynamics = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "PMBendDepth" ) ) { + this.PMBendDepth = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "PMBendLength" ) ) { + this.PMBendLength = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "DEMdecGainRate" ) ) { + this.DEMdecGainRate = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "DEMaccent" ) ) { + this.DEMaccent = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "LyricHandle" ) ) { + this.LyricHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + + } else if ( spl[0].equals( "IconHandle" ) ) { + this.IconHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + } else if ( spl[0].equals( "VibratoHandle" ) ) { + this.VibratoHandle_index = VsqHandle.HandleIndexFromString( spl[1] ); + } else if ( spl[0].equals( "VibratoDelay" ) ) { + this.VibratoDelay = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "PMbPortamentoUse" ) ) { + PMbPortamentoUse = Integer.parseInt( spl[1] ); + } + if ( sr.peek() < 0 ) { + break; + } + last_line.set( sr.readLine() ); + } + } + + public String toString() { + String ret = "{Type=" + type; + DecimalFormat df = new DecimalFormat( "0000" ); + switch ( type ) { + case Anote: + ret += ", Length=" + Length; + ret += ", Note#=" + Note; + ret += ", Dynamics=" + Dynamics; + ret += ", PMBendDepth=" + PMBendDepth; + ret += ", PMBendLength=" + PMBendLength; + ret += ", PMbPortamentoUse=" + PMbPortamentoUse; + ret += ", DEMdecGainRate=" + DEMdecGainRate; + ret += ", DEMaccent=" + DEMaccent; + if ( LyricHandle != null ) { + ret += ", LyricHandle=h#" + df.format( LyricHandle_index ); + } + if ( VibratoHandle != null ) { + ret += ", VibratoHandle=h#" + df.format( VibratoHandle_index ); + ret += ", VibratoDelay=" + VibratoDelay; + } + break; + case Singer: + ret += ", IconHandle=h#" + df.format( IconHandle_index ); + break; + } + ret += "}"; + return ret; + } + + + /// + /// インスタンスをテキストファイルに出力します + /// + /// 出力先 + public void write( TextMemoryStream sw ) { + DecimalFormat df = new DecimalFormat( "0000" ); + sw.writeLine( "[ID#" + df.format( value ) + "]" ); + sw.writeLine( "Type=" + type ); + switch ( type ) { + case Anote: + sw.writeLine( "Length=" + Length ); + sw.writeLine( "Note#=" + Note ); + sw.writeLine( "Dynamics=" + Dynamics ); + sw.writeLine( "PMBendDepth=" + PMBendDepth ); + sw.writeLine( "PMBendLength=" + PMBendLength ); + sw.writeLine( "PMbPortamentoUse=" + PMbPortamentoUse ); + sw.writeLine( "DEMdecGainRate=" + DEMdecGainRate ); + sw.writeLine( "DEMaccent=" + DEMaccent ); + if ( LyricHandle != null ) { + sw.writeLine( "LyricHandle=h#" + df.format( LyricHandle_index ) ); + } + if ( VibratoHandle != null ) { + sw.writeLine( "VibratoHandle=h#" + df.format( VibratoHandle_index ) ); + sw.writeLine( "VibratoDelay=" + VibratoDelay ); + } + break; + case Singer: + sw.writeLine( "IconHandle=h#" + df.format( IconHandle_index ) ); + break; + } + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqIDType.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqIDType.java new file mode 100644 index 0000000..5cfaa0d --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqIDType.java @@ -0,0 +1,24 @@ +/* + * VsqIDType.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +public enum VsqIDType { + Singer, + Anote, + Unknown +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMaster.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMaster.java new file mode 100644 index 0000000..3a0b51e --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMaster.java @@ -0,0 +1,69 @@ +/* + * VsqMaster.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.io.*; + +/** + * + * @author kbinani + */ +public class VsqMaster implements Cloneable { + public int PreMeasure; + + public Object clone() { + VsqMaster res = new VsqMaster( PreMeasure ); + return res; + } + + /** + * プリメジャー値を指定したコンストラクタ + */ + public VsqMaster( int pre_measure ) { + this.PreMeasure = pre_measure; + } + + /** + * テキストファイルからのコンストラクタ + * @param sr 読み込み元 + * @param last_line 最後に読み込んだ行が返されます + * @throws java.lang.Exception + */ + public VsqMaster( TextMemoryStream sr, TextResult last_line ) { + PreMeasure = 0; + String[] spl; + last_line.set( sr.readLine() ); + while ( !last_line.get().startsWith( "[" ) ) { + spl = last_line.get().split( "=" ); + if ( spl[0].equals( "PreMeasure" ) ) { + this.PreMeasure = Integer.valueOf( spl[1] ); + break; + } + if ( sr.peek() < 0 ) { + break; + } + last_line.set( sr.readLine() ); + } + } + + /** + * インスタンスの内容をテキストファイルに出力します + * @param sw出力先 + */ + public void write( TextMemoryStream sw ){ + sw.writeLine( "[Master]" ); + sw.writeLine( "PreMeasure=" + PreMeasure ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMetaText.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMetaText.java new file mode 100644 index 0000000..9b56917 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMetaText.java @@ -0,0 +1,911 @@ +/* + * VsqMetaText.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +import java.text.*; +import java.awt.*; + +/** + * vsqのメタテキストの中身を処理するためのクラス + * @author kbinani + */ +public class VsqMetaText implements Cloneable { + protected VsqCommon common; + protected VsqMaster master; + protected VsqMixer mixer; + //private List m_events; + private VsqEventList m_events; + //private List m_another_events; + /// + /// PIT。ピッチベンド。default=0 + /// + private VsqBPList pitchBendBPList; + /// + /// PBS。ピッチベンドセンシティビティ。dfault=2 + /// + private VsqBPList pitchBendSensBPList; + /// + /// DYN。ダイナミクス。default=64 + /// + private VsqBPList dynamicsBPList; + /// + /// BRE。ブレシネス。default=0 + /// + private VsqBPList epRResidualBPList; + /// + /// BRI。ブライトネス。default=64 + /// + private VsqBPList epRESlopeBPList; + /// + /// CLE。クリアネス。default=0 + /// + private VsqBPList epRESlopeDepthBPList; + private VsqBPList reso1FreqBPList; + private VsqBPList reso2FreqBPList; + private VsqBPList reso3FreqBPList; + private VsqBPList reso4FreqBPList; + private VsqBPList reso1BWBPList; + private VsqBPList reso2BWBPList; + private VsqBPList reso3BWBPList; + private VsqBPList reso4BWBPList; + private VsqBPList reso1AmpBPList; + private VsqBPList reso2AmpBPList; + private VsqBPList reso3AmpBPList; + private VsqBPList reso4AmpBPList; + /// + /// GEN。ジェンダーファクター。default=64 + /// + private VsqBPList genderFactorBPList; + /// + /// POR。ポルタメントタイミング。default=64 + /// + private VsqBPList portamentoTimingBPList; + /// + /// OPE。オープニング。default=127 + /// + private VsqBPList openingBPList; + + public Object clone() { + VsqMetaText res = new VsqMetaText(); + if ( common != null ) { + res.common = (VsqCommon)common.clone(); + } + if ( master != null ) { + res.master = (VsqMaster)master.clone(); + } + if ( mixer != null ) { + res.mixer = (VsqMixer)mixer.clone(); + } + if ( m_events != null ) { + res.m_events = new VsqEventList();// List(); + + for ( Iterator itr = m_events.iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + res.m_events.add( (VsqEvent)item.clone() ); + } + } + /*if ( m_another_events != null ) { + res.m_another_events = new List(); + foreach ( VsqEvent item in m_another_events ) { + res.m_another_events.Add( (VsqEvent)item.clone() ); + } + }*/ + if ( pitchBendBPList != null ) { + res.pitchBendBPList = (VsqBPList)pitchBendBPList.clone(); + } + if ( pitchBendSensBPList != null ) { + res.pitchBendSensBPList = (VsqBPList)pitchBendSensBPList.clone(); + } + if ( dynamicsBPList != null ) { + res.dynamicsBPList = (VsqBPList)dynamicsBPList.clone(); + } + if ( epRResidualBPList != null ) { + res.epRResidualBPList = (VsqBPList)epRResidualBPList.clone(); + } + if ( epRESlopeBPList != null ) { + res.epRESlopeBPList = (VsqBPList)epRESlopeBPList.clone(); + } + if ( epRESlopeDepthBPList != null ) { + res.epRESlopeDepthBPList = (VsqBPList)epRESlopeDepthBPList.clone(); + } + if ( reso1FreqBPList != null ) { + res.reso1FreqBPList = (VsqBPList)reso1FreqBPList.clone(); + } + if ( reso2FreqBPList != null ) { + res.reso2FreqBPList = (VsqBPList)reso2FreqBPList.clone(); + } + if ( reso3FreqBPList != null ) { + res.reso3FreqBPList = (VsqBPList)reso3FreqBPList.clone(); + } + if ( reso4FreqBPList != null ) { + res.reso4FreqBPList = (VsqBPList)reso4FreqBPList.clone(); + } + if ( reso1BWBPList != null ) { + res.reso1BWBPList = (VsqBPList)reso1BWBPList.clone(); + } + if ( reso2BWBPList != null ) { + res.reso2BWBPList = (VsqBPList)reso2BWBPList.clone(); + } + if ( reso3BWBPList != null ) { + res.reso3BWBPList = (VsqBPList)reso3BWBPList.clone(); + } + if ( reso4BWBPList != null ) { + res.reso4BWBPList = (VsqBPList)reso4BWBPList.clone(); + } + if ( reso1AmpBPList != null ) { + res.reso1AmpBPList = (VsqBPList)reso1AmpBPList.clone(); + } + if ( reso2AmpBPList != null ) { + res.reso2AmpBPList = (VsqBPList)reso2AmpBPList.clone(); + } + if ( reso3AmpBPList != null ) { + res.reso3AmpBPList = (VsqBPList)reso3AmpBPList.clone(); + } + if ( reso4AmpBPList != null ) { + res.reso4AmpBPList = (VsqBPList)reso4AmpBPList.clone(); + } + if ( genderFactorBPList != null ) { + res.genderFactorBPList = (VsqBPList)genderFactorBPList.clone(); + } + if ( portamentoTimingBPList != null ) { + res.portamentoTimingBPList = (VsqBPList)portamentoTimingBPList.clone(); + } + if ( openingBPList != null ) { + res.openingBPList = (VsqBPList)openingBPList.clone(); + } + return res; + } + + +// public List Events { + public VsqEventList getEventList() { + return m_events; + } + + + /*public List AnotherEvents { + get { + return m_another_events; + } + }*/ + public VsqBPList getVsqBPList( VsqCurveType type ) { + switch ( type ) { + case BRE: + return this.epRResidualBPList; + case BRI: + return this.epRESlopeBPList; + case CLE: + return this.epRESlopeDepthBPList; + case DYN: + return this.dynamicsBPList; + case GEN: + return this.genderFactorBPList; + case OPE: + return this.openingBPList; + case PBS: + return this.pitchBendSensBPList; + case PIT: + return this.pitchBendBPList; + case POR: + return this.portamentoTimingBPList; + default: + return null; + } + } + + public void setVsqBPList( VsqCurveType type, VsqBPList value ) { + switch ( type ) { + case BRE: + this.epRResidualBPList = value; + break; + case BRI: + this.epRESlopeBPList = value; + break; + case CLE: + this.epRESlopeDepthBPList = value; + break; + case DYN: + this.dynamicsBPList = value; + break; + case GEN: + this.genderFactorBPList = value; + break; + case OPE: + this.openingBPList = value; + break; + case PBS: + this.pitchBendSensBPList = value; + break; + case PIT: + this.pitchBendBPList = value; + break; + case POR: + this.portamentoTimingBPList = value; + break; + } + } + + /*// + /// LyricEvents用に使用できる空きID番号を取得します.next=0の時は次に利用可能なID,next=1は,next=0として得られるIDを使用した後利用可能なID,etc.. + /// + /// + private int GetNextId_( int next ) { + int index = -1; + int count = m_events.Count; + boolean[] list = new boolean[count]; + for ( int i = 0; i < count; i++ ) { + list[i] = false; + } + for ( int i = 0; i < count; i++ ) { + if ( 0 <= m_events[i].InternalID && m_events[i].InternalID < count ) { + list[i] = true; + } + } + int j = -1; + for ( int i = 0; i < count; i++ ) { + if ( !list[i] ) { + j++; + if ( j == next ) { + return i; + } + } + } + return count + next + 1; + } + private int GetNextId( int next ) { + int index = -1; + List current = new List(); + for ( int i = 0; i < m_events.Count; i++ ) { + current.Add( m_events[i].InternalID ); + } + int nfound = 0; + while ( true ) { + index++; + boolean found = false; + for ( int i = 0; i < current.Count; i++ ) { + if ( index == current[i] ) { + found = true; + break; + } + } + if ( !found ) { + nfound++; + if ( nfound == next + 1 ) { + return index; + } else { + current.Add( index ); + } + } + } + }*/ + /*// + /// AnotherEvents用に使用できる次の空きID番号を取得します + /// + /// + public int GetNextIdForAnotherEvent( int next ) { + int index = -1; + List current = new List(); + for ( int i = 0; i < m_another_events.Count; i++ ) { + current.Add( m_another_events[i].InternalID ); + } + int nfound = 0; + while ( true ) { + index++; + boolean found = false; + for ( int i = 0; i < current.Count; i++ ) { + if ( index == current[i] ) { + found = true; + break; + } + } + if ( !found ) { + nfound++; + if ( nfound == next + 1 ) { + return index; + } else { + current.Add( index ); + } + } + } + }*/ +/// +/// Editor画面上で上からindex番目のカーブを表すBPListを求めます +/// +/// +/// + /*public VsqBPList GetCurve( + int index ) { + switch ( index ) { + case 1: + return DYN; + case 2: + return BRE; + case 3: + return BRI; + case 4: + return CLE; + case 5: + return OPE; + case 6: + return GEN; + case 7: + return POR; + case 8: + return PIT; + case 9: + return PBS; + default: + return null; + } + + }*/ + /// + /// Editor画面上で上からindex番目のカーブの名前を調べます + /// + /// + /// + public static String getCurveName( int index ) { + switch ( index ) { + case 0: + return "VEL"; + case 1: + return "DYN"; + case 2: + return "BRE"; + case 3: + return "BRI"; + case 4: + return "CLE"; + case 5: + return "OPE"; + case 6: + return "GEN"; + case 7: + return "POR"; + case 8: + return "PIT"; + case 9: + return "PBS"; + default: + return ""; + } + + } + + /// + /// Singerプロパティに指定されている + /// + public String getSinger() { + for ( Iterator itr = m_events.iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.ID.type == VsqIDType.Singer ) { + return item.ID.IconHandle.IDS; + } + } + return ""; + } + + public void setSinger( String value ) { + for ( Iterator itr = m_events.iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + if ( item.ID.type == VsqIDType.Singer ) { + item.ID.IconHandle.IDS = value; + break; + } + } + } + + /// + /// EOSイベントが記録されているクロックを取得します。 + /// + /// + public int getIndexOfEos() { + int result; + if ( m_events.size() > 0 ) { + int ilast = m_events.size() - 1; + result = m_events.get( ilast ).Clock; + } else { + result = -1; + } + + return result; + } + + /** + * このインスタンスから、IDとHandleのリストを構築します + * + *@param id + *@param handle + **/ + private void buildIdHandleList( Vector id, Vector handle ) { + id = new Vector(); + handle = new Vector(); + int current_id = -1; + int current_handle = -1; + Vector events = new Vector(); + for ( Iterator itr = m_events.iterator(); itr.hasNext();) { + VsqEvent item = (VsqEvent)itr.next(); + events.add( item ); + } + Collections.sort( events ); + for ( int i = 0; i < events.size(); i++ ) { + VsqEvent item = events.get( i ); + VsqID id_item = (VsqID)item.ID.clone(); + current_id++; + item.ID.value = current_id; + id_item.value = current_id; + // IconHandle + if ( item.ID.IconHandle != null ) { + current_handle++; + VsqHandle handle_item = (VsqHandle)item.ID.IconHandle.clone(); + handle_item.Index = current_handle; + handle.add( handle_item ); + id_item.IconHandle_index = current_handle; + } + + // LyricHandle + if ( item.ID.LyricHandle != null ) { + current_handle++; + VsqHandle handle_item = (VsqHandle)item.ID.LyricHandle.clone(); + handle_item.Index = current_handle; + handle.add( handle_item ); + id_item.LyricHandle_index = current_handle; + } + + // VibratoHandle + if ( item.ID.VibratoHandle != null ) { + current_handle++; + VsqHandle handle_item = (VsqHandle)item.ID.VibratoHandle.clone(); + handle_item.Index = current_handle; + handle.add( handle_item ); + id_item.VibratoHandle_index = current_handle; + } + + id.add( id_item ); + } + + } + + + /// + /// このインスタンスの内容を指定されたファイルに出力します。 + /// + /// + /// + public void print( TextMemoryStream sw, boolean encode, long eos, int start ) { + //using ( StreamWriter sw = new StreamWriter( fpath ) ) { + if ( common != null ) { + common.write( sw ); + } + + if ( master != null ) { + master.write( sw ); + } + + if ( mixer != null ) { + mixer.write( sw ); + } + + Vector id = null; + Vector handle = null; + buildIdHandleList( id, handle ); + writeEventList( sw, eos ); + int i; + for ( i = 0; i < id.size(); i++ ) { + id.get( i ).write( sw ); + } + + for ( i = 0; i < handle.size(); i++ ) { + handle.get( i ).write( sw, encode ); + } + + if ( pitchBendBPList.size() > 0 ) { + pitchBendBPList.print( sw, start, "[PitchBendBPList]" ); + } + + if ( pitchBendSensBPList.size() > 0 ) { + pitchBendSensBPList.print( sw, start, "[PitchBendSensBPList]" ); + } + + if ( dynamicsBPList.size() > 0 ) { + dynamicsBPList.print( sw, start, "[DynamicsBPList]" ); + } + + if ( epRResidualBPList.size() > 0 ) { + epRResidualBPList.print( sw, start, "[EpRResidualBPList]" ); + } + + if ( epRESlopeBPList.size() > 0 ) { + epRESlopeBPList.print( sw, start, "[EpRESlopeBPList]" ); + } + + if ( epRESlopeDepthBPList.size() > 0 ) { + epRESlopeDepthBPList.print( sw, start, "[EpRESlopeDepthBPList]" ); + } + + if ( reso1FreqBPList.size() > 0 ) { + reso1FreqBPList.print( sw, start, "[Reso1FreqBPList]" ); + } + + if ( reso2FreqBPList.size() > 0 ) { + reso2FreqBPList.print( sw, start, "[Reso2FreqBPList]" ); + } + + if ( reso3FreqBPList.size() > 0 ) { + reso3FreqBPList.print( sw, start, "[Reso3FreqBPList]" ); + } + + if ( reso4FreqBPList.size() > 0 ) { + reso4FreqBPList.print( sw, start, "[Reso4FreqBPList]" ); + } + + if ( reso1BWBPList.size() > 0 ) { + reso1BWBPList.print( sw, start, "[Reso1BWBPList]" ); + } + + if ( reso2BWBPList.size() > 0 ) { + reso2BWBPList.print( sw, start, "[Reso2BWBPList]" ); + } + + if ( reso3BWBPList.size() > 0 ) { + reso3BWBPList.print( sw, start, "[Reso3BWBPList]" ); + } + + if ( reso4BWBPList.size() > 0 ) { + reso4BWBPList.print( sw, start, "[Reso4BWBPList]" ); + } + + if ( reso1AmpBPList.size() > 0 ) { + reso1AmpBPList.print( sw, start, "[Reso1AmpBPList]" ); + } + + if ( reso2AmpBPList.size() > 0 ) { + reso2AmpBPList.print( sw, start, "[Reso2AmpBPList]" ); + } + + if ( reso3AmpBPList.size() > 0 ) { + reso3AmpBPList.print( sw, start, "[Reso3AmpBPList]" ); + } + + if ( reso4AmpBPList.size() > 0 ) { + reso4AmpBPList.print( sw, start, "[Reso4AmpBPList]" ); + } + + if ( genderFactorBPList.size() > 0 ) { + genderFactorBPList.print( sw, start, "[GenderFactorBPList]" ); + } + + if ( portamentoTimingBPList.size() > 0 ) { + portamentoTimingBPList.print( sw, start, "[PortamentoTimingBPList]" ); + } + + if ( openingBPList.size() > 0 ) { + openingBPList.print( sw, start, "[OpeningBPList]" ); + } +//} + + } + + private void writeEventList( TextMemoryStream sw, long eos ) { + sw.writeLine( "[EventList]" ); + Vector temp = new Vector(); + /*foreach ( VsqEvent item in m_another_events ) { + temp.Add( item ); + }*/ + for ( Iterator itr = m_events.iterator(); itr.hasNext();) { + temp.add( (VsqEvent)itr.next() ); + } + + Collections.sort( temp ); + int i = 0; + DecimalFormat df = new DecimalFormat( "0000" ); + while ( i < temp.size() ) { + VsqEvent item = temp.get( i ); + if ( !item.ID.equals( VsqID.EOS ) ) { + String ids = "ID#" + df.format( i ); + int clock = temp.get( i ).Clock; + while ( i + 1 < temp.size() && clock == temp.get( i + 1 ).Clock ) { + i++; + ids += ",ID#" + df.format( i ); + } + + sw.writeLine( clock + "=" + ids ); + } + + i++; + } + + sw.writeLine( eos + "=EOS" ); + } + + +/// +/// 何も無いVsqMetaTextを構築する。これは、Master Track用のMetaTextとしてのみ使用されるべき +/// + public VsqMetaText() { + } + + + /// + /// 最初のトラック以外の一般のメタテキストを構築。(Masterが作られない) + /// + public VsqMetaText( String name, String singer ) { + this( name, 0, singer, false ); + } + + + /// + /// 最初のトラックのメタテキストを構築。(Masterが作られる) + /// + /// + public VsqMetaText( String name, String singer, int pre_measure ) { + this( name, pre_measure, singer, true ); + } + + private VsqMetaText( String name, int pre_measure, String singer, boolean is_first_track ) { + common = new VsqCommon( name, new Color( 179, 181, 123 ), 1, 1 ); + pitchBendBPList = new VsqBPList( 0, -8192, 8192 ); + pitchBendBPList.add( 0, pitchBendBPList.getDefault() ); + + pitchBendSensBPList = new VsqBPList( 2, 0, 24 ); + pitchBendSensBPList.add( 0, pitchBendSensBPList.getDefault() ); + + dynamicsBPList = new VsqBPList( 64, 0, 127 ); + dynamicsBPList.add( 0, dynamicsBPList.getDefault() ); + + epRResidualBPList = new VsqBPList( 0, 0, 127 ); + epRResidualBPList.add( 0, epRResidualBPList.getDefault() ); + + epRESlopeBPList = new VsqBPList( 64, 0, 127 ); + epRESlopeBPList.add( 0, epRESlopeBPList.getDefault() ); + + epRESlopeDepthBPList = new VsqBPList( 0, 0, 127 ); + epRESlopeDepthBPList.add( 0, epRESlopeDepthBPList.getDefault() ); + + reso1FreqBPList = new VsqBPList( 255, 0, 255 ); + reso1FreqBPList.add( 0, reso1FreqBPList.getDefault() ); + + reso2FreqBPList = new VsqBPList( 255, 0, 255 ); + reso2FreqBPList.add( 0, reso2FreqBPList.getDefault() ); + + reso3FreqBPList = new VsqBPList( 255, 0, 255 ); + reso3FreqBPList.add( 0, reso3FreqBPList.getDefault() ); + + reso4FreqBPList = new VsqBPList( 255, 0, 255 ); + reso4FreqBPList.add( 0, reso4FreqBPList.getDefault() ); + + reso1BWBPList = new VsqBPList( 255, 0, 255 ); + reso1BWBPList.add( 0, reso1BWBPList.getDefault() ); + + reso2BWBPList = new VsqBPList( 255, 0, 255 ); + reso2BWBPList.add( 0, reso2BWBPList.getDefault() ); + + reso3BWBPList = new VsqBPList( 255, 0, 255 ); + reso3BWBPList.add( 0, reso3BWBPList.getDefault() ); + + reso4BWBPList = new VsqBPList( 255, 0, 255 ); + reso4BWBPList.add( 0, reso4BWBPList.getDefault() ); + + reso1AmpBPList = new VsqBPList( 255, 0, 255 ); + reso1AmpBPList.add( 0, reso1AmpBPList.getDefault() ); + + reso2AmpBPList = new VsqBPList( 255, 0, 255 ); + reso2AmpBPList.add( 0, reso2AmpBPList.getDefault() ); + + reso3AmpBPList = new VsqBPList( 255, 0, 255 ); + reso3AmpBPList.add( 0, reso3AmpBPList.getDefault() ); + + reso4AmpBPList = new VsqBPList( 255, 0, 255 ); + reso4AmpBPList.add( 0, reso4AmpBPList.getDefault() ); + + genderFactorBPList = new VsqBPList( 64, 0, 127 ); + genderFactorBPList.add( 0, genderFactorBPList.getDefault() ); + + portamentoTimingBPList = new VsqBPList( 64, 0, 127 ); + portamentoTimingBPList.add( 0, portamentoTimingBPList.getDefault() ); + + openingBPList = new VsqBPList( 127, 0, 127 ); + openingBPList.add( 0, openingBPList.getDefault() ); + + if ( is_first_track ) { + master = new VsqMaster( pre_measure ); + } else { + master = null; + } + + m_events = new VsqEventList(); + //m_another_events = new List(); + VsqID id = new VsqID( 0 ); + id.type = VsqIDType.Singer; + id.IconHandle = new IconHandle(); + id.IconHandle.Type = VsqHandleType.Singer; + id.IconHandle.IconID = "$07010000"; + id.IconHandle.IDS = singer; + id.IconHandle.Original = 0; + id.IconHandle.Caption = ""; + id.IconHandle.Length = 1; + id.IconHandle.Language = 0; + id.IconHandle.Program = 0; + m_events.add( new VsqEvent( 0, id ) ); + } + + public VsqMetaText( TextMemoryStream sr ) { + Vector> t_event_list = new Vector>(); + //SortedDictionary t_event_list = new SortedDictionary(); + TreeMap __id = new TreeMap(); + TreeMap __handle = new TreeMap(); + pitchBendBPList = new VsqBPList( 0, -8192, 8192 ); + pitchBendSensBPList = new VsqBPList( 2, 0, 24 ); + dynamicsBPList = new VsqBPList( 64, 0, 127 ); + epRResidualBPList = new VsqBPList( 0, 0, 127 ); + epRESlopeBPList = new VsqBPList( 64, 0, 127 ); + epRESlopeDepthBPList = new VsqBPList( 0, 0, 127 ); + reso1FreqBPList = new VsqBPList( 255, 0, 255 ); + reso2FreqBPList = new VsqBPList( 255, 0, 255 ); + reso3FreqBPList = new VsqBPList( 255, 0, 255 ); + reso4FreqBPList = new VsqBPList( 255, 0, 255 ); + reso1BWBPList = new VsqBPList( 255, 0, 255 ); + reso2BWBPList = new VsqBPList( 255, 0, 255 ); + reso3BWBPList = new VsqBPList( 255, 0, 255 ); + reso4BWBPList = new VsqBPList( 255, 0, 255 ); + reso1AmpBPList = new VsqBPList( 255, 0, 255 ); + reso2AmpBPList = new VsqBPList( 255, 0, 255 ); + reso3AmpBPList = new VsqBPList( 255, 0, 255 ); + reso4AmpBPList = new VsqBPList( 255, 0, 255 ); + genderFactorBPList = new VsqBPList( 64, 0, 127 ); + portamentoTimingBPList = new VsqBPList( 64, 0, 127 ); + openingBPList = new VsqBPList( 127, 0, 127 ); + + TextResult last_line = new TextResult( "" ); + last_line.set( sr.readLine() ); + while ( true ) { + if ( last_line.get().length() == 0 ) { + break; + } + + if ( last_line.get().equals( "[Common]" ) ) { + common = new VsqCommon( sr, last_line ); + } else if ( last_line.get().equals( "[Master]" ) ) { + master = new VsqMaster( sr, last_line ); + } else if ( last_line.get().equals( "[Mixer]" ) ) { + mixer = new VsqMixer( sr, last_line ); + } else if ( last_line.get().equals( "[EventList]" ) ) { + last_line.set( sr.readLine() ); + while ( !last_line.get().startsWith( "[" ) ) { + String[] spl2 = last_line.get().split( "=" ); + int clock = Integer.parseInt( spl2[0] ); + int id_number = -1; + if ( spl2[1] != "EOS" ) { + String[] ids = spl2[1].split( "," ); + for ( int i = 0; i < ids.length; i++ ) { + String[] spl3 = ids[i].split( "#" ); + id_number = Integer.parseInt( spl3[1] ); + t_event_list.add( new KeyValuePair( clock, id_number ) ); + } + } else { + t_event_list.add( new KeyValuePair( clock, -1 ) ); + } + + if ( sr.peek() < 0 ) { + break; + } else { + last_line.set( sr.readLine() ); + } + + } + } else if ( last_line.get().equals( "[PitchBendBPList]" ) ) { + last_line.set( pitchBendBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[PitchBendSensBPList]" ) ) { + last_line.set( pitchBendSensBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[DynamicsBPList]" ) ) { + last_line.set( dynamicsBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[EpRResidualBPList]" ) ) { + last_line.set( epRResidualBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[EpRESlopeBPList]" ) ) { + last_line.set( epRESlopeBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[EpRESlopeDepthBPList]" ) ) { + last_line.set( epRESlopeDepthBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso1FreqBPList]" ) ) { + last_line.set( reso1FreqBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso2FreqBPList]" ) ) { + last_line.set( reso2FreqBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso3FreqBPList]" ) ) { + last_line.set( reso3FreqBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso4FreqBPList]" ) ) { + last_line.set( reso4FreqBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso1BWBPList]" ) ) { + last_line.set( reso1BWBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso2BWBPList]" ) ) { + last_line.set( reso2BWBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso3BWBPList]" ) ) { + last_line.set( reso3BWBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso4BWBPList]" ) ) { + last_line.set( reso4BWBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso1AmpBPList]" ) ) { + last_line.set( reso1AmpBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso2AmpBPList]" ) ) { + last_line.set( reso2AmpBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso3AmpBPList]" ) ) { + last_line.set( reso3AmpBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[Reso4AmpBPList]" ) ) { + last_line.set( reso4AmpBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[GenderFactorBPList]" ) ) { + last_line.set( genderFactorBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[PortamentoTimingBPList]" ) ) { + last_line.set( portamentoTimingBPList.readFrom( sr ) ); + } else if ( last_line.get().equals( "[OpeningBPList]" ) ) { + last_line.set( openingBPList.readFrom( sr ) ); + } else { + String buffer = last_line.get(); + buffer = + buffer.replace( "[", "" ); + buffer = + buffer.replace( "]", "" ); + String[] spl = buffer.split( "#" ); + int index = Integer.parseInt( spl[1] ); + if ( last_line.get().startsWith( "[ID#" ) ) { + __id.put( index, new VsqID( sr, index, last_line ) ); + } else if ( last_line.get().startsWith( "[h#" ) ) { + __handle.put( index, new VsqHandle( sr, index, last_line ) ); + } + + + + } + + if ( sr.peek() < 0 ) { + break; + } + + } + + // まずhandleをidに埋め込み + for ( int i = 0; i < + __id.size(); i++ ) { + if ( __handle.containsKey( __id.get( i ).IconHandle_index ) ) { + __id.get( i ).IconHandle = __handle.get( __id.get( i ).IconHandle_index ).ConvertToIconHandle(); + } + + if ( __handle.containsKey( __id.get( i ).LyricHandle_index ) ) { + __id.get( i ).LyricHandle = __handle.get( __id.get( i ).LyricHandle_index ).ConvertToLyricHandle(); + } + + if ( __handle.containsKey( __id.get( i ).VibratoHandle_index ) ) { + __id.get( i ).VibratoHandle = __handle.get( __id.get( i ).VibratoHandle_index ).ConvertToVibratoHandle(); + } + + } + + // idをeventListに埋め込み + m_events = new VsqEventList();// List(); + //m_another_events = new List(); + + for ( int i = 0; i < t_event_list.size(); i++ ) { + KeyValuePair item = t_event_list.get( i ); + int clock = item.Key; + int id_number = item.Value; + if ( __id.containsKey( id_number ) ) { + //if ( __id[id_number].type == VsqIDType.Anote ) { + m_events.add( new VsqEvent( clock, (VsqID)__id.get( id_number ).clone() ) ); + //} else { + // m_another_events.Add( new VsqEvent( clock, (VsqID)__id[id_number].clone(), GetNextIdForAnotherEvent( 0 ) ) ); + //} + } + + } + } + +} + diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixer.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixer.java new file mode 100644 index 0000000..105b943 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixer.java @@ -0,0 +1,219 @@ +/* + * VsqMixer.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + +/// +/// vsqファイルのメタテキストの[Mixer]セクションに記録される内容を取り扱う +/// +public class VsqMixer implements Cloneable { + //private int MasterFeder; + public int MasterFeder; + //private int MasterPanpot; + public int MasterPanpot; + //private int MasterMute; + public int MasterMute; +//private int OutputMode; + public int OutputMode; +//public int Tracks; + /// + /// vsqファイルの各トラックのfader, panpot, muteおよびoutputmode値を保持します + /// + public Vector Slave = new Vector(); + + /// + /// このインスタンスのSlave要素に保持されるアイテムの個数。vsqファイルの"トラック数 - 1"に等しい + /// + public int getTracks() { + return Slave.size(); + } + + + /*public property Vector Slave { + get { + return m_slave; + } + set { + m_slave = value; + } + };*/ + /*public property int MasterFeder { + get { + return MasterFeder; + } + set { + MasterFeder = value; + } + };*/ + /*public property int MasterPanpot { + get { + return MasterPanpot; + } + set { + MasterPanpot = value; + } + };*/ + /*public property int MasterMute { + get { + return MasterMute; + } + set { + MasterMute = value; + } + };*/ + /*public property int OutputMode { + get { + return MasterMute; + } + set { + MasterMute = value; + } + };*/ + public Object clone() { + VsqMixer res = new VsqMixer( MasterFeder, MasterPanpot, MasterMute, OutputMode ); + res.Slave = new Vector(); + //res.Tracks = Tracks; + for ( int i = 0; i < Slave.size(); i++ ) { + VsqMixerEntry item = Slave.get( i ); + res.Slave.add( (VsqMixerEntry) item.clone() ); + } + return res; + } + + + /// + /// 各パラメータを指定したコンストラクタ + /// + /// MasterFader値 + /// MasterPanpot値 + /// MasterMute値 + /// OutputMode値 + public VsqMixer( int master_fader, int master_panpot, int master_mute, int output_mode ) { + this.MasterFeder = master_fader; + this.MasterMute = master_mute; + this.MasterPanpot = master_panpot; + this.OutputMode = output_mode; + Slave = new Vector(); + } + + + /// + /// テキストファイルからのコンストラクタ + /// + /// 読み込み対象 + /// 最後に読み込んだ行が返されます + public VsqMixer( TextMemoryStream sr, TextResult last_line ) { + MasterFeder = 0; + MasterPanpot = 0; + MasterMute = 0; + OutputMode = 0; + //Tracks = 1; + int tracks = 0; + String[] spl; + String buffer = ""; + last_line.set( sr.readLine() ); + while ( !last_line.get().startsWith( "[" ) ) { + spl = last_line.get().split( "=" ); + if ( spl[0].equals( "MasterFeder" ) ) { + MasterFeder = Integer.parseInt( spl[1] ); + } else if ( spl[0].equals( "MasterPanpot" ) ) { + MasterPanpot = Integer.parseInt( + spl[1] ); + } else if ( spl[0].equals( "MasterMute" ) ) { + MasterMute = Integer.parseInt( + spl[1] ); + } else if ( spl[0].equals( "OutputMode" ) ) { + OutputMode = Integer.parseInt( + spl[1] ); + } else if ( spl[0].equals( "Tracks" ) ) { + tracks = Integer.parseInt( + spl[1] ); + } else { + if ( spl[0].startsWith( "Feder" ) || + spl[0].startsWith( "Panpot" ) || + spl[0].startsWith( "Mute" ) || + spl[0].startsWith( "Solo" ) ) { + buffer += spl[0] + "=" + spl[1] + "\n"; + } + } + if ( sr.peek() < 0 ) { + break; + } + last_line.set( sr.readLine() ); + } + + Slave = new Vector(); + for ( int i = 0; i < tracks; i++ ) { + Slave.add( new VsqMixerEntry( 0, 0, 0, 0 ) ); + } + spl = buffer.split( "\n" ); + String[] spl2; + for ( int i = 0; i < spl.length; i++ ) { + String ind = ""; + int index; + spl2 = spl[i].split( "=" ); + if ( spl2[0].startsWith( "Feder" ) ) { + ind = spl2[0].replace( "Feder", "" ); + index = Integer.parseInt( + ind ); + Slave.get( index ).Feder = Integer.parseInt( + spl2[1] ); + } else if ( spl2[0].startsWith( "Panpot" ) ) { + ind = spl2[0].replace( "Panpot", "" ); + index = Integer.parseInt( + ind ); + Slave.get( index ).Panpot = Integer.parseInt( + spl2[1] ); + } else if ( spl2[0].startsWith( "Mute" ) ) { + ind = spl2[0].replace( "Mute", "" ); + index = Integer.parseInt( + ind ); + Slave.get( index ).Mute = Integer.parseInt( + spl2[1] ); + } else if ( spl2[0].startsWith( "Solo" ) ) { + ind = spl2[0].replace( "Solo", "" ); + index = Integer.parseInt( + ind ); + Slave.get( index ).Solo = Integer.parseInt( + spl2[1] ); + } + + } + } + + + /// + /// このインスタンスをテキストファイルに出力します + /// + /// 出力対象 + public void write( TextMemoryStream sw ) { + sw.writeLine( "[Mixer]" ); + sw.writeLine( "MasterFeder=" + MasterFeder ); + sw.writeLine( "MasterPanpot=" + MasterPanpot ); + sw.writeLine( "MasterMute=" + MasterMute ); + sw.writeLine( "OutputMode=" + OutputMode ); + sw.writeLine( "Tracks=" + getTracks() ); + for ( int i = 0; i < Slave.size(); i++ ) { + sw.writeLine( "Feder" + i + "=" + Slave.get( i ).Feder ); + sw.writeLine( "Panpot" + i + "=" + Slave.get( i ).Panpot ); + sw.writeLine( "Mute" + i + "=" + Slave.get( i ).Mute ); + sw.writeLine( "Solo" + i + "=" + Slave.get( i ).Solo ); + } + } + +} + + + diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixerEntry.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixerEntry.java new file mode 100644 index 0000000..f908f62 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqMixerEntry.java @@ -0,0 +1,40 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package jp.sourceforge.lipsync.vsq; + +/** + * + * @author kbinani + */ +/// +/// VsqMixerのSlave要素に格納される各エントリ +/// +public class VsqMixerEntry implements Cloneable { + public int Feder; + public int Panpot; + public int Mute; + public int Solo; + + public Object clone() { + VsqMixerEntry res = new VsqMixerEntry( Feder, Panpot, Mute, Solo ); + return res; + } + + + /// + /// 各パラメータを指定したコンストラクタ + /// + /// Feder値 + /// Panpot値 + /// Mute値 + /// Solo値 + public VsqMixerEntry( int feder, int panpot, int mute, int solo ) { + this.Feder = feder; + this.Panpot = panpot; + this.Mute = mute; + this.Solo = solo; + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNote.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNote.java new file mode 100644 index 0000000..7cc8d55 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNote.java @@ -0,0 +1,239 @@ +/* + * VsqMixer.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/// +/// 音階を表現するためのクラス +/// +public class VsqNote { + int _note; + private static final boolean[] _KEY_TYPE = new boolean[]{ + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + false, + true, + true, + false, + true, + false, + true, + true, + false, + true, + }; + + /// + /// 音階のノート値からのコンストラクタ。 + /// + /// この音階を初期化するためのノート値 + public VsqNote( int note ) { + _note = note; + } + + /*// + /// このインスタンスが表す音階のノート値 + /// + public property int Value { + get { + return _note; + } + set { + _note = value; + } + }*/ + /// + /// このインスタンスが表す音階が、ピアノの白鍵かどうかを返します + /// + public boolean getIsWhiteKey() { + return NoteIsWhiteKey( _note ); + } + + + /// + /// 指定した音階が、ピアノの白鍵かどうかを返します + /// + /// + /// + public static boolean NoteIsWhiteKey( int note ) { + if ( 0 <= note && note <= 127 ) { + return _KEY_TYPE[note]; + } else { + int odd = note % 12; + switch ( odd ) { + case 1: + case 3: + case 6: + case 8: + case 10: + return false; + default: + return true; + } + } + } + + public static String NoteToString( int note ) { + int odd = note % 12; + int order = (note - odd) / 12 - 2; + switch ( odd ) { + case 0: + return "C" + order; + case 1: + return "C#" + order; + case 2: + return "D" + order; + case 3: + return "Eb" + order; + case 4: + return "E" + order; + case 5: + return "F" + order; + case 6: + return "F#" + order; + case 7: + return "G" + order; + case 8: + return "G#" + order; + case 9: + return "A" + order; + case 10: + return "Bb" + order; + case 11: + return "B" + order; + default: + return ""; + } + } + + public String toString() { + return NoteToString( _note ); + } + +} diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNrpn.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNrpn.java new file mode 100644 index 0000000..3c4f998 --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqNrpn.java @@ -0,0 +1,143 @@ +/* + * VsqMixer.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + +public class VsqNrpn implements Comparable { + /** + *
+     * public property int Clock {
+     *   get {
+     *        return m_clock;
+     *    }
+     *    set {
+     *        m_clock = value;
+     *    }
+     *};
+ */ + public int Clock; + private int m_nrpn; + private byte m_datamsb; + private byte m_datalsb; + private boolean m_datalsb_specified = false; + private Vector m_list; + + public VsqNrpn( int clock, int nrpn, byte data_msb ) { + Clock = clock; + m_nrpn = nrpn; + m_datamsb = data_msb; + m_datalsb_specified = false; + m_list = new Vector(); + } + + public VsqNrpn( int clock, int nrpn, byte data_msb, byte data_lsb ) { + Clock = clock; + m_nrpn = nrpn; + m_datamsb = data_msb; + m_datalsb = data_lsb; + m_datalsb_specified = true; + m_list = new Vector(); + } + + private VsqNrpn() { + } + + public VsqNrpn[] expand() { + Vector ret = new Vector(); + if ( m_datalsb_specified ) { + ret.add( new VsqNrpn( Clock, m_nrpn, m_datamsb, m_datalsb ) ); + } else { + ret.add( new VsqNrpn( Clock, m_nrpn, m_datamsb ) ); + } + for ( int i = 0; i < m_list.size(); i++ ) { + VsqNrpn item = m_list.get( i ); + if ( item.m_datalsb_specified ) { + ret.add( new VsqNrpn( item.Clock, item.m_nrpn, item.m_datamsb, item.m_datalsb ) ); + } else { + ret.add( new VsqNrpn( item.Clock, item.m_nrpn, item.m_datamsb ) ); + } + } + return ret.toArray( new VsqNrpn[0] ); + } + + public static VsqNrpn[] merge( VsqNrpn[] src1, VsqNrpn[] src2 ) { + Vector ret = new Vector(); + for ( int i = 0; i < src1.length; i++ ) { + ret.add( src1[i] ); + } + for ( int i = 0; i < src2.length; i++ ) { + ret.add( src2[i] ); + } + Collections.sort( ret ); + return ret.toArray( new VsqNrpn[0] ); + } + + public static NrpnData[] convert( VsqNrpn[] source ) { + int nrpn = source[0].getNrpn(); + byte msb = (byte)(nrpn >> 8); + byte lsb = (byte)(nrpn - (nrpn << 8)); + Vector ret = new Vector(); + ret.add( new NrpnData( source[0].Clock, (byte)0x63, msb ) ); + ret.add( new NrpnData( source[0].Clock, (byte)0x62, lsb ) ); + ret.add( new NrpnData( source[0].Clock, (byte)0x06, source[0].getDataMsb() ) ); + if ( source[0].getDataLsbSpecified() ) { + ret.add( new NrpnData( source[0].Clock, (byte)0x26, source[0].getDataLsb() ) ); + } + for ( int i = 1; i < source.length; i++ ) { + int tnrpn = source[i].getNrpn(); + byte tmsb = (byte)(tnrpn >> 8); + byte tlsb = (byte)(tnrpn - (tnrpn << 8)); + if ( tmsb != msb ) { + ret.add( new NrpnData( source[i].Clock, (byte)0x63, tmsb ) ); + msb = tmsb; + } + ret.add( new NrpnData( source[i].Clock, (byte)0x62, tlsb ) ); + ret.add( new NrpnData( source[i].Clock, (byte)0x06, source[i].getDataMsb() ) ); + if ( source[i].getDataLsbSpecified() ) { + ret.add( new NrpnData( source[i].Clock, (byte)0x26, source[i].getDataLsb() ) ); + } + } + return ret.toArray( new NrpnData[0] ); + } + + public int compareTo( VsqNrpn item ) { + return Clock - item.Clock; + } + + public void append( int nrpn, byte data_msb ) { + m_list.add( new VsqNrpn( Clock, nrpn, data_msb ) ); + } + + public void append( int nrpn, byte data_msb, byte data_lsb ) { + m_list.add( new VsqNrpn( Clock, nrpn, data_msb, data_lsb ) ); + } + + public int getNrpn() { + return m_nrpn; + } + + public byte getDataMsb() { + return m_datamsb; + } + + public byte getDataLsb() { + return m_datalsb; + } + + private boolean getDataLsbSpecified() { + return m_datalsb_specified; + } + +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqPhoneticSymbol.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqPhoneticSymbol.java new file mode 100644 index 0000000..de553ec --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqPhoneticSymbol.java @@ -0,0 +1,146 @@ +/* + * VsqPhoneticSymbol.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +public class VsqPhoneticSymbol { + private static final String[] _SYMBOL_VOWEL_JP = new String[] { + "a", + "i", + "M", + "e", + "o", + }; + private static String[] _SYMBOL_CONSONANT_JP = new String[] { + "k", + "k'", + "g", + "g'", + "N", + "N'", + "s", + "S", + "z", + "Z", + "dz", + "dZ", + "t", + "t'", + "ts", + "tS", + "d", + "d'", + "n", + "J", + "h", + "h\\", + "C", + "p\\", + "p\\'", + "b", + "b'", + "p", + "p'", + "m", + "m'", + "j", + "4", + "4'", + "w", + "N\\", + }; + private static String[] _SYMBOL_EN = new String[] { + "@", + "V", + "e", + "e", + "I", + "i:", + "{", + "O:", + "Q", + "U", + "u:", + "@r", + "eI", + "aI", + "OI", + "@U", + "aU", + "I@", + "e@", + "U@", + "O@", + "Q@", + "w", + "j", + "b", + "d", + "g", + "bh", + "dh", + "gh", + "dZ", + "v", + "D", + "z", + "Z", + "m", + "n", + "N", + "r", + "l", + "l0", + "p", + "t", + "k", + "ph", + "th", + "kh", + "tS", + "f", + "T", + "s", + "S", + "h", + }; + + public static boolean IsConsonant( String symbol ) { + for ( int i = 0; i < _SYMBOL_CONSONANT_JP.length; i++ ) { + if ( _SYMBOL_CONSONANT_JP[i].equals( symbol ) ) { + return true; + } + } + return false; + } + + public static boolean IsValidSymbol( String symbol ) { + for ( int i = 0; i < _SYMBOL_VOWEL_JP.length; i++ ) { + if ( _SYMBOL_VOWEL_JP[i].equals( symbol ) ) { + return true; + } + } + for ( int i = 0; i < _SYMBOL_CONSONANT_JP.length; i++ ) { + if ( _SYMBOL_CONSONANT_JP[i].equals( symbol ) ) { + return true; + } + } + for ( int i = 0; i < _SYMBOL_EN.length; i++ ) { + if ( _SYMBOL_EN[i].equals( symbol ) ) { + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqTrack.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqTrack.java new file mode 100644 index 0000000..821e91e --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqTrack.java @@ -0,0 +1,307 @@ +/* + * VsqTrack.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; +import java.io.*; + +public class VsqTrack implements Cloneable { + private String m_name; + private VsqMetaText m_meta_text; + private Vector m_midi_event; + private int m_edited_start = Integer.MAX_VALUE; + private int m_edited_end = Integer.MIN_VALUE; + + public VsqEventIterator singerEventEnumerator() { + return m_meta_text.getEventList().iterator( VsqEventIteratorMode.Singer ); + } + + public VsqEventIterator noteEventEnumerator() { + return m_meta_text.getEventList().iterator( VsqEventIteratorMode.Anote ); + } + + public void printMetaText( TextMemoryStream sw, boolean encode, long eos, int start ) { + m_meta_text.print( sw, encode, eos, start ); + } + + public void printMetaText( String file ) throws IOException { + TextMemoryStream tms = new TextMemoryStream(); + int count = m_meta_text.getEventList().size(); + int clLast = m_meta_text.getEventList().get( count - 1 ).Clock + 480; + m_meta_text.print( tms, true, (long)clLast, 0 ); + BufferedWriter sw = new BufferedWriter( new FileWriter( file ) ); + tms.rewind(); + while ( tms.peek() >= 0 ) { + String line = tms.readLine(); + sw.write( line + "\n" ); + } + } + + /** + * for future implement:
+     *property VsqMaster Master {
+     *    public get {
+     *        return m_meta_text.master;
+     *    }
+     *    protected set {
+     *        m_meta_text.master = value;
+     *    }
+     *};
+ * @return + */ + public VsqMaster getMaster() { + return m_meta_text.master; + } + + protected void setMaster( VsqMaster value ) { + m_meta_text.master = value; + } + + /** + * for future implement:
+     *property VsqMixer Mixer {
+     *    public get {
+     *        return m_meta_text.mixer;
+     *    }
+     *    protected set {
+     *        m_meta_text.mixer = value;
+     *    }
+     *};
+ * @return + */ + public VsqMixer getMixer() { + return m_meta_text.mixer; + } + + protected void setMixer( VsqMixer value ) { + m_meta_text.mixer = value; + } + + public VsqBPList getVsqBPList( VsqCurveType curveType ) { + return m_meta_text.getVsqBPList( curveType ); + } + + public void setVsqBPList( VsqCurveType curveType, VsqBPList value ) { + m_meta_text.setVsqBPList( curveType, value ); + } + + public VsqEventList getEvents() { + return m_meta_text.getEventList(); + } + + /** + * for future implement:
+     * property int EditedStart {
+     *     public get {
+     *         return m_edited_start;
+     *     }
+     *     protected set {
+     *         if ( value < m_edited_start ) {
+     *              m_edited_start = value;
+     *          }
+     *      }
+     * };
+ */ + public int getEditedStart(){ + return m_edited_start; + } + protected void setEditedStart( int value ){ + m_edited_start = value; + } + public int getEditedEnd() { + return m_edited_end; + } + + protected void setEditedEnd( int value ) { + if ( m_edited_end < value ) { + m_edited_end = value; + } + } + + public void resetEditedArea() { + m_edited_start = Integer.MAX_VALUE; + m_edited_end = Integer.MIN_VALUE; + } + + public Object clone() { + VsqTrack res = new VsqTrack(); + res.m_name = m_name; + if ( m_meta_text != null ) { + res.m_meta_text = (VsqMetaText)m_meta_text.clone(); + } + if ( m_midi_event != null ) { + res.m_midi_event = new Vector(); + for ( int i = 0; i < m_midi_event.size(); i++ ) { + MidiEvent item = m_midi_event.get( i ); + res.m_midi_event.add( (MidiEvent)item.clone() ); + } + } + res.m_edited_start = m_edited_start; + res.m_edited_end = m_edited_end; + return res; + } + + private VsqTrack() { + } + + /** + * Master Trackを構築 + * @param tempo + * @param numerator + * @param denominator + */ + public VsqTrack( int tempo, int numerator, int denominator ) { + this.m_name = "Master Track"; + this.m_meta_text = null; + this.m_midi_event = new Vector(); + this.m_midi_event.add( new MidiEvent( "0 Tempo " + tempo ) ); + this.m_midi_event.add( new MidiEvent( "0 TimeSig " + numerator + "/" + denominator + " 24 8" ) ); + } + + /** + * Master Trackでないトラックを構築。 + * @param name + * @param singer + */ + public VsqTrack( String name, String singer ) { + m_name = name; + m_meta_text = new VsqMetaText( name, singer ); + m_midi_event = new Vector(); + } + + /** + * + * メタテキスト。 + * private property VsqMetaText MetaText { + * get { + * return m_meta_text; + * } + * }; + */ + protected VsqMetaText getVsqMetaText() { + return m_meta_text; + } + + /** + * トラックの名前。 + * public property String Name { + * get { + * return m_name; + * } + * set { + * m_name = value; + * } + * }; + */ + public String getName() { + return m_name; + } + + public void setName( String value ) { + m_name = value; + } + + /** + * 歌詞の文字数を調べます + * @returns + */ + public int getLyricLength() { + int counter = 0; + VsqEventList list = m_meta_text.getEventList(); + for ( int i = 0; i < list.size(); i++ ) { + if ( list.get( i ).ID.type == VsqIDType.Anote ) { + counter++; + } + } + return counter; + } + + /** + * vsqファイルをmf2t形式にテキスト化されたファイルからコンストラクト。 + * @param lines + */ + public VsqTrack( Vector lines ) throws IOException { + m_midi_event = new Vector(); + m_name = ""; + String meta_text_path; + File temp_file = File.createTempFile( "temp", ".bin" ); + meta_text_path = temp_file.getPath(); + + TextMemoryStream sw = new TextMemoryStream(); + int signal; + for ( int j = 0; j < lines.size(); j++ ) { + String s = lines.get( j ); + String line = s; + // signalを取得 + int index = line.indexOf( ' ' ); + String str_signal = line.substring( 0, index ); + signal = Integer.parseInt( str_signal ); + String remain = line.substring( index + 1 ); + + // イベントの種類で処理を分岐 + String[] spl = remain.split( " " ); + if ( spl[0] == "Meta" && spl[1] == "Text" ) { + line = line.replace( signal + " Meta Text \"", "" ); + int second_colon = line.indexOf( ":", 3 ); + line = line.substring( second_colon + 1 ); + line = line.substring( 0, line.length() - 1 ); + line = line.replace( "\\n", "\n" ); + sw.write( line ); + } else if ( spl[0] == "Meta" && (spl[1] == "TrkName" || spl[1] == "SeqName") ) { + m_name = spl[2]; + for ( int i = 3; i < spl.length; i++ ) { + m_name += " " + spl[i]; + } + m_name = m_name.replace( "\"", "" ); + m_name = Lyric.decode( m_name ); + } else { + m_midi_event.add( new MidiEvent( line ) ); + } + } + sw.rewind(); + m_meta_text = new VsqMetaText( sw ); + temp_file.delete(); + } + + /** + * MidiEventの中からテンポ情報を抽出します + * @returns + */ + public Vector getTempoList() { + Vector list = new Vector(); + for ( int i = 0; i < m_midi_event.size(); i++ ) { + if ( m_midi_event.get( i ).type == MidiEventType.tempo ) { + list.add( m_midi_event.get( i ) ); + } + } + Collections.sort( list ); + return list; + } + + /** + * MidiEventの中から拍子情報を抽出します + * @returns + */ + public Vector getTimeSigList() { + Vector list = new Vector(); + for ( int i = 0; i < m_midi_event.size(); i++ ) { + if ( m_midi_event.get( i ).type == MidiEventType.time_signal ) { + list.add( m_midi_event.get( i ) ); + } + } + Collections.sort( list ); + return list; + } + +} \ No newline at end of file diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqUtil.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqUtil.java new file mode 100644 index 0000000..d25209b --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqUtil.java @@ -0,0 +1,326 @@ +/* + * VsqUtil.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +import java.util.*; + /// + /// コンピュータにインストールされたVOCALOID2システムについての情報を取得するためのスタティック・ライブラリ。 + /// + public class VsqUtil { + /// + /// VOCALOIDシステムの仕様上設定可能な歌手の最大数 + /// + public final int MAX_SINGERS = 0x4000; + + private static String s_dll_path = ""; + private static boolean s_dll_path_done = false; + private static String s_exp_db_dir = ""; + private static boolean s_exp_db_dir_done = false; + private static Dictionary s_singer_configs = null; + private static Vector s_installed_singers = new Vector(); + + /// + /// 指定したプログラムチェンジが担当する歌手の歌唱言語を表すインデクスを取得します + /// + /// + /// + public static VsqVoiceLanguage GetLanguage( int program_change ) { + String name = GetOriginalSinger( program_change ); + switch ( name ) { + case "Miku": + case "Rin": + case "Len": + case "Rin_ACT2": + case "Len_ACT2": + case "Gackpoid": + return VsqVoiceLanguage.Japanese; + } + return VsqVoiceLanguage.Default; + } + + + /// + /// 指定したプログラムチェンジが担当する歌手の、オリジナルの歌手名を取得します。 + /// + /// + /// + public static String GetOriginalSinger( int program_change ) { + if ( s_singer_configs == null ) { + LoadSingerConfigs(); + } + if ( s_singer_configs.ContainsKey( program_change ) ) { + SingerConfig sc = GetSingerInfo( program_change ); + String voiceidstr = sc.VOICEIDSTR; + foreach ( SingerConfig installed in s_installed_singers ) { + if ( installed.VOICEIDSTR == voiceidstr ) { + return installed.VOICENAME; + } + } + } + return ""; + } + + + /// + /// 指定したプログラムチェンジが担当する歌手の情報を、VsqIDに変換した物を取得します + /// + /// + /// + public static VsqID GetSingerID( int program_change ) { + VsqID ret = new VsqID( 0 ); + ret.type = VsqIDType.Singer; + SingerConfig sc = GetSingerInfo( program_change ); + int language = 0; + foreach ( SingerConfig sc2 in s_installed_singers ) { + if ( sc.VOICEIDSTR == sc2.VOICEIDSTR ) { + switch ( sc2.VOICENAME ) { + case "Miku": + language = 0; + break; + } + } + } + ret.IconHandle = new IconHandle(); + ret.IconHandle.IconID = "$0701" + program_change.ToString( "0000" ); + ret.IconHandle.IDS = sc.VOICENAME; + ret.IconHandle.Index = 0; + ret.IconHandle.Language = language; + ret.IconHandle.Length = 1; + ret.IconHandle.Original = sc.Original; + ret.IconHandle.Program = program_change; + ret.IconHandle.Type = VsqHandleType.Singer; + ret.IconHandle.Caption = ""; + return ret; + } + + + /// + /// 指定したプログラムチェンジの歌手情報を取得します。 + /// + /// + /// + public static SingerConfig GetSingerInfo( int program_change ) { + if ( s_singer_configs == null ) { + LoadSingerConfigs(); + } + if ( s_singer_configs.ContainsKey( program_change ) ) { + return s_singer_configs[program_change]; + } else { + return null; + } + } + + + /// + /// 歌手設定を読み込む。GetSingerInfo, GetSingerIDが最初に呼ばれた時に自動的に呼び出されるが、明示的に呼び出しても良い。 + /// + public static void LoadSingerConfigs() { + if ( s_singer_configs == null ) { + LoadSingerConfigs( GetExpDbPath() ); + } + } + + + /// + /// SingerEditorによって設定された歌手のリストを取得する.リストのキーは「プログラムチェンジ」の値に対応する + /// + /// + /// + private static void LoadSingerConfigs( String path ) { + s_singer_configs = new Dictionary(); + String map_file = Path.Combine( path, "voice.map" ); + if ( !File.Exists( map_file ) ) { + return; + } + using ( FileStream fs = new FileStream( map_file, FileMode.Open, FileAccess.Read ) ) { + byte[] dat = new byte[8]; + fs.Seek( 0x20, SeekOrigin.Begin ); + for ( int i = 0; i < MAX_SINGERS; i++ ) { + fs.Read( dat, 0, 8 ); + ulong value = makelong_le( dat ); + if ( value >= 1 ) { +#if DEBUG + Console.WriteLine( " value=" + value ); +#endif + String file = Path.Combine( path, "vvoice" + value + ".vvd" ); + if ( File.Exists( file ) ) { + s_singer_configs.Add( i, new SingerConfig( file, (int)(value - 1) ) ); + } + } + } + } + Vector voiceidstrs = new Vector(); + foreach ( SingerConfig sc in s_singer_configs.Values ) { + if ( !voiceidstrs.Contains( sc.VOICEIDSTR ) ) { + voiceidstrs.Add( sc.VOICEIDSTR ); + } + } + foreach ( String s in voiceidstrs ) { + String dir = Path.Combine( path, s ); + String[] files = Directory.GetFiles( dir, "*.vvd" ); + foreach ( String s2 in files ) { + String file = Path.Combine( dir, s2 ); + if ( File.Exists( file ) ) { + s_installed_singers.Add( new SingerConfig( file, -1 ) ); + } + } + } + } + + + /// + /// 長さ8のバイト列をリトルエンディアンとみなし、unsigned longに変換します + /// + /// + /// + private static long makelong_le( byte[] oct ) { + return (ulong)oct[7] << 56 | (ulong)oct[6] << 48 | (ulong)oct[5] << 40 | (ulong)oct[4] << 32 | (ulong)oct[3] << 24 | (ulong)oct[2] << 16 | (ulong)oct[1] << 8 | (ulong)oct[0]; + } + + + /// + /// VOCALOID2 VSTiのdllへのフルパスを取得します + /// + /// + public static unsafe String GetVstiDllPath() { + if ( s_dll_path_done ) { + return s_dll_path; + } + try { + uint hKey; + int ret = windows.RegOpenKeyExW( windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\VOCALOID2\\APPLICATION", 0, windows.KEY_READ, &hKey ); + if ( ret != windows.ERROR_SUCCESS ) { + ret = windows.RegOpenKeyExW( windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\VOCALOID2_DEMO\\APPLICATION", 0, windows.KEY_READ, &hKey ); + if ( ret != windows.ERROR_SUCCESS ) { + return s_dll_path; + } + } + + FILETIME ft; + for ( uint i = 0; ; i++ ) { + String lpszName = new String( new char[64] ); + String pClass = new String( new char[64] ); + uint dwNameSize = (uint)lpszName.Length; + uint pcbClass = 64; + int lRes = windows.RegEnumKeyExW( hKey, i, lpszName, &dwNameSize, (uint*)0, pClass, &pcbClass, &ft ); + if ( lRes != windows.ERROR_SUCCESS ) { + break; + } + + uint hChildKey; + ret = windows.RegOpenKeyExW( hKey, lpszName, 0, windows.KEY_READ, &hChildKey ); + if ( ret != windows.ERROR_SUCCESS ) { + continue; + } + + uint dwType = windows.REG_SZ; + uint dwSize = windows.MAX_PATH; + byte[] tszVSTPlugin = new byte[windows.MAX_PATH]; + tszVSTPlugin[0] = (byte)'\0'; + fixed ( byte* pData = &tszVSTPlugin[0] ) { + ret = windows.RegQueryValueExW( hChildKey, "PATH", (uint*)0, &dwType, pData, &dwSize ); + } + windows.RegCloseKey( hChildKey ); + if ( ret != windows.ERROR_SUCCESS ) { + continue; + } + + String name = Encoding.Unicode.GetString( tszVSTPlugin, 0, (int)dwSize ); + if ( name.EndsWith( "\0" ) ) { + name = name.SubString( 0, name.Length - 1 ); + } + // 製品版 + if ( name.EndsWith( "\\vocaloid2.dll" ) ) { + s_dll_path = name; + break; + } + // デモ版 + if ( name.EndsWith( "\\vocaloid2_demo.dll" ) ) { + s_dll_path = name; + break; + } + } + windows.RegCloseKey( hKey ); + } catch { + } finally { + s_dll_path_done = true; + } + return s_dll_path; + } + + + /// + /// 歌唱データベースが保存されているディレクトリのフルパスを取得します + /// + /// + public static unsafe String GetExpDbPath() { + if ( s_exp_db_dir_done ) { + return s_exp_db_dir; + } + try { + uint hKey; + int ret = windows.RegOpenKeyExW( windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\VOCALOID2\\DATABASE\\VOICE", 0, windows.KEY_READ, &hKey ); + if ( ret != windows.ERROR_SUCCESS ) { + ret = windows.RegOpenKeyExW( windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\VOCALOID2_DEMO\\DATABASE\\VOICE", 0, windows.KEY_READ, &hKey ); + if ( ret != windows.ERROR_SUCCESS ) { + return s_exp_db_dir; + } + } + + FILETIME ft; + for ( uint i = 0; ; i++ ) { + String lpszName = new String( new char[64] ); + String pClass = new String( new char[64] ); + uint dwNameSize = (uint)lpszName.Length; + uint pcbClass = 64; + int lRes = windows.RegEnumKeyExW( hKey, i, lpszName, &dwNameSize, (uint*)0, pClass, &pcbClass, &ft ); + if ( lRes != windows.ERROR_SUCCESS ) { + break; + } + + uint hChildKey; + ret = windows.RegOpenKeyExW( hKey, lpszName, 0, windows.KEY_READ, &hChildKey ); + if ( ret != windows.ERROR_SUCCESS ) { + continue; + } + + uint dwType = windows.REG_SZ; + uint dwSize = windows.MAX_PATH; + byte[] tszVSTPlugin = new byte[windows.MAX_PATH]; + tszVSTPlugin[0] = (byte)'\0'; + fixed ( byte* pData = &tszVSTPlugin[0] ) { + ret = windows.RegQueryValueExW( hChildKey, "INSTALLDIR", (uint*)0, &dwType, pData, &dwSize ); + } + windows.RegCloseKey( hChildKey ); + if ( ret != windows.ERROR_SUCCESS ) { + continue; + } + + String name = Encoding.Unicode.GetString( tszVSTPlugin, 0, (int)dwSize ); + if ( name.EndsWith( "\0" ) ) { + name = name.SubString( 0, name.Length - 1 ); + } + if ( name.EndsWith( "\\voicedbdir" ) ) { + s_exp_db_dir = name; + break; + } + } + windows.RegCloseKey( hKey ); + } catch { + } finally { + s_exp_db_dir_done = true; + } + return s_exp_db_dir; + } + } diff --git a/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqVoiceLanguage.java b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqVoiceLanguage.java new file mode 100644 index 0000000..4dc2c5d --- /dev/null +++ b/trunk/LipSync/JVsq/src/jp/sourceforge/lipsync/vsq/VsqVoiceLanguage.java @@ -0,0 +1,29 @@ +/* + * VsqVoiceLanguage.java + * Copyright (c) 2008 kbinani + * + * This file is part of jp.sourceforge.lipsync.vsq. + * + * jp.sourceforge.lipsync.vsq is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * jp.sourceforge.lipsync.vsq is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +package jp.sourceforge.lipsync.vsq; + +/** + *VOCALOID2の歌唱言語 + * @author kbinani + */ +public enum VsqVoiceLanguage { + /** + * デフォルト。Japaneseと同値 + */ + Default, + /** + * 日本語 + */ + Japanese, +} diff --git a/trunk/LipSync/LipSync.sln b/trunk/LipSync/LipSync.sln new file mode 100644 index 0000000..136543e --- /dev/null +++ b/trunk/LipSync/LipSync.sln @@ -0,0 +1,86 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C# Express 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LipSync", "LipSync\LipSync.csproj", "{15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IPlugin", "IPlugin\IPlugin.csproj", "{FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NicoComment", "NicoComment\NicoComment.csproj", "{6CBD22A6-34C4-4444-8F90-9EE0D150CEC1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VFlip", "VFlip\VFlip.csproj", "{E5F9AD85-0C02-4286-AC4C-F5B34EA10650}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Background", "Background\Background.csproj", "{F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DevUtl", "DevUtl\DevUtl.csproj", "{A7798205-28BD-4DCD-A4EC-56FD23EE7AB9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lang2po", "lang2po\lang2po.csproj", "{D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boare.Lib.AppUtil", "..\Boare.Lib.AppUtil\Boare.Lib.AppUtil.csproj", "{0C58B068-272F-4390-A14F-3D72AFCF3DFB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boare.Lib.Media", "..\Boare.Lib.Media\Boare.Lib.Media.csproj", "{F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boare.Lib.Vsq", "..\Boare.Lib.Vsq\Boare.Lib.Vsq.csproj", "{673347F3-6FC2-4F82-9273-BF158E0F8CB1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bocoree", "..\bocoree\bocoree.csproj", "{C8AAE632-9C6C-4372-8175-811528A66742}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Boare.Lib.Swf", "..\Boare.Lib.Swf\Boare.Lib.Swf.csproj", "{D861973B-3BC6-4F52-83BE-49A8C269C09F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56}.Release|Any CPU.Build.0 = Release|Any CPU + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00}.Release|Any CPU.Build.0 = Release|Any CPU + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1}.Release|Any CPU.Build.0 = Release|Any CPU + {E5F9AD85-0C02-4286-AC4C-F5B34EA10650}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5F9AD85-0C02-4286-AC4C-F5B34EA10650}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5F9AD85-0C02-4286-AC4C-F5B34EA10650}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5F9AD85-0C02-4286-AC4C-F5B34EA10650}.Release|Any CPU.Build.0 = Release|Any CPU + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9}.Release|Any CPU.Build.0 = Release|Any CPU + {A7798205-28BD-4DCD-A4EC-56FD23EE7AB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7798205-28BD-4DCD-A4EC-56FD23EE7AB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7798205-28BD-4DCD-A4EC-56FD23EE7AB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7798205-28BD-4DCD-A4EC-56FD23EE7AB9}.Release|Any CPU.Build.0 = Release|Any CPU + {D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9}.Release|Any CPU.Build.0 = Release|Any CPU + {0C58B068-272F-4390-A14F-3D72AFCF3DFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C58B068-272F-4390-A14F-3D72AFCF3DFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C58B068-272F-4390-A14F-3D72AFCF3DFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C58B068-272F-4390-A14F-3D72AFCF3DFB}.Release|Any CPU.Build.0 = Release|Any CPU + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452}.Release|Any CPU.Build.0 = Release|Any CPU + {673347F3-6FC2-4F82-9273-BF158E0F8CB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {673347F3-6FC2-4F82-9273-BF158E0F8CB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {673347F3-6FC2-4F82-9273-BF158E0F8CB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {673347F3-6FC2-4F82-9273-BF158E0F8CB1}.Release|Any CPU.Build.0 = Release|Any CPU + {C8AAE632-9C6C-4372-8175-811528A66742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8AAE632-9C6C-4372-8175-811528A66742}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8AAE632-9C6C-4372-8175-811528A66742}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8AAE632-9C6C-4372-8175-811528A66742}.Release|Any CPU.Build.0 = Release|Any CPU + {D861973B-3BC6-4F52-83BE-49A8C269C09F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D861973B-3BC6-4F52-83BE-49A8C269C09F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D861973B-3BC6-4F52-83BE-49A8C269C09F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D861973B-3BC6-4F52-83BE-49A8C269C09F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/trunk/LipSync/LipSync/Common/AviutlPlugin.cs b/trunk/LipSync/LipSync/Common/AviutlPlugin.cs new file mode 100644 index 0000000..6f2d0f4 --- /dev/null +++ b/trunk/LipSync/LipSync/Common/AviutlPlugin.cs @@ -0,0 +1,45 @@ +using System.Runtime.InteropServices; + +namespace Boare.Lib.AviutlPlugin{ + + /*class aviutl { + + [DllImport( "Invoke", EntryPoint="GetFilterTable")] + public extern static FILTER_DLL GetFilterTable(); + + } + + + struct FILTER_DLL { + int flag; + int x,y; + TCHAR *name; + int track_n; + TCHAR **track_name; + int* track_default; + int* track_s; + int* track_e; + int check_n; + TCHAR **check_name; + int* check_default; + BOOL (*func_proc)( FILTER *fp,FILTER_PROC_INFO *fpip ); + BOOL (*func_init)( FILTER *fp ); + BOOL (*func_exit)( FILTER *fp ); + BOOL (*func_update)( FILTER *fp,int status ); + BOOL (*func_WndProc)( HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam,void *editp,FILTER *fp ); + int* track; + int* check; + void* ex_data_ptr; + int ex_data_size; + TCHAR *information; + BOOL (*func_save_start)( FILTER *fp,int s,int e,void *editp ); + BOOL (*func_save_end)( FILTER *fp,void *editp ); + EXFUNC *exfunc; + HWND hwnd; + HINSTANCE dll_hinst; + void* ex_data_def; + BOOL (*func_is_saveframe)( FILTER *fp,void *editp,int saveno,int frame,int fps,int edit_flag,int inter ); + int[] reserve = new int[6]; + }*/ + +} diff --git a/trunk/LipSync/LipSync/Common/Common.cs b/trunk/LipSync/LipSync/Common/Common.cs new file mode 100644 index 0000000..d5cd2c5 --- /dev/null +++ b/trunk/LipSync/LipSync/Common/Common.cs @@ -0,0 +1,264 @@ +/* + * Common.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; +using System.Windows.Forms; + +namespace LipSync { + + /// + /// LipSync共用の関数 + /// + public class Common { + private static string m_log_file = ""; + private static StreamWriter m_sw = null; + private static SaveFileDialog s_dialog = null; + public static Color CURVE_X = Color.Black; + public static Color CURVE_Y = Color.White; + public static Color CURVE_SCALE = Color.Orange; + public static Color CURVE_ALPHA = Color.Red; + public static Color CURVE_ROTATE = Color.Navy; + + /// + /// ファイルダイアログのFilterに指定しようとしている文字列がエラーを起こさないかどうかを確かめます + /// + /// + /// + public static bool CheckFilterValidity( string filter ) { + if ( s_dialog == null ) { + s_dialog = new SaveFileDialog(); + } + try { + s_dialog.Filter = filter; + return true; + } catch { + return false; + } + } + + public static void DebugWriteLine( string s ) { +#if DEBUG +#if MONO + Console.WriteLine( s ); + System.Diagnostics.Trace.WriteLine( s ); + System.Diagnostics.Debug.WriteLine( s ); +#else + //System.Diagnostics.Debug.WriteLine( s ); + Console.WriteLine( s ); +#endif +#endif + } + + public static Image GetThumbnailImage( Image image, int width, int height ) { + Bitmap res = new Bitmap( width, height, PixelFormat.Format32bppArgb ); + if ( image == null ) { + return res; + } + int w = image.Width; + int h = image.Height; + float ASPECTO = (float)width / (float)height; + float aspecto = (float)w / (float)h; + float order = 1f; //拡大率 + int top = 0; //描画位置y座標 + int left = 0; //描画位置x座標 + if ( ASPECTO > aspecto ) { + // サムネイルのほうが横長 + order = (float)height / (float)h; + left = (int)(width - order * w) / 2; + } else { + // サムネイルのほうが縦長 + order = (float)width / (float)w; + top = (int)(height - order * h) / 2; + } + using ( Graphics g = Graphics.FromImage( res ) ) { + g.Clear( Color.Transparent ); + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; + g.DrawImage( image, left, top, w * order, h * order ); + } + return res; + } + + /// + /// 2つの整数の最大公約数を返します。 + /// + /// + /// + /// + public static long GetGCD( long m, long n ) { + if ( n > m ) { + long a = n; + n = m; + m = a; + } + while ( true ) { + if ( n == 0 ) { + return m; + } + long quotient = m / n; + long odd = m - n * quotient; + if ( odd == 0 ) { + return n; + } + m = n; + n = odd; + } + } + + + public static Point PointFromPointF( PointF point_f ) { + return new Point( (int)point_f.X, (int)point_f.Y ); + } + + + public static Size SizeFromSizeF( SizeF size_f ) { + return new Size( (int)size_f.Width, (int)size_f.Height ); + } + + + /// + /// 画像から不透明領域を検出する。 + /// + /// + /// + public static Rectangle GetNonTransparentRegion( Bitmap bmp ) { + if ( bmp.PixelFormat != PixelFormat.Format32bppArgb ) { + return new Rectangle(); + } + BitmapData bmpdat = bmp.LockBits( + new Rectangle( 0, 0, bmp.Width, bmp.Height ), + ImageLockMode.ReadOnly, + PixelFormat.Format32bppArgb + ); + + int stride = bmpdat.Stride; + + int ymax = 0; + int ymin = (bmp.Height - 1) * stride; + int xmax = 0; + int xmin = (bmp.Width - 1) * 4; + const byte ZERO = 0; + unsafe { + byte* dat = (byte*)(void*)bmpdat.Scan0; + int xend = bmp.Width * 4; + int yend; + for ( int x = 0; x < xend; x += 4 ) { + // yminを決める + yend = ymin;//ymin* stride; + for ( int y = 0; y <= yend; y += stride ) { + if ( dat[x + y + 3] != ZERO ) { + //ymin = Math.Min( ymin, y / stride ); + ymin = Math.Min( ymin, y ); + break; + } + } + + // ymaxを決める + yend = ymax;// ymax * stride; + for ( int y = (bmp.Height - 1) * stride; y >= yend; y -= stride ) { + if ( dat[x + y + 3] != ZERO ) { + //ymax = Math.Max( ymax, y / stride ); + ymax = Math.Max( ymax, y ); + break; + } + } + } + + yend = ymax;// ymax * stride; + for ( int y = ymin; y <= yend; y += stride ) { + // xminを決める + for ( int x = 0; x < xmin; x += 4 ) { + if ( dat[x + y + 3] != ZERO ) { + //xmin = Math.Min( xmin, x / 4 ); + xmin = Math.Min( xmin, x ); + break; + } + } + + // xmaxを決める + for ( int x = (bmp.Width - 1) * 4; x >= xmax; x -= 4 ) { + if ( dat[x + y + 3] != ZERO ) { + //xmax = Math.Max( xmax, x / 4 ); + xmax = Math.Max( xmax, x ); + break; + } + } + } + if ( xmax <= xmin || ymax <= ymin ) { + xmin = 0; + xmax = bmp.Width - 1; + ymin = 0; + ymax = bmp.Height - 1; + } else { + xmin = xmin / 4; + xmax = xmax / 4; + ymin = ymin / stride; + ymax = ymax / stride; + } + } + bmp.UnlockBits( bmpdat ); + return new Rectangle( xmin, ymin, xmax - xmin + 1, ymax - ymin + 1 ); + } + + public static void LogPush( Exception ex ) { + LogPush( ex.Source + Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace ); + } + public static void LogPush( string procedure, string message_type, string message ) { + LogPush( procedure + ";" + message_type + ";" + message ); + } + static void LogPush( string message ) { + if ( m_sw == null ) { + m_log_file = Path.Combine( Application.StartupPath, "error.log" ); + m_sw = new StreamWriter( m_log_file, true, Encoding.Unicode ); + m_sw.WriteLine( "************************************************************************" ); + m_sw.WriteLine( "Logger started : " + DateTime.Now.ToString() ); + m_sw.WriteLine( "------------------------------------------------------------------------" ); + } + m_sw.WriteLine( DateTime.Now.ToString() + ";" + message ); + m_sw.Flush(); + } + + public static void LogClose() { + if ( m_sw != null ) { + m_sw.Close(); + m_sw = null; + } + } + + /// + /// 指定したパスのファイルからイメージを読み込みます + /// + /// イメージファイルへのパス + /// + public static Image ImageFromFile( string fpath ) { + Bitmap result = null; + if ( File.Exists( fpath ) ) { + using ( FileStream fs = new FileStream( fpath, FileMode.Open, FileAccess.Read ) ) { + Image temp = Image.FromStream( fs ); + result = new Bitmap( temp.Width, temp.Height, PixelFormat.Format32bppArgb ); + using ( Graphics g = Graphics.FromImage( result ) ) { + g.DrawImage( temp, 0, 0, temp.Width, temp.Height ); + } + temp.Dispose(); + } + } + return result; + } + } + +} diff --git a/trunk/LipSync/LipSync/Common/CurveEditor.cs b/trunk/LipSync/LipSync/Common/CurveEditor.cs new file mode 100644 index 0000000..8ebfbd8 --- /dev/null +++ b/trunk/LipSync/LipSync/Common/CurveEditor.cs @@ -0,0 +1,2653 @@ +/* + * CurveEditor.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; +using LipSync; + +namespace CurveEditor { + + public partial class CurveEditor : UserControl { + public delegate void CurveEditedEventHandler(); + + public enum MouseDownMode { + Nothing, + MovePoint, + } + + private class ScaleAndOffset { + public float Scale; + public float Offset; + + public ScaleAndOffset( float scale, float offset ) { + Scale = scale; + Offset = offset; + } + } + + Dictionary m_list = new Dictionary(); + Dictionary m_list_minmax = new Dictionary(); + bool m_drag_ = false; + bool m_drag_with_space_key = false; + Point m_drag_start; + float m_old_xoffset; + float m_old_yoffset; + const int LABEL_WIDTH = 15; + const int LIST_WIDTH = 60; + string m_selected = ""; + int m_picked_point_id = -1; + PickedSide m_picked_side; + bool m_scale_locked = false; + ControlType m_last_added_type = ControlType.None; + List m_commands = new List(); + int m_command_position = -1; + PointF m_before_edit; + //bool m_moved = false; + //bool m_mouse_upped = true; + bool m_change_xscale = false; + bool m_change_yscale = false; + int m_change_origin; + float m_old_scale; + float CHANGE_SCALE_ORDER = 70f; + bool m_spacekey_down = false; + Cursor HAND; + bool _number_visible = false; + PointF _number; + Font _font; + Point _mouse_position; + ContextMenuStrip _cmenu; + ToolStripMenuItem _cmenuNumericInput; + bool m_rescaley_enabled = true; + XLabel m_xlabel = XLabel.None; + YLabel m_ylabel = YLabel.None; + bool m_change_xscale_with_wheel = true; + bool m_change_yscale_with_wheel = true; + bool m_show_list = true; + float m_max_xscale = 100f; + float m_min_xscale = 1e-4f; + float m_max_yscale = 100f; + float m_min_yscale = 1e-4f; + Color m_origin_scale_line = Color.FromArgb( 44, 44, 44 ); + Color m_scale_line = Color.FromArgb( 94, 94, 94 ); + Color m_sub_scale_line = Color.FromArgb( 110, 110, 110 ); + Color m_cHandle_master = Color.FromArgb( 240, 144, 160 ); + Color m_cControl_master = Color.FromArgb( 255, 130, 0 ); + Color m_cHandle_normal = Color.FromArgb( 255, 130, 0 ); + Color m_cControl_normal = Color.FromArgb( 51, 192, 64 ); + Color m_data_point = Color.Black; + Color m_data_point_hilight = Color.Red; + int m_data_point_size = 2; + int m_control_point_size = 2; + PointType m_data_point_type; + PointType m_control_point_type; + Color m_label_back = Color.FromArgb( 172, 172, 172 ); + Color m_list_back = Color.FromArgb( 143, 143, 143 ); + float m_xscale = 1f; + float m_yscale = 1f; + float m_xoffset = 0f; + float m_yoffset = 0f; + int m_place_count_x = 1; + int m_place_count_y = 1; + bool m_scroll_enabled = true; + bool m_mouse_moved = false; + MouseDownMode m_mouse_down_mode = MouseDownMode.Nothing; + + /// + /// カーブのデータ点・制御点などが編集された時に発生します + /// + public event CurveEditedEventHandler CurveEdited; + + /// + /// パブリックコンストラクタ + /// + public CurveEditor() { + InitializeComponent(); + this.MouseWheel += new MouseEventHandler( CurveEditor_MouseWheel ); + this.SetStyle( ControlStyles.DoubleBuffer, true ); + this.SetStyle( ControlStyles.UserPaint, true ); + this.SetStyle( ControlStyles.AllPaintingInWmPaint, true ); + byte[] foo = new byte[] { 0x0, 0x0, 0x2, 0x0, 0x1, 0x0, 0x20, 0x20, 0x0, 0x0, 0x10, 0x0, 0x10, 0x0, 0xe8, 0x2, 0x0, 0x0, 0x16, 0x0, + 0x0, 0x0, 0x28, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x80, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, + 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x0, 0x80, 0x80, 0x0, 0xc0, 0xc0, 0xc0, 0x0, 0x80, 0x80, 0x80, 0x0, 0xff, 0x0, + 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0xff, + 0xff, 0x0, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, + 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0x87, 0xe1, 0xff, 0xff, 0x7, + 0xe0, 0xff, 0xff, 0x7, 0xe0, 0xff, 0xff, 0x87, 0xe1, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xf8, + 0x1f, 0xff, 0xff, 0xf8, 0x1f, 0xff, 0xff, 0xfc, 0x3f, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; + using ( MemoryStream ms = new MemoryStream( foo ) ) { + HAND = new Cursor( ms ); + } + _font = new Font( "MS UI Gothic", 10 ); + } + + public bool GetYScaleAndYOffset( string ID, out float y_scale, out float y_offset ) { + if ( m_list_minmax.ContainsKey( ID ) ) { + y_scale = m_list_minmax[ID].Scale; + y_offset = m_list_minmax[ID].Offset; + return true; + } else { + y_scale = 1f; + y_offset = 0f; + return false; + } + } + + public void SetYScaleAndYOffset( string ID, float y_scale, float y_offset ) { + if ( m_list_minmax.ContainsKey( ID ) ) { + m_list_minmax[ID].Scale = y_scale; + m_list_minmax[ID].Offset = y_offset; + this.Invalidate(); + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public Size GraphSize { + get { + int width, height; + if ( XLabel != XLabel.None ) { + height = this.Height - LABEL_WIDTH; + } else { + height = this.Height; + } + if ( YLabel != YLabel.None ) { + width = this.Width - LABEL_WIDTH; + } else { + width = this.Width; + } + if ( ShowList ) { + width -= LIST_WIDTH; + } + return new Size( width, height ); + } + } + + /// + /// 縦軸スケールの変更を許可するかどうかを取得または設定します + /// + public bool RescaleYEnabled { + get { + return m_rescaley_enabled; + } + set { + m_rescaley_enabled = value; + } + } + + bool Drag { + get { + return m_drag_; + } + set { + m_drag_ = value; + if ( m_drag_ ) { + this.Cursor = HAND; + } else { + this.Cursor = Cursors.Default; + } + } + } + + /// + /// 現在カーブエディタに設定されているデータを全て破棄し,初期化します + /// + public void Clear() { + m_list.Clear(); + m_list_minmax.Clear(); + m_commands.Clear(); + m_command_position = -1; + m_selected = ""; + m_picked_point_id = -1; + } + + /// + /// Undo, Redo用のバッファを全て破棄し,初期化します + /// + public void ClearBuffer() { + m_commands.Clear(); + m_command_position = -1; + } + + /// + /// 横軸の目盛の種類を取得または設定します + /// + public XLabel XLabel { + get { + return m_xlabel; + } + set { + m_xlabel = value; + } + } + + /// + /// 縦軸の目盛の種類を取得または設定します + /// + public YLabel YLabel { + get { + return m_ylabel; + } + set { + m_ylabel = value; + } + } + + /// + /// マウスホイールで横軸のスケールを変更するかどうかを取得または設定します + /// + public bool ChangeXScaleWithWheel { + get { + return m_change_xscale_with_wheel; + } + set { + m_change_xscale_with_wheel = value; + } + } + + /// + /// マウスホイールで縦軸のスケールを変更するかどうかを取得または設定します + /// + public bool ChangeYScaleWithWheel { + get { + return m_change_yscale_with_wheel; + } + set { + m_change_yscale_with_wheel = value; + } + } + + /// + /// 編集対象となるカーブのリストを,画面右側に表示するかどうかを取得または設定します + /// + public bool ShowList { + get { + return m_show_list; + } + set { + m_show_list = value; + } + } + + /// + /// 横軸のスケールとして設定できる最大値を取得または設定します + /// + public float MaxXScale { + get { + return m_max_xscale; + } + set { + if ( value > 0 && value > m_min_xscale ) { + m_max_xscale = value; + } + } + } + + /// + /// 横軸のスケールとして設定できる最小値を取得または設定します + /// + public float MinXScale { + get { + return m_min_xscale; + } + set { + if ( value > 0 && value < m_max_xscale ) { + m_min_xscale = value; + } + } + } + + /// + /// 縦軸のスケールとして設定できる最大値を取得または設定します + /// + public float MaxYScale { + get { + return m_max_yscale; + } + set { + if ( value > 0 && value > m_min_yscale ) { + m_max_yscale = value; + } + } + } + + /// + /// 縦軸のスケールとして設定できる最小値を取得または設定します + /// + public float MinYScale { + get { + return m_min_yscale; + } + set { + if ( value > 0 && value < m_max_yscale ) { + m_min_yscale = value; + } + } + } + + void CurveEditor_MouseWheel( object sender, MouseEventArgs e ) { + Keys modifier = Control.ModifierKeys; + if ( modifier == Keys.Control ) { + float dx = e.Delta / XScale; + XOffset -= dx; + this.Invalidate(); + } else if ( modifier == Keys.Shift ) { + float dy = e.Delta / YScale; + YOffset -= dy; + if ( m_selected != "" ) { + m_list_minmax[m_selected].Offset = YOffset; + } + this.Invalidate(); + } else if ( modifier == Keys.None ) { + float count = e.Delta / 120f; + float n_xscale; + float n_yscale; + float order; + if ( count < 0 ) { + order = (float)Math.Pow( 0.83, Math.Abs( count ) ); + } else { + order = (float)(1f / Math.Pow( 0.83, Math.Abs( count ) )); + } + if ( m_change_xscale_with_wheel ) { + n_xscale = m_xscale * order; + } else { + n_xscale = m_xscale; + } + if ( m_change_yscale_with_wheel ) { + n_yscale = m_yscale * order; + } else { + n_yscale = m_yscale; + } + if ( m_xscale != n_xscale || m_yscale != n_yscale ) { + bool changed = false; + if ( MinXScale <= n_xscale && n_xscale <= MaxXScale ) { + XOffset = e.X * (1f / n_xscale - 1f / XScale) + XOffset; + XScale = n_xscale; + changed = true; + } + if ( MinYScale <= n_yscale && n_yscale <= MaxYScale ) { + YOffset = (this.Height - e.Y) * (1f / n_yscale - 1f / YScale) + YOffset; + YScale = n_yscale; + changed = true; + } + if ( changed ) { + this.Invalidate(); + } + } + } + } + + /// + /// 編集対象となるカーブを,このコントロールに追加します + /// + /// + /// + /*public void Add( string ID, Color curve ) { + m_list.Add( ID, new BezierChain( curve ) ); + }*/ + + public void Add( string ID, BezierChain chain ) { + m_list.Add( ID, chain ); + m_list_minmax.Add( ID, new ScaleAndOffset( 1f, 0f ) ); + } + + //todo:動かしうるxの範囲を探知できるようにする?pt1-4それぞれが動く場合。 + /// + /// 4つの制御点からなるベジエ曲線が、x軸について陰かどうかを判定する + /// + /// 始点 + /// 制御点1 + /// 制御点2 + /// 終点 + /// + public static bool IsBezierImplicit( float pt1, float pt2, float pt3, float pt4 ) { + double a = pt4 - 3 * pt3 + 3 * pt2 - pt1; + double b = 2 * pt3 - 4 * pt2 + 2 * pt1; + double c = pt2 - pt1; + if ( a == 0 ) { + if ( c >= 0 && b + c >= 0 ) { + return true; + } else { + return false; + } + } else if ( a > 0 ) { + if ( -b / (2 * a) <= 0 ) { + if ( c >= 0 ) { + return true; + } else { + return false; + } + } else if ( 1 <= -b / (2 * a) ) { + if ( a + b + c >= 0 ) { + return true; + } else { + return false; + } + } else { + if ( c - b * b / (4 * a) >= 0 ) { + return true; + } else { + return false; + } + } + } else { + if ( -b / (2 * a) <= 0.5 ) { + if ( a + b + c >= 0 ) { + return true; + } else { + return false; + } + } else { + if ( c >= 0 ) { + return true; + } else { + return false; + } + } + } + } + + #region 描画設定 + public Color MainScaleLine { + get { + return m_origin_scale_line; + } + set { + m_origin_scale_line = value; + } + } + + + public Color ScaleLine { + get { + return m_scale_line; + } + set { + m_scale_line = value; + } + } + + + public Color SubScaleLine { + get { + return m_sub_scale_line; + } + set { + m_sub_scale_line = value; + } + } + + + public Color HandleMaster { + get { + return m_cHandle_master; + } + set { + m_cHandle_master = value; + } + } + + + public Color ControlMaster { + get { + return m_cControl_master; + } + set { + m_cControl_master = value; + } + } + + + public Color HandleNormal { + get { + return m_cHandle_normal; + } + set { + m_cHandle_normal = value; + } + } + + + public Color ControlNormal { + get { + return m_cControl_normal; + } + set { + m_cControl_normal = value; + } + } + + /// + /// データポイントの描画色を取得または設定します + /// + public Color DataPoint { + get { + return m_data_point; + } + set { + m_data_point = value; + } + } + + /// + /// 選択されたデータポイントの描画色を取得または設定します + /// + public Color DataPointHilight { + get { + return m_data_point_hilight; + } + set { + m_data_point_hilight = value; + } + } + + public int DataPointSize { + get { + return m_data_point_size; + } + set { + m_data_point_size = value; + } + } + + + public int ControlPointSize { + get { + return m_control_point_size; + } + set { + m_control_point_size = value; + } + } + + + public PointType DataPointType { + get { + return m_data_point_type; + } + set { + m_data_point_type = value; + } + } + + + public PointType ControlPointType { + get { + return m_control_point_type; + } + set { + m_control_point_type = value; + } + } + + + public Color LabelBackground { + get { + return m_label_back; + } + set { + m_label_back = value; + } + } + + + public Color ListBackground { + get { + return m_list_back; + } + set { + m_list_back = value; + } + } + #endregion + + /// + /// 横軸のスケールを取得または設定します[pixel/(任意の単位)] + /// + public float XScale { + get { + return m_xscale; + } + set { + if ( !m_scale_locked && MinXScale <= value && value <= MaxXScale ) { + m_xscale = value; + } + } + } + + /// + /// 縦軸のスケールを取得または設定します[pixel/(任意の単位)] + /// + public float YScale { + get { + return m_yscale; + } + set { + if ( !m_scale_locked && MinYScale <= value && value <= MaxYScale ) { + m_yscale = value; + } + } + } + + /// + /// 画面左端におけるx軸の値を取得または設定します + /// + public float XOffset { + get { + return m_xoffset; + } + set { + m_xoffset = value; + } + } + + /// + /// + /// + public float YOffset { + get { + return m_yoffset; + } + set { + m_yoffset = value; + } + } + + /// + /// グラフ上のX座標を,コントロール上の座標(pixel)に換算します + /// + /// + /// + private int cX( float sX ) { + return (int)((sX + XOffset) * XScale); + } + + /// + /// グラフ上のY座標を,コントロール上の座標(pixel)に換算します + /// + /// + /// + private int cY( float sY ) { + return this.Height - (int)((sY + YOffset) * YScale); + } + + private Point cPoint( PointF sPoint ) { + return new Point( cX( sPoint.X ), cY( sPoint.Y ) ); + } + + private float sX( int cX ) { + return cX / XScale - XOffset; + } + + private float sY( int cY ) { + return (this.Height - cY) / YScale - YOffset; + } + + private PointF sPoint( Point cPoint ) { + return new PointF( sX( cPoint.X ), sY( cPoint.Y ) ); + } + + private float m_place_x { + get { + int n1 = (int)Math.Log10( 400 / XScale ); + int n2 = (int)Math.Log10( 200 / XScale ); + int n5 = (int)Math.Log10( 80 / XScale ); + float d1 = (float)Math.Pow( 10, n1 ); + float d2 = (float)Math.Pow( 10, n2 ); + float d5 = (float)Math.Pow( 10, n5 ); + if ( d1 <= 2 * d2 && d1 <= 5 * d5 ) { + m_place_count_x = 1; + return d1; + } else if ( 2 * d2 <= d1 && 2 * d2 <= 5 * d5 ) { + m_place_count_x = 2; + return d2; + } else { + m_place_count_x = 5; + return d5; + } + } + } + + private float m_place_y { + get { + int n1 = (int)Math.Log10( 400 / YScale ); + int n2 = (int)Math.Log10( 200 / YScale ); + int n5 = (int)Math.Log10( 80 / YScale ); + float d1 = (float)Math.Pow( 10, n1 ); + float d2 = (float)Math.Pow( 10, n2 ); + float d5 = (float)Math.Pow( 10, n5 ); + if ( d1 <= 2 * d2 && d1 <= 5 * d5 ) { + m_place_count_y = 1; + return d1; + } else if ( 2 * d2 <= d1 && 2 * d2 <= 5 * d5 ) { + m_place_count_y = 2; + return d2; + } else { + m_place_count_y = 5; + return d5; + } + } + } + + public BezierChain this[string ID] { + get { + return m_list[ID]; + } + set { + m_list[ID] = value; + } + } + + public float this[string ID, float x] { + get { + return m_list[ID].GetValue( x ); + } + } + + public bool ScrollEnabled { + get { + return m_scroll_enabled; + } + set { + m_scroll_enabled = value; + } + } + + /// + /// + /// + /// + /// + /// 関数を抜けるとき確実にm_scale_locked = falseとすること!! + private void CurveEditor_Paint( object sender, PaintEventArgs e ) { + m_scale_locked = true; + + //グラフ内のメモリを描画 + int o_x = cX( 0f ); + int o_y = cY( 0f ); + e.Graphics.DrawLine( new Pen( MainScaleLine ), new Point( 0, o_y ), new Point( this.Width, o_y ) ); + e.Graphics.DrawLine( new Pen( MainScaleLine ), new Point( o_x, 0 ), new Point( o_x, this.Height ) ); +#if DEBUG + //MessageBox.Show( "place_x=" + place_x ); +#endif + float place_x = m_place_count_x * m_place_x; + int start_x = (int)(sX( 0 ) / place_x) - 1; + int end_x = (int)(sX( this.Width ) / place_x) + 1; + for ( int i = start_x; i <= end_x; i++ ) { + float sx; + int px; + if ( i != 0 ) { + sx = i * place_x; + px = cX( sx ); + e.Graphics.DrawLine( new Pen( ScaleLine ), new Point( px, 0 ), new Point( px, this.Height ) ); + } + sx = (i + 0.5f) * place_x; + px = cX( sx ); + e.Graphics.DrawLine( new Pen( SubScaleLine ), new Point( px, 0 ), new Point( px, this.Height ) ); + } + + float place_y = m_place_count_y * m_place_y; + int start_y = (int)(sY( this.Height ) / place_y) - 1; + int end_y = (int)(sY( 0 ) / place_y) + 1; + for ( int i = start_y; i <= end_y; i++ ) { + float sy; + int py; + if ( i != 0 ) { + sy = i * place_y; + py = cY( sy ); + e.Graphics.DrawLine( new Pen( ScaleLine ), new Point( 0, py ), new Point( this.Width, py ) ); + } + sy = (i + 0.5f) * place_y; + py = cY( sy ); + e.Graphics.DrawLine( new Pen( SubScaleLine ), new Point( 0, py ), new Point( this.Width, py ) ); + } + + //foreach ( BezierChain chain in m_list.Values ) { + foreach ( string ID in m_list.Keys ) { + BezierChain chain = m_list[ID]; + BezierPoint last; + if ( chain.Count >= 2 ) { + last = chain.List[0]; + } else { + int default_y = cY( chain.Default ); + e.Graphics.DrawLine( new Pen( chain.Color ), new Point( 0, default_y ), new Point( this.Width, default_y ) ); + if ( ID == m_selected && chain.Count >= 1 ) { + int width2 = m_data_point_size; + switch ( DataPointType ) { + case PointType.Circle: + if ( chain.List[0].ID == m_picked_point_id ) { + e.Graphics.FillEllipse( new SolidBrush( DataPointHilight ), + new Rectangle( cX( chain.List[0].Base.X ) - width2, cY( chain.List[0].Base.Y ) - width2, 2 * width2, 2 * width2 ) ); + } else { + e.Graphics.FillEllipse( new SolidBrush( DataPoint ), + new Rectangle( cX( chain.List[0].Base.X ) - width2, cY( chain.List[0].Base.Y ) - width2, 2 * width2, 2 * width2 ) ); + } + break; + case PointType.Rectangle: + if ( chain.List[0].ID == m_picked_point_id ) { + e.Graphics.FillRectangle( new SolidBrush( DataPointHilight ), + new Rectangle( cX( chain.List[0].Base.X ) - width2, cY( chain.List[0].Base.Y ) - width2, 2 * width2, 2 * width2 ) ); + } else { + e.Graphics.FillRectangle( new SolidBrush( DataPoint ), + new Rectangle( cX( chain.List[0].Base.X ) - width2, cY( chain.List[0].Base.Y ) - width2, 2 * width2, 2 * width2 ) ); + } + break; + } + } + continue; + } + int width = m_data_point_size; + if ( ID == m_selected ) { + switch ( DataPointType ) { + case PointType.Circle: + if ( chain.List[0].ID == m_picked_point_id ) { + e.Graphics.FillEllipse( new SolidBrush( DataPointHilight ), + new Rectangle( cX( chain.List[0].Base.X ) - width, cY( chain.List[0].Base.Y ) - width, 2 * width, 2 * width ) ); + } else { + e.Graphics.FillEllipse( new SolidBrush( DataPoint ), + new Rectangle( cX( chain.List[0].Base.X ) - width, cY( chain.List[0].Base.Y ) - width, 2 * width, 2 * width ) ); + } + break; + case PointType.Rectangle: + if ( chain.List[0].ID == m_picked_point_id ) { + e.Graphics.FillRectangle( new SolidBrush( DataPointHilight ), + new Rectangle( cX( chain.List[0].Base.X ) - width, cY( chain.List[0].Base.Y ) - width, 2 * width, 2 * width ) ); + } else { + e.Graphics.FillRectangle( new SolidBrush( DataPoint ), + new Rectangle( cX( chain.List[0].Base.X ) - width, cY( chain.List[0].Base.Y ) - width, 2 * width, 2 * width ) ); + } + break; + } + } + + //デフォルト値(左側)の描画 + if ( chain.Count >= 1 ) { + int default_y = cY( chain.Default ); + int x = cX( chain.List[0].Base.X ); + int y = cY( chain.List[0].Base.Y ); + e.Graphics.DrawLine( new Pen( chain.Color ), new Point( x, default_y ), new Point( -1, default_y ) ); + e.Graphics.DrawLine( new Pen( chain.Color ), new Point( x, default_y ), new Point( x, y ) ); + } + //for ( int i = 1; i < chain.Count; i++ ) { + bool first = true; + Size sz = new Size( 2 * width, 2 * width ); + for( int i = 0; i < chain.List.Count; i++ ){ + BezierPoint bp = chain.List[i]; + if ( first ) { + last = bp; + first = false; + continue; + } + //if ( last.ControlRightType != ControlType.None && chain[i].ControlLeftType != ControlType.None ) { + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; + e.Graphics.DrawBezier( new Pen( chain.Color ), + cPoint( last.Base ), + cPoint( last.ControlRight ), + cPoint( bp.ControlLeft ), + cPoint( bp.Base ) ); + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + + //制御ハンドル用の線 + if ( ID == m_selected ) { + if ( bp.ControlLeftType == ControlType.Master ) { + e.Graphics.DrawLine( new Pen( HandleMaster ), cPoint( bp.Base ), cPoint( bp.ControlLeft ) ); + } else if ( bp.ControlLeftType == ControlType.Normal ) { + e.Graphics.DrawLine( new Pen( HandleNormal ), cPoint( bp.Base ), cPoint( bp.ControlLeft ) ); + } + if ( last.ControlRightType == ControlType.Master ) { + e.Graphics.DrawLine( new Pen( HandleMaster ), cPoint( last.Base ), cPoint( last.ControlRight ) ); + } else if ( last.ControlRightType == ControlType.Normal ) { + e.Graphics.DrawLine( new Pen( HandleNormal ), cPoint( last.Base ), cPoint( last.ControlRight ) ); + } + + //データ点 + width = m_data_point_size; + Point data_point = new Point( cX( bp.Base.X ) - width, cY( bp.Base.Y ) - width ); + switch ( DataPointType ) { + case PointType.Circle: + if ( bp.ID == m_picked_point_id ) { + e.Graphics.FillEllipse( new SolidBrush( DataPointHilight ), + new Rectangle( data_point, sz ) ); + } else { + e.Graphics.FillEllipse( new SolidBrush( DataPoint ), + new Rectangle( data_point, sz ) ); + } + break; + case PointType.Rectangle: + if ( bp.ID == m_picked_point_id ) { + e.Graphics.FillRectangle( new SolidBrush( DataPointHilight ), + new Rectangle( data_point, sz ) ); + } else { + e.Graphics.FillRectangle( new SolidBrush( DataPoint ), + new Rectangle( data_point, sz ) ); + } + break; + } + + //制御ハンドル点 + width = m_control_point_size; + Color cLeft = Color.Black; + Color cRight = Color.Black; + if ( bp.ControlLeftType == ControlType.Master ) { + cLeft = ControlMaster; + } else if ( bp.ControlLeftType == ControlType.Normal ) { + cLeft = ControlNormal; + } + if ( last.ControlRightType == ControlType.Master ) { + cRight = ControlMaster; + } else if ( last.ControlRightType == ControlType.Normal ) { + cRight = ControlNormal; + } + if ( bp.ControlLeftType != ControlType.None && (bp.ControlLeft.X != bp.Base.X || bp.ControlLeft.Y != bp.Base.Y) ) { + Point ctrl_left = new Point( cX( bp.ControlLeft.X ) - width, cY( bp.ControlLeft.Y ) - width ); + switch ( ControlPointType ) { + case PointType.Circle: + e.Graphics.FillEllipse( new SolidBrush( cLeft ), new Rectangle( ctrl_left, sz ) ); + break; + case PointType.Rectangle: + e.Graphics.FillRectangle( new SolidBrush( cLeft ), new Rectangle( ctrl_left, sz ) ); + break; + } + } + if ( last.ControlRightType != ControlType.None && (last.ControlRight.X != last.Base.X || last.ControlRight.Y != last.Base.Y) ) { + Point ctrl_right = new Point( cX( last.ControlRight.X ) - width, cY( last.ControlRight.Y ) - width ); + switch ( ControlPointType ) { + case PointType.Circle: + e.Graphics.FillEllipse( new SolidBrush( cRight ), new Rectangle( ctrl_right, sz ) ); + break; + case PointType.Rectangle: + e.Graphics.FillRectangle( new SolidBrush( cRight ), new Rectangle( ctrl_right, sz ) ); + break; + } + } + } + last = bp; + } + + //デフォルト値(右側)の描画 + if ( chain.Count >= 1 ) { + int default_y = cY( chain.Default ); + int x = cX( last.Base.X ); + int y = cY( last.Base.Y ); + e.Graphics.DrawLine( new Pen( chain.Color ), new Point( x, default_y ), new Point( this.Width + 1, default_y ) ); + e.Graphics.DrawLine( new Pen( chain.Color ), new Point( x, default_y ), new Point( x, y ) ); + } + } + + // マウス位置の数値を描画 + if ( _number_visible ) { + int x = cX( _number.X ); + int y = cY( _number.Y ); + e.Graphics.DrawString( "x : " + _number.X, + _font, + Brushes.Black, + new PointF( x, y - 24 ) ); + e.Graphics.DrawString( "y : " + _number.Y, + _font, + Brushes.Black, + new PointF( x, y - 12 ) ); + } else { + float x = sX( _mouse_position.X ); + float y = sY( _mouse_position.Y ); + e.Graphics.DrawString( "x : " + x, + _font, + Brushes.Black, + new PointF( _mouse_position.X, _mouse_position.Y - 24 ) ); + e.Graphics.DrawString( "y : " + y, + _font, + Brushes.Black, + new PointF( _mouse_position.X, _mouse_position.Y - 12 ) ); + } + + int label_y = 0; + using ( Font font = new Font( "MS UI Gothic", 9 ) ) { + //ラベルを描画。(必要なら) + switch ( XLabel ) { + case XLabel.Top: + e.Graphics.FillRectangle( new SolidBrush( LabelBackground ), + new Rectangle( 0, 0, this.Width, LABEL_WIDTH ) ); + break; + case XLabel.Bottom: + e.Graphics.FillRectangle( new SolidBrush( LabelBackground ), + new Rectangle( 0, this.Height - LABEL_WIDTH, this.Width, LABEL_WIDTH ) ); + label_y = this.Height - LABEL_WIDTH; + break; + } + if ( XLabel != XLabel.None ) { + for ( int i = start_x; i <= end_x; i++ ) { + float sx = i * place_x; + int px = cX( sx ); + e.Graphics.DrawString( sx.ToString(), font, Brushes.Black, new PointF( px, label_y ) ); + } + } + + int label_x = 0; + switch ( YLabel ) { + case YLabel.Left: + e.Graphics.FillRectangle( + new SolidBrush( LabelBackground ), + new Rectangle( 0, 0, LABEL_WIDTH, this.Height ) ); + break; + case YLabel.Right: + if ( ShowList ) { + label_x = this.Width - LABEL_WIDTH - LIST_WIDTH; + } else { + label_x = this.Width - LABEL_WIDTH; + } + e.Graphics.FillRectangle( + new SolidBrush( LabelBackground ), + new Rectangle( label_x, 0, LABEL_WIDTH, this.Height ) ); + break; + } + if ( YLabel != YLabel.None ) { + for ( int i = start_y; i <= end_y; i++ ) { + float sy = i * place_y; + int py = cY( sy ); + e.Graphics.DrawString( sy.ToString(), font, Brushes.Black, new PointF( label_x, py ) ); + } + } + + //リストを描く + if ( ShowList ) { + e.Graphics.FillRectangle( + new SolidBrush( ListBackground ), + new Rectangle( this.Width - LIST_WIDTH, 0, LIST_WIDTH, this.Height ) ); + e.Graphics.DrawLine( + Pens.Black, + new Point( this.Width - LIST_WIDTH, 0 ), + new Point( this.Width - LIST_WIDTH, this.Height ) ); + int count = 0; + using ( Font labelfont = new Font( "Arial", 12, FontStyle.Bold, GraphicsUnit.Pixel ) ) { + foreach ( string name in m_list.Keys ) { + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; + if ( name == m_selected ) { + e.Graphics.DrawString( + name, + labelfont, + Brushes.White, + new PointF( this.Width - 40, count * 17 + 2 ) ); + } else { + e.Graphics.DrawString( + name, + labelfont, + Brushes.Black, + new PointF( this.Width - 40, count * 17 + 2 ) ); + } + e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; + e.Graphics.FillRectangle( + new SolidBrush( m_list[name].Color ), + new Rectangle( this.Width - 55, count * 17 + 2, 10, 15 ) ); + count++; + } + } + } + } + m_scale_locked = false; + } + + private void CurveEditor_MouseDown( object sender, MouseEventArgs e ) { + m_mouse_moved = false; + if ( e.Button == MouseButtons.Middle || (m_spacekey_down && e.Button == MouseButtons.Left ) ) { + if ( m_spacekey_down && ((e.Button & MouseButtons.Left) == MouseButtons.Left) ) { + m_drag_with_space_key = true; + } + #region MouseButtons.Middle + if ( ScrollEnabled ) { + switch ( XLabel ) { + case XLabel.Top: + if ( e.Y <= LABEL_WIDTH ) { + return; + } + break; + case XLabel.Bottom: + if ( this.Height - LABEL_WIDTH <= e.Y ) { + return; + } + break; + } + switch ( YLabel ) { + case YLabel.Left: + if ( e.X <= LABEL_WIDTH ) { + return; + } + if ( ShowList && this.Width - LIST_WIDTH <= e.X ) { + return; + } + break; + case YLabel.Right: + if ( ShowList ) { + if ( this.Width - LIST_WIDTH - LABEL_WIDTH <= e.X && e.X <= this.Width - LIST_WIDTH ) { + // 軸ラベルの部分でマウスダウン + return; + } else if ( this.Width - LIST_WIDTH <= e.X ) { + // リストの部分でマウスダウン + return; + } + } else { + if ( this.Width - LABEL_WIDTH <= e.X ) { + return; + } + } + break; + } + m_drag_start = e.Location; + m_old_xoffset = m_xoffset; + m_old_yoffset = m_yoffset; + Drag = true; + } + #endregion + } else if ( e.Button == MouseButtons.Left ) { + #region MouseButtons.Left + + #region リスト + // 右のリストの部分がクリックされたかどうかを検査 + if ( ShowList && this.Width - LIST_WIDTH <= e.X ) { + int count = 0; + + foreach ( string name in m_list.Keys ) { + Rectangle active = new Rectangle( this.Width - 55, count * 17, 50, 16 ); + if ( active.X <= e.X && e.X <= active.X + active.Width && + active.Y <= e.Y && e.Y <= active.Y + active.Height ) { + m_selected = name; + if ( RescaleYEnabled ) { + /*float min, max; + m_list[m_selected].GetMinMax( out min, out max ); +#if DEBUG + LipSync.Common.DebugWriteLine( "min,max=" + min + "," + max ); +#endif + if ( min != max ) { + float dif = max - min; + YScale = this.GraphSize.Height / (dif * 1.1f); + float new_offset; + if ( XLabel == XLabel.Bottom ) { + new_offset = -(min - dif * 0.05f - LABEL_WIDTH / YScale); + } else { + new_offset = -min + dif * 0.05f; + } + YOffset = new_offset; + }*/ + YScale = m_list_minmax[m_selected].Scale; + YOffset = m_list_minmax[m_selected].Offset; + } + this.Invalidate(); + return; + } + count++; + } + m_selected = ""; + this.Invalidate(); + return; + } + + #endregion + + #region スケール部分 + if ( XLabel == XLabel.Top ) { + if ( 0 <= e.Y && e.Y <= LABEL_WIDTH ) { + m_change_xscale = true; + m_change_origin = e.X; + m_old_scale = XScale; + return; + } + } else if ( XLabel == XLabel.Bottom ) { + if ( this.Height - LABEL_WIDTH <= e.Y && e.Y <= this.Height ) { + m_change_xscale = true; + m_change_origin = e.X; + m_old_scale = XScale; + return; + } + } + + if ( YLabel == YLabel.Left ) { + if ( 0 <= e.X && e.X <= LABEL_WIDTH ) { + m_change_yscale = true; + m_change_origin = e.Y; + m_old_scale = YScale; + return; + } + } else if ( YLabel == YLabel.Right ) { + if ( ShowList ) { + if ( this.Width - LIST_WIDTH - LABEL_WIDTH <= e.X && e.X <= this.Width - LIST_WIDTH ) { + m_change_yscale = true; + m_change_origin = e.Y; + m_old_scale = YScale; + return; + } + } else { + if ( this.Width - LABEL_WIDTH <= e.X && e.X <= this.Width ) { + m_change_yscale = true; + m_change_origin = e.Y; + m_old_scale = YScale; + return; + } + } + } + + #endregion + + #region マウス位置のデータ点を検索 + + DetectSelectedPoint( e.Location, out m_picked_point_id, out m_picked_side ); +#if DEBUG + Common.DebugWriteLine( "CureveEditor_MouseDown" ); + Common.DebugWriteLine( " m_picked_point_id=" + m_picked_point_id ); + Common.DebugWriteLine( " m_picked_side=" + m_picked_side ); +#endif + if ( m_picked_point_id >= 0 ) { + if ( m_picked_side == PickedSide.Base ) { + m_before_edit = m_list[m_selected][m_picked_point_id].Base; + } else if ( m_picked_side == PickedSide.Left ) { + m_before_edit = m_list[m_selected][m_picked_point_id].ControlLeft; + } else { + m_before_edit = m_list[m_selected][m_picked_point_id].ControlRight; + } + _number_visible = true; + m_mouse_down_mode = MouseDownMode.MovePoint; + Invalidate(); + } else { + m_mouse_down_mode = MouseDownMode.Nothing; + } + + #endregion + #endregion + } + } + + /// + /// カーブエディタ画面上の指定された点にあるデータ点を調べます。 + /// + /// + /// + /// + private void DetectSelectedPoint( Point e, out int picked_point_id, out PickedSide picked_side ) { + picked_point_id = -1; + picked_side = PickedSide.Base; + if ( m_selected != "" ) { + Rectangle active; + Point pt; + for ( int i = 0; i < m_list[m_selected].List.Count; i++ ) { + pt = cPoint( m_list[m_selected].List[i].Base ); + int width = m_data_point_size; + pt = new Point( pt.X - width - 1, pt.Y - width - 1 ); + active = new Rectangle( pt, new Size( width * 2 + 2, width * 2 + 2 ) ); + if ( active.X <= e.X && e.X <= active.X + active.Width && + active.Y <= e.Y && e.Y <= active.Y + active.Height ) { + picked_point_id = m_list[m_selected].List[i].ID; + picked_side = PickedSide.Base; + //m_before_edit = m_list[m_selected][i].Base; + //m_mouse_upped = false; + //_number_visible = true; + return; + } + + pt = cPoint( m_list[m_selected].List[i].ControlLeft ); + width = m_control_point_size; + pt = new Point( pt.X - width - 1, pt.Y - width - 1 ); + active = new Rectangle( pt, new Size( width * 2 + 2, width * 2 + 2 ) ); + if ( active.X <= e.X && e.X <= active.X + active.Width && + active.Y <= e.Y && e.Y <= active.Y + active.Height ) { + picked_point_id = m_list[m_selected].List[i].ID; + picked_side = PickedSide.Left; + //m_before_edit = m_list[m_selected][i].ControlLeft; + //m_mouse_upped = false; + //_number_visible = true; + return; + } + pt = cPoint( m_list[m_selected].List[i].ControlRight ); + width = m_control_point_size; + pt = new Point( pt.X - width - 1, pt.Y - width - 1 ); + active = new Rectangle( pt, new Size( width * 2 + 2, width * 2 + 2 ) ); + if ( active.X <= e.X && e.X <= active.X + active.Width && + active.Y <= e.Y && e.Y <= active.Y + active.Height ) { + picked_point_id = m_list[m_selected].List[i].ID; + picked_side = PickedSide.Right; + //m_before_edit = m_list[m_selected][i].ControlRight; + //m_mouse_upped = false; + //_number_visible = true; + return; + } + } + //m_picked_point = -1; + //m_mouse_upped = true; + } + } + + private void CurveEditor_MouseUp( object sender, MouseEventArgs e ) { + Drag = false; + m_drag_with_space_key = false; + if ( m_selected != "" && m_mouse_down_mode == MouseDownMode.MovePoint && m_picked_point_id >= 0 && m_mouse_moved ) { + PointF new_pt = m_list[m_selected][m_picked_point_id].GetPosition( m_picked_side ); + Command run = Command.GCommandEditPosition( m_selected, m_picked_point_id, m_picked_side, new_pt ); + m_list[m_selected][m_picked_point_id].SetPosition( m_picked_side, m_before_edit ); + Register( Execute( run ) ); + this.Invalidate(); + } + m_mouse_down_mode = MouseDownMode.Nothing; + + m_change_xscale = false; + m_change_yscale = false; + + _number_visible = false; + } + + private void CurveEditor_MouseMove( object sender, MouseEventArgs e ) { + m_mouse_moved = true; + _mouse_position = e.Location; + if ( Drag ) { + bool drag_ok = false; + if ( m_drag_with_space_key ) { + if ( m_spacekey_down ) { + drag_ok = true; + } + } else { + drag_ok = true; + } + if ( drag_ok && m_selected != "" ) { + int dx = e.X - m_drag_start.X; + int dy = m_drag_start.Y - e.Y; + XOffset = m_old_xoffset + dx / m_xscale; + YOffset = m_old_yoffset + dy / m_yscale; + m_list_minmax[m_selected].Offset = YOffset; + this.Invalidate(); + } + } else if ( m_picked_point_id >= 0 && m_mouse_down_mode == MouseDownMode.MovePoint ) { + PointF new_pt = sPoint( e.Location ); + BezierPoint bp = m_list[m_selected][m_picked_point_id]; + int centre = m_list[m_selected].GetIndexFromId( m_picked_point_id ); + int left_id = m_list[m_selected].GetIdFromIndex( centre - 1 ); + int right_id = m_list[m_selected].GetIdFromIndex( centre + 1 ); + switch ( m_picked_side ) { + case PickedSide.Base: + #region PickedSide.Base + if ( 1 <= centre ) { + if ( new_pt.X < m_list[m_selected][left_id].Base.X ) { + new_pt.X = m_list[m_selected][left_id].Base.X; + } + if ( bp.ControlLeftType != ControlType.None ) { + float x1 = m_list[m_selected][left_id].Base.X; + float x2 = m_list[m_selected][left_id].ControlRight.X; + float x3 = new_pt.X + (bp.ControlLeft.X - bp.Base.X); + float x4 = new_pt.X; + if ( !IsBezierImplicit( x1, x2, x3, x4 ) ) { + bp.Base = new PointF( bp.Base.X, new_pt.Y ); + _number = bp.Base; + this.Invalidate(); + return; + } + } + } + if ( centre < m_list[m_selected].Count - 1 ) { + if ( m_list[m_selected][right_id].Base.X < new_pt.X ) { + new_pt.X = m_list[m_selected][right_id].Base.X; + } + if ( bp.ControlRightType != ControlType.None ) { + float x1 = new_pt.X; + float x2 = new_pt.X + (bp.ControlRight.X - bp.Base.X); + float x3 = m_list[m_selected][right_id].ControlLeft.X; + float x4 = m_list[m_selected][right_id].Base.X; + if ( !IsBezierImplicit( x1, x2, x3, x4 ) ) { + bp.Base = new PointF( bp.Base.X, new_pt.Y ); + _number = bp.Base; + this.Invalidate(); + return; + } + } + } + bp.Base = new_pt; + _number = bp.Base; + #endregion + break; + case PickedSide.Right: + #region PickedSide.Right + if ( centre < m_list[m_selected].Count - 1 ) { + float x1 = bp.Base.X; + float x2 = new_pt.X; + float x3 = m_list[m_selected][right_id].ControlLeft.X; + float x4 = m_list[m_selected][right_id].Base.X; + bool is_right = IsBezierImplicit( x1, x2, x3, x4 ); + + bool is_left = true; + float dx = new_pt.X - bp.Base.X; + float dy = new_pt.Y - bp.Base.Y; + float k = 1f; + //if ( bp.ControlRightType == ControlType.Master && m_picked_point >= 1 ) { + if ( bp.ControlRightType != ControlType.None && centre >= 1 ) { + x1 = m_list[m_selected][left_id].Base.X; + x2 = m_list[m_selected][left_id].ControlRight.X; + float dx1 = (bp.ControlLeft.X - bp.Base.X) * XScale; + float dy1 = (bp.ControlLeft.Y - bp.Base.Y) * YScale; + float length = (float)Math.Sqrt( dx1 * dx1 + dy1 * dy1 ); + float tdx = dx * XScale; + float tdy = dy * YScale; + k = length / (float)Math.Sqrt( tdx * tdx + tdy * tdy ); + x3 = bp.Base.X - dx * k; + x4 = bp.Base.X; + is_left = IsBezierImplicit( x1, x2, x3, x4 ); + } + if ( is_right && is_left ) { + bp.ControlRight = new_pt; + _number = bp.ControlRight; + if ( bp.ControlRightType == ControlType.Master && centre >= 1 && bp.ControlLeftType != ControlType.None ) { + bp.ControlLeft = new PointF( bp.Base.X - dx * k, bp.Base.Y - dy * k ); + } + this.Invalidate(); + return; + } else { + if ( centre == 0 ) { + bp.ControlRight = new PointF( bp.ControlRight.X, new_pt.Y ); + _number = bp.ControlRight; + this.Invalidate(); + return; + } else { + //とりあえずnew_ptのyだけ替えてみて再評価してみる + new_pt = new PointF( bp.ControlRight.X, new_pt.Y ); + dx = new_pt.X - bp.Base.X; + dy = new_pt.Y - bp.Base.Y; + x1 = bp.Base.X; + x2 = new_pt.X; + x3 = m_list[m_selected][right_id].ControlLeft.X; + x4 = m_list[m_selected][right_id].Base.X; + is_right = IsBezierImplicit( x1, x2, x3, x4 ); + is_left = true; + if ( bp.ControlRightType == ControlType.Master ) { + x1 = m_list[m_selected][left_id].Base.X; + x2 = m_list[m_selected][left_id].ControlRight.X; + float dx2 = (bp.ControlLeft.X - bp.Base.X) * XScale; + float dy2 = (bp.ControlLeft.Y - bp.Base.Y) * YScale; + float length = (float)Math.Sqrt( dx2 * dx2 + dy2 * dy2 ); + float tdx = dx * XScale; + float tdy = dy * YScale; + k = length / (float)Math.Sqrt( tdx * tdx + tdy * tdy ); + x3 = bp.Base.X - dx * k; + x4 = bp.Base.X; + is_left = IsBezierImplicit( x1, x2, x3, x4 ); + } + if ( is_right && is_left ) { + bp.ControlRight = new PointF( bp.ControlRight.X, new_pt.Y ); + _number = bp.ControlRight; + if ( bp.ControlRightType == ControlType.Master ) { + bp.ControlLeft = new PointF( bp.Base.X - dx * k, bp.Base.Y - dy * k ); + } + this.Invalidate(); + return; + } + } + } + } else { + bp.ControlRight = new_pt; + _number = bp.ControlRight; + } + #endregion + break; + case PickedSide.Left: + #region PickedSide.Left + if ( centre >= 1 ) { + float x1 = m_list[m_selected][left_id].Base.X; + float x2 = m_list[m_selected][left_id].ControlRight.X; + float x3 = new_pt.X; + float x4 = bp.Base.X; + bool is_left = IsBezierImplicit( x1, x2, x3, x4 ); + + bool is_right = true; + float dx = new_pt.X - bp.Base.X; + float dy = new_pt.Y - bp.Base.Y; + float k = 1f; + if ( bp.ControlLeftType != ControlType.None && centre < m_list[m_selected].Count - 1 ) { + //if ( bp.ControlLeftType == ControlType.Master && m_picked_point < m_list[m_selected].Count - 1 ) { + float dx1 = (bp.ControlRight.X - bp.Base.X) * XScale; + float dy1 = (bp.ControlRight.Y - bp.Base.Y) * YScale; + float length = (float)Math.Sqrt( dx1 * dx1 + dy1 * dy1 ); + float tdx = dx * XScale; + float tdy = dy * YScale; + k = length / (float)Math.Sqrt( tdx * tdx + tdy * tdy ); + x1 = bp.Base.X; + x2 = bp.Base.X - dx * k; + x3 = m_list[m_selected][right_id].ControlLeft.X; + x4 = m_list[m_selected][right_id].Base.X; + is_right = IsBezierImplicit( x1, x2, x3, x4 ); + } + if ( is_right && is_left ) { + bp.ControlLeft = new_pt; + _number = bp.ControlLeft; + if ( bp.ControlLeftType == ControlType.Master && centre >= 1 && bp.ControlRightType != ControlType.None ) { + bp.ControlRight = new PointF( bp.Base.X - dx * k, bp.Base.Y - dy * k ); + } + this.Invalidate(); + return; + } else { + if ( centre == m_list[m_selected].Count - 1 ) { + bp.ControlLeft = new PointF( bp.ControlLeft.X, new_pt.Y ); + _number = bp.ControlLeft; + this.Invalidate(); + return; + } else { + //とりあえずnew_ptのyだけ替えてみて再評価してみる + new_pt = new PointF( bp.ControlLeft.X, new_pt.Y ); + dx = new_pt.X - bp.Base.X; + dy = new_pt.Y - bp.Base.Y; + x1 = m_list[m_selected][left_id].Base.X; + x2 = m_list[m_selected][left_id].ControlRight.X; + x3 = new_pt.X; + x4 = bp.Base.X; + is_left = IsBezierImplicit( x1, x2, x3, x4 ); + is_right = true; + if ( bp.ControlLeftType == ControlType.Master ) { + float dx2 = (bp.ControlRight.X - bp.Base.X) * XScale; + float dy2 = (bp.ControlRight.Y - bp.Base.Y) * YScale; + float length = (float)Math.Sqrt( dx2 * dx2 + dy2 * dy2 ); + float tdx = dx * XScale; + float tdy = dy * YScale; + k = length / (float)Math.Sqrt( tdx * tdx + tdy * tdy ); + x1 = bp.Base.X; + x2 = bp.Base.X - dx * k; + x3 = m_list[m_selected][right_id].ControlLeft.X; + x4 = m_list[m_selected][right_id].Base.X; + is_right = IsBezierImplicit( x1, x2, x3, x4 ); + } + if ( is_right && is_left ) { + bp.ControlLeft = new PointF( bp.ControlLeft.X, new_pt.Y ); + _number = bp.ControlLeft; + if ( bp.ControlLeftType == ControlType.Master ) { + bp.ControlRight = new PointF( bp.Base.X - dx * k, bp.Base.Y - dy * k ); + } + this.Invalidate(); + return; + } + } + } + } else { + bp.ControlLeft = new_pt; + _number = bp.ControlLeft; + } + //昔の=> + /*if ( m_picked_point >= 1 ) { + float x1 = m_list[m_selected][m_picked_point - 1].Base.X; + float x2 = m_list[m_selected][m_picked_point - 1].ControlRight.X; + float x3 = new_pt.X; + float x4 = bp.Base.X; + if ( !IsBezierImplicit( x1, x2, x3, x4 ) ) { + bp.ControlLeft = new PointF( bp.ControlLeft.X, new_pt.Y ); + this.Invalidate(); + return; + } + } + bp.ControlLeft = new_pt;*/ + //<=ここまで + #endregion + break; + } + this.Invalidate(); + } else if ( m_change_xscale ) { + float new_scale = m_old_scale * (float)Math.Pow( 10, (e.X - m_change_origin) / CHANGE_SCALE_ORDER ); + if ( new_scale < MinXScale ) { + new_scale = MinXScale; + } else if ( MaxXScale < new_scale ) { + new_scale = MaxXScale; + } + if ( new_scale != XScale ) { + XOffset = (m_change_origin) * (1f / new_scale - 1f / XScale) + XOffset; + XScale = new_scale; + this.Invalidate(); + } + } else if ( m_change_yscale ) { + float new_scale = m_old_scale * (float)Math.Pow( 10, (e.Y - m_change_origin) / CHANGE_SCALE_ORDER ); + if ( new_scale < MinYScale ) { + new_scale = MinYScale; + } else if ( MaxYScale < new_scale ) { + new_scale = MaxYScale; + } + if ( new_scale != YScale ) { + YOffset = m_change_origin * (1f / new_scale - 1f / YScale) + YOffset; + YScale = new_scale; + m_list_minmax[m_selected].Offset = YOffset; + m_list_minmax[m_selected].Scale = YScale; + this.Invalidate(); + } + } + this.Invalidate(); + } + + private void CurveEditor_Resize( object sender, EventArgs e ) { + this.Invalidate(); + } + + private void CurveEditor_MouseDoubleClick( object sender, MouseEventArgs e ) { + if ( m_selected == "" ) { + return; + } + float x = sX( e.X ); + float y = sY( e.Y ); + + int picked_id; + PickedSide picked_side; + DetectSelectedPoint( e.Location, out picked_id, out picked_side ); + if ( picked_id >= 0 ) { + m_picked_point_id = picked_id; + m_picked_side = picked_side; + m_before_edit = m_list[m_selected][m_picked_point_id].GetPosition( m_picked_side ); + using ( LipSync.SetSize dlg = new LipSync.SetSize( + _( "Numeric entry" ), + "x", + "y", + m_before_edit.X, + m_before_edit.Y ) ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + SizeF res = new SizeF( dlg.ResultWidth, dlg.ResultHeight ); + PointF new_pt = new PointF( res.Width, res.Height ); + Command run = Command.GCommandEditPosition( m_selected, m_picked_point_id, m_picked_side, new_pt ); + m_list[m_selected][m_picked_point_id].SetPosition( m_picked_side, m_before_edit ); + Register( Execute( run ) ); + this.Invalidate(); + } + } + } else { + float handle_length; + float slope = 0f; + if ( m_list[m_selected].Count == 0 ) { + handle_length = x * 0.5f; + } else { + int right_point = -1; + //右側の点を検索 + for ( int i = 0; i < m_list[m_selected].List.Count; i++ ) { + if ( x == m_list[m_selected].List[i].Base.X ) { + //xが等しくなる位置にはデータ点を追加できない仕様。 + return; + } + if ( x < m_list[m_selected].List[i].Base.X ) { + right_point = i; + break; + } + } + if ( right_point == -1 ) { + // 最も右 + float dx = Math.Abs( x - m_list[m_selected].List[m_list[m_selected].List.Count - 1].Base.X ); + handle_length = dx / 2; + } else if ( right_point == 0 ) { + float dx = Math.Abs( m_list[m_selected].List[0].Base.X - x ); + handle_length = dx / 2; + } else { + float dx_r = Math.Abs( m_list[m_selected].List[right_point].Base.X - x ); + float dx_l = Math.Abs( x - m_list[m_selected].List[right_point - 1].Base.X ); + handle_length = Math.Min( dx_r, dx_l ) / 2; + slope = (m_list[m_selected].List[right_point].Base.Y - m_list[m_selected].List[right_point - 1].Base.Y) / + (m_list[m_selected].List[right_point].Base.X - m_list[m_selected].List[right_point - 1].Base.X); + } + } + + PointF p_left, p_right; + p_right = new PointF( x + handle_length, y + handle_length * slope ); + p_left = new PointF( x - handle_length, y - handle_length * slope ); + BezierPoint bp = new BezierPoint( new PointF( x, y ), + p_left, + p_right ); + bp.ControlLeftType = m_last_added_type; + bp.ControlRightType = m_last_added_type; + Command run = Command.GCommandAdd( m_selected, bp ); + Register( Execute( run ) ); + m_picked_side = PickedSide.Base; + for ( int i = 0; i < m_list[m_selected].List.Count; i++ ) { + BezierPoint bpoint = m_list[m_selected].List[i]; + if ( x == bpoint.Base.X ) { + m_picked_point_id = bpoint.ID; + break; + } + } + } + this.Invalidate(); + } + + private void CurveEditor_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e ) { + if ( m_selected != "" && m_picked_point_id >= 0 ) { + if ( m_picked_side != PickedSide.Base ) { + switch ( e.KeyCode ) { + case Keys.H: + if ( m_list[m_selected][m_picked_point_id].GetControlType( m_picked_side ) != ControlType.Master ) { + Command run = Command.GCommandChangeType( m_selected, m_picked_point_id, m_picked_side, ControlType.Master ); + Register( Execute( run ) ); + } + break; + case Keys.V: + if ( m_list[m_selected][m_picked_point_id].GetControlType( m_picked_side ) != ControlType.Normal ) { + Command run = Command.GCommandChangeType( m_selected, m_picked_point_id, m_picked_side, ControlType.Normal ); + Register( Execute( run ) ); + } + break; + case Keys.Delete: + if ( m_list[m_selected][m_picked_point_id].GetControlType( m_picked_side ) != ControlType.None ) { + Command run = Command.GCommandChangeType( m_selected, m_picked_point_id, m_picked_side, ControlType.None ); + Register( Execute( run ) ); + } + break; + } + this.Invalidate(); + } else { + ControlType target; + switch ( e.KeyCode ) { + case Keys.H: + target = ControlType.Master; + break; + case Keys.V: + target = ControlType.Normal; + break; + case Keys.Delete: + Command run = Command.GCommandDelete( m_selected, m_picked_point_id ); + Register( Execute( run ) ); + m_picked_point_id = -1; + this.Invalidate(); + return; + default: + return; + } + BezierPoint bpoint = m_list[m_selected][m_picked_point_id]; + if ( bpoint != null ) { + if ( m_list[m_selected][m_picked_point_id].ControlLeftType != target || + m_list[m_selected][m_picked_point_id].ControlRightType != target ) { + BezierPoint bp = m_list[m_selected][m_picked_point_id].Clone(); + bp.ControlLeftType = target; + bp.ControlRightType = target; + Command run = Command.GCommandEdit( m_selected, m_picked_point_id, bp ); + Register( Execute( run ) ); + this.Invalidate(); + } + } + } + } + } + + private Command Execute( Command run ) { +#if DEBUG + Common.DebugWriteLine( "CurveEditor.Execute" ); + /*Common.DebugWriteLine( " before" ); + for ( int i = 0; i < m_list[m_selected].List.Count; i++ ) { + BezierPoint bp = m_list[m_selected].List[i]; + Common.DebugWriteLine( " Base.X=" + bp.Base.X + ", ID=" + bp.ID ); + }*/ +#endif + Command ret = null; + switch ( run.Type ) { + case CommandType.Position: + switch ( run.Side ) { + case PickedSide.Base: + ret = Command.GCommandEditPosition( run.ID, run.PointID, run.Side, m_list[run.ID][run.PointID].Base ); + break; + case PickedSide.Left: + ret = Command.GCommandEditPosition( run.ID, run.PointID, run.Side, m_list[run.ID][run.PointID].ControlLeft ); + break; + case PickedSide.Right: + ret = Command.GCommandEditPosition( run.ID, run.PointID, run.Side, m_list[run.ID][run.PointID].ControlRight ); + break; + } +#if DEBUG + LipSync.Common.DebugWriteLine( " before;Position=" + m_list[run.ID][run.PointID].GetPosition( PickedSide.Base ) ); +#endif + m_list[run.ID][run.PointID].SetPosition( run.Side, run.Position ); +#if DEBUG + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + if ( AppManager.SaveData.m_telop_ex2[i].Text == run.ID ) { + + } + } +#endif + break; + case CommandType.Type: + switch ( run.Side ) { + case PickedSide.Left: + ret = Command.GCommandChangeType( run.ID, run.PointID, run.Side, m_list[run.ID][run.PointID].ControlLeftType ); + m_list[run.ID][run.PointID].ControlLeftType = run.ControlType; + break; + case PickedSide.Right: + ret = Command.GCommandChangeType( run.ID, run.PointID, run.Side, m_list[run.ID][run.PointID].ControlRightType ); + m_list[run.ID][run.PointID].ControlRightType = run.ControlType; + break; + } + break; + case CommandType.Add: + BezierPoint bp = run.BezierPoint.Clone(); + bp.ID = m_list[run.ID].GetNextID(); + ret = Command.GCommandDelete( run.ID, bp.ID ); + m_list[run.ID].Add( bp ); + break; + case CommandType.Delete: + ret = Command.GCommandAdd( run.ID, m_list[run.ID][run.PointID] ); + m_list[run.ID].RemoveAt( run.PointID ); + break; + case CommandType.Edit: + ret = Command.GCommandEdit( run.ID, run.PointID, m_list[run.ID][run.PointID] ); + m_list[run.ID][run.PointID] = run.BezierPoint.Clone(); + break; + default: + return null; + } + if ( this.CurveEdited != null ) { + CurveEdited(); + } +#if DEBUG + /*Common.DebugWriteLine( " after" ); + for ( int i = 0; i < m_list[m_selected].List.Count; i++ ) { + BezierPoint bp = m_list[m_selected].List[i]; + Common.DebugWriteLine( " Base.X=" + bp.Base.X + ", ID=" + bp.ID ); + }*/ +#endif + return ret; + } + + /// + /// アンドゥ処理行います + /// + public void Undo() { + if ( IsUndoAvailable ) { + Command run = m_commands[m_command_position].Clone(); + m_commands[m_command_position] = Execute( run ); + m_command_position--; + this.Invalidate(); + } + } + + /// + /// リドゥ処理行います + /// + public void Redo() { + if ( IsRedoAvailable ) { + Command run = m_commands[m_command_position + 1].Clone(); + m_commands[m_command_position + 1] = Execute( run ); + m_command_position++; + this.Invalidate(); + } + } + + /// + /// リドゥ操作が可能かどうかを表す値を取得します + /// + public bool IsRedoAvailable { + get { + if ( m_command_position + 1 < m_commands.Count ) { + return true; + } else { + return false; + } + } + } + + /// + /// アンドゥ操作が可能かどうかを表す値を取得します + /// + public bool IsUndoAvailable { + get { + if ( 0 > m_command_position ) { + return false; + } else { + return true; + } + } + } + + /// + /// コマンドバッファに指定されたコマンドを登録します + /// + /// + void Register( Command command ) { + if ( m_command_position == m_commands.Count - 1 ) { + // 新しいコマンドバッファを追加する場合 + m_commands.Add( command.Clone() ); + m_command_position = m_commands.Count - 1; + } else { + // 既にあるコマンドバッファを上書きする場合 + m_commands[m_command_position + 1].Dispose(); + m_commands[m_command_position + 1] = command.Clone(); + for ( int i = m_commands.Count - 1; i >= m_command_position + 2; i-- ) { + m_commands.RemoveAt( i ); + } + m_command_position++; + } + } + + private void CurveEditor_KeyDown( object sender, KeyEventArgs e ) { + if ( e.KeyCode == Keys.Space ) { + m_spacekey_down = true; + this.Cursor = HAND; + } else { + m_spacekey_down = false; + this.Cursor = Cursors.Default; + } + } + + private void CurveEditor_KeyUp( object sender, KeyEventArgs e ) { + m_spacekey_down = false; + this.Cursor = Cursors.Default; + } + + void _num_input_FormClosing( object sender, FormClosingEventArgs e ) { + e.Cancel = true; + } + + /// + /// データ点の数値入力用のコンテキストメニューを初期化します + /// + private void InitializeContextMenu() { + if( _cmenu != null ) { + _cmenu.Dispose(); + } + if( _cmenuNumericInput != null ) { + _cmenuNumericInput.Dispose(); + } + _cmenu = new ContextMenuStrip(); + _cmenu.ShowCheckMargin = false; + _cmenu.ShowImageMargin = false; + _cmenuNumericInput = new ToolStripMenuItem(); + _cmenu.Items.AddRange( new ToolStripItem[] { + _cmenuNumericInput} ); + _cmenu.Name = "cmenu"; + _cmenu.Size = new System.Drawing.Size( 135, 26 ); + _cmenu.Font = this.Font; + _cmenuNumericInput.Name = "cmenuNumericInput"; + _cmenuNumericInput.Size = new System.Drawing.Size( 134, 22 ); + _cmenuNumericInput.Text = _( "Numeric entry" ) + "(&N)"; + _cmenuNumericInput.Click += new EventHandler( _cmenuNumericInput_Click ); + } + + void _cmenuNumericInput_Click( object sender, EventArgs e ) { + m_before_edit = m_list[m_selected][m_picked_point_id].GetPosition( m_picked_side ); + using ( LipSync.SetSize dlg = new LipSync.SetSize( + _( "Numeric entry" ), + "x", + "y", + m_before_edit.X, + m_before_edit.Y ) ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + SizeF res = new SizeF( dlg.ResultWidth, dlg.ResultHeight ); + PointF new_pt = new PointF( res.Width, res.Height ); + Command run = Command.GCommandEditPosition( m_selected, m_picked_point_id, m_picked_side, new_pt ); + m_list[m_selected][m_picked_point_id].SetPosition( m_picked_side, m_before_edit ); + Register( Execute( run ) ); + this.Invalidate(); + } + } + } + + private void CurveEditor_MouseClick( object sender, MouseEventArgs e ) { + if ( (e.Button & MouseButtons.Right) == MouseButtons.Right ) { + DetectSelectedPoint( e.Location, out m_picked_point_id, out m_picked_side ); +#if DEBUG + Common.DebugWriteLine( "CureveEditor_MouseClick" ); + Common.DebugWriteLine( " m_picked_point_id=" + m_picked_point_id ); + Common.DebugWriteLine( " m_picked_side=" + m_picked_side ); +#endif + if ( m_picked_point_id >= 0 ) { + InitializeContextMenu(); + _cmenu.Show( this, e.Location ); + _number_visible = false; +#if DEBUG + LipSync.Common.DebugWriteLine( "MouseClick, m_picked_point_id=" + m_picked_point_id ); +#endif + } + } + } + + private void CurveEditor_FontChanged( object sender, EventArgs e ) { + if ( _cmenu != null ) { + _cmenu.Font = this.Font; + } + } + } + + + internal class Command /*: ICloneable*/ { + string m_id; + //int m_picked_index; + PickedSide m_picked_side; + PointF m_new_position; + CommandType m_command_type; + ControlType m_control_type; + BezierPoint m_bp; + //float m_x; + int m_pid; + + public override string ToString() { + return "{ID=" + ID + ", PointID=" + PointID + ", Side=" + Side + ", CommandType=" + Type + ", Position=" + Position + "}"; + } + + public Command Clone() { + Command result = new Command(); + result.m_id = this.m_id; + //result.m_picked_index = this.m_picked_index; + result.m_new_position = this.m_new_position; + result.m_command_type = this.m_command_type; + result.m_control_type = this.m_control_type; + if ( this.m_bp != null ) { + result.m_bp = this.m_bp.Clone(); + } + result.m_pid = this.m_pid; + result.m_picked_side = this.m_picked_side; + return result; + } + + public void Dispose(){ + m_bp = null; + } + + public static Command GCommandEditPosition( string ID, int picked_id, PickedSide picked_side, PointF new_position ) { + Command ret = new Command(); + ret.m_id = ID; + ret.m_pid = picked_id; + ret.m_picked_side = picked_side; + ret.m_new_position = new_position; + ret.m_command_type = CommandType.Position; + ret.m_control_type = ControlType.None; + return ret; + } + + public static Command GCommandChangeType( string ID, int picked_id, PickedSide picked_side, ControlType control_type ){ + Command ret = new Command(); + ret.m_id = ID; + ret.m_pid = picked_id; + ret.m_picked_side = picked_side; + ret.m_command_type = CommandType.Type; + ret.m_control_type = control_type; + return ret; + } + + public static Command GCommandAdd( string ID, BezierPoint point ) { + Command ret = new Command(); + ret.m_id = ID; + if ( point != null ) { + ret.m_bp = (BezierPoint)point.Clone(); + } + ret.m_command_type = CommandType.Add; + return ret; + } + + public static Command GCommandDelete( string ID, /*float*/int pid ) { + Command ret = new Command(); + ret.m_id = ID; + //this.m_x = x; + ret.m_pid = pid; + ret.m_command_type = CommandType.Delete; + return ret; + } + + public static Command GCommandNothing() { + return new Command(); + } + + private Command() { + this.m_command_type = CommandType.None; + } + + public static Command GCommandEdit( string ID, int picked_id, BezierPoint point ) { + Command ret = new Command(); + ret.m_id = ID; + ret.m_pid = picked_id; + if ( point != null ) { + ret.m_bp = (BezierPoint)point.Clone(); + } + ret.m_command_type = CommandType.Edit; + return ret; + } + + public int PointID { + get { + return m_pid; + } + } + + /*public float X { + get { + return m_x; + } + }*/ + + public BezierPoint BezierPoint { + get { + return m_bp; + } + } + + public CommandType Type{ + get{ + return m_command_type; + } + } + + public ControlType ControlType { + get { + return m_control_type; + } + } + + public string ID{ + get{ + return m_id; + } + } + + public PickedSide Side{ + get{ + return m_picked_side; + } + } + + public PointF Position{ + get{ + return m_new_position; + } + } + } + + internal enum CommandType { + Position,//単に位置を変更する + Type,//制御点のタイプを変更する + Add, + Delete, + None, + Edit, + } + + + public enum PickedSide { + Right, + Base, + Left, + } + + + public enum PointType { + Circle, + Rectangle, + } + + public enum XLabel { + None, + Top, + Bottom, + } + + public enum YLabel { + None, + Left, + Right, + } + + [Serializable] + public class BezierChain : IDisposable, ICloneable { + private List list; + private float m_default = 0f; + private Color m_color; + + public bool GetKeyMinMax( out float min, out float max ) { + if ( list.Count == 0 ) { + min = 0f; + max = 0f; + return false; + } + min = float.MaxValue; + max = float.MinValue; + for ( int i = 0; i < list.Count; i++ ) { + min = Math.Min( min, list[i].Base.X ); + max = Math.Max( max, list[i].Base.X ); + } + return true; + } + + public int GetIndexFromId( int id ) { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].ID == id ) { + return i; + } + } + return -1; + } + + public int GetIdFromIndex( int index ) { + if ( 0 <= index && index < list.Count ) { + return list[index].ID; + } + return -1; + } + + public List List { + get { + return list; + } + set { + list = value; + } + } + + [OnDeserialized] + void onDeserialized( StreamingContext sc ) { + for ( int i = 0; i < list.Count; i++ ) { + list[i].ID = i; + list[i].Order = i; + } + } + + public void Sort() { + //list.Sort( new BezierChainOrderIgnoaringComparator() ); + list.Sort(); + for ( int i = 0; i < list.Count; i++ ) { + list[i].Order = i; + } + } + + public void Dispose() { + if ( list != null ) { + list.Clear(); + } + } + + public int GetNextID() { + int max = -1; + for ( int i = 0; i < list.Count; i++ ) { + max = Math.Max( max, list[i].ID ); + } + return max + 1; + } + + public void GetValueMinMax( out float min, out float max ){ + //todo: ベジエが有効なときに、曲線の描く最大値、最小値も考慮 + min = Default; + max = Default; + foreach ( BezierPoint bp in list ) { + min = Math.Min( min, bp.Base.Y ); + max = Math.Max( max, bp.Base.Y ); + } + } + + public object Clone() { + BezierChain result = new BezierChain( this.m_color ); + foreach ( BezierPoint bp in list ) { + result.list.Add( bp.Clone() ); + } + result.m_default = this.m_default; + return result; + } + + public float Default { + get { + return m_default; + } + set { + m_default = value; + } + } + + public BezierChain( Color curve ) { + list = new List(); + m_color = curve; + } + + public BezierPoint this[int id] { + get { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].ID == id ) { + return list[i]; + } + } + return null; + } + set { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].ID == id ) { + list[i] = value; + return; + } + } + throw new Exception( "invalid point id" ); + } + } + + public Color Color { + get { + return m_color; + } + set { + m_color = value; + } + } + + public void Add( BezierPoint bp ) { + if ( list == null ) { + list = new List(); + m_color = Color.Black; + } +#if DEBUG + Common.DebugWriteLine( "BezierChain.Add" ); + Common.DebugWriteLine( " before" ); + for ( int i = 0; i < list.Count; i++ ) { + Common.DebugWriteLine( " Base.X=" + list[i].Base.X + ", Order=" + list[i].Order ); + } +#endif + bool found = false; + for ( int i = 0; i < list.Count - 1; i++ ) { + if ( list[i].Base.X <= bp.Base.X && bp.Base.X < list[i + 1].Base.X ) { + bp.Order = list[i].Order + 1; + for ( int j = i + 1; j < list.Count; j++ ) { + list[j].Order = list[j].Order + 1; + } + found = true; + break; + } + } + if ( !found ) { + if ( list.Count == 0 ){ + bp.Order = 0; + }else{ + bp.Order = list[list.Count - 1].Order + 1; + } + } + list.Add( bp ); + Sort(); +#if DEBUG + Common.DebugWriteLine( "BezierChain.Add" ); + Common.DebugWriteLine( " after" ); + for ( int i = 0; i < list.Count; i++ ) { + Common.DebugWriteLine( " Base.X=" + list[i].Base.X + ", Order=" + list[i].Order ); + } +#endif + } + + public void RemoveAt( int id ) { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].ID == id ) { + list.RemoveAt( i ); + Sort(); + return; + } + } + } + + /*public void RemoveAt( float x ) { + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].Base.X == x ) { + list.RemoveAt( i ); + break; + } + } + }*/ + + public int Count { + get { + if ( list == null ) { + return 0; + } + return list.Count; + } + } + + public float GetValue( float x ) { + for ( int i = 0; i < list.Count - 1; i++ ) { + if ( list[i].Base.X <= x && x <= list[i + 1].Base.X ) { + if ( list[i].ControlRightType == ControlType.None && list[i + 1].ControlLeftType == ControlType.None ) { + PointF p1 = list[i].Base; + PointF p2 = list[i + 1].Base; + float slope = (p2.Y - p1.Y) / (p2.X - p1.X); + return p1.Y + slope * (x - p1.X); + } else { + float x1 = list[i].Base.X; + float x2 = list[i].ControlRight.X; + float x3 = list[i + 1].ControlLeft.X; + float x4 = list[i + 1].Base.X; + float a3 = x4 - 3 * x3 + 3 * x2 - x1; + float a2 = 3 * x3 - 6 * x2 + 3 * x1; + float a1 = 3 * (x2 - x1); + float a0 = x1; + if ( x1 == x ) { + return list[i].Base.Y; + } else if ( x4 == x ) { + return list[i + 1].Base.Y; + } else { + float t = SolveCubicEquation( a3, a2, a1, a0, x ); + x1 = list[i].Base.Y; + x2 = list[i].ControlRight.Y; + x3 = list[i + 1].ControlLeft.Y; + x4 = list[i + 1].Base.Y; + a3 = x4 - 3 * x3 + 3 * x2 - x1; + a2 = 3 * x3 - 6 * x2 + 3 * x1; + a1 = 3 * (x2 - x1); + a0 = x1; + return ((a3 * t + a2) * t + a1) * t + a0; + } + } + } + } + return m_default; + } + + /// + /// 3次方程式a3*x^3 + a2*x^2 + a1*x + a0 = ansの解をニュートン法を使って計算します。ただし、単調増加である必要がある。 + /// + /// + /// + /// + /// + /// + /// + /// + private static float SolveCubicEquation( float a3, float a2, float a1, float a0, float ans ) { + double EPSILON = 1e-9; + double suggested_t = 0.4; + double a3_3 = a3 * 3.0; + double a2_2 = a2 * 2.0; + while ( (a3_3 * suggested_t + a2_2) * suggested_t + a1 == 0.0 ) { + suggested_t += 0.1; + } + double x = suggested_t; + double new_x = suggested_t; + for( int i = 0; i < 5000; i++ ){ + new_x = x - (((a3 * x + a2) * x + a1) * x + a0 - ans) / ((a3_3 * x + a2_2) * x + a1); + if ( Math.Abs( new_x - x ) < EPSILON * new_x ) { + break; + } + x = new_x; + } + return (float)new_x; + } + } + + public enum ControlType { + None, + Normal, + Master, + } + + /// + /// ベジエ曲線を構成するデータ点。 + /// + [Serializable] + public class BezierPoint : IComparable { + PointF m_base; + internal PointF m_control_left; + internal PointF m_control_right; + ControlType m_type_left; + ControlType m_type_right; + [NonSerialized] + int m_id; + [OptionalField] + public int Order; + + public int ID { + get { + return m_id; + } + internal set { + m_id = value; + } + } + + public override string ToString() { + return "m_base=" + m_base.X + "," + m_base.Y + "\n" + + "m_control_left=" + m_control_left.X + "," + m_control_left.Y + "\n" + + "m_control_right=" + m_control_right.X + "," + m_control_right.Y + "\n" + + "m_type_left=" + m_type_left + "\n" + + "m_type_right=" + m_type_right + "\n"; + } + + public BezierPoint( PointF p1, PointF left, PointF right ) { + m_base = p1; + m_control_left = new PointF( left.X - m_base.X, left.Y - m_base.Y ); + m_control_right = new PointF( right.X - m_base.X, right.Y - m_base.Y ); + m_type_left = ControlType.None; + m_type_right = ControlType.None; + } + + public BezierPoint Clone() { + BezierPoint result = new BezierPoint( this.Base, this.ControlLeft, this.ControlRight ); + result.m_control_left = this.m_control_left; + result.m_control_right = this.m_control_right; + result.m_type_left = this.m_type_left; + result.m_type_right = this.m_type_right; + result.Order = this.Order; + result.m_id = this.m_id; + return result; + } + + public int CompareTo( BezierPoint item ) { + if ( this.Base.X > item.Base.X ) { + return 1; + } else if ( this.Base.X < item.Base.X ) { + return -1; + } else { + return this.Order - item.Order; + /*if ( this.ID > item.ID ) { + return 1; + } else if ( this.ID < item.ID ) { + return -1; + } else { + return 0; + }*/ + } + } + + public PointF Base { + get { + return m_base; + } + set { + m_base = value; + } + } + + public void SetPosition( PickedSide picked_side, PointF new_position ) { + if ( picked_side == PickedSide.Base ) { + this.Base = new_position; + } else if ( picked_side == PickedSide.Left ) { + this.m_control_left = new PointF( new_position.X - this.Base.X, new_position.Y - this.Base.Y); + } else { + this.m_control_right = new PointF( new_position.X - this.Base.X, new_position.Y - this.Base.Y ); + } + } + + public PointF GetPosition( PickedSide picked_side ) { + if ( picked_side == PickedSide.Base ) { + return this.Base; + } else if ( picked_side == PickedSide.Left ) { + return this.ControlLeft; + } else { + return this.ControlRight; + } + } + + public ControlType GetControlType( PickedSide picked_side ) { + if ( picked_side == PickedSide.Left ) { + return this.ControlLeftType; + } else if ( picked_side == PickedSide.Right ) { + return this.ControlRightType; + } else { + return ControlType.None; + } + } + + public PointF ControlLeft { + get { + if ( m_type_left != ControlType.None ) { + return new PointF( m_base.X + m_control_left.X, m_base.Y + m_control_left.Y ); + } else { + return m_base; + } + } + set { + m_control_left = new PointF( value.X - m_base.X, value.Y - m_base.Y ); + } + } + + public PointF ControlRight { + get { + if ( m_type_right != ControlType.None ) { + return new PointF( m_base.X + m_control_right.X, m_base.Y + m_control_right.Y ); + } else { + return m_base; + } + } + set { + m_control_right = new PointF( value.X - m_base.X, value.Y - m_base.Y ); + } + } + + public ControlType ControlLeftType { + get { + return m_type_left; + } + set { + m_type_left = value; + } + } + + public ControlType ControlRightType { + get { + return m_type_right; + } + set { + m_type_right = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Common/CurveEditor.designer.cs b/trunk/LipSync/LipSync/Common/CurveEditor.designer.cs new file mode 100644 index 0000000..322262a --- /dev/null +++ b/trunk/LipSync/LipSync/Common/CurveEditor.designer.cs @@ -0,0 +1,68 @@ +/* + * CurveEditor.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace CurveEditor { + partial class CurveEditor { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.SuspendLayout(); + // + // CurveEditor + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.Control; + this.Name = "CurveEditor"; + this.Size = new System.Drawing.Size( 333, 120 ); + this.Paint += new System.Windows.Forms.PaintEventHandler( this.CurveEditor_Paint ); + this.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler( this.CurveEditor_PreviewKeyDown ); + this.MouseMove += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseMove ); + this.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseDoubleClick ); + this.FontChanged += new System.EventHandler( this.CurveEditor_FontChanged ); + this.KeyUp += new System.Windows.Forms.KeyEventHandler( this.CurveEditor_KeyUp ); + this.MouseClick += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseClick ); + this.MouseDown += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseDown ); + this.Resize += new System.EventHandler( this.CurveEditor_Resize ); + this.MouseUp += new System.Windows.Forms.MouseEventHandler( this.CurveEditor_MouseUp ); + this.KeyDown += new System.Windows.Forms.KeyEventHandler( this.CurveEditor_KeyDown ); + this.ResumeLayout( false ); + + } + + #endregion + + + + } +} diff --git a/trunk/LipSync/LipSync/Common/NativeMethods.cs b/trunk/LipSync/LipSync/Common/NativeMethods.cs new file mode 100644 index 0000000..85267d8 --- /dev/null +++ b/trunk/LipSync/LipSync/Common/NativeMethods.cs @@ -0,0 +1,290 @@ +/*================================================================================ + File: NativeMethods.cs + + Summary: This is part of a sample showing how to place Windows Forms controls + inside one of the common file dialogs. +---------------------------------------------------------------------------------- +Copyright (C) Microsoft Corporation. All rights reserved. + +This source code is intended only as a supplement to Microsoft Development Tools +and/or on-line documentation. See these other materials for detailed information +regarding Microsoft code samples. + +This sample is not intended for production use. Code and policy for a production +application must be developed to meet the specific data and security requirements +of the application. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +================================================================================*/ + +using System; +using System.Runtime.InteropServices; +using System.Text; + +namespace ExtensibleDialogs +{ + /// + /// Defines the shape of hook procedures that can be called by the OpenFileDialog + /// + internal delegate IntPtr OfnHookProc( IntPtr hWnd, UInt16 msg, Int32 wParam, Int32 lParam ); + + /// + /// Values that can be placed in the OPENFILENAME structure, we don't use all of them + /// + internal class OpenFileNameFlags + { + public const Int32 ReadOnly = 0x00000001; + public const Int32 OverWritePrompt = 0x00000002; + public const Int32 HideReadOnly = 0x00000004; + public const Int32 NoChangeDir = 0x00000008; + public const Int32 ShowHelp = 0x00000010; + public const Int32 EnableHook = 0x00000020; + public const Int32 EnableTemplate = 0x00000040; + public const Int32 EnableTemplateHandle = 0x00000080; + public const Int32 NoValidate = 0x00000100; + public const Int32 AllowMultiSelect = 0x00000200; + public const Int32 ExtensionDifferent = 0x00000400; + public const Int32 PathMustExist = 0x00000800; + public const Int32 FileMustExist = 0x00001000; + public const Int32 CreatePrompt = 0x00002000; + public const Int32 ShareAware = 0x00004000; + public const Int32 NoReadOnlyReturn = 0x00008000; + public const Int32 NoTestFileCreate = 0x00010000; + public const Int32 NoNetworkButton = 0x00020000; + public const Int32 NoLongNames = 0x00040000; + public const Int32 Explorer = 0x00080000; + public const Int32 NoDereferenceLinks = 0x00100000; + public const Int32 LongNames = 0x00200000; + public const Int32 EnableIncludeNotify = 0x00400000; + public const Int32 EnableSizing = 0x00800000; + public const Int32 DontAddToRecent = 0x02000000; + public const Int32 ForceShowHidden = 0x10000000; + }; + + /// + /// Values that can be placed in the FlagsEx field of the OPENFILENAME structure + /// + internal class OpenFileNameFlagsEx + { + public const Int32 NoPlacesBar = 0x00000001; + }; + + /// + /// A small subset of the window messages that can be sent to the OpenFileDialog + /// These are just the ones that this implementation is interested in + /// + internal class WindowMessage + { + public const UInt16 InitDialog = 0x0110; + public const UInt16 Size = 0x0005; + public const UInt16 Notify = 0x004E; + }; + + /// + /// The possible notification messages that can be generated by the OpenFileDialog + /// We only look for CDN_SELCHANGE + /// + internal class CommonDlgNotification + { + private const UInt16 First = unchecked((UInt16)((UInt16)0 - (UInt16)601)); + + public const UInt16 InitDone = (First - 0x0000); + public const UInt16 SelChange = (First - 0x0001); + public const UInt16 FolderChange = (First - 0x0002); + public const UInt16 ShareViolation = (First - 0x0003); + public const UInt16 Help = (First - 0x0004); + public const UInt16 FileOk = (First - 0x0005); + public const UInt16 TypeChange = (First - 0x0006); + public const UInt16 IncludeItem = (First - 0x0007); + } + + /// + /// Messages that can be send to the common dialogs + /// We only use CDM_GETFILEPATH + /// + internal class CommonDlgMessage { + private const UInt16 User = 0x0400; + private const UInt16 First = User + 100; + private const UInt16 Last = User + 200; + public const UInt16 GetSpec = First; + public const UInt16 GetFilePath = First + 0x0001; + public const UInt16 GetFolderPath = First + 0x0002; + public const UInt16 GetFolderIDList = First + 0x0003; + public const UInt16 SetControlText = First + 0x0004; + public const UInt16 HideControl = First + 0x0005; + public const UInt16 SetDefExt = First + 0x0006; + }; + + /// + /// See the documentation for OPENFILENAME + /// + internal struct OpenFileName + { + public Int32 lStructSize; + public IntPtr hwndOwner; + public IntPtr hInstance; + public IntPtr lpstrFilter; + public IntPtr lpstrCustomFilter; + public Int32 nMaxCustFilter; + public Int32 nFilterIndex; + public IntPtr lpstrFile; + public Int32 nMaxFile; + public IntPtr lpstrFileTitle; + public Int32 nMaxFileTitle; + public IntPtr lpstrInitialDir; + public IntPtr lpstrTitle; + public Int32 Flags; + public Int16 nFileOffset; + public Int16 nFileExtension; + public IntPtr lpstrDefExt; + public Int32 lCustData; + public OfnHookProc lpfnHook; + public IntPtr lpTemplateName; + public IntPtr pvReserved; + public Int32 dwReserved; + public Int32 FlagsEx; + }; + + /// + /// Part of the notification messages sent by the common dialogs + /// + [StructLayout(LayoutKind.Explicit)] + internal struct NMHDR + { + [FieldOffset(0)] public IntPtr hWndFrom; + [FieldOffset(4)] public UInt16 idFrom; + [FieldOffset(8)] public UInt16 code; + }; + + /// + /// Part of the notification messages sent by the common dialogs + /// + [StructLayout(LayoutKind.Explicit)] + internal struct OfNotify + { + [FieldOffset(0)] public NMHDR hdr; + [FieldOffset(12)] public IntPtr ipOfn; + [FieldOffset(16)] public IntPtr ipFile; + }; + + /// + /// Win32 window style constants + /// We use them to set up our child window + /// + internal class DlgStyle + { + public const Int32 DsSetFont = 0x00000040; + public const Int32 Ds3dLook = 0x00000004; + public const Int32 DsControl = 0x00000400; + public const Int32 WsChild = 0x40000000; + public const Int32 WsClipSiblings = 0x04000000; + public const Int32 WsVisible = 0x10000000; + public const Int32 WsGroup = 0x00020000; + public const Int32 SsNotify = 0x00000100; + }; + + /// + /// Win32 "extended" window style constants + /// + internal class ExStyle + { + public const Int32 WsExNoParentNotify = 0x00000004; + public const Int32 WsExControlParent = 0x00010000; + }; + + /// + /// An in-memory Win32 dialog template + /// Note: this has a very specific structure with a single static "label" control + /// See documentation for DLGTEMPLATE and DLGITEMTEMPLATE + /// + [StructLayout(LayoutKind.Sequential)] + internal class DlgTemplate + { + // The dialog template - see documentation for DLGTEMPLATE + public Int32 style = DlgStyle.Ds3dLook | DlgStyle.DsControl | DlgStyle.WsChild | DlgStyle.WsClipSiblings | DlgStyle.SsNotify; + public Int32 extendedStyle = ExStyle.WsExControlParent; + public Int16 numItems = 1; + public Int16 x = 0; + public Int16 y = 0; + public Int16 cx = 0; + public Int16 cy = 0; + public Int16 reservedMenu = 0; + public Int16 reservedClass = 0; + public Int16 reservedTitle = 0; + + // Single dlg item, must be dword-aligned - see documentation for DLGITEMTEMPLATE + public Int32 itemStyle = DlgStyle.WsChild; + public Int32 itemExtendedStyle = ExStyle.WsExNoParentNotify; + public Int16 itemX = 0; + public Int16 itemY = 0; + public Int16 itemCx = 0; + public Int16 itemCy = 0; + public Int16 itemId = 0; + public UInt16 itemClassHdr = 0xffff; // we supply a constant to indicate the class of this control + public Int16 itemClass = 0x0082; // static label control + public Int16 itemText = 0x0000; // no text for this control + public Int16 itemData = 0x0000; // no creation data for this control + }; + + /// + /// The rectangle structure used in Win32 API calls + /// + [StructLayout(LayoutKind.Sequential)] + internal struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + }; + + /// + /// The point structure used in Win32 API calls + /// + [StructLayout(LayoutKind.Sequential)] + internal struct POINT + { + public int X; + public int Y; + }; + + /// + /// Contains all of the p/invoke declarations for the Win32 APIs used in this sample + /// + public class NativeMethods + { + + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + internal static extern IntPtr GetDlgItem( IntPtr hWndDlg, Int16 Id ); + + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + internal static extern IntPtr GetParent( IntPtr hWnd ); + + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + internal static extern IntPtr SetParent( IntPtr hWndChild, IntPtr hWndNewParent ); + + [DllImport("User32.dll", CharSet = CharSet.Unicode)] + internal static extern UInt32 SendMessage( IntPtr hWnd, UInt32 msg, UInt32 wParam, StringBuilder buffer ); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + internal static extern int GetWindowRect( IntPtr hWnd, ref RECT rc ); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + internal static extern int GetClientRect( IntPtr hWnd, ref RECT rc ); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + internal static extern bool ScreenToClient( IntPtr hWnd, ref POINT pt ); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + internal static extern bool MoveWindow( IntPtr hWnd, int X, int Y, int Width, int Height, bool repaint ); + + [DllImport("ComDlg32.dll", CharSet = CharSet.Unicode)] + internal static extern bool GetOpenFileName( ref OpenFileName ofn ); + + [DllImport("ComDlg32.dll", CharSet = CharSet.Unicode)] + internal static extern Int32 CommDlgExtendedError(); + + } +} diff --git a/trunk/LipSync/LipSync/Common/NumericUpDownEx.Designer.cs b/trunk/LipSync/LipSync/Common/NumericUpDownEx.Designer.cs new file mode 100644 index 0000000..158b79a --- /dev/null +++ b/trunk/LipSync/LipSync/Common/NumericUpDownEx.Designer.cs @@ -0,0 +1,45 @@ +/* + * NumericUpDownEx.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class NumericUpDownEx { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + } + + #endregion + } +} diff --git a/trunk/LipSync/LipSync/Common/NumericUpDownEx.cs b/trunk/LipSync/LipSync/Common/NumericUpDownEx.cs new file mode 100644 index 0000000..95a6718 --- /dev/null +++ b/trunk/LipSync/LipSync/Common/NumericUpDownEx.cs @@ -0,0 +1,44 @@ +/* + * NumericUpDownEx.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +//using System.Data; +using System.Text; +using System.Windows.Forms; + +namespace LipSync { + /// + /// MouseWheelでIncrementずつ値を増減させることのできるNumericUpDown + /// + public partial class NumericUpDownEx : NumericUpDown { + public NumericUpDownEx() { + InitializeComponent(); + } + protected override void OnMouseWheel( MouseEventArgs e ) { + decimal new_val; + if ( e.Delta > 0 ) { + new_val = this.Value + this.Increment; + } else if ( e.Delta < 0 ) { + new_val = this.Value - this.Increment; + } else { + return; + } + if ( this.Minimum <= new_val && new_val <= this.Maximum ) { + this.Value = new_val; + } + } + } +} diff --git a/trunk/LipSync/LipSync/Common/OpenFileDialog.cs b/trunk/LipSync/LipSync/Common/OpenFileDialog.cs new file mode 100644 index 0000000..4c180fc --- /dev/null +++ b/trunk/LipSync/LipSync/Common/OpenFileDialog.cs @@ -0,0 +1,506 @@ +/*================================================================================ + File: OpenFileDialog.cs + + Summary: This is part of a sample showing how to place Windows Forms controls + inside one of the common file dialogs. +---------------------------------------------------------------------------------- +Copyright (C) Microsoft Corporation. All rights reserved. + +This source code is intended only as a supplement to Microsoft Development Tools +and/or on-line documentation. See these other materials for detailed information +regarding Microsoft code samples. + +This sample is not intended for production use. Code and policy for a production +application must be developed to meet the specific data and security requirements +of the application. + +THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. +================================================================================*/ + +using System; +using System.Text; +using System.Runtime.InteropServices; +using System.Drawing; +using System.IO; + +namespace ExtensibleDialogs { + /// + /// The extensible OpenFileDialog + /// + public class OpenFileDialog : IDisposable { + // The maximum number of characters permitted in a path + private const int _MAX_PATH = 260; + + // The "control ID" of the content window inside the OpenFileDialog + // See the accompanying article to learn how I discovered it + private const int _CONTENT_PANEL_ID = 0x0461; + + // A constant that determines the spacing between panels inside the OpenFileDialog + private const int _PANEL_GAP_FACTOR = 3; + + /// + /// Clients can implement handlers of this type to catch "selection changed" events + /// + public delegate void SelectionChangedHandler( string path ); + + /// + /// This event is fired whenever the user selects an item in the dialog + /// + public event SelectionChangedHandler SelectionChanged; + + public delegate void FolderChangedHandler( string path ); + public event FolderChangedHandler FolderChanged; + + // unmanaged memory buffers to hold the file name (with and without full path) + private IntPtr _fileNameBuffer; + private IntPtr _fileTitleBuffer; + private IntPtr _initialDirBuffer; + + // user-supplied control that gets placed inside the OpenFileDialog + private System.Windows.Forms.Control _userControl; + + // unmanaged memory buffer that holds the Win32 dialog template + private IntPtr _ipTemplate; + + private string _filter; + private string _fileName; + private string _defaultExtension; + private int _filterIndex; + private short _fileOffset; + private short _fileExtension; + private string _initialDir; + + public string InitialDirectory { + get { + return _initialDir; + } + set { + _initialDir = value; + if ( !Path.IsPathRooted( _initialDir ) ) { + if ( !Directory.Exists( _initialDir ) ) { + _initialDir = Path.GetDirectoryName( _initialDir ); + } + } + _fileName = ""; + UnicodeEncoding ue = new UnicodeEncoding(); + byte[] zero = new byte[2 * _MAX_PATH]; + for ( int i = 0; i < 2 * _MAX_PATH; i++ ) { + zero[i] = 0; + } + Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH ); + Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH ); + if ( _initialDir.Length > 0 ) { + byte[] initial_dir_buffer = ue.GetBytes( _initialDir ); + Marshal.Copy( initial_dir_buffer, 0, _initialDirBuffer, initial_dir_buffer.Length ); + } + } + } + + + public int FilterIndex { + get { + return _filterIndex; + } + set { + _filterIndex = value; + } + } + + + public OpenFileDialog( System.Windows.Forms.Control userControl ) + : this( "", "", "", userControl ) { + } + + + /// + /// Sets up the data structures necessary to display the OpenFileDialog + /// + /// The file extension to use if the user doesn't specify one (no "." required) + /// You can specify a filename to appear in the dialog, although the user can change it + /// See the documentation for the OPENFILENAME structure for a description of filter strings + /// Any Windows Forms control, it will be placed inside the OpenFileDialog + private OpenFileDialog( string defaultExtension, string fileName, string filter, System.Windows.Forms.Control userControl ) { + _filter = filter; + _fileName = fileName; + _defaultExtension = defaultExtension; + + // LipSync Character Config(*.lsc,content.xml)|*.lsc;content.xml|All Files(*.*)|*.* + // ↁE + // LipSync Character Config(*.lsc,content.xml)\0*.lsc;content.xml\0All Files(*.*)\0*.*\0\0 + filter = filter.Replace( "|", "\0" ) + "\0\0"; + + // Need two buffers in unmanaged memory to hold the filename + // Note: the multiplication by 2 is to allow for Unicode (16-bit) characters + _fileNameBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH ); + _fileTitleBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH ); + _initialDirBuffer = Marshal.AllocCoTaskMem( 2 * _MAX_PATH ); + + // Zero these two buffers + byte[] zeroBuffer = new byte[2 * (_MAX_PATH + 1)]; + for ( int i = 0; i < 2 * (_MAX_PATH + 1); i++ ) { + zeroBuffer[i] = 0; + } + Marshal.Copy( zeroBuffer, 0, _fileNameBuffer, 2 * _MAX_PATH ); + Marshal.Copy( zeroBuffer, 0, _fileTitleBuffer, 2 * _MAX_PATH ); + Marshal.Copy( zeroBuffer, 0, _initialDirBuffer, 2 * _MAX_PATH ); + + _filterIndex = 0; + _fileOffset = 0; + _fileExtension = 0; + + // keep a reference to the user-supplied control + _userControl = userControl; + } + + + public string FileName { + get { + return _fileName; + } + set { + if ( value == null ) { + return; + } + _fileName = value; + string folder; + if ( Path.IsPathRooted( _fileName ) ) { + folder = _fileName; + _fileName = ""; + } else { + if ( Directory.Exists( _fileName ) ) { + folder = _fileName; + _fileName = ""; + } else { + if ( _fileName != "" ) { + folder = Path.GetDirectoryName( _fileName ); + } else { + folder = ""; + } + } + } +#if DEBUG + LipSync.Common.DebugWriteLine( "FileName.set(); folder=" + folder ); + LipSync.Common.DebugWriteLine( "FileName.set(); _fileName=" + _fileName ); +#endif + byte[] zero = new byte[2 * _MAX_PATH]; + for ( int i = 0; i < 2 * _MAX_PATH; i++ ) { + zero[i] = 0; + } + Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH ); + Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH ); + + UnicodeEncoding ue = new UnicodeEncoding(); + if ( _fileName.Length > 0 ) { + byte[] file_name_bytes = ue.GetBytes( _fileName ); + Marshal.Copy( file_name_bytes, 0, _fileNameBuffer, file_name_bytes.Length ); + } + + if ( folder.Length > 0 ) { + byte[] initial_dir_bytes = ue.GetBytes( folder ); + Marshal.Copy( initial_dir_bytes, 0, _initialDirBuffer, initial_dir_bytes.Length ); + } +#if DEBUG + LipSync.Common.DebugWriteLine( "FileName.set(); _fileNameBuffer=" + Marshal.PtrToStringUni( _fileNameBuffer ) ); + LipSync.Common.DebugWriteLine( "FileName.set(); _initialDir=" + Marshal.PtrToStringUni( _initialDirBuffer ) ); +#endif + } + } + + + public string Filter { + get { + return _filter; + } + set { + _filter = value; + } + } + + + public string DefaultExt { + get { + return _defaultExtension; + } + set { + _defaultExtension = value; + } + } + + + /// + /// The finalizer will release the unmanaged memory, if I should forget to call Dispose + /// + ~OpenFileDialog() { + Dispose( false ); + } + + + /// + /// Display the OpenFileDialog and allow user interaction + /// + /// true if the user clicked OK, false if they clicked cancel (or close) + public System.Windows.Forms.DialogResult ShowDialog() { + // Create an in-memory Win32 dialog template; this will be a "child" window inside the FileOpenDialog + // We have no use for this child window, except that its presence allows us to capture events when + // the user interacts with the FileOpenDialog + _ipTemplate = BuildDialogTemplate(); + + // Populate the OPENFILENAME structure + // The flags specified are the minimal set to get the appearance and behaviour we need + OpenFileName ofn = new OpenFileName(); + ofn.lStructSize = Marshal.SizeOf( ofn ); + ofn.lpstrFile = _fileNameBuffer; + ofn.nMaxFile = _MAX_PATH; + ofn.lpstrDefExt = Marshal.StringToCoTaskMemUni( _defaultExtension ); + ofn.lpstrFileTitle = _fileTitleBuffer; + ofn.nMaxFileTitle = _MAX_PATH; + string filter = _filter.Replace( "|", "\0" ) + "\0\0"; + ofn.lpstrFilter = Marshal.StringToCoTaskMemUni( filter ); + ofn.Flags = OpenFileNameFlags.EnableHook | OpenFileNameFlags.EnableTemplateHandle | OpenFileNameFlags.EnableSizing | OpenFileNameFlags.Explorer; + ofn.hInstance = _ipTemplate; + ofn.lpfnHook = new OfnHookProc( MyHookProc ); + ofn.lpstrInitialDir = _initialDirBuffer; + ofn.nFilterIndex = _filterIndex; + ofn.nFileOffset = _fileOffset; + ofn.nFileExtension = _fileExtension; + + // copy initial file name into unmanaged memory buffer + UnicodeEncoding ue = new UnicodeEncoding(); + byte[] fileNameBytes = ue.GetBytes( _fileName ); + Marshal.Copy( fileNameBytes, 0, _fileNameBuffer, fileNameBytes.Length ); + Marshal.Copy( fileNameBytes, 0, _initialDirBuffer, fileNameBytes.Length ); + + if ( NativeMethods.GetOpenFileName( ref ofn ) ) { + _fileName = Marshal.PtrToStringUni( _fileNameBuffer ); + _filterIndex = ofn.nFilterIndex; + byte[] file_name_buffer = ue.GetBytes( _fileName ); + Marshal.Copy( file_name_buffer, 0, _initialDirBuffer, file_name_buffer.Length ); + _fileOffset = ofn.nFileOffset; + _fileExtension = ofn.nFileExtension; + return System.Windows.Forms.DialogResult.OK; + } else { + return System.Windows.Forms.DialogResult.Cancel; + } + } + + + /// + /// Builds an in-memory Win32 dialog template. See documentation for DLGTEMPLATE. + /// + /// a pointer to an unmanaged memory buffer containing the dialog template + private IntPtr BuildDialogTemplate() { + // We must place this child window inside the standard FileOpenDialog in order to get any + // notifications sent to our hook procedure. Also, this child window must contain at least + // one control. We make no direct use of the child window, or its control. + + // Set up the contents of the DLGTEMPLATE + DlgTemplate template = new DlgTemplate(); + + // Allocate some unmanaged memory for the template structure, and copy it in + IntPtr ipTemplate = Marshal.AllocCoTaskMem( Marshal.SizeOf( template ) ); + Marshal.StructureToPtr( template, ipTemplate, true ); + return ipTemplate; + } + + + /// + /// The hook procedure for window messages generated by the FileOpenDialog + /// + /// the handle of the window at which this message is targeted + /// the message identifier + /// message-specific parameter data + /// mess-specific parameter data + /// + public IntPtr MyHookProc( IntPtr hWnd, UInt16 msg, Int32 wParam, Int32 lParam ) { + if ( hWnd == IntPtr.Zero ) + return IntPtr.Zero; + + // Behaviour is dependant on the message received + switch ( msg ) { + // We're not interested in every possible message; just return a NULL for those we don't care about + default: { + return IntPtr.Zero; + } + + // WM_INITDIALOG - at this point the OpenFileDialog exists, so we pull the user-supplied control + // into the FileOpenDialog now, using the SetParent API. + case WindowMessage.InitDialog: { + if( _userControl != null ){ + IntPtr hWndParent = NativeMethods.GetParent( hWnd ); + NativeMethods.SetParent( _userControl.Handle, hWndParent ); + } + return IntPtr.Zero; + } + + // WM_SIZE - the OpenFileDialog has been resized, so we'll resize the content and user-supplied + // panel to fit nicely + case WindowMessage.Size: { + FindAndResizePanels( hWnd ); + return IntPtr.Zero; + } + + // WM_NOTIFY - we're only interested in the CDN_SELCHANGE notification message: + // we grab the currently-selected filename and fire our event + case WindowMessage.Notify: { + IntPtr ipNotify = new IntPtr( lParam ); + OfNotify ofNot = (OfNotify)Marshal.PtrToStructure( ipNotify, typeof( OfNotify ) ); + UInt16 code = ofNot.hdr.code; + if ( code == CommonDlgNotification.SelChange ) { + // This is the first time we can rely on the presence of the content panel + // Resize the content and user-supplied panels to fit nicely + FindAndResizePanels( hWnd ); + + // get the newly-selected path + IntPtr hWndParent = NativeMethods.GetParent( hWnd ); + StringBuilder pathBuffer = new StringBuilder( _MAX_PATH ); + UInt32 ret = NativeMethods.SendMessage( hWndParent, CommonDlgMessage.GetFilePath, _MAX_PATH, pathBuffer ); + string path = pathBuffer.ToString(); + + // copy the string into the path buffer + byte[] zero = new byte[2 * _MAX_PATH]; + for ( int i = 0; i < 2 * _MAX_PATH; i++ ) { + zero[i] = 0; + } + Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH ); + UnicodeEncoding ue = new UnicodeEncoding(); + byte[] pathBytes = ue.GetBytes( path ); + Marshal.Copy( pathBytes, 0, _fileNameBuffer, pathBytes.Length ); + + _fileName = path; +#if DEBUG + LipSync.Common.DebugWriteLine( "ExtensibleDialog.OpenFiledialog.MyHookProc; SelChange; _fileName=" + path ); +#endif + // fire selection-changed event + if ( SelectionChanged != null ) { + SelectionChanged( path ); + } + } else if ( code == CommonDlgNotification.FolderChange ) { + // This is the first time we can rely on the presence of the content panel + // Resize the content and user-supplied panels to fit nicely + FindAndResizePanels( hWnd ); + + // get the newly-selected path + IntPtr hWndParent = NativeMethods.GetParent( hWnd ); + StringBuilder pathBuffer = new StringBuilder( _MAX_PATH ); + UInt32 ret = NativeMethods.SendMessage( hWndParent, CommonDlgMessage.GetFolderPath, _MAX_PATH, pathBuffer ); + string path = pathBuffer.ToString(); + + // copy the string into the path buffer + byte[] zero = new byte[2 * _MAX_PATH]; + for ( int i = 0; i < 2 * _MAX_PATH; i++ ) { + zero[i] = 0; + } + Marshal.Copy( zero, 0, _initialDirBuffer, 2 * _MAX_PATH ); + Marshal.Copy( zero, 0, _fileNameBuffer, 2 * _MAX_PATH ); + UnicodeEncoding ue = new UnicodeEncoding(); + byte[] pathBytes = ue.GetBytes( path ); + Marshal.Copy( pathBytes, 0, _initialDirBuffer, pathBytes.Length ); + + // fire selection-changed event + if ( FolderChanged != null ) { + FolderChanged( path ); + } + } + return IntPtr.Zero; + } + } + } + + + /// + /// Layout the content of the OpenFileDialog, according to the overall size of the dialog + /// + /// handle of window that received the WM_SIZE message + private void FindAndResizePanels( IntPtr hWnd ) { + // The FileOpenDialog is actually of the parent of the specified window + IntPtr hWndParent = NativeMethods.GetParent( hWnd ); + + // The "content" window is the one that displays the filenames, tiles, etc. + // The _CONTENT_PANEL_ID is a magic number - see the accompanying text to learn + // how I discovered it. + IntPtr hWndContent = NativeMethods.GetDlgItem( hWndParent, _CONTENT_PANEL_ID ); + + Rectangle rcClient = new Rectangle( 0, 0, 0, 0 ); + Rectangle rcContent = new Rectangle( 0, 0, 0, 0 ); + + // Get client rectangle of dialog + RECT rcTemp = new RECT(); + NativeMethods.GetClientRect( hWndParent, ref rcTemp ); + rcClient.X = rcTemp.left; + rcClient.Y = rcTemp.top; + rcClient.Width = rcTemp.right - rcTemp.left; + rcClient.Height = rcTemp.bottom - rcTemp.top; + + // The content window may not be present when the dialog first appears + if ( hWndContent != IntPtr.Zero ) { + // Find the dimensions of the content panel + RECT rc = new RECT(); + NativeMethods.GetWindowRect( hWndContent, ref rc ); + + // Translate these dimensions into the dialog's coordinate system + POINT topLeft; + topLeft.X = rc.left; + topLeft.Y = rc.top; + NativeMethods.ScreenToClient( hWndParent, ref topLeft ); + POINT bottomRight; + bottomRight.X = rc.right; + bottomRight.Y = rc.bottom; + NativeMethods.ScreenToClient( hWndParent, ref bottomRight ); + rcContent.X = topLeft.X; + rcContent.Width = bottomRight.X - topLeft.X; + rcContent.Y = topLeft.Y; + rcContent.Height = bottomRight.Y - topLeft.Y; + + // Shrink content panel's width + int width = rcClient.Right - rcContent.Left; + if ( _userControl != null ) { + rcContent.Width = (width / 2) + _PANEL_GAP_FACTOR; + } else { + rcContent.Width = width + _PANEL_GAP_FACTOR; + } + NativeMethods.MoveWindow( hWndContent, rcContent.Left, rcContent.Top, rcContent.Width, rcContent.Height, true ); + } + + if( _userControl != null ){ + // Position the user-supplied control alongside the content panel + Rectangle rcUser = new Rectangle( rcContent.Right + (2 * _PANEL_GAP_FACTOR), rcContent.Top, rcClient.Right - rcContent.Right - (3 * _PANEL_GAP_FACTOR), rcContent.Bottom - rcContent.Top ); + NativeMethods.MoveWindow( _userControl.Handle, rcUser.X, rcUser.Y, rcUser.Width, rcUser.Height, true ); + } + } + + /// + /// returns the path currently selected by the user inside the OpenFileDialog + /// + public string SelectedPath { + get { + return Marshal.PtrToStringUni( _fileNameBuffer ); + } + } + + #region IDisposable Members + + public void Dispose() { + Dispose( true ); + } + + /// + /// Free any unamanged memory used by this instance of OpenFileDialog + /// + /// true if called by Dispose, false otherwise + public void Dispose( bool disposing ) { + if ( disposing ) { + GC.SuppressFinalize( this ); + } + + Marshal.FreeCoTaskMem( _fileNameBuffer ); + Marshal.FreeCoTaskMem( _fileTitleBuffer ); + Marshal.FreeCoTaskMem( _initialDirBuffer ); + Marshal.FreeCoTaskMem( _ipTemplate ); + } + + #endregion + } + +} diff --git a/trunk/LipSync/LipSync/EditResx.pl b/trunk/LipSync/LipSync/EditResx.pl new file mode 100644 index 0000000..2d68c6c --- /dev/null +++ b/trunk/LipSync/LipSync/EditResx.pl @@ -0,0 +1,14 @@ +$file = $ARGV[0]; + +$index = rindex( $file, "." ); +$newfile = substr( $file, 0, $index ) . "_.resx"; + +open( FILE, $file ); +open( EDIT, ">" . $newfile ); +while( $line = ){ +# chomp $line; + $line =~ s/[\\]/\//g; + print EDIT $line; +} +close( FILE ); +close( EDIT ); diff --git a/trunk/LipSync/LipSync/Editor/AppManager.cs b/trunk/LipSync/LipSync/Editor/AppManager.cs new file mode 100644 index 0000000..fb4a32d --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/AppManager.cs @@ -0,0 +1,468 @@ +/* + * AppManager.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Windows.Forms; + +namespace LipSync { + + public static class AppManager { + public static bool Playing = false; + public static SettingsEx SaveData; + public static EnvSettings Config; + internal static List m_commands = new List(); + internal static int m_command_position = -1; + private static readonly Bitmap m_author_list = null; + /// + /// telopの描画に必要な最大のトラック数 + /// + public static int MaxTelopLanes = 0; + private static bool m_edited; + + /// + /// Editedプロパティが変更された時発生します + /// + public static event EventHandler EditedChanged; + + #region _AUTHOR_LIST + private const string _AUTHOR_LSIT = "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" + + "MC83dOc2+P8BipnMHXM09SIAAAAASUVORK5CYII="; + #endregion + + /// + /// rectの中にpointが入っているかどうかを判定 + /// + /// + /// + /// + public static bool IsInRectangle( Point point, Rectangle rect ) { + if ( rect.X <= point.X && point.X <= rect.X + rect.Width ) { + if ( rect.Y <= point.Y && point.Y <= rect.Y + rect.Height ) { + return true; + } + } + return false; + } + + public static bool Edited { + get { + return m_edited; + } + set { + bool old = m_edited; + m_edited = value; + if ( EditedChanged != null ) { + EditedChanged( typeof( AppManager ), new EventArgs() ); + } + } + } + + public static string VERSION { + get { +#if DEBUG + return GetAssemblyVersion( typeof( Form1 ) ) + " (build:debug)"; +#else + return GetAssemblyVersion( typeof( Form1 ) ) + " (build:release)"; +#endif + } + } + + private static string GetAssemblyVersion( Type t ) { + Assembly a = Assembly.GetAssembly( t ); + AssemblyFileVersionAttribute afva = (AssemblyFileVersionAttribute)Attribute.GetCustomAttribute( a, typeof( AssemblyFileVersionAttribute ) ); + return afva.Version; + } + + /// + /// pictureBox1の行の表示状態を表す配列を取得します。 + /// + /// + public static int[] GetTimeLineLanes() { + List ret = new List(); + // vsq + if ( SaveData.m_group_vsq.Folded ) { + ret.Add( 1 ); + } else { + ret.Add( SaveData.m_group_vsq.Count + 1 ); + } + // character + for ( int i = 0; i < SaveData.m_groups_character.Count; i++ ) { + if ( SaveData.m_groups_character[i].Folded ) { + ret.Add( 1 ); + } else { + ret.Add( SaveData.m_groups_character[i].Count + 1 ); + } + } + // telop + if ( SaveData.TelopListFolded ) { + ret.Add( 1 ); + } else { + ret.Add( MaxTelopLanes + 1 ); + } + // another image + if ( SaveData.m_group_another.Folded ) { + ret.Add( 1 ); + } else { + ret.Add( SaveData.m_group_another.Count + 1 ); + } + // plugin + if ( SaveData.m_group_plugin.Folded ) { + ret.Add( 1 ); + } else { + ret.Add( SaveData.m_group_plugin.Count + 1 ); + } + return ret.ToArray(); + } + + /// + /// アプリケーションのメイン エントリ ポイントです。 + /// + [STAThread] + static void Main( string[] argv ) { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault( false ); +#if !DEBUG + try { +#endif + string file = ""; + if ( argv.Length > 0 ) { + file = argv[0]; + } + Form1 form1 = null; + if ( File.Exists( file ) ) { + form1 = new Form1( file ); + } else { + form1 = new Form1( "" ); + } + Application.Run( form1 ); + Common.LogClose(); +#if !DEBUG + } catch ( Exception e ) { + Common.LogPush( e ); + Common.LogClose(); + } +#endif + } + + static AppManager() { + using ( MemoryStream ms = new MemoryStream( Convert.FromBase64String( _AUTHOR_LSIT ) ) ) { + m_author_list = new Bitmap( ms ); + } + } + + /// + /// 現在保持しているコマンドバッファをクリアします。 + /// + public static void ClearCommandBuffer() { + m_commands.Clear(); + m_command_position = -1; + } + + /// + /// 次回アンドゥ処理されるコマンドの種類を調べます + /// + /// + public static CommandType GetNextUndoCommandType() { + if ( IsUndoAvailable ) { + return m_commands[m_command_position].type; + } else { + return CommandType.nothing; + } + } + + /// + /// アンドゥ処理を行います + /// + public static void Undo() { + if ( IsUndoAvailable ) { + Command run = m_commands[m_command_position]; + Command inv = SaveData.Execute( run ); + m_commands[m_command_position] = inv; + m_command_position--; + } + } + + /// + /// 次回リドゥ処理されるコマンドの種類を調べます + /// + /// + public static CommandType GetNextRedoCommandType() { + if ( IsRedoAvailable ) { + return m_commands[m_command_position + 1].type; + } else { + return CommandType.nothing; + } + } + + /// + /// リドゥ処理を行います + /// + public static void Redo() { + if ( IsRedoAvailable ) { + Command run = m_commands[m_command_position + 1]; + Command inv = SaveData.Execute( run ); + m_commands[m_command_position + 1] = inv; + m_command_position++; + } + } + + /// + /// リドゥ操作が可能かどうかを表すプロパティ + /// + public static bool IsRedoAvailable { + get { + if ( m_commands.Count > 0 && 0 <= m_command_position + 1 && m_command_position + 1 < m_commands.Count ) { + return true; + } else { + return false; + } + } + } + + /// + /// アンドゥ操作が可能かどうかを表すプロパティ + /// + public static bool IsUndoAvailable { + get { + if ( m_commands.Count > 0 && 0 <= m_command_position && m_command_position < m_commands.Count ) { + return true; + } else { + return false; + } + } + } + + /// + /// コマンドバッファに指定されたコマンドを登録します + /// + /// + public static void Register( Command command ) { + if ( m_command_position == m_commands.Count - 1 ) { + // 新しいコマンドバッファを追加する場合 + m_commands.Add( command ); + m_command_position = m_commands.Count - 1; + } else { + // 既にあるコマンドバッファを上書きする場合 + //m_commands[m_command_position + 1].Dispose(); + m_commands[m_command_position + 1] = command; + for ( int i = m_commands.Count - 1; i >= m_command_position + 2; i-- ) { + m_commands.RemoveAt( i ); + } + m_command_position++; + } + } + + public static Bitmap author_list { + get { + return (Bitmap)m_author_list.Clone(); + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/AviOutput.cs b/trunk/LipSync/LipSync/Editor/AviOutput.cs new file mode 100644 index 0000000..9b86e8a --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/AviOutput.cs @@ -0,0 +1,220 @@ +/* + * AviOutput.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Windows.Forms; +using System.Drawing; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class AviOutput : Form, IMultiLanguageControl { + private bool m_raw_mode = false; + private float m_start = 0f; + private float m_end = 0f; + + public AviOutput( bool raw_mode ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + m_raw_mode = raw_mode; + if ( groupAudio.Enabled ) { + if ( File.Exists( AppManager.SaveData.m_audioFile ) ) { + this.chkMergeAudio.Enabled = true; + } else { + this.chkMergeAudio.Enabled = false; + } + } + if ( m_raw_mode ) { + btnVideoCompression.Enabled = false; + txtDescription.Enabled = false; + } else { + btnVideoCompression.Enabled = true; + txtDescription.Enabled = true; + } + txtFile.Text = AppManager.Config.LastAviPath; + JudgeWritable(); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + btnCancel.Text = _( "Cancel" ); + btnOK.Text = _( "Save" ); + lblFileName.Text = _( "File Name" ); + if ( AppManager.Config.PathFFmpeg != "" && File.Exists( AppManager.Config.PathFFmpeg ) ) { + groupAudio.Text = _( "Audio" ); + groupAudio.Enabled = true; + } else { + groupAudio.Text = _( "Audio" ) + " (" + _( "Set the path of ffmpeg to enable this option" ) + ")"; + groupAudio.Enabled = false; + } + if ( AppManager.Config.PathMEncoder != "" && File.Exists( AppManager.Config.PathMEncoder ) ) { + groupFlv.Text = _( "FLV and MP4" ); + groupFlv.Enabled = true; + } else { + groupFlv.Text = _( "FLV and MP4" ) + " (" + _( "Set the path of mencoder and ffmpeg to enable this option" ) + ")"; + groupFlv.Enabled = false; + } + chkFLV.Text = _( "Convert to FLV" ); + chkMP4.Text = _( "Convert to MP4" ); + chkMergeAudio.Text = _( "Merge WAVE to AVI" ); + chkDeleteIntermediate.Text = _( "Delete Intermediate File" ); + btnVideoCompression.Text = _( "Video Compression" ); + groupStartEnd.Text = _( "Specify Output Range" ); + chkStart.Text = _( "Start" ); + chkEnd.Text = _( "End" ); + checkContainsAlpha.Text = _( "Add Alpha" ); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public AviOutputArguments Arguments { + get { + AviOutputArguments aoa = new AviOutputArguments(); + aoa.AviFile = this.FileName; + aoa.End = m_end; + aoa.EndSpecified = chkEnd.Checked; + aoa.FileNameParser = ""; + aoa.ImageFormat = null; + aoa.IsDeleteIntermediateRequired = chkDeleteIntermediate.Checked; + aoa.IsFlvEncodeRequired = chkFLV.Checked; + aoa.IsMp4EncodeRequired = chkMP4.Checked; + if ( aoa.IsMp4EncodeRequired && aoa.IsFlvEncodeRequired ) { + aoa.IsFlvEncodeRequired = false; + } + aoa.IsTransparent = checkContainsAlpha.Checked; + aoa.IsWaveMergeRequired = chkMergeAudio.Checked; + aoa.Start = m_start; + aoa.StartSpecified = chkStart.Checked; + aoa.UseVfwEncoder = radioVfw.Checked; + return aoa; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + //ディレクトリが存在するかどうかを確認 + string name = FileName; + if ( !Directory.Exists( Path.GetDirectoryName( name ) ) ) { + MessageBox.Show( string.Format( _( "Directory {0} does not exist." ), Path.GetDirectoryName( name ) ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + + //既にファイルが存在することを警告 + if ( File.Exists( name ) ) { + if ( MessageBox.Show( string.Format( _( "{0} already exists.\nDo you want to replace it?" ), name ), + "LipSync", + MessageBoxButtons.YesNo, + MessageBoxIcon.Exclamation ) == DialogResult.No ) { + return; + } + } + try { + m_start = float.Parse( txtStart.Text ); + m_end = float.Parse( txtEnd.Text ); + this.DialogResult = DialogResult.OK; + } catch ( Exception ex ) { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + Common.LogPush( ex ); + } + } + + private string FileName { + get { + if ( Path.GetExtension( txtFile.Text ).ToLower() != ".avi" ) { + string name = txtFile.Text; + txtFile.Text = Path.Combine( Path.GetDirectoryName( name ), Path.GetFileNameWithoutExtension( name ) + ".avi" ); + } + return txtFile.Text; + } + } + + private void btnFile_Click( object sender, EventArgs e ) { + using ( SaveFileDialog dlg = new SaveFileDialog() ) { + if ( AppManager.Config.LastAviPath != "" ) { + try { + dlg.InitialDirectory = Path.GetDirectoryName( AppManager.Config.LastAviPath ); + } catch { + } + } + try { + dlg.Filter = _( "Avi file(*.avi)|*.avi" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Avi file(*.avi)|*.avi|All Files(*.*)|*.*"; + } + dlg.OverwritePrompt = false; + if ( dlg.ShowDialog() == DialogResult.OK ) { + AppManager.Config.LastAviPath = dlg.FileName; + txtFile.Text = dlg.FileName; + JudgeWritable(); + } + } + } + + private void JudgeWritable() { + if ( txtFile.Text != "" ) { + btnOK.Enabled = true; + } else { + btnOK.Enabled = false; + } + } + + private void chkStart_CheckedChanged( object sender, EventArgs e ) { + txtStart.Enabled = chkStart.Checked; + if ( txtStart.Enabled ) { + txtStart.Focus(); + } + } + + private void checkBox1_CheckedChanged( object sender, EventArgs e ) { + txtEnd.Enabled = chkEnd.Checked; + if ( txtEnd.Enabled ) { + txtEnd.Focus(); + } + } + + private void chkFLV_CheckedChanged( object sender, EventArgs e ) { + if ( chkFLV.Checked && chkMP4.Checked ) { + chkMP4.Checked = false; + } + this.chkDeleteIntermediate.Enabled = chkFLV.Checked | chkMP4.Checked | chkMergeAudio.Checked; + } + + private void chkMP4_CheckedChanged( object sender, EventArgs e ) { + if ( chkMP4.Checked && chkFLV.Checked ) { + chkFLV.Checked = false; + } + this.chkDeleteIntermediate.Enabled = chkFLV.Checked | chkMP4.Checked | chkMergeAudio.Checked; + } + + private void chkMergeAudio_CheckedChanged( object sender, EventArgs e ) { + this.chkDeleteIntermediate.Enabled = chkFLV.Checked | chkMP4.Checked | chkMergeAudio.Checked; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/AviOutput.designer.cs b/trunk/LipSync/LipSync/Editor/AviOutput.designer.cs new file mode 100644 index 0000000..dae5946 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/AviOutput.designer.cs @@ -0,0 +1,378 @@ +/* + * AviOutput.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class AviOutput { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.txtFile = new System.Windows.Forms.TextBox(); + this.lblFileName = new System.Windows.Forms.Label(); + this.btnFile = new System.Windows.Forms.Button(); + this.btnVideoCompression = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.chkStart = new System.Windows.Forms.CheckBox(); + this.groupStartEnd = new System.Windows.Forms.GroupBox(); + this.txtEnd = new System.Windows.Forms.TextBox(); + this.txtStart = new System.Windows.Forms.TextBox(); + this.chkEnd = new System.Windows.Forms.CheckBox(); + this.groupFlv = new System.Windows.Forms.GroupBox(); + this.chkMP4 = new System.Windows.Forms.CheckBox(); + this.chkDeleteIntermediate = new System.Windows.Forms.CheckBox(); + this.chkFLV = new System.Windows.Forms.CheckBox(); + this.checkContainsAlpha = new System.Windows.Forms.CheckBox(); + this.txtDescription = new System.Windows.Forms.Label(); + this.groupAudio = new System.Windows.Forms.GroupBox(); + this.chkMergeAudio = new System.Windows.Forms.CheckBox(); + this.groupAviEncoder = new System.Windows.Forms.GroupBox(); + this.radioVcm = new System.Windows.Forms.RadioButton(); + this.radioVfw = new System.Windows.Forms.RadioButton(); + this.groupStartEnd.SuspendLayout(); + this.groupFlv.SuspendLayout(); + this.groupAudio.SuspendLayout(); + this.groupAviEncoder.SuspendLayout(); + this.SuspendLayout(); + // + // txtFile + // + this.txtFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtFile.BackColor = System.Drawing.SystemColors.Window; + this.txtFile.Location = new System.Drawing.Point( 73, 14 ); + this.txtFile.Name = "txtFile"; + this.txtFile.Size = new System.Drawing.Size( 221, 19 ); + this.txtFile.TabIndex = 0; + // + // lblFileName + // + this.lblFileName.AutoSize = true; + this.lblFileName.Location = new System.Drawing.Point( 15, 17 ); + this.lblFileName.Name = "lblFileName"; + this.lblFileName.Size = new System.Drawing.Size( 51, 12 ); + this.lblFileName.TabIndex = 4; + this.lblFileName.Text = "ファイル名"; + // + // btnFile + // + this.btnFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnFile.Location = new System.Drawing.Point( 300, 12 ); + this.btnFile.Name = "btnFile"; + this.btnFile.Size = new System.Drawing.Size( 24, 23 ); + this.btnFile.TabIndex = 1; + this.btnFile.Text = "..."; + this.btnFile.UseVisualStyleBackColor = true; + this.btnFile.Click += new System.EventHandler( this.btnFile_Click ); + // + // btnVideoCompression + // + this.btnVideoCompression.Enabled = false; + this.btnVideoCompression.Location = new System.Drawing.Point( 142, 423 ); + this.btnVideoCompression.Name = "btnVideoCompression"; + this.btnVideoCompression.Size = new System.Drawing.Size( 113, 24 ); + this.btnVideoCompression.TabIndex = 14; + this.btnVideoCompression.Text = "ビデオ圧縮"; + this.btnVideoCompression.UseVisualStyleBackColor = true; + this.btnVideoCompression.Visible = false; + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 246, 381 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 13; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Enabled = false; + this.btnOK.Location = new System.Drawing.Point( 147, 381 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 12; + this.btnOK.Text = "保存"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // chkStart + // + this.chkStart.AutoSize = true; + this.chkStart.Location = new System.Drawing.Point( 35, 18 ); + this.chkStart.Name = "chkStart"; + this.chkStart.Size = new System.Drawing.Size( 48, 16 ); + this.chkStart.TabIndex = 8; + this.chkStart.Text = "開始"; + this.chkStart.UseVisualStyleBackColor = true; + this.chkStart.CheckedChanged += new System.EventHandler( this.chkStart_CheckedChanged ); + // + // groupStartEnd + // + this.groupStartEnd.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupStartEnd.Controls.Add( this.txtEnd ); + this.groupStartEnd.Controls.Add( this.txtStart ); + this.groupStartEnd.Controls.Add( this.chkEnd ); + this.groupStartEnd.Controls.Add( this.chkStart ); + this.groupStartEnd.Location = new System.Drawing.Point( 12, 293 ); + this.groupStartEnd.Name = "groupStartEnd"; + this.groupStartEnd.Size = new System.Drawing.Size( 308, 72 ); + this.groupStartEnd.TabIndex = 7; + this.groupStartEnd.TabStop = false; + this.groupStartEnd.Text = "出力範囲を指定"; + // + // txtEnd + // + this.txtEnd.Enabled = false; + this.txtEnd.Location = new System.Drawing.Point( 103, 40 ); + this.txtEnd.Name = "txtEnd"; + this.txtEnd.Size = new System.Drawing.Size( 144, 19 ); + this.txtEnd.TabIndex = 11; + this.txtEnd.Text = "0"; + // + // txtStart + // + this.txtStart.Enabled = false; + this.txtStart.Location = new System.Drawing.Point( 103, 16 ); + this.txtStart.Name = "txtStart"; + this.txtStart.Size = new System.Drawing.Size( 144, 19 ); + this.txtStart.TabIndex = 9; + this.txtStart.Text = "0"; + // + // chkEnd + // + this.chkEnd.AutoSize = true; + this.chkEnd.Location = new System.Drawing.Point( 35, 42 ); + this.chkEnd.Name = "chkEnd"; + this.chkEnd.Size = new System.Drawing.Size( 48, 16 ); + this.chkEnd.TabIndex = 10; + this.chkEnd.Text = "終了"; + this.chkEnd.UseVisualStyleBackColor = true; + this.chkEnd.CheckedChanged += new System.EventHandler( this.checkBox1_CheckedChanged ); + // + // groupFlv + // + this.groupFlv.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupFlv.Controls.Add( this.chkMP4 ); + this.groupFlv.Controls.Add( this.chkFLV ); + this.groupFlv.Location = new System.Drawing.Point( 13, 148 ); + this.groupFlv.Name = "groupFlv"; + this.groupFlv.Size = new System.Drawing.Size( 311, 72 ); + this.groupFlv.TabIndex = 2; + this.groupFlv.TabStop = false; + this.groupFlv.Text = "FLV"; + // + // chkMP4 + // + this.chkMP4.AutoSize = true; + this.chkMP4.Location = new System.Drawing.Point( 23, 44 ); + this.chkMP4.Name = "chkMP4"; + this.chkMP4.Size = new System.Drawing.Size( 104, 16 ); + this.chkMP4.TabIndex = 4; + this.chkMP4.Text = "Convert to MP4"; + this.chkMP4.UseVisualStyleBackColor = true; + this.chkMP4.CheckedChanged += new System.EventHandler( this.chkMP4_CheckedChanged ); + // + // chkDeleteIntermediate + // + this.chkDeleteIntermediate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.chkDeleteIntermediate.AutoSize = true; + this.chkDeleteIntermediate.Enabled = false; + this.chkDeleteIntermediate.Location = new System.Drawing.Point( 173, 48 ); + this.chkDeleteIntermediate.Name = "chkDeleteIntermediate"; + this.chkDeleteIntermediate.Size = new System.Drawing.Size( 134, 16 ); + this.chkDeleteIntermediate.TabIndex = 3; + this.chkDeleteIntermediate.Text = "中間ファイルを削除する"; + this.chkDeleteIntermediate.UseVisualStyleBackColor = true; + // + // chkFLV + // + this.chkFLV.AutoSize = true; + this.chkFLV.Location = new System.Drawing.Point( 23, 22 ); + this.chkFLV.Name = "chkFLV"; + this.chkFLV.Size = new System.Drawing.Size( 103, 16 ); + this.chkFLV.TabIndex = 2; + this.chkFLV.Text = "Convert to FLV"; + this.chkFLV.UseVisualStyleBackColor = true; + this.chkFLV.CheckedChanged += new System.EventHandler( this.chkFLV_CheckedChanged ); + // + // checkContainsAlpha + // + this.checkContainsAlpha.AutoSize = true; + this.checkContainsAlpha.Location = new System.Drawing.Point( 36, 48 ); + this.checkContainsAlpha.Name = "checkContainsAlpha"; + this.checkContainsAlpha.Size = new System.Drawing.Size( 110, 16 ); + this.checkContainsAlpha.TabIndex = 4; + this.checkContainsAlpha.Text = "アルファ値を含める"; + this.checkContainsAlpha.UseVisualStyleBackColor = true; + // + // txtDescription + // + this.txtDescription.AutoSize = true; + this.txtDescription.Enabled = false; + this.txtDescription.Location = new System.Drawing.Point( 294, 429 ); + this.txtDescription.Name = "txtDescription"; + this.txtDescription.Size = new System.Drawing.Size( 9, 12 ); + this.txtDescription.TabIndex = 19; + this.txtDescription.Text = " "; + this.txtDescription.Visible = false; + // + // groupAudio + // + this.groupAudio.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupAudio.Controls.Add( this.chkMergeAudio ); + this.groupAudio.Location = new System.Drawing.Point( 12, 226 ); + this.groupAudio.Name = "groupAudio"; + this.groupAudio.Size = new System.Drawing.Size( 311, 61 ); + this.groupAudio.TabIndex = 5; + this.groupAudio.TabStop = false; + this.groupAudio.Text = "オーディオ"; + // + // chkMergeAudio + // + this.chkMergeAudio.AutoSize = true; + this.chkMergeAudio.Enabled = false; + this.chkMergeAudio.Location = new System.Drawing.Point( 35, 26 ); + this.chkMergeAudio.Name = "chkMergeAudio"; + this.chkMergeAudio.Size = new System.Drawing.Size( 96, 16 ); + this.chkMergeAudio.TabIndex = 6; + this.chkMergeAudio.Text = "AVIに埋め込む"; + this.chkMergeAudio.UseVisualStyleBackColor = true; + this.chkMergeAudio.CheckedChanged += new System.EventHandler( this.chkMergeAudio_CheckedChanged ); + // + // groupAviEncoder + // + this.groupAviEncoder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupAviEncoder.Controls.Add( this.radioVcm ); + this.groupAviEncoder.Controls.Add( this.radioVfw ); + this.groupAviEncoder.Location = new System.Drawing.Point( 13, 70 ); + this.groupAviEncoder.Name = "groupAviEncoder"; + this.groupAviEncoder.Size = new System.Drawing.Size( 311, 72 ); + this.groupAviEncoder.TabIndex = 20; + this.groupAviEncoder.TabStop = false; + this.groupAviEncoder.Text = "Avi Encoder"; + // + // radioVcm + // + this.radioVcm.AutoSize = true; + this.radioVcm.Location = new System.Drawing.Point( 23, 45 ); + this.radioVcm.Name = "radioVcm"; + this.radioVcm.Size = new System.Drawing.Size( 169, 16 ); + this.radioVcm.TabIndex = 1; + this.radioVcm.TabStop = true; + this.radioVcm.Text = "Video Compression Manager"; + this.radioVcm.UseVisualStyleBackColor = true; + // + // radioVfw + // + this.radioVfw.AutoSize = true; + this.radioVfw.Checked = true; + this.radioVfw.Location = new System.Drawing.Point( 23, 23 ); + this.radioVfw.Name = "radioVfw"; + this.radioVfw.Size = new System.Drawing.Size( 118, 16 ); + this.radioVfw.TabIndex = 0; + this.radioVfw.TabStop = true; + this.radioVfw.Text = "Video for Windows"; + this.radioVfw.UseVisualStyleBackColor = true; + // + // AviOutput + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 335, 421 ); + this.Controls.Add( this.groupAviEncoder ); + this.Controls.Add( this.chkDeleteIntermediate ); + this.Controls.Add( this.checkContainsAlpha ); + this.Controls.Add( this.txtDescription ); + this.Controls.Add( this.groupAudio ); + this.Controls.Add( this.groupFlv ); + this.Controls.Add( this.groupStartEnd ); + this.Controls.Add( this.btnVideoCompression ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnFile ); + this.Controls.Add( this.lblFileName ); + this.Controls.Add( this.txtFile ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "AviOutput"; + this.ShowInTaskbar = false; + this.Text = "AviOutput"; + this.groupStartEnd.ResumeLayout( false ); + this.groupStartEnd.PerformLayout(); + this.groupFlv.ResumeLayout( false ); + this.groupFlv.PerformLayout(); + this.groupAudio.ResumeLayout( false ); + this.groupAudio.PerformLayout(); + this.groupAviEncoder.ResumeLayout( false ); + this.groupAviEncoder.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtFile; + private System.Windows.Forms.Label lblFileName; + private System.Windows.Forms.Button btnFile; + private System.Windows.Forms.Button btnVideoCompression; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.CheckBox chkStart; + private System.Windows.Forms.GroupBox groupStartEnd; + private System.Windows.Forms.TextBox txtEnd; + private System.Windows.Forms.TextBox txtStart; + private System.Windows.Forms.CheckBox chkEnd; + private System.Windows.Forms.GroupBox groupFlv; + private System.Windows.Forms.CheckBox chkDeleteIntermediate; + private System.Windows.Forms.CheckBox chkFLV; + private System.Windows.Forms.GroupBox groupAudio; + private System.Windows.Forms.CheckBox chkMergeAudio; + private System.Windows.Forms.Label txtDescription; + private System.Windows.Forms.CheckBox checkContainsAlpha; + private System.Windows.Forms.CheckBox chkMP4; + private System.Windows.Forms.GroupBox groupAviEncoder; + private System.Windows.Forms.RadioButton radioVfw; + private System.Windows.Forms.RadioButton radioVcm; + } +} diff --git a/trunk/LipSync/LipSync/Editor/AviOutputArguments.cs b/trunk/LipSync/LipSync/Editor/AviOutputArguments.cs new file mode 100644 index 0000000..a650413 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/AviOutputArguments.cs @@ -0,0 +1,32 @@ +/* + * AviOutputArguments.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + public class AviOutputArguments { + public string AviFile = ""; + public float Start = 0f; + public float End = 0f; + public bool StartSpecified = false; + public bool EndSpecified = false; + public bool IsWaveMergeRequired = false; + public bool IsFlvEncodeRequired = false; + public bool IsMp4EncodeRequired = false; + public bool IsDeleteIntermediateRequired = false; + public bool IsTransparent = false; + public string FileNameParser; + public System.Drawing.Imaging.ImageFormat ImageFormat; + public bool UseVfwEncoder = true; + } + +} diff --git a/trunk/LipSync/LipSync/Editor/AviReaderEx.cs b/trunk/LipSync/LipSync/Editor/AviReaderEx.cs new file mode 100644 index 0000000..24e9801 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/AviReaderEx.cs @@ -0,0 +1,47 @@ +/* + * AviReaderEx.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +using Boare.Lib.Media; + +namespace LipSync { + + public class AviReaderEx : AviReader { + private int m_num_openfailed = 0; + + /// + /// aviファイルのOpenに失敗した累積回数を取得します + /// + public int NumFailed { + get { + return m_num_openfailed; + } + } + + + public AviReaderEx() : base() { + m_num_openfailed = 0; + } + + + public new void Open( string file ){ + try { + base.Open( file ); + } catch { + m_num_openfailed++; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/BarLineType.cs b/trunk/LipSync/LipSync/Editor/BarLineType.cs new file mode 100644 index 0000000..7af7074 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/BarLineType.cs @@ -0,0 +1,28 @@ +/* + * BarLineType.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + public struct BarLineType { + public double Time; + public bool IsSeparator; + public bool NeverUseForSnapPoint; + + public BarLineType( double time, bool is_separator, bool never_use_for_snap_point ) { + Time = time; + IsSeparator = is_separator; + NeverUseForSnapPoint = never_use_for_snap_point; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/BugReport.Designer.cs b/trunk/LipSync/LipSync/Editor/BugReport.Designer.cs new file mode 100644 index 0000000..d099432 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/BugReport.Designer.cs @@ -0,0 +1,75 @@ +/* + * BugReport.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class BugReport { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.textBox1 = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Font = new System.Drawing.Font( "MS ゴシック", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)) ); + this.textBox1.Location = new System.Drawing.Point( 12, 49 ); + this.textBox1.Multiline = true; + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 357, 223 ); + this.textBox1.TabIndex = 0; + // + // BugReport + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 381, 284 ); + this.Controls.Add( this.textBox1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "BugReport"; + this.ShowIcon = false; + this.Text = "BugReport"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox textBox1; + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/BugReport.cs b/trunk/LipSync/LipSync/Editor/BugReport.cs new file mode 100644 index 0000000..bce1710 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/BugReport.cs @@ -0,0 +1,84 @@ +/* + * BugReport.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Windows.Forms; + +namespace LipSync { + + public partial class BugReport : Form { + public BugReport() { + InitializeComponent(); + string runtime_version = System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion(); + textBox1.Text = "[ OS ]:" + OsVersion() + Environment.NewLine + + "[.NET runtime]:" + runtime_version + Environment.NewLine + + "[ LipSync ]:v" + AppManager.VERSION; + } + + private static string OsVersion() { + OperatingSystem os = System.Environment.OSVersion; + string version = "(" + os.Version.ToString() + ")"; + switch ( os.Platform ) { + case PlatformID.Win32Windows: + if ( os.Version.Major >= 4 ) { + switch ( os.Version.Minor ) { + case 0: + return "Windows 95" + version; + case 10: + return "Windows 98" + version; + case 90: + return "Windows Me" + version; + } + } + break; + case PlatformID.Win32NT: + switch ( os.Version.Major ) { + case 3: + switch ( os.Version.Minor ) { + case 0: + return "Windows NT 3" + version; + case 1: + return "Windows NT 3.1" + version; + case 5: + return "Windows NT 3.5" + version; + case 51: + return "Windows NT 3.51" + version; + } + break; + case 4: + if ( os.Version.Minor == 0 ) { + return "Windows NT 4.0" + version; + } + break; + case 5: + if ( os.Version.Minor == 0 ) { + return "Windows 2000" + version; + } else if ( os.Version.Minor == 1 ) { + return "Windows XP" + version; + } + break; + case 6: + if ( os.Version.Minor == 0 ) { + return "Windows Vista" + version; + } + break; + } + break; + case PlatformID.Win32S: + return "Win32s" + version; + } + return os.Platform.ToString() + version; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Character.cs b/trunk/LipSync/LipSync/Editor/Character.cs new file mode 100644 index 0000000..dfe2fda --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Character.cs @@ -0,0 +1,300 @@ +/* + * Character.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; + +namespace LipSync { + + public enum CharacterType { + def, + plugin + } + + [Serializable] + public class Character : IDisposable { + public CharacterType type; + string m_Name; + public PluginConfig m_pluginConfig; + public Size m_plugin_drawarea; + + [Obsolete] + public Image Base; + [Obsolete] + public Image a; + [Obsolete] + public Image aa; + [Obsolete] + public Image i; + [Obsolete] + public Image u; + [Obsolete] + public Image e; + [Obsolete] + public Image o; + [Obsolete] + public Image xo; + [Obsolete] + public Image nn; + + public List Images; + [NonSerialized] + private Bitmap m_cache = null; + [NonSerialized] + private string m_cache_draw = ""; + [OptionalField] + public string version;//setDefaultで変更するので、readonlyにしたいけどできん + [OptionalField] + public Size m_size; + [OptionalField] + public Bitmap m_preview = null; + + [NonSerialized] + bool internal_operation = false; + + [OnDeserializing] + private void onDeserializing( StreamingContext sc ) { + version = "0"; + m_size = new Size( 0, 0 ); + } + + [OnSerialized] + private void onSerialized( StreamingContext sc ) { + if ( m_size.Equals( new Size( 0, 0 ) ) ) { + foreach ( ImageEntry img in Images ) { + if ( img.title == "base" ) { + if ( img.Image != null ) { + m_size = new Size( img.Image.Width, img.Image.Height ); + break; + } + } + } + } + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ){ + // 古いバージョンの*.lseとの互換性を保つため。 + // base, a, ..., nnのデータをImagesに移動させる + if ( nn != null ) { + Images.Insert( 0, new ImageEntry( "nn", nn, "口", false ) ); + nn.Dispose(); + } + if ( xo != null ) { + Images.Insert( 0, new ImageEntry( "xo", xo, "口", false ) ); + xo.Dispose(); + } + if ( o != null ) { + Images.Insert( 0, new ImageEntry( "o", o, "口", false ) ); + o.Dispose(); + } + if ( e != null ) { + Images.Insert( 0, new ImageEntry( "e", e, "口", false ) ); + e.Dispose(); + } + if ( u != null ) { + Images.Insert( 0, new ImageEntry( "u", u, "口", false ) ); + u.Dispose(); + } + if ( i != null ) { + Images.Insert( 0, new ImageEntry( "i", i, "口", false ) ); + i.Dispose(); + } + if ( aa != null ) { + Images.Insert( 0, new ImageEntry( "aa", aa, "口", false ) ); + aa.Dispose(); + } + if ( a != null ) { + Images.Insert( 0, new ImageEntry( "a", a, "口", false ) ); + a.Dispose(); + } + if ( Base != null ) { + Images.Insert( 0, new ImageEntry( "base", Base, "本体", true ) ); + Base.Dispose(); + } + if ( version == "0" ) { + for ( int k = 0; k < Images.Count; k++ ) { + if ( Images[k].title == "base" ) { + Images[k].IsDefault = true; + m_size = Images[k].Image.Size; + version = "2"; + } + } + } + + if ( m_size.Width <= 0 || m_size.Height <= 0 ) { + int max_x = 0; + int max_y = 0; + foreach ( ImageEntry img in Images ) { + if ( img.Image != null ) { + max_x = Math.Max( max_x, img.Image.Width + img.XOffset ); + max_y = Math.Max( max_y, img.Image.Height + img.YOffset ); + } + } + m_size = new Size( max_x, max_y ); + } + + } + + public void Dispose() { + m_Name = null; + m_pluginConfig = null; + if ( Base != null ) { + Base.Dispose(); + } + if ( a != null ) { + a.Dispose(); + } + if ( aa != null ) { + aa.Dispose(); + } + if ( i != null ) { + i.Dispose(); + } + if ( u != null ) { + u.Dispose(); + } + if ( e != null ) { + e.Dispose(); + } + if ( o != null ) { + o.Dispose(); + } + if ( xo != null ) { + xo.Dispose(); + } + if ( nn != null ) { + nn.Dispose(); + } + Images.Clear(); + } + + public void Write( Stream stream ) { + BinaryFormatter bf = new BinaryFormatter(); + bf.Serialize( stream, this ); + } + + public string GetMD5() { + System.Security.Cryptography.MD5CryptoServiceProvider mcsp = new System.Security.Cryptography.MD5CryptoServiceProvider(); + using ( MemoryStream ms = new MemoryStream() ) { + this.Write( ms ); + byte[] dat = mcsp.ComputeHash( ms ); + string res = ""; + foreach ( byte b in dat ) { + res += b.ToString( "x2" ); + } + return res; + } + return ""; + } + + public static Character FromFile( Stream stream ) { + Character result = null; + BinaryFormatter bf = new BinaryFormatter(); + result = (Character)bf.Deserialize( stream ); + bf = null; + return result; + } + + public static Character FromFile( string filepath ) { + Character result = null; + if ( File.Exists( filepath ) ) { + using ( FileStream fs = new FileStream( filepath, FileMode.Open ) ) { + result = FromFile( fs ); + } + } + return result; + } + + public int Width { + get { + return m_size.Width; + } + } + + public int Height { + get { + return m_size.Height; + } + } + + public string Name { + get { + return m_Name; + } + set { + m_Name = value; + } + } + + public Bitmap DefaultFace { + get { + string type = ""; + foreach ( ImageEntry img in this.Images ) { + if ( img.IsDefault ) { + type += img.title + "\n"; + } + } + Bitmap res = Face( type ); +#if DEBUG + if ( res == null ) { + Common.DebugWriteLine( "Character.DefaultFace.get(); res==null" ); + Common.DebugWriteLine( " Width=" + Width ); + Common.DebugWriteLine( " Height=" + Height ); + Common.DebugWriteLine( " type=" + type ); + } +#endif + return res; + } + } + + public Bitmap Face( string type ) { + if ( Width <= 0 || Height <= 0 ) { + return null; + } + + if ( m_cache != null ) { + if ( m_cache_draw == type ) { + return (Bitmap)m_cache.Clone(); + } + } + + Bitmap bmp = new Bitmap( Width, Height ); + string[] spl = type.Split( "\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); + using ( Graphics g = Graphics.FromImage( bmp ) ) { + //Image drawing; + for ( int i = 0; i < spl.Length; i++ ) { + for ( int index = 0; index < Images.Count; index++ ) { + if ( Images[index].title == spl[i] ) { + //drawing = Images[index].image; + Images[index].DrawTo( g ); + break; + } + } + } + } + + m_cache_draw = type; + if ( m_cache != null ) { + m_cache.Dispose(); + } + m_cache = (Bitmap)bmp.Clone(); + return bmp; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Character3.cs b/trunk/LipSync/LipSync/Editor/Character3.cs new file mode 100644 index 0000000..11362af --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Character3.cs @@ -0,0 +1,739 @@ +/* + * Character3.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Xml.Serialization; + +using LipSync.Properties; + +namespace LipSync { + + /// + /// キャラクタを取り扱うクラス。 + /// 第3世代 + /// + [Serializable] + public class Character3 : ICloneable, IDisposable { + string m_name; + CharacterType m_type; + ImageEntry[] m_basic = new ImageEntry[9]; + List m_another; + Size m_size; + [NonSerialized] + Bitmap m_cache = null; + [NonSerialized] + int[] m_cache_draw; + string m_author; + string m_version; + PluginConfig m_plugin_config; + bool m_updated = false; // 第2世代のCharacterからアップデートされたものであることを表すフラグ + bool m_is_build_in = false; + /// + /// 使用上の注意など + /// + [OptionalField] + string m_lisence; + + #region public static field + /// + /// ビルトイン・キャラクタ。 + /// + public static readonly Character3 Miku = new Character3( + "Miku", + "さなり", + "", + new ImageEntry[] { + new ImageEntry( "base", Resources.b_miku175_base, "base", true ), + new ImageEntry( "a", Resources.b_miku175_a, "mouth", false ), + new ImageEntry( "aa", Resources.b_miku175_aa, "mouth", false ), + new ImageEntry( "i", Resources.b_miku175_i, "mouth", false ), + new ImageEntry( "u", Resources.b_miku175_u, "mouth", false ), + new ImageEntry( "e", Resources.b_miku175_e, "mouth", false ), + new ImageEntry( "o", Resources.b_miku175_o, "mouth", false ), + new ImageEntry( "xo", Resources.b_miku175_xo, "mouth", false ), + new ImageEntry( "nn", Resources.b_miku175_nn, "mouth", false ) + }, + new ImageEntry[] { + new ImageEntry( "目閉じ", Resources.b_miku175_eyeclose, "eye", false ), + new ImageEntry( "低目にっこり", Resources.b_miku175_smile, "eye", false ), + new ImageEntry( "目半目", Resources.b_miku175_eyethin, "eye", false ), + new ImageEntry( "こなた", Resources.b_miku175_konata, "eye", false ), + new ImageEntry( "><", Resources.b_miku175_kudo, "eye", false ), + new ImageEntry( "哀左ウィンク", Resources.b_miku175_winkleft, "eye", false ), + new ImageEntry( "右ウィンク", Resources.b_miku175_winkright, "eye", false ), + new ImageEntry( "bee", Resources.b_miku175_bee, "mouth", false), + new ImageEntry( "neko", Resources.b_miku175_neko, "mouth", false ) + }, + true + ); + + public static readonly Character3 Rin = new Character3( + "Rin", + "さなり", + "", + new ImageEntry[] { + new ImageEntry( "base", Resources.b_rin100_base, "base",true ), + new ImageEntry( "a", Resources.b_rin100_a, "mouth", false ), + new ImageEntry( "aa", Resources.b_rin100_aa, "mouth", false ), + new ImageEntry( "i", Resources.b_rin100_i, "mouth", false ), + new ImageEntry( "u", Resources.b_rin100_u, "mouth", false ), + new ImageEntry( "e", Resources.b_rin100_e, "mouth", false ), + new ImageEntry( "o", Resources.b_rin100_o, "mouth", false ), + new ImageEntry( "xo", Resources.b_rin100_xo, "mouth", false ), + new ImageEntry( "nn", Resources.b_rin100_nn, "mouth", false ) + }, + new ImageEntry[] { + new ImageEntry( "目閉じ", Resources.b_rin100_eyeclose, "eye", false ), + new ImageEntry( "低目にっこり", Resources.b_rin100_smile, "eye", false ), + new ImageEntry( "目半目", Resources.b_rin100_eyethin, "eye", false ), + new ImageEntry( "><", Resources.b_rin100_kudo, "eye", false ), + new ImageEntry( "哀左ウィンク", Resources.b_rin100_winkleft, "eye", false ), + new ImageEntry( "低右ウィンク", Resources.b_rin100_winkright, "eye" , false), + new ImageEntry( "bee", Resources.b_rin100_bee, "mouth", false ), + new ImageEntry( "neko", Resources.b_rin100_neko, "mouth", false ), + new ImageEntry( "きしし", Resources.b_rin100_kisisi, "mouth", false ) + }, + true + ); + + public static readonly Character3 Len = new Character3( + "Len", + "さなり", + "", + new ImageEntry[] { + new ImageEntry( "base", Resources.b_len100_base, "本体", true ), + new ImageEntry( "a", Resources.b_len100_a, "mouth", false ), + new ImageEntry( "aa", Resources.b_len100_aa, "mouth", false ), + new ImageEntry( "i", Resources.b_len100_i, "mouth", false ), + new ImageEntry( "u", Resources.b_len100_u, "mouth", false ), + new ImageEntry( "e", Resources.b_len100_e, "mouth", false ), + new ImageEntry( "o", Resources.b_len100_o, "mouth", false ), + new ImageEntry( "xo", Resources.b_len100_xo, "mouth", false ), + new ImageEntry( "nn", Resources.b_len100_nn, "mouth", false ) + }, + new ImageEntry[] { + new ImageEntry( "目閉じ", Resources.b_len100_eyeclose, "eye", false ), + new ImageEntry( "低目にっこり", Resources.b_len100_smile, "eye", false ), + new ImageEntry( "目半目", Resources.b_len100_eyethin, "eye", false ), + new ImageEntry( "(`・ω・´)", Resources.b_len100_shakin, "eye", false ), + new ImageEntry( "哀左ウィンク", Resources.b_len100_winkleft, "eye", false ), + new ImageEntry( "中右ウィンク", Resources.b_len100_winkright, "eye", false ), + new ImageEntry( "きしし", Resources.b_len100_kisisi, "mouth", false ) + }, + true + ); + #endregion + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { + SortedList slist = new SortedList(); + foreach ( ImageEntry ie in m_basic ) { + slist.Add( ie.Z, ie.title ); + } + foreach ( ImageEntry ie in m_another ) { + slist.Add( ie.Z, ie.title ); + } + for ( int i = 0; i < slist.Keys.Count; i++ ) { + string title = slist[slist.Keys[i]]; + bool found = false; + for ( int j = 0; j < m_basic.Length; j++ ) { + if ( m_basic[j].title == title ) { + m_basic[j].Z = i; + found = true; + break; + } + } + if ( !found ) { + for ( int j = 0; j < m_another.Count; j++ ) { + if ( m_another[j].title == title ) { + m_another[j].Z = i; + break; + } + } + } + } + } + + public bool IsBuildIn { + get { + return m_is_build_in; + } + } + + public void Remove( string title ) { + for ( int i = 0; i < m_another.Count; i++ ) { + if ( m_another[i].title == title ) { + m_another.RemoveAt( i ); + break; + } + } + } + + public void SetImage( Image img, int index ) { + this[index].SetImage( img ); + } + + public void SetImage( Image img, string title ) { + this[title].SetImage( img ); + } + + public PluginConfig PluginConfig { + get { + return m_plugin_config; + } + set { + m_plugin_config = value; + } + } + + public int Count { + get { + return 9 + m_another.Count; + } + } + + public void Dispose() { + m_basic = null; + m_another.Clear(); + if ( m_cache != null ) { + m_cache.Dispose(); + } + } + + public void Add( ImageEntry item ) { + ImageEntry adding = (ImageEntry)item.Clone(); + adding.Z = this.Count; + m_another.Add( adding ); + } + + public string Version { + get { + return m_version; + } + set { + m_version = value; + } + } + + public string Author { + get { + return m_author; + } + set { + m_author = value; + } + } + + public Character3() { + m_name = ""; + m_type = CharacterType.def; + m_basic = new ImageEntry[9]; + m_basic[0] = new ImageEntry( "base", null, "base", true ); + m_basic[1] = new ImageEntry( "a", null, "mouth", false ); + m_basic[2] = new ImageEntry( "aa", null, "mouth", false ); + m_basic[3] = new ImageEntry( "i", null, "mouth", false ); + m_basic[4] = new ImageEntry( "u", null, "mouth", false ); + m_basic[5] = new ImageEntry( "e", null, "mouth", false ); + m_basic[6] = new ImageEntry( "o", null, "mouth", false ); + m_basic[7] = new ImageEntry( "xo", null, "mouth", false ); + m_basic[8] = new ImageEntry( "nn", null, "mouth", false ); + for ( int i = 0; i < 9; i++ ) { + m_basic[i].Z = i; + } + m_another = new List(); + m_size = new Size(); + m_author = ""; + m_version = ""; + } + + public void Write( Stream s ) { + BinaryFormatter bf = new BinaryFormatter(); + bf.Serialize( s, this ); + } + + public string GetMD5() { + System.Security.Cryptography.MD5CryptoServiceProvider mcsp = new System.Security.Cryptography.MD5CryptoServiceProvider(); + using ( MemoryStream ms = new MemoryStream() ) { + this.Write( ms ); + byte[] dat = mcsp.ComputeHash( ms ); + string res = ""; + foreach ( byte b in dat ) { + res += b.ToString( "x2" ); + } + return res; + } + return ""; + } + + /// + /// ファイルに保存する + /// + /// + /// + public void WriteXml( string path ) { + string f = Path.GetFileName( path ); + if ( f != "content.xml" ) { + return; + } + int width = this.Width; + int height = this.Height; + string base_path = Path.GetDirectoryName( path ); + string image_path = Path.Combine( base_path, "images" ); + if ( !Directory.Exists( image_path ) ) { + Directory.CreateDirectory( Path.Combine( base_path, "images" ) ); + } + using ( FileStream fs = new FileStream( Path.Combine( base_path, "content.xml" ), FileMode.Create ) ) { + XmlSerializer xs = new XmlSerializer( typeof( Character3 ) ); + xs.Serialize( fs, this ); + } + using ( FileStream fs = new FileStream( Path.Combine( base_path, "basic.xml" ), FileMode.Create ) ) { + XmlSerializer xs = new XmlSerializer( typeof( ImageEntry[] ) ); + xs.Serialize( fs, m_basic ); + } + using ( FileStream fs = new FileStream( Path.Combine( base_path, "another.xml" ), FileMode.Create ) ) { + XmlSerializer xs = new XmlSerializer( typeof( List ) ); + xs.Serialize( fs, m_another ); + } + int count = -1; + foreach ( ImageEntry img in this ) { + count++; + if ( img.Image != null ) { + string file = Path.Combine( Path.Combine( base_path, "images" ), img.Z + ".png" ); + Bitmap temp = img.GetImage( width, height ); + temp.Save( file ); + } + } + } + + public Character3( PluginConfig plugin_config ) { + m_name = plugin_config.ID; + m_type = CharacterType.plugin; + m_plugin_config = plugin_config.Clone(); + m_updated = false; + } + + public static Character3 Read( Stream s ) { + BinaryFormatter bf = new BinaryFormatter(); + Character3 res = null; + try { + res = (Character3)bf.Deserialize( s ); + return res; + } catch { + return null; + } + } + + /// + /// xmlファイルからのコンストラクタ + /// + public static Character3 FromXml( string path ) { +#if DEBUG + Common.DebugWriteLine( "Character3.ctor(string);" ); +#endif + Character3 res; + string dir = Path.GetDirectoryName( path ); + using ( FileStream fs = new FileStream( path, FileMode.Open ) ) { + XmlSerializer xs = new XmlSerializer( typeof( Character3 ) ); + res = (Character3)xs.Deserialize( fs ); + } + + using ( FileStream fs = new FileStream( Path.Combine( dir, "basic.xml" ), FileMode.Open ) ) { + XmlSerializer xs = new XmlSerializer( typeof( ImageEntry[] ) ); + res.m_basic = (ImageEntry[])xs.Deserialize( fs ); + } + using ( FileStream fs = new FileStream( Path.Combine( dir, "another.xml" ), FileMode.Open ) ) { + XmlSerializer xs = new XmlSerializer( typeof( List ) ); + res.m_another = (List)xs.Deserialize( fs ); + } + //res.ZReorder(); + for ( int i = 0; i < res.Count; i++ ) { + int z = res[i].Z; + string file = Path.Combine( Path.Combine( dir, "images" ), z + ".png" ); +#if DEBUG + Common.DebugWriteLine( "Character3.ctor(String); file=" + file ); +#endif + if ( File.Exists( file ) ) { + res[i].SetImage( Common.ImageFromFile( file ) ); + } + } +#if DEBUG + Common.DebugWriteLine( "Character3.FromXml()" ); + for ( int i = 0; i < res.Count; i++ ) { + Common.DebugWriteLine( "i=" + i + "; title=" + res[i].title + "; (image==null)=" + (res[i].Image == null) ); + } + Common.DebugWriteLine( "m_size=" + res.m_size ); +#endif + return res; + } + + public static Character3 FromFile( string path ) { + Character3 res; + using ( FileStream fs = new FileStream( path, FileMode.Open ) ) { + BinaryFormatter bf = new BinaryFormatter(); + res = (Character3)bf.Deserialize( fs ); + } + return res; + } + + /// + /// 第2世代目のCharacterからのコンバート + /// + /// + /// + public Character3( Character character ) { + List basic = new List(); + List another = new List(); + string[] titles = new string[] { "base", "a", "aa", "i", "u", "e", "o", "xo", "nn" }; + + // zオーダーを更新しておく + for ( int i = 0; i < character.Images.Count; i++ ) { + character.Images[i].Z = i; + } +#if DEBUG + string t1 = ""; + for ( int i = 0; i < character.Images.Count; i++ ) { + t1 += character.Images[i].ToString() + "\n"; + } + System.Windows.Forms.MessageBox.Show( t1 ); +#endif + foreach ( string title in titles ) { + bool found = false; + foreach ( ImageEntry img in character.Images ) { + if ( img.title == title ) { + ImageEntry cp = new ImageEntry( img.title, null, img.tag, img.IsDefault, img.Z ); + cp.SetImage( img.GetImage() ); + basic.Add( cp ); + found = true; + break; + } + } + if ( !found ) { + if ( title == "base" ) { + basic.Add( new ImageEntry( title, null, "base", true ) ); + } else { + basic.Add( new ImageEntry( title, null, "mouth", false ) ); + } + } + } + + // another + foreach ( ImageEntry img in character.Images ) { + bool is_basic = false; + foreach ( string title in titles ) { + if ( img.title == title ) { + is_basic = true; + break; + } + } + if ( !is_basic ) { + ImageEntry cp = new ImageEntry( img.title, null, img.tag, img.IsDefault, img.Z ); + cp.SetImage( img.GetImage() ); + another.Add( cp ); + } + } + + m_name = character.Name; + m_basic = basic.ToArray(); + m_another = new List( another.ToArray() ); + m_size = character.m_size; + m_type = CharacterType.def; + m_author = ""; + m_version = ""; + m_updated = true; + //ZReorder(); +#if DEBUG + string t = ""; + for ( int i = 0; i < m_basic.Length; i++ ) { + t += m_basic[i].ToString() + "\n"; + } + for ( int i = 0; i < m_another.Count; i++ ) { + t += m_another[i].ToString() + "\n"; + } + System.Windows.Forms.MessageBox.Show( t ); +#endif + } + + [XmlIgnore] + public Bitmap DefaultFace { + get { + List type = new List(); + int count = -1; + foreach ( ImageEntry img in this ) { + count++; + if ( img.IsDefault ) { + type.Add( count ); + } + } + return Face( type.ToArray() ); + } + } + + public IEnumerator GetEnumerator() { + for ( int i = 0; i < m_basic.Length; i++ ) { + yield return m_basic[i]; + } + for ( int i = 0; i < m_another.Count; i++ ) { + yield return m_another[i]; + } + } + + public Bitmap Face( int[] targets ) { + if ( Width <= 0 || Height <= 0 ) { + return null; + } + + // zオーダー順に描画する画像を並べ替える + int[] zorder = new int[targets.Length]; + for ( int i = 0; i < targets.Length; i++ ) { + zorder[i] = this[targets[i]].Z; + } + bool c = true; + while ( c ) { + c = false; + for ( int i = 0; i < targets.Length - 1; i++ ) { + if ( zorder[i] > zorder[i + 1] ) { + int b = targets[i]; + targets[i] = targets[i + 1]; + targets[i + 1] = b; + b = zorder[i]; + zorder[i] = zorder[i + 1]; + zorder[i + 1] = b; + c = true; + } + } + if ( !c ) { + break; + } + } + + // 前回描画したのと同じ描画要求であれば、キャッシュをそのまま返す + if ( m_cache != null && m_cache_draw != null ) { + if ( m_cache_draw.Length == targets.Length ) { + bool match = true; + for ( int i = 0; i < targets.Length; i++ ) { + if ( m_cache_draw[i] != targets[i] ) { + match = false; + break; + } + } + if ( match ) { + return (Bitmap)m_cache.Clone(); + } + } + } + m_cache_draw = targets; + + Bitmap bmp = new Bitmap( Width, Height ); + using ( Graphics g = Graphics.FromImage( bmp ) ) { + for ( int i = 0; i < targets.Length; i++ ) { + ImageEntry img = this[targets[i]]; + if ( img != null ) { + img.DrawTo( g ); + } + } + } + + if ( m_cache != null ) { + m_cache = null; + } + m_cache = (Bitmap)bmp.Clone(); + return bmp; + } + + public ImageEntry this[string title] { + get { + for ( int i = 0; i < m_basic.Length; i++ ) { + if ( m_basic[i].title == title ) { + return m_basic[i]; + } + } + for ( int i = 0; i < m_another.Count; i++ ) { + if ( m_another[i].title == title ) { + return m_another[i]; + } + } + return null; + } + /*set { + for ( int i = 0; i < m_basic.Length; i++ ) { + if ( m_basic[i].title == title ) { + m_basic[i] = value; + } + } + for ( int i = 0; i < m_another.Count; i++ ) { + if ( m_another[i].title == title ) { + m_another[i] = value; + } + } + }*/ + } + + public ImageEntry this[int zorder] { + get { + for ( int i = 0; i < m_basic.Length; i++ ) { + if ( m_basic[i].Z == zorder ) { + return m_basic[i]; + } + } + for ( int i = 0; i < m_another.Count; i++ ) { + if ( m_another[i].Z == zorder ) { + return m_another[i]; + } + } + return null; + } + set { + for ( int i = 0; i < m_basic.Length; i++ ) { + if ( m_basic[i].Z == zorder ) { + m_basic[i] = value; + m_basic[i].Z = zorder; + return; + } + } + for ( int i = 0; i < m_another.Count; i++ ) { + if ( m_another[i].Z == zorder ) { + m_another[i] = value; + m_another[i].Z = zorder; + return; + } + } + } + } + + public Size Size { + get { + if ( m_type == CharacterType.def ) { + return m_size; + } else { + throw new NotImplementedException(); + } + } + set { + m_size = value; + } + } + + [XmlIgnore] + public int Width { + get { + return m_size.Width; + } + } + + [XmlIgnore] + public int Height { + get { + return m_size.Height; + } + } + + public object Clone() { + Character3 res = new Character3(); + res.m_name = m_name; + res.m_author = m_author; + res.m_version = m_version; + res.m_type = m_type; + if ( m_plugin_config != null ) { + res.m_plugin_config = m_plugin_config.Clone(); + } + for ( int i = 0; i < 9; i++ ) { + res.m_basic[i] = (ImageEntry)m_basic[i].Clone(); + } + res.m_another.Clear(); + for ( int i = 0; i < m_another.Count; i++ ) { + res.m_another.Add( (ImageEntry)m_another[i].Clone() ); + } + res.m_updated = m_updated; + res.m_size = m_size; + return res; + } + + private Character3( string name, string author, string version, ImageEntry[] basic, ImageEntry[] another, bool is_build_in ) + : this( name, author, version, basic, another ) { + m_is_build_in = is_build_in; + } + + public Character3( string name, string author, string version, ImageEntry[] basic, ImageEntry[] another ) { + m_type = CharacterType.def; + m_name = name; + m_author = author; + m_version = version; + if ( basic.Length < 9 ) { + throw new ArgumentException( "basic.Length < 9" ); + } + int z = -1; + for ( int i = 0; i < 9; i++ ) { + z++; + m_basic[i] = (ImageEntry)basic[i].Clone(); + m_basic[i].Z = z; + } + if ( another != null ) { + m_another = new List( another ); + } else { + m_another = new List(); + } + for ( int i = 0; i < m_another.Count; i++ ) { + z++; + m_another[i].Z = z; + } + int width = 0; + int height = 0; + if ( basic != null ) { + foreach ( ImageEntry img in basic ) { + if ( img.Image != null ) { + width = Math.Max( width, img.Image.Width ); + height = Math.Max( height, img.Image.Height ); + } + } + } + if ( another != null ) { + foreach ( ImageEntry img in another ) { + if ( img.Image != null ) { + width = Math.Max( width, img.Image.Width ); + height = Math.Max( height, img.Image.Height ); + } + } + } + //ZReorder(); + m_size = new Size( width, height ); + m_updated = false; + } + + /// + /// キャラクタのタイプを取得します + /// + public CharacterType Type { + get { + return m_type; + } + } + + /// + /// キャラクタの名称を取得します + /// + public string Name { + get { + return m_name; + } + set { + m_name = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/CharacterConfigCollection.cs b/trunk/LipSync/LipSync/Editor/CharacterConfigCollection.cs new file mode 100644 index 0000000..89b4d73 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/CharacterConfigCollection.cs @@ -0,0 +1,136 @@ +/* + * CharacterConfigCollection.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; + +namespace LipSync { + + /// + /// キャラクタ設定ファイルのリストを管理するクラス + /// + public static class CharacterConfigCollection { + + /// + /// リストの最大長 + /// + const int MAX_DICT_LEN = 128; + static List m_list = new List(); + + /// + /// IDがidであるキャラクタ設定ファイルがリストに登録されているかどうかを返します + /// + /// + /// + public static bool IsRegistered( string id ) { + foreach ( CharacterConfigSpecifier item in m_list ) { + if ( item.ID == id ) { + return true; + } + } + return false; + } + + + /// + /// 現在のリストの内容を逐次返すiterator + /// + /// + public static IEnumerator GetEnumerator() { + foreach ( CharacterConfigSpecifier item in m_list ) { + yield return item; + } + yield break; + } + + + /// + /// ファイル名がidであるキャラクタ設定ファイルのプレビューを返します.未登録の場合はnullを返します + /// + /// + /// + public static Image GetPreviewImage( string id ) { + foreach ( CharacterConfigSpecifier item in m_list ) { + if ( item.ID == id ) { + return item.Image; + } + } + return null; + } + + + /// + /// ファイル名がfileであるキャラクタ設定ファイルを読み込み,リストに登録します. + /// 既に登録済みであっても,登録された時点よりファイルが新しければ,登録内容を更新します + /// + /// + public static void Register( string file ) { +#if DEBUG + Common.DebugWriteLine( "CharacterConfigCollection.Register(String); m_list.Count=" + m_list.Count ); +#endif + if ( !File.Exists( file ) ) { + return; + } + DateTime date = File.GetLastWriteTimeUtc( file ); + DateTime date_registered = new DateTime(); + int index = -1; + for( int i = 0; i < m_list.Count; i++ ){ + if ( m_list[i].ID == file ) { + index = i; + date_registered = m_list[i].LastModefied; + break; + } + } + + // Character, Character3クラスを読み込んで,登録 + CharacterConfigSpecifier item = null; + if ( Path.GetFileName( file ).ToLower() == "content.xml" ) { + Character3 ch = Character3.FromXml( file ); + item = new CharacterConfigSpecifier( ch, file, File.GetLastWriteTimeUtc( file ) ); + } else { + try { + Character3 ch = Character3.FromFile( file ); + item = new CharacterConfigSpecifier( ch, file, File.GetLastWriteTimeUtc( file ) ); + } catch { + try { + Character t = LipSync.Character.FromFile( file ); + item = new CharacterConfigSpecifier( t, file, File.GetLastWriteTimeUtc( file ) ); + } catch { + item = new CharacterConfigSpecifier( file, File.GetLastWriteTimeUtc( file ) ); + } + } + } + if ( item != null ) { +#if DEBUG + string dir = Path.GetDirectoryName( file ); + Common.GetThumbnailImage( item.Image, 128, 128 ).Save( Path.Combine( dir, Path.GetFileNameWithoutExtension( file ) ) + ".png" ); +#endif + if ( index >= 0 ) { + if ( date > date_registered ) { + m_list.RemoveAt( index ); + if ( m_list.Count > MAX_DICT_LEN ) { + m_list.RemoveAt( 0 ); + } + m_list.Add( item ); + } + } else { + m_list.Add( item ); + } + } + } + + } + +} diff --git a/trunk/LipSync/LipSync/Editor/CharacterConfigSpecifier.cs b/trunk/LipSync/LipSync/Editor/CharacterConfigSpecifier.cs new file mode 100644 index 0000000..bd52768 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/CharacterConfigSpecifier.cs @@ -0,0 +1,95 @@ +/* + * CharacterConfigSpecifier.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + /// + /// キャラクタ設定ファイルを識別するためのクラス + /// + public class CharacterConfigSpecifier { + Image m_preview; + string m_id; + DateTime m_last_modefied; + + const int w = 256; + const int h = 256; + + /// + /// キャラクタ設定ファイルを特定するID.通常はファイルへのフルパス + /// + public string ID { + get { + return m_id; + } + } + + /// + /// キャラクタ設定ファイルの最終更新時刻 + /// + public DateTime LastModefied { + get { + return m_last_modefied; + } + } + + /// + /// キャラクタ設定ファイルのプレビュー + /// + public Image Image { + get { + return m_preview; + } + } + + public CharacterConfigSpecifier( string id, DateTime date ) { + m_id = id; + m_last_modefied = date; + } + + public CharacterConfigSpecifier( Character3 character, string id, DateTime date ) { + if ( character != null ) { + Bitmap bmp = character.DefaultFace; + Rectangle rc = Common.GetNonTransparentRegion( bmp ); + using ( Bitmap t = new Bitmap( rc.Width, rc.Height ) ) + using ( Graphics g = Graphics.FromImage( t ) ) { + g.DrawImage( + bmp, + 0, 0, rc, GraphicsUnit.Pixel ); + m_preview = Common.GetThumbnailImage( t, w, h ); + } + } + m_id = id; + m_last_modefied = date; + } + + public CharacterConfigSpecifier( Character character, string id, DateTime date ) { + if ( character != null ) { + Bitmap bmp = character.DefaultFace; + Rectangle rc = Common.GetNonTransparentRegion( bmp ); + using ( Bitmap t = new Bitmap( rc.Width, rc.Height ) ) + using ( Graphics g = Graphics.FromImage( t ) ) { + g.DrawImage( + bmp, + 0, 0, rc, GraphicsUnit.Pixel ); + m_preview = Common.GetThumbnailImage( t, w, h ); + } + } + m_id = id; + m_last_modefied = date; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/ColorSet.cs b/trunk/LipSync/LipSync/Editor/ColorSet.cs new file mode 100644 index 0000000..3a24365 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ColorSet.cs @@ -0,0 +1,95 @@ +/* + * ColorSet.cs + * Copyright (c) 2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + public class ColorSet { + public int A = 255; + public int R; + public int G; + public int B; + + public ColorSet( int alpha, int red, int green, int blue ) { + if ( red < 0 || 255 < red ) { + throw new ArgumentOutOfRangeException( "red" ); + } + if ( green < 0 || 255 < green ) { + throw new ArgumentOutOfRangeException( "green" ); + } + if ( blue < 0 || 255 < blue ) { + throw new ArgumentOutOfRangeException( "blue" ); + } + if ( alpha < 0 || 255 < alpha ) { + throw new ArgumentOutOfRangeException( "alpha" ); + } + R = red; + G = green; + B = blue; + A = alpha; + } + + public ColorSet() + : this( 255, 255, 255, 255 ) { + } + + public ColorSet( int red, int green, int blue ) + : this( 255, red, green, blue ) { + } + + public ColorSet( Color color ) + : this( color.A, color.R, color.G, color.B ) { + } + + public ColorSet( int alpha, ColorSet color ) + : this( alpha, color.R, color.G, color.B ) { + } + + public ColorSet( int alpha, Color color ) : + this( alpha, color.R, color.G, color.B ) { + } + + public Color Color { + get { + return Color.FromArgb( A, R, G, B ); + } + } + + public override bool Equals( object obj ) { + return Equals( obj, false ); + } + + public bool Equals( object obj, bool ignore_alpha ) { + if ( obj is ColorSet ) { + ColorSet item = (ColorSet)obj; + if ( ignore_alpha ) { + return (item.R == R && item.G == G && item.B == B); + } else { + return (item.A == A && item.R == R && item.G == G && item.B == B); + } + } else if ( obj is Color ) { + Color item = (Color)obj; + if ( ignore_alpha ) { + return (item.R == R && item.G == G && item.B == B); + } else { + return (item.A == A && item.R == R && item.G == G && item.B == B); + } + } else { + return base.Equals( obj ); + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Command.cs b/trunk/LipSync/LipSync/Editor/Command.cs new file mode 100644 index 0000000..2d48d7e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Command.cs @@ -0,0 +1,316 @@ +/* + * Command.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + public class Command { + public TimeTableType target; + public CommandType type; + public TimeTableEntry item; + public TimeTable table; + public TimeTableGroup tablegroup; + public Image image; + public Point position; + public int group; + public int track; + public int entry; + public string str; + public float floatValue; + public Size size; + public Telop telop; + public uint dwRate; + public uint dwScale; + public Color color; + public Command child; + public object[] args; + + public static Command GCommandChangeBackgroundColor( Color color ){ + Command ret = new Command(); + ret.target = TimeTableType.whole; + ret.type = CommandType.changeBackgroundColor; + ret.color = color; + return ret; + } + + public static Command GCommandAddTelop( Telop telop ) { + Command ret = new Command(); + ret.target = TimeTableType.telop; + ret.type = CommandType.addTelop; + if ( telop != null ) { + ret.telop = (Telop)telop.Clone(); + } + return ret; + } + + public static Command GCommandAddTelopRange( Telop[] telops ) { + Command ret = new Command(); + ret.target = TimeTableType.telop; + ret.type = CommandType.addTelopRange; + ret.args = new object[1]; + Telop[] add = new Telop[telops.Length]; + for ( int i = 0; i < add.Length; i++ ) { + add[i] = (Telop)telops[i].Clone(); + } + ret.args[0] = add; + return ret; + } + + public static Command GCommandEditTelop( int id, Telop telop ) { + Command ret = new Command(); + ret.target = TimeTableType.telop; + ret.type = CommandType.editTelop; + ret.entry = id; + if ( telop != null ) { + ret.telop = (Telop)telop.Clone(); + } + return ret; + } + + public static Command GCommandDeleteTelop( Telop item ) { + Command ret = new Command(); + ret.target = TimeTableType.telop; + ret.type = CommandType.deleteTelop; + ret.telop = (Telop)item.Clone(); + return ret; + } + + public static Command GCommandDeleteTelopRange( Telop[] items ) { + Command ret = new Command(); + ret.target = TimeTableType.telop; + ret.type = CommandType.deleteTelopRange; + ret.args = new object[1]; + Telop[] items2 = new Telop[items.Length]; + for ( int i = 0; i < items2.Length; i++ ) { + items2[i] = (Telop)items[i].Clone(); + } + ret.args[0] = items2; + return ret; + } + + public static Command GCommandDeleteTimeTableGroup( TimeTableType target, int group ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.deleteGroup; + ret.group = group; + return ret; + } + + public static Command GCommandDeleteTimeTable( TimeTableType target, int group, int track ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.deleteTimeTable; + ret.group = group; + ret.track = track; + return ret; + } + + public static Command GCommandSetMp3( string file_name ){ + Command ret = new Command(); + ret.target = TimeTableType.whole; + ret.type = CommandType.setMP3; + ret.str = file_name; + return ret; + } + + public static Command GCommandChangeVideoSize( Size size ){ + Command ret = new Command(); + ret.target = TimeTableType.whole; + ret.type = CommandType.changeVideoSize; + ret.size = size; + return ret; + } + + public static Command GCommandShiftTimeTable( TimeTableType target, int track, float floatValue ){ + Command ret = new Command(); + ret.target = target; + if ( target == TimeTableType.character ) { + ret.group = track; + } else { + ret.track = track; + } + ret.type = CommandType.shiftTimeTable; + ret.floatValue = floatValue; + return ret; + } + + public static Command GCommandChangeFps( uint rate, uint scale ){ + Command ret = new Command(); + ret.target = TimeTableType.whole; + ret.type = CommandType.changeFps; + ret.dwRate = rate; + ret.dwScale = scale; + return ret; + } + + public static Command GCommandChangeScale( TimeTableType target, int group, int track, float scale ){ + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.changeScale; + ret.group = group; + ret.track = track; + ret.floatValue = scale; + return ret; + } + + public static Command GCommandChangePluginConfig( int track, string config ) { + Command ret = new Command(); + ret.target = TimeTableType.whole; + ret.type = CommandType.changePluginConfig; + ret.track = track; + ret.str = config; + return ret; + } + + public static Command GCommandSetAvi( int track, string file_name ){ + Command ret = new Command(); + ret.target = TimeTableType.another; + ret.type = CommandType.setAvi; + ret.track = track; + ret.str = file_name; + return ret; + } + + public static Command GCommandEditTimeTableEntry( TimeTableType target, int group, int track, int entry, TimeTableEntry item ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.editEntry; + ret.group = group; + ret.track = track; + ret.entry = entry; + if ( item != null ) { + ret.item = (TimeTableEntry)item.Clone(); + } + return ret; + } + + public static Command GCommandAddTimeTableEntry( TimeTableType target, int group, int track, TimeTableEntry item ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.addEntry; + ret.group = group; + ret.track = track; + if ( item != null ) { + ret.item = (TimeTableEntry)item.Clone(); + } + return ret; + } + + public static Command GCommandDeleteTimeTableEntry( TimeTableType target, int group, int track, TimeTableEntry item ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.deleteEntry; + ret.group = group; + ret.track = track; + if ( item != null ) { + ret.item = (TimeTableEntry)item.Clone(); + } + return ret; + } + + public static Command GCommandEditTimeTable( TimeTableType target, int group, int track, TimeTable table ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.editTimeTable; + ret.group = group; + ret.track = track; + if ( table != null ) { + ret.table = (TimeTable)table.Clone(); + } + return ret; + } + + public static Command GCommandAddTimeTable( TimeTableType target, int group, int track, TimeTable table ){ + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.addTimeTable; + ret.group = group; + ret.track = track; + if ( table != null ) { + ret.table = (TimeTable)table.Clone(); + } + return ret; + } + + public static Command GCommandEditGroup( TimeTableType target, int group, TimeTableGroup table_group ) { + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.editGroup; + ret.group = group; + ret.tablegroup = (TimeTableGroup)table_group.Clone(); + return ret; + } + + public static Command GCommandAddGroup( TimeTableType target, int group, TimeTableGroup tablegroup ){ + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.addGroup; + ret.group = group; + if ( tablegroup != null ) { + ret.tablegroup = (TimeTableGroup)tablegroup.Clone(); + } else { + ret.tablegroup = null; + } + return ret; + } + + public static Command GCommandSetImage( int track, Image img ){ + Command ret = new Command(); + ret.target = TimeTableType.another; + ret.type = CommandType.setImage; + ret.track = track; + if ( img != null ) { + ret.image = (Image)img.Clone(); + } else { + ret.image = null; + } + return ret; + } + + public static Command GCommandSetPosition( TimeTableType target, int group, int track, Point position ){ + Command ret = new Command(); + ret.target = target; + ret.type = CommandType.setPosition; + ret.group = group; + ret.track = track; + ret.position = position; + return ret; + } + + public static Command GCommandNothing() { + Command ret = new Command(); + ret.target = TimeTableType.none; + return ret; + } + + private Command() { + } + + public override string ToString() { + string res = ""; + res += target.ToString(); + res += "," + type.ToString(); + res += ",group=" + group + ",track=" + track + ";entry=" + entry; + + if ( item == null ) { + res += ";item=null"; + } else { + res += ";item={begin=" + item.begin + ",end=" + item.end + ",body=" + item.body; + } + return res; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/CommandType.cs b/trunk/LipSync/LipSync/Editor/CommandType.cs new file mode 100644 index 0000000..d921dba --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/CommandType.cs @@ -0,0 +1,44 @@ +/* + * CommandType.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + public enum CommandType { + nothing, + addEntry, + deleteEntry, + editEntry, + addTimeTable, + deleteTimeTable, + editTimeTable, + addGroup, // CommandTarget == characterの時のみ + editGroup, // CommandTarget == characterの時のみ + deleteGroup, // CommandTarget == characterの時のみ + setPosition, + setImage, + changePluginConfig, + changeFps, + changeVideoSize, + shiftTimeTable, + changeScale, + setMP3, + addTelop, + addTelopRange, + editTelop, + deleteTelop, + deleteTelopRange, + setAvi, + changeBackgroundColor, + } + +} diff --git a/trunk/LipSync/LipSync/Editor/DisplacementControl.cs b/trunk/LipSync/LipSync/Editor/DisplacementControl.cs new file mode 100644 index 0000000..73113ea --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/DisplacementControl.cs @@ -0,0 +1,235 @@ +/* + * DisplacementControl.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class DisplacementControl : Form, IMultiLanguageControl { + private PointF m_scaleandoffset_x = new PointF( 1f, 0f ); + private PointF m_scaleandoffset_y = new PointF( 1f, 0f ); + private PointF m_scaleandoffset_alpha = new PointF( 400f, 0.3f ); + private PointF m_scaleandoffset_scale = new PointF( 40f, 0.5f ); + private PointF m_scaleandoffset_rotate = new PointF( 1f, 0f ); + private bool m_first_scaleandoffset = true; + + public DisplacementControl() { + InitializeComponent(); + ApplyFont( AppManager.Config.Font.GetFont() ); + ApplyLanguage(); + Rectangle r = AppManager.Config.CurveWindowPos; + Point pt_lt = new Point( r.Left, r.Top ); + Point pt_lb = new Point( r.Left, r.Bottom ); + Point pt_rt = new Point( r.Right, r.Top ); + Point pt_rb = new Point( r.Right, r.Bottom ); + bool visible = false; + foreach ( Screen s in Screen.AllScreens ) { + visible = visible | (IsInRectangle( pt_lt, s.Bounds ) | IsInRectangle( pt_lb, s.Bounds ) | IsInRectangle( pt_rt, s.Bounds ) | IsInRectangle( pt_rb, s.Bounds )); + } + if ( visible ) { + this.Left = r.Left; + this.Top = r.Top; + this.Width = r.Width; + this.Height = r.Height; + } else { + this.Width = Screen.PrimaryScreen.Bounds.Width / 2; + this.Height = Screen.PrimaryScreen.Bounds.Height / 2; + this.Left = this.Width / 2; + this.Top = this.Height / 2; + } + if ( AppManager.Config.CurveMaximized ) { + this.WindowState = FormWindowState.Maximized; + } else { + this.WindowState = FormWindowState.Normal; + } + this.SizeChanged += new EventHandler( DisplacementControl_LocationOrSizeChanged ); + this.LocationChanged += new EventHandler( DisplacementControl_LocationOrSizeChanged ); + } + + /// + /// どのカーブも選択されていない状態にします + /// + public void SetSelectedNone() { + curveEditor.Clear(); + curveEditor.ClearBuffer(); + comboObjects.SelectedIndex = -1; + } + + /// + /// rectの中にpointが入っているかどうかを判定 + /// + /// + /// + /// + private static bool IsInRectangle( Point point, Rectangle rect ) { + if ( rect.X <= point.X && point.X <= rect.X + rect.Width ) { + if ( rect.Y <= point.Y && point.Y <= rect.Y + rect.Height ) { + return true; + } + } + return false; + } + + public void ApplyLanguage() { + this.Text = _( "Edit Motion Curve" ); + menuClose.Text = _( "Close" ) + "(&C)"; + menuFile.Text = _( "File" ) + "(&F)"; + menuRedo.Text = _( "Redo" ); + menuUndo.Text = _( "Undo" ); + menuEdit.Text = _( "Edit" ) + "(&E)"; + + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + /// + /// 現在の編集情報を破棄します + /// + public void Clear() { + curveEditor.Clear(); + comboObjects.Items.Clear(); + comboObjects.Text = ""; + } + + private void DisplacementControl_FormClosing( object sender, FormClosingEventArgs e ) { + e.Cancel = true; + } + + private void menuUndo_Click( object sender, EventArgs e ) { + curveEditor.Undo(); + } + + private void menuRedo_Click( object sender, EventArgs e ) { + curveEditor.Redo(); + } + + private void menuEdit_DropDownOpening( object sender, EventArgs e ) { + menuUndo.Enabled = curveEditor.IsUndoAvailable; + menuRedo.Enabled = curveEditor.IsRedoAvailable; + } + + private void comboObjects_SelectedIndexChanged( object sender, EventArgs e ) { + int index = comboObjects.SelectedIndex; +#if DEBUG + Console.WriteLine( "DisplacementControl+comboObjects_SelectedIndexChanged" ); + Console.WriteLine( " index=" + index ); +#endif + if ( m_first_scaleandoffset ) { + float scale, offset; + if ( curveEditor.GetYScaleAndYOffset( "X", out scale, out offset ) ) { + m_scaleandoffset_x = new PointF( scale, offset ); + } + if ( curveEditor.GetYScaleAndYOffset( "Y", out scale, out offset ) ) { + m_scaleandoffset_y = new PointF( scale, offset ); + } + if ( curveEditor.GetYScaleAndYOffset( "Alpha", out scale, out offset ) ) { + m_scaleandoffset_alpha = new PointF( scale, offset ); + +#if DEBUG + Console.WriteLine( "Alpha, scale=" + scale + "; offset=" + offset ); +#endif + } + if ( curveEditor.GetYScaleAndYOffset( "Scale", out scale, out offset ) ) { + m_scaleandoffset_scale = new PointF( scale, offset ); + } + if ( curveEditor.GetYScaleAndYOffset( "Rotate", out scale, out offset ) ) { + m_scaleandoffset_rotate = new PointF( scale, offset ); + } + } + curveEditor.Clear(); + curveEditor.ClearBuffer(); + if ( index >= 0 ) { + TagForTreeNode node = (TagForTreeNode)comboObjects.Items[index]; + int id = node.id_or_index; + switch ( node.type ) { + case ZorderItemType.another: + curveEditor.Add( "X", AppManager.SaveData.m_group_another[id].mc_x ); + curveEditor.Add( "Y", AppManager.SaveData.m_group_another[id].mc_y ); + curveEditor.Add( "Alpha", AppManager.SaveData.m_group_another[id].mc_alpha ); + curveEditor.Add( "Scale", AppManager.SaveData.m_group_another[id].mc_scale ); + curveEditor.Add( "Roate", AppManager.SaveData.m_group_another[id].mc_rotate ); + break; + case ZorderItemType.character: + curveEditor.Add( "X", AppManager.SaveData.m_groups_character[id].mc_x ); + curveEditor.Add( "Y", AppManager.SaveData.m_groups_character[id].mc_y ); + curveEditor.Add( "Alpha", AppManager.SaveData.m_groups_character[id].mc_alpha ); + curveEditor.Add( "Scale", AppManager.SaveData.m_groups_character[id].mc_scale ); + curveEditor.Add( "Roate", AppManager.SaveData.m_groups_character[id].mc_rotate ); + break; + case ZorderItemType.plugin: + curveEditor.Add( "X", AppManager.SaveData.m_group_plugin[id].mc_x ); + curveEditor.Add( "Y", AppManager.SaveData.m_group_plugin[id].mc_y ); + curveEditor.Add( "Alpha", AppManager.SaveData.m_group_plugin[id].mc_alpha ); + curveEditor.Add( "Scale", AppManager.SaveData.m_group_plugin[id].mc_scale ); + curveEditor.Add( "Roate", AppManager.SaveData.m_group_plugin[id].mc_rotate ); + break; + case ZorderItemType.telop: + curveEditor.Add( "X", AppManager.SaveData[id].mc_x ); + curveEditor.Add( "Y", AppManager.SaveData[id].mc_y ); + curveEditor.Add( "Alpha", AppManager.SaveData[id].mc_alpha ); + curveEditor.Add( "Scale", AppManager.SaveData[id].mc_scale ); + curveEditor.Add( "Roate", AppManager.SaveData[id].mc_rotate ); + break; + } + curveEditor.SetYScaleAndYOffset( "X", m_scaleandoffset_x.X, m_scaleandoffset_x.Y ); + curveEditor.SetYScaleAndYOffset( "Y", m_scaleandoffset_y.X, m_scaleandoffset_y.Y ); + curveEditor.SetYScaleAndYOffset( "Alpha", m_scaleandoffset_alpha.X, m_scaleandoffset_alpha.Y ); + curveEditor.SetYScaleAndYOffset( "Scale", m_scaleandoffset_scale.X, m_scaleandoffset_scale.Y ); + curveEditor.SetYScaleAndYOffset( "Rotate", m_scaleandoffset_rotate.X, m_scaleandoffset_rotate.Y ); + if ( m_first_scaleandoffset ) { + m_first_scaleandoffset = false; + } + curveEditor.Invalidate(); + } + } + + private void DisplacementControl_VisibleChanged( object sender, EventArgs e ) { + ApplyLanguage(); + } + + private void menuVisualNumericInput_CheckedChanged( object sender, EventArgs e ) { + this.Invalidate(); + } + + private void curveEditor_CurveEdited() { + AppManager.Edited = true; + } + + private void DisplacementControl_LocationOrSizeChanged( object sender, EventArgs e ) { + if ( AppManager.Config != null ) { + if ( this.WindowState == FormWindowState.Normal ) { + AppManager.Config.CurveWindowPos = this.Bounds; + } + AppManager.Config.CurveMaximized = (this.WindowState == FormWindowState.Maximized); + } + } + + private void menuClose_Click( object sender, EventArgs e ) { + this.Close(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/DisplacementControl.designer.cs b/trunk/LipSync/LipSync/Editor/DisplacementControl.designer.cs new file mode 100644 index 0000000..2bfc5d7 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/DisplacementControl.designer.cs @@ -0,0 +1,194 @@ +/* + * DisplacementControl.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class DisplacementControl { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.menuFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuClose = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.comboObjects = new System.Windows.Forms.ComboBox(); + this.curveEditor = new CurveEditor.CurveEditor(); + this.menuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuFile, + this.menuEdit} ); + this.menuStrip1.Location = new System.Drawing.Point( 0, 0 ); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size( 557, 24 ); + this.menuStrip1.TabIndex = 7; + this.menuStrip1.Text = "menuStrip1"; + // + // menuFile + // + this.menuFile.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuClose} ); + this.menuFile.Name = "menuFile"; + this.menuFile.Size = new System.Drawing.Size( 66, 20 ); + this.menuFile.Text = "ファイル(&F)"; + // + // menuClose + // + this.menuClose.Name = "menuClose"; + this.menuClose.ShortcutKeys = System.Windows.Forms.Keys.F9; + this.menuClose.Size = new System.Drawing.Size( 152, 22 ); + this.menuClose.Text = "閉じる(&C)"; + this.menuClose.Click += new System.EventHandler( this.menuClose_Click ); + // + // menuEdit + // + this.menuEdit.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuUndo, + this.menuRedo} ); + this.menuEdit.Name = "menuEdit"; + this.menuEdit.Size = new System.Drawing.Size( 56, 20 ); + this.menuEdit.Text = "編集(&E)"; + this.menuEdit.DropDownOpening += new System.EventHandler( this.menuEdit_DropDownOpening ); + // + // menuUndo + // + this.menuUndo.Name = "menuUndo"; + this.menuUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuUndo.Size = new System.Drawing.Size( 192, 22 ); + this.menuUndo.Text = "元に戻す(&U)"; + this.menuUndo.Click += new System.EventHandler( this.menuUndo_Click ); + // + // menuRedo + // + this.menuRedo.Name = "menuRedo"; + this.menuRedo.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.Z))); + this.menuRedo.Size = new System.Drawing.Size( 192, 22 ); + this.menuRedo.Text = "やり直し(&R)"; + this.menuRedo.Click += new System.EventHandler( this.menuRedo_Click ); + // + // comboObjects + // + this.comboObjects.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.comboObjects.FormattingEnabled = true; + this.comboObjects.Location = new System.Drawing.Point( 0, 24 ); + this.comboObjects.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 1 ); + this.comboObjects.Name = "comboObjects"; + this.comboObjects.Size = new System.Drawing.Size( 557, 20 ); + this.comboObjects.TabIndex = 8; + this.comboObjects.SelectedIndexChanged += new System.EventHandler( this.comboObjects_SelectedIndexChanged ); + // + // curveEditor1 + // + this.curveEditor.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.curveEditor.BackColor = System.Drawing.SystemColors.AppWorkspace; + this.curveEditor.ChangeXScaleWithWheel = true; + this.curveEditor.ChangeYScaleWithWheel = true; + this.curveEditor.ControlMaster = System.Drawing.Color.FromArgb( ((int)(((byte)(255)))), ((int)(((byte)(130)))), ((int)(((byte)(0)))) ); + this.curveEditor.ControlNormal = System.Drawing.Color.FromArgb( ((int)(((byte)(51)))), ((int)(((byte)(192)))), ((int)(((byte)(64)))) ); + this.curveEditor.ControlPointSize = 2; + this.curveEditor.ControlPointType = CurveEditor.PointType.Circle; + this.curveEditor.DataPoint = System.Drawing.Color.Black; + this.curveEditor.DataPointHilight = System.Drawing.Color.Red; + this.curveEditor.DataPointSize = 2; + this.curveEditor.DataPointType = CurveEditor.PointType.Circle; + this.curveEditor.HandleMaster = System.Drawing.Color.FromArgb( ((int)(((byte)(240)))), ((int)(((byte)(144)))), ((int)(((byte)(160)))) ); + this.curveEditor.HandleNormal = System.Drawing.Color.FromArgb( ((int)(((byte)(255)))), ((int)(((byte)(130)))), ((int)(((byte)(0)))) ); + this.curveEditor.LabelBackground = System.Drawing.Color.FromArgb( ((int)(((byte)(172)))), ((int)(((byte)(172)))), ((int)(((byte)(172)))) ); + this.curveEditor.ListBackground = System.Drawing.Color.FromArgb( ((int)(((byte)(143)))), ((int)(((byte)(143)))), ((int)(((byte)(143)))) ); + this.curveEditor.Location = new System.Drawing.Point( 0, 45 ); + this.curveEditor.MainScaleLine = System.Drawing.Color.FromArgb( ((int)(((byte)(44)))), ((int)(((byte)(44)))), ((int)(((byte)(44)))) ); + this.curveEditor.Margin = new System.Windows.Forms.Padding( 0 ); + this.curveEditor.MaxXScale = 100F; + this.curveEditor.MaxYScale = 1000F; + this.curveEditor.MinimumSize = new System.Drawing.Size( 100, 100 ); + this.curveEditor.MinXScale = 1F; + this.curveEditor.MinYScale = 0.2F; + this.curveEditor.Name = "curveEditor1"; + this.curveEditor.RescaleYEnabled = true; + this.curveEditor.ScaleLine = System.Drawing.Color.FromArgb( ((int)(((byte)(94)))), ((int)(((byte)(94)))), ((int)(((byte)(94)))) ); + this.curveEditor.ScrollEnabled = true; + this.curveEditor.ShowList = true; + this.curveEditor.Size = new System.Drawing.Size( 557, 340 ); + this.curveEditor.SubScaleLine = System.Drawing.Color.FromArgb( ((int)(((byte)(110)))), ((int)(((byte)(110)))), ((int)(((byte)(110)))) ); + this.curveEditor.TabIndex = 6; + this.curveEditor.XLabel = CurveEditor.XLabel.Bottom; + this.curveEditor.XOffset = 0F; + this.curveEditor.XScale = 1F; + this.curveEditor.YLabel = CurveEditor.YLabel.Left; + this.curveEditor.YOffset = 0F; + this.curveEditor.YScale = 0.2F; + this.curveEditor.CurveEdited += new CurveEditor.CurveEditor.CurveEditedEventHandler( this.curveEditor_CurveEdited ); + // + // DisplacementControl + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackColor = System.Drawing.SystemColors.Control; + this.ClientSize = new System.Drawing.Size( 557, 385 ); + this.Controls.Add( this.comboObjects ); + this.Controls.Add( this.curveEditor ); + this.Controls.Add( this.menuStrip1 ); + this.MainMenuStrip = this.menuStrip1; + this.Name = "DisplacementControl"; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "変位の制御"; + this.VisibleChanged += new System.EventHandler( this.DisplacementControl_VisibleChanged ); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler( this.DisplacementControl_FormClosing ); + this.menuStrip1.ResumeLayout( false ); + this.menuStrip1.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private CurveEditor.CurveEditor curveEditor; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuFile; + private System.Windows.Forms.ToolStripMenuItem menuEdit; + public System.Windows.Forms.ToolStripMenuItem menuUndo; + public System.Windows.Forms.ToolStripMenuItem menuRedo; + public System.Windows.Forms.ComboBox comboObjects; + private System.Windows.Forms.ToolStripMenuItem menuClose; + } +} diff --git a/trunk/LipSync/LipSync/Editor/EditEntry.Designer.cs b/trunk/LipSync/LipSync/Editor/EditEntry.Designer.cs new file mode 100644 index 0000000..adb2a34 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EditEntry.Designer.cs @@ -0,0 +1,207 @@ +/* + * EditEntry.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class EditEntry { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.lblOnTime = new System.Windows.Forms.Label(); + this.lblOffTime = new System.Windows.Forms.Label(); + this.txtStart = new System.Windows.Forms.TextBox(); + this.txtEnd = new System.Windows.Forms.TextBox(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.txtMinStart = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); + this.txtMaxEnd = new System.Windows.Forms.TextBox(); + this.btnUseThisValue = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // lblOnTime + // + this.lblOnTime.AutoSize = true; + this.lblOnTime.Location = new System.Drawing.Point( 12, 20 ); + this.lblOnTime.Name = "lblOnTime"; + this.lblOnTime.Size = new System.Drawing.Size( 69, 12 ); + this.lblOnTime.TabIndex = 0; + this.lblOnTime.Text = "ON時刻 (秒)"; + // + // lblOffTime + // + this.lblOffTime.AutoSize = true; + this.lblOffTime.Location = new System.Drawing.Point( 12, 53 ); + this.lblOffTime.Name = "lblOffTime"; + this.lblOffTime.Size = new System.Drawing.Size( 75, 12 ); + this.lblOffTime.TabIndex = 1; + this.lblOffTime.Text = "OFF時刻 (秒)"; + // + // txtStart + // + this.txtStart.Location = new System.Drawing.Point( 109, 17 ); + this.txtStart.Name = "txtStart"; + this.txtStart.Size = new System.Drawing.Size( 100, 19 ); + this.txtStart.TabIndex = 0; + this.txtStart.Text = "0"; + this.txtStart.TextChanged += new System.EventHandler( this.txtStart_TextChanged ); + this.txtStart.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler( this.txtStart_PreviewKeyDown ); + this.txtStart.KeyPress += new System.Windows.Forms.KeyPressEventHandler( this.txtStart_KeyPress ); + // + // txtEnd + // + this.txtEnd.Location = new System.Drawing.Point( 109, 50 ); + this.txtEnd.Name = "txtEnd"; + this.txtEnd.Size = new System.Drawing.Size( 100, 19 ); + this.txtEnd.TabIndex = 1; + this.txtEnd.Text = "0"; + this.txtEnd.TextChanged += new System.EventHandler( this.txtEnd_TextChanged ); + this.txtEnd.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler( this.txtEnd_PreviewKeyDown ); + this.txtEnd.KeyPress += new System.Windows.Forms.KeyPressEventHandler( this.txtEnd_KeyPress ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 229, 171 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 7; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 131, 171 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 6; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // txtMinStart + // + this.txtMinStart.Location = new System.Drawing.Point( 18, 26 ); + this.txtMinStart.Name = "txtMinStart"; + this.txtMinStart.ReadOnly = true; + this.txtMinStart.Size = new System.Drawing.Size( 63, 19 ); + this.txtMinStart.TabIndex = 3; + this.txtMinStart.Text = "0"; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point( 87, 29 ); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size( 17, 12 ); + this.label3.TabIndex = 9; + this.label3.Text = "~"; + // + // txtMaxEnd + // + this.txtMaxEnd.Location = new System.Drawing.Point( 110, 26 ); + this.txtMaxEnd.Name = "txtMaxEnd"; + this.txtMaxEnd.ReadOnly = true; + this.txtMaxEnd.Size = new System.Drawing.Size( 63, 19 ); + this.txtMaxEnd.TabIndex = 4; + this.txtMaxEnd.Text = "0"; + // + // btnUseThisValue + // + this.btnUseThisValue.Location = new System.Drawing.Point( 188, 24 ); + this.btnUseThisValue.Name = "btnUseThisValue"; + this.btnUseThisValue.Size = new System.Drawing.Size( 89, 23 ); + this.btnUseThisValue.TabIndex = 5; + this.btnUseThisValue.Text = "この値を使う"; + this.btnUseThisValue.UseVisualStyleBackColor = true; + this.btnUseThisValue.Click += new System.EventHandler( this.btnUseThisValue_Click ); + // + // groupBox1 + // + this.groupBox1.Controls.Add( this.btnUseThisValue ); + this.groupBox1.Controls.Add( this.txtMinStart ); + this.groupBox1.Controls.Add( this.txtMaxEnd ); + this.groupBox1.Controls.Add( this.label3 ); + this.groupBox1.Location = new System.Drawing.Point( 12, 84 ); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size( 293, 69 ); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "変更可能な値の範囲"; + // + // EditEntry + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 319, 211 ); + this.Controls.Add( this.groupBox1 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.txtEnd ); + this.Controls.Add( this.txtStart ); + this.Controls.Add( this.lblOffTime ); + this.Controls.Add( this.lblOnTime ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "EditEntry"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "数値入力"; + this.groupBox1.ResumeLayout( false ); + this.groupBox1.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label lblOnTime; + private System.Windows.Forms.Label lblOffTime; + private System.Windows.Forms.TextBox txtStart; + private System.Windows.Forms.TextBox txtEnd; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.TextBox txtMinStart; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.TextBox txtMaxEnd; + private System.Windows.Forms.Button btnUseThisValue; + private System.Windows.Forms.GroupBox groupBox1; + } +} diff --git a/trunk/LipSync/LipSync/Editor/EditEntry.cs b/trunk/LipSync/LipSync/Editor/EditEntry.cs new file mode 100644 index 0000000..76f4f46 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EditEntry.cs @@ -0,0 +1,178 @@ +/* + * EditEntry.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class EditEntry : Form, IMultiLanguageControl { + private float m_start; + private float m_end; + private float m_min_start; + private float m_max_end; + /// + /// On timeがテキストボックスによって編集されたかどうか + /// + private bool m_start_edited = false; + /// + /// Off timeがテキストボックスによって編集されたかどうか + /// + private bool m_end_edited = false; + + public EditEntry( float start, float end, float min_start, float max_end ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + txtStart.Text = start.ToString(); + txtEnd.Text = end.ToString(); + txtMinStart.Text = min_start.ToString(); + txtMaxEnd.Text = max_end.ToString(); + m_min_start = min_start; + m_max_end = max_end; + m_start_edited = false; + m_end_edited = false; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.lblOnTime.Text = _( "ON time (sec)" ); + this.lblOffTime.Text = _( "OFF time (sec)" ); + this.btnCancel.Text = _( "Cancel" ); + this.btnOK.Text = _( "OK" ); + this.btnUseThisValue.Text = _( "Use this value" ); + this.groupBox1.Text = _( "Expandable range of this entry" ); + this.Text = _( "Numeric entry" ); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public float Start { + get { + return m_start; + } + } + + public float End { + get { + return m_end; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + /*if ( !m_start_edited ) { + m_start = m_start; + } + if ( !m_end_edited ) { + m_end = m_end; + }*/ + if ( m_start >= m_end || m_start < m_min_start || m_max_end < m_end ) { + MessageBox.Show( _( "Invalid value has been entered" ), _( "Error" ), MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + this.DialogResult = DialogResult.Cancel; + } else { + this.DialogResult = (!m_end_edited && !m_start_edited) ? DialogResult.Cancel : DialogResult.OK; + } + this.Close(); + } + + private void btnUseThisValue_Click( object sender, EventArgs e ) { + if ( m_start != m_min_start || m_end != m_max_end ) { + txtStart.Text = m_min_start.ToString(); + txtEnd.Text = m_max_end.ToString(); + m_start = m_min_start; + m_end = m_max_end; + m_end_edited = true; + m_start_edited = true; + } + } + + private void txtStart_TextChanged( object sender, EventArgs e ) { + float old_begin = m_start; + m_start_edited = true; + try { + m_start = float.Parse( txtStart.Text ); + } catch ( Exception ex ) { + m_start = old_begin; + txtStart.Text = m_start.ToString(); + txtStart.SelectAll(); + Common.LogPush( ex ); + } + } + + private void txtEnd_TextChanged( object sender, EventArgs e ) { + float old_end = m_end; + m_end_edited = true; + try { + m_end = float.Parse( txtEnd.Text ); + } catch ( Exception ex ) { + m_end = old_end; + txtEnd.Text = m_end.ToString(); + txtEnd.SelectAll(); + } + } + + private void txtStart_KeyPress( object sender, KeyPressEventArgs e ) { + if ( (e.KeyChar < '0' || e.KeyChar > '9') && e.KeyChar != '\b' && e.KeyChar != '.' ) { + e.Handled = true; + } + } + + private void txtEnd_KeyPress( object sender, KeyPressEventArgs e ) { + if ( (e.KeyChar < '0' || e.KeyChar > '9') && e.KeyChar != '\b' && e.KeyChar != '.' ) { + e.Handled = true; + } + } + + private void txtStart_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e ) { + if ( (e.Modifiers & Keys.Control) == Keys.Control ) { + if ( (e.KeyCode & Keys.X) == Keys.X ) { + Clipboard.SetText( txtStart.Text ); + txtStart.Text = ""; + } else if ( (e.KeyCode & Keys.C) == Keys.C ) { + Clipboard.SetText( txtStart.Text ); + } else if ( (e.KeyCode & Keys.V) == Keys.V ) { + if ( Clipboard.ContainsText() ) { + txtStart.Text = Clipboard.GetText(); + } + } + } + } + + private void txtEnd_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e ) { + if ( (e.Modifiers & Keys.Control) == Keys.Control ) { + if ( (e.KeyCode & Keys.X) == Keys.X ) { + Clipboard.SetText( txtEnd.Text ); + txtEnd.Text = ""; + } else if ( (e.KeyCode & Keys.C) == Keys.C ) { + Clipboard.SetText( txtEnd.Text ); + } else if ( (e.KeyCode & Keys.V) == Keys.V ) { + if ( Clipboard.ContainsText() ) { + txtEnd.Text = Clipboard.GetText(); + } + } + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/EditMode.cs b/trunk/LipSync/LipSync/Editor/EditMode.cs new file mode 100644 index 0000000..6d6f036 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EditMode.cs @@ -0,0 +1,43 @@ +/* + * EditMode.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + enum EditMode { + /// + /// デフォルト。何も編集して無い + /// + None, + /// + /// エントリが選択されてるだけの状態 + /// + Selected, + /// + /// エントリの右端をドラッグして終了時刻を編集するモード + /// + EditingRight, + /// + /// エントリの左端をドラッグして開始時刻を編集するモード + /// + EditingLeft, + /// + /// タイムライン上の左ボタンドラッグによりエントリを追加するモード + /// + Dragging, + /// + /// エントリをドラッグしてスライドさせるモード + /// + Sliding, + } + +} diff --git a/trunk/LipSync/LipSync/Editor/EditingBounds.cs b/trunk/LipSync/LipSync/Editor/EditingBounds.cs new file mode 100644 index 0000000..5a6e95c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EditingBounds.cs @@ -0,0 +1,76 @@ +/* + * EditingBounds.cs + * Copyright (c) 2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + public class EditingBounds { + private Rectangle m_rect; + private bool m_fixed; + public bool XFixed; + public bool YFixed; + + public EditingBounds() { + m_rect = new Rectangle(); + m_fixed = false; + XFixed = false; + YFixed = false; + } + + public EditingBounds( Rectangle bounds, bool item_fixed, bool x_fixed, bool y_fixed ) { + m_rect = bounds; + m_fixed = item_fixed; + XFixed = x_fixed; + YFixed = y_fixed; + } + + public int X { + get { + return m_rect.X; + } + } + + public int Y { + get { + return m_rect.Y; + } + } + + public int Width { + get { + return m_rect.Width; + } + } + + public int Height { + get { + return m_rect.Height; + } + } + + public bool Fixed { + get { + return m_fixed; + } + } + + public Rectangle Bounds { + get { + return m_rect; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/EnvConfiguration.Designer.cs b/trunk/LipSync/LipSync/Editor/EnvConfiguration.Designer.cs new file mode 100644 index 0000000..5e63cb2 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EnvConfiguration.Designer.cs @@ -0,0 +1,871 @@ +/* + * EnvConfiguration.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class EnvConfiguration { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.comboLanguage = new System.Windows.Forms.ComboBox(); + this.tabControl1 = new System.Windows.Forms.TabControl(); + this.tabUserConfig = new System.Windows.Forms.TabPage(); + this.groupControl = new System.Windows.Forms.GroupBox(); + this.chkSyncAtCenter = new System.Windows.Forms.CheckBox(); + this.lblWheelRatio = new System.Windows.Forms.Label(); + this.btnWheelRatioDefault = new System.Windows.Forms.Button(); + this.groupLanguage = new System.Windows.Forms.GroupBox(); + this.btnReloadLanguageConfig = new System.Windows.Forms.Button(); + this.tabAppearance = new System.Windows.Forms.TabPage(); + this.groupDesign = new System.Windows.Forms.GroupBox(); + this.btnFontDefault = new System.Windows.Forms.Button(); + this.lblFontName = new System.Windows.Forms.Label(); + this.lblFont = new System.Windows.Forms.Label(); + this.btnChangeFont = new System.Windows.Forms.Button(); + this.lblEntryHeight = new System.Windows.Forms.Label(); + this.btnEntryHeightDefault = new System.Windows.Forms.Button(); + this.groupColor = new System.Windows.Forms.GroupBox(); + this.lblTimeLineTitle = new System.Windows.Forms.Label(); + this.lblTimelineTitleColor = new System.Windows.Forms.Label(); + this.btnChangeTimeLineTitle = new System.Windows.Forms.Button(); + this.btnTimeLineTitleDefault = new System.Windows.Forms.Button(); + this.lblTimeLineVSQ = new System.Windows.Forms.Label(); + this.btnTimeLineDefaultDefault = new System.Windows.Forms.Button(); + this.lblTimeLineVSQColor = new System.Windows.Forms.Label(); + this.btnChangeTimeLineDefault = new System.Windows.Forms.Button(); + this.btnChangeTimeLineVSQ = new System.Windows.Forms.Button(); + this.lblTimeLineDefaultColor = new System.Windows.Forms.Label(); + this.btnTimeLineVSQDefault = new System.Windows.Forms.Button(); + this.lblTimeLineDefault = new System.Windows.Forms.Label(); + this.lblTimeLinePlugin = new System.Windows.Forms.Label(); + this.btnTimeLinePluginDefault = new System.Windows.Forms.Button(); + this.lblTimeLinePluginColor = new System.Windows.Forms.Label(); + this.btnChangeTimeLinePlugin = new System.Windows.Forms.Button(); + this.tabLipSync = new System.Windows.Forms.TabPage(); + this.groupSerialVowel = new System.Windows.Forms.GroupBox(); + this.txtCombineThreshold = new System.Windows.Forms.TextBox(); + this.lblCombineThreshold = new System.Windows.Forms.Label(); + this.chkSerialVowel = new System.Windows.Forms.CheckBox(); + this.groupPhoneticSymbol = new System.Windows.Forms.GroupBox(); + this.tabSystem = new System.Windows.Forms.TabPage(); + this.groupAnotherBehavior = new System.Windows.Forms.GroupBox(); + this.chkHeavyOpenCharacterDialog = new System.Windows.Forms.CheckBox(); + this.chkGenCharacterAutomaticaly = new System.Windows.Forms.CheckBox(); + this.groupEncoder = new System.Windows.Forms.GroupBox(); + this.txtFFmpeg = new System.Windows.Forms.TextBox(); + this.lblFFmpeg = new System.Windows.Forms.Label(); + this.btnMEncoder = new System.Windows.Forms.Button(); + this.txtMEncoder = new System.Windows.Forms.TextBox(); + this.btnFFmpeg = new System.Windows.Forms.Button(); + this.lblMEncoder = new System.Windows.Forms.Label(); + this.colorDialog1 = new System.Windows.Forms.ColorDialog(); + this.fontDialog = new System.Windows.Forms.FontDialog(); + this.numWheelRatio = new LipSync.NumericUpDownEx(); + this.numEntryHeight = new LipSync.NumericUpDownEx(); + this.mListClose = new LipSync.MListView(); + this.mListU = new LipSync.MListView(); + this.mListI = new LipSync.MListView(); + this.tabControl1.SuspendLayout(); + this.tabUserConfig.SuspendLayout(); + this.groupControl.SuspendLayout(); + this.groupLanguage.SuspendLayout(); + this.tabAppearance.SuspendLayout(); + this.groupDesign.SuspendLayout(); + this.groupColor.SuspendLayout(); + this.tabLipSync.SuspendLayout(); + this.groupSerialVowel.SuspendLayout(); + this.groupPhoneticSymbol.SuspendLayout(); + this.tabSystem.SuspendLayout(); + this.groupAnotherBehavior.SuspendLayout(); + this.groupEncoder.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numWheelRatio)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.numEntryHeight)).BeginInit(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 182, 421 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 71, 24 ); + this.btnOK.TabIndex = 13; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 285, 421 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 71, 24 ); + this.btnCancel.TabIndex = 14; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // comboLanguage + // + this.comboLanguage.FormattingEnabled = true; + this.comboLanguage.Location = new System.Drawing.Point( 15, 28 ); + this.comboLanguage.Name = "comboLanguage"; + this.comboLanguage.Size = new System.Drawing.Size( 121, 20 ); + this.comboLanguage.TabIndex = 1; + this.comboLanguage.SelectedIndexChanged += new System.EventHandler( this.comboLanguage_SelectedIndexChanged ); + // + // tabControl1 + // + this.tabControl1.Controls.Add( this.tabUserConfig ); + this.tabControl1.Controls.Add( this.tabAppearance ); + this.tabControl1.Controls.Add( this.tabLipSync ); + this.tabControl1.Controls.Add( this.tabSystem ); + this.tabControl1.Dock = System.Windows.Forms.DockStyle.Top; + this.tabControl1.Location = new System.Drawing.Point( 0, 0 ); + this.tabControl1.Margin = new System.Windows.Forms.Padding( 0 ); + this.tabControl1.Name = "tabControl1"; + this.tabControl1.SelectedIndex = 0; + this.tabControl1.Size = new System.Drawing.Size( 409, 402 ); + this.tabControl1.TabIndex = 0; + // + // tabUserConfig + // + this.tabUserConfig.BackColor = System.Drawing.SystemColors.Control; + this.tabUserConfig.Controls.Add( this.groupControl ); + this.tabUserConfig.Controls.Add( this.groupLanguage ); + this.tabUserConfig.Location = new System.Drawing.Point( 4, 21 ); + this.tabUserConfig.Name = "tabUserConfig"; + this.tabUserConfig.Padding = new System.Windows.Forms.Padding( 3 ); + this.tabUserConfig.Size = new System.Drawing.Size( 401, 377 ); + this.tabUserConfig.TabIndex = 0; + this.tabUserConfig.Text = "ユーザー設定"; + this.tabUserConfig.UseVisualStyleBackColor = true; + // + // groupControl + // + this.groupControl.Controls.Add( this.chkSyncAtCenter ); + this.groupControl.Controls.Add( this.lblWheelRatio ); + this.groupControl.Controls.Add( this.btnWheelRatioDefault ); + this.groupControl.Controls.Add( this.numWheelRatio ); + this.groupControl.Location = new System.Drawing.Point( 10, 79 ); + this.groupControl.Name = "groupControl"; + this.groupControl.Size = new System.Drawing.Size( 381, 100 ); + this.groupControl.TabIndex = 30; + this.groupControl.TabStop = false; + this.groupControl.Text = "操作"; + // + // chkSyncAtCenter + // + this.chkSyncAtCenter.AutoSize = true; + this.chkSyncAtCenter.Location = new System.Drawing.Point( 24, 56 ); + this.chkSyncAtCenter.Name = "chkSyncAtCenter"; + this.chkSyncAtCenter.Size = new System.Drawing.Size( 199, 16 ); + this.chkSyncAtCenter.TabIndex = 16; + this.chkSyncAtCenter.Text = "Fix cursor to center in Sync mode"; + this.chkSyncAtCenter.UseVisualStyleBackColor = true; + this.chkSyncAtCenter.CheckedChanged += new System.EventHandler( this.chkSyncAtCenter_CheckedChanged ); + // + // lblWheelRatio + // + this.lblWheelRatio.AutoSize = true; + this.lblWheelRatio.Location = new System.Drawing.Point( 22, 24 ); + this.lblWheelRatio.Name = "lblWheelRatio"; + this.lblWheelRatio.Size = new System.Drawing.Size( 95, 12 ); + this.lblWheelRatio.TabIndex = 15; + this.lblWheelRatio.Text = "マウスホイール速度"; + // + // btnWheelRatioDefault + // + this.btnWheelRatioDefault.Location = new System.Drawing.Point( 313, 19 ); + this.btnWheelRatioDefault.Name = "btnWheelRatioDefault"; + this.btnWheelRatioDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnWheelRatioDefault.TabIndex = 4; + this.btnWheelRatioDefault.Text = "Default"; + this.btnWheelRatioDefault.UseVisualStyleBackColor = true; + this.btnWheelRatioDefault.Click += new System.EventHandler( this.btnWheelRatioDefault_Click ); + // + // groupLanguage + // + this.groupLanguage.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupLanguage.AutoSize = true; + this.groupLanguage.Controls.Add( this.btnReloadLanguageConfig ); + this.groupLanguage.Controls.Add( this.comboLanguage ); + this.groupLanguage.Location = new System.Drawing.Point( 10, 6 ); + this.groupLanguage.Name = "groupLanguage"; + this.groupLanguage.Size = new System.Drawing.Size( 381, 67 ); + this.groupLanguage.TabIndex = 29; + this.groupLanguage.TabStop = false; + this.groupLanguage.Text = "言語"; + // + // btnReloadLanguageConfig + // + this.btnReloadLanguageConfig.Location = new System.Drawing.Point( 207, 26 ); + this.btnReloadLanguageConfig.Name = "btnReloadLanguageConfig"; + this.btnReloadLanguageConfig.Size = new System.Drawing.Size( 163, 23 ); + this.btnReloadLanguageConfig.TabIndex = 2; + this.btnReloadLanguageConfig.Text = "言語設定ファイルをリロード"; + this.btnReloadLanguageConfig.UseVisualStyleBackColor = true; + this.btnReloadLanguageConfig.Click += new System.EventHandler( this.btnReloadLanguageConfig_Click ); + // + // tabAppearance + // + this.tabAppearance.Controls.Add( this.groupDesign ); + this.tabAppearance.Controls.Add( this.groupColor ); + this.tabAppearance.Location = new System.Drawing.Point( 4, 21 ); + this.tabAppearance.Name = "tabAppearance"; + this.tabAppearance.Padding = new System.Windows.Forms.Padding( 3 ); + this.tabAppearance.Size = new System.Drawing.Size( 401, 377 ); + this.tabAppearance.TabIndex = 3; + this.tabAppearance.Text = "外観"; + this.tabAppearance.UseVisualStyleBackColor = true; + // + // groupDesign + // + this.groupDesign.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupDesign.AutoSize = true; + this.groupDesign.Controls.Add( this.numEntryHeight ); + this.groupDesign.Controls.Add( this.btnFontDefault ); + this.groupDesign.Controls.Add( this.lblFontName ); + this.groupDesign.Controls.Add( this.lblFont ); + this.groupDesign.Controls.Add( this.btnChangeFont ); + this.groupDesign.Controls.Add( this.lblEntryHeight ); + this.groupDesign.Controls.Add( this.btnEntryHeightDefault ); + this.groupDesign.Location = new System.Drawing.Point( 8, 171 ); + this.groupDesign.Name = "groupDesign"; + this.groupDesign.Size = new System.Drawing.Size( 381, 100 ); + this.groupDesign.TabIndex = 32; + this.groupDesign.TabStop = false; + this.groupDesign.Text = "表示"; + // + // btnFontDefault + // + this.btnFontDefault.Location = new System.Drawing.Point( 312, 59 ); + this.btnFontDefault.Name = "btnFontDefault"; + this.btnFontDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnFontDefault.TabIndex = 12; + this.btnFontDefault.Text = "Default"; + this.btnFontDefault.UseVisualStyleBackColor = true; + this.btnFontDefault.Click += new System.EventHandler( this.btnFontDefault_Click ); + // + // lblFontName + // + this.lblFontName.AutoSize = true; + this.lblFontName.Location = new System.Drawing.Point( 61, 64 ); + this.lblFontName.Name = "lblFontName"; + this.lblFontName.Size = new System.Drawing.Size( 0, 12 ); + this.lblFontName.TabIndex = 31; + // + // lblFont + // + this.lblFont.AutoSize = true; + this.lblFont.Location = new System.Drawing.Point( 16, 64 ); + this.lblFont.Name = "lblFont"; + this.lblFont.Size = new System.Drawing.Size( 38, 12 ); + this.lblFont.TabIndex = 30; + this.lblFont.Text = "フォント"; + // + // btnChangeFont + // + this.btnChangeFont.Location = new System.Drawing.Point( 232, 59 ); + this.btnChangeFont.Name = "btnChangeFont"; + this.btnChangeFont.Size = new System.Drawing.Size( 75, 23 ); + this.btnChangeFont.TabIndex = 11; + this.btnChangeFont.Text = "変更"; + this.btnChangeFont.UseVisualStyleBackColor = true; + this.btnChangeFont.Click += new System.EventHandler( this.btnChangeFont_Click ); + // + // lblEntryHeight + // + this.lblEntryHeight.AutoSize = true; + this.lblEntryHeight.Location = new System.Drawing.Point( 16, 27 ); + this.lblEntryHeight.Name = "lblEntryHeight"; + this.lblEntryHeight.Size = new System.Drawing.Size( 117, 12 ); + this.lblEntryHeight.TabIndex = 26; + this.lblEntryHeight.Text = "エントリの高さ (ピクセル)"; + // + // btnEntryHeightDefault + // + this.btnEntryHeightDefault.Location = new System.Drawing.Point( 312, 22 ); + this.btnEntryHeightDefault.Name = "btnEntryHeightDefault"; + this.btnEntryHeightDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnEntryHeightDefault.TabIndex = 10; + this.btnEntryHeightDefault.Text = "Default"; + this.btnEntryHeightDefault.UseVisualStyleBackColor = true; + this.btnEntryHeightDefault.Click += new System.EventHandler( this.btnEntryHeightDefault_Click ); + // + // groupColor + // + this.groupColor.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupColor.AutoSize = true; + this.groupColor.Controls.Add( this.lblTimeLineTitle ); + this.groupColor.Controls.Add( this.lblTimelineTitleColor ); + this.groupColor.Controls.Add( this.btnChangeTimeLineTitle ); + this.groupColor.Controls.Add( this.btnTimeLineTitleDefault ); + this.groupColor.Controls.Add( this.lblTimeLineVSQ ); + this.groupColor.Controls.Add( this.btnTimeLineDefaultDefault ); + this.groupColor.Controls.Add( this.lblTimeLineVSQColor ); + this.groupColor.Controls.Add( this.btnChangeTimeLineDefault ); + this.groupColor.Controls.Add( this.btnChangeTimeLineVSQ ); + this.groupColor.Controls.Add( this.lblTimeLineDefaultColor ); + this.groupColor.Controls.Add( this.btnTimeLineVSQDefault ); + this.groupColor.Controls.Add( this.lblTimeLineDefault ); + this.groupColor.Controls.Add( this.lblTimeLinePlugin ); + this.groupColor.Controls.Add( this.btnTimeLinePluginDefault ); + this.groupColor.Controls.Add( this.lblTimeLinePluginColor ); + this.groupColor.Controls.Add( this.btnChangeTimeLinePlugin ); + this.groupColor.Location = new System.Drawing.Point( 8, 6 ); + this.groupColor.Name = "groupColor"; + this.groupColor.Size = new System.Drawing.Size( 381, 159 ); + this.groupColor.TabIndex = 31; + this.groupColor.TabStop = false; + this.groupColor.Text = "配色"; + // + // lblTimeLineTitle + // + this.lblTimeLineTitle.AutoSize = true; + this.lblTimeLineTitle.Location = new System.Drawing.Point( 6, 24 ); + this.lblTimeLineTitle.Name = "lblTimeLineTitle"; + this.lblTimeLineTitle.Size = new System.Drawing.Size( 103, 12 ); + this.lblTimeLineTitle.TabIndex = 10; + this.lblTimeLineTitle.Text = "タイムラインのタイトル"; + // + // lblTimelineTitleColor + // + this.lblTimelineTitleColor.BackColor = System.Drawing.Color.White; + this.lblTimelineTitleColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblTimelineTitleColor.Location = new System.Drawing.Point( 116, 18 ); + this.lblTimelineTitleColor.Name = "lblTimelineTitleColor"; + this.lblTimelineTitleColor.Size = new System.Drawing.Size( 100, 23 ); + this.lblTimelineTitleColor.TabIndex = 11; + // + // btnChangeTimeLineTitle + // + this.btnChangeTimeLineTitle.Location = new System.Drawing.Point( 232, 19 ); + this.btnChangeTimeLineTitle.Name = "btnChangeTimeLineTitle"; + this.btnChangeTimeLineTitle.Size = new System.Drawing.Size( 75, 23 ); + this.btnChangeTimeLineTitle.TabIndex = 1; + this.btnChangeTimeLineTitle.Text = "変更"; + this.btnChangeTimeLineTitle.UseVisualStyleBackColor = true; + this.btnChangeTimeLineTitle.Click += new System.EventHandler( this.btnChangeTimeLineTitle_Click ); + // + // btnTimeLineTitleDefault + // + this.btnTimeLineTitleDefault.Location = new System.Drawing.Point( 313, 19 ); + this.btnTimeLineTitleDefault.Name = "btnTimeLineTitleDefault"; + this.btnTimeLineTitleDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnTimeLineTitleDefault.TabIndex = 2; + this.btnTimeLineTitleDefault.Text = "Default"; + this.btnTimeLineTitleDefault.UseVisualStyleBackColor = true; + this.btnTimeLineTitleDefault.Click += new System.EventHandler( this.btnTimeLineTitleDefault_Click ); + // + // lblTimeLineVSQ + // + this.lblTimeLineVSQ.AutoSize = true; + this.lblTimeLineVSQ.Location = new System.Drawing.Point( 6, 57 ); + this.lblTimeLineVSQ.Name = "lblTimeLineVSQ"; + this.lblTimeLineVSQ.Size = new System.Drawing.Size( 61, 12 ); + this.lblTimeLineVSQ.TabIndex = 14; + this.lblTimeLineVSQ.Text = "VSQエントリ"; + // + // btnTimeLineDefaultDefault + // + this.btnTimeLineDefaultDefault.Location = new System.Drawing.Point( 313, 118 ); + this.btnTimeLineDefaultDefault.Name = "btnTimeLineDefaultDefault"; + this.btnTimeLineDefaultDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnTimeLineDefaultDefault.TabIndex = 8; + this.btnTimeLineDefaultDefault.Text = "Default"; + this.btnTimeLineDefaultDefault.UseVisualStyleBackColor = true; + this.btnTimeLineDefaultDefault.Click += new System.EventHandler( this.btnTimeLineDefaultDefault_Click ); + // + // lblTimeLineVSQColor + // + this.lblTimeLineVSQColor.BackColor = System.Drawing.Color.White; + this.lblTimeLineVSQColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblTimeLineVSQColor.Location = new System.Drawing.Point( 116, 51 ); + this.lblTimeLineVSQColor.Name = "lblTimeLineVSQColor"; + this.lblTimeLineVSQColor.Size = new System.Drawing.Size( 100, 23 ); + this.lblTimeLineVSQColor.TabIndex = 15; + // + // btnChangeTimeLineDefault + // + this.btnChangeTimeLineDefault.Location = new System.Drawing.Point( 232, 118 ); + this.btnChangeTimeLineDefault.Name = "btnChangeTimeLineDefault"; + this.btnChangeTimeLineDefault.Size = new System.Drawing.Size( 75, 23 ); + this.btnChangeTimeLineDefault.TabIndex = 7; + this.btnChangeTimeLineDefault.Text = "変更"; + this.btnChangeTimeLineDefault.UseVisualStyleBackColor = true; + this.btnChangeTimeLineDefault.Click += new System.EventHandler( this.btnChangeTimeLineDefault_Click ); + // + // btnChangeTimeLineVSQ + // + this.btnChangeTimeLineVSQ.Location = new System.Drawing.Point( 232, 52 ); + this.btnChangeTimeLineVSQ.Name = "btnChangeTimeLineVSQ"; + this.btnChangeTimeLineVSQ.Size = new System.Drawing.Size( 75, 23 ); + this.btnChangeTimeLineVSQ.TabIndex = 3; + this.btnChangeTimeLineVSQ.Text = "変更"; + this.btnChangeTimeLineVSQ.UseVisualStyleBackColor = true; + this.btnChangeTimeLineVSQ.Click += new System.EventHandler( this.btnChangeTimeLineVSQ_Click ); + // + // lblTimeLineDefaultColor + // + this.lblTimeLineDefaultColor.BackColor = System.Drawing.Color.White; + this.lblTimeLineDefaultColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblTimeLineDefaultColor.Location = new System.Drawing.Point( 116, 117 ); + this.lblTimeLineDefaultColor.Name = "lblTimeLineDefaultColor"; + this.lblTimeLineDefaultColor.Size = new System.Drawing.Size( 100, 23 ); + this.lblTimeLineDefaultColor.TabIndex = 23; + // + // btnTimeLineVSQDefault + // + this.btnTimeLineVSQDefault.Location = new System.Drawing.Point( 313, 52 ); + this.btnTimeLineVSQDefault.Name = "btnTimeLineVSQDefault"; + this.btnTimeLineVSQDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnTimeLineVSQDefault.TabIndex = 4; + this.btnTimeLineVSQDefault.Text = "Default"; + this.btnTimeLineVSQDefault.UseVisualStyleBackColor = true; + this.btnTimeLineVSQDefault.Click += new System.EventHandler( this.btnTimeLineVSQDefault_Click ); + // + // lblTimeLineDefault + // + this.lblTimeLineDefault.AutoSize = true; + this.lblTimeLineDefault.Location = new System.Drawing.Point( 6, 123 ); + this.lblTimeLineDefault.Name = "lblTimeLineDefault"; + this.lblTimeLineDefault.Size = new System.Drawing.Size( 79, 12 ); + this.lblTimeLineDefault.TabIndex = 22; + this.lblTimeLineDefault.Text = "その他のエントリ"; + // + // lblTimeLinePlugin + // + this.lblTimeLinePlugin.AutoSize = true; + this.lblTimeLinePlugin.Location = new System.Drawing.Point( 6, 90 ); + this.lblTimeLinePlugin.Name = "lblTimeLinePlugin"; + this.lblTimeLinePlugin.Size = new System.Drawing.Size( 82, 12 ); + this.lblTimeLinePlugin.TabIndex = 18; + this.lblTimeLinePlugin.Text = "プラグインエントリ"; + // + // btnTimeLinePluginDefault + // + this.btnTimeLinePluginDefault.Location = new System.Drawing.Point( 313, 85 ); + this.btnTimeLinePluginDefault.Name = "btnTimeLinePluginDefault"; + this.btnTimeLinePluginDefault.Size = new System.Drawing.Size( 57, 23 ); + this.btnTimeLinePluginDefault.TabIndex = 6; + this.btnTimeLinePluginDefault.Text = "Default"; + this.btnTimeLinePluginDefault.UseVisualStyleBackColor = true; + this.btnTimeLinePluginDefault.Click += new System.EventHandler( this.btnTimeLinePluginDefault_Click ); + // + // lblTimeLinePluginColor + // + this.lblTimeLinePluginColor.BackColor = System.Drawing.Color.White; + this.lblTimeLinePluginColor.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.lblTimeLinePluginColor.Location = new System.Drawing.Point( 116, 84 ); + this.lblTimeLinePluginColor.Name = "lblTimeLinePluginColor"; + this.lblTimeLinePluginColor.Size = new System.Drawing.Size( 100, 23 ); + this.lblTimeLinePluginColor.TabIndex = 19; + // + // btnChangeTimeLinePlugin + // + this.btnChangeTimeLinePlugin.Location = new System.Drawing.Point( 232, 85 ); + this.btnChangeTimeLinePlugin.Name = "btnChangeTimeLinePlugin"; + this.btnChangeTimeLinePlugin.Size = new System.Drawing.Size( 75, 23 ); + this.btnChangeTimeLinePlugin.TabIndex = 5; + this.btnChangeTimeLinePlugin.Text = "変更"; + this.btnChangeTimeLinePlugin.UseVisualStyleBackColor = true; + this.btnChangeTimeLinePlugin.Click += new System.EventHandler( this.btnChangeTimeLinePlugin_Click ); + // + // tabLipSync + // + this.tabLipSync.BackColor = System.Drawing.SystemColors.Control; + this.tabLipSync.Controls.Add( this.groupSerialVowel ); + this.tabLipSync.Controls.Add( this.groupPhoneticSymbol ); + this.tabLipSync.Location = new System.Drawing.Point( 4, 21 ); + this.tabLipSync.Name = "tabLipSync"; + this.tabLipSync.Padding = new System.Windows.Forms.Padding( 3 ); + this.tabLipSync.Size = new System.Drawing.Size( 401, 377 ); + this.tabLipSync.TabIndex = 1; + this.tabLipSync.Text = "口パク生成"; + this.tabLipSync.UseVisualStyleBackColor = true; + // + // groupSerialVowel + // + this.groupSerialVowel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupSerialVowel.Controls.Add( this.txtCombineThreshold ); + this.groupSerialVowel.Controls.Add( this.lblCombineThreshold ); + this.groupSerialVowel.Controls.Add( this.chkSerialVowel ); + this.groupSerialVowel.Location = new System.Drawing.Point( 8, 277 ); + this.groupSerialVowel.Name = "groupSerialVowel"; + this.groupSerialVowel.Size = new System.Drawing.Size( 385, 89 ); + this.groupSerialVowel.TabIndex = 5; + this.groupSerialVowel.TabStop = false; + this.groupSerialVowel.Text = "その他の設定"; + // + // txtCombineThreshold + // + this.txtCombineThreshold.Location = new System.Drawing.Point( 222, 54 ); + this.txtCombineThreshold.Name = "txtCombineThreshold"; + this.txtCombineThreshold.Size = new System.Drawing.Size( 132, 19 ); + this.txtCombineThreshold.TabIndex = 5; + this.txtCombineThreshold.Text = "0"; + // + // lblCombineThreshold + // + this.lblCombineThreshold.AutoSize = true; + this.lblCombineThreshold.Location = new System.Drawing.Point( 17, 57 ); + this.lblCombineThreshold.Name = "lblCombineThreshold"; + this.lblCombineThreshold.Size = new System.Drawing.Size( 128, 12 ); + this.lblCombineThreshold.TabIndex = 1; + this.lblCombineThreshold.Text = "連続音とみなす無音時間"; + // + // chkSerialVowel + // + this.chkSerialVowel.Location = new System.Drawing.Point( 19, 25 ); + this.chkSerialVowel.Name = "chkSerialVowel"; + this.chkSerialVowel.Size = new System.Drawing.Size( 360, 16 ); + this.chkSerialVowel.TabIndex = 4; + this.chkSerialVowel.Text = "同一母音が連続するとき、口を閉じる"; + this.chkSerialVowel.UseVisualStyleBackColor = true; + // + // groupPhoneticSymbol + // + this.groupPhoneticSymbol.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupPhoneticSymbol.Controls.Add( this.mListClose ); + this.groupPhoneticSymbol.Controls.Add( this.mListU ); + this.groupPhoneticSymbol.Controls.Add( this.mListI ); + this.groupPhoneticSymbol.Location = new System.Drawing.Point( 8, 6 ); + this.groupPhoneticSymbol.Name = "groupPhoneticSymbol"; + this.groupPhoneticSymbol.Size = new System.Drawing.Size( 385, 265 ); + this.groupPhoneticSymbol.TabIndex = 4; + this.groupPhoneticSymbol.TabStop = false; + this.groupPhoneticSymbol.Text = "発音の直前に口の形を変化させる発音記号を指定します"; + // + // tabSystem + // + this.tabSystem.BackColor = System.Drawing.SystemColors.Control; + this.tabSystem.Controls.Add( this.groupAnotherBehavior ); + this.tabSystem.Controls.Add( this.groupEncoder ); + this.tabSystem.Location = new System.Drawing.Point( 4, 21 ); + this.tabSystem.Name = "tabSystem"; + this.tabSystem.Padding = new System.Windows.Forms.Padding( 3 ); + this.tabSystem.Size = new System.Drawing.Size( 401, 377 ); + this.tabSystem.TabIndex = 2; + this.tabSystem.Text = "システム"; + this.tabSystem.UseVisualStyleBackColor = true; + // + // groupAnotherBehavior + // + this.groupAnotherBehavior.Controls.Add( this.chkHeavyOpenCharacterDialog ); + this.groupAnotherBehavior.Controls.Add( this.chkGenCharacterAutomaticaly ); + this.groupAnotherBehavior.Location = new System.Drawing.Point( 6, 118 ); + this.groupAnotherBehavior.Name = "groupAnotherBehavior"; + this.groupAnotherBehavior.Size = new System.Drawing.Size( 389, 94 ); + this.groupAnotherBehavior.TabIndex = 19; + this.groupAnotherBehavior.TabStop = false; + this.groupAnotherBehavior.Text = "その他の動作設定"; + // + // chkHeavyOpenCharacterDialog + // + this.chkHeavyOpenCharacterDialog.Location = new System.Drawing.Point( 14, 56 ); + this.chkHeavyOpenCharacterDialog.Name = "chkHeavyOpenCharacterDialog"; + this.chkHeavyOpenCharacterDialog.Size = new System.Drawing.Size( 364, 16 ); + this.chkHeavyOpenCharacterDialog.TabIndex = 6; + this.chkHeavyOpenCharacterDialog.Text = "プレビュー可能なキャラクタファイル選択ダイアログを使用"; + this.chkHeavyOpenCharacterDialog.UseVisualStyleBackColor = true; + this.chkHeavyOpenCharacterDialog.CheckedChanged += new System.EventHandler( this.chkHeavyOpenCharacterDialog_CheckedChanged ); + // + // chkGenCharacterAutomaticaly + // + this.chkGenCharacterAutomaticaly.Location = new System.Drawing.Point( 14, 27 ); + this.chkGenCharacterAutomaticaly.Name = "chkGenCharacterAutomaticaly"; + this.chkGenCharacterAutomaticaly.Size = new System.Drawing.Size( 364, 16 ); + this.chkGenCharacterAutomaticaly.TabIndex = 5; + this.chkGenCharacterAutomaticaly.Text = "VSQ読込み時にキャラクタを自動生成する"; + this.chkGenCharacterAutomaticaly.UseVisualStyleBackColor = true; + this.chkGenCharacterAutomaticaly.CheckedChanged += new System.EventHandler( this.chkGenCharacterAutomaticaly_CheckedChanged ); + // + // groupEncoder + // + this.groupEncoder.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupEncoder.Controls.Add( this.txtFFmpeg ); + this.groupEncoder.Controls.Add( this.lblFFmpeg ); + this.groupEncoder.Controls.Add( this.btnMEncoder ); + this.groupEncoder.Controls.Add( this.txtMEncoder ); + this.groupEncoder.Controls.Add( this.btnFFmpeg ); + this.groupEncoder.Controls.Add( this.lblMEncoder ); + this.groupEncoder.Location = new System.Drawing.Point( 6, 6 ); + this.groupEncoder.Name = "groupEncoder"; + this.groupEncoder.Size = new System.Drawing.Size( 389, 106 ); + this.groupEncoder.TabIndex = 18; + this.groupEncoder.TabStop = false; + this.groupEncoder.Text = "エンコーダ/デコーダ"; + // + // txtFFmpeg + // + this.txtFFmpeg.Location = new System.Drawing.Point( 100, 32 ); + this.txtFFmpeg.Name = "txtFFmpeg"; + this.txtFFmpeg.Size = new System.Drawing.Size( 248, 19 ); + this.txtFFmpeg.TabIndex = 1; + this.txtFFmpeg.TextChanged += new System.EventHandler( this.txtFFmpeg_TextChanged ); + // + // lblFFmpeg + // + this.lblFFmpeg.AutoSize = true; + this.lblFFmpeg.Location = new System.Drawing.Point( 6, 35 ); + this.lblFFmpeg.Name = "lblFFmpeg"; + this.lblFFmpeg.Size = new System.Drawing.Size( 74, 12 ); + this.lblFFmpeg.TabIndex = 0; + this.lblFFmpeg.Text = "ffmpegの場所"; + // + // btnMEncoder + // + this.btnMEncoder.Location = new System.Drawing.Point( 354, 68 ); + this.btnMEncoder.Name = "btnMEncoder"; + this.btnMEncoder.Size = new System.Drawing.Size( 24, 23 ); + this.btnMEncoder.TabIndex = 4; + this.btnMEncoder.Text = "..."; + this.btnMEncoder.UseVisualStyleBackColor = true; + this.btnMEncoder.Click += new System.EventHandler( this.btnMEncoder_Click ); + // + // txtMEncoder + // + this.txtMEncoder.Location = new System.Drawing.Point( 100, 70 ); + this.txtMEncoder.Name = "txtMEncoder"; + this.txtMEncoder.Size = new System.Drawing.Size( 248, 19 ); + this.txtMEncoder.TabIndex = 3; + this.txtMEncoder.TextChanged += new System.EventHandler( this.txtMEncoder_TextChanged ); + // + // btnFFmpeg + // + this.btnFFmpeg.Location = new System.Drawing.Point( 354, 30 ); + this.btnFFmpeg.Name = "btnFFmpeg"; + this.btnFFmpeg.Size = new System.Drawing.Size( 24, 23 ); + this.btnFFmpeg.TabIndex = 2; + this.btnFFmpeg.Text = "..."; + this.btnFFmpeg.UseVisualStyleBackColor = true; + this.btnFFmpeg.Click += new System.EventHandler( this.btnFFmpeg_Click ); + // + // lblMEncoder + // + this.lblMEncoder.AutoSize = true; + this.lblMEncoder.Location = new System.Drawing.Point( 6, 73 ); + this.lblMEncoder.Name = "lblMEncoder"; + this.lblMEncoder.Size = new System.Drawing.Size( 88, 12 ); + this.lblMEncoder.TabIndex = 15; + this.lblMEncoder.Text = "mencoderの場所"; + // + // numWheelRatio + // + this.numWheelRatio.Location = new System.Drawing.Point( 168, 22 ); + this.numWheelRatio.Minimum = new decimal( new int[] { + 1, + 0, + 0, + 0} ); + this.numWheelRatio.Name = "numWheelRatio"; + this.numWheelRatio.Size = new System.Drawing.Size( 120, 19 ); + this.numWheelRatio.TabIndex = 3; + this.numWheelRatio.Value = new decimal( new int[] { + 50, + 0, + 0, + 0} ); + this.numWheelRatio.ValueChanged += new System.EventHandler( this.numWheelRatio_ValueChanged ); + // + // numEntryHeight + // + this.numEntryHeight.Location = new System.Drawing.Point( 149, 25 ); + this.numEntryHeight.Minimum = new decimal( new int[] { + 10, + 0, + 0, + 0} ); + this.numEntryHeight.Name = "numEntryHeight"; + this.numEntryHeight.Size = new System.Drawing.Size( 120, 19 ); + this.numEntryHeight.TabIndex = 9; + this.numEntryHeight.Value = new decimal( new int[] { + 10, + 0, + 0, + 0} ); + this.numEntryHeight.ValueChanged += new System.EventHandler( this.numEntryHeight_ValueChanged ); + // + // mListClose + // + this.mListClose.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.mListClose.CheckBoxes = true; + this.mListClose.Header = "口を閉じる"; + this.mListClose.HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Left; + this.mListClose.Location = new System.Drawing.Point( 6, 18 ); + this.mListClose.Name = "mListClose"; + this.mListClose.Size = new System.Drawing.Size( 373, 68 ); + this.mListClose.TabIndex = 1; + // + // mListU + // + this.mListU.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.mListU.CheckBoxes = true; + this.mListU.Header = "\"う\"の口"; + this.mListU.HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Left; + this.mListU.Location = new System.Drawing.Point( 6, 167 ); + this.mListU.Name = "mListU"; + this.mListU.Size = new System.Drawing.Size( 373, 87 ); + this.mListU.TabIndex = 3; + // + // mListI + // + this.mListI.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.mListI.CheckBoxes = true; + this.mListI.Header = "\"い\"の口"; + this.mListI.HeaderAlignment = System.Windows.Forms.HorizontalAlignment.Left; + this.mListI.Location = new System.Drawing.Point( 6, 92 ); + this.mListI.Name = "mListI"; + this.mListI.Size = new System.Drawing.Size( 373, 69 ); + this.mListI.TabIndex = 2; + // + // EnvConfiguration + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 409, 461 ); + this.Controls.Add( this.tabControl1 ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnCancel ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "EnvConfiguration"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "オプション"; + this.Load += new System.EventHandler( this.EnvConfiguration_Load ); + this.tabControl1.ResumeLayout( false ); + this.tabUserConfig.ResumeLayout( false ); + this.tabUserConfig.PerformLayout(); + this.groupControl.ResumeLayout( false ); + this.groupControl.PerformLayout(); + this.groupLanguage.ResumeLayout( false ); + this.tabAppearance.ResumeLayout( false ); + this.tabAppearance.PerformLayout(); + this.groupDesign.ResumeLayout( false ); + this.groupDesign.PerformLayout(); + this.groupColor.ResumeLayout( false ); + this.groupColor.PerformLayout(); + this.tabLipSync.ResumeLayout( false ); + this.groupSerialVowel.ResumeLayout( false ); + this.groupSerialVowel.PerformLayout(); + this.groupPhoneticSymbol.ResumeLayout( false ); + this.tabSystem.ResumeLayout( false ); + this.groupAnotherBehavior.ResumeLayout( false ); + this.groupEncoder.ResumeLayout( false ); + this.groupEncoder.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.numWheelRatio)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.numEntryHeight)).EndInit(); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.ComboBox comboLanguage; + private System.Windows.Forms.TabControl tabControl1; + private System.Windows.Forms.TabPage tabUserConfig; + private System.Windows.Forms.TabPage tabLipSync; + private System.Windows.Forms.ColorDialog colorDialog1; + private MListView mListClose; + private MListView mListU; + private MListView mListI; + private System.Windows.Forms.GroupBox groupLanguage; + private System.Windows.Forms.TabPage tabSystem; + private System.Windows.Forms.TextBox txtFFmpeg; + private System.Windows.Forms.Label lblFFmpeg; + private System.Windows.Forms.Button btnFFmpeg; + private System.Windows.Forms.Button btnMEncoder; + private System.Windows.Forms.TextBox txtMEncoder; + private System.Windows.Forms.Label lblMEncoder; + private System.Windows.Forms.FontDialog fontDialog; + private System.Windows.Forms.GroupBox groupPhoneticSymbol; + private System.Windows.Forms.GroupBox groupSerialVowel; + private System.Windows.Forms.CheckBox chkSerialVowel; + private System.Windows.Forms.GroupBox groupEncoder; + private System.Windows.Forms.GroupBox groupAnotherBehavior; + private System.Windows.Forms.CheckBox chkGenCharacterAutomaticaly; + private System.Windows.Forms.TextBox txtCombineThreshold; + private System.Windows.Forms.Label lblCombineThreshold; + private System.Windows.Forms.CheckBox chkHeavyOpenCharacterDialog; + private System.Windows.Forms.Button btnReloadLanguageConfig; + private System.Windows.Forms.TabPage tabAppearance; + private System.Windows.Forms.GroupBox groupColor; + private System.Windows.Forms.Label lblTimeLineTitle; + private System.Windows.Forms.Label lblTimelineTitleColor; + private System.Windows.Forms.Button btnChangeTimeLineTitle; + private System.Windows.Forms.Button btnTimeLineTitleDefault; + private System.Windows.Forms.Label lblTimeLineVSQ; + private System.Windows.Forms.Button btnTimeLineDefaultDefault; + private System.Windows.Forms.Label lblTimeLineVSQColor; + private System.Windows.Forms.Button btnChangeTimeLineDefault; + private System.Windows.Forms.Button btnChangeTimeLineVSQ; + private System.Windows.Forms.Label lblTimeLineDefaultColor; + private System.Windows.Forms.Button btnTimeLineVSQDefault; + private System.Windows.Forms.Label lblTimeLineDefault; + private System.Windows.Forms.Label lblTimeLinePlugin; + private System.Windows.Forms.Button btnTimeLinePluginDefault; + private System.Windows.Forms.Label lblTimeLinePluginColor; + private System.Windows.Forms.Button btnChangeTimeLinePlugin; + private System.Windows.Forms.GroupBox groupDesign; + private NumericUpDownEx numEntryHeight; + private System.Windows.Forms.Button btnFontDefault; + private System.Windows.Forms.Label lblFontName; + private System.Windows.Forms.Label lblFont; + private System.Windows.Forms.Button btnChangeFont; + private System.Windows.Forms.Label lblEntryHeight; + private System.Windows.Forms.Button btnEntryHeightDefault; + private System.Windows.Forms.GroupBox groupControl; + private System.Windows.Forms.Button btnWheelRatioDefault; + private NumericUpDownEx numWheelRatio; + private System.Windows.Forms.Label lblWheelRatio; + private System.Windows.Forms.CheckBox chkSyncAtCenter; + } +} diff --git a/trunk/LipSync/LipSync/Editor/EnvConfiguration.cs b/trunk/LipSync/LipSync/Editor/EnvConfiguration.cs new file mode 100644 index 0000000..338bd5a --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EnvConfiguration.cs @@ -0,0 +1,412 @@ +/* + * EnvConfiguration.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class EnvConfiguration : Form, IMultiLanguageControl { + const string _DEFAULT_LANGUAGE_STRING = "Default"; + EnvSettings m_config; + + public EnvConfiguration( EnvSettings config ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + + m_config = (EnvSettings)config.Clone(); + int selected = -1; + + string[] t_list = Messaging.GetRegisteredLanguage(); + comboLanguage.Items.Clear(); + comboLanguage.Items.Add( _DEFAULT_LANGUAGE_STRING ); + foreach ( string lang in t_list ) { + comboLanguage.Items.Add( lang ); + if ( lang == Messaging.Language ) { + selected = comboLanguage.Items.Count - 1; + } + } + if ( selected >= 0 ) { + comboLanguage.SelectedIndex = selected; + } else { + comboLanguage.SelectedIndex = 0; + } + + // nn + string[] list_nn = new string[] { "b", "p", "m", "b'", "p'", "m'" }; + mListClose.Items.Clear(); + for ( int i = 0; i < list_nn.Length; i++ ) { + string s = list_nn[i]; + mListClose.Items.Add( new ListViewItem( s ) ); + mListClose.Items[i].Checked = VowelType.IsRegisteredToNN( s ); + } + + // i + string[] list_i = new string[] { "k'", "g'", "S", "dZ", "tS", "J", "C" }; + mListI.Items.Clear(); + for ( int i = 0; i < list_i.Length; i++ ) { + string s = list_i[i]; + mListI.Items.Add( new ListViewItem( s ) ); + mListI.Items[i].Checked = VowelType.IsRegisteredToI( s ); + } + + // u + string[] list_u = new string[] { @"p\", @"p\'", "w", "ts", "dz" }; + for ( int i = 0; i < list_u.Length; i++ ) { + string s = list_u[i]; + mListU.Items.Add( new ListViewItem( s ) ); + mListU.Items[i].Checked = VowelType.IsRegisteredToU( s ); + } + //mListClose.BackColor = tabLipSync.BackColor; + //mListI.BackColor = tabLipSync.BackColor; + //mListU.BackColor = tabLipSync.BackColor; + + ScreenFont = m_config.Font.GetFont(); + numWheelRatio.Value = (decimal)(1.0 / m_config.WheelRatio); + + chkGenCharacterAutomaticaly.Checked = m_config.GenerateCharacterAutomatically; + chkHeavyOpenCharacterDialog.Checked = m_config.UseHeavyDialogInOpeningCharacterSettings; + chkSerialVowel.Checked = m_config.CloseMouthWhenSameVowelsRepeated; + + txtFFmpeg.Text = m_config.PathFFmpeg; + txtMEncoder.Text = m_config.PathMEncoder; + + chkSyncAtCenter.Checked = m_config.SyncAtCentre; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.btnOK.Text = _( "OK" ); + this.btnCancel.Text = _( "Cancel" ); + this.groupLanguage.Text = _( "Language" ); + this.Text = _( "Option" ); + + this.tabUserConfig.Text = _( "User Config" ); + this.tabAppearance.Text = _( "Appearance" ); + this.tabLipSync.Text = _( "lip-sync Option" ); + this.tabSystem.Text = _( "System" ); + + this.lblTimeLineTitle.Text = _( "Title of timeline" ); + this.lblTimeLineVSQ.Text = _( "VSQ Entry" ); + this.lblTimeLinePlugin.Text = _( "Plugin Entry" ); + this.lblTimeLineDefault.Text = _( "Another Entry" ); + this.lblEntryHeight.Text = _( "Entry height (pixel)" ); + this.btnChangeTimeLineTitle.Text = _( "Change" ); + this.btnChangeTimeLineVSQ.Text = _( "Change" ); + this.btnChangeTimeLinePlugin.Text = _( "Change" ); + this.btnChangeTimeLineDefault.Text = _( "Change" ); + this.groupPhoneticSymbol.Text = _( "Check phonetic symbol to configure detailed mouth shape control" ); + this.mListClose.Header = _( "Close mouth before pronunciation" ); + this.mListI.Header = _( "\"i\" shaped mouth before pronunciation" ); + this.mListU.Header = _( "\"u\" shaped mouth before pronunciation" ); + this.groupColor.Text = _( "Color" ); + this.groupDesign.Text = _( "Design" ); + this.lblFFmpeg.Text = _( "Path of ffmpeg" ); + this.lblMEncoder.Text = _( "Path of mencoder" ); + this.lblFont.Text = _( "Font" ); + this.btnChangeFont.Text = _( "Change" ); + this.groupSerialVowel.Text = _( "Another settings" ); + this.chkSerialVowel.Text = _( "Close mouth when same vowels repeated" ); + this.groupEncoder.Text = _( "Encoder/Decoder" ); + this.chkGenCharacterAutomaticaly.Text = _( "Generate character automaticaly when importing vsq" ); + this.lblCombineThreshold.Text = _( "Threshold silence length(sec)" ); + this.groupAnotherBehavior.Text = _( "Another settings" ); + this.chkHeavyOpenCharacterDialog.Text = _( "Use preview-enabled dialog in character selection" ); + this.btnReloadLanguageConfig.Text = _( "Reload language configurations" ); + this.groupControl.Text = _( "Operation" ); + this.lblWheelRatio.Text = _( "mouse wheel rate" ); + this.chkSyncAtCenter.Text = _( "Fix cursor to center in Sync mode" ); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + private Font ScreenFont { + get { + return m_config.Font.GetFont(); + } + set { + m_config.Font = new FontConfig( value ); + lblFontName.Text = m_config.Font.GetFont().FontFamily.Name + ", " + m_config.Font.GetFont().SizeInPoints + "pt, " + m_config.Font.GetFont().Style.ToString(); + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + m_config.CloseMouthPhoneticSymbols.Clear(); + foreach ( ListViewItem item in mListClose.Items ) { + if ( item.Checked ) { + m_config.CloseMouthPhoneticSymbols.Add( item.Text ); + } + } + + m_config.IMouthPhoneticSymbols.Clear(); + foreach ( ListViewItem item in mListI.Items ) { + if ( item.Checked ) { + m_config.IMouthPhoneticSymbols.Add( item.Text ); + } + } + + m_config.UMouthPhoneticSymbols.Clear(); + foreach ( ListViewItem item in mListU.Items ) { + if ( item.Checked ) { + m_config.UMouthPhoneticSymbols.Add( item.Text ); + } + } + + try { + m_config.EntryCombineThreshold = float.Parse( txtCombineThreshold.Text ); + } catch { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + this.DialogResult = DialogResult.Cancel; + } + this.DialogResult = DialogResult.OK; + } + + private void EnvConfiguration_Load( object sender, EventArgs e ) { + ApplyColorConfig(); + numEntryHeight.Value = m_config.TrackHeight; + txtCombineThreshold.Text = m_config.EntryCombineThreshold + ""; + } + + private void ApplyColorConfig() { + lblTimelineTitleColor.BackColor = m_config.TimeLineTitleColor.Color; + lblTimeLineVSQColor.BackColor = m_config.TimeLineVsqColor.Color; + lblTimeLinePluginColor.BackColor = m_config.TimeLinePluginColor.Color; + lblTimeLineDefaultColor.BackColor = m_config.TimeLineDefaultColor.Color; + this.Invalidate(); + } + + private void btnChangeTimeLineTitle_Click( object sender, EventArgs e ) { + colorDialog1.Reset(); + colorDialog1.Color = m_config.TimeLineTitleColor.Color; + if ( colorDialog1.ShowDialog() == DialogResult.OK ) { + m_config.TimeLineTitleColor = new ColorSet( colorDialog1.Color ); + ApplyColorConfig(); + } + } + + private void btnChangeTimeLineVSQ_Click( object sender, EventArgs e ) { + colorDialog1.Reset(); + colorDialog1.Color = m_config.TimeLineVsqColor.Color; + if ( colorDialog1.ShowDialog() == DialogResult.OK ) { + m_config.TimeLineVsqColor = new ColorSet( colorDialog1.Color ); + ApplyColorConfig(); + } + } + + private void btnChangeTimeLinePlugin_Click( object sender, EventArgs e ) { + colorDialog1.Reset(); + colorDialog1.Color = m_config.TimeLinePluginColor.Color; + if ( colorDialog1.ShowDialog() == DialogResult.OK ) { + m_config.TimeLinePluginColor = new ColorSet( colorDialog1.Color ); + ApplyColorConfig(); + } + } + + private void btnChangeTimeLineDefault_Click( object sender, EventArgs e ) { + colorDialog1.Reset(); + colorDialog1.Color = m_config.TimeLineDefaultColor.Color; + if ( colorDialog1.ShowDialog() == DialogResult.OK ) { + m_config.TimeLineDefaultColor = new ColorSet( colorDialog1.Color ); + ApplyColorConfig(); + } + } + + private void btnTimeLineTitleDefault_Click( object sender, EventArgs e ) { + m_config.TimeLineTitleColor = new ColorSet( Color.LightPink ); + ApplyColorConfig(); + } + + private void btnTimeLineVSQDefault_Click( object sender, EventArgs e ) { + m_config.TimeLineVsqColor = new ColorSet( Color.FromArgb( 175, 222, 82 ) ); + ApplyColorConfig(); + } + + private void btnTimeLinePluginDefault_Click( object sender, EventArgs e ) { + m_config.TimeLinePluginColor = new ColorSet( Color.FromArgb( 255, 184, 51 ) ); + ApplyColorConfig(); + } + + private void btnTimeLineDefaultDefault_Click( object sender, EventArgs e ) { + m_config.TimeLineDefaultColor = new ColorSet( Color.LightBlue ); + ApplyColorConfig(); + } + + private void btnEntryHeightDefault_Click( object sender, EventArgs e ) { + m_config.TrackHeight = 18; + numEntryHeight.Value = m_config.TrackHeight; + } + + private void numEntryHeight_ValueChanged( object sender, EventArgs e ) { + m_config.TrackHeight = (int)numEntryHeight.Value; + } + + private void btnFFmpeg_Click( object sender, EventArgs e ) { + using ( OpenFileDialog dlg = new OpenFileDialog() ) { + if ( m_config.PathFFmpeg != "" ) { + try { + dlg.InitialDirectory = Path.GetDirectoryName( m_config.PathFFmpeg ); + dlg.FileName = m_config.PathFFmpeg; + } catch { + } + } + try { + dlg.Filter = _( "Executable file(*.exe)|*.exe" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Executable file(*.exe)|*.exe|All Files(*.*)|*.*"; + } + if ( dlg.ShowDialog() == DialogResult.OK ) { + string file = dlg.FileName; + if ( File.Exists( file ) ) { + txtFFmpeg.Text = file; + m_config.PathFFmpeg = file; + } + } + } + } + + private void btnMEncoder_Click( object sender, EventArgs e ) { + using ( OpenFileDialog dlg = new OpenFileDialog() ) { + if ( m_config.PathMEncoder != "" ) { + try { + dlg.InitialDirectory = Path.GetDirectoryName( m_config.PathMEncoder ); + dlg.FileName = m_config.PathMEncoder; + } catch { + } + } + try { + dlg.Filter = _( "Executable file(*.exe)|*.exe" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Executable file(*.exe)|*.exe|All Files(*.*)|*.*"; + } + if ( dlg.ShowDialog() == DialogResult.OK ) { + string file = dlg.FileName; + if ( File.Exists( file ) ) { + txtMEncoder.Text = file; + m_config.PathMEncoder = file; + } + } + } + } + + public string PathFFmpeg { + get { + return txtFFmpeg.Text; + } + set { + txtFFmpeg.Text = value; + } + } + + public string PathMEncoder { + get { + return txtMEncoder.Text; + } + set { + txtMEncoder.Text = value; + } + } + + private void btnChangeFont_Click( object sender, EventArgs e ) { + fontDialog.Font = ScreenFont; + if ( fontDialog.ShowDialog() == DialogResult.OK ) { + ScreenFont = fontDialog.Font; + } + } + + private void btnFontDefault_Click( object sender, EventArgs e ) { + ScreenFont = new Font( "MS UI Gothic", 9 ); + } + + private void btnReloadLanguageConfig_Click( object sender, EventArgs e ) { + Messaging.LoadMessages(); + string current_lang = m_config.Language; + comboLanguage.Items.Clear(); + List list = new List( Messaging.GetRegisteredLanguage() ); + if ( !list.Contains( current_lang ) ) { + current_lang = _DEFAULT_LANGUAGE_STRING; + } + list.Insert( 0, _DEFAULT_LANGUAGE_STRING ); + comboLanguage.Items.AddRange( list.ToArray() ); + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i] == current_lang ) { + comboLanguage.SelectedIndex = i; + break; + } + } + } + + private void comboLanguage_SelectedIndexChanged( object sender, EventArgs e ) { + string res = ""; + if( comboLanguage.SelectedIndex >= 0 ) { + res = (string)comboLanguage.Items[comboLanguage.SelectedIndex]; + } + if ( res == _DEFAULT_LANGUAGE_STRING ) { + res = ""; + } + m_config.Language = res; + } + + private void numWheelRatio_ValueChanged( object sender, EventArgs e ) { + m_config.WheelRatio = (float)(1.0 / (double)numWheelRatio.Value); + } + + private void btnWheelRatioDefault_Click( object sender, EventArgs e ) { + numWheelRatio.Value = 5; + } + + public EnvSettings EnvSettings { + get { + return m_config; + } + } + + private void chkHeavyOpenCharacterDialog_CheckedChanged( object sender, EventArgs e ) { + m_config.UseHeavyDialogInOpeningCharacterSettings = chkHeavyOpenCharacterDialog.Checked; + } + + private void chkGenCharacterAutomaticaly_CheckedChanged( object sender, EventArgs e ) { + m_config.GenerateCharacterAutomatically = chkGenCharacterAutomaticaly.Checked; + } + + private void txtFFmpeg_TextChanged( object sender, EventArgs e ) { + m_config.PathFFmpeg = txtFFmpeg.Text; + } + + private void txtMEncoder_TextChanged( object sender, EventArgs e ) { + m_config.PathMEncoder = txtMEncoder.Text; + } + + private void chkSyncAtCenter_CheckedChanged( object sender, EventArgs e ) { + m_config.SyncAtCentre = chkSyncAtCenter.Checked; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/EnvSettings.cs b/trunk/LipSync/LipSync/Editor/EnvSettings.cs new file mode 100644 index 0000000..efaac18 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/EnvSettings.cs @@ -0,0 +1,351 @@ +/* + * EnvSettings.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Forms; +using System.Xml.Serialization; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + /// + /// 操作環境の設定値を格納します + /// + public class EnvSettings : ICloneable{ + private static XmlSerializer m_xml_serializer = null; + + public float PixelPerSec = 150.0f; + public float WheelRatio = 0.2f; + public int TimeLineInterval = 5; + public Rectangle WindowPosition = new Rectangle( 0, 0, 473, 435 ); + public bool WindowIsMaximized = false; + public Rectangle PreviewWindowPos = new Rectangle( 0, 0, 349, 340 ); + public Rectangle CurveWindowPos = new Rectangle( 0, 0, 349, 340 ); + public bool PreviewMaximized = false; + public bool CurveMaximized = false; + public PictureBoxSizeMode PreviewZoomMode = PictureBoxSizeMode.Zoom; + public string Language = ""; + public ColorSet TimeLineTitleColor = new ColorSet( Color.LightPink ); + public ColorSet TimeLineVsqColor = new ColorSet( Color.FromArgb( 175, 222, 82 ) ); + public ColorSet TimeLinePluginColor = new ColorSet( Color.FromArgb( 255, 184, 51 ) ); + public ColorSet TimeLineDefaultColor = new ColorSet( Color.LightBlue ); + public string PathFFmpeg = ""; + public string PathMEncoder = ""; + public bool PreviewHidden = false; + public float LastPreviewAspecto = 0.5f; + public FontConfig TelopDefaultFont = new FontConfig( "MS UI Gothic", 18 ); + public ColorSet TelopDefaultColor = new ColorSet( Color.Black ); + public bool PropertyHidden = false; + public int LastPropertyWidth = 175; + public int VerticalStringOffset = 3; + public bool CloseMouthWhenSameVowelsRepeated = true; + public bool GenerateCharacterAutomatically = true; + public float EntryCombineThreshold = 0f; + public string LastCharacterPath = ""; + public string LastMusicPath = ""; + public string LastVsqPath = ""; + public bool UseHeavyDialogInOpeningCharacterSettings = false; + public bool DrawBars = true; + /// + /// Vsqトラックを常に表示するかどうかを表す + /// + public bool FixVsqTrackPosition = false; + /// + /// 最後に使用されたAviファイルへのパス + /// + public string LastAviPath = ""; + public FontConfig Font = new FontConfig( "MS UI Gothic", 9 ); + /// + /// キャラクタ設定ファイルの編集時に、静止画ファイルの名前をそのまま画像のタイトルとするかどうか + /// + public bool FileNameAsImageTitle = true; + + private QuantizeMode m_quantize_mode = QuantizeMode.off; // 音符編集時の量子化モード + private bool m_quantize_triplet = false; // 3連符モードが有効かどうか + private bool m_sync_at_centre = true; + private int m_track_height = 15; + private bool m_save_character_config_outside = false; + private List m_close_mouth_phonetic_symbols = new List( new string[] { "b", "p", "m", "b'", "p'", "m'" } ); + private List m_i_mouth_phonetic_symbols = new List( new string[] { "k'", "g'", "S", "dZ", "tS", "J", "C" } ); + private List m_u_mouth_phonetic_symbols = new List( new string[] { @"p\", @"p\'", "w", "ts", "dz" } ); + + public int TrackHeight { + get { + return m_track_height; + } + set { + m_track_height = value; + Size font_size = Misc.MeasureString( "abQBHqj", Font.GetFont() ); + VerticalStringOffset = (m_track_height - font_size.Height) / 2; + } + } + + public static EnvSettings FromFile( string config_file ) { + EnvSettings env; + if ( File.Exists( config_file ) ) { + if ( m_xml_serializer == null ) { + m_xml_serializer = new XmlSerializer( typeof( EnvSettings ) ); + } + FileStream fs = null; + try { + fs = new FileStream( config_file, FileMode.Open ); + env = (EnvSettings)m_xml_serializer.Deserialize( fs ); + } catch { +#if DEBUG + Common.DebugWriteLine( "EnvSettings2+FromFile" ); + Common.DebugWriteLine( " ctor from xml has been failed. trying ctor from EnvSettings." ); +#endif + /*if ( fs != null ) { + fs.Close(); + } + try { + fs = new FileStream( config_file, FileMode.Open ); + BinaryFormatter bf = new BinaryFormatter(); + EnvSettings env1 = (EnvSettings)bf.Deserialize( fs ); + env = new EnvSettings2( env1 ); + } catch ( Exception ex ){ +#if DEBUG + Common.DebugWriteLine( " ex=" + ex.ToString() ); +#endif + env = new EnvSettings2(); + } finally { + if ( fs != null ) { + fs.Close(); + } + }*/ + env = new EnvSettings(); + } finally { + if ( fs != null ) { + fs.Close(); + } + } + } else { + env = new EnvSettings(); + env.Save( config_file ); + } + return env; + } + + public EnvSettings() { + } + + /*internal EnvSettings2( EnvSettings old ) { + PixelPerSec = old.PIXEL_PER_SEC; + WheelRatio = old.WHEEL_RATIO; + TimeLineInterval = old.TIMELINE_INTERVAL; + WindowPosition = old.WINDOW_POS; + WindowIsMaximized = old.MAXIMIZED; + PreviewWindowPos = old.PREVIEW_WINDOW_POS; + CurveWindowPos = new Rectangle( 0, 0, 349, 340 ); + PreviewMaximized = false; + CurveMaximized = false; + PreviewZoomMode = old.PREVIEW_PICTUREMODE; + if ( old.LANGUAGE == LipSync.Language.ja ) { + Language = "ja"; + } else { + Language = ""; + } + TimeLineTitleColor = new ColorSet( old.TIMELINE_TITLE ); + TimeLineVsqColor = new ColorSet( old.TIMELINE_VSQ_ENTRY ); + TimeLinePluginColor = new ColorSet( old.TIMELINE_PLUGIN_ENTRY ); + TimeLineDefaultColor = new ColorSet( old.TIMELINE_DEFAULT_ENTRY ); + PathFFmpeg = old.PATH_FFMPEG; + PathMEncoder = old.PATH_MENCODER; + PreviewHidden = old.PREVIEW_HIDDEN; + LastPreviewAspecto = old.LAST_ASPECTO; + TelopDefaultFont = new FontConfig( old.TELOP_DEFAULT_FONT ); + TelopDefaultColor = new ColorSet( old.TELOP_DEFAULT_COLOR ); + PropertyHidden = old.PROPERTY_HIDDEN; + LastPropertyWidth = old.LAST_PROPERTY_WIDTH; + VerticalStringOffset = old.STRING_OFFSET; + CloseMouthWhenSameVowelsRepeated = old.CLOSE_MOUTH_WHEN_SAME_VOWEL_REPEATED; + GenerateCharacterAutomatically = old.GEN_CHARACTER_AUTOMATICELY; + EntryCombineThreshold = old.COMBINE_THRESHOLD; + LastCharacterPath = old.LAST_CHARACTER_PATH; + LastMusicPath = old.LAST_MUSIC_PATH; + LastVsqPath = old.LAST_VSQ_PATH; + UseHeavyDialogInOpeningCharacterSettings = old.USE_HEAVY_DIALOG; + DrawBars = true; + FixVsqTrackPosition = false; + LastAviPath = ""; + Font = new FontConfig( "MS UI Gothic", 9 ); + m_quantize_mode = QuantizeMode.off; + m_quantize_triplet = false; + m_sync_at_centre = true; + m_track_height = old.TRACK_HEIGHT; + m_save_character_config_outside = false; + m_close_mouth_phonetic_symbols = old.LIST_NN; + m_i_mouth_phonetic_symbols = old.LIST_I; + m_u_mouth_phonetic_symbols = old.LIST_U; + }*/ + + public void Save( string file ) { + if ( m_xml_serializer == null ) { + m_xml_serializer = new XmlSerializer( typeof( EnvSettings ) ); + } + using ( FileStream fs = new FileStream( file, FileMode.Create ) ) { + m_xml_serializer.Serialize( fs, this ); + } + } + + public bool SaveCharacterConfigOutside { + get { + return m_save_character_config_outside; + } + } + + [XmlArrayItem(typeof(string), ElementName="PhoneticSymbol")] + public List CloseMouthPhoneticSymbols { + get { + return m_close_mouth_phonetic_symbols; + } + set { + m_close_mouth_phonetic_symbols = new List( value.ToArray() ); + } + } + + [XmlArrayItem( typeof( string ), ElementName = "PhoneticSymbol" )] + public List IMouthPhoneticSymbols { + get { + return m_i_mouth_phonetic_symbols; + } + set { + m_i_mouth_phonetic_symbols = new List( value.ToArray() ); + } + } + + [XmlArrayItem( typeof( string ), ElementName = "PhoneticSymbol" )] + public List UMouthPhoneticSymbols { + get { + return m_u_mouth_phonetic_symbols; + } + set { + m_u_mouth_phonetic_symbols = new List( value.ToArray() ); + } + } + + public QuantizeMode QuantizeMode { + get { + return m_quantize_mode; + } + set { + m_quantize_mode = value; + } + } + + public bool QuantizeTripletEnabled { + get { + return m_quantize_triplet; + } + set { + m_quantize_triplet = value; + } + } + + public void CleanUpMouthList() { + for ( int i = 0; i < IMouthPhoneticSymbols.Count - 1; i++ ) { + bool changed = true; + while ( changed ) { + changed = false; + for ( int j = i + 1; j < IMouthPhoneticSymbols.Count; j++ ) { + if ( IMouthPhoneticSymbols[i] == IMouthPhoneticSymbols[j] ) { + IMouthPhoneticSymbols.RemoveAt( j ); + changed = true; + break; + } + } + } + } + for ( int i = 0; i < UMouthPhoneticSymbols.Count - 1; i++ ) { + bool changed = true; + while ( changed ) { + changed = false; + for ( int j = i + 1; j < UMouthPhoneticSymbols.Count; j++ ) { + if ( UMouthPhoneticSymbols[i] == UMouthPhoneticSymbols[j] ) { + UMouthPhoneticSymbols.RemoveAt( j ); + changed = true; + break; + } + } + } + } + for ( int i = 0; i < CloseMouthPhoneticSymbols.Count - 1; i++ ) { + bool changed = true; + while ( changed ) { + changed = false; + for ( int j = i + 1; j < CloseMouthPhoneticSymbols.Count; j++ ) { + if ( CloseMouthPhoneticSymbols[i] == CloseMouthPhoneticSymbols[j] ) { + CloseMouthPhoneticSymbols.RemoveAt( j ); + changed = true; + break; + } + } + } + } + } + + public bool SyncAtCentre { + get { + return m_sync_at_centre; + } + set { + m_sync_at_centre = value; + } + } + + public object Clone() { + EnvSettings res = new EnvSettings(); + res.CloseMouthWhenSameVowelsRepeated = this.CloseMouthWhenSameVowelsRepeated; + res.EntryCombineThreshold = this.EntryCombineThreshold; + res.GenerateCharacterAutomatically = this.GenerateCharacterAutomatically; + res.Language = this.Language; + res.LastPreviewAspecto = this.LastPreviewAspecto; + res.LastCharacterPath = this.LastCharacterPath; + res.LastMusicPath = this.LastMusicPath; + res.LastPropertyWidth = this.LastPropertyWidth; + res.LastVsqPath = this.LastVsqPath; + res.IMouthPhoneticSymbols = new List( this.IMouthPhoneticSymbols.ToArray() ); + res.CloseMouthPhoneticSymbols = new List( this.CloseMouthPhoneticSymbols.ToArray() ); + res.UMouthPhoneticSymbols = new List( this.UMouthPhoneticSymbols.ToArray() ); + res.WindowIsMaximized = this.WindowIsMaximized; + res.PathFFmpeg = this.PathFFmpeg; + res.PathMEncoder = this.PathMEncoder; + res.PixelPerSec = this.PixelPerSec; + res.PreviewZoomMode = this.PreviewZoomMode; + res.PropertyHidden = this.PropertyHidden; + res.Font = (FontConfig)this.Font.Clone(); + res.VerticalStringOffset = this.VerticalStringOffset; + res.TelopDefaultColor = this.TelopDefaultColor; + res.TelopDefaultFont = this.TelopDefaultFont; + res.TimeLineDefaultColor = this.TimeLineDefaultColor; + res.TimeLineInterval = this.TimeLineInterval; + res.TimeLinePluginColor = this.TimeLinePluginColor; + res.TimeLineTitleColor = this.TimeLineTitleColor; + res.TimeLineVsqColor = this.TimeLineVsqColor; + res.TrackHeight = this.TrackHeight; + res.UseHeavyDialogInOpeningCharacterSettings = this.UseHeavyDialogInOpeningCharacterSettings; + res.WheelRatio = this.WheelRatio; + res.WindowPosition = this.WindowPosition; + res.DrawBars = this.DrawBars; + res.m_quantize_mode = this.m_quantize_mode; + res.m_quantize_triplet = this.m_quantize_triplet; + res.m_sync_at_centre = this.m_sync_at_centre; + return res; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FontConfig.cs b/trunk/LipSync/LipSync/Editor/FontConfig.cs new file mode 100644 index 0000000..ed9af3c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FontConfig.cs @@ -0,0 +1,89 @@ +/* + * FontConfig.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + /// + /// フォントの設定値をXmlSerializerで"美しく"格納するためのクラス + /// + public class FontConfig : ICloneable{ + string m_font_family; + FontStyle m_font_style; + float m_font_size; + Font m_font = null; + + public string Family { + get { + return m_font_family; + } + set { + m_font_family = value; + } + } + + public string Style { + get { + return m_font_style + ""; + } + set { + m_font_style = (FontStyle)System.Enum.Parse( typeof( FontStyle ), value ); + } + } + + public float Size { + get { + return m_font_size; + } + set { + m_font_size = value; + } + } + + public FontConfig() { + m_font_family = "MS UI Gothic"; + m_font_style = FontStyle.Regular; + m_font_size = 18; + } + + public FontConfig( Font value ) { + m_font_family = value.FontFamily.Name; + m_font_style = value.Style; + m_font_size = value.Size; + } + + public FontConfig( string family, float size ) { + m_font_family = family; + m_font_size = size; + m_font_style = FontStyle.Regular; + } + + public Font GetFont() { + if ( m_font == null ) { + m_font = new Font( m_font_family, m_font_size, m_font_style ); + } + return m_font; + } + + public object Clone() { + FontConfig ret = new FontConfig(); + ret.m_font_family = m_font_family; + ret.m_font_size = m_font_size; + ret.m_font_style = m_font_style; + return ret; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Form1.cs b/trunk/LipSync/LipSync/Editor/Form1.cs new file mode 100644 index 0000000..be51d96 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Form1.cs @@ -0,0 +1,3727 @@ +/* + * Form1.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.IO; +using System.Reflection; +using System.Text; +using System.Threading; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; +using Boare.Lib.Media; +using Boare.Lib.Vsq; +using Plugin; +#if DEBUG +using Boare.Lib.Swf; +#endif + +namespace LipSync { + + public partial class Form1 : Form, IMultiLanguageControl { + #region Constants + private const byte FILEFORMAT = 1; + /// + /// プレビューとタイムラインのシンクロを行うとき、次の画面へ移動する時の両側の重複部分の幅 + /// + private const float SIDE_WIDTH = 0.15f; + /// + /// m_editHandleLeft, Rightの幅 + /// + private const int HANDLE_WIDTH = 8; + /// + /// 自動スクロール適用直後、画面の中央が、現在の再生時刻位置まで滑らかに移動するブレンド時間 + /// + private const float FIT_CENTER_BREND_TIME = 2f; + const int BUF_LEN = 10; + #endregion + + #region Static Readonly Field + private static readonly AuthorListEntry[] m_credit = new AuthorListEntry[]{ + new AuthorListEntry( "is developped by:", FontStyle.Italic ), + new AuthorListEntry( "kbinani" ), + new AuthorListEntry( "and he thanks to:", FontStyle.Italic ), + new AuthorListEntry(), + new AuthorListEntry( "author of embedded character", FontStyle.Italic ), + new AuthorListEntry( "さなり" ), + new AuthorListEntry(), + new AuthorListEntry( "contributors", FontStyle.Italic ), + new AuthorListEntry( "evm" ), + new AuthorListEntry( "鈴村優" ), + new AuthorListEntry( "そろそろP" ), + new AuthorListEntry( "めがね110" ), + new AuthorListEntry( "上総" ), + new AuthorListEntry( "NOIKE" ), + new AuthorListEntry( "逃亡者" ), + new AuthorListEntry(), + new AuthorListEntry( "translator", FontStyle.Italic ), + new AuthorListEntry( "E-Avalance" ), + new AuthorListEntry(), + new AuthorListEntry( "bugs and suggestions reporters", FontStyle.Italic ), + new AuthorListEntry( "だんちゃん" ), + new AuthorListEntry( "灰" ), + new AuthorListEntry( "sanryo" ), + new AuthorListEntry( "やなぎがうら" ), + new AuthorListEntry( "elthy" ), + new AuthorListEntry( "fyfy" ), + new AuthorListEntry( "k-roh" ), + new AuthorListEntry( "さえ" ), + new AuthorListEntry( "上総" ), + new AuthorListEntry( "MI" ), + new AuthorListEntry( "ほとほと" ), + new AuthorListEntry( "IGASIO" ), + new AuthorListEntry( "PEX" ), + new AuthorListEntry(), + new AuthorListEntry( "and you.", FontStyle.Bold | FontStyle.Italic ), + }; + private static readonly Pen HILIGHT = new Pen( Color.Gray, 2 ); + private static readonly Pen HILIGHT_EDIT = new Pen( Color.Red, 2 ); + private static readonly Color REPEAT_AREA = Color.FromArgb( 105, 139, 105 ); + private static readonly Pen _PEN_123_123_123 = new Pen( Color.FromArgb( 123, 123, 123 ) ); + private static readonly SolidBrush _BRS_TRACKBG_ODD = new SolidBrush( Color.FromArgb( 240, 240, 240 ) ); + private static readonly SolidBrush _BRS_TRACKBG_EVEN = new SolidBrush( Color.FromArgb( 212, 212, 212 ) ); + private static readonly SolidBrush _BRS_TRACK_NAME = new SolidBrush( Color.FromArgb( 80, 80, 80 ) ); + private static readonly Pen _PEN_BOUNDS = new Pen( new HatchBrush( HatchStyle.Percent50, Color.Black, Color.White ), 4 ); + private static readonly Pen _PEN_FIXED_BOUNDS = new Pen( new HatchBrush( HatchStyle.Percent50, Color.Red, Color.White ), 4 ); + #endregion + + #region Static Field + //private static Color CANVAS_BACKGROUND_HILIGHT = Color.Black; + #endregion + + #region Field + /// + /// ファイルには保存されていたが、現在の環境では使えないプラグインのトラック情報。 + /// 読込時に判定して作成し、保存時には一応保存する。 + /// + private List m_not_used_plugin = new List(); + private List m_not_used_plugin_config = new List(); + /// + /// 変更可能な設定値 + /// + //private EnvSettings AppManager.Config = new EnvSettings(); + private Color TRIANGLE_COLOR = Color.SteelBlue; + /// + /// pictureBox1上のマウスの位置 + /// + private Point m_mousePosition; + /// + /// pictureBox1上のクリックされたアイテムの場所 + /// + private Item m_clicked; + private Rectangle m_rcHilight; + /// + /// エントリの編集モードで、マウスカーソルを変更するべきエリア + /// + private Rectangle m_editHandleLeft = new Rectangle(); + private Rectangle m_editHandleRight = new Rectangle(); + private Item m_edit_handle_ed_item; + private string m_filePath = ""; + private int m_startToDrawX = 0; + private int m_startToDrawY = 0; + private PointF m_expandRange; + private bool m_initialized = false; + //private bool m_edited = false; + /// + /// コピーされたタイムテーブル + /// + private TimeTable m_copied_timetable = null; + private Color TOOL_COLOR = Color.DarkGray; + /// + /// トラック上のドラッグによりエントリを追加するもーど中に保持される、もともとのタイムテーブルグループのキャッシュ + /// + private TimeTableGroup m_editing_group; + /// + /// ドラッグ中のアイテム + /// + private Item m_dragging; + private float m_editing_t1, m_editing_t2; + private TimeTableEntry m_copied_entry = null; + private Telop m_copied_telop = null; + private Item m_copied; + private EditMode m_edit_mode = EditMode.None; + /// + /// ドラッグによりエントリをスライドするモードで、スライド開始前の、エントリのもともとのbegin時刻 + /// + private TimeTableEntry m_slide_original = null; + private bool m_slide_moved = false; + //private float m_total_memory = 0f; +#if DEBUG + private long m_counter = 0L; +#endif + private DateTime m_preview_time; + private VersionInfo m_version_form = null; + + private bool m_avi_writing = false; + private Keys m_last_key = Keys.None; + private int m_realtime_group = 0; + private int m_realtime_track; + private int m_realtime_entry; + private DisplacementControl m_curve; + private bool m_is_repeat_mode = false; + /// + /// Paintイベントをスキップする必要のある時true + /// + private bool m_skip_paint = false; + /// + /// クオンタイズする際のグリッド時刻のリスト。スクロールバーが移動した時、更新 + /// + private float[] m_grids; + /// + /// VSQトラックを固定表示する場合の、VSQトラック表示部分の高さ + /// + private int m_vsq_height = 0; + private FormPreview m_form_preview; + bool m_avi_cancel = false; + Thread m_stdout; + Process m_ffmpeg; + Process m_mencoder; + bool m_is_rawmode = false; + private int m_current_frame = 0; + private MediaPlayer m_player; + private ZorderItem m_editing_item = null; + private EditingBounds m_editing = new EditingBounds(); + /// + /// 最初画像がクリックされた位置の、画像座標系での位置 + /// + private Point m_base_point; + /// + /// 画像がクリックされた時点での、その画像の位置設定情報 + /// + private Point m_init_position; + /// + /// テキストエディットモード + /// + bool m_text_edit = false; + /// + /// 編集中のテキスト + /// + TextBox m_text = null; + /// + /// オリジナルのテキスト + /// + string m_text_original; + /// + /// 編集しているテキストのID + /// + int m_text_id; + double[] m_buf = new double[BUF_LEN]; + double m_fps; + DateTime m_last_ignitted = new DateTime(); + private DateTime m_started_date; + private Thread m_preview_thread = null; + private BSplitContainer m_panels; + private Telop m_editing_telop_original = null; + #endregion + + private delegate void ChangeTitleTextDelegate( string encoder_type, int percent, int current_frame, int max_frames ); + private delegate void ForceScreenUpdateDelegate(); + private delegate void Form1_AviWritingChange( bool value ); + + public Form1( string file ) { + AppManager.SaveData = new SettingsEx(); + m_filePath = file; + InitializeComponent(); + + m_panels = new BSplitContainer(); + + // m_panels + m_panels.Name = "m_panels"; + m_panels.Orientation = Orientation.Vertical; + m_panels.Panel1.BorderColor = SystemColors.ControlDark; + m_panels.Panel1.BorderStyle = BorderStyle.FixedSingle; + m_panels.Panel2.BorderColor = SystemColors.ControlDark; + m_panels.Panel2.BorderStyle = BorderStyle.FixedSingle; + m_panels.FixedPanel = FixedPanel.Panel1; + m_panels.Panel1.Controls.Add( previewer ); + m_panels.Panel2.Controls.AddRange( new Control[]{ side, + pictureBox1, + hScrollBar1, + vScrollBar1, + pictureBox2, + preview_image } ); + m_panels.Panel1MinSize = 0; + m_panels.Panel2.SizeChanged += new EventHandler( Panel2_SizeChanged ); + m_container.FixedPanel = FixedPanel.Panel1; + m_container.Panel1.Controls.Add( property ); + m_container.Panel2.Controls.Add( m_panels ); + m_panels.Dock = DockStyle.Fill; + property.Dock = DockStyle.Fill; + previewer.Dock = DockStyle.Fill; + + this.pictureBox1.MouseWheel += new MouseEventHandler( pictureBox1_MouseWheel ); + m_player = new MediaPlayer(); + previewer.TrackVolumeValue = m_player.Volume; + Messaging.LoadMessages(); + LoadConfig(); + this.SizeChanged += new EventHandler( Form1_LocationOrSizeChanged ); + this.LocationChanged += new EventHandler( Form1_LocationOrSizeChanged ); + AppManager.EditedChanged += new EventHandler( AppManager_EditedChanged ); + m_form_preview = new FormPreview(); + m_form_preview.FormClosing += new FormClosingEventHandler( m_form_preview_FormClosing ); + m_curve = new DisplacementControl(); + m_curve.FormClosing += new FormClosingEventHandler( m_curve_FormClosing ); + menuVisualVsqTrack.Checked = AppManager.Config.FixVsqTrackPosition; + ApplyLanguage(); + } + + private void m_curve_FormClosing( object sender, FormClosingEventArgs e ) { + e.Cancel = true; + menuVisualTransform.Checked = false; + } + + private void AppManager_EditedChanged( object sender, EventArgs e ) { + UpdateFormTitle(); + UpdateObjectList(); + menuEditRedo.Enabled = AppManager.IsRedoAvailable; //ExecuteとResiterが離れているので,ここで更新する必要がある + menuEditUndo.Enabled = AppManager.IsUndoAvailable; + if ( AppManager.Edited ) { + this.Invalidate(); + } + } + + private void Panel2_SizeChanged( object sender, EventArgs e ) { + ResizePanel2(); + } + + private void m_form_preview_FormClosing( object sender, FormClosingEventArgs e ) { + e.Cancel = true; + m_form_preview.Hide(); + previewer.Parent = m_panels.Panel1; + int total_height = m_panels.Panel1.Height + m_panels.Panel2.Height; + int new_distance = (int)(total_height * AppManager.Config.LastPreviewAspecto); + m_panels.SplitterDistance = new_distance; + m_panels.IsSplitterFixed = false; + menuVisualPreviewSeparate.Checked = false; + } + + #region property + private void property_TelopDeleting( ZorderItem e ) { +#if DEBUG + Common.DebugWriteLine( "property1_TelopDeleting" ); + Common.DebugWriteLine( " e.Type=" + e.Type ); +#endif + if ( e.Type == ZorderItemType.telop ) { + Command run = Command.GCommandDeleteTelop( AppManager.SaveData[e.Index] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + Telop.DecideLane( AppManager.SaveData.m_telop_ex2 ); + property.Editing = null; + if ( m_curve.comboObjects.SelectedItem != null ){ + TagForTreeNode t = (TagForTreeNode)m_curve.comboObjects.SelectedItem; + if ( t.type == ZorderItemType.telop && t.id_or_index == e.Index ) { + m_curve.SetSelectedNone(); + } + } + SetVScrollRange(); + } + } + + private void property_EditingItemChanged( ZorderItem item ) { +#if DEBUG + Common.DebugWriteLine( "property1_EditingItemChanged" ); +#endif + if ( item != null ) { + switch ( item.Type ) { + case ZorderItemType.another: + property.SelectedObject = AppManager.SaveData.m_group_another[item.Index].Clone(); + break; + case ZorderItemType.character: + property.SelectedObject = AppManager.SaveData.m_groups_character[item.Index].Clone(); + break; + case ZorderItemType.telop: + //Telop.DecideLane( AppManager.SaveData.m_telop_ex2 ); + property.SelectedObject = AppManager.SaveData[item.Index].Clone(); + break; + } + } else { + property.SelectedObject = null; + } + } + + private void property_TelopAdding() { + h_addTelop( this, new EventArgs() ); + } + + private void property_PropertyValueChanged( object sender, PropertyValueChangedEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "property1_PropertyValueChanged(object,PropertyValueChangedEventArgs)" ); +#endif + int target = property.Editing.Index; + string start = ""; + string type = ""; + string name = ""; + +#if DEBUG + Common.DebugWriteLine( " (property1.SelectedObject is TimeTable) =" + (property.SelectedObject is TimeTable) ); + Common.DebugWriteLine( " (property1.SelectedObject is TimeTableGroup)=" + (property.SelectedObject is TimeTableGroup) ); + Common.DebugWriteLine( " (property1.SelectedObject is Telop) =" + (property.SelectedObject is Telop) ); +#endif + // property1.SelectedObjectは,それぞれの編集対象の単なるクローンなので, + // 変更されたらCommandを使って本体を更新する必要がある + if ( property.SelectedObject is TimeTable ) { + Command run = Command.GCommandEditTimeTable( TimeTableType.another, -1, target, (TimeTable)property.SelectedObject ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + start = AppManager.SaveData[TimeTableType.another, -1].GetFirstOn( target ) + ""; + type = "another"; + name = AppManager.SaveData[TimeTableType.another, -1][target].Text; + } else if ( property.SelectedObject is TimeTableGroup ) { + Command run = Command.GCommandEditGroup( TimeTableType.character, target, (TimeTableGroup)property.SelectedObject ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + start = "" + AppManager.SaveData[TimeTableType.character, target].GetFirstOn(); + type = "character"; + name = AppManager.SaveData[TimeTableType.character, target].Text; + } else if ( property.SelectedObject is Telop ) { + Command run = Command.GCommandEditTelop( target, (Telop)property.SelectedObject ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + start = "" + AppManager.SaveData[target].Start; + type = "telop"; + name = AppManager.SaveData[target].Text; + } + + // property1.ListViewの表示内容を更新 + ZorderItem editing = property.Editing; +#if DEBUG + Common.DebugWriteLine( " editing.Type=" + editing.Type ); + Common.DebugWriteLine( " editing.Index=" + editing.Index ); + Common.DebugWriteLine( " editing.Name=" + editing.Name ); + bool found = false; +#endif + foreach ( ListViewItem item in property.ListView.Items ) { + if ( item.Tag is ZorderItem ) { + ZorderItem zitem = (ZorderItem)item.Tag; + if ( zitem.Type == editing.Type && zitem.Index == editing.Index ) { + item.SubItems[0].Text = start; + item.SubItems[1].Text = type; + item.SubItems[2].Text = name; +#if DEBUG + found = true; +#endif + break; + } + } + } + +#if DEBUG + Common.DebugWriteLine( "found=" + found ); +#endif + UpdateEditHandle(); + AppManager.Edited = true; + } + #endregion + + #region hScrollBar1 + private void hScrollBar1_Scroll( object sender, ScrollEventArgs e ) { + m_startToDrawX = StartToDrawX(); + UpdateGridList(); + pictureBox1.Invalidate(); + } + #endregion + + private void vScrollBar1_Scroll( object sender, ScrollEventArgs e ) { + m_startToDrawY = StartToDrawY(); + side.Refresh(); + pictureBox1.Refresh(); + } + + #region pictureBox1 + private void pictureBox1_MouseWheel( object sender, MouseEventArgs e ) { + if ( (Control.ModifierKeys & Keys.Shift) == Keys.Shift ) { + if ( vScrollBar1.Enabled ) { + int prev = vScrollBar1.Value; + float add = -(float)e.Delta / AppManager.Config.WheelRatio; + int set = (int)((float)prev + add); + if ( set > vScrollBar1.Maximum + 1 - vScrollBar1.LargeChange ) { + set = vScrollBar1.Maximum + 1 - vScrollBar1.LargeChange; + } else if ( set < vScrollBar1.Minimum ) { + set = vScrollBar1.Minimum; + } + if ( prev != set ) { + vScrollBar1.Value = set; + m_startToDrawY = StartToDrawY(); + pictureBox1.Invalidate(); + side.Invalidate(); + } + } + } else { + if ( hScrollBar1.Enabled ) { + int prev = hScrollBar1.Value; + float add = -(float)e.Delta / AppManager.Config.WheelRatio; + int set = (int)((float)prev + add); + if ( set > hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange ) { + set = hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange; + } else if ( set < hScrollBar1.Minimum ) { + set = hScrollBar1.Minimum; + } + if ( prev != set ) { + hScrollBar1.Value = set; + m_startToDrawX = StartToDrawX(); + pictureBox1.Invalidate(); + } + UpdateGridList(); + } + } + } + + private void pictureBox1_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e ) { + if ( e.KeyCode == Keys.Delete ) { + DeleteEntry(); + } + if ( AppManager.Playing && menuEditRealTime.Checked ) { + if ( m_last_key == e.KeyCode ) { + return; + } + string target = ""; + float m_end = Now; + switch ( e.KeyCode ) { + case Keys.A: + target = "a"; + break; + case Keys.I: + target = "i"; + break; + case Keys.U: + target = "u"; + break; + case Keys.E: + target = "e"; + break; + case Keys.O: + target = "o"; + break; + case Keys.Space: + if ( m_last_key != Keys.None ) { + TimeTableEntry tte = (TimeTableEntry)AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track][m_realtime_entry].Clone(); + tte.end = m_end; + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track][m_realtime_entry].end = m_end; + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track].RemoveAt( m_realtime_entry ); + Command run = Command.GCommandAddTimeTableEntry( TimeTableType.character, + m_realtime_group, + m_realtime_track, + tte ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + m_last_key = Keys.None; + return; + default: + return; + } + //まず、直前に入力されたエントリを終了させる処理 + if ( m_last_key != Keys.None ) { + TimeTableEntry tte = (TimeTableEntry)AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track][m_realtime_entry].Clone(); + tte.end = m_end; + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track].RemoveAt( m_realtime_entry ); + Command run = Command.GCommandAddTimeTableEntry( TimeTableType.character, + m_realtime_group, + m_realtime_track, + tte ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + //今しがた押されたキーに対応するエントリを追加。 + for ( int i = 0; i < AppManager.SaveData.m_groups_character[m_realtime_group].Count; i++ ) { + if ( AppManager.SaveData.m_groups_character[m_realtime_group][i].Text == target ) { + m_realtime_track = i; + break; + } + } + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track].Add( new TimeTableEntry( m_end, m_end, target ) ); + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track].Sort(); + //sortしたのでm_realtime_entryを検索で探す + for ( int entry = 0; entry < AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track].Count; entry++ ) { + if ( AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track][entry].begin == m_end ) { + m_realtime_entry = entry; + break; + } + } + m_last_key = e.KeyCode; + } + } + + private void pictureBox1_MouseClick( object sender, MouseEventArgs e ) { + m_mousePosition.X = e.X; + m_mousePosition.Y = e.Y; + + if ( e.Button == MouseButtons.Right ) { + if ( 0 <= e.Y && e.Y <= AppManager.Config.TrackHeight ) { + cmenuRepeat.Show( pictureBox1, e.X, e.Y ); + return; + } + } + + if ( m_edit_mode == EditMode.Dragging ) { + return; + } + + if ( m_edit_mode == EditMode.Sliding ) { + if ( m_slide_moved ) { + return; + } + m_edit_mode = EditMode.None; + } + + if ( m_edit_mode == EditMode.Selected ) { + if ( e.Button == MouseButtons.Right ) { + m_edit_mode = EditMode.None; + } + } + + if ( m_edit_mode == EditMode.None/*!m_editMode*/ ) { + m_clicked = GetGroupItem( m_mousePosition.X + m_startToDrawX, m_mousePosition.Y + m_startToDrawY ); + if ( e.Button == MouseButtons.Right ) { + #region 右クリック + m_edit_mode = EditMode.None; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + + if ( !cmenu.IsDisposed || cmenu != null ) { + cmenu.Dispose(); + } + cmenu = new ContextMenuStrip(); + cmenu.RenderMode = ToolStripRenderMode.ManagerRenderMode; + cmenu.ShowCheckMargin = false; + cmenu.ShowImageMargin = false; + cmenu.Font = AppManager.Config.Font.GetFont(); + + if ( m_clicked.type == TimeTableType.top ) { + return; + } + if ( group < 0 ) { + cmenu.Items.Add( _( "Video size configuration" ), + null, + new EventHandler( h_setVideoSize ) ); + } else { + if ( track < 0 ) { + #region タイトルがクリックされたとき + switch ( m_clicked.type ) { + case TimeTableType.vsq: + cmenu.Items.Add( _( "Read from VSQ file" ), null, new EventHandler( h_readVsq ) ); + break; + case TimeTableType.character: + if ( AppManager.SaveData.m_groups_character[group].Character != null ) { + cmenu.Items.Add( _( "Edit character" ), null, new EventHandler( h_editCharacter ) ); + if ( AppManager.SaveData.m_groups_character[group].Character.Type == CharacterType.def ) { + cmenu.Items.Add( "-" ); + cmenu.Items.Add( _( "Preview image" ), null, new EventHandler( h_previewImage ) ); + cmenu.Items.Add( _( "Image placement" ), null, new EventHandler( h_setImagePosition ) ); + cmenu.Items.Add( _( "Scale setting" ), null, new EventHandler( h_setScale ) ); + cmenu.Items.Add( "-" ); + cmenu.Items.Add( _( "Generate wink" ), null, new EventHandler( h_addWink ) ); + } + } + cmenu.Items.Add( "-" ); + cmenu.Items.Add( _( "Delete" ), null, new EventHandler( h_deleteTrack ) ); + break; + case TimeTableType.telop: + cmenu.Items.Add( _( "Add Telop" ), null, new EventHandler( h_addTelop ) ); + break; + case TimeTableType.another: + cmenu.Items.Add( _( "Add track" ), null, new EventHandler( h_addTrack ) ); + break; + } + #endregion + } else { + bool copy_enabled = true; + if ( entry < 0 ) { + #region トラックがクリックされたとき + switch ( m_clicked.type ) { + case TimeTableType.vsq: + cmenu.Items.Add( _( "Generate Lipsync from this track" ), null, new EventHandler( h_genMouthFromVsq ) ); + if ( AppManager.SaveData.m_group_vsq[track].Count == 0 ) { + copy_enabled = false; + } + break; + case TimeTableType.character: + cmenu.Items.Add( _( "Note ON from here" ) + "(&O)", + null, + new EventHandler( h_noteON ) ); + cmenu.Items.Add( _( "Preview image" ), + null, + new EventHandler( h_previewImage ) ); + if ( AppManager.SaveData.m_groups_character[group][track].Count == 0 ) { + copy_enabled = false; + } + break; + case TimeTableType.another: + cmenu.Items.Add( _( "Note ON from here" ) + "(&O)", + null, + new EventHandler( h_noteON ) ); + if ( AppManager.SaveData.m_group_another[track].Image == null ) { + cmenu.Items.Add( _( "Set image" ), + null, + new EventHandler( h_setImage ) ); + } else { + cmenu.Items.Add( _( "Preview image" ), + null, + new EventHandler( h_previewImage ) ); + cmenu.Items.Add( _( "Change image" ), + null, + new EventHandler( h_setImage ) ); + } + ToolStripMenuItem mItemImage = new ToolStripMenuItem( _( "Image" ) ); + mItemImage.DropDown = new ContextMenuStrip(); + ((ContextMenuStrip)mItemImage.DropDown).Items.Add( _( "Image placement" ), + null, + new EventHandler( h_setImagePosition ) ); + ((ContextMenuStrip)mItemImage.DropDown).Items.Add( _( "Scale setting" ), + null, + new EventHandler( h_setScale ) ); + ((ContextMenuStrip)mItemImage.DropDown).ShowCheckMargin = false; + ((ContextMenuStrip)mItemImage.DropDown).ShowImageMargin = false; + cmenu.Items.Add( mItemImage ); + if ( AppManager.SaveData.m_group_another[track].Count == 0 ) { + copy_enabled = false; + } + break; + case TimeTableType.plugin: + cmenu.Items.Add( _( "Note ON from here" ) + "(&O)", + null, + new EventHandler( h_noteON ) ); + if ( AppManager.SaveData.m_group_plugin[track].Count == 0 ) { + copy_enabled = false; + } + break; + } + + //エントリの貼付け + if ( m_clicked.type != TimeTableType.vsq ) { + cmenu.Items.Add( _( "Paste" ) + "(&V)", + null, + new EventHandler( h_pasteEntry ) ); + if ( m_copied_entry == null && m_copied_telop == null ) { + cmenu.Items[cmenu.Items.Count - 1].Enabled = false; + } + } + + + #endregion + } else { + #region エントリがクリックされたとき + copy_enabled = true;//エントリがクリックされたので、エントリの個数は1個以上! + if ( m_clicked.type != TimeTableType.vsq ) { + cmenu.Items.Add( _( "Note OFF" ) + "(&O)", null, new EventHandler( h_noteOFF ) ); + if ( m_clicked.type == TimeTableType.character ) { + cmenu.Items.Add( _( "Image Preview" ), null, new EventHandler( h_previewImage ) ); + } + cmenu.Items.Add( _( "Numeric Entry" ) + "(&N)", null, new EventHandler( h_editEntry ) ); + if ( m_clicked.type != TimeTableType.telop ) { + cmenu.Items.Add( _( "Expand" ) + "(&E)", null, new EventHandler( h_expandEntry ) ); + } + cmenu.Items.Add( "-" ); + + // グループ固有の機能 + if ( m_clicked.type == TimeTableType.another ) { + if ( AppManager.SaveData.m_group_another[track].Image == null ) { + //if ( s.m_group_another[track].GetImage( 0f ) == null ) { + cmenu.Items.Add( _( "Set Image" ), null, new EventHandler( h_setImage ) ); + } else { + cmenu.Items.Add( _( "Preview Image" ), null, new EventHandler( h_previewImage ) ); + cmenu.Items.Add( _( "Change Image" ), null, new EventHandler( h_setImage ) ); + } + ToolStripMenuItem mItemImage = new ToolStripMenuItem( _( "Image" ) ); + mItemImage.DropDown = new ContextMenuStrip(); + ((ContextMenuStrip)mItemImage.DropDown).Items.Add( _( "Image placement" ), + null, + new EventHandler( h_setImagePosition ) ); + ((ContextMenuStrip)mItemImage.DropDown).Items.Add( _( "Scale setting" ), + null, + new EventHandler( h_setScale ) ); + ((ContextMenuStrip)mItemImage.DropDown).ShowCheckMargin = false; + ((ContextMenuStrip)mItemImage.DropDown).ShowImageMargin = false; + cmenu.Items.Add( mItemImage ); + cmenu.Items.Add( "-" ); + } else if ( m_clicked.type == TimeTableType.plugin ) { + if ( (AppManager.SaveData.m_plugins[m_clicked.track].Instance.Type & Constants.LS_ENABLES_ENTRY_SETTING) == Constants.LS_ENABLES_ENTRY_SETTING ) { + cmenu.Items.Add( _( "Plugin config. of this entry" ), null, new EventHandler( h_entrySetting ) ); + cmenu.Items.Add( "-" ); + } + } + + //編集系の共通コマンド + cmenu.Items.Add( _( "Copy" ) + "(&C)", null, new EventHandler( h_copyEntry ) ); + cmenu.Items.Add( _( "Cut" ) + "(&X)", null, new EventHandler( h_cutEntry ) ); + cmenu.Items.Add( _( "Split Entry" ) + "(&S)", null, new EventHandler( h_splitEntry ) ); + } + #endregion + } + + #region タイムライン用の共通コマンド + //タイムライン + if ( m_clicked.type != TimeTableType.telop ) { + ToolStripMenuItem mItemTimeline = new ToolStripMenuItem( _( "Timeline" ) ); + ContextMenuStrip cItemTimeline = new ContextMenuStrip(); + cItemTimeline.Items.Add( _( "Copy" ), null, new EventHandler( h_copyTimeTable ) ); + if ( !copy_enabled ) { + cItemTimeline.Items[cItemTimeline.Items.Count - 1].Enabled = false; + } + cItemTimeline.Items.Add( _( "Copy On/Off inverted" ), null, new EventHandler( h_copyTimeTableInvert ) ); + if ( !copy_enabled ) { + cItemTimeline.Items[cItemTimeline.Items.Count - 1].Enabled = false; + } + cItemTimeline.Items.Add( _( "Paste" ), null, new EventHandler( h_pasteTimeTable ) ); + if ( m_copied_timetable == null ) { + cItemTimeline.Items[cItemTimeline.Items.Count - 1].Enabled = false; + } + cItemTimeline.Items.Add( _( "Import from TEXT" ), null, new EventHandler( h_importFromText ) ); + cItemTimeline.Items.Add( _( "Export to TEXT" ), null, new EventHandler( h_exportToText ) ); + cItemTimeline.ShowCheckMargin = false; + cItemTimeline.ShowImageMargin = false; + mItemTimeline.DropDown = cItemTimeline; + cmenu.Items.Add( mItemTimeline ); + } + + //編集 + ToolStripMenuItem mItemEdit = new ToolStripMenuItem( _( "Edit" ) ); + ContextMenuStrip cItemEdit = new ContextMenuStrip(); + if ( m_clicked.type != TimeTableType.plugin && m_clicked.type != TimeTableType.character && m_clicked.type != TimeTableType.telop ) { + cItemEdit.Items.Add( _( "Delete" ), null, new EventHandler( h_deleteTrack ) ); + } + cItemEdit.Items.Add( _( "Delete entries" ), null, new EventHandler( h_clearEntry ) ); + if ( !copy_enabled ) { + cItemEdit.Items[cItemEdit.Items.Count - 1].Enabled = false; + } + cItemEdit.Items.Add( _( "Shift this time-line" ), null, new EventHandler( h_shiftEntries ) ); + if ( !copy_enabled ) { + cItemEdit.Items[cItemEdit.Items.Count - 1].Enabled = false; + } + cItemEdit.ShowCheckMargin = false; + cItemEdit.ShowImageMargin = false; + mItemEdit.DropDown = cItemEdit; + cmenu.Items.Add( mItemEdit ); + + #endregion + + } + } + if ( cmenu.Items.Count >= 1 ) { + cmenu.Show( pictureBox1, new Point( e.X, e.Y ) ); + } + #endregion + } else if ( e.Button == MouseButtons.Left ) { + #region 左クリック + if ( m_clicked.entry >= 0 ) { + m_edit_handle_ed_item = GetGroupItem( e.X + m_startToDrawX, e.Y + m_startToDrawY ); +#if DEBUG + Common.DebugWriteLine( "pictureBox1_MouseClick; m_edit_handle_ed_item.entry=" + m_edit_handle_ed_item.entry ); +#endif + UpdateEditHandle( e.X, e.Y ); + m_edit_mode = EditMode.Selected; + float time = SecFromXCoord( e.X ); + UpdateExpandRange( time ); + if ( m_clicked.type == TimeTableType.telop ) { + Telop selected = AppManager.SaveData[m_clicked.entry]; + property.Editing = new ZorderItem( selected.Text, ZorderItemType.telop, selected.ID ); + } + pictureBox1.Invalidate(); + } + #endregion + } + } else if ( m_edit_mode != EditMode.EditingLeft && m_edit_mode != EditMode.EditingRight/* !m_editEntry*/ ) { + m_clicked = GetGroupItem( e.X + m_startToDrawX, e.Y + m_startToDrawY ); + if ( m_clicked.entry >= 0 ) { + UpdateEditHandle( e.X, e.Y ); + float time = SecFromXCoord( e.X ); + UpdateExpandRange( time ); + if ( m_clicked.type == TimeTableType.telop ) { + Telop selected = AppManager.SaveData[m_clicked.entry]; + property.Editing = new ZorderItem( selected.Text, ZorderItemType.telop, selected.ID ); + } + pictureBox1.Invalidate(); + } else { + m_edit_mode = EditMode.None; + } + } + } + + private void pictureBox1_MouseMove( object sender, MouseEventArgs e ) { + if ( AppManager.Playing ) { + m_mousePosition = e.Location; + return; + } + + Rectangle last = m_rcHilight; + m_rcHilight = GetHilightRect( m_mousePosition.X, m_mousePosition.Y ); + + if ( preview_image.Visible ) { + TimeSpan ts = DateTime.Now.Subtract( m_preview_time ); + if ( ts.TotalMilliseconds > 1000 ) { + preview_image.Visible = false; + } + } + + statusTime.Text = SecFromXCoord( e.X ).ToString( "0.00" ) + " sec"; + if ( m_edit_mode != EditMode.Selected ) { + m_mousePosition.X = e.X; + m_mousePosition.Y = e.Y; + if ( m_edit_mode == EditMode.Dragging ) { + // エントリを追加するモード + m_editing_t2 = SecFromXCoord( e.X ); + m_slide_moved = true; + if ( AppManager.Config.QuantizeMode != QuantizeMode.off && m_grids != null ) { + m_editing_t2 = GetSnapPoint( m_editing_t2 ); + } + float begin = m_editing_t1; + float end = m_editing_t2; + if ( begin > end ) { + float b = begin; + begin = end; + end = b; + } + if ( begin < 0f ) { + begin = 0f; + } + if ( AppManager.SaveData.m_totalSec < end ) { + end = AppManager.SaveData.m_totalSec; + } + if ( m_dragging.type == TimeTableType.telop ) { + AppManager.SaveData[m_editing_telop_original.ID].Start = begin; + AppManager.SaveData[m_editing_telop_original.ID].End = end; + } else if ( m_dragging.type != TimeTableType.vsq ) { + AppManager.SaveData[m_dragging.type, m_dragging.group] = null; + AppManager.SaveData[m_dragging.type, m_dragging.group] = (TimeTableGroup)m_editing_group.Clone(); + AppManager.SaveData[m_dragging.type, m_dragging.group].Interrup( m_dragging.track, begin, end ); + } + pictureBox1.Cursor = Cursors.Arrow; + } else if ( m_edit_mode == EditMode.Sliding ) { + // エントリをドラッグしてスライドさせるモード + m_slide_moved = true; + m_editing_t2 = SecFromXCoord( e.X ); + int group = m_dragging.group; + int track = m_dragging.track; + int entry = m_dragging.entry; + float diff = (m_editing_t2 - m_editing_t1); + float original_begin; + if ( m_dragging.type == TimeTableType.telop ) { + original_begin = m_editing_telop_original.Start; + } else { + original_begin = m_slide_original.begin; + } + float begin = original_begin + diff; + + if ( AppManager.Config.QuantizeMode != QuantizeMode.off && m_grids != null ) { + begin = GetSnapPoint( begin ); + diff = begin - original_begin; + } + float end = 0; + float length = 0; + + if ( m_dragging.type == TimeTableType.telop ) { + end = m_editing_telop_original.End + diff; + length = m_editing_telop_original.Length; + } else if ( m_dragging.type != TimeTableType.vsq ) { + end = AppManager.SaveData[m_dragging.type, group][track][entry].end + diff; + length = AppManager.SaveData[m_dragging.type, group][track][entry].Length; + if ( begin < m_expandRange.X ) { + begin = m_expandRange.X; + end = begin + length; + } else { + if ( m_expandRange.Y < end ) { + end = m_expandRange.Y; + begin = end - length; + } else { + end = begin + length; + } + } + } + + int ibegin = XCoordFromSec( begin ); + int y = m_dragging.row_index * AppManager.Config.TrackHeight - m_startToDrawY; + int width = (int)(length * AppManager.Config.PixelPerSec); + m_rcHilight = new Rectangle( ibegin, y, width, AppManager.Config.TrackHeight ); + + if ( m_dragging.type == TimeTableType.telop ) { + AppManager.SaveData[m_editing_telop_original.ID].Start = begin; + AppManager.SaveData[m_editing_telop_original.ID].End = end; + } else if ( m_dragging.type != TimeTableType.vsq ) { + AppManager.SaveData[m_dragging.type, group][track][entry].begin = begin; + AppManager.SaveData[m_dragging.type, group][track][entry].end = end; + } + pictureBox1.Cursor = Cursors.Arrow; + } else if ( m_edit_mode == EditMode.EditingLeft || m_edit_mode == EditMode.EditingRight ) { + TimeTableType type = m_edit_handle_ed_item.type; + if ( type != TimeTableType.vsq ) { + int group = m_edit_handle_ed_item.group; + int track = m_edit_handle_ed_item.track; + int entry = m_edit_handle_ed_item.entry; + if ( entry < 0 ) { + m_edit_mode = EditMode.None; + return; + } + float draft_begin, draft_end; + if ( type == TimeTableType.telop ) { + draft_begin = m_editing_telop_original.Start; + draft_end = m_editing_telop_original.End; + } else { + draft_begin = m_editing_group[track][entry].begin; + draft_end = m_editing_group[track][entry].end; + } + if ( m_edit_mode == EditMode.EditingLeft ) { + draft_begin = SecFromXCoord( e.X ); + if ( AppManager.Config.QuantizeMode != QuantizeMode.off && m_grids != null ) { + draft_begin = GetSnapPoint( draft_begin ); + } + if ( draft_begin < 0f ) { + draft_begin = 0f; + } + } else { + draft_end = SecFromXCoord( e.X ); + if ( AppManager.Config.QuantizeMode != QuantizeMode.off && m_grids != null ) { + draft_end = GetSnapPoint( draft_end ); + } + if ( AppManager.SaveData.m_totalSec < draft_end ) { + draft_end = AppManager.SaveData.m_totalSec; + } + } + if ( draft_begin < draft_end ) { + if ( type == TimeTableType.telop ) { + AppManager.SaveData[entry].Start = draft_begin; + AppManager.SaveData[entry].End = draft_end; + } else { + AppManager.SaveData[type, group] = null; + AppManager.SaveData[type, group] = (TimeTableGroup)m_editing_group.Clone(); + AppManager.SaveData[type, group][track].RemoveAt( entry ); + AppManager.SaveData[type, group].Interrup( track, draft_begin, draft_end ); + } + } + } + pictureBox1.Cursor = Cursors.VSplit; + } + } else { + Point pt = new Point( e.X, e.Y ); + if ( AppManager.IsInRectangle( pt, m_editHandleLeft ) ) { + pictureBox1.Cursor = Cursors.VSplit; + } else if ( AppManager.IsInRectangle( pt, m_editHandleRight ) ) { + pictureBox1.Cursor = Cursors.VSplit; + } else { + pictureBox1.Cursor = Cursors.Arrow; + } + } + pictureBox1.Refresh(); + } + + private void pictureBox1_MouseLeave( object sender, EventArgs e ) { + pictureBox1.Invalidate(); + } + + /// + /// + /// + /// + /// + private void pictureBox1_MouseDown( object sender, MouseEventArgs e ) { + pictureBox1.Focus(); + + m_mousePosition.X = e.X; + m_mousePosition.Y = e.Y; + + if ( m_edit_mode == EditMode.Selected ) { + if ( m_edit_handle_ed_item.type == TimeTableType.telop ) { + int id = m_edit_handle_ed_item.entry; + if ( AppManager.IsInRectangle( e.Location, m_editHandleLeft ) ) { + m_editing_telop_original = (Telop)AppManager.SaveData[id].Clone(); + m_edit_mode = EditMode.EditingLeft; + } else if ( AppManager.IsInRectangle( e.Location, m_editHandleRight ) ) { + m_editing_telop_original = (Telop)AppManager.SaveData[id].Clone(); + m_edit_mode = EditMode.EditingRight; + } + } else { + if ( AppManager.IsInRectangle( e.Location, m_editHandleLeft ) ) { + m_editing_group = null; + m_editing_group = (TimeTableGroup)AppManager.SaveData[m_edit_handle_ed_item.type, m_edit_handle_ed_item.group].Clone(); + m_edit_mode = EditMode.EditingLeft; + } else if ( AppManager.IsInRectangle( e.Location, m_editHandleRight ) ) { + m_editing_group = null; + m_editing_group = (TimeTableGroup)AppManager.SaveData[m_edit_handle_ed_item.type, m_edit_handle_ed_item.group].Clone(); + m_edit_mode = EditMode.EditingRight; + } + } +#if DEBUG + Common.DebugWriteLine( "pictureBox1_MouseDown; m_edit_handle_ed_item.entry=" + m_edit_handle_ed_item.entry ); +#endif + } else if ( e.Button == MouseButtons.Left ) { + m_editing_t1 = SecFromXCoord( e.X ); + if ( AppManager.Config.QuantizeMode != QuantizeMode.off ) { + m_editing_t1 = GetSnapPoint( m_editing_t1 ); + } + m_clicked = GetGroupItem( m_mousePosition.X + m_startToDrawX, m_mousePosition.Y + m_startToDrawY ); + if ( m_clicked.track >= 0 ) { + int track = m_clicked.track; + int group = m_clicked.group; + int entry = m_clicked.entry; + if ( m_clicked.type == TimeTableType.vsq ) { + m_edit_mode = EditMode.None; + } else if ( m_clicked.type == TimeTableType.telop ) { + m_slide_moved = false; + m_dragging = m_clicked; + if ( m_clicked.entry < 0 ) { + int id = AppManager.SaveData.GetNextID(); + m_editing_telop_original = new Telop( id ); + m_editing_telop_original.Text = "(none)"; + m_editing_telop_original.Start = SecFromXCoord( e.X ); + m_editing_telop_original.End = m_editing_telop_original.Start; + m_editing_telop_original.Lane = m_clicked.track; + Command run2 = Command.GCommandAddTelop( m_editing_telop_original ); + AppManager.SaveData.Execute( run2 ); + m_edit_mode = EditMode.Dragging; + } else { + m_editing_telop_original = (Telop)AppManager.SaveData[m_clicked.entry].Clone(); + m_edit_mode = EditMode.Sliding; + } + } else { + m_editing_group = null; + m_editing_group = (TimeTableGroup)AppManager.SaveData[m_clicked.type, m_clicked.group].Clone(); + m_dragging = new Item( m_clicked.type, m_clicked.group, m_clicked.track, m_clicked.entry, m_clicked.row_index ); + m_slide_moved = false; + if ( m_clicked.entry < 0 ) { + // エントリ追加モード + m_edit_mode = EditMode.Dragging; + } else { + // エントリスライドモード + m_edit_mode = EditMode.Sliding; + UpdateExpandRange( SecFromXCoord( e.X ) ); + if ( m_clicked.type != TimeTableType.vsq ) { + m_slide_original = (TimeTableEntry)AppManager.SaveData[m_clicked.type, group][track][entry].Clone(); + } + } + } + } + } + } + + private void pictureBox1_MouseDoubleClick( object sender, MouseEventArgs e ) { + if ( m_edit_mode == EditMode.None ) { + Item clicked = GetGroupItem( e.X + m_startToDrawX, e.Y + m_startToDrawY ); + if ( clicked.type == TimeTableType.top ) { + float time = SecFromXCoord( e.X ); + int nof = (int)(time * AppManager.SaveData.FrameRate); + if ( previewer.TrackBarMinimum <= nof && nof <= previewer.TrackBarMaximum ) { + previewer.TrackBarValue = nof; + correctPosition(); + this.Invalidate(); + } + } else if ( clicked.track < 0 ) { + if ( clicked.type == TimeTableType.telop ) { + AppManager.SaveData.TelopListFolded = !AppManager.SaveData.TelopListFolded; + SetVScrollRange(); + Invalidate(); + } else { + if ( AppManager.SaveData[clicked.type, clicked.group] != null ) { + AppManager.SaveData[clicked.type, clicked.group].Folded = !AppManager.SaveData[clicked.type, clicked.group].Folded; + SetVScrollRange(); + this.Invalidate(); + } + } + } + } else { + Item clicked = GetGroupItem( e.X + m_startToDrawX, e.Y + m_startToDrawY ); + if ( clicked.entry >= 0 ) { + m_clicked = clicked; + h_editEntry( this, new EventArgs() ); + } + } + } + + private void pictureBox1_MouseUp( object sender, MouseEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "pictureBox1_MouseUp" ); + Common.DebugWriteLine( " m_slide_moved=" + m_slide_moved ); +#endif + if ( m_edit_mode == EditMode.EditingLeft || m_edit_mode == EditMode.EditingRight/* m_editEntry*/ ) { + #region EditMode.EditingLeft EditMode.EditRight + int x = e.X; + + float time = SecFromXCoord( x ); + float new_begin; + float new_end; + + TimeTableType type = m_edit_handle_ed_item.type; + int group = m_edit_handle_ed_item.group; + int track = m_edit_handle_ed_item.track; + int entry = m_edit_handle_ed_item.entry; +#if DEBUG + Common.DebugWriteLine( "pictureBox1_MouseUp; m_edit_mode==EditingLeft||EditingRight;" ); + Common.DebugWriteLine( "type=" + type + "; group=" + group + "; track=" + track + "; entry=" + entry ); +#endif + if ( track < 0 || entry < 0 ) { + AppManager.SaveData[type, group] = null; + AppManager.SaveData[type, group] = (TimeTableGroup)m_editing_group.Clone(); + return; + } + + if ( type == TimeTableType.telop ) { + new_begin = AppManager.SaveData[entry].Start; + new_end = AppManager.SaveData[entry].End; + } else if ( type != TimeTableType.vsq ) { + new_begin = m_editing_group[track][entry].begin; + new_end = m_editing_group[track][entry].end; + } else { + m_edit_mode = EditMode.None; + return; + } + + TimeTableEntry item; + if ( new_end <= new_begin ) { + // 終了時刻として開始時刻と同じか小さい時刻を指定された場合。エントリを削除 + if ( type == TimeTableType.telop ) { + Command run = Command.GCommandDeleteTelop( AppManager.SaveData[entry] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } else if ( type != TimeTableType.vsq ) { + int g = group; + if ( type != TimeTableType.character ) { + g = -1; + } + Command run = Command.GCommandDeleteTimeTableEntry( type, g, track, AppManager.SaveData[type, group][track][entry] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + AppManager.Edited = true; + this.Invalidate(); + m_edit_mode = EditMode.None; + return; + } + if ( type == TimeTableType.telop ) { + Telop edited = (Telop)AppManager.SaveData[entry].Clone(); + AppManager.SaveData[entry] = m_editing_telop_original; + Command run = Command.GCommandEditTelop( entry, edited ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } else if ( type != TimeTableType.vsq ) { + item = (TimeTableEntry)m_editing_group[track][entry].Clone(); + item.begin = new_begin; + item.end = new_end; + if ( type != TimeTableType.character ) { + group = -1; + } + Command run = Command.GCommandEditGroup( type, group, AppManager.SaveData[type, group] ); + AppManager.SaveData[type, group] = (TimeTableGroup)m_editing_group.Clone(); + AppManager.Register( AppManager.SaveData.Execute( run ) ); +#if DEBUG + Common.DebugWriteLine( "Command run & registered" ); +#endif + } else { + m_edit_mode = EditMode.None; + return; + } + pictureBox1.Cursor = Cursors.Arrow; + AppManager.Edited = true; + m_rcHilight = GetHilightRect( e.X, e.Y ); + this.Invalidate(); + m_edit_mode = EditMode.None; + #endregion + } else if ( m_edit_mode == EditMode.Dragging ) { + #region EditMode.Dragging + m_edit_mode = EditMode.None; + TimeTableType type = m_dragging.type; + int group = m_dragging.group; + int track = m_dragging.track; + if ( type == TimeTableType.telop ) { + Telop added = null; + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + if ( AppManager.SaveData.m_telop_ex2[i].ID == m_editing_telop_original.ID ) { + added = (Telop)AppManager.SaveData.m_telop_ex2[i].Clone(); + AppManager.SaveData.m_telop_ex2.RemoveAt( i ); + break; + } + } + if ( added != null && m_slide_moved ) { + Telop.DecideLane( AppManager.SaveData.m_telop_ex2 ); + Command run2 = Command.GCommandAddTelop( added ); + Command inv = AppManager.SaveData.Execute( run2 ); + property.Editing = new ZorderItem( inv.telop.Text, ZorderItemType.telop, inv.telop.ID ); + AppManager.Register( inv ); + UpdateEditHandle(); + SetVScrollRange(); + AppManager.Edited = true; + } + } else if ( type != TimeTableType.vsq ) { + int g = group; + if ( type != TimeTableType.character ) { + g = -1; + } + Command run = Command.GCommandEditGroup( type, g, AppManager.SaveData[type, group] ); + AppManager.SaveData[type, group] = null; + AppManager.SaveData[type, group] = (TimeTableGroup)m_editing_group.Clone(); + if ( m_slide_moved ) { + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + m_slide_moved = false; + //timerTimeLine.Enabled = true; + this.Invalidate(); + #endregion + } else if ( m_edit_mode == EditMode.Sliding ) { + #region EditMode.Sliding + TimeTableType type = m_dragging.type; + int group = m_dragging.group; + int track = m_dragging.track; + int entry = m_dragging.entry; + m_edit_mode = EditMode.None; + m_slide_moved = false; + if ( type == TimeTableType.telop ) { + Telop edited = (Telop)AppManager.SaveData[m_editing_telop_original.ID].Clone(); + AppManager.SaveData[m_editing_telop_original.ID] = (Telop)m_editing_telop_original.Clone(); + Command run2 = Command.GCommandEditTelop( edited.ID, edited ); + AppManager.Register( AppManager.SaveData.Execute( run2 ) ); + AppManager.Edited = true; + } else if ( type != TimeTableType.vsq ) { + int g = group; + if ( type != TimeTableType.character ) { + g = -1; + } + Command run = Command.GCommandEditTimeTableEntry( type, g, track, entry, AppManager.SaveData[type, group][track][entry] ); + AppManager.SaveData[type, group][track][entry] = null; + AppManager.SaveData[type, group][track][entry] = (TimeTableEntry)m_slide_original.Clone(); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + //timerTimeLine.Enabled = true; + this.Invalidate(); + #endregion + } + } + + private void pictureBox1_Paint( object sender, PaintEventArgs e ) { + if ( m_skip_paint ) { + return; + } + Graphics g = e.Graphics; + g.Clear( SystemColors.Control ); + + int[] lanes = AppManager.GetTimeLineLanes(); + int height; + bool always_show_vsq = AppManager.Config.FixVsqTrackPosition; + Rectangle clip_for_vsq = new Rectangle(); + if ( always_show_vsq ) { + m_vsq_height = (AppManager.SaveData.m_group_vsq.VisibleTracks + 2) * AppManager.Config.TrackHeight; + clip_for_vsq = new Rectangle( 0, + AppManager.Config.TrackHeight, + pictureBox1.Width, + (AppManager.SaveData.m_group_vsq.VisibleTracks + 1) * AppManager.Config.TrackHeight ); + } + + int total_height = 0; + for ( int lane = 0; lane < lanes.Length; lane++ ) { + total_height += AppManager.Config.TrackHeight; + for ( int i = 2; i <= lanes[lane]; i++ ) { + int y = (i - 1) * AppManager.Config.TrackHeight - m_startToDrawY; + if ( always_show_vsq && lane == 0 ) { + y += m_startToDrawY; + } + Rectangle outline = new Rectangle( 0, total_height + y, pictureBox1.Width, AppManager.Config.TrackHeight ); + if ( i % 2 == 0 ) { + g.FillRectangle( _BRS_TRACKBG_ODD, outline ); + } else { + g.FillRectangle( _BRS_TRACKBG_EVEN, outline ); + } + } + if ( always_show_vsq && lane == 0 ) { + g.ExcludeClip( clip_for_vsq ); + } + if ( lanes[lane] >= 2 ) { + total_height += (lanes[lane] - 1) * AppManager.Config.TrackHeight; + } + } + + // 小節毎の線 + g.ResetClip(); + if ( menuVisualBars.Checked ) { + IEnumerable blte = AppManager.SaveData.GetBarLineTypeEnumerator( AppManager.Config.QuantizeMode, AppManager.Config.QuantizeTripletEnabled ); + foreach ( BarLineType barsec in blte ) { + int x = (int)(barsec.Time * AppManager.Config.PixelPerSec) - m_startToDrawX; + if ( x > pictureBox1.Width ) { + break; + } else if ( 0 < x ) { + if ( barsec.IsSeparator ) { + g.DrawLine( new Pen( Color.FromArgb( 161, 157, 136 ) ), + new Point( x, 0 ), + new Point( x, pictureBox1.Height ) ); + } else { + g.DrawLine( new Pen( Color.FromArgb( 209, 204, 172 ) ), + new Point( x, 0 ), + new Point( x, pictureBox1.Height ) ); + } + } + } + } + + g.ExcludeClip( clip_for_vsq ); + total_height = AppManager.Config.TrackHeight; + if ( !always_show_vsq ) { + DrawTimeTableGroup( g, + new Point( 0, total_height - m_startToDrawY ), + out height, + AppManager.SaveData.m_group_vsq, + _( "VSQ Tracks" ) ); + total_height += height; + } else { + total_height = m_vsq_height; + } + + for ( int i = 0; i < AppManager.SaveData.m_groups_character.Count; i++ ) { + DrawTimeTableGroup( g, + new Point( 0, total_height - m_startToDrawY ), + out height, + AppManager.SaveData.m_groups_character[i], + _( "Character" ) + "(" + AppManager.SaveData.m_groups_character[i].Character.Name + ")" ); + total_height += height; + } + + DrawTelop( g, + new Point( 0, total_height - m_startToDrawY ), + out height, + _( "Telop" ) ); + total_height += height; + + DrawTimeTableGroup( g, + new Point( 0, total_height - m_startToDrawY ), + out height, + AppManager.SaveData.m_group_another, + _( "Another Images" ) ); + total_height += height; + + DrawTimeTableGroup( g, + new Point( 0, total_height - m_startToDrawY ), + out height, + AppManager.SaveData.m_group_plugin, + _( "Plugin" ) ); + + if ( always_show_vsq ) { + g.ResetClip(); + DrawTimeTableGroup( g, + new Point( 0, AppManager.Config.TrackHeight ), + out height, + AppManager.SaveData.m_group_vsq, + _( "VSQ Tracks" ) ); + total_height += height; + } + + // 画面に一定時間ごとのラインを引く + g.FillRectangle( new SolidBrush( TOOL_COLOR ), 0, 0, pictureBox1.Width, AppManager.Config.TrackHeight ); + // リピートエリアを別色で描く + g.FillRectangle( new SolidBrush( REPEAT_AREA ), + new Rectangle( (int)(RepeatStart * AppManager.Config.PixelPerSec - m_startToDrawX), + 0, + (int)((RepeatEnd - RepeatStart) * AppManager.Config.PixelPerSec), + AppManager.Config.TrackHeight ) ); + int start_to_draw_x = m_startToDrawX; + int start_sec = (int)((double)(start_to_draw_x) / AppManager.Config.PixelPerSec) / AppManager.Config.TimeLineInterval; + if ( start_sec == 0 ) { + start_sec = 1; + } + int end_sec = (int)((double)(start_to_draw_x + pictureBox1.Width) / AppManager.Config.PixelPerSec) / AppManager.Config.TimeLineInterval + 1; + for ( int i = start_sec; i <= end_sec; i++ ) { + int x = (int)(i * AppManager.Config.TimeLineInterval * AppManager.Config.PixelPerSec) - start_to_draw_x; + g.DrawString( i * AppManager.Config.TimeLineInterval + " sec", + AppManager.Config.Font.GetFont(), + Brushes.Black, + new Point( x, AppManager.Config.VerticalStringOffset ) ); + g.DrawLine( new Pen( Color.FromArgb( 128, Color.Black ) ), + new Point( x, 0 ), new Point( x, pictureBox1.Height ) ); + } + + if ( m_edit_mode == EditMode.Selected/* m_editMode*/ ) { + g.DrawRectangle( HILIGHT_EDIT, m_rcHilight ); + } else { + g.DrawRectangle( HILIGHT, m_rcHilight ); + } + + // カーソル位置に縦線 + int cursor; + float now = Now; + if ( menuVisualSync.Checked && AppManager.Config.SyncAtCentre ) { + float w = pictureBox1.Width / 2 / AppManager.Config.PixelPerSec; + if ( now < w || AppManager.SaveData.m_totalSec - w < now ) { + cursor = (int)(now * AppManager.Config.PixelPerSec - m_startToDrawX); + } else { + cursor = pictureBox1.Width / 2; + } + } else { + cursor = (int)(now * AppManager.Config.PixelPerSec - m_startToDrawX); + } + g.DrawLine( new Pen( Color.Black, 2.0f ), new Point( cursor, 0 ), new Point( cursor, pictureBox1.Height ) ); + g.DrawLine( + Pens.Black, + new Point( m_mousePosition.X, 0 ), + new Point( m_mousePosition.X, pictureBox1.Height ) ); + + if ( always_show_vsq ) { + g.DrawLine( new Pen( Color.Black, 2 ), + new Point( 0, m_vsq_height ), + new Point( pictureBox1.Width, m_vsq_height ) ); + } + } + #endregion + + private void preview_image_MouseLeave( object sender, EventArgs e ) { + TimeSpan ts = DateTime.Now.Subtract( m_preview_time ); + if ( ts.TotalMilliseconds > 200 ) { + preview_image.Visible = false; + } + } + + #region menuHelp + private void menuHelpDebugExtract_Click( object sender, EventArgs e ) { +#if DEBUG + /* using ( OpenFileDialog dlg = new OpenFileDialog() ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + string file = dlg.FileName; + string dir = Path.GetDirectoryName( file ); + string fname = Path.GetFileNameWithoutExtension( file ); + float scale = 0.45f; + using ( Character3 chara = new Character3( file ) ) { + foreach ( ImageEntry img in chara ) { + float width = img.image.Width;// * scale; + float height = img.image.Height;// *scale; + //using ( Bitmap t = new Bitmap( (int)width, (int)height, PixelFormat.Format32bppArgb ) ) + //using ( Graphics g = Graphics.FromImage( t ) ) { + //g.InterpolationMode = InterpolationMode.HighQualityBicubic; + //g.DrawImage( img.image, 0f, 0f, width, height ); + img.image.Save( Path.Combine( dir, fname + "_" + img.title + ".png" ) ); + //} + } + } + } + } +*/ +#endif + } + + private void menuHelpBugReport_Click( object sender, EventArgs e ) { + BugReport dlg = new BugReport(); + dlg.Show(); + } + + private void menuHelpDebugEditCharacter_Click( object sender, EventArgs e ) { +#if DEBUG + +#endif + } + + private void menuHelpDebugInverseImages_Click( object sender, EventArgs e ) { +#if DEBUG + +#endif + } + + private static string GetAssemblyNameAndVersion( Type t ) { + Assembly a = Assembly.GetAssembly( t ); + AssemblyFileVersionAttribute afva = (AssemblyFileVersionAttribute)Attribute.GetCustomAttribute( a, typeof( AssemblyFileVersionAttribute ) ); + return a.GetName().Name + " v" + afva.Version; + } + + /// + /// バージョン情報を表示 + /// + /// + /// + private void menuHelpVersionInfo_Click( object sender, EventArgs e ) { + if ( m_version_form == null ) { + string version_str = AppManager.VERSION + "\n\n" + + GetAssemblyNameAndVersion( typeof( Boare.Lib.AppUtil.Misc ) ) + "\n" + + GetAssemblyNameAndVersion( typeof( Boare.Lib.Media.AviWriterVcm ) ) + "\n" + + GetAssemblyNameAndVersion( typeof( Boare.Lib.Vsq.VsqFile ) ) + "\n" + +#if DEBUG + GetAssemblyNameAndVersion( typeof( Boare.Lib.Swf.SwfWriter ) ) + "\n" + +#endif + GetAssemblyNameAndVersion( typeof( bocoree.math ) ); + m_version_form = new Boare.Lib.AppUtil.VersionInfo( _( "LipSync" ), version_str ); + m_version_form.Font = AppManager.Config.Font.GetFont(); + m_version_form.AuthorList = m_credit; + m_version_form.AppNameColor = Color.RoyalBlue; + m_version_form.VersionColor = Color.DimGray; +#if !DEBUG + m_version_form.Credit = AppManager.author_list; +#endif + m_version_form.FormClosed += new FormClosedEventHandler( m_version_form_FormClosed ); + m_version_form.Show(); + } + } + #endregion + + void m_version_form_FormClosed( object sender, FormClosedEventArgs e ) { + m_version_form.Dispose(); + m_version_form = null; + } + + #region Form1 + private void Form1_Shown( object sender, EventArgs e ) { + m_initialized = true; + ResizePanel2(); + } + + private void Form1_Load( object sender, EventArgs e ) { +#if MONO + Common.DebugWriteLine( "this assembly was compiled under the define of \"NET_2_0\"" ); +#endif + ResizePanel2(); + ApplyFont( AppManager.Config.Font.GetFont() ); + + // プラグインを読み込み + //インストールされているプラグインを調べる + //すべてのプラグインクラスのインスタンスを作成する + AppManager.SaveData.m_plugins = PluginInfo.FindPlugins(); + + AppManager.SaveData.m_group_plugin = new TimeTableGroup( _( "Plugin" ), -1, null ); + + AppManager.SaveData.m_plugins_config = new List(); + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + AppManager.SaveData.m_plugins_config.Add( new PluginConfig( AppManager.SaveData.m_plugins[i].Instance.Name, AppManager.SaveData.m_plugins[i].Instance.Config, Path.GetFileName( AppManager.SaveData.m_plugins[i].Location ) ) ); + AppManager.SaveData.m_group_plugin.Add( new TimeTable( AppManager.SaveData.m_plugins_config[i].ID, 0, TimeTableType.plugin, null ) ); + } + + /* + * プラグインの種類に応じて、メインメニューを更新 + */ + // プラグイン設定 + if ( AppManager.SaveData.m_plugins.Length > 0 ) { + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + if ( (AppManager.SaveData.m_plugins[i].Instance.Type & Plugin.Constants.LS_NO_EVENT_HANDLER) != Plugin.Constants.LS_NO_EVENT_HANDLER ) { + menuToolPluginConfig.DropDownItems.Add( AppManager.SaveData.m_plugins_config[i].ID, null, new EventHandler( h_pluginSetting ) ); + } + } + } + + // プラグインの情報 + menuHelpPluginInfo.DropDownItems.Clear(); + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + menuHelpPluginInfo.DropDownItems.Add( AppManager.SaveData.m_plugins[i].Instance.Name, null, new EventHandler( h_pluginInfo ) ); + } + + AppManager.SaveData.m_group_vsq = new TimeTableGroup( _( "VSQ Tracks" ), -1, null ); + AppManager.SaveData.m_groups_character = new List(); + AppManager.SaveData.m_group_another = new TimeTableGroup( _( "Another images" ), -1, null ); + SettingsEx.CommandExecuted += new CommandExecutedEventHandler( SettingsEx_CommandExecuted ); + + AppManager.SaveData.m_screenWidth = this.Width; + AppManager.SaveData.m_screenHeight = this.Height; + + AppManager.Edited = false; + + if ( m_filePath != "" ) { + Read( m_filePath ); + } + SetHScrollRange(); + SetVScrollRange(); + + AppManager.SaveData.UpdateZorder(); + + preview_image.Parent = pictureBox1; + + QuantizeMenuCheckedStateUpdate(); + UpdateGridList(); + + property.PropertyValueChanged += new PropertyValueChangedEventHandler( property_PropertyValueChanged ); + property.TelopAdding += new TelopAddingEventHandler( property_TelopAdding ); + property.EditingItemChanged += new EditingItemChangedEventHandler( property_EditingItemChanged ); + property.TelopDeleting += new TelopDeletingEventHandler( property_TelopDeleting ); + property.ListUpdateRequired += new ListUpdateRequiredEventHandler( UpdateObjectList ); + property.UpdateLayout(); + + previewer.Image = new Bitmap( AppManager.SaveData.m_movieSize.Width, AppManager.SaveData.m_movieSize.Height ); + using ( Graphics g = Graphics.FromImage( previewer.Image ) ) { + AppManager.SaveData.DrawTo( g, new Size( AppManager.SaveData.m_movieSize.Width, AppManager.SaveData.m_movieSize.Height ), 0.0f, false ); + } + +#if DEBUG + FormCommandHistory fch = new FormCommandHistory(); + fch.Show(); +#endif + } + + private void Form1_FormClosing( object sender, FormClosingEventArgs e ) { + if ( AppManager.Edited ) { + //MessageBox.Show( "Form1_FormClosing" ); + DialogResult result = requestIntention(); + switch ( result ) { + case DialogResult.Yes: + if ( m_filePath == "" ) { + if ( saveFileDialog1.ShowDialog() == DialogResult.OK ) { + m_filePath = saveFileDialog1.FileName; + Save( m_filePath ); + } else { + return; + } + } else { + Save( m_filePath ); + } + break; + case DialogResult.Cancel: + e.Cancel = true; + return; + } + } + if ( m_player != null ) { + m_player.Stop(); + m_player.Close(); + } + if ( m_preview_thread != null ) { + m_preview_thread.Abort(); + while ( m_preview_thread.IsAlive ) { + Application.DoEvents(); + } + } + SaveConfig(); + } + + private void Form1_DragEnter( object sender, DragEventArgs e ) { + e.Effect = DragDropEffects.All; + } + + private void Form1_DragDrop( object sender, DragEventArgs e ) { + if ( e.Data.GetDataPresent( DataFormats.FileDrop ) ) { + string[] filename = (string[])e.Data.GetData( DataFormats.FileDrop ); + if ( Path.GetExtension( filename[0] ).ToLower() == ".vsq" || Path.GetExtension( filename[0] ).ToLower() == ".ust" ) { + // vsqファイル + ReadVsq( filename[0] ); + } else if ( Path.GetExtension( filename[0] ).ToLower() == ".lse" ) { + // LipSync Editorファイル + Read( filename[0] ); + m_filePath = filename[0]; + UpdateFormTitle(); + SetHScrollRange(); + SetVScrollRange(); + //rebuildDrawing(); + this.Invalidate(); + } + } + } + + private void Form1_Paint( object sender, PaintEventArgs e ) { + if ( m_skip_paint ) { + return; + } + float now; + if ( !AviWriting && !AppManager.Config.PreviewHidden ) { +#if OBSOLETE_MODE + if ( PreviewP.Image != null ) { + PreviewP.Image.Dispose(); + } + PreviewP.Image = getPicture( now ); +#endif + //PreviewP.Refresh(); + //previewer.Preview.Invalidate(); + } + + float speed = m_player.Speed; + previewer.LabelSpeedText = "x" + speed.ToString( "0.00" ); + + pictureBox1.Refresh(); + side.Refresh(); + } + + private void Form1_LocationOrSizeChanged( object sender, EventArgs e ) { + if ( AppManager.Config != null ) { + if ( this.WindowState == FormWindowState.Normal ) { + AppManager.Config.WindowPosition = this.Bounds; + } + AppManager.Config.WindowIsMaximized = (this.WindowState == FormWindowState.Maximized); + } + } + + private void Form1_Activated( object sender, EventArgs e ) { + m_edit_mode = EditMode.None; + } + + private void Form1_Deactivate( object sender, EventArgs e ) { + m_edit_mode = EditMode.None; + } + #endregion + + #region bgWorkAvi + private void bgWorkAvi_DoWork( object sender, DoWorkEventArgs e ) { + IAviWriter writer = null; + AviOutputArguments args = (AviOutputArguments)e.Argument; + if ( File.Exists( args.AviFile ) ) { + File.Delete( args.AviFile ); + } + Size size = AppManager.SaveData.m_movieSize; + m_avi_cancel = false; + + long start_frame; + if ( args.StartSpecified ) { + start_frame = (long)(args.Start * AppManager.SaveData.FrameRate); + } else { + start_frame = 0L; + } + + long end_frame; + if ( args.EndSpecified ) { + end_frame = (long)(args.End * AppManager.SaveData.FrameRate); + } else { + end_frame = (long)((AppManager.SaveData.m_totalSec) * AppManager.SaveData.FrameRate); + } + long total_frames = end_frame - start_frame + 1; +#if !DEBUG + try { +#endif + Bitmap bmp = null; + if ( args.UseVfwEncoder ) { + bmp = new Bitmap( size.Width, size.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb ); + AviWriterVfw awvfw = new AviWriterVfw(); + bool ret = awvfw.Open( args.AviFile, + AppManager.SaveData.DwScale, + AppManager.SaveData.DwRate, + size.Width, + size.Height, + Process.GetCurrentProcess().MainWindowHandle ); + if ( !ret ) { + return; + } + writer = awvfw; + } else { + bmp = args.IsTransparent ? + new Bitmap( size.Width, size.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb ) : + new Bitmap( size.Width, size.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb ); + AviWriterVcm awvcm = new AviWriterVcm(); + bool ret = awvcm.Open( args.AviFile, + AppManager.SaveData.DwScale, + AppManager.SaveData.DwRate, + size.Width, + size.Height, + !m_is_rawmode, + args.IsTransparent, + Process.GetCurrentProcess().MainWindowHandle ); + if ( !ret ) { + return; + } + writer = awvcm; + } + using ( Graphics g = Graphics.FromImage( bmp ) ) { + for ( long frame = start_frame; frame <= end_frame; frame++ ) { + float now = (float)frame / AppManager.SaveData.FrameRate; + using ( Bitmap frm = GetPicture( now, args.IsTransparent ) ) { + frm.RotateFlip( RotateFlipType.Rotate180FlipX ); + g.DrawImage( frm, 0, 0, size.Width, size.Height ); + } + try { + writer.AddFrame( bmp ); + } catch ( Exception ex ) { +#if DEBUG + Common.LogPush( ex ); +#endif + writer.Close(); + this.Invoke( new Form1_AviWritingChange( ChangeAviWriting ), new object[] { false } ); + return; + } + bgWorkAvi.ReportProgress( (int)((double)(frame - start_frame) / (double)(total_frames) * 100.0), new long[] { frame - start_frame, total_frames } ); + if ( m_avi_cancel ) { + bmp.Dispose(); + g.Dispose(); + writer.Close(); + m_avi_cancel = false; + return; + } + } + writer.Close(); + + string audio_file = AppManager.SaveData.m_audioFile; + +#if DEBUG + Common.DebugWriteLine( "bgWorkAvi_DoWork" ); + Common.DebugWriteLine( " args.IsWaveMergeRequired=" + args.IsWaveMergeRequired ); +#endif + if ( args.IsWaveMergeRequired ) { + #region merge wave file + if ( File.Exists( audio_file ) && AppManager.Config.PathFFmpeg != "" && File.Exists( AppManager.Config.PathFFmpeg ) ) { + string tmp_avi = Misc.GetTempFileNameIn( Path.GetDirectoryName( args.AviFile ), ".avi" ); + File.Move( args.AviFile, tmp_avi ); + // ffmpeg -i movie.mpeg -i audio.wav combined.avi + long frames = end_frame - start_frame + 1; + m_ffmpeg = new Process(); + m_ffmpeg.StartInfo.FileName = "\"" + AppManager.Config.PathFFmpeg + "\""; + m_ffmpeg.StartInfo.Arguments = "-i \"" + audio_file + "\" -i \"" + tmp_avi + "\" -vframes " + frames + " -vcodec copy -acodec copy \"" + args.AviFile + "\""; +#if DEBUG + Common.DebugWriteLine( " m_ffmpeg.StarInfo.Arguments=" + m_ffmpeg.StartInfo.Arguments ); +#endif + m_ffmpeg.StartInfo.CreateNoWindow = true; + m_ffmpeg.StartInfo.UseShellExecute = false; + m_ffmpeg.StartInfo.RedirectStandardError = true; + m_ffmpeg.Start(); + + this.m_stdout = new Thread( new ParameterizedThreadStart( this.FFMpegOutputRead ) ); + this.m_stdout.Name = "output_ffmpeg"; + this.m_stdout.Start( end_frame - start_frame ); + m_ffmpeg.WaitForExit(); + if ( args.IsDeleteIntermediateRequired ) { + File.Delete( tmp_avi ); + } + } + #endregion + } + + if ( args.IsFlvEncodeRequired && AppManager.Config.PathMEncoder != "" && File.Exists( AppManager.Config.PathMEncoder ) ) { + #region encode flv + //string flv_file = @"C:\test.flv"; + string flv_file = Path.Combine( Path.GetDirectoryName( args.AviFile ), Path.GetFileNameWithoutExtension( args.AviFile ) + ".flv" ); + string arguments = "\"" + args.AviFile + "\" -of lavf -lavfopts format=flv -ovc lavc -lavcopts vcodec=flv:vbitrate=500:mbd=2:ss:aiv:umv:preme=2:mv0:qprd:trell:v4mv:cbp -oac mp3lame -lameopts abr:br=128 -vf scale=" + size.Width + ":" + size.Height + " -sws 9 -af resample=44100 -o \"" + flv_file + "\""; + m_mencoder = new Process(); + m_mencoder.StartInfo.FileName = "\"" + AppManager.Config.PathMEncoder + "\""; + m_mencoder.StartInfo.Arguments = arguments; + m_mencoder.StartInfo.CreateNoWindow = true; + m_mencoder.StartInfo.UseShellExecute = false; + m_mencoder.StartInfo.RedirectStandardOutput = true; + m_mencoder.Start(); + + m_stdout = new Thread( new ParameterizedThreadStart( this.MEncoderOutputRead ) ); + m_stdout.Name = "stdout_mencoder"; + m_stdout.Start( end_frame - start_frame ); + + m_mencoder.WaitForExit(); + + if ( args.IsDeleteIntermediateRequired ) { + File.Delete( args.AviFile ); + } + + #endregion + } else if ( args.IsMp4EncodeRequired && AppManager.Config.PathFFmpeg != "" && File.Exists( AppManager.Config.PathFFmpeg ) ) { + #region encode mp4 + try { + // ffmpeg -i teaser8000k1280_720_3.avi -r 24 -s 512x288 -refs 1 -bf 2 -flags2 dct8x8 -partitions parti8x8+partp8x8+partb8x8 -sc_threshold 50 -qpel -trell -me hex -directpred 3 -bufsize 128 -b 472k -bt 472k -mbd 2 -preme 2 -f mp4 -vcodec libx264 -an -pass 1 -passlogfile "passlog" enc.mp4 + // ffmpeg -i teaser8000k1280_720_3.avi -r 24 -s 512x288 -refs 1 -bf 2 -flags2 dct8x8 -partitions parti8x8+partp8x8+partb8x8 -sc_threshold 50 -qpel -trell -me hex -directpred 3 -bufsize 128 -b 472k -bt 472k -mbd 2 -preme 2 -ab 64k -f mp4 -vcodec libx264 -acodec libfaac -pass 2 -passlogfile "passlog" enc.mp4 + string mp4_file = Path.Combine( Path.GetDirectoryName( args.AviFile ), Path.GetFileNameWithoutExtension( args.AviFile ) + ".mp4" ); + string arguments = ""; + string work_dir = Path.Combine( Application.StartupPath, "temp" ); + if ( !Directory.Exists( work_dir ) ) { + Directory.CreateDirectory( work_dir ); + } + + // first pass + arguments = "-i \"" + args.AviFile + "\" -refs 1 -bf 2 -flags2 dct8x8 -partitions parti8x8+partp8x8+partb8x8 -sc_threshold 40 -qpel -trell -me hex -directpred 3 -bufsize 128 -b 472k -bt 472k -mbd 2 -preme 2 -f mp4 -vcodec libx264 -an -pass 1 -passlogfile \"passlog\" -y \"" + mp4_file + "\""; +#if DEBUG + Common.DebugWriteLine( "1st pass arguments=" + arguments ); +#endif + m_ffmpeg = new Process(); + m_ffmpeg.StartInfo.WorkingDirectory = work_dir; + m_ffmpeg.StartInfo.FileName = "\"" + AppManager.Config.PathFFmpeg + "\""; + m_ffmpeg.StartInfo.Arguments = arguments; + m_ffmpeg.StartInfo.CreateNoWindow = true; + m_ffmpeg.StartInfo.UseShellExecute = false; + m_ffmpeg.StartInfo.RedirectStandardError = true; + m_ffmpeg.Start(); + this.m_stdout = new Thread( new ParameterizedThreadStart( this.FFMpegOutputRead ) ); + this.m_stdout.Name = "output_ffmpeg"; + this.m_stdout.Start( end_frame - start_frame ); + m_ffmpeg.WaitForExit(); + + // 2nd pass + arguments = "-i \"" + args.AviFile + "\" -refs 1 -bf 2 -flags2 dct8x8 -partitions parti8x8+partp8x8+partb8x8 -sc_threshold 40 -qpel -trell -me hex -directpred 3 -bufsize 128 -b 472k -bt 472k -mbd 2 -preme 2 -ab 64k -f mp4 -vcodec libx264 -acodec libfaac -pass 2 -passlogfile \"passlog\" -y \"" + mp4_file + "\""; +#if DEBUG + Common.DebugWriteLine( "2nd pass arguments=" + arguments ); +#endif + m_ffmpeg = new Process(); + m_ffmpeg.StartInfo.WorkingDirectory = work_dir; + m_ffmpeg.StartInfo.FileName = "\"" + AppManager.Config.PathFFmpeg + "\""; + m_ffmpeg.StartInfo.Arguments = arguments; + m_ffmpeg.StartInfo.CreateNoWindow = true; + m_ffmpeg.StartInfo.UseShellExecute = false; + m_ffmpeg.StartInfo.RedirectStandardError = true; + m_ffmpeg.Start(); + this.m_stdout = new Thread( new ParameterizedThreadStart( this.FFMpegOutputRead ) ); + this.m_stdout.Name = "output_ffmpeg"; + this.m_stdout.Start( end_frame - start_frame ); + m_ffmpeg.WaitForExit(); + } catch ( Exception ex ) { +#if DEBUG + Common.DebugWriteLine( ex.ToString() ); +#endif + } + #endregion + } + + } + + + //mencoder test.avi -of lavf -lavfopts format=flv -ovc lavc -lavcopts vcodec=flv:vbitrate=500:mbd=2:ss:aiv:umv:preme=2:mv0:qprd:trell:v4mv:cbp -oac mp3lame -lameopts abr:br=128 -passlogfile pass.log -vf scale=512:384 -sws 9 -af resample=44100 -o test.flv +#if !DEBUG + } catch { + writer.Close(); + MessageBox.Show( + _( "Initialization of video compression failed.\nThis video codec may require image width in multiples of certain number." ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation + ); + } +#endif + } + + private void bgWorkAvi_ProgressChanged( object sender, ProgressChangedEventArgs e ) { + long[] stat = (long[])e.UserState; + this.Text = _( "AVI Progress" ) + " " + e.ProgressPercentage + "% [" + stat[0] + "/" + stat[1] + "]"; + } + + private void bgWorkAvi_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e ) { + this.Invoke( new Form1_AviWritingChange( ChangeAviWriting ), new object[] { false } ); + m_avi_cancel = false; + UpdateFormTitle(); + } + #endregion + + #region menuEdit + /// + /// キャンバス背景色の変更 + /// + /// + /// + private void menuEditBGColor_Click( object sender, EventArgs e ) { + colorDialog1.Color = AppManager.SaveData.CANVAS_BACKGROUND; + if ( colorDialog1.ShowDialog() == DialogResult.OK ) { + Command run = Command.GCommandChangeBackgroundColor( colorDialog1.Color ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + this.Invalidate(); + } + } + + private void menuEditAddCharacter_Click( object sender, EventArgs e ) { + List plugins = new List(); + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + if ( (AppManager.SaveData.m_plugins[i].Instance.Type & Plugin.Constants.LS_TYPE_CHARACTER) == Plugin.Constants.LS_TYPE_CHARACTER ) { + plugins.Add( AppManager.SaveData.m_plugins_config[i].ID ); + } + } + using ( SelectCharacater sc = new SelectCharacater( plugins ) ) { + if ( sc.ShowDialog() == DialogResult.OK ) { + using ( TimeTable tempo = new TimeTable( "", 0, TimeTableType.vsq, null ) ) { + GenerateLipsyncFromVsq( tempo, sc.Character, true ); + } + AppManager.Edited = true; + AppManager.Config.LastCharacterPath = sc.Path; + UpdateObjectList(); + SetVScrollRange(); + this.Invalidate(); + } + } + } + + private void menuEditVideoLength_Click( object sender, EventArgs e ) { + using ( InputBox box = new InputBox( _( "Video size configuration" ), _( "Input video length in second" ) ) ) { + box.rText = AppManager.SaveData.m_totalSec.ToString(); + if ( box.ShowDialog() == DialogResult.OK ) { + float buff = AppManager.SaveData.m_totalSec; + try { + buff = float.Parse( box.rText ); + } catch { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation + ); + buff = AppManager.SaveData.m_totalSec; + } finally { + AppManager.SaveData.m_totalSec = buff; + } + //rebuildDrawing(); + AppManager.Edited = true; + AppManager.SaveData.UpdateZorder(); + SetHScrollRange(); + this.Invalidate(); + } + } + } + + private void menuEditShiftTimeline_Click( object sender, EventArgs e ) { + using ( InputBox ibox = new InputBox( _( "Shift all time-tables" ), _( "Input shift time in second (you can enter minus value)" ) ) ) { + if ( ibox.ShowDialog() == DialogResult.OK ) { + float shift; + try { + shift = float.Parse( ibox.rText ); + } catch { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation + ); + return; + } + Command run = Command.GCommandShiftTimeTable( TimeTableType.whole, -1, shift ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + + private void menuEditFrameRate_Click( object sender, EventArgs e ) { + using ( FormSetFrameRate dlg = new FormSetFrameRate( AppManager.SaveData.DwRate, AppManager.SaveData.DwScale ) ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + uint rate = dlg.DwRate; + uint scale = dlg.DwScale; + if ( rate <= 0 || scale <= 0 ) { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation + ); + } else { +#if DEBUG + Common.DebugWriteLine( "menuEditFrameRate_Click; rate=" + rate + "; scale=" + scale ); +#endif + Command run = Command.GCommandChangeFps( rate, scale ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + ChangeBitrate(); + AppManager.Edited = true; +#if DEBUG + Common.DebugWriteLine( "menuEditFrameRate_Click; s.DwRate=" + AppManager.SaveData.DwRate + "; s.DwScale=" + AppManager.SaveData.DwScale ); +#endif + } + } + } + } + + private void menuEditUndo_Click( object sender, EventArgs e ) { + CommandType next = AppManager.GetNextUndoCommandType(); + AppManager.Undo(); + if ( next == CommandType.changeFps ) { + ChangeBitrate(); + } + UpdateObjectList(); + AppManager.Edited = true; + this.Invalidate(); + } + + private void menuEditRedo_Click( object sender, EventArgs e ) { + CommandType next = AppManager.GetNextRedoCommandType(); + AppManager.Redo(); + if ( next == CommandType.changeFps ) { + ChangeBitrate(); + } + UpdateObjectList(); + AppManager.Edited = true; + this.Invalidate(); + } + + /// + /// + /// + /// + /// + private void menuEditZOrder_Click( object sender, EventArgs e ) { + ZOrder zorder = new ZOrder(); + zorder.Clear(); + int count = 0; + int cur_z = -1; + + #region フォームを作成 + + // まず、zオーダーを設定可能なオブジェクトの個数を数える + // プラグイン + count += AppManager.SaveData.m_plugins.Length; + bool[] b_plugins = new bool[AppManager.SaveData.m_group_plugin.Count]; + for ( int i = 0; i < AppManager.SaveData.m_group_plugin.Count; i++ ) { + b_plugins[i] = false; + cur_z = Math.Max( cur_z, AppManager.SaveData.m_group_plugin[i].ZOrder ); + } + // キャラクタ + count += AppManager.SaveData.m_groups_character.Count; + bool[] b_groups_character = new bool[AppManager.SaveData.m_groups_character.Count]; + for ( int i = 0; i < b_groups_character.Length; i++ ) { + b_groups_character[i] = false; + cur_z = Math.Max( cur_z, AppManager.SaveData.m_groups_character[i].ZOrder ); + } + // その他のイメージ + count += AppManager.SaveData.m_group_another.Count; + bool[] b_group_another = new bool[AppManager.SaveData.m_group_another.Count]; + for ( int i = 0; i < b_group_another.Length; i++ ) { + b_group_another[i] = false; + cur_z = Math.Max( cur_z, AppManager.SaveData.m_group_another[i].ZOrder ); + } + + //MessageBox.Show( "count=" + count ); + + ZorderItem[] list = new ZorderItem[count]; + int[] eval = new int[count]; + int[] order = new int[count]; + int index = -1; + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + index++; + list[index] = new ZorderItem( AppManager.SaveData.m_plugins_config[i].ID, ZorderItemType.plugin, i ); + eval[index] = AppManager.SaveData.m_group_plugin[i].ZOrder; + } + for ( int i = 0; i < AppManager.SaveData.m_groups_character.Count; i++ ) { + index++; + list[index] = new ZorderItem( AppManager.SaveData.m_groups_character[i].Text, ZorderItemType.character, i ); + eval[index] = AppManager.SaveData.m_groups_character[i].ZOrder; + } + for ( int i = 0; i < AppManager.SaveData.m_group_another.Count; i++ ) { + index++; + list[index] = new ZorderItem( AppManager.SaveData.m_group_another[i].Text, ZorderItemType.another, i ); + eval[index] = AppManager.SaveData.m_group_another[i].ZOrder; + } + + // 並べ変え + int change = 1; + ZorderItem tmp; + int itemp; + while ( change > 0 ) { + change = 0; + for ( int i = 0; i < count - 1; i++ ) { + if ( eval[i] > eval[i + 1] ) { + tmp = list[i]; + list[i] = list[i + 1]; + list[i + 1] = tmp; + itemp = eval[i]; + eval[i] = eval[i + 1]; + eval[i + 1] = itemp; + change++; + } + } + } + + // zオーダーの大きいものから、listBox1に登録 + for ( int i = 0; i < count; i++ ) { + zorder.itemAdd( list[i] ); + } + #endregion + + //MessageBox.Show( "zorder.Count=" + zorder.Count ); + + if ( zorder.ShowDialog() == DialogResult.OK ) { + + // フォームの応答から、zorderを再計算 + for ( int i = 0; i < zorder.Count; i++ ) { + AppManager.SaveData.SetZorder( zorder[i], i + 1 ); + } + + AppManager.Edited = true; + AppManager.SaveData.UpdateZorder(); + } + zorder.Dispose(); + } + + private void menuEditRealTime_Click( object sender, EventArgs e ) { + UpdateFormTitle(); + } + + private void menuEdit_DropDownOpening( object sender, EventArgs e ) { + menuEditUndo.Enabled = AppManager.IsUndoAvailable; + menuEditRedo.Enabled = AppManager.IsRedoAvailable; + if ( AppManager.SaveData.m_totalSec <= 0.0f ) { + menuEditShiftTimeline.Enabled = false; + menuEditAddCharacter.Enabled = false; + } else { + menuEditShiftTimeline.Enabled = true; + menuEditAddCharacter.Enabled = true; + } + if ( AppManager.SaveData.m_groups_character.Count == 0 ) { + menuEditRealTime.Enabled = false; + } else { + menuEditRealTime.Enabled = true; + } + menuEditAddCharacter.Enabled = !AppManager.Playing; + } + + private void menuEditVideoSize_Click( object sender, EventArgs e ) { + sizeChange(); + } + + private void menuFileOutputAvi_Click( object sender, EventArgs e ) { + if ( AppManager.Playing ) { + StopMusic(); + } + initializeFirstEntry(); + m_is_rawmode = false; + ShowDialogCore(); + } + + private void menuFileOutputRawAvi_Click( object sender, EventArgs e ) { + if ( AppManager.Playing ) { + StopMusic(); + } + initializeFirstEntry(); + m_is_rawmode = true; + ShowDialogCore(); + } + #endregion + + #region xmenuFile + private void xmenuFileClose_Click( object sender, EventArgs e ) { + if ( AppManager.Edited ) { + //MessageBox.Show( "Form1_FormClosing" ); + DialogResult result = requestIntention(); + switch ( result ) { + case DialogResult.Yes: + if ( m_filePath == "" ) { + if ( saveFileDialog1.ShowDialog() == DialogResult.OK ) { + m_filePath = saveFileDialog1.FileName; + Save( m_filePath ); + } else { + return; + } + } else { + Save( m_filePath ); + } + break; + case DialogResult.Cancel: + return; + } + } + if ( m_player != null ) { + m_player.Stop(); + m_player.Close(); + } + + AppManager.Edited = false; + m_filePath = ""; + UpdateFormTitle(); + ClearExistingData(); + AppManager.ClearCommandBuffer(); + AppManager.SaveData.UpdateZorder(); + this.Invalidate(); + } + + private void xmenuFileOpenVsq_Click( object sender, EventArgs e ) { + // 既存のトラックがないかどうか確認。 + int count = 0; + count += AppManager.SaveData.m_group_vsq.Count; + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + count += AppManager.SaveData.m_groups_character[group].Count; + } + count += AppManager.SaveData.m_group_another.Count; + count += AppManager.SaveData.m_telop_ex2.Count; + if ( count > 0 ) { + if ( MessageBox.Show( + _( "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" ) + "\n\n" + _( "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" ), + _( "Confirmation" ), + MessageBoxButtons.OKCancel, + MessageBoxIcon.Question ) != DialogResult.OK ) { + return; + } + } + + List track_name = new List(); + int tracks; + + // VSQファイルを開いて、解析 + openVsqDialog.FileName = AppManager.Config.LastVsqPath; + try { + openVsqDialog.Filter = _( "VOCALOID2 Sequence File(*.vsq)|*.vsq" ) + "|" + + _( "UTAU Script File(*.ust)|*.ust" ) + "|" + + _( "All Files(*.*)|*.*" ); + } catch { + openVsqDialog.Filter = "VOCALOID2 Sequence File(*.vsq)|*.vsq|UTAU Script File(*.ust)|*.ust|All Files(*.*)|*.*"; + } + if ( openVsqDialog.ShowDialog() != DialogResult.OK ) { + return; + } + AppManager.Config.LastVsqPath = openVsqDialog.FileName; + + // 既存のtime tableを破棄 + ClearExistingData(); + tracks = 0; + + if ( openVsqDialog.FilterIndex == 0 || Path.GetExtension( openVsqDialog.FileName ).ToLower() == ".vsq" ) { + // VsqFileを取得 + int most_lyrics_track = 0; // 一番歌詞の文字数が多かったトラックの番号 + VsqFile vsqFile = new VsqFile( openVsqDialog.FileName ); + AppManager.SaveData.m_totalSec = (float)vsqFile.getTotalSec(); + + AppManager.SaveData.m_timesig_ex = new List( vsqFile.getTimeSigList().ToArray() ); + AppManager.SaveData.m_tempo = new List( vsqFile.getTempoList().ToArray() ); + AppManager.SaveData.m_base_tempo = vsqFile.getBaseTempo(); + + // 歌詞の含まれるトラック数を取得 + { + int most_lyrics = 0; + for ( int i = 0; i < vsqFile.getTrackCount(); i++ ) { + int track_num = vsqFile.getTrack( i ).getLyricLength(); + if ( most_lyrics < track_num ) { + most_lyrics_track = i; + most_lyrics = track_num; + } + if ( track_num > 0 ) { + track_name.Add( vsqFile.getTrack( i ).Name ); + tracks++; + } + } + } + most_lyrics_track--; + + // tableを更新 + for ( int track = 0; track < vsqFile.getTrackCount(); track++ ) { + int lyrics = vsqFile.getTrack( track ).getLyricLength(); + if ( lyrics <= 0 ) { + continue; + } + addTimeLineFromTrack( vsqFile, track, false ); + // todo この辺うまく行ってない? + } + + if ( AppManager.Config.GenerateCharacterAutomatically ) { + // 一番歌詞の文字数が多かったトラックの歌詞をもとに + // 口の動きを決める + GenerateLipsyncFromVsq( AppManager.SaveData.m_group_vsq[most_lyrics_track], Character3.Miku, false ); + } + } else { + UstFile ust_file = new UstFile( openVsqDialog.FileName ); + for ( int track = 0; track < ust_file.getTrackCount(); track++ ) { + foreach ( UstEvent ue in ust_file.getTrack( track ).getNoteEventEnumerator() ) { + if ( ue.Lyric == "u" ) { + ue.Lyric = "う"; + } + } + } + AppManager.SaveData.m_totalSec = (float)ust_file.getTotalSec(); + + AppManager.SaveData.m_timesig_ex = new List(); + AppManager.SaveData.m_timesig_ex.Add( new TimeSigTableEntry( 0, 4, 4, 0 ) ); //todo: bar_countは零? + AppManager.SaveData.m_tempo = new List( ust_file.getTempoList().ToArray() ); + AppManager.SaveData.m_base_tempo = ust_file.getBaseTempo(); + + // tableを更新 + for ( int track = 0; track < ust_file.getTrackCount(); track++ ) { + AddTimeLineFromUst( ust_file, track, false ); + } + + if ( AppManager.Config.GenerateCharacterAutomatically ) { + // 一番歌詞の文字数が多かったトラックの歌詞をもとに + // 口の動きを決める + GenerateLipsyncFromVsq( AppManager.SaveData.m_group_vsq[0], Character3.Miku, false ); + } + } + + // そのほかのイメージトラック用のグループを追加 + AppManager.SaveData.m_group_another = null; + AppManager.SaveData.m_group_another = new TimeTableGroup( _( "Another images" ), -1, null ); + + // スクリーンの(仮想)サイズを更新 + SetHScrollRange(); + SetVScrollRange(); + + AppManager.ClearCommandBuffer(); + AppManager.SaveData.UpdateZorder(); + AppManager.Edited = true; + UpdateGridList(); + UpdateObjectList(); + + // 再描画を要求 + this.Invalidate(); + } + + private void xmenuFileOutputAbort_Click( object sender, EventArgs e ) { + if ( !m_avi_cancel ) { + m_avi_cancel = true; + AviWriting = false; + UpdateFormTitle(); + } + } + + private void xmenuFile_DropDownOpening( object sender, EventArgs e ) { + bool value = !AviWriting && AppManager.SaveData.m_totalSec > 0.0f; + xmenuFileOutputAvi.Enabled = value; + xmenuFileOutputRawAvi.Enabled = value; + xmenuFileSeriesBitmap.Enabled = value; + + if ( AppManager.SaveData.m_groups_character.Count <= 0 ) { + xmenuFileExportHatwune.Enabled = false; + xmenuFileExportVocaloMark.Enabled = false; + } else { + xmenuFileExportHatwune.Enabled = true; + xmenuFileExportVocaloMark.Enabled = true; + } + } + + private void xmenuFileExportHatwune_Click( object sender, EventArgs e ) { + int target = 0; + if ( AppManager.SaveData.m_groups_character.Count > 1 ) { + string msg = _( "Specify the index of target character" ); + for ( int i = 0; i < AppManager.SaveData.m_groups_character.Count; i++ ) { + msg += "\n" + i + " : " + AppManager.SaveData.m_groups_character[i].Text; + } + using ( InputBox dlg = new InputBox( msg, "LipSync" ) ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + try { + target = int.Parse( dlg.rText ); + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + if ( target < 0 || AppManager.SaveData.m_groups_character.Count <= target ) { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + } + } + } + using ( SaveFileDialog dlg2 = new SaveFileDialog() ) { + if ( dlg2.ShowDialog() == DialogResult.OK ) { + string file = dlg2.FileName; + using ( StreamWriter sw = new StreamWriter( file, false, Encoding.GetEncoding( "Shift_JIS" ) ) ) + using ( TimeTable table = new TimeTable( "", 0, TimeTableType.none, null ) ) { + sw.WriteLine( "Init{" ); + sw.WriteLine( "\tSetFog( 10.0, 180.0, 200, 225, 255 )" ); + sw.WriteLine( "\tSetGlareFilter( 1.0, 1.0, 1.0, 0.20, -0.81, -0.80, -0.78, 0.0 )" ); + sw.WriteLine( "\tSetDirectionLight( -1.0, -0.6, -0.4 )" ); + sw.WriteLine( "\tSetAmbientLight( 1.0, 1.0, 1.0 )" ); + sw.WriteLine( "\tSetBGColor( 0, 0, 0 )" ); + sw.WriteLine( "\tLoadStage( \"data\\xsi\\stage01\\\", \"stage01.xsibin\" )" ); + bool wave_exists = false; + if ( Path.GetExtension( AppManager.SaveData.m_audioFile ).ToLower() == ".wav" ) { + wave_exists = true; + sw.WriteLine( "\tLoadBGM( \"" + Path.GetDirectoryName( AppManager.SaveData.m_audioFile ) + "\", \"" + Path.GetFileName( AppManager.SaveData.m_audioFile ) + "\" )" ); + } + sw.WriteLine( "}" ); + sw.WriteLine( "Main{" ); + sw.WriteLine( "\tCamera( 0, Offset, 0, 1.45, 3.2, 0, 1.0, 0, 0, Linear, 0 )" ); + sw.WriteLine( "\tMotion( 0, GoMyWay, 0, 1.5, 0 )" ); + if ( wave_exists ) { + sw.WriteLine( " PlayBGM( 1.0 )" ); + } + sw.WriteLine( "\tAppendTriggerUncondition( 1.0, Face_Group )" ); + sw.WriteLine( "\tEnd( " + (AppManager.SaveData.m_totalSec + 1) + ", Return )" ); + sw.WriteLine( "}" ); + sw.WriteLine( "Face_Group{" ); + + // エントリを列挙 + for ( int track = 0; track < AppManager.SaveData.m_groups_character[target].Count; track++ ) { + for ( int entry = 0; entry < AppManager.SaveData.m_groups_character[target][track].Count; entry++ ) { + TimeTableEntry ent = AppManager.SaveData.m_groups_character[target][track][entry]; + table.Add( (TimeTableEntry)ent.Clone() ); + } + } + table.Sort(); + + //繋がってる奴は連結させておく + bool change = true; + while ( change ) { + change = false; + for ( int entry = 0; entry < table.Count - 1; entry++ ) { + if ( table[entry].body == table[entry + 1].body && table[entry].end == table[entry + 1].begin ) { + table[entry].end = table[entry + 1].end; + table.RemoveAt( entry + 1 ); + change = true; + break; + } + } + } + + for ( int entry = 0; entry < table.Count; entry++ ) { + string type; + float begin = table[entry].begin; + float end = table[entry].end; + switch ( table[entry].body ) { + case "a": + type = "L_A"; + break; + case "i": + type = "L_I"; + break; + case "u": + type = "L_U"; + break; + case "e": + type = "L_E"; + break; + case "o": + case "xo": + type = "L_O"; + break; + case "nn": + type = "L_Default"; + break; + default: + type = ""; + break; + } + if ( type != "" ) { + bool force_default = true; + if ( entry + 1 < table.Count ) { + if ( end == table[entry + 1].begin ) { + force_default = false; + } + } + + if ( force_default ) { + //todo: 0.30より短い場合は? + sw.WriteLine( "\tFace( " + begin + ", " + type + ", " + 0.15 + " )" ); + sw.WriteLine( "\tFace( " + (end - 0.15) + ", L_Default, " + 0.15 + " )" ); + } else { + sw.WriteLine( "\tFace( " + begin + ", " + type + ", " + 0.15 + " )" ); + } + } + } + sw.WriteLine( "}" ); + } + } + } + } + + private void xmenuFileExportVocaloMark_Click( object sender, EventArgs e ) { + using ( FormVocalomark fv = new FormVocalomark( AppManager.SaveData.m_groups_character[0].Character ) ) { + fv.ShowDialog(); + int target = 0; + if ( AppManager.SaveData.m_groups_character.Count > 1 ) { + string msg = _( "Specify the index of target character" ); + for ( int i = 0; i < AppManager.SaveData.m_groups_character.Count; i++ ) { + msg += "\n" + i + " : " + AppManager.SaveData.m_groups_character[i].Text; + } + using ( InputBox dlg = new InputBox( msg, "LipSync" ) ) { + if ( dlg.ShowDialog() == DialogResult.OK ) { + try { + target = int.Parse( dlg.rText ); + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + if ( target < 0 || AppManager.SaveData.m_groups_character.Count <= target ) { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + } + } + } + using ( SaveFileDialog dlg2 = new SaveFileDialog() ) { + if ( dlg2.ShowDialog() == DialogResult.OK ) { + string file = dlg2.FileName; + using ( StreamWriter sw = new StreamWriter( file, false, Encoding.GetEncoding( "Shift_JIS" ) ) ) + using ( TimeTable table = new TimeTable( "", 0, TimeTableType.none, null ) ) { + // エントリを列挙 + for ( int track = 0; track < AppManager.SaveData.m_groups_character[target].Count; track++ ) { + for ( int entry = 0; entry < AppManager.SaveData.m_groups_character[target][track].Count; entry++ ) { + TimeTableEntry ent = AppManager.SaveData.m_groups_character[target][track][entry]; + table.Add( (TimeTableEntry)ent.Clone() ); + } + } + table.Sort(); + + //繋がってる奴は連結させておく + bool change = true; + while ( change ) { + change = false; + for ( int entry = 0; entry < table.Count - 1; entry++ ) { + if ( table[entry].body == table[entry + 1].body && table[entry].end == table[entry + 1].begin ) { + table[entry].end = table[entry + 1].end; + table.RemoveAt( entry + 1 ); + change = true; + break; + } + } + } + + Dictionary dict = new Dictionary(); + foreach ( KeyValuePair kvp in fv.Assignment ) { + dict.Add( kvp.Value, kvp.Key ); + } + + sw.WriteLine( "ShapeAnime_LipSync{" ); + for ( int i = 0; i < table.Count; i++ ) { + if ( dict.ContainsKey( table[i].body ) ) { + string type = dict[table[i].body]; + float blend_from_default = 0.05f; + float blend_to_default = 0.05f; + string def = "L_Default"; + if ( type.StartsWith( "E_" ) ){ + blend_from_default = fv.BlendEyeFromDefault; + blend_to_default = fv.BlendEyeToDefault; + def = "E_Default"; + } else if ( type.StartsWith( "EB_" ) ){ + blend_from_default = fv.BlendEyebrowFromDefault; + blend_to_default = fv.BlendEyebrowToDefault; + def = "EB_Default"; + } else if ( type.StartsWith( "L_" ) ){ + blend_from_default = fv.BlendLipFromDefault; + blend_to_default = fv.BlendLipToDefault; + } + sw.WriteLine( "\tSetShape(" + table[i].begin.ToString( "0.000000" ) + ", DefaultUnit, " + type + ", " + blend_from_default.ToString( "0.000000" ) + ")" ); + sw.WriteLine( "\tSetShape(" + table[i].end.ToString( "0.000000" ) + ", DefaultUnit, " + def + ", " + blend_to_default.ToString( "0.000000" ) + ")" ); + sw.WriteLine(); + } + } + sw.WriteLine( "}" ); + } + } + } + } + //todo: Form1+xmenuFileExportVocaloMark_Click + //ShapeAnime_LipSync + //{ + // SetShape(4.195052, DefaultUnit, L_O, 0.1) + // SetShape(4.375056, DefaultUnit, L_Default, 0.2) + + //ShapeAnime_Eye + //{ + // SetShape(1.945060, DefaultUnit, E_Close, 0.05) + // SetShape(2.020068, DefaultUnit, E_Default, 0.05) + //E_Close + //E_Default + //E_Sad + //E_Serious + //E_Smile + //E_Surprise + //E_WinkL + //E_WinkR + //EB_Confuse + //EB_Default + //EB_Sad + //EB_Serious + //EB_Surprise + //L_Default + //L_A + //L_E + //L_I + //L_N + //L_O + //L_U + } + + private void xmenuFileImportRipsync_Click( object sender, EventArgs e ) { + if ( MessageBox.Show( _( "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" ), + _( "Confirmation" ), + MessageBoxButtons.OKCancel, + MessageBoxIcon.Question ) != DialogResult.OK ) { + return; + } + if ( openRseDialog.ShowDialog() == DialogResult.OK ) { + string file = openRseDialog.FileName; + if ( File.Exists( file ) ) { + ClearExistingData(); + RspImporter.Import( file, ref AppManager.SaveData ); + AppManager.Edited = true; + SetVScrollRange(); + SetHScrollRange(); + if ( m_player.SoundLocation != "" ) { + m_player.Close(); + AppManager.Playing = false; + StopPauseCore(); + previewer.PlayPauseText = _( "Play" ); + } + m_player.Load( AppManager.SaveData.m_audioFile ); + } else { + MessageBox.Show( _( "File not found" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + } + } + } + + private void xmenuFileExit_Click( object sender, EventArgs e ) { + SaveConfig(); + this.Close(); + } + + private void xmenuFileSaveAs_Click( object sender, EventArgs e ) { + if ( saveFileDialog1.ShowDialog() == DialogResult.OK ) { + if ( Path.GetExtension( saveFileDialog1.FileName ).ToLower() == ".lse" ) { + m_filePath = saveFileDialog1.FileName; + Save( m_filePath ); + } else { + MessageBox.Show( _( "Extension must be *.lse" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + } + } + } + + private void xmenuFileOpen_Click( object sender, EventArgs e ) { + if ( openLse.ShowDialog() == DialogResult.OK ) { + Read( openLse.FileName ); + m_filePath = openLse.FileName; + UpdateFormTitle(); + SetHScrollRange(); + SetVScrollRange(); + AppManager.SaveData.UpdateZorder(); + UpdateObjectList(); + pictureBox1.Invalidate(); + } + } + + private void xmenuFileSave_Click( object sender, EventArgs e ) { + if ( m_filePath == "" ) { + if ( saveFileDialog1.ShowDialog() == DialogResult.OK ) { + if ( Path.GetExtension( saveFileDialog1.FileName ).ToLower() == ".lse" ) { + m_filePath = saveFileDialog1.FileName; + Save( m_filePath ); + } else { + MessageBox.Show( _( "Extension must be *.lse" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + } + } else { + return; + } + } else { + if ( Path.GetExtension( m_filePath ).ToLower() == ".lse" ) { + Save( m_filePath ); + } else { + MessageBox.Show( _( "Extension must be *.lse" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + } + } + } + + private void xmenuFileSeriesBitmap_Click( object sender, EventArgs e ) { + using ( FormSeriesImage fsi = new FormSeriesImage() ) { + if ( fsi.ShowDialog() == DialogResult.OK ) { + AviWriting = true; + m_avi_cancel = false; + AviOutputArguments args = new AviOutputArguments(); + args.AviFile = fsi.DirectoryName; + args.StartSpecified = fsi.StartSpecified; + args.EndSpecified = fsi.EndSpecified; + args.Start = fsi.Start; + args.End = fsi.End; + args.FileNameParser = fsi.ParserString; + args.ImageFormat = fsi.ImageFormat; + bgWorkSeriesImage.RunWorkerAsync( args ); + } + } + } + #endregion + + #region side + private void side_MouseClick( object sender, MouseEventArgs e ) { + if ( e.Button == MouseButtons.Left ) { + int y = e.Y + m_startToDrawY; + + int rows = 1; + bool vsq_fixed = AppManager.Config.FixVsqTrackPosition; + // VSQトラック + if ( vsq_fixed ) { + if ( rows * AppManager.Config.TrackHeight <= e.Y && e.Y < (rows + 1) * AppManager.Config.TrackHeight ) { + AppManager.SaveData.m_group_vsq.Folded = !AppManager.SaveData.m_group_vsq.Folded; + m_vsq_height = AppManager.Config.TrackHeight * (AppManager.SaveData.m_group_vsq.VisibleTracks + 2); + SetVScrollRange(); + this.Invalidate(); + return; + } + } else { + if ( rows * AppManager.Config.TrackHeight <= y && y < (rows + 1) * AppManager.Config.TrackHeight ) { + AppManager.SaveData.m_group_vsq.Folded = !AppManager.SaveData.m_group_vsq.Folded; + m_vsq_height = AppManager.Config.TrackHeight * (AppManager.SaveData.m_group_vsq.VisibleTracks + 2); + SetVScrollRange(); + this.Invalidate(); + return; + } + } + rows++; + if ( !AppManager.SaveData.m_group_vsq.Folded ) { + rows += AppManager.SaveData.m_group_vsq.Count; + } + // character + if ( AppManager.SaveData.m_groups_character.Count > 0 ) { + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + if ( rows * AppManager.Config.TrackHeight <= y && y < (rows + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && e.Y >= m_vsq_height) ) { + AppManager.SaveData.m_groups_character[group].Folded = !AppManager.SaveData.m_groups_character[group].Folded; + SetVScrollRange(); + m_startToDrawY = StartToDrawY(); + this.Invalidate(); + return; + } + } + rows++; + if ( !AppManager.SaveData.m_groups_character[group].Folded ) { + rows += AppManager.SaveData.m_groups_character[group].Count; + } + } + } + // telop + if ( rows * AppManager.Config.TrackHeight <= y && y < (rows + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && e.Y >= m_vsq_height) ) { + AppManager.SaveData.TelopListFolded = !AppManager.SaveData.TelopListFolded; + SetVScrollRange(); + m_startToDrawY = StartToDrawY(); + this.Invalidate(); + return; + } + } + rows++; + if ( !AppManager.SaveData.TelopListFolded ) { + rows += AppManager.MaxTelopLanes; + } + // another + if ( rows * AppManager.Config.TrackHeight <= y && y < (rows + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && e.Y >= m_vsq_height) ) { + AppManager.SaveData.m_group_another.Folded = !AppManager.SaveData.m_group_another.Folded; + SetVScrollRange(); + m_startToDrawY = StartToDrawY(); + this.Invalidate(); + return; + } + } + rows++; + if ( !AppManager.SaveData.m_group_another.Folded ) { + rows += AppManager.SaveData.m_group_another.Count; + } + // plugin + if ( rows * AppManager.Config.TrackHeight <= y && y < (rows + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && e.Y >= m_vsq_height) ) { + AppManager.SaveData.m_group_plugin.Folded = !AppManager.SaveData.m_group_plugin.Folded; + SetVScrollRange(); + m_startToDrawY = StartToDrawY(); + this.Invalidate(); + return; + } + } + rows++; + if ( !AppManager.SaveData.m_group_plugin.Folded ) { + rows += AppManager.SaveData.m_group_plugin.Count; + } + } else if ( e.Button == MouseButtons.Right ) { + if ( !cmenu.IsDisposed || cmenu != null ) { + cmenu.Dispose(); + } + cmenu = new ContextMenuStrip(); + cmenu.RenderMode = ToolStripRenderMode.ManagerRenderMode; + cmenu.ShowCheckMargin = false; + cmenu.ShowImageMargin = false; + cmenu.Font = AppManager.Config.Font.GetFont(); + cmenu.Items.Add( _( "Expand All" ), null, new EventHandler( h_expandAll ) ); + cmenu.Items.Add( _( "Fold All" ), null, new EventHandler( h_foldAll ) ); + cmenu.Show( side, new Point( e.X, e.Y ) ); + } + } + + private void side_Paint( object sender, PaintEventArgs e ) { + if ( m_skip_paint ) { + return; + } + Graphics g = e.Graphics; + g.Clear( TOOL_COLOR ); + int rows = 1; + // VSQトラック + bool vsq_fixed = AppManager.Config.FixVsqTrackPosition; + if ( !vsq_fixed ) { + DrawTriangle( g, rows * AppManager.Config.TrackHeight - m_startToDrawY, AppManager.SaveData.m_group_vsq.Folded ); + } + rows++; + if ( !AppManager.SaveData.m_group_vsq.Folded ) { + rows += AppManager.SaveData.m_group_vsq.Count; + } + + // character + if ( AppManager.SaveData.m_groups_character.Count > 0 ) { + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + DrawTriangle( g, rows * AppManager.Config.TrackHeight - m_startToDrawY, AppManager.SaveData.m_groups_character[group].Folded ); + rows++; + if ( !AppManager.SaveData.m_groups_character[group].Folded ) { + rows += AppManager.SaveData.m_groups_character[group].Count; + } + } + } + + // telop + DrawTriangle( g, rows * AppManager.Config.TrackHeight - m_startToDrawY, AppManager.SaveData.TelopListFolded ); + rows++; + if ( !AppManager.SaveData.TelopListFolded ) { + rows += AppManager.MaxTelopLanes; + } + + // another + DrawTriangle( g, rows * AppManager.Config.TrackHeight - m_startToDrawY, AppManager.SaveData.m_group_another.Folded ); + rows++; + if ( !AppManager.SaveData.m_group_another.Folded ) { + rows += AppManager.SaveData.m_group_another.Count; + } + // plugin + DrawTriangle( g, rows * AppManager.Config.TrackHeight - m_startToDrawY, AppManager.SaveData.m_group_plugin.Folded ); + rows++; + if ( !AppManager.SaveData.m_group_plugin.Folded ) { + rows += AppManager.SaveData.m_group_plugin.Count; + } + if ( vsq_fixed ) { + g.FillRectangle( + new SolidBrush( TOOL_COLOR ), + new Rectangle( 0, 0, side.Width, m_vsq_height ) ); + g.DrawLine( + new Pen( Color.Black, 2 ), + new Point( 0, m_vsq_height ), + new Point( side.Width, m_vsq_height ) ); + DrawTriangle( g, AppManager.Config.TrackHeight, AppManager.SaveData.m_group_vsq.Folded ); + } + } + #endregion + + private void SettingsEx_CommandExecuted( TimeTableType command_target, CommandType command_type ) { +#if DEBUG + Common.DebugWriteLine( "AppManager_CommandExecuted" ); +#endif + if ( command_type == CommandType.deleteEntry || + command_type == CommandType.deleteGroup || + command_type == CommandType.deleteTelop || + command_type == CommandType.deleteTimeTable ) { + + } + menuEditRedo.Enabled = AppManager.IsRedoAvailable; + menuEditUndo.Enabled = AppManager.IsUndoAvailable; + this.Refresh(); + } + + private void previewer_SpeedClicked( object sender, EventArgs e ) { + previewer.TrackSpeedValue = 1000; + ChangeSpeed( 1000 ); + } + + #region trackSpeed + private void previewer_TrackSpeedMouseUp( object sender, MouseEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "trackSpeed_MouseUp" ); +#endif + ChangeSpeed( previewer.TrackSpeedValue ); + } + + private void previewer_TrackSpeedScroll( object sender, EventArgs e ) { + float speed = previewer.TrackSpeedValue * 0.001f; + previewer.LabelSpeedText = "x" + speed.ToString( "0.00" ); + } + #endregion + + #region cmenuRepeat + private void cmenuRepeatStart_Click( object sender, EventArgs e ) { + AppManager.SaveData.REPEAT_START = SecFromXCoord( m_mousePosition.X ); + } + + private void cmenuRepeatEnd_Click( object sender, EventArgs e ) { + AppManager.SaveData.REPEAT_END = SecFromXCoord( m_mousePosition.X ); + } + + private void cmenuRepeatReset_Click( object sender, EventArgs e ) { + AppManager.SaveData.REPEAT_START = 0f; + AppManager.SaveData.REPEAT_END = -1f; + } + + private void cmenuRepeat_Opening( object sender, CancelEventArgs e ) { + float pos = SecFromXCoord( m_mousePosition.X ); + if ( RepeatEnd < pos ) { + cmenuRepeatStart.Enabled = false; + } else { + cmenuRepeatStart.Enabled = true; + } + if ( RepeatStart > pos ) { + cmenuRepeatEnd.Enabled = false; + } else { + cmenuRepeatEnd.Enabled = true; + } + } + #endregion + + #region menuVisual* + private void menuVisualTop_Click( object sender, EventArgs e ) { + if ( hScrollBar1.Value != hScrollBar1.Minimum ) { + hScrollBar1.Value = hScrollBar1.Minimum; + m_startToDrawX = StartToDrawX(); + this.Invalidate(); + } + } + + private void menuVisualEnd_Click( object sender, EventArgs e ) { + if ( hScrollBar1.Value != hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange ) { + hScrollBar1.Value = hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange; + m_startToDrawX = StartToDrawX(); + this.Invalidate(); + } + } + + /// + /// タイムラインの時間拡大率をリセットします + /// + /// + /// + private void menuVisualZoomReset_Click( object sender, EventArgs e ) { + AppManager.Config.PixelPerSec = 150.0f; + SetHScrollRange(); + correctPosition(); + //rebuildDrawing(); + this.Invalidate(); + } + + private void menuVisualZoomOut_Click( object sender, EventArgs e ) { + if ( AppManager.Config.PixelPerSec >= 20.0f ) { + AppManager.Config.PixelPerSec -= 10.0f; + SetHScrollRange(); + correctPosition(); + //rebuildDrawing(); + base.Invalidate(); + } + } + + private void menuVisualRepeatPlayPause_Click( object sender, EventArgs e ) { + m_is_repeat_mode = true; + if ( AppManager.Playing ) { + Pause(); + } else { + Play(); + } + } + + private void menuVisualRepeatTop_Click( object sender, EventArgs e ) { + m_is_repeat_mode = true; + if ( AppManager.Playing ) { + Pause(); + previewer.TrackBarValue = (int)(RepeatStart * AppManager.SaveData.FrameRate); + Play(); + } else { + previewer.TrackBarValue = (int)(RepeatStart * AppManager.SaveData.FrameRate); + } + this.Invalidate(); + } + + private void menuVisualRepeatEnd_Click( object sender, EventArgs e ) { + m_is_repeat_mode = true; + if ( AppManager.Playing ) { + Pause(); + } + previewer.TrackBarValue = (int)(RepeatEnd * AppManager.SaveData.FrameRate); + this.Invalidate(); + } + + private void menuVisualTransform_CheckedChanged( object sender, EventArgs e ) { + m_curve.Visible = menuVisualTransform.Checked; + } + + private void menuVisualPlayPause_Click( object sender, EventArgs e ) { + m_is_repeat_mode = false; + if ( AppManager.Playing ) { + Pause(); + } else { + Play(); + } + } + + private void menuVisualObjectList_Click( object sender, EventArgs e ) { + ChangePropertyHidden(); + } + + private void menuVisualZoomIn_Click( object sender, EventArgs e ) { + AppManager.Config.PixelPerSec += 10.0f; + SetHScrollRange(); + correctPosition(); + //rebuildDrawing(); + base.Invalidate(); + } + + private void menuVisualPreviewFlipVisible_Click( object sender, EventArgs e ) { + ChangePreviewHidden(); + } + + private void menuVisualPreviewSeparate_Click( object sender, EventArgs e ) { + PreviewWindowFlipMode(); + } + #endregion + + #region menuTool* + private void menuToolMusic_Click( object sender, EventArgs e ) { + if ( m_player.SoundLocation != "" ) { + m_player.Close(); + AppManager.Playing = false; + StopPauseCore();//timerPreview.Enabled = false; + previewer.PlayPauseText = _( "Play" ); + } + openMusicDialog.FileName = AppManager.Config.LastMusicPath; + try { + openMusicDialog.Filter = _( "Audio File(*.mp3;*.wav)|*.mp3;*.wav" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + openMusicDialog.Filter = "Audio File(*.mp3;*.wav)|*.mp3;*.wav|All Files(*.*)|*.*"; + } + if ( openMusicDialog.ShowDialog() == DialogResult.OK ) { + AppManager.Config.LastMusicPath = openMusicDialog.FileName; + Command run = Command.GCommandSetMp3( openMusicDialog.FileName ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + m_player.Load( AppManager.SaveData.m_audioFile ); + AppManager.Edited = true; + } + } + + private void menuToolMoveTo_Click( object sender, EventArgs e ) { + using ( InputBox ib = new InputBox( _( "Go to specified frame" ), _( "please input frame index" ) ) ) { + if ( ib.ShowDialog() == DialogResult.OK ) { + int frame; + try { + frame = int.Parse( ib.rText.Trim() ); + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + ib.Dispose(); + return; + } + if ( previewer.TrackBarMaximum < frame || frame < previewer.TrackBarMinimum ) { + MessageBox.Show( _( "invalid frame index" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + previewer.TrackBarValue = frame; + this.Invalidate(); + } + } + } + + private void menuToolQuantize04_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.q04; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantize08_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.q08; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantize16_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.q16; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantize32_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.q32; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantize64_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.q64; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantizeOff_Click( object sender, EventArgs e ) { + AppManager.Config.QuantizeMode = QuantizeMode.off; + QuantizeMenuCheckedStateUpdate(); + } + + private void menuToolQuantizeTriplet_CheckedChanged( object sender, EventArgs e ) { + AppManager.Config.QuantizeTripletEnabled = menuToolQuantizeTriplet.Checked; + UpdateGridList(); + } + + private void menuToolOption_Click( object sender, EventArgs e ) { + using ( EnvConfiguration env = new EnvConfiguration( AppManager.Config ) ) { + if ( env.ShowDialog() == DialogResult.OK ) { + // language + AppManager.Config = null; + AppManager.Config = (EnvSettings)env.EnvSettings.Clone(); + + ApplyFont( AppManager.Config.Font.GetFont() ); + property.UpdateLayout(); + if ( m_curve != null ) { + m_curve.ApplyFont( AppManager.Config.Font.GetFont() ); + } + if ( m_version_form != null ) { + m_version_form.Font = AppManager.Config.Font.GetFont(); + } + if ( m_form_preview != null ) { + m_form_preview.ApplyFont( AppManager.Config.Font.GetFont() ); + } + + string lang = AppManager.Config.Language; + string[] t_list = Messaging.GetRegisteredLanguage(); + bool found = false; + foreach ( string lng in t_list ) { + if ( lng == lang ) { + AppManager.Config.Language = lng; + Messaging.Language = lng; + found = true; + break; + } + } + if ( !found ) { + AppManager.Config.Language = ""; + Messaging.Language = ""; + } + ApplyLanguage(); + UpdateFormTitle(); + this.Invalidate(); + } + } + } + #endregion + + private void previewer_PlayPauseClicked( object sender, EventArgs e ) { + m_is_repeat_mode = false; + if ( AppManager.Playing ) { + Pause(); + } else { + Play(); + } + } + + private void previewer_StopClicked( object sender, EventArgs e ) { + StopMusic(); + } + + private void previewer_CheckMuteCheckedChanged( object sender, EventArgs e ) { + if ( previewer.CheckMuteChecked ) { + m_player.IsMuted = true; + } else { + m_player.IsMuted = false; + } + } + + private void previewer_TrackVolumeScroll( object sender, EventArgs e ) { + int volume = previewer.TrackVolumeValue; + m_player.Volume = volume; + } + + #region previewer + private void previewer_PreviewMouseDown( object sender, MouseEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "PreviewP_MouseDown" ); +#endif + if ( AppManager.Playing || AviWriting ) { + return; + } + + timerScreenUpdater.Enabled = true; + // オブジェクトのzオーダー順に、クリックされた位置に + // 表示されているオブジェクトが何かを検索する + float now = Now; + + //最初にテロップを検索 + foreach ( Telop telop in AppManager.SaveData.m_telop_ex2 ) { + if ( telop.Start <= now && now <= telop.End ) { + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( telop.GetPosition( now ) ), + Common.SizeFromSizeF( telop.ImageSize ) ), + telop.GetScale( now ) ), + telop.PositionFixed, + telop.IsXFixedAt( now ), + telop.IsYFixedAt( now ) ); +#if DEBUG + Common.DebugWriteLine( " telop.ImageSize=" + telop.ImageSize ); + Common.DebugWriteLine( " m_editing.Bounds=" + m_editing.Bounds ); +#endif + if ( AppManager.IsInRectangle( e.Location, m_editing.Bounds ) ) { + ZorderItem zi = new ZorderItem( telop.Text, ZorderItemType.telop, telop.ID ); + property.Editing = (ZorderItem)zi.Clone(); + if ( !telop.PositionFixed ) { + m_editing_item = zi; + m_init_position = Common.PointFromPointF( telop.Position ); + m_base_point = ICoordFromC( e.Location ); + } + return; + } + } + } + + bool found = false; + for ( int i = AppManager.SaveData.m_zorder.Count - 1; i >= 0; i-- ) { + #region s.m_zorderを検索 + ZorderItem item = AppManager.SaveData.m_zorder[i]; + switch ( item.Type ) { + case ZorderItemType.another: + for ( int entry = 0; entry < AppManager.SaveData.m_group_another[item.Index].Count; entry++ ) { + TimeTable table = AppManager.SaveData.m_group_another[item.Index]; + if ( table[entry].begin <= now && now <= table[entry].end ) { + if ( table.IsAviMode || + (!table.IsAviMode && table.Image != null) ) { + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table.GetPosition( now ) ), + table.ImageSize ), + Math.Abs( table.GetScale( now ) ) ), + table.PositionFixed, + table.IsXFixedAt( now ), + table.IsYFixedAt( now ) ); + if ( AppManager.IsInRectangle( e.Location, m_editing.Bounds ) ) { + if ( !table.PositionFixed ) { + m_editing_item = item; + m_init_position = Common.PointFromPointF( table.Position ); + } + property.Editing = (ZorderItem)item.Clone(); + found = true; + break; + } + } + m_editing = new EditingBounds(); + } else { + break; + } + } + break; + case ZorderItemType.character: + TimeTableGroup table_group = AppManager.SaveData.m_groups_character[item.Index]; + string[] spl = table_group.GetDrawObjectNames( now ); + if ( spl.Length > 0 ) { + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table_group.GetPosition( now ) ), + table_group.Character.Size ), + Math.Abs( table_group.GetScale( now ) ) ), + table_group.PositionFixed, + table_group.IsXFixedAt( now ), + table_group.IsYFixedAt( now ) ); + if ( AppManager.IsInRectangle( e.Location, m_editing.Bounds ) ) { + if ( !table_group.PositionFixed ) { + m_editing_item = item; + m_init_position = Common.PointFromPointF( table_group.GetPosition( now ) ); + } + property.Editing = (ZorderItem)item.Clone(); + found = true; + break; + } + m_editing = new EditingBounds(); + } + break; + } + #endregion + if ( found ) { + m_base_point = ICoordFromC( e.Location ); + break; + } + } + + if ( !found ) { + m_editing = new EditingBounds(); + if ( m_text_edit && m_text != null ) { + int id = m_text_id; + Telop item = (Telop)AppManager.SaveData[id].Clone(); + item.Text = m_text.Text; + Command run = Command.GCommandEditTelop( id, item ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + m_text.Dispose(); + m_text = null; + } + m_text_edit = false; + m_editing_item = null; + } + this.Invalidate(); + } + + private void previewer_PreviewMouseMove( object sender, MouseEventArgs e ) { + if ( m_editing_item != null ) { +#if DEBUG + Common.DebugWriteLine( "PreviewP_MouseMove" ); +#endif + float now = Now; + Point iCurrent = ICoordFromC( e.Location ); + int index = m_editing_item.Index; + + Point new_point = new Point( m_init_position.X + (iCurrent.X - m_base_point.X), + m_init_position.Y + (iCurrent.Y - m_base_point.Y) ); + switch ( m_editing_item.Type ) { + case ZorderItemType.telop: + if ( !m_text_edit ) { + Telop telop = AppManager.SaveData[index]; + telop.Position = new_point; + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( telop.GetPosition( now ) ), + Common.SizeFromSizeF( telop.ImageSize ) ), + telop.GetScale( now ) ), + telop.PositionFixed, + telop.IsXFixedAt( now ), + telop.IsYFixedAt( now ) ); + } + break; + case ZorderItemType.another: + TimeTable table = AppManager.SaveData.m_group_another[index]; + table.Position = new_point; + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table.GetPosition( now ) ), + Common.SizeFromSizeF( table.ImageSize ) ), + Math.Abs( table.GetScale( now ) ) ), + table.PositionFixed, + table.IsXFixedAt( now ), + table.IsYFixedAt( now ) ); + break; + case ZorderItemType.character: +#if DEBUG + Common.DebugWriteLine( " new_point=" + new_point ); +#endif + TimeTableGroup table_group = AppManager.SaveData.m_groups_character[index]; + table_group.Position = new_point; + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table_group.GetPosition( now ) ), + Common.SizeFromSizeF( table_group.Character.Size ) ), + Math.Abs( table_group.GetScale( now ) ) ), + table_group.PositionFixed, + table_group.IsXFixedAt( now ), + table_group.IsYFixedAt( now ) ); + break; + } + previewer.Invalidate(); + } + } + + private void previewer_PreviewMouseUp( object sender, MouseEventArgs e ) { + timerScreenUpdater.Enabled = false; +#if DEBUG + Common.DebugWriteLine( "PreviewP_MouseUp" ); +#endif + if ( m_editing_item != null ) { + bool found = false; + int index = m_editing_item.Index; + Point new_pos; + switch ( m_editing_item.Type ) { + case ZorderItemType.telop: + new_pos = AppManager.SaveData[index].Position; + if ( new_pos.X != m_init_position.X || new_pos.Y != m_init_position.Y ) { + Command run = Command.GCommandEditTelop( index, AppManager.SaveData[index] ); + AppManager.SaveData[index].Position = m_init_position; + AppManager.Register( AppManager.SaveData.Execute( run ) ); + property.Editing = new ZorderItem( "", ZorderItemType.telop, index ); + AppManager.Edited = true; + } + found = true; + break; + case ZorderItemType.another: + new_pos = AppManager.SaveData.m_group_another[index].Position; + if ( new_pos.X != m_init_position.X || new_pos.Y != m_init_position.Y ) { + Command run = Command.GCommandSetPosition( TimeTableType.another, -1, index, AppManager.SaveData.m_group_another[index].Position ); + AppManager.SaveData.m_group_another[index].Position = m_init_position; + AppManager.Register( AppManager.SaveData.Execute( run ) ); + property.Editing = new ZorderItem( "", ZorderItemType.another, index ); + AppManager.Edited = true; + } else { + AppManager.SaveData.m_group_another[index].Position = m_init_position; + } + found = true; + break; + case ZorderItemType.character: + new_pos = AppManager.SaveData.m_groups_character[index].Position; +#if DEBUG + Common.DebugWriteLine( " new_pos=" + new_pos.ToString() ); + Common.DebugWriteLine( " m_init_position=" + m_init_position ); + Common.DebugWriteLine( " AppManager.SaveData.m_groups_character[index].Position=" + AppManager.SaveData.m_groups_character[index].Position ); +#endif + if ( new_pos.X != m_init_position.X || new_pos.Y != m_init_position.Y ) { + Command run = Command.GCommandSetPosition( TimeTableType.character, index, -1, AppManager.SaveData.m_groups_character[index].Position ); + AppManager.SaveData.m_groups_character[index].Position = m_init_position; + AppManager.Register( AppManager.SaveData.Execute( run ) ); + property.Editing = new ZorderItem( "", ZorderItemType.character, index ); + AppManager.Edited = true; + } else { + AppManager.SaveData.m_groups_character[index].Position = m_init_position; + } + found = true; + break; + } + + if ( found ) { + m_editing_item = null; + this.Invalidate(); + return; + } + } + } + + private void previewer_PreviewMouseDoubleClick( object sender, MouseEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "PreviewP_MouseDoubleClick" ); +#endif + if ( m_editing_item != null ) { + if ( m_editing_item.Type == ZorderItemType.telop ) { + Telop item = AppManager.SaveData[m_editing_item.Index]; + m_text_edit = true; + m_text = new TextBox(); + m_text.Visible = false; + m_text.Text = item.Text; + m_text_original = item.Text; + m_text_id = m_editing_item.Index; + Rectangle rc_telop = new Rectangle( Common.PointFromPointF( item.Position ), Common.SizeFromSizeF( item.ImageSize ) ); + float dum_x, dum_y, scale; + GetScaleAndOrigin( out dum_x, out dum_y, out scale ); + Rectangle rc_text = CRectFromIRect( rc_telop, scale ); + m_text.Parent = previewer.Preview; + m_text.Location = new Point( (int)(rc_text.Left + 1 * scale), (int)(rc_text.Top - 3 * scale) ); + m_text.Font = new Font( item.Font.FontFamily, item.Font.Size * scale, item.Font.Style ); + m_text.Multiline = true; + m_text.Size = m_text.PreferredSize; + m_text.Tag = m_text.Size.Width; + m_text.ImeMode = ImeMode.NoControl; + m_text.TextChanged += new EventHandler( m_text_TextChanged ); + m_text.Show(); + m_text.BringToFront(); + m_text.Visible = true; + m_text.Focus(); + } + } + } + + private void previewer_PreviewSizeChanged( object sender, EventArgs e ) { + UpdateEditHandle(); + } + + private void previewer_PreviewPaint( object sender, PaintEventArgs e ) { + if ( !m_avi_writing ) { + using ( Graphics g = Graphics.FromImage( previewer.Image ) ) { + string mouth = ""; + if ( menuEditRealTime.Checked ) { + if ( m_last_key == Keys.A ) { + mouth = "a"; + } else if ( m_last_key == Keys.I ) { + mouth = "i"; + } else if ( m_last_key == Keys.U ) { + mouth = "u"; + } else if ( m_last_key == Keys.E ) { + mouth = "e"; + } else if ( m_last_key == Keys.O ) { + mouth = "o"; + } + } + AppManager.SaveData.DrawTo( g, AppManager.SaveData.m_movieSize, Now, false, mouth, m_realtime_group ); + } + bool pos_fixed = m_editing.Fixed || (m_editing.XFixed && m_editing.YFixed); + if ( pos_fixed ) { + e.Graphics.DrawRectangle( _PEN_FIXED_BOUNDS, m_editing.Bounds ); + } else { + int x = m_editing.Bounds.X; + int y = m_editing.Bounds.Y; + int width = m_editing.Bounds.Width; + int height = m_editing.Bounds.Height; + int pen_width = (int)(_PEN_FIXED_BOUNDS.Width / 2f); +#if DEBUG + //Common.DebugWriteLine( "previewer_PreviewPaint" ); + //Common.DebugWriteLine( " m_editing.XFixed=" + m_editing.XFixed ); + //Common.DebugWriteLine( " m_Editing.YFixed=" + m_editing.YFixed ); +#endif + if ( m_editing.XFixed ) { + e.Graphics.DrawLine( _PEN_FIXED_BOUNDS, + new Point( x, y - pen_width ), + new Point( x, y + height + pen_width ) ); + e.Graphics.DrawLine( _PEN_FIXED_BOUNDS, + new Point( x + width, y - pen_width ), + new Point( x + width, y + height + pen_width ) ); + e.Graphics.DrawLine( _PEN_BOUNDS, + new Point( x + pen_width, y ), + new Point( x - pen_width + width, y ) ); + e.Graphics.DrawLine( _PEN_BOUNDS, + new Point( x + pen_width, y + height ), + new Point( x - pen_width + width, y + height ) ); + } else if ( m_editing.YFixed ){ + e.Graphics.DrawLine( _PEN_BOUNDS, + new Point( x, y + pen_width ), + new Point( x, y - pen_width + height ) ); + e.Graphics.DrawLine( _PEN_BOUNDS, + new Point( x + width, y + pen_width ), + new Point( x + width, y - pen_width + height ) ); + e.Graphics.DrawLine( _PEN_FIXED_BOUNDS, + new Point( x - pen_width, y ), + new Point( x + pen_width + width, y ) ); + e.Graphics.DrawLine( _PEN_FIXED_BOUNDS, + new Point( x - pen_width, y + height ), + new Point( x + pen_width + width, y + height ) ); + } else { + e.Graphics.DrawRectangle( _PEN_BOUNDS, m_editing.Bounds ); + } + } + } + } + #endregion + + private void previewer_TrackBarScroll( object sender, EventArgs e ) { + if ( menuVisualSync.Checked ) { + correctPosition(); + } + this.Invalidate(); + } + + /// + /// + /// + /// + /// + private void previewer_MenuHundredClick( object sender, EventArgs e ) { + previewer.PreviewSizeMode = PictureBoxSizeMode.CenterImage; + AppManager.Config.PreviewZoomMode = previewer.PreviewSizeMode; + } + + private void previewer_MenuFitClick( object sender, EventArgs e ) { + previewer.PreviewSizeMode = PictureBoxSizeMode.Zoom; + AppManager.Config.PreviewZoomMode = previewer.PreviewSizeMode; + } + + private void previewer_LabelTimeMouseDoubleClick( object sender, EventArgs e ) { + PreviewWindowFlipMode(); + } + + private void m_container_Panel2_SizeChanged( object sender, EventArgs e ) { + ResizePanel2(); + } + + #region bgWorkSeriesImage + private void bgWorkSeriesImage_DoWork( object sender, DoWorkEventArgs e ) { + Size size = AppManager.SaveData.m_movieSize; + m_avi_cancel = false; + + long start_frame; + AviOutputArguments args = (AviOutputArguments)e.Argument; + if ( args.StartSpecified ) { + start_frame = (long)(args.Start * AppManager.SaveData.FrameRate); + } else { + start_frame = 0L; + } + + long end_frame; + if ( args.EndSpecified ) { + end_frame = (long)(args.End * AppManager.SaveData.FrameRate); + } else { + end_frame = (long)((AppManager.SaveData.m_totalSec) * AppManager.SaveData.FrameRate); + } + long total_frames = end_frame - start_frame + 1; +#if !DEBUG + try { +#endif + long count = -1; + for ( long frame = start_frame; frame <= end_frame; frame++ ) { + count++; + float now = (float)frame / AppManager.SaveData.FrameRate; + Bitmap frm = GetPicture( now, false ); + try { + string file = Path.Combine( args.AviFile, string.Format( args.FileNameParser, count ) ); + frm.Save( file, args.ImageFormat ); + } catch ( Exception ex ) { +#if DEBUG + Common.LogPush( ex ); +#endif + this.Invoke( new Form1_AviWritingChange( ChangeAviWriting ), new object[] { false } ); + return; + } + bgWorkSeriesImage.ReportProgress( (int)((double)(frame - start_frame) / (double)(total_frames) * 100.0), new long[] { frame - start_frame, total_frames } ); + if ( m_avi_cancel ) { + m_avi_cancel = false; + return; + } + } +#if !DEBUG + } catch { + } +#endif + } + + private void bgWorkSeriesImage_ProgressChanged( object sender, ProgressChangedEventArgs e ) { + long[] stat = (long[])e.UserState; + this.Text = _( "Series Image Progress" ) + " " + e.ProgressPercentage + "% [" + stat[0] + "/" + stat[1] + "]"; + } + + private void bgWorkSeriesImage_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e ) { + this.Invoke( new Form1_AviWritingChange( ChangeAviWriting ), new object[] { false } ); + m_avi_cancel = false; + UpdateFormTitle(); + } + #endregion + + private void timerScreenUpdater_Tick( object sender, EventArgs e ) { + previewer.Invalidate(); + } + + private void menuVisualVsqTrack_CheckedChanged( object sender, EventArgs e ) { + AppManager.Config.FixVsqTrackPosition = menuVisualVsqTrack.Checked; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Form1.designer.cs b/trunk/LipSync/LipSync/Editor/Form1.designer.cs new file mode 100644 index 0000000..356eae6 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Form1.designer.cs @@ -0,0 +1,1294 @@ +/* + * Form1.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using Boare.Lib.AppUtil; + +namespace LipSync { + + partial class Form1 { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.preview_image = new System.Windows.Forms.PictureBox(); + this.pictureBox2 = new System.Windows.Forms.PictureBox(); + this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); + this.hScrollBar1 = new System.Windows.Forms.HScrollBar(); + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.side = new System.Windows.Forms.PictureBox(); + this.openVsqDialog = new System.Windows.Forms.OpenFileDialog(); + this.dialogImage = new System.Windows.Forms.OpenFileDialog(); + this.cmenu = new System.Windows.Forms.ContextMenuStrip( this.components ); + this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); + this.openLse = new System.Windows.Forms.OpenFileDialog(); + this.statusStrip1 = new System.Windows.Forms.StatusStrip(); + this.statusLabel = new System.Windows.Forms.ToolStripStatusLabel(); + this.statusTime = new System.Windows.Forms.ToolStripStatusLabel(); + this.statusComment = new System.Windows.Forms.ToolStripStatusLabel(); + this.openRseDialog = new System.Windows.Forms.OpenFileDialog(); + this.saveAviFile = new System.Windows.Forms.SaveFileDialog(); + this.bgWorkAvi = new System.ComponentModel.BackgroundWorker(); + this.colorDialog1 = new System.Windows.Forms.ColorDialog(); + this.openMusicDialog = new System.Windows.Forms.OpenFileDialog(); + this.cmenuRepeat = new System.Windows.Forms.ContextMenuStrip( this.components ); + this.cmenuRepeatStart = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRepeatEnd = new System.Windows.Forms.ToolStripMenuItem(); + this.cmenuRepeatReset = new System.Windows.Forms.ToolStripMenuItem(); + this.menuStrip2 = new System.Windows.Forms.MenuStrip(); + this.xmenuFile = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileOpen = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileClose = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator(); + this.xmenuFileSave = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileSaveAs = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileImport = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileImportRipsync = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileExport = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileExportHatwune = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileExportVocaloMark = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripSeparator(); + this.xmenuFileOpenVsq = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileOutputAvi = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileOutputRawAvi = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileSeriesBitmap = new System.Windows.Forms.ToolStripMenuItem(); + this.xmenuFileOutputAbort = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripSeparator(); + this.xmenuFileExit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditUndo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditRedo = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuEditVideoSize = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditFrameRate = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditZOrder = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditVideoLength = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditShiftTimeline = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripSeparator(); + this.menuEditAddCharacter = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditBGColor = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditRealTime = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisual = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualZoomIn = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualZoomOut = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualZoomReset = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualTop = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualEnd = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator(); + this.menuVisualPlayPause = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualRepeat = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualRepeatPlayPause = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualRepeatTop = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualRepeatEnd = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripSeparator(); + this.menuVisualPreview = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualPreviewFlipVisible = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualPreviewSeparate = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualSync = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualObjectList = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripSeparator(); + this.menuVisualTransform = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualVsqTrack = new System.Windows.Forms.ToolStripMenuItem(); + this.menuVisualBars = new System.Windows.Forms.ToolStripMenuItem(); + this.menuTool = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolOption = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolMusic = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolMoveTo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize04 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize08 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize16 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize32 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantize64 = new System.Windows.Forms.ToolStripMenuItem(); + this.menuToolQuantizeOff = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); + this.menuToolQuantizeTriplet = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); + this.menuToolPluginConfig = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelp = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpPluginInfo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpVersionInfo = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpBugReport = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpDebug = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpDebugEditCharacter = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpDebugInverseImages = new System.Windows.Forms.ToolStripMenuItem(); + this.menuHelpDebugExtract = new System.Windows.Forms.ToolStripMenuItem(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer(); + this.previewer = new LipSync.Previewer(); + this.property = new LipSync.Property(); + this.m_container = new Boare.Lib.AppUtil.BSplitContainer(); + this.bgWorkSeriesImage = new System.ComponentModel.BackgroundWorker(); + this.timerScreenUpdater = new System.Windows.Forms.Timer( this.components ); + ((System.ComponentModel.ISupportInitialize)(this.preview_image)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.side)).BeginInit(); + this.statusStrip1.SuspendLayout(); + this.cmenuRepeat.SuspendLayout(); + this.menuStrip2.SuspendLayout(); + this.toolStripContainer1.BottomToolStripPanel.SuspendLayout(); + this.toolStripContainer1.ContentPanel.SuspendLayout(); + this.toolStripContainer1.TopToolStripPanel.SuspendLayout(); + this.toolStripContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // preview_image + // + this.preview_image.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.preview_image.Location = new System.Drawing.Point( 114, 17 ); + this.preview_image.Name = "preview_image"; + this.preview_image.Size = new System.Drawing.Size( 196, 138 ); + this.preview_image.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage; + this.preview_image.TabIndex = 7; + this.preview_image.TabStop = false; + this.preview_image.Visible = false; + this.preview_image.MouseLeave += new System.EventHandler( this.preview_image_MouseLeave ); + // + // pictureBox2 + // + this.pictureBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox2.Location = new System.Drawing.Point( 428, 241 ); + this.pictureBox2.MaximumSize = new System.Drawing.Size( 16, 16 ); + this.pictureBox2.MinimumSize = new System.Drawing.Size( 16, 16 ); + this.pictureBox2.Name = "pictureBox2"; + this.pictureBox2.Size = new System.Drawing.Size( 16, 16 ); + this.pictureBox2.TabIndex = 18; + this.pictureBox2.TabStop = false; + // + // vScrollBar1 + // + this.vScrollBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Right))); + this.vScrollBar1.Enabled = false; + this.vScrollBar1.Location = new System.Drawing.Point( 428, 0 ); + this.vScrollBar1.Maximum = 200; + this.vScrollBar1.Name = "vScrollBar1"; + this.vScrollBar1.Size = new System.Drawing.Size( 16, 241 ); + this.vScrollBar1.TabIndex = 17; + this.vScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler( this.vScrollBar1_Scroll ); + // + // hScrollBar1 + // + this.hScrollBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.hScrollBar1.Enabled = false; + this.hScrollBar1.Location = new System.Drawing.Point( 19, 241 ); + this.hScrollBar1.Name = "hScrollBar1"; + this.hScrollBar1.Size = new System.Drawing.Size( 409, 16 ); + this.hScrollBar1.TabIndex = 16; + this.hScrollBar1.Scroll += new System.Windows.Forms.ScrollEventHandler( this.hScrollBar1_Scroll ); + // + // pictureBox1 + // + this.pictureBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.pictureBox1.Location = new System.Drawing.Point( 19, 0 ); + this.pictureBox1.Margin = new System.Windows.Forms.Padding( 0 ); + this.pictureBox1.MinimumSize = new System.Drawing.Size( 100, 100 ); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size( 409, 241 ); + this.pictureBox1.TabIndex = 15; + this.pictureBox1.TabStop = false; + this.pictureBox1.MouseLeave += new System.EventHandler( this.pictureBox1_MouseLeave ); + this.pictureBox1.PreviewKeyDown += new System.Windows.Forms.PreviewKeyDownEventHandler( this.pictureBox1_PreviewKeyDown ); + this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseMove ); + this.pictureBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseDoubleClick ); + this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseClick ); + this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseDown ); + this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler( this.pictureBox1_Paint ); + this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseUp ); + // + // side + // + this.side.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.side.BackColor = System.Drawing.Color.Silver; + this.side.Location = new System.Drawing.Point( 0, 0 ); + this.side.Margin = new System.Windows.Forms.Padding( 0 ); + this.side.Name = "side"; + this.side.Size = new System.Drawing.Size( 19, 257 ); + this.side.TabIndex = 11; + this.side.TabStop = false; + this.side.MouseClick += new System.Windows.Forms.MouseEventHandler( this.side_MouseClick ); + this.side.Paint += new System.Windows.Forms.PaintEventHandler( this.side_Paint ); + // + // openVsqDialog + // + this.openVsqDialog.Filter = "VOCALOID2 Sequence File(*.vsq)|*.vsq|all files(*.*)|*.*"; + // + // dialogImage + // + this.dialogImage.Filter = "Image Files|*.bmp;*.png;*.jpg|All Files|*.*"; + // + // cmenu + // + this.cmenu.Name = "cmenu"; + this.cmenu.ShowImageMargin = false; + this.cmenu.ShowItemToolTips = false; + this.cmenu.Size = new System.Drawing.Size( 36, 4 ); + // + // saveFileDialog1 + // + this.saveFileDialog1.Filter = "Lip Sync(*.lse)|*.lse|all files(*.*)|*.*"; + // + // openLse + // + this.openLse.Filter = "Lip Sync(*.lse)|*.lse|all files(*.*)|*.*"; + // + // statusStrip1 + // + this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None; + this.statusStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.statusLabel, + this.statusTime, + this.statusComment} ); + this.statusStrip1.Location = new System.Drawing.Point( 0, 0 ); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.Size = new System.Drawing.Size( 958, 22 ); + this.statusStrip1.TabIndex = 8; + this.statusStrip1.Text = "statusStrip1"; + // + // statusLabel + // + this.statusLabel.Name = "statusLabel"; + this.statusLabel.Size = new System.Drawing.Size( 0, 17 ); + // + // statusTime + // + this.statusTime.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom))); + this.statusTime.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenOuter; + this.statusTime.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; + this.statusTime.Name = "statusTime"; + this.statusTime.Size = new System.Drawing.Size( 51, 17 ); + this.statusTime.Text = "0.00 sec"; + // + // statusComment + // + this.statusComment.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right) + | System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom))); + this.statusComment.BorderStyle = System.Windows.Forms.Border3DStyle.SunkenOuter; + this.statusComment.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; + this.statusComment.Name = "statusComment"; + this.statusComment.Size = new System.Drawing.Size( 4, 17 ); + // + // openRseDialog + // + this.openRseDialog.Filter = "Rip Sync(*.rsp)|*.rsp|all files(*.*)|*.*"; + // + // saveAviFile + // + this.saveAviFile.Filter = "avi|*.avi"; + // + // bgWorkAvi + // + this.bgWorkAvi.WorkerReportsProgress = true; + this.bgWorkAvi.WorkerSupportsCancellation = true; + this.bgWorkAvi.DoWork += new System.ComponentModel.DoWorkEventHandler( this.bgWorkAvi_DoWork ); + this.bgWorkAvi.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler( this.bgWorkAvi_RunWorkerCompleted ); + this.bgWorkAvi.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler( this.bgWorkAvi_ProgressChanged ); + // + // openMusicDialog + // + this.openMusicDialog.FileName = "openFileDialog1"; + // + // cmenuRepeat + // + this.cmenuRepeat.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.cmenuRepeatStart, + this.cmenuRepeatEnd, + this.cmenuRepeatReset} ); + this.cmenuRepeat.Name = "cmenuRepeat"; + this.cmenuRepeat.ShowImageMargin = false; + this.cmenuRepeat.Size = new System.Drawing.Size( 161, 70 ); + this.cmenuRepeat.Opening += new System.ComponentModel.CancelEventHandler( this.cmenuRepeat_Opening ); + // + // cmenuRepeatStart + // + this.cmenuRepeatStart.Name = "cmenuRepeatStart"; + this.cmenuRepeatStart.Size = new System.Drawing.Size( 160, 22 ); + this.cmenuRepeatStart.Text = "リピート開始位置に指定"; + this.cmenuRepeatStart.Click += new System.EventHandler( this.cmenuRepeatStart_Click ); + // + // cmenuRepeatEnd + // + this.cmenuRepeatEnd.Name = "cmenuRepeatEnd"; + this.cmenuRepeatEnd.Size = new System.Drawing.Size( 160, 22 ); + this.cmenuRepeatEnd.Text = "リピート終了位置に指定"; + this.cmenuRepeatEnd.Click += new System.EventHandler( this.cmenuRepeatEnd_Click ); + // + // cmenuRepeatReset + // + this.cmenuRepeatReset.Name = "cmenuRepeatReset"; + this.cmenuRepeatReset.Size = new System.Drawing.Size( 160, 22 ); + this.cmenuRepeatReset.Text = "リピート範囲をリセット"; + this.cmenuRepeatReset.Click += new System.EventHandler( this.cmenuRepeatReset_Click ); + // + // menuStrip2 + // + this.menuStrip2.Dock = System.Windows.Forms.DockStyle.None; + this.menuStrip2.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.xmenuFile, + this.menuEdit, + this.menuVisual, + this.menuTool, + this.menuHelp} ); + this.menuStrip2.Location = new System.Drawing.Point( 0, 0 ); + this.menuStrip2.Name = "menuStrip2"; + this.menuStrip2.Size = new System.Drawing.Size( 958, 24 ); + this.menuStrip2.TabIndex = 12; + this.menuStrip2.Text = "menuStrip2"; + // + // xmenuFile + // + this.xmenuFile.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.xmenuFileOpen, + this.xmenuFileClose, + this.toolStripMenuItem8, + this.xmenuFileSave, + this.xmenuFileSaveAs, + this.xmenuFileImport, + this.xmenuFileExport, + this.toolStripMenuItem9, + this.xmenuFileOpenVsq, + this.xmenuFileOutputAvi, + this.xmenuFileOutputRawAvi, + this.xmenuFileSeriesBitmap, + this.xmenuFileOutputAbort, + this.toolStripMenuItem10, + this.xmenuFileExit} ); + this.xmenuFile.Name = "xmenuFile"; + this.xmenuFile.Size = new System.Drawing.Size( 66, 20 ); + this.xmenuFile.Text = "ファイル(&F)"; + this.xmenuFile.DropDownOpening += new System.EventHandler( this.xmenuFile_DropDownOpening ); + // + // xmenuFileOpen + // + this.xmenuFileOpen.Name = "xmenuFileOpen"; + this.xmenuFileOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O))); + this.xmenuFileOpen.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileOpen.Text = "開く(&O)"; + this.xmenuFileOpen.Click += new System.EventHandler( this.xmenuFileOpen_Click ); + // + // xmenuFileClose + // + this.xmenuFileClose.Name = "xmenuFileClose"; + this.xmenuFileClose.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileClose.Text = "閉じる(&C)"; + this.xmenuFileClose.Click += new System.EventHandler( this.xmenuFileClose_Click ); + // + // toolStripMenuItem8 + // + this.toolStripMenuItem8.Name = "toolStripMenuItem8"; + this.toolStripMenuItem8.Size = new System.Drawing.Size( 155, 6 ); + // + // xmenuFileSave + // + this.xmenuFileSave.Name = "xmenuFileSave"; + this.xmenuFileSave.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S))); + this.xmenuFileSave.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileSave.Text = "保存(&S)"; + this.xmenuFileSave.Click += new System.EventHandler( this.xmenuFileSave_Click ); + // + // xmenuFileSaveAs + // + this.xmenuFileSaveAs.Name = "xmenuFileSaveAs"; + this.xmenuFileSaveAs.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileSaveAs.Text = "別名で保存(&A)"; + this.xmenuFileSaveAs.Click += new System.EventHandler( this.xmenuFileSaveAs_Click ); + // + // xmenuFileImport + // + this.xmenuFileImport.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.xmenuFileImportRipsync} ); + this.xmenuFileImport.Name = "xmenuFileImport"; + this.xmenuFileImport.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileImport.Text = "インポート(&I)"; + // + // xmenuFileImportRipsync + // + this.xmenuFileImportRipsync.Name = "xmenuFileImportRipsync"; + this.xmenuFileImportRipsync.Size = new System.Drawing.Size( 140, 22 ); + this.xmenuFileImportRipsync.Text = "RipSyncデータ"; + this.xmenuFileImportRipsync.Click += new System.EventHandler( this.xmenuFileImportRipsync_Click ); + // + // xmenuFileExport + // + this.xmenuFileExport.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.xmenuFileExportHatwune, + this.xmenuFileExportVocaloMark} ); + this.xmenuFileExport.Name = "xmenuFileExport"; + this.xmenuFileExport.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileExport.Text = "エクスポート"; + // + // xmenuFileExportHatwune + // + this.xmenuFileExportHatwune.Name = "xmenuFileExportHatwune"; + this.xmenuFileExportHatwune.Size = new System.Drawing.Size( 200, 22 ); + this.xmenuFileExportHatwune.Text = "はとぅねベンチ用スクリプト"; + this.xmenuFileExportHatwune.Click += new System.EventHandler( this.xmenuFileExportHatwune_Click ); + // + // xmenuFileExportVocaloMark + // + this.xmenuFileExportVocaloMark.Name = "xmenuFileExportVocaloMark"; + this.xmenuFileExportVocaloMark.Size = new System.Drawing.Size( 200, 22 ); + this.xmenuFileExportVocaloMark.Text = "Script for VOCALOMARK"; + this.xmenuFileExportVocaloMark.Click += new System.EventHandler( this.xmenuFileExportVocaloMark_Click ); + // + // toolStripMenuItem9 + // + this.toolStripMenuItem9.Name = "toolStripMenuItem9"; + this.toolStripMenuItem9.Size = new System.Drawing.Size( 155, 6 ); + // + // xmenuFileOpenVsq + // + this.xmenuFileOpenVsq.Name = "xmenuFileOpenVsq"; + this.xmenuFileOpenVsq.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileOpenVsq.Text = "VSQを開く(&O)"; + this.xmenuFileOpenVsq.Click += new System.EventHandler( this.xmenuFileOpenVsq_Click ); + // + // xmenuFileOutputAvi + // + this.xmenuFileOutputAvi.Name = "xmenuFileOutputAvi"; + this.xmenuFileOutputAvi.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileOutputAvi.Text = "AVI出力(&S)"; + this.xmenuFileOutputAvi.Click += new System.EventHandler( this.menuFileOutputAvi_Click ); + // + // xmenuFileOutputRawAvi + // + this.xmenuFileOutputRawAvi.Name = "xmenuFileOutputRawAvi"; + this.xmenuFileOutputRawAvi.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileOutputRawAvi.Text = "無圧縮AVIを出力"; + this.xmenuFileOutputRawAvi.Click += new System.EventHandler( this.menuFileOutputRawAvi_Click ); + // + // xmenuFileSeriesBitmap + // + this.xmenuFileSeriesBitmap.Name = "xmenuFileSeriesBitmap"; + this.xmenuFileSeriesBitmap.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileSeriesBitmap.Text = "連番ビットマップ"; + this.xmenuFileSeriesBitmap.Click += new System.EventHandler( this.xmenuFileSeriesBitmap_Click ); + // + // xmenuFileOutputAbort + // + this.xmenuFileOutputAbort.Enabled = false; + this.xmenuFileOutputAbort.Name = "xmenuFileOutputAbort"; + this.xmenuFileOutputAbort.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileOutputAbort.Text = "出力の中断(&E)"; + this.xmenuFileOutputAbort.Click += new System.EventHandler( this.xmenuFileOutputAbort_Click ); + // + // toolStripMenuItem10 + // + this.toolStripMenuItem10.Name = "toolStripMenuItem10"; + this.toolStripMenuItem10.Size = new System.Drawing.Size( 155, 6 ); + // + // xmenuFileExit + // + this.xmenuFileExit.Name = "xmenuFileExit"; + this.xmenuFileExit.Size = new System.Drawing.Size( 158, 22 ); + this.xmenuFileExit.Text = "終了(&X)"; + this.xmenuFileExit.Click += new System.EventHandler( this.xmenuFileExit_Click ); + // + // menuEdit + // + this.menuEdit.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuEditUndo, + this.menuEditRedo, + this.toolStripMenuItem1, + this.menuEditVideoSize, + this.menuEditFrameRate, + this.menuEditZOrder, + this.menuEditVideoLength, + this.menuEditShiftTimeline, + this.toolStripMenuItem11, + this.menuEditAddCharacter, + this.menuEditBGColor, + this.menuEditRealTime} ); + this.menuEdit.Name = "menuEdit"; + this.menuEdit.Size = new System.Drawing.Size( 56, 20 ); + this.menuEdit.Text = "編集(&E)"; + this.menuEdit.DropDownOpening += new System.EventHandler( this.menuEdit_DropDownOpening ); + // + // menuEditUndo + // + this.menuEditUndo.Enabled = false; + this.menuEditUndo.Name = "menuEditUndo"; + this.menuEditUndo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z))); + this.menuEditUndo.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditUndo.Text = "元に戻す(&U)"; + this.menuEditUndo.Click += new System.EventHandler( this.menuEditUndo_Click ); + // + // menuEditRedo + // + this.menuEditRedo.Enabled = false; + this.menuEditRedo.Name = "menuEditRedo"; + this.menuEditRedo.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.Z))); + this.menuEditRedo.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditRedo.Text = "やり直し(&R)"; + this.menuEditRedo.Click += new System.EventHandler( this.menuEditRedo_Click ); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size( 189, 6 ); + // + // menuEditVideoSize + // + this.menuEditVideoSize.Name = "menuEditVideoSize"; + this.menuEditVideoSize.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditVideoSize.Text = "ビデオサイズ(&V)"; + this.menuEditVideoSize.Click += new System.EventHandler( this.menuEditVideoSize_Click ); + // + // menuEditFrameRate + // + this.menuEditFrameRate.Name = "menuEditFrameRate"; + this.menuEditFrameRate.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditFrameRate.Text = "フレームレート(&F)"; + this.menuEditFrameRate.Click += new System.EventHandler( this.menuEditFrameRate_Click ); + // + // menuEditZOrder + // + this.menuEditZOrder.Name = "menuEditZOrder"; + this.menuEditZOrder.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditZOrder.Text = "描画順序(&Z)"; + this.menuEditZOrder.Click += new System.EventHandler( this.menuEditZOrder_Click ); + // + // menuEditVideoLength + // + this.menuEditVideoLength.Name = "menuEditVideoLength"; + this.menuEditVideoLength.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditVideoLength.Text = "ビデオの長さを変更(&C)"; + this.menuEditVideoLength.Click += new System.EventHandler( this.menuEditVideoLength_Click ); + // + // menuEditShiftTimeline + // + this.menuEditShiftTimeline.Name = "menuEditShiftTimeline"; + this.menuEditShiftTimeline.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditShiftTimeline.Text = "全タイムラインをシフト(&S)"; + this.menuEditShiftTimeline.Click += new System.EventHandler( this.menuEditShiftTimeline_Click ); + // + // toolStripMenuItem11 + // + this.toolStripMenuItem11.Name = "toolStripMenuItem11"; + this.toolStripMenuItem11.Size = new System.Drawing.Size( 189, 6 ); + // + // menuEditAddCharacter + // + this.menuEditAddCharacter.Name = "menuEditAddCharacter"; + this.menuEditAddCharacter.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditAddCharacter.Text = "空のキャラクタを追加(&A)"; + this.menuEditAddCharacter.Click += new System.EventHandler( this.menuEditAddCharacter_Click ); + // + // menuEditBGColor + // + this.menuEditBGColor.Name = "menuEditBGColor"; + this.menuEditBGColor.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditBGColor.Text = "背景色(&B)"; + this.menuEditBGColor.Click += new System.EventHandler( this.menuEditBGColor_Click ); + // + // menuEditRealTime + // + this.menuEditRealTime.CheckOnClick = true; + this.menuEditRealTime.Name = "menuEditRealTime"; + this.menuEditRealTime.ShortcutKeys = System.Windows.Forms.Keys.F4; + this.menuEditRealTime.Size = new System.Drawing.Size( 192, 22 ); + this.menuEditRealTime.Text = "リアルタイム打ち込み"; + this.menuEditRealTime.Click += new System.EventHandler( this.menuEditRealTime_Click ); + // + // menuVisual + // + this.menuVisual.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuVisualZoomIn, + this.menuVisualZoomOut, + this.menuVisualZoomReset, + this.menuVisualTop, + this.menuVisualEnd, + this.toolStripMenuItem6, + this.menuVisualPlayPause, + this.menuVisualRepeat, + this.toolStripMenuItem12, + this.menuVisualPreview, + this.menuVisualSync, + this.menuVisualObjectList, + this.toolStripMenuItem13, + this.menuVisualTransform, + this.menuVisualVsqTrack, + this.menuVisualBars} ); + this.menuVisual.Name = "menuVisual"; + this.menuVisual.Size = new System.Drawing.Size( 57, 20 ); + this.menuVisual.Text = "表示(&V)"; + // + // menuVisualZoomIn + // + this.menuVisualZoomIn.Name = "menuVisualZoomIn"; + this.menuVisualZoomIn.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Up))); + this.menuVisualZoomIn.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualZoomIn.Text = "拡大(&I)"; + this.menuVisualZoomIn.Click += new System.EventHandler( this.menuVisualZoomIn_Click ); + // + // menuVisualZoomOut + // + this.menuVisualZoomOut.Name = "menuVisualZoomOut"; + this.menuVisualZoomOut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Down))); + this.menuVisualZoomOut.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualZoomOut.Text = "縮小(&O)"; + this.menuVisualZoomOut.Click += new System.EventHandler( this.menuVisualZoomOut_Click ); + // + // menuVisualZoomReset + // + this.menuVisualZoomReset.Name = "menuVisualZoomReset"; + this.menuVisualZoomReset.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualZoomReset.Text = "元の倍率(&R)"; + this.menuVisualZoomReset.Click += new System.EventHandler( this.menuVisualZoomReset_Click ); + // + // menuVisualTop + // + this.menuVisualTop.Name = "menuVisualTop"; + this.menuVisualTop.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Home))); + this.menuVisualTop.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualTop.Text = "先頭へ"; + this.menuVisualTop.Click += new System.EventHandler( this.menuVisualTop_Click ); + // + // menuVisualEnd + // + this.menuVisualEnd.Name = "menuVisualEnd"; + this.menuVisualEnd.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.End))); + this.menuVisualEnd.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualEnd.Text = "最後へ"; + this.menuVisualEnd.Click += new System.EventHandler( this.menuVisualEnd_Click ); + // + // toolStripMenuItem6 + // + this.toolStripMenuItem6.Name = "toolStripMenuItem6"; + this.toolStripMenuItem6.Size = new System.Drawing.Size( 205, 6 ); + // + // menuVisualPlayPause + // + this.menuVisualPlayPause.Name = "menuVisualPlayPause"; + this.menuVisualPlayPause.ShortcutKeys = System.Windows.Forms.Keys.F5; + this.menuVisualPlayPause.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualPlayPause.Text = "再生/一時停止"; + this.menuVisualPlayPause.Click += new System.EventHandler( this.menuVisualPlayPause_Click ); + // + // menuVisualRepeat + // + this.menuVisualRepeat.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuVisualRepeatPlayPause, + this.menuVisualRepeatTop, + this.menuVisualRepeatEnd} ); + this.menuVisualRepeat.Name = "menuVisualRepeat"; + this.menuVisualRepeat.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualRepeat.Text = "リピート再生"; + // + // menuVisualRepeatPlayPause + // + this.menuVisualRepeatPlayPause.Name = "menuVisualRepeatPlayPause"; + this.menuVisualRepeatPlayPause.ShortcutKeys = System.Windows.Forms.Keys.F3; + this.menuVisualRepeatPlayPause.Size = new System.Drawing.Size( 166, 22 ); + this.menuVisualRepeatPlayPause.Text = "再生/一時停止"; + this.menuVisualRepeatPlayPause.Click += new System.EventHandler( this.menuVisualRepeatPlayPause_Click ); + // + // menuVisualRepeatTop + // + this.menuVisualRepeatTop.Name = "menuVisualRepeatTop"; + this.menuVisualRepeatTop.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Left))); + this.menuVisualRepeatTop.Size = new System.Drawing.Size( 166, 22 ); + this.menuVisualRepeatTop.Text = "先頭へ"; + this.menuVisualRepeatTop.Click += new System.EventHandler( this.menuVisualRepeatTop_Click ); + // + // menuVisualRepeatEnd + // + this.menuVisualRepeatEnd.Name = "menuVisualRepeatEnd"; + this.menuVisualRepeatEnd.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Right))); + this.menuVisualRepeatEnd.Size = new System.Drawing.Size( 166, 22 ); + this.menuVisualRepeatEnd.Text = "最後へ"; + this.menuVisualRepeatEnd.Click += new System.EventHandler( this.menuVisualRepeatEnd_Click ); + // + // toolStripMenuItem12 + // + this.toolStripMenuItem12.Name = "toolStripMenuItem12"; + this.toolStripMenuItem12.Size = new System.Drawing.Size( 205, 6 ); + // + // menuVisualPreview + // + this.menuVisualPreview.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuVisualPreviewFlipVisible, + this.menuVisualPreviewSeparate} ); + this.menuVisualPreview.Name = "menuVisualPreview"; + this.menuVisualPreview.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualPreview.Text = "プレビュー"; + // + // menuVisualPreviewFlipVisible + // + this.menuVisualPreviewFlipVisible.Name = "menuVisualPreviewFlipVisible"; + this.menuVisualPreviewFlipVisible.ShortcutKeys = System.Windows.Forms.Keys.F6; + this.menuVisualPreviewFlipVisible.Size = new System.Drawing.Size( 199, 22 ); + this.menuVisualPreviewFlipVisible.Text = "プレビューを非表示"; + this.menuVisualPreviewFlipVisible.Click += new System.EventHandler( this.menuVisualPreviewFlipVisible_Click ); + // + // menuVisualPreviewSeparate + // + this.menuVisualPreviewSeparate.CheckOnClick = true; + this.menuVisualPreviewSeparate.Name = "menuVisualPreviewSeparate"; + this.menuVisualPreviewSeparate.Size = new System.Drawing.Size( 199, 22 ); + this.menuVisualPreviewSeparate.Text = "プレビューをウィンドウに分離"; + this.menuVisualPreviewSeparate.Click += new System.EventHandler( this.menuVisualPreviewSeparate_Click ); + // + // menuVisualSync + // + this.menuVisualSync.CheckOnClick = true; + this.menuVisualSync.Name = "menuVisualSync"; + this.menuVisualSync.ShortcutKeys = System.Windows.Forms.Keys.F7; + this.menuVisualSync.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualSync.Text = "タイムテーブルとシンクロ"; + // + // menuVisualObjectList + // + this.menuVisualObjectList.Name = "menuVisualObjectList"; + this.menuVisualObjectList.ShortcutKeys = System.Windows.Forms.Keys.F8; + this.menuVisualObjectList.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualObjectList.Text = "オブジェクトリストを非表示"; + this.menuVisualObjectList.Click += new System.EventHandler( this.menuVisualObjectList_Click ); + // + // toolStripMenuItem13 + // + this.toolStripMenuItem13.Name = "toolStripMenuItem13"; + this.toolStripMenuItem13.Size = new System.Drawing.Size( 205, 6 ); + // + // menuVisualTransform + // + this.menuVisualTransform.CheckOnClick = true; + this.menuVisualTransform.Name = "menuVisualTransform"; + this.menuVisualTransform.ShortcutKeys = System.Windows.Forms.Keys.F9; + this.menuVisualTransform.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualTransform.Text = "変位の制御"; + this.menuVisualTransform.CheckedChanged += new System.EventHandler( this.menuVisualTransform_CheckedChanged ); + // + // menuVisualVsqTrack + // + this.menuVisualVsqTrack.CheckOnClick = true; + this.menuVisualVsqTrack.Name = "menuVisualVsqTrack"; + this.menuVisualVsqTrack.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualVsqTrack.Text = "VSQトラックを常に表示"; + this.menuVisualVsqTrack.CheckedChanged += new System.EventHandler( this.menuVisualVsqTrack_CheckedChanged ); + // + // menuVisualBars + // + this.menuVisualBars.CheckOnClick = true; + this.menuVisualBars.Name = "menuVisualBars"; + this.menuVisualBars.Size = new System.Drawing.Size( 208, 22 ); + this.menuVisualBars.Text = "小節の境界を表示"; + // + // menuTool + // + this.menuTool.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuToolOption, + this.menuToolMusic, + this.menuToolMoveTo, + this.menuToolQuantize, + this.toolStripMenuItem2, + this.menuToolPluginConfig} ); + this.menuTool.Name = "menuTool"; + this.menuTool.Size = new System.Drawing.Size( 61, 20 ); + this.menuTool.Text = "ツール(&T)"; + // + // menuToolOption + // + this.menuToolOption.Name = "menuToolOption"; + this.menuToolOption.Size = new System.Drawing.Size( 218, 22 ); + this.menuToolOption.Text = "オプション(&O)"; + this.menuToolOption.Click += new System.EventHandler( this.menuToolOption_Click ); + // + // menuToolMusic + // + this.menuToolMusic.Name = "menuToolMusic"; + this.menuToolMusic.Size = new System.Drawing.Size( 218, 22 ); + this.menuToolMusic.Text = "同時再生する曲(&M)"; + this.menuToolMusic.Click += new System.EventHandler( this.menuToolMusic_Click ); + // + // menuToolMoveTo + // + this.menuToolMoveTo.Name = "menuToolMoveTo"; + this.menuToolMoveTo.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G))); + this.menuToolMoveTo.Size = new System.Drawing.Size( 218, 22 ); + this.menuToolMoveTo.Text = "指定フレームに移動(&G)"; + this.menuToolMoveTo.Click += new System.EventHandler( this.menuToolMoveTo_Click ); + // + // menuToolQuantize + // + this.menuToolQuantize.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuToolQuantize04, + this.menuToolQuantize08, + this.menuToolQuantize16, + this.menuToolQuantize32, + this.menuToolQuantize64, + this.menuToolQuantizeOff, + this.toolStripMenuItem3, + this.menuToolQuantizeTriplet} ); + this.menuToolQuantize.Name = "menuToolQuantize"; + this.menuToolQuantize.Size = new System.Drawing.Size( 218, 22 ); + this.menuToolQuantize.Text = "クォンタイズ(&Q)"; + // + // menuToolQuantize04 + // + this.menuToolQuantize04.Name = "menuToolQuantize04"; + this.menuToolQuantize04.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantize04.Text = "1/4"; + this.menuToolQuantize04.Click += new System.EventHandler( this.menuToolQuantize04_Click ); + // + // menuToolQuantize08 + // + this.menuToolQuantize08.Name = "menuToolQuantize08"; + this.menuToolQuantize08.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantize08.Text = "1/8"; + this.menuToolQuantize08.Click += new System.EventHandler( this.menuToolQuantize08_Click ); + // + // menuToolQuantize16 + // + this.menuToolQuantize16.Name = "menuToolQuantize16"; + this.menuToolQuantize16.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantize16.Text = "1/16"; + this.menuToolQuantize16.Click += new System.EventHandler( this.menuToolQuantize16_Click ); + // + // menuToolQuantize32 + // + this.menuToolQuantize32.Name = "menuToolQuantize32"; + this.menuToolQuantize32.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantize32.Text = "1/32"; + this.menuToolQuantize32.Click += new System.EventHandler( this.menuToolQuantize32_Click ); + // + // menuToolQuantize64 + // + this.menuToolQuantize64.Name = "menuToolQuantize64"; + this.menuToolQuantize64.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantize64.Text = "1/64"; + this.menuToolQuantize64.Click += new System.EventHandler( this.menuToolQuantize64_Click ); + // + // menuToolQuantizeOff + // + this.menuToolQuantizeOff.Checked = true; + this.menuToolQuantizeOff.CheckState = System.Windows.Forms.CheckState.Checked; + this.menuToolQuantizeOff.Name = "menuToolQuantizeOff"; + this.menuToolQuantizeOff.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantizeOff.Text = "オフ"; + this.menuToolQuantizeOff.Click += new System.EventHandler( this.menuToolQuantizeOff_Click ); + // + // toolStripMenuItem3 + // + this.toolStripMenuItem3.Name = "toolStripMenuItem3"; + this.toolStripMenuItem3.Size = new System.Drawing.Size( 97, 6 ); + // + // menuToolQuantizeTriplet + // + this.menuToolQuantizeTriplet.CheckOnClick = true; + this.menuToolQuantizeTriplet.Name = "menuToolQuantizeTriplet"; + this.menuToolQuantizeTriplet.Size = new System.Drawing.Size( 100, 22 ); + this.menuToolQuantizeTriplet.Text = "3連符"; + this.menuToolQuantizeTriplet.CheckedChanged += new System.EventHandler( this.menuToolQuantizeTriplet_CheckedChanged ); + // + // toolStripMenuItem2 + // + this.toolStripMenuItem2.Name = "toolStripMenuItem2"; + this.toolStripMenuItem2.Size = new System.Drawing.Size( 215, 6 ); + // + // menuToolPluginConfig + // + this.menuToolPluginConfig.Name = "menuToolPluginConfig"; + this.menuToolPluginConfig.Size = new System.Drawing.Size( 218, 22 ); + this.menuToolPluginConfig.Text = "プラグイン設定(&G)"; + // + // menuHelp + // + this.menuHelp.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuHelpPluginInfo, + this.menuHelpVersionInfo, + this.menuHelpBugReport, + this.menuHelpDebug} ); + this.menuHelp.Name = "menuHelp"; + this.menuHelp.Size = new System.Drawing.Size( 62, 20 ); + this.menuHelp.Text = "ヘルプ(&H)"; + // + // menuHelpPluginInfo + // + this.menuHelpPluginInfo.Name = "menuHelpPluginInfo"; + this.menuHelpPluginInfo.Size = new System.Drawing.Size( 163, 22 ); + this.menuHelpPluginInfo.Text = "プラグイン情報(&P)"; + // + // menuHelpVersionInfo + // + this.menuHelpVersionInfo.Name = "menuHelpVersionInfo"; + this.menuHelpVersionInfo.Size = new System.Drawing.Size( 163, 22 ); + this.menuHelpVersionInfo.Text = "LipSyncについて(&A)"; + this.menuHelpVersionInfo.Click += new System.EventHandler( this.menuHelpVersionInfo_Click ); + // + // menuHelpBugReport + // + this.menuHelpBugReport.Name = "menuHelpBugReport"; + this.menuHelpBugReport.Size = new System.Drawing.Size( 163, 22 ); + this.menuHelpBugReport.Text = "バグレポート(&B)"; + this.menuHelpBugReport.Click += new System.EventHandler( this.menuHelpBugReport_Click ); + // + // menuHelpDebug + // + this.menuHelpDebug.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuHelpDebugEditCharacter, + this.menuHelpDebugInverseImages, + this.menuHelpDebugExtract} ); + this.menuHelpDebug.Name = "menuHelpDebug"; + this.menuHelpDebug.Size = new System.Drawing.Size( 163, 22 ); + this.menuHelpDebug.Text = "デバッグ"; + this.menuHelpDebug.Visible = false; + // + // menuHelpDebugEditCharacter + // + this.menuHelpDebugEditCharacter.Name = "menuHelpDebugEditCharacter"; + this.menuHelpDebugEditCharacter.ShortcutKeys = ((System.Windows.Forms.Keys)((((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt) + | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.Q))); + this.menuHelpDebugEditCharacter.Size = new System.Drawing.Size( 295, 22 ); + this.menuHelpDebugEditCharacter.Text = "キャラクタを編集"; + this.menuHelpDebugEditCharacter.Click += new System.EventHandler( this.menuHelpDebugEditCharacter_Click ); + // + // menuHelpDebugInverseImages + // + this.menuHelpDebugInverseImages.Name = "menuHelpDebugInverseImages"; + this.menuHelpDebugInverseImages.ShortcutKeys = ((System.Windows.Forms.Keys)((((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt) + | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.W))); + this.menuHelpDebugInverseImages.Size = new System.Drawing.Size( 295, 22 ); + this.menuHelpDebugInverseImages.Text = "その他のイメージを左右反転"; + this.menuHelpDebugInverseImages.Click += new System.EventHandler( this.menuHelpDebugInverseImages_Click ); + // + // menuHelpDebugExtract + // + this.menuHelpDebugExtract.Name = "menuHelpDebugExtract"; + this.menuHelpDebugExtract.ShortcutKeys = ((System.Windows.Forms.Keys)((((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt) + | System.Windows.Forms.Keys.Shift) + | System.Windows.Forms.Keys.E))); + this.menuHelpDebugExtract.Size = new System.Drawing.Size( 295, 22 ); + this.menuHelpDebugExtract.Text = "抽出"; + this.menuHelpDebugExtract.Click += new System.EventHandler( this.menuHelpDebugExtract_Click ); + // + // openFileDialog1 + // + this.openFileDialog1.FileName = "openFileDialog1"; + // + // toolStripContainer1 + // + // + // toolStripContainer1.BottomToolStripPanel + // + this.toolStripContainer1.BottomToolStripPanel.Controls.Add( this.statusStrip1 ); + // + // toolStripContainer1.ContentPanel + // + this.toolStripContainer1.ContentPanel.Controls.Add( this.pictureBox1 ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.hScrollBar1 ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.pictureBox2 ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.side ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.vScrollBar1 ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.previewer ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.preview_image ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.property ); + this.toolStripContainer1.ContentPanel.Controls.Add( this.m_container ); + this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size( 958, 437 ); + this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.toolStripContainer1.Location = new System.Drawing.Point( 1, 1 ); + this.toolStripContainer1.Name = "toolStripContainer1"; + this.toolStripContainer1.Size = new System.Drawing.Size( 958, 483 ); + this.toolStripContainer1.TabIndex = 20; + this.toolStripContainer1.Text = "toolStripContainer1"; + // + // toolStripContainer1.TopToolStripPanel + // + this.toolStripContainer1.TopToolStripPanel.Controls.Add( this.menuStrip2 ); + // + // previewer + // + this.previewer.CheckMuteChecked = false; + this.previewer.Image = null; + this.previewer.LabelSpeedText = "x1.0"; + this.previewer.LabelTimeText = "0.0s"; + this.previewer.Location = new System.Drawing.Point( 0, 0 ); + this.previewer.Name = "previewer"; + this.previewer.PlayPauseEnabled = true; + this.previewer.PlayPauseText = "再生"; + this.previewer.PreviewSizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.previewer.Size = new System.Drawing.Size( 373, 252 ); + this.previewer.TabIndex = 17; + this.previewer.TrackBarEnabled = true; + this.previewer.TrackBarMaximum = 10; + this.previewer.TrackBarMinimum = 0; + this.previewer.TrackBarValue = 0; + this.previewer.TrackSpeedValue = 1000; + this.previewer.TrackVolumeValue = 1000; + this.previewer.TrackBarScroll += new System.EventHandler( this.previewer_TrackBarScroll ); + this.previewer.TrackVolumeScroll += new System.EventHandler( this.previewer_TrackVolumeScroll ); + this.previewer.MenuHundredClick += new System.EventHandler( this.previewer_MenuHundredClick ); + this.previewer.LabelTimeMouseDoubleClick += new System.EventHandler( this.previewer_LabelTimeMouseDoubleClick ); + this.previewer.TrackSpeedScroll += new System.EventHandler( this.previewer_TrackSpeedScroll ); + this.previewer.TrackSpeedMouseUp += new System.Windows.Forms.MouseEventHandler( this.previewer_TrackSpeedMouseUp ); + this.previewer.PreviewSizeChanged += new System.EventHandler( this.previewer_PreviewSizeChanged ); + this.previewer.CheckMuteCheckedChanged += new System.EventHandler( this.previewer_CheckMuteCheckedChanged ); + this.previewer.StopClicked += new System.EventHandler( this.previewer_StopClicked ); + this.previewer.PreviewMouseUp += new System.Windows.Forms.MouseEventHandler( this.previewer_PreviewMouseUp ); + this.previewer.SpeedClicked += new System.EventHandler( this.previewer_SpeedClicked ); + this.previewer.PreviewMouseMove += new System.Windows.Forms.MouseEventHandler( this.previewer_PreviewMouseMove ); + this.previewer.PreviewMouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.previewer_PreviewMouseDoubleClick ); + this.previewer.PreviewPaint += new System.Windows.Forms.PaintEventHandler( this.previewer_PreviewPaint ); + this.previewer.PreviewMouseDown += new System.Windows.Forms.MouseEventHandler( this.previewer_PreviewMouseDown ); + this.previewer.PlayPauseClicked += new System.EventHandler( this.previewer_PlayPauseClicked ); + this.previewer.MenuFitClick += new System.EventHandler( this.previewer_MenuFitClick ); + // + // property1 + // + this.property.Editing = null; + this.property.Location = new System.Drawing.Point( 0, 0 ); + this.property.Name = "property1"; + this.property.SelectedIndex = -1; + this.property.SelectedObject = null; + this.property.Size = new System.Drawing.Size( 174, 436 ); + this.property.TabIndex = 0; + // + // m_container + // + this.m_container.Dock = System.Windows.Forms.DockStyle.Fill; + this.m_container.FixedPanel = System.Windows.Forms.FixedPanel.None; + this.m_container.IsSplitterFixed = false; + this.m_container.Location = new System.Drawing.Point( 0, 0 ); + this.m_container.Name = "m_container"; + this.m_container.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // + // + this.m_container.Panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.m_container.Panel1.BorderColor = System.Drawing.Color.Black; + this.m_container.Panel1.Location = new System.Drawing.Point( 0, 0 ); + this.m_container.Panel1.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 4 ); + this.m_container.Panel1.Name = "m_panel1"; + this.m_container.Panel1.Size = new System.Drawing.Size( 200, 437 ); + this.m_container.Panel1.TabIndex = 0; + this.m_container.Panel1MinSize = 0; + // + // + // + this.m_container.Panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.m_container.Panel2.BorderColor = System.Drawing.Color.Black; + this.m_container.Panel2.Location = new System.Drawing.Point( 204, 0 ); + this.m_container.Panel2.Margin = new System.Windows.Forms.Padding( 0 ); + this.m_container.Panel2.Name = "m_panel2"; + this.m_container.Panel2.Size = new System.Drawing.Size( 754, 437 ); + this.m_container.Panel2.TabIndex = 1; + this.m_container.Panel2.SizeChanged += new System.EventHandler( this.m_container_Panel2_SizeChanged ); + this.m_container.Panel2MinSize = 25; + this.m_container.Size = new System.Drawing.Size( 958, 437 ); + this.m_container.SplitterDistance = 200; + this.m_container.SplitterWidth = 4; + this.m_container.TabIndex = 19; + this.m_container.Text = "splitContainerEx1"; + // + // bgWorkSeriesImage + // + this.bgWorkSeriesImage.WorkerReportsProgress = true; + this.bgWorkSeriesImage.WorkerSupportsCancellation = true; + this.bgWorkSeriesImage.DoWork += new System.ComponentModel.DoWorkEventHandler( this.bgWorkSeriesImage_DoWork ); + this.bgWorkSeriesImage.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler( this.bgWorkSeriesImage_RunWorkerCompleted ); + this.bgWorkSeriesImage.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler( this.bgWorkSeriesImage_ProgressChanged ); + // + // timerScreenUpdater + // + this.timerScreenUpdater.Tick += new System.EventHandler( this.timerScreenUpdater_Tick ); + // + // Form1 + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 960, 485 ); + this.Controls.Add( this.toolStripContainer1 ); + this.MainMenuStrip = this.menuStrip2; + this.Name = "Form1"; + this.Padding = new System.Windows.Forms.Padding( 1 ); + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "LipSync"; + this.Deactivate += new System.EventHandler( this.Form1_Deactivate ); + this.Load += new System.EventHandler( this.Form1_Load ); + this.Paint += new System.Windows.Forms.PaintEventHandler( this.Form1_Paint ); + this.Shown += new System.EventHandler( this.Form1_Shown ); + this.Activated += new System.EventHandler( this.Form1_Activated ); + this.DragDrop += new System.Windows.Forms.DragEventHandler( this.Form1_DragDrop ); + this.DragEnter += new System.Windows.Forms.DragEventHandler( this.Form1_DragEnter ); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler( this.Form1_FormClosing ); + ((System.ComponentModel.ISupportInitialize)(this.preview_image)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox2)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.side)).EndInit(); + this.statusStrip1.ResumeLayout( false ); + this.statusStrip1.PerformLayout(); + this.cmenuRepeat.ResumeLayout( false ); + this.menuStrip2.ResumeLayout( false ); + this.menuStrip2.PerformLayout(); + this.toolStripContainer1.BottomToolStripPanel.ResumeLayout( false ); + this.toolStripContainer1.BottomToolStripPanel.PerformLayout(); + this.toolStripContainer1.ContentPanel.ResumeLayout( false ); + this.toolStripContainer1.TopToolStripPanel.ResumeLayout( false ); + this.toolStripContainer1.TopToolStripPanel.PerformLayout(); + this.toolStripContainer1.ResumeLayout( false ); + this.toolStripContainer1.PerformLayout(); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.OpenFileDialog openVsqDialog; + private System.Windows.Forms.OpenFileDialog dialogImage; + private System.Windows.Forms.PictureBox preview_image; + private System.Windows.Forms.ContextMenuStrip cmenu; + private System.Windows.Forms.SaveFileDialog saveFileDialog1; + private System.Windows.Forms.OpenFileDialog openLse; + private System.Windows.Forms.StatusStrip statusStrip1; + private System.Windows.Forms.ToolStripStatusLabel statusLabel; + private System.Windows.Forms.OpenFileDialog openRseDialog; + private System.Windows.Forms.PictureBox pictureBox2; + private System.Windows.Forms.VScrollBar vScrollBar1; + private System.Windows.Forms.HScrollBar hScrollBar1; + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.PictureBox side; + private System.Windows.Forms.SaveFileDialog saveAviFile; + private System.ComponentModel.BackgroundWorker bgWorkAvi; + private System.Windows.Forms.ColorDialog colorDialog1; + private System.Windows.Forms.ToolStripStatusLabel statusTime; + private System.Windows.Forms.ToolStripStatusLabel statusComment; + public LipSync.Property property; + private System.Windows.Forms.OpenFileDialog openMusicDialog; + private System.Windows.Forms.ContextMenuStrip cmenuRepeat; + private System.Windows.Forms.ToolStripMenuItem cmenuRepeatStart; + private System.Windows.Forms.ToolStripMenuItem cmenuRepeatEnd; + private System.Windows.Forms.ToolStripMenuItem cmenuRepeatReset; + private System.Windows.Forms.MenuStrip menuStrip2; + private System.Windows.Forms.ToolStripMenuItem xmenuFile; + private System.Windows.Forms.ToolStripMenuItem xmenuFileOpen; + private System.Windows.Forms.ToolStripMenuItem xmenuFileClose; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem8; + private System.Windows.Forms.ToolStripMenuItem xmenuFileSave; + private System.Windows.Forms.ToolStripMenuItem xmenuFileSaveAs; + private System.Windows.Forms.ToolStripMenuItem xmenuFileImport; + private System.Windows.Forms.ToolStripMenuItem xmenuFileExport; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem9; + private System.Windows.Forms.ToolStripMenuItem xmenuFileOpenVsq; + private System.Windows.Forms.ToolStripMenuItem xmenuFileOutputAvi; + private System.Windows.Forms.ToolStripMenuItem xmenuFileOutputRawAvi; + private System.Windows.Forms.ToolStripMenuItem xmenuFileOutputAbort; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem10; + private System.Windows.Forms.ToolStripMenuItem xmenuFileExit; + private System.Windows.Forms.ToolStripMenuItem xmenuFileImportRipsync; + private System.Windows.Forms.ToolStripMenuItem xmenuFileExportHatwune; + private System.Windows.Forms.ToolStripMenuItem menuEdit; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem menuEditVideoSize; + private System.Windows.Forms.ToolStripMenuItem menuEditFrameRate; + private System.Windows.Forms.ToolStripMenuItem menuEditZOrder; + private System.Windows.Forms.ToolStripMenuItem menuEditVideoLength; + private System.Windows.Forms.ToolStripMenuItem menuEditShiftTimeline; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11; + private System.Windows.Forms.ToolStripMenuItem menuEditAddCharacter; + private System.Windows.Forms.ToolStripMenuItem menuEditBGColor; + private System.Windows.Forms.ToolStripMenuItem menuEditRealTime; + public System.Windows.Forms.ToolStripMenuItem menuEditUndo; + public System.Windows.Forms.ToolStripMenuItem menuEditRedo; + private System.Windows.Forms.ToolStripMenuItem menuVisual; + private System.Windows.Forms.ToolStripMenuItem menuVisualZoomIn; + private System.Windows.Forms.ToolStripMenuItem menuVisualZoomOut; + private System.Windows.Forms.ToolStripMenuItem menuVisualZoomReset; + private System.Windows.Forms.ToolStripMenuItem menuVisualTop; + private System.Windows.Forms.ToolStripMenuItem menuVisualEnd; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6; + private System.Windows.Forms.ToolStripMenuItem menuVisualPlayPause; + private System.Windows.Forms.ToolStripMenuItem menuVisualRepeat; + private System.Windows.Forms.ToolStripMenuItem menuVisualRepeatPlayPause; + private System.Windows.Forms.ToolStripMenuItem menuVisualRepeatTop; + private System.Windows.Forms.ToolStripMenuItem menuVisualRepeatEnd; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem12; + private System.Windows.Forms.ToolStripMenuItem menuVisualSync; + private System.Windows.Forms.ToolStripMenuItem menuVisualObjectList; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem13; + private System.Windows.Forms.ToolStripMenuItem menuVisualVsqTrack; + private System.Windows.Forms.ToolStripMenuItem menuVisualBars; + public System.Windows.Forms.ToolStripMenuItem menuVisualTransform; + private System.Windows.Forms.ToolStripMenuItem menuTool; + private System.Windows.Forms.ToolStripMenuItem menuToolOption; + private System.Windows.Forms.ToolStripMenuItem menuToolMusic; + private System.Windows.Forms.ToolStripMenuItem menuToolMoveTo; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2; + private System.Windows.Forms.ToolStripMenuItem menuToolPluginConfig; + private System.Windows.Forms.ToolStripMenuItem menuHelp; + private System.Windows.Forms.ToolStripMenuItem menuHelpPluginInfo; + private System.Windows.Forms.ToolStripMenuItem menuHelpVersionInfo; + private System.Windows.Forms.ToolStripMenuItem menuHelpBugReport; + private System.Windows.Forms.ToolStripMenuItem menuHelpDebug; + private System.Windows.Forms.ToolStripMenuItem menuHelpDebugEditCharacter; + private System.Windows.Forms.ToolStripMenuItem menuHelpDebugInverseImages; + private System.Windows.Forms.ToolStripMenuItem menuHelpDebugExtract; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize04; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize08; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize16; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize32; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantize64; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantizeOff; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3; + private System.Windows.Forms.ToolStripMenuItem menuToolQuantizeTriplet; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.ToolStripMenuItem xmenuFileSeriesBitmap; + private Previewer previewer; + private System.Windows.Forms.ToolStripMenuItem menuVisualPreview; + private System.Windows.Forms.ToolStripMenuItem menuVisualPreviewSeparate; + private System.Windows.Forms.ToolStripMenuItem menuVisualPreviewFlipVisible; + private BSplitContainer m_container; + private System.Windows.Forms.ToolStripContainer toolStripContainer1; + private System.ComponentModel.BackgroundWorker bgWorkSeriesImage; + private System.Windows.Forms.Timer timerScreenUpdater; + private System.Windows.Forms.ToolStripMenuItem xmenuFileExportVocaloMark; + + } + +} + diff --git a/trunk/LipSync/LipSync/Editor/Form1Util.cs b/trunk/LipSync/LipSync/Editor/Form1Util.cs new file mode 100644 index 0000000..56e6cd4 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Form1Util.cs @@ -0,0 +1,2228 @@ +/* + * Form1Util.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using System.Threading; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; +using Boare.Lib.Vsq; + +namespace LipSync { + + public partial class Form1 { + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + private void ChangeAviWriting( bool value ) { + AviWriting = value; + } + + private void ResizePanel2() { + if ( m_initialized ) { + side.Height = m_panels.Panel2.Height; + pictureBox1.Width = m_panels.Panel2.Width - side.Width - vScrollBar1.Width; + pictureBox1.Height = m_panels.Panel2.Height - hScrollBar1.Height; + + vScrollBar1.Left = pictureBox1.Left + pictureBox1.Width; + vScrollBar1.Height = pictureBox1.Height; + + hScrollBar1.Top = m_panels.Panel2.Height - hScrollBar1.Height; + hScrollBar1.Width = pictureBox1.Width; + + pictureBox2.Top = pictureBox1.Top + pictureBox1.Height; + pictureBox2.Left = vScrollBar1.Left; + this.Invalidate(); + SetHScrollRange(); + SetVScrollRange(); + m_startToDrawY = StartToDrawY(); + } + } + + private float GetSnapPoint( float time ) { + if ( m_grids != null ) { + if ( m_grids.Length > 0 ) { + float nearest = m_grids[0]; + float dif = Math.Abs( m_grids[0] - time ); + for ( int i = 1; i < m_grids.Length; i++ ) { + float d = Math.Abs( m_grids[i] - time ); + if ( d < dif ) { + dif = d; + nearest = m_grids[i]; + } + } + return nearest; + } + } + return time; + } + + private void PreviewWindowFlipMode() { + if ( previewer.Parent == m_form_preview ) { + previewer.Parent = m_panels.Panel1; + m_form_preview.Hide(); + int total_height = m_panels.Panel1.Height + m_panels.Panel2.Height; + int new_distance = (int)(total_height * AppManager.Config.LastPreviewAspecto); + m_panels.SplitterDistance = new_distance; + m_panels.IsSplitterFixed = false; + menuVisualPreviewSeparate.Checked = false; + } else { + AppManager.Config.LastPreviewAspecto = ((float)m_panels.Panel1.Height) / ((float)(m_panels.Panel2.Height + m_panels.Panel1.Height)); + m_panels.SplitterDistance = 0; + m_panels.IsSplitterFixed = true; + previewer.Parent = m_form_preview; + menuVisualPreviewSeparate.Checked = true; + m_form_preview.Show(); + } + } + + /// + /// 表示言語の設定を適用します。 + /// + public void ApplyLanguage() { + this.xmenuFile.Text = _( "File" ) + "(&F)"; + this.xmenuFileOpen.Text = _( "Open" ) + "(&O)"; + this.xmenuFileSave.Text = _( "Save" ) + "(&S)"; + this.xmenuFileSaveAs.Text = _( "Save As" ) + "(&A)"; + this.xmenuFileImport.Text = _( "Import" ) + "(&I)"; + this.xmenuFileImportRipsync.Text = _( "from RipSync data" ); + this.xmenuFileOpenVsq.Text = _( "Open VSQ/UST file" ) + "(&V)"; + this.xmenuFileExit.Text = _( "Exit" ) + "(&X)"; + this.xmenuFileExportVocaloMark.Text = _( "Script for VOCALOMARK" ); + //this.menuWindow.Text = MessageEx.GetMessage( MessageID.WINDOW ) + "(&W)"; + //this.menuPreview.Text = MessageEx.GetMessage( MessageID.SHOW_PREVIEW ) + "(&P)"; + //this.menuMove.Text = MessageEx.GetMessage( MessageID.GOTO_PREVIEW ) + "(&M)"; + this.menuHelp.Text = _( "Help" ) + "(&H)"; + this.menuHelpPluginInfo.Text = _( "Plugin Information" ) + "(&P)"; + this.menuHelpVersionInfo.Text = _( "About LipSync" ) + "(&A)"; + this.menuHelpDebug.Text = _( "Debug" ); + this.menuHelpDebugEditCharacter.Text = _( "Edit Character" ); + this.menuHelpDebugInverseImages.Text = _( "Flip Images Horizontaly" ); + this.menuEdit.Text = _( "Edit" ) + "(&E)"; + this.menuEditUndo.Text = _( "Undo" ) + "(&U)"; + this.menuEditRedo.Text = _( "Redo" ) + "(&R)"; + this.menuEditVideoSize.Text = _( "Video Size" ) + "(&V)"; + this.menuEditFrameRate.Text = _( "Frame Rate" ) + "(&F)"; + this.menuEditZOrder.Text = _( "Z order" ) + "(&Z)"; + this.menuEditVideoLength.Text = _( "Video Length" ) + "(&C)"; + this.menuEditShiftTimeline.Text = _( "Shift All Time-tables" ) + "(&S)"; + this.menuTool.Text = _( "Tool" ) + "(&T)"; + this.menuToolOption.Text = _( "Option" ) + "(&O)"; + this.menuToolPluginConfig.Text = _( "Plugin Config" ) + "(&P)"; + this.menuEditAddCharacter.Text = _( "Add Empty Character" ) + "(&A)"; + + this.xmenuFileOutputAvi.Text = _( "Generate Avi" ) + "(&G)"; + this.menuToolMusic.Text = _( "Chose Sound File" ) + "(&M)"; + this.menuToolMoveTo.Text = _( "Go to Specified Frame" ) + "(&G)"; + this.xmenuFileOutputAbort.Text = _( "Stop Writing Avi" ) + "(&E)"; + this.menuEditBGColor.Text = _( "Background Color" ) + "(&B)"; + this.xmenuFileClose.Text = _( "Close" ) + "(&C)"; + this.xmenuFileOutputRawAvi.Text = _( "Generate Raw Avi" ) + "(&R)"; + this.xmenuFileExport.Text = _( "Export" ); + this.xmenuFileExportHatwune.Text = _( "Script for H@TWUNEBENCH" ); + if ( AppManager.Config.PropertyHidden ) { + this.menuVisualObjectList.Text = _( "Show Object List" ); + } else { + this.menuVisualObjectList.Text = _( "Hide Object List" ); + } + this.menuHelpBugReport.Text = _( "Bug Report" ) + "(&B)"; + + string draft_filter = _( "VOCALOID2 Sequence File(*.vsq)|*.vsq" ) + "|" + + _( "All Files(*.*)|*.*" ); + if ( Common.CheckFilterValidity( draft_filter ) ){ + this.openVsqDialog.Filter = draft_filter; + } else { + this.openVsqDialog.Filter = "VOCALOID2 Sequence File(*.vsq)|*.vsq|All Files(*.*)|*.*"; + } + + draft_filter = _( "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" ) + "|" + + _( "Avi File(*.avi)|*.avi" ) + "|" + + _( "All Files(*.*)|*.*" ); + if ( Common.CheckFilterValidity( draft_filter ) ){ + this.dialogImage.Filter = draft_filter; + } else { + this.dialogImage.Filter = "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg|Avi File(*.avi)|*.avi|All Files(*.*)|*.*"; + } + + draft_filter = _( "LipSync Data File(*.lse)|*.lse" ) + "|" + + _( "All Files(*.*)|*.*" ); + if ( Common.CheckFilterValidity( draft_filter ) ){ + this.openLse.Filter = draft_filter; + } else { + this.openLse.Filter = "LipSync Data File(*.lse)|*.lse|All Files(*.*)|*.*"; + } + + draft_filter = _( "LipSync Data file(*.lse)|*.lse" ) + "|" + + _( "All Files(*.*)|*.*" ); + if ( Common.CheckFilterValidity( draft_filter ) ){ + this.saveFileDialog1.Filter = draft_filter; + } else { + this.saveFileDialog1.Filter = "LipSync Data file(*.lse)|*.lse|All Files(*.*)|*.*"; + } + //this.menuGenTelop.Text = MessageEx.GetMessage( MessageID.GENERATE_TELOP_FROM_VSQ ) + "(&T)"; + menuEditRealTime.Text = _( "Real Time \"lipsync\"" ); + cmenuRepeatEnd.Text = _( "End Repeat Here" ); + cmenuRepeatStart.Text = _( "Start Repeat Here" ); + cmenuRepeatReset.Text = _( "Reset Repeat region" ); + + #region menuVisual* + menuVisual.Text = _( "View" ) + "(&V)"; + menuVisualZoomIn.Text = _( "Zoom" ) + "(&I)"; + menuVisualZoomOut.Text = _( "Mooz" ) + "(&O)"; + menuVisualZoomReset.Text = _( "Set Default Scale" ) + "(&R)"; + menuVisualTop.Text = _( "Move to Top" ); + menuVisualEnd.Text = _( "Move to End" ); + menuVisualRepeat.Text = _( "Repeat play" ); + menuVisualRepeatEnd.Text = _( "Move to End" ); + menuVisualRepeatTop.Text = _( "Move to Top" ); + menuVisualTransform.Text = _( "Edit Motion Curve" ); + menuVisualRepeatPlayPause.Text = _( "Play" ) + "/" + _( "Pause" ); + menuVisualVsqTrack.Text = _( "Show VSQ Tracks Allways" ); + menuVisualBars.Text = _( "Show Bars" ); + menuVisualPreview.Text = _( "Preview" ) + "(&P)"; + menuVisualPlayPause.Text = _( "Play" ) + "/" + _( "Pause" ); + menuVisualSync.Text = _( "Sync with Time-table" ); + if ( AppManager.Config.PreviewHidden ) { + menuVisualPreviewFlipVisible.Text = _( "Enable Preview" ); + } else { + menuVisualPreviewFlipVisible.Text = _( "Disable Preview" ); + } + menuVisualPreviewSeparate.Text = _( "Separate Preview Window" ) + "(&S)"; + #endregion + + menuToolQuantize.Text = _( "Quantize" ) + "(&Q)"; + menuToolQuantizeOff.Text = _( "Off" ); + menuToolQuantizeTriplet.Text = _( "Triplet" ); + + property.titleUpper.Text = _( "List of Object" ); + property.titleLower.Text = _( "Property" ); + property.ApplyLanguage(); + + if ( AppManager.SaveData.m_plugins != null ) { + foreach ( PluginInfo plugin in AppManager.SaveData.m_plugins ) { + plugin.Instance.ApplyLanguage( AppManager.Config.Language ); + } + } + + if ( m_version_form != null ) { + m_version_form.ApplyLanguage(); + } + xmenuFileSeriesBitmap.Text = _( "Series Image" ) + "(&B)"; + + previewer.ApplyLanguage(); + + if ( m_curve != null ) { + m_curve.ApplyLanguage(); + } + if ( m_version_form != null ) { + m_version_form.ApplyLanguage(); + } + if ( m_form_preview != null ) { + m_form_preview.ApplyLanguage(); + } + } + + private void ReadVsq( string filename ) { + if ( Path.GetExtension( filename ).ToLower() == ".ust" ) { + UstFile ust = new UstFile( filename ); + if ( MessageBox.Show( _( "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" ), + _( "Confirmation" ), MessageBoxButtons.YesNo, + MessageBoxIcon.Exclamation ) == DialogResult.Yes ) { + if ( AppManager.SaveData.m_timesig_ex != null ) { + AppManager.SaveData.m_timesig_ex.Clear(); + AppManager.SaveData.m_timesig_ex = null; + } + if ( AppManager.SaveData.m_tempo != null ) { + AppManager.SaveData.m_tempo.Clear(); + AppManager.SaveData.m_tempo = null; + } + AppManager.SaveData.m_timesig_ex = new List(); + AppManager.SaveData.m_timesig_ex.Add( new TimeSigTableEntry( 0, 4, 4, 0 ) ); + AppManager.SaveData.m_tempo = new List( ust.getTempoList().ToArray() ); + AppManager.SaveData.m_base_tempo = ust.getBaseTempo(); + } + for ( int i = 0; i < ust.getTrackCount(); i++ ) { + AddTimeLineFromUst( ust, i, true ); + } + AppManager.SaveData.m_totalSec = Math.Max( AppManager.SaveData.m_totalSec, (float)ust.getTotalSec() ); + } else { + VsqFile vsqFile = new VsqFile( filename ); + int tracks = vsqFile.getTrackCount(); + string[] track_names = new string[tracks]; + for ( int track = 0; track < tracks; track++ ) { + track_names[track] = vsqFile.getTrack( track ).Name; + } + using ( TrackSelecter selecter = new TrackSelecter( filename, track_names ) ) { + selecter.ImportTempoAndTimesig = false; + if ( selecter.ShowDialog() == DialogResult.OK ) { + foreach ( int i in selecter.CheckedItem ) { + addTimeLineFromTrack( vsqFile, i, true ); + } + if ( selecter.ImportTempoAndTimesig ) { + if ( MessageBox.Show( _( "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" ), + _( "Confirmation" ), MessageBoxButtons.YesNo, + MessageBoxIcon.Exclamation ) == DialogResult.Yes ) { + if ( AppManager.SaveData.m_timesig_ex != null ) { + AppManager.SaveData.m_timesig_ex.Clear(); + AppManager.SaveData.m_timesig_ex = null; + } + if ( AppManager.SaveData.m_tempo != null ) { + AppManager.SaveData.m_tempo.Clear(); + AppManager.SaveData.m_tempo = null; + } + AppManager.SaveData.m_timesig_ex = new List( vsqFile.getTimeSigList().ToArray() ); + AppManager.SaveData.m_tempo = new List( vsqFile.getTempoList().ToArray() ); + AppManager.SaveData.m_base_tempo = vsqFile.getBaseTempo(); + } + } + } + } + + AppManager.SaveData.m_totalSec = Math.Max( AppManager.SaveData.m_totalSec, (float)vsqFile.getTotalSec() ); + + } + SetHScrollRange(); + SetVScrollRange(); + UpdateGridList(); + + AppManager.Edited = true; + this.Invalidate(); + } + + /// + /// + /// + /// + /// + /// + /// + private float nextInterval( ref Random rnd, float base_interval, bool randomize ) { + const float BAND_WIDTH = 0.8f; + if ( randomize ) { + return base_interval - (BAND_WIDTH / 2f) * base_interval + + (float)(rnd.NextDouble()) * base_interval * BAND_WIDTH; + } else { + return base_interval; + } + } + + /// + /// ツールメニューのクオンタイズのチェック状態を,m_quantize_*にあわせて更新します + /// + private void QuantizeMenuCheckedStateUpdate() { + menuToolQuantize04.Checked = false; + menuToolQuantize08.Checked = false; + menuToolQuantize16.Checked = false; + menuToolQuantize32.Checked = false; + menuToolQuantize64.Checked = false; + menuToolQuantizeOff.Checked = false; + switch ( AppManager.Config.QuantizeMode ) { + case QuantizeMode.q04: + menuToolQuantize04.Checked = true; + break; + case QuantizeMode.q08: + menuToolQuantize08.Checked = true; + break; + case QuantizeMode.q16: + menuToolQuantize16.Checked = true; + break; + case QuantizeMode.q32: + menuToolQuantize32.Checked = true; + break; + case QuantizeMode.q64: + menuToolQuantize64.Checked = true; + break; + case QuantizeMode.off: + menuToolQuantizeOff.Checked = true; + break; + } + menuToolQuantizeTriplet.Checked = AppManager.Config.QuantizeTripletEnabled; + UpdateGridList(); + pictureBox1.Refresh(); + } + + private void ChangeSpeed( int speed ) { + if ( AppManager.Playing ) { + m_player.Pause(); + } + float current = m_player.GetPosition() * 0.001f; + m_player.Speed = speed * 0.001f; + m_started_date = DateTime.Now; + m_started_date = m_started_date.AddSeconds( -current / (0.001f * speed) ); + if ( AppManager.Playing ) { + m_player.PlayFrom( current ); + } + float t_speed = speed * 0.001f; + previewer.LabelSpeedText = "x" + t_speed.ToString( "0.00" ); + } + + public bool AviWriting { + get { + return m_avi_writing; + } + set { + m_avi_writing = value; + xmenuFileOutputAvi.Enabled = !value; + previewer.PlayPauseEnabled = !value; + previewer.TrackBarEnabled = !value; + menuEdit.Enabled = !value; + xmenuFileOpen.Enabled = !value; + xmenuFileImportRipsync.Enabled = !value; + xmenuFileOpenVsq.Enabled = !value; + pictureBox1.Enabled = !value; + xmenuFileClose.Enabled = !value; + xmenuFileSeriesBitmap.Enabled = !value; + xmenuFileOutputAbort.Enabled = value; + if ( m_avi_writing ) { + m_player.Close(); + } else { + if ( AppManager.SaveData.m_audioFile != "" ) { + m_player.Load( AppManager.SaveData.m_audioFile ); + } + } + } + } + + private void ChangePropertyHidden() { + float total_width = m_container.Panel1.Width + m_container.Panel2.Width; + if ( AppManager.Config.PropertyHidden ) { + m_container.SplitterDistance = AppManager.Config.LastPropertyWidth; + AppManager.Config.PropertyHidden = false; + menuVisualObjectList.Text = _( "Hide object list" ); + m_container.IsSplitterFixed = false; + } else { + AppManager.Config.LastPropertyWidth = m_container.SplitterDistance; + m_container.SplitterDistance = 0; + AppManager.Config.PropertyHidden = true; + menuVisualObjectList.Text = _( "Show object list" ); + m_container.IsSplitterFixed = true; + } + } + + /// + /// ビットレートを変更したときに呼び出される + /// + private void ChangeBitrate() { + previewer.TrackBarMaximum = (int)(AppManager.SaveData.m_totalSec * AppManager.SaveData.FrameRate); + } + + private void UpdateFormTitle() { + string changed_title; + if ( menuEditRealTime.Checked ) { + changed_title = "[REAL TIME] "; + } else { + changed_title = ""; + } + if ( AppManager.Edited ) { + changed_title += "* "; + } else { + changed_title += ""; + } + if ( m_filePath == "" ) { + changed_title += _( "(no name)" ); + } else { + changed_title += Path.GetFileName( m_filePath ); + } + changed_title += " - LipSync"; + if ( this.Text != changed_title ) { + this.Text = changed_title; + } + } + + /// + /// プレビューの非表示・表示を切り替えます + /// + private void ChangePreviewHidden() { + if ( AppManager.Config.PreviewHidden ) { + int total_height = m_panels.Panel1.Height + m_panels.Panel2.Height; + int new_distance = (int)(total_height * AppManager.Config.LastPreviewAspecto); + m_panels.SplitterDistance = new_distance; + AppManager.Config.PreviewHidden = false; + menuVisualPreviewFlipVisible.Text = _( "Disable Preview" ); + m_panels.IsSplitterFixed = false; + } else { + AppManager.Config.LastPreviewAspecto = ((float)m_panels.Panel1.Height) / ((float)(m_panels.Panel2.Height + m_panels.Panel1.Height)); + m_panels.SplitterDistance = 0; + AppManager.Config.PreviewHidden = true; + menuVisualPreviewFlipVisible.Text = _( "Enable Preview" ); + m_panels.IsSplitterFixed = true; + } + } + + private void Save( string file ) { + bool backup_created = false; + string new_file = ""; + if ( File.Exists( file ) ) { + new_file = file + "_"; + while ( File.Exists( new_file ) ) { + new_file += "_"; + } + File.Move( file, new_file ); + backup_created = true; + } + using ( SettingsEx temp = (SettingsEx)AppManager.SaveData.Clone() ) + using ( FileStream fs = new FileStream( file, FileMode.Create ) ) { + BinaryFormatter bf = new BinaryFormatter(); + for ( int i = 0; i < m_not_used_plugin.Count; i++ ) { + temp.m_group_plugin.Add( (TimeTable)m_not_used_plugin[i].Clone() ); + } + for ( int i = 0; i < m_not_used_plugin_config.Count; i++ ) { + temp.m_plugins_config.Add( m_not_used_plugin_config[i].Clone() ); + } + try { + bf.Serialize( fs, temp ); + AppManager.Edited = false; + } catch ( Exception ex ) { + Common.LogPush( ex ); + MessageBox.Show( + _( "Failed file saving" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + fs.Close(); + if ( backup_created ) { + try { + File.Delete( file ); + File.Move( new_file, file ); + } catch { + } + } + } finally { + bf = null; + if ( backup_created && File.Exists( new_file ) ) { + File.Delete( new_file ); + } + } + } + } + + private void Read( string file ) { +#if DEBUG + Common.DebugWriteLine( "read(string)" ); +#endif + StopPauseCore(); //timerPreview.Enabled = false; + + if ( AppManager.Edited ) { + DialogResult result = requestIntention(); + if ( result == DialogResult.Yes ) { + if ( m_filePath != "" ) { + Save( m_filePath ); + } else { + if ( saveFileDialog1.ShowDialog() == DialogResult.OK ) { + Save( saveFileDialog1.FileName ); + } else { + return; + } + } + } else if ( result == DialogResult.Cancel ) { + return; + } + } + + previewer.TrackBarValue = previewer.TrackBarMinimum; + using ( FileStream fs = new FileStream( file, FileMode.Open ) ) { + BinaryFormatter bf = new BinaryFormatter(); + m_skip_paint = true; + + List t_plugin_info = new List(); + foreach ( PluginInfo pinfo in AppManager.SaveData.m_plugins ) { + t_plugin_info.Add( (PluginInfo)pinfo.Clone() ); + } + + object tmp = bf.Deserialize( fs ); + if ( tmp.GetType() == typeof( LipSync.Settings ) ) { +#if DEBUG + Common.DebugWriteLine( " deserialized object is LipSync.Settings" ); +#endif + Settings tSettings = (Settings)tmp; + AppManager.SaveData.Dispose(); + AppManager.SaveData = new SettingsEx( tSettings ); + } else if ( tmp.GetType() == typeof( LipSync.SettingsEx ) ) { +#if DEBUG + Common.DebugWriteLine( " deserialized object is LipSync.SettingsEx" ); +#endif + AppManager.SaveData.Dispose(); + AppManager.SaveData = (SettingsEx)tmp; + } else { + // 読み込み失敗 + MessageBox.Show( + _( "Failed file reading" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Error ); + return; + } + + AppManager.SaveData.m_zorder.Clear(); + + int n_plugin = t_plugin_info.Count; + if ( n_plugin > 0 ) { + AppManager.SaveData.m_plugins = new PluginInfo[t_plugin_info.Count]; + for ( int i = 0; i < t_plugin_info.Count; i++ ) { + AppManager.SaveData.m_plugins[i] = (PluginInfo)t_plugin_info[i].Clone(); + } + } + + AppManager.Edited = false; + + // いまインストールされているプラグインの情報を元に、 + // 使用できるプラグインの情報のみをm_変数に入れる + // 使えないものは、m_not_used_変数に保管しておく。 + m_not_used_plugin.Clear(); + m_not_used_plugin_config.Clear(); + + List tmp_ttable = new List(); + List tmp_config = new List(); + for ( int i = 0; i < AppManager.SaveData.m_plugins_config.Count; i++ ) { +#if DEBUG + Common.DebugWriteLine( "Form1.read(String); m_plugins_config[]; id=" + AppManager.SaveData.m_plugins_config[i].ID + "; config=" + AppManager.SaveData.m_plugins_config[i].Config ); +#endif + bool found = false; + for ( int j = 0; j < AppManager.SaveData.m_plugins.Length; j++ ) { + if ( AppManager.SaveData.m_plugins_config[i].ID == AppManager.SaveData.m_plugins[j].ID ) { + found = true; + break; + } + } + if ( found ) { + tmp_ttable.Add( (TimeTable)AppManager.SaveData.m_group_plugin[i].Clone() ); + tmp_config.Add( AppManager.SaveData.m_plugins_config[i].Clone() ); + } else { + m_not_used_plugin.Add( (TimeTable)AppManager.SaveData.m_group_plugin[i].Clone() ); + m_not_used_plugin_config.Add( AppManager.SaveData.m_plugins_config[i].Clone() ); + } + } + + // Settingsに転送 + AppManager.SaveData.m_group_plugin.Clear(); + AppManager.SaveData.m_plugins_config.Clear(); + for ( int i = 0; i < tmp_ttable.Count; i++ ) { + AppManager.SaveData.m_group_plugin.Add( (TimeTable)tmp_ttable[i].Clone() ); + AppManager.SaveData.m_plugins_config.Add( tmp_config[i].Clone() ); + } + + // プラグインの全体設定を適用 + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + string id = AppManager.SaveData.m_plugins[i].ID; + AppManager.SaveData.m_plugins[i].Instance.Config = ""; + for ( int j = 0; j < AppManager.SaveData.m_group_plugin.Count; j++ ) { + if ( AppManager.SaveData.m_plugins_config[j].ID == id ) { + AppManager.SaveData.m_plugins[i].Instance.Config = AppManager.SaveData.m_plugins_config[j].Config; + break; + } + } + } + + bf = null; + } + AppManager.ClearCommandBuffer(); + AppManager.SaveData.UpdateZorder(); + Telop.DecideLane( AppManager.SaveData.m_telop_ex2 ); + m_skip_paint = false; + + if ( AppManager.SaveData.m_audioFile.Length > 0 && File.Exists( AppManager.SaveData.m_audioFile ) ) { + m_player.Load( AppManager.SaveData.m_audioFile ); + } + + previewer.Image = new Bitmap( AppManager.SaveData.m_movieSize.Width, AppManager.SaveData.m_movieSize.Height ); + using ( Graphics g = Graphics.FromImage( previewer.Image ) ) { + AppManager.SaveData.DrawTo( g, previewer.Image.Size, Now, false ); + } + previewer.Invalidate(); + + UpdateFormTitle(); + this.Invalidate(); +#if DEBUG + for ( int i = 0; i < AppManager.SaveData.m_plugins_config.Count; i++ ) { + Common.DebugWriteLine( "Form1.read(String); registered; id=" + AppManager.SaveData.m_plugins_config[i].ID + "; config=" + AppManager.SaveData.m_plugins_config[i].Config ); + } + for ( int i = 0; i < m_not_used_plugin_config.Count; i++ ) { + Common.DebugWriteLine( "Form1.read(String); not registered; id=" + m_not_used_plugin_config[i].ID ); + } + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + Common.DebugWriteLine( "Form1.read(String); current plugin; id=" + AppManager.SaveData.m_plugins[i].ID + "; Config=" + AppManager.SaveData.m_plugins[i].Instance.Config ); + } +#endif + } + + private void sizeChange() { + using ( SetSize setsize = new SetSize( _( "Video size configuration" ), _( "Width" ), _( "Height" ), AppManager.SaveData.m_movieSize.Width, AppManager.SaveData.m_movieSize.Height ) ) { + if ( setsize.ShowDialog() == DialogResult.OK ) { + Command run = Command.GCommandChangeVideoSize( new Size( (int)setsize.ResultWidth, (int)setsize.ResultHeight ) ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + previewer.Image = new Bitmap( (int)setsize.ResultWidth, (int)setsize.ResultHeight ); + using ( Graphics g = Graphics.FromImage( previewer.Image ) ) { + AppManager.SaveData.DrawTo( g, previewer.Image.Size, Now, false ); + } + previewer.Invalidate(); + AppManager.Edited = true; + } + } + } + + public Bitmap GetPicture( float now, bool is_transparent ) { + if ( m_skip_paint ) { + return null; + } + Size mSize = AppManager.SaveData.m_movieSize; + Bitmap bmp = is_transparent ? + new Bitmap( mSize.Width, mSize.Height, PixelFormat.Format32bppArgb ) : + new Bitmap( mSize.Width, mSize.Height, PixelFormat.Format24bppRgb ); + using ( Graphics g = Graphics.FromImage( bmp ) ) { + AppManager.SaveData.DrawTo( g, mSize, now, is_transparent ); + } + return bmp; + } + + private void DeleteEntry() { + if ( m_edit_mode == EditMode.Selected/* m_editMode*/ ) { + bool changed = false; + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + if ( type == TimeTableType.character || type == TimeTableType.another || type == TimeTableType.plugin ) { + Command run = Command.GCommandDeleteTimeTableEntry( type, group, track, AppManager.SaveData[type, group][track][entry] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + changed = true; + } + if ( changed ) { + m_edit_mode = EditMode.None; + AppManager.Edited = true; + pictureBox1.Invalidate(); + } + } + } + + private float RepeatStart { + get { + return AppManager.SaveData.REPEAT_START; + } + } + + private float RepeatEnd { + get { + if ( AppManager.SaveData.REPEAT_END < 0 ) { + return AppManager.SaveData.m_totalSec; + } else { + return AppManager.SaveData.REPEAT_END; + } + } + } + + private void UpdateExpandRange( float time ) { + bool exclusion_mode = false; + + if ( m_clicked.type == TimeTableType.character ) { + string title = AppManager.SaveData.m_groups_character[m_clicked.group][m_clicked.track].Text; + string tag = AppManager.SaveData.m_groups_character[m_clicked.group].Character[title].tag; + if ( tag != "" ) { + exclusion_mode = true; + } + } + + if ( exclusion_mode ) { + m_expandRange = GetEntryLimit( m_clicked, time, true ); + } else { + m_expandRange = GetEntryLimitSingle( m_clicked, time, true ); + } + } + + private void UpdateEditHandle( int x, int y ) { + Rectangle hilight = GetHilightRect( x, y ); + m_editHandleLeft.X = hilight.X - HANDLE_WIDTH / 2; + m_editHandleLeft.Y = hilight.Y; + m_editHandleLeft.Width = HANDLE_WIDTH; + m_editHandleLeft.Height = AppManager.Config.TrackHeight; + + m_editHandleRight.X = hilight.X + hilight.Width - HANDLE_WIDTH / 2; + m_editHandleRight.Y = hilight.Y; + m_editHandleRight.Width = HANDLE_WIDTH; + m_editHandleRight.Height = AppManager.Config.TrackHeight; + } + + private void SetHScrollRange() { + AppManager.SaveData.m_screenWidth = (int)(AppManager.SaveData.m_totalSec * AppManager.Config.PixelPerSec); + previewer.TrackBarMaximum = (int)(AppManager.SaveData.m_totalSec * AppManager.SaveData.FrameRate); + if ( AppManager.SaveData.m_totalSec == 0.0f ) { + hScrollBar1.Maximum = 109; + } else { + hScrollBar1.Maximum = (int)(AppManager.SaveData.m_totalSec * AppManager.Config.PixelPerSec); + hScrollBar1.LargeChange = pictureBox1.Width; + if ( AppManager.SaveData.m_screenWidth > pictureBox1.Width ) { + hScrollBar1.Enabled = true; + } else { + hScrollBar1.Enabled = false; + } + } + } + + private void SetVScrollRange() { + if ( AppManager.SaveData.m_group_vsq == null ) { + return; + } + int[] lane = AppManager.GetTimeLineLanes(); + int tracks = 1; + for ( int i = 0; i < lane.Length; i++ ) { + tracks += lane[i]; + } + AppManager.SaveData.m_screenHeight = tracks * AppManager.Config.TrackHeight; + vScrollBar1.Maximum = AppManager.SaveData.m_screenHeight; + vScrollBar1.LargeChange = pictureBox1.Height; + if ( AppManager.SaveData.m_screenHeight > pictureBox1.Height ) { + vScrollBar1.Enabled = true; + } else { + vScrollBar1.Value = vScrollBar1.Minimum; + vScrollBar1.Enabled = false; + } + } + + private int XCoordFromSec( float time ) { + return (int)(time * AppManager.Config.PixelPerSec) - m_startToDrawX; + } + + /// + /// pictureBox1上のx座標位置を、秒数に変換します + /// + /// + /// + private float SecFromXCoord( int pixel ) { + return (pixel + m_startToDrawX) / AppManager.Config.PixelPerSec; + } + + private int StartToDrawX() { + float ratio = ((float)(hScrollBar1.Value) / (float)(hScrollBar1.Maximum - hScrollBar1.Minimum + 1 - hScrollBar1.LargeChange)); + if ( AppManager.SaveData.m_screenWidth - pictureBox1.Width >= 0 ) { + return (int)((AppManager.SaveData.m_screenWidth - pictureBox1.Width) * ratio); + } else { + return 0; + } + } + + private int StartToDrawY() { + float ratio = ((float)(vScrollBar1.Value) / ((float)(vScrollBar1.Maximum - vScrollBar1.Minimum + 1 - vScrollBar1.LargeChange))); + //MessageBox.Show( "StartToDrawY=" + (int)(ratio * (m_screenHeight - pictureBox1.Height)) ); + if ( AppManager.SaveData.m_screenHeight - pictureBox1.Height >= 0 ) { + return (int)(ratio * (AppManager.SaveData.m_screenHeight - pictureBox1.Height)); + } else { + return 0; + } + } + + /// + /// s.m_groups_characterの第group番グループの、時刻timeの位置において、 + /// 延長可能な時刻をPointEx型で返します + /// + /// グループのインデックス + /// 時刻 + /// + /// 指定されたグループの他のTimeTableType.mouthと被らずに前後に延長することができる範囲。 + /// + private PointF GetEntryLimit( Item item, float time, bool ignore_me ) { + if ( item.type == TimeTableType.character ) { + string title = AppManager.SaveData.m_groups_character[item.group][item.track].Text; + string tag = AppManager.SaveData.m_groups_character[item.group].Character[title].tag; + + int track_num = AppManager.SaveData.m_groups_character[item.group].Count; + PointF[] points = new PointF[track_num]; + for ( int track = 0; track < track_num; track++ ) { + Item tmp = new Item( item.type, item.group, item.track, item.entry, item.row_index ); + string tmp_title = AppManager.SaveData.m_groups_character[item.group][track].Text; + string tmp_tag = AppManager.SaveData.m_groups_character[item.group].Character[tmp_title].tag; + if ( tag != "" && tag == tmp_tag ) { + tmp.track = track; + if ( track == item.track ) { + points[track] = GetEntryLimitSingle( tmp, time, ignore_me ); + } else { + points[track] = GetEntryLimitSingle( tmp, time, false ); + } + } else { + points[track].X = 0.0f; + points[track].Y = AppManager.SaveData.m_totalSec; + } + } + PointF result = new PointF( 0.0f, AppManager.SaveData.m_totalSec ); + for ( int track = 0; track < track_num; track++ ) { + result.X = Math.Max( result.X, points[track].X ); + result.Y = Math.Min( result.Y, points[track].Y ); + } + return result; + + } else { + return new PointF( time, time ); + } + } + + /// + /// Item構造体で指定される、トラックの時刻timeの位置にエントリを追加した場合に、 + /// 同じトラックの前後のエントリと被らずに延長することのできる時間の範囲を調べます。 + /// ignore_me == trueの時、item.entryの存在を無視します。 + /// + /// + /// + /// + /// + private PointF GetEntryLimitSingle( Item item, float time, bool ignore_me ) { + TimeTableType type = item.type; + int group = item.group; + int track = item.track; + + if ( type == TimeTableType.character || type == TimeTableType.another || type == TimeTableType.plugin ) { + return GetEntryLimitSinglePart( AppManager.SaveData[type, group][track], time, ignore_me, item ); + } else { + return new PointF( time, time ); + } + } + + private PointF GetEntryLimitSinglePart( TimeTable table, float time, bool ignore_me, Item item ) { + if ( table.Count == 0 ) { + return new PointF( 0.0f, AppManager.SaveData.m_totalSec ); + } + int index_before; + int index_after; + index_before = -1; + index_after = table.Count; + float begin; + float end; + for ( int entry = 0; entry < table.Count; entry++ ) { + if ( ignore_me && entry == item.entry ) { + continue; + } + if ( time < table[entry].begin ) { + index_after = entry; + break; + } + } + for ( int entry = index_after - 1; entry >= 0; entry-- ) { + if ( ignore_me && entry == item.entry ) { + continue; + } + if ( table[entry].end < time ) { + index_before = entry; + break; + } + } + + // 新しく設定する時刻をセット + if ( index_before == -1 ) { + begin = 0.0f; + } else { + begin = table[index_before].end; + } + if ( index_after == table.Count ) { + end = AppManager.SaveData.m_totalSec; + } else { + end = table[index_after].begin; + } + + // + if ( index_after == index_before + 1 ) { + return new PointF( begin, end ); + } else { + if ( ignore_me && index_before == item.entry - 1 && index_after == item.entry + 1 ) { + return new PointF( begin, end ); + } else { + return new PointF( time, time ); + } + } + } + + /// + /// マウスのy座標から、タイムテーブル・グループの番号を取得します + /// + /// 仮想スクリーン上のマウスの座標 + /// + /// 第iタイムテーブルグループのタイトルにマウスがあったとき + /// new Item( i, -1, -1) + /// 第iタイムテーブル・グループの第jタイムテーブルの、テーブルエントリ以外の場所にマウスがあったとき + /// new Item( i, j, -1 ) + /// 第iタイムテーブル・グループの第jタイムテーブルの第kエントリーにマウスがあったとき + /// new Item( i, j, k ) + /// + private Item GetGroupItem( int x, int y ) { + int track_count = 0; + Item item = new Item( TimeTableType.none, -1, -1, -1, -1 ); + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + item.type = TimeTableType.top; + return item; + } + + bool vsq_fixed = menuVisualVsqTrack.Checked; + /* + * vsqのグループを検索 + */ + // タイトル + track_count++; + int yy = y; + if ( vsq_fixed ) { + yy = y - m_startToDrawY; + } + if ( track_count * AppManager.Config.TrackHeight <= yy && yy < (track_count + 1) * AppManager.Config.TrackHeight ) { + item.type = TimeTableType.vsq; + item.group = 0; + item.row_index = track_count; + return item; + } + if ( !AppManager.SaveData.m_group_vsq.Folded ) { + // 本体 + for ( int i = 0; i < AppManager.SaveData.m_group_vsq.Count; i++ ) { + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= yy && yy < (track_count + 1) * AppManager.Config.TrackHeight ) { + item.type = TimeTableType.vsq; + item.group = 0; + item.track = i; + item.row_index = track_count; + for ( int entry = 0; entry < AppManager.SaveData.m_group_vsq[item.track].Count; entry++ ) { + int xx = (int)(AppManager.SaveData.m_group_vsq[item.track][entry].begin * AppManager.Config.PixelPerSec); + int xend = (int)(AppManager.SaveData.m_group_vsq[item.track][entry].end * AppManager.Config.PixelPerSec); + if ( xx <= x && x < xend ) { + item.entry = entry; + break; + } + } + return item; + } + } + } + + /* + * キャラクタのグループを検索 + */ + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + // タイトル + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = TimeTableType.character; + item.group = group; + item.row_index = track_count; + return item; + } + } + if ( !AppManager.SaveData.m_groups_character[group].Folded ) { + for ( int track = 0; track < AppManager.SaveData.m_groups_character[group].Count; track++ ) { + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = AppManager.SaveData.m_groups_character[group][track].Type; + item.group = group; + item.track = track; + item.row_index = track_count; + for ( int entry = 0; entry < AppManager.SaveData.m_groups_character[item.group][item.track].Count; entry++ ) { + int xx = (int)(AppManager.SaveData.m_groups_character[item.group][item.track][entry].begin * AppManager.Config.PixelPerSec); + int xend = (int)(AppManager.SaveData.m_groups_character[item.group][item.track][entry].end * AppManager.Config.PixelPerSec); + if ( xx <= x && x < xend ) { + item.entry = entry; + break; + } + } + return item; + } + } + } + } + } + + /* + * 字幕を検索 + */ + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ){ + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height ) ){ + item.type = TimeTableType.telop; + item.group = 0; + item.track = -1; + item.row_index = track_count; + return item; + } + } + if ( !AppManager.SaveData.TelopListFolded ){ + if ( (track_count + 1) * AppManager.Config.TrackHeight <= y && y < (track_count + AppManager.MaxTelopLanes + 1) * AppManager.Config.TrackHeight ) { + item.type = TimeTableType.telop; + item.group = 0; + item.track = 0; + item.row_index = track_count; + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + int xx = (int)(AppManager.SaveData.m_telop_ex2[i].Start * AppManager.Config.PixelPerSec); + int xend = (int)(AppManager.SaveData.m_telop_ex2[i].End * AppManager.Config.PixelPerSec); + int y1 = (track_count + AppManager.SaveData.m_telop_ex2[i].Lane + 1) * AppManager.Config.TrackHeight; + if ( xx <= x && x < xend && y1 <= y && y < y1 + AppManager.Config.TrackHeight ) { + item.row_index = track_count + AppManager.SaveData.m_telop_ex2[i].Lane + 1; + item.entry = AppManager.SaveData.m_telop_ex2[i].ID; + break; + } + } + return item; + } + track_count += AppManager.MaxTelopLanes; + } + + /* + * その他のイメージを検索 + */ + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = TimeTableType.another; + item.group = 0; + item.row_index = track_count; + return item; + } + } + // 本体 + if ( !AppManager.SaveData.m_group_another.Folded ) { + for ( int i = 0; i < AppManager.SaveData.m_group_another.Count; i++ ) { + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = TimeTableType.another; + item.group = 0; + item.track = i; + item.row_index = track_count; + for ( int entry = 0; entry < AppManager.SaveData.m_group_another[item.track].Count; entry++ ) { + int xx = (int)(AppManager.SaveData.m_group_another[item.track][entry].begin * AppManager.Config.PixelPerSec); + int xend = (int)(AppManager.SaveData.m_group_another[item.track][entry].end * AppManager.Config.PixelPerSec); + if ( xx <= x && x < xend ) { + item.entry = entry; + break; + } + } + return item; + } + } + } + } + + // プラグインを検索 + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = TimeTableType.plugin; + item.group = 0; + item.row_index = track_count; + return item; + } + } + // 本体 + if ( !AppManager.SaveData.m_group_plugin.Folded ) { + for ( int i = 0; i < AppManager.SaveData.m_group_plugin.Count; i++ ) { + track_count++; + if ( track_count * AppManager.Config.TrackHeight <= y && y < (track_count + 1) * AppManager.Config.TrackHeight ) { + if ( !vsq_fixed || (vsq_fixed && yy >= m_vsq_height) ) { + item.type = TimeTableType.plugin; + item.group = 0; + item.track = i; + item.row_index = track_count; + for ( int entry = 0; entry < AppManager.SaveData.m_group_plugin[item.track].Count; entry++ ) { + int xx = (int)(AppManager.SaveData.m_group_plugin[item.track][entry].begin * AppManager.Config.PixelPerSec); + int xend = (int)(AppManager.SaveData.m_group_plugin[item.track][entry].end * AppManager.Config.PixelPerSec); + if ( xx <= x && x < xend ) { + item.entry = entry; + break; + } + } + return item; + } + } + } + } + return item; + } + + /// + /// 指定された画像を指定した位置にプレビュー表示します + /// + /// 表示する画像 + /// pictureBox1上のプレビュー画像の表示位置位置 + private void ShowPreviewPictureBox( Image image, Point position ) { + if ( image == null ) { + return; + } + int width = image.Width; + int height = image.Height; + preview_image.Width = width; + preview_image.Height = height; + preview_image.Image = image; + int x = position.X; + int y = position.Y; + bool right = false; + bool down = false; + if ( pictureBox1.Width / 2 < x ) { + x -= width; + right = true; + } + if ( pictureBox1.Height / 2 < y ) { + y -= height; + down = true; + } + float scale_x = 1f; + if ( x + width > pictureBox1.Width ) { + scale_x = (float)(pictureBox1.Width - x) / (float)width; + } else if ( x < 0 ) { + scale_x = (float)(x + width) / (float)width; + } + float scale_y = 1f; + if ( y + height > pictureBox1.Height ) { + scale_y = (float)(pictureBox1.Height - y) / (float)height; + } else if ( y < 0 ) { + scale_y = (float)(y + height) / (float)height; + } + float scale = Math.Min( scale_x, scale_y ); + if ( scale < 1f ) { + preview_image.Size = new Size( (int)(width * scale), (int)(height * scale) ); + if ( right ) { + x += (int)(width - width * scale); + } else { + if ( x < 0 ) { + x = 0; + } + } + if ( down ) { + y += (int)(height - height * scale); + } else { + if ( y < 0 ) { + y = 0; + } + } + } + preview_image.Top = y;//position.Y;// + Panels.Panel2.Top + 1; + preview_image.Left = x;//position.X;// + Panels.Panel2.Left + 1; + + m_preview_time = DateTime.Now; + preview_image.Visible = true; + this.Invalidate(); + } + + /// + /// 既存のデータを破棄します。未保存時のチェックは行わない。 + /// + private void ClearExistingData() { + StopPauseCore(); //timerPreview.Enabled = false; + previewer.TrackBarValue = 0; + previewer.TrackBarMaximum = 0; + AppManager.SaveData.m_zorder.Clear(); + AppManager.SaveData.m_group_vsq.Clear(); + AppManager.SaveData.m_groups_character.Clear(); + AppManager.SaveData.m_group_another.Clear(); + for ( int i = 0; i < AppManager.SaveData.m_group_plugin.Count; i++ ) { + AppManager.SaveData.m_group_plugin[i].Clear(); + AppManager.SaveData.m_plugins_config[i].Config = ""; + } + AppManager.ClearCommandBuffer(); + AppManager.SaveData.m_totalSec = 0.0f; + m_not_used_plugin.Clear(); + m_not_used_plugin_config.Clear(); + m_player.Close(); + AppManager.SaveData.m_telop_ex2.Clear(); + AppManager.MaxTelopLanes = 0; + property.Editing = null; + AppManager.SaveData.REPEAT_START = 0f; + AppManager.SaveData.REPEAT_END = -1f; + if ( AppManager.SaveData.m_timesig_ex != null ) { + AppManager.SaveData.m_timesig_ex.Clear(); + } + if ( AppManager.SaveData.m_tempo != null ) { + AppManager.SaveData.m_tempo.Clear(); + } + m_curve.Clear(); + menuEditRedo.Enabled = false; + menuEditUndo.Enabled = false; + UpdateObjectList(); + } + + /// + /// 指定されたトラックから、歌詞のタイムラインを読み込み、現在のvsqトラックリスト、 + /// s.m_group_vsqに追加します。 + /// + /// 追加するトラック + private void addTimeLineFromTrack( VsqFile vsqFile, int track_number, bool enable_undo ) { + string tmp_lyric = Path.GetTempFileName(); + vsqFile.printLyricTable( track_number, tmp_lyric ); + using ( TimeTable temp = new TimeTable( vsqFile.getTrack( track_number ).Name, 0, TimeTableType.vsq, null ) ) { + using ( StreamReader sr = new StreamReader( tmp_lyric ) ) { + string line; + while ( sr.Peek() >= 0 ) { + line = sr.ReadLine(); + string[] spl = line.Split( new char[] { ',' } ); + float begin = float.Parse( spl[1] ); + float end = float.Parse( spl[2] ); + string body = spl[3] + "(" + spl[4] + ")"; + temp.Add( new TimeTableEntry( begin, end, body ) ); + } + } + Command run = Command.GCommandAddTimeTable( TimeTableType.vsq, -1, AppManager.SaveData.m_group_vsq.Count, temp ); + Command inv = AppManager.SaveData.Execute( run ); + if ( enable_undo ) { + AppManager.Register( inv ); + } + + } + + File.Delete( tmp_lyric ); + AppManager.Edited = true; + } + + private void AddTimeLineFromUst( UstFile ust_file, int track_number, bool enable_undo ) { + TimeTable temp = new TimeTable( ust_file.getProjectName(), 0, TimeTableType.vsq, null ); + int count = 0; + for ( int i = 0; i < ust_file.getTrack( track_number ).getEventCount(); i++ ) { + UstEvent ue = ust_file.getTrack( track_number ).getEvent( i ); + float start = (float)ust_file.getSecFromClock( count ); + float end = (float)ust_file.getSecFromClock( (int)(count + ue.Length) ); + string phrase = ue.Lyric; + if ( phrase != "R" ) { + string symbol = "a"; + if ( !SymbolTable.attatch( phrase, out symbol ) ) { + symbol = "a"; + } + temp.Add( new TimeTableEntry( start, end, phrase + "(" + symbol + ")" ) ); + } + count += (int)ue.Length; + } + Command run = Command.GCommandAddTimeTable( TimeTableType.vsq, -1, AppManager.SaveData.m_group_vsq.Count, temp ); + Command inv = AppManager.SaveData.Execute( run ); + if ( enable_undo ) { + AppManager.Register( inv ); + } + } + + /// + /// VSQファイルのトラック情報から、口の動きのタイムラインを作成します + /// + /// + private void GenerateLipsyncFromVsq( TimeTable time_table, Character3 character, bool enable_undo ) { + string name = character.Name; + TimeTableGroup temp = new TimeTableGroup( name, 0, character ); + + TimeTableGroup.GenerateLipSyncFromVsq( time_table, + ref temp, + character, + AppManager.SaveData.m_totalSec, + AppManager.Config.CloseMouthWhenSameVowelsRepeated, + AppManager.SaveData.FrameRate, + AppManager.Config.EntryCombineThreshold ); + + Command run = Command.GCommandAddGroup( TimeTableType.character, + AppManager.SaveData.m_groups_character.Count, + temp ); + Command inv = AppManager.SaveData.Execute( run ); + if ( enable_undo ) { + AppManager.Register( inv ); + } + temp.Dispose(); + + if ( enable_undo ) { + AppManager.Edited = true; + } + UpdateObjectList(); + AppManager.SaveData.UpdateZorder(); + } + + private DialogResult requestIntention() { + if ( m_filePath != "" ) { + return MessageBox.Show( "'" + Path.GetFileName( m_filePath ) + "'" + _( " has been changed. Do you wish to save changes to file?" ), "LipSync", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation ); + } else { + return MessageBox.Show( _( "Do you wish to save changes to file?" ), "LipSync", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation ); + } + } + + /// + /// 操作環境の設定項目を保存します + /// + private void SaveConfig() { + AppManager.Config.CloseMouthPhoneticSymbols.Clear(); + foreach ( string s in VowelType.m_list_nn ) { + AppManager.Config.CloseMouthPhoneticSymbols.Add( s ); + } + AppManager.Config.IMouthPhoneticSymbols.Clear(); + foreach ( string s in VowelType.m_list_i ) { + AppManager.Config.IMouthPhoneticSymbols.Add( s ); + } + AppManager.Config.UMouthPhoneticSymbols.Clear(); + foreach ( string s in VowelType.m_list_u ) { + AppManager.Config.UMouthPhoneticSymbols.Add( s ); + } + AppManager.Config.CleanUpMouthList(); + string config_file = Path.Combine( Application.StartupPath, "LipSync.config" ); + AppManager.Config.Save( config_file ); + } + + /// + /// 操作環境の設定項目をファイルから読み込み、適用します + /// + private void LoadConfig() { + string config_file = Path.Combine( Application.StartupPath, "LipSync.config" ); + AppManager.Config = EnvSettings.FromFile( config_file ); + AppManager.Config.CleanUpMouthList(); + VowelType.m_list_i.Clear(); + foreach ( string s in AppManager.Config.IMouthPhoneticSymbols ) { + VowelType.m_list_i.Add( s ); + } + VowelType.m_list_nn.Clear(); + foreach ( string s in AppManager.Config.CloseMouthPhoneticSymbols ) { + VowelType.m_list_nn.Add( s ); + } + VowelType.m_list_u.Clear(); + foreach ( string s in AppManager.Config.UMouthPhoneticSymbols ) { + VowelType.m_list_u.Add( s ); + } + + // restore window size & location | ウィンドウ位置・サイズの復元 + bool visible = false; + Point pt_lu = AppManager.Config.WindowPosition.Location; + Point pt_ll = new Point( AppManager.Config.WindowPosition.Left, AppManager.Config.WindowPosition.Bottom ); + Point pt_ru = new Point( AppManager.Config.WindowPosition.Right, AppManager.Config.WindowPosition.Top ); + Point pt_rl = new Point( AppManager.Config.WindowPosition.Right, AppManager.Config.WindowPosition.Bottom ); + foreach ( Screen s in Screen.AllScreens ) { + Rectangle r = s.Bounds; + visible = visible | (AppManager.IsInRectangle( pt_lu, r ) | AppManager.IsInRectangle( pt_ll, r ) | AppManager.IsInRectangle( pt_ru, r ) | AppManager.IsInRectangle( pt_rl, r )); + } + if ( visible ) { + this.Top = AppManager.Config.WindowPosition.Top; + this.Left = AppManager.Config.WindowPosition.Left; + this.Width = AppManager.Config.WindowPosition.Width; + this.Height = AppManager.Config.WindowPosition.Height; + } else { + this.Width = Screen.PrimaryScreen.Bounds.Width / 2; + this.Height = Screen.PrimaryScreen.Bounds.Height / 2; + this.Top = this.Height / 2; + this.Left = this.Width / 2; + } + if ( AppManager.Config.WindowIsMaximized ) { + base.WindowState = FormWindowState.Maximized; + } + + Messaging.Language = AppManager.Config.Language; + ApplyLanguage(); + + // 拡張前の設定ファイルに対応 + // いまんとこなにもなし + + previewer.PreviewSizeMode = AppManager.Config.PreviewZoomMode; + + AppManager.Config.PreviewHidden = !AppManager.Config.PreviewHidden; + ChangePreviewHidden(); + AppManager.Config.PropertyHidden = !AppManager.Config.PropertyHidden; + ChangePropertyHidden(); + + menuVisualBars.Checked = AppManager.Config.DrawBars; + } + + /// + /// クオンタイズモード用のグリッドリスト「m_grids」を更新します + /// + private void UpdateGridList() { + IEnumerable blte = AppManager.SaveData.GetBarLineTypeEnumerator( AppManager.Config.QuantizeMode, AppManager.Config.QuantizeTripletEnabled ); + float start = m_startToDrawX / (float)AppManager.Config.PixelPerSec; + float end = (m_startToDrawX + pictureBox1.Width) / (float)AppManager.Config.PixelPerSec; + List c = new List(); + foreach ( BarLineType bar in blte ) { + if ( start <= bar.Time && bar.Time <= end && !bar.NeverUseForSnapPoint ) { + c.Add( (float)bar.Time ); + } else if ( bar.Time > end ) { + break; + } + } + m_grids = c.ToArray(); + } + + public float Now { + get { + if ( AppManager.Playing ) { + TimeSpan ts = (DateTime.Now).Subtract( m_started_date ); + return (float)ts.TotalSeconds * m_player.Speed; + } else { + int nof = previewer.TrackBarValue; + return nof / AppManager.SaveData.FrameRate; + } + } + } + + /// + /// タイムライン左端の,グループ折りたたみ状態を表す三角形を描画する + /// + /// + /// + /// + private void DrawTriangle( Graphics g, int y, bool folded ) { + SmoothingMode past = g.SmoothingMode; + g.SmoothingMode = SmoothingMode.AntiAlias; + using ( SolidBrush brs = new SolidBrush( TRIANGLE_COLOR ) ) { + using ( Pen pen = new Pen( brs ) ) { + pen.LineJoin = LineJoin.Round; + Point[] list = new Point[6]; + if ( folded ) { + list[0] = new Point( 6, y + 15 ); + list[1] = new Point( 6, y + 2 ); + list[2] = new Point( 7, y + 2 ); + list[3] = new Point( 13, y + 8 ); + list[4] = new Point( 13, y + 9 ); + list[5] = new Point( 7, y + 15 ); + } else { + list[0] = new Point( 2, y + 5 ); + list[1] = new Point( 15, y + 5 ); + list[2] = new Point( 15, y + 6 ); + list[3] = new Point( 9, y + 12 ); + list[4] = new Point( 8, y + 12 ); + list[5] = new Point( 2, y + 6 ); + } + g.DrawLines( pen, list ); + g.FillPolygon( brs, list ); + } + } + g.SmoothingMode = past; + } + + /// + /// タイムテーブルグループtableを、グラフィクスgを用いて、位置positionに描画します。 + /// 描画の結果、描かれたタイムテーブルの画面上の高さ(ピクセル)をheightに返します。 + /// + /// + /// + /// + /// + /// + private void DrawTimeTableGroup( Graphics g, Point position, out int height, TimeTableGroup table, string title ) { + //int y = position.Y; + Rectangle outline = new Rectangle( position.X, position.Y, pictureBox1.Width, AppManager.Config.TrackHeight ); + g.FillRectangle( new SolidBrush( AppManager.Config.TimeLineTitleColor.Color ), + outline ); + g.DrawString( title, + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X, position.Y + AppManager.Config.VerticalStringOffset ) ); + if ( table.Folded ) { + height = AppManager.Config.TrackHeight; + return; + } + if ( table.Count > 0 ) { + TimeTableType type = table[0].Type; + for ( int j = 0; j < table.Count; j++ ) { + int i = j; + int y = (i + 1) * AppManager.Config.TrackHeight; + bool first_draw = true; + for ( int list_index = 0; list_index < table[i].Count; list_index++ ) { + int x = (int)(table[i][list_index].begin * AppManager.Config.PixelPerSec) - m_startToDrawX; + int xend = (int)(table[i][list_index].end * AppManager.Config.PixelPerSec) - m_startToDrawX; + if ( first_draw ) { + if ( xend >= 0 ) { + first_draw = false; + } else { + continue; + } + } else { + if ( x > pictureBox1.Width ) { + break; + } + } + int yend = y + AppManager.Config.TrackHeight; + Color col; + switch ( table[i].Type ) { + case TimeTableType.vsq: + col = AppManager.Config.TimeLineVsqColor.Color; + break; + case TimeTableType.plugin: + col = AppManager.Config.TimeLinePluginColor.Color; + break; + default: + col = AppManager.Config.TimeLineDefaultColor.Color; + break; + } + using ( Brush fill = new SolidBrush( col ) ) { + Rectangle rc = new Rectangle( + new Point( position.X + x, position.Y + y ), + new Size( xend - x, AppManager.Config.TrackHeight - 1 ) ); + g.FillRectangle( fill, rc ); + if ( table[i].Type == TimeTableType.plugin ) { + g.DrawString( "[]", + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X + x, position.Y + y + AppManager.Config.VerticalStringOffset ) ); + } else if ( table[i].Type == TimeTableType.vsq ) { + string bd = table[i][list_index].body; + bd = bd.Replace( @"\\", @"\" ); + g.DrawString( bd, + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X + x, position.Y + y + AppManager.Config.VerticalStringOffset ) ); + } else { + g.DrawString( table[i][list_index].body, + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X + x, position.Y + y + AppManager.Config.VerticalStringOffset ) ); + } + if ( x <= m_mousePosition.X && m_mousePosition.X < xend && + y <= m_mousePosition.Y && m_mousePosition.Y < yend ) { + } else { + g.DrawRectangle( _PEN_123_123_123, rc ); + } + } + } + + g.DrawString( table[i].Text, + AppManager.Config.Font.GetFont(), + _BRS_TRACK_NAME, + new PointF( position.X, position.Y + y + AppManager.Config.VerticalStringOffset ) ); + } + } + height = (table.Count + 1) * AppManager.Config.TrackHeight; + } + + /// + /// Draw telop(s) to the specified position using specified Graphics + /// + /// + /// + /// + /// + private void DrawTelop( Graphics g, Point position, out int height, string title ) { + height = (AppManager.MaxTelopLanes + 1) * AppManager.Config.TrackHeight; + Rectangle outline = new Rectangle( position.X, position.Y, pictureBox1.Width, AppManager.Config.TrackHeight ); + g.FillRectangle( new SolidBrush( AppManager.Config.TimeLineTitleColor.Color ), + outline ); + g.DrawString( title, + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X, position.Y + AppManager.Config.VerticalStringOffset ) ); + if ( AppManager.SaveData.TelopListFolded ) { + height = AppManager.Config.TrackHeight; + return; + } + using ( Brush fill = new SolidBrush( AppManager.Config.TimeLineDefaultColor.Color ) ) { + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + int y = (AppManager.SaveData.m_telop_ex2[i].Lane + 1) * AppManager.Config.TrackHeight; + int x = (int)(AppManager.SaveData.m_telop_ex2[i].Start * AppManager.Config.PixelPerSec) - m_startToDrawX; + int xend = (int)(AppManager.SaveData.m_telop_ex2[i].End * AppManager.Config.PixelPerSec) - m_startToDrawX; + Rectangle rc = new Rectangle( + new Point( position.X + x, position.Y + y ), + new Size( xend - x, AppManager.Config.TrackHeight - 1 ) ); + g.FillRectangle( fill, rc ); + g.DrawString( AppManager.SaveData.m_telop_ex2[i].Text.Replace( '\n', ' ' ), + AppManager.Config.Font.GetFont(), + Brushes.Black, + new PointF( position.X + x, position.Y + y + AppManager.Config.VerticalStringOffset ) ); + g.DrawRectangle( _PEN_123_123_123, rc ); + } + } + } + + public string _( string s ) { + return Messaging.GetMessage( s ); + } + + private void m_text_TextChanged( object sender, EventArgs e ) { + Size size = m_text.PreferredSize; + if ( size.Width <= (int)m_text.Tag ) { + size = new Size( (int)m_text.Tag, size.Height ); + } + m_text.Size = size; + property.Editing = new ZorderItem( "", ZorderItemType.telop, m_text_id ); + UpdateEditHandle(); + } + + public void UpdateEditHandle() { + ZorderItem item = property.Selected; + if ( item == null ) { + return; + } + int index = item.Index; + float now = Now; + Rectangle rc; + bool item_fixed; + switch ( item.Type ) { + case ZorderItemType.telop: + Telop telop = AppManager.SaveData[index]; + if ( telop.Start <= now && now <= telop.End ) { + rc = CRectFromIRect( new Rectangle( Common.PointFromPointF( telop.GetPosition( now ) ), + Common.SizeFromSizeF( telop.ImageSize ) ), + telop.GetScale( now ) ); + item_fixed = telop.PositionFixed; + } else { + rc = new Rectangle(); + item_fixed = false; + } + m_editing = new EditingBounds( rc, item_fixed, telop.IsXFixedAt( now ), telop.IsYFixedAt( now ) ); + break; + case ZorderItemType.another: + TimeTable table = AppManager.SaveData.m_group_another[index]; + if ( table.IsOn( now ) ) { + if ( table.Image != null ) { + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table.GetPosition( now ) ), + Common.SizeFromSizeF( table.ImageSize ) ), + Math.Abs( table.Scale ) ), + table.PositionFixed, + table.IsXFixedAt( now ), + table.IsYFixedAt( now ) ); + } + } else { + m_editing = new EditingBounds(); + } + break; + case ZorderItemType.character: + TimeTableGroup table_group = AppManager.SaveData.m_groups_character[index]; + m_editing = new EditingBounds( CRectFromIRect( new Rectangle( Common.PointFromPointF( table_group.GetPosition( now ) ), + table_group.Character.Size ), + Math.Abs( table_group.Scale ) ), + table_group.PositionFixed, + table_group.IsXFixedAt( now ), + table_group.IsYFixedAt( now ) ); + break; + } + previewer.Invalidate(); + } + + /// + /// ビデオ画像上の座標を、PreviewP上の座標に返還します + /// + /// + /// + /// + private Rectangle CRectFromIRect( Rectangle iRect, float scale ) { + Point p = iRect.Location; + Size size = iRect.Size; + int xx, yy, width, height; + xx = p.X; + yy = p.Y; + width = (int)(size.Width * scale); + height = (int)(size.Height * scale); + Point iTopLeft = new Point( xx, yy ); + Point iBottomRight = new Point( xx + width, yy + height ); + Point cTopLeft = CCoordFromI( iTopLeft ); + Point cBottomRight = CCoordFromI( iBottomRight ); + return new Rectangle( cTopLeft, new Size( cBottomRight.X - cTopLeft.X, cBottomRight.Y - cTopLeft.Y ) ); + } + + private void timerPreview_Tick( object sender, EventArgs e ) { + float now; + if ( AppManager.Playing ) { + now = Now; + int nof = (int)(now * AppManager.SaveData.FrameRate); + if ( m_is_repeat_mode ) { + if ( previewer.TrackBarValue < (int)(RepeatStart * AppManager.SaveData.FrameRate) || (int)(RepeatEnd * AppManager.SaveData.FrameRate) < previewer.TrackBarValue ) { +#if DEBUG + Common.DebugWriteLine( "trackBar1.Value,(int)(RepeatStart * s.fps)=" + previewer.TrackBarValue + "," + (int)(RepeatStart * AppManager.SaveData.FrameRate) ); +#endif + Pause(); + previewer.TrackBarValue = (int)(RepeatStart * AppManager.SaveData.FrameRate); + Play(); + return; + } + } else { + if ( nof > previewer.TrackBarMaximum ) { + StopMusic(); + return; + } + } + if ( nof < previewer.TrackBarMinimum || previewer.TrackBarMaximum < nof ) { + StopMusic(); + } else { + previewer.TrackBarValue = nof; + } + } else { + now = Now; + } + + DateTime n = DateTime.Now; + TimeSpan ts = n.Subtract( m_last_ignitted ); + m_last_ignitted = n; + double diff = ts.TotalSeconds; + for ( int i = 0; i < BUF_LEN - 1; i++ ) { + m_buf[i] = m_buf[i + 1] + diff; + } + m_buf[BUF_LEN - 1] = diff; + m_fps = BUF_LEN / m_buf[0]; + correctPosition(); + if ( m_last_key != Keys.None ) { + AppManager.SaveData.m_groups_character[m_realtime_group][m_realtime_track][m_realtime_entry].end = Now; + } + previewer.LabelTimeText = now.ToString( "0.00" ) + "s"; + previewer.Invalidate();// PreviewP.Invalidate(); + pictureBox1.Invalidate(); + //lblTime.Invalidate(); + } + + private int GetDraftStartToDrawX( int scroll_value ) { + float ratio = ((float)(scroll_value) / (float)(hScrollBar1.Maximum - hScrollBar1.Minimum + 1 - hScrollBar1.LargeChange)); + if ( AppManager.SaveData.m_screenWidth - pictureBox1.Width >= 0 ) { + return (int)((AppManager.SaveData.m_screenWidth - pictureBox1.Width) * ratio); + } else { + return 0; + } + } + + /// + /// プレビューとタイムテーブルがシンクロするように、hScrollBar1.Valueを変更します + /// + private void correctPosition() { + if ( menuVisualSync.Checked ) { + if ( AppManager.Config.SyncAtCentre ) { + float now = Now;// t * m_player.Speed * 0.001f; + int draft_start_to_draw_x = (int)(now * AppManager.Config.PixelPerSec) - pictureBox1.Width / 2; + int scroll_value = (int)(draft_start_to_draw_x * (float)(hScrollBar1.Maximum - hScrollBar1.Minimum + 1 - hScrollBar1.LargeChange) / (AppManager.SaveData.m_screenWidth - pictureBox1.Width)); + if ( scroll_value < hScrollBar1.Minimum ) { + scroll_value = hScrollBar1.Minimum; + } else if ( scroll_value > hScrollBar1.Maximum - hScrollBar1.LargeChange ) { + scroll_value = hScrollBar1.Maximum - hScrollBar1.LargeChange; + } + hScrollBar1.Value = scroll_value; + m_startToDrawX = StartToDrawX(); + } else { + int new_value; + int draft_hScrollBar1_Value = hScrollBar1.Value; // hScrollBar1.Valueの候補値。correctPositionが続けて呼ばれるのを防ぐため。 + int draft_start_to_draw_x = m_startToDrawX; + float t_start = m_startToDrawX / AppManager.Config.PixelPerSec; + float t_end = t_start + pictureBox1.Width / AppManager.Config.PixelPerSec; + float band_width = (t_end - t_start) * SIDE_WIDTH; + float now = Now; + int count = 0; + while ( t_end - band_width < now || now < t_start ) { // 次のpreviewTimer.TickでcorrectPositionが呼ばれないように。 + count++; + if ( count > 100 ) { + break; + } + if ( t_end - band_width < now ) { + // 次の画面へスクロールする必要がある。 + new_value = draft_hScrollBar1_Value + (int)((t_end - t_start - band_width) * AppManager.Config.PixelPerSec); + if ( new_value <= hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange ) { + draft_hScrollBar1_Value = new_value; + } else { + draft_hScrollBar1_Value = hScrollBar1.Maximum + 1 - hScrollBar1.LargeChange; + } + draft_start_to_draw_x = GetDraftStartToDrawX( draft_hScrollBar1_Value ); + } else if ( now < t_start ) { + // 前の画面へスクロールする必要がある + new_value = draft_hScrollBar1_Value - (int)((t_end - t_start - band_width) * AppManager.Config.PixelPerSec); + if ( new_value >= hScrollBar1.Minimum ) { + draft_hScrollBar1_Value = new_value; + } else { + draft_hScrollBar1_Value = hScrollBar1.Minimum; + } + draft_start_to_draw_x = GetDraftStartToDrawX( draft_hScrollBar1_Value ); + } + t_start = draft_start_to_draw_x / AppManager.Config.PixelPerSec; + t_end = t_start + pictureBox1.Width / AppManager.Config.PixelPerSec; + band_width = (t_end - t_start) * SIDE_WIDTH; + now = Now; + } + hScrollBar1.Value = draft_hScrollBar1_Value; + m_startToDrawX = StartToDrawX(); + } + } + } + + private void UpdateScreenCore() { + timerPreview_Tick( null, null ); + Application.DoEvents(); + } + + private void UpdateScreen() { + while ( true ) { + this.Invoke( new ForceScreenUpdateDelegate( UpdateScreenCore ) ); + Application.DoEvents(); + } + } + + private void Play() { + m_editing_item = null; + m_editing = new EditingBounds(); + + Size size = AppManager.SaveData.m_movieSize; + previewer.PlayPauseText = _( "Pause" ); + m_current_frame = previewer.TrackBarValue; + initializeFirstEntry(); + + bool ret = m_player.PlayFrom( ((double)m_current_frame) / AppManager.SaveData.FrameRate ); +#if DEBUG + Common.DebugWriteLine( "m_current_frame=" + m_current_frame ); + Common.DebugWriteLine( "AppManager.SaveData.FrameRate=" + AppManager.SaveData.FrameRate ); +#endif + m_started_date = DateTime.Now; + //timerPreview.Enabled = true; + m_preview_thread = new Thread( new ThreadStart( this.UpdateScreen ) ); + m_preview_thread.Priority = ThreadPriority.BelowNormal; + m_preview_thread.Start(); + m_started_date = m_started_date.AddSeconds( -Now / (m_player.Speed) ); + + //m_fit_centre_a = 3f * (Now * m_config.PIXEL_PER_SEC - m_startToDrawX - pictureBox1.Width / 2) / (FIT_CENTER_BREND_TIME * FIT_CENTER_BREND_TIME * FIT_CENTER_BREND_TIME); + //m_fit_centre_init_starttodrawx = m_startToDrawX; +#if DEBUG + //Common.DebugWriteLine( "Play; m_fit_centre_a=" + m_fit_centre_a ); +#endif + + AppManager.Playing = true; + if ( menuEditRealTime.Checked ) { + pictureBox1.Focus(); + } + m_rcHilight = new Rectangle(); + } + + private void Pause() { + pauseMusic(); + UpdateGridList(); + } + + private void pauseMusic() { + StopPauseCore(); + m_player.Pause(); + } + + /// + /// 検索開始インデックスの値をすべて0にそろえます。 + /// + public void initializeFirstEntry() { + for ( int track = 0; track < AppManager.SaveData.m_group_another.Count; track++ ) { + AppManager.SaveData.m_group_another[track].Value = 0; + } + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + for ( int track = 0; track < AppManager.SaveData.m_groups_character[group].Count; track++ ) { + AppManager.SaveData.m_groups_character[group][track].Value = 0; + } + } + for ( int track = 0; track < AppManager.SaveData.m_group_plugin.Count; track++ ) { + AppManager.SaveData.m_group_plugin[track].Value = 0; + } + } + + public void StopPauseCore() { + previewer.PlayPauseText = _( "Play" ); + if ( m_preview_thread != null ) { + m_preview_thread.Abort(); + m_preview_thread = null; + } + AppManager.Playing = false; + } + + private void StopMusic() { + StopPauseCore(); + m_player.Stop(); + previewer.TrackBarValue = 0; + } + + /// + /// PreviewP上の位置座標から、対応する画像の位置座標を求めます + /// + /// + /// + private Point ICoordFromC( Point cCoord ) { + int x = cCoord.X; + int y = cCoord.Y; + float base_x, base_y; + float scale; + GetScaleAndOrigin( out base_x, out base_y, out scale ); + x = (int)(x / scale + base_x); + y = (int)(y / scale + base_y); + return new Point( x, y ); + } + + private Point CCoordFromI( PointF iCoord ) { + float x = iCoord.X; + float y = iCoord.Y; + float base_x, base_y; + float scale; + GetScaleAndOrigin( out base_x, out base_y, out scale ); + x = (x - base_x) * scale; + y = (y - base_y) * scale; + return new Point( (int)x, (int)y ); + } + + /// + /// 画面の左上の座標を、画像の座標系で見たときの座標に変換します + /// + /// + /// + /// + private void GetScaleAndOrigin( out float origin_x, out float origin_y, out float scale ) { + if ( previewer.PreviewSizeMode == PictureBoxSizeMode.CenterImage ) { + scale = 1.0f; + origin_x = (previewer.Image.Width - previewer.PreviewWidth) / 2f; + origin_y = (previewer.Image.Height - previewer.PreviewHeight) / 2f; + } else { + float aspecto_image = ((float)previewer.Image.Width) / ((float)previewer.Image.Height); + float aspecto_control = ((float)previewer.PreviewWidth) / ((float)previewer.PreviewHeight); + if ( aspecto_control > aspecto_image ) { + scale = ((float)previewer.PreviewHeight) / ((float)previewer.Image.Height); + origin_x = (previewer.Image.Width * scale - previewer.PreviewWidth) / 2f / scale; + origin_y = 0; + } else { + scale = ((float)previewer.PreviewWidth) / ((float)previewer.Image.Width); + origin_x = 0; + origin_y = (previewer.Image.Height * scale - previewer.PreviewHeight) / 2f / scale; + } + } + } + + private void ShowDialogCore() { + using ( AviOutput aviOutput = new AviOutput( m_is_rawmode ) ) { + if ( aviOutput.ShowDialog() == DialogResult.OK ) { + AviWriting = true; + m_avi_cancel = false; + AviOutputArguments args = aviOutput.Arguments; + bgWorkAvi.RunWorkerAsync( args ); + } + } + } + + private void ChangeFormTitle( string encoder_type, int percent, int current_frame, int max_frames ) { + this.Text = encoder_type + " " + _( "Progress" ) + " " + percent + "% [" + current_frame + "/" + max_frames + "]"; + } + + private void FFMpegOutputRead( object start_args ) { + // frame= 151 fps= 7 q=12.5 Lsize= 568kB time=5.0 bitrate= 930.6kbits/s + long max_frames = 1; + if ( start_args is long ) { + max_frames = (long)start_args; + } + StreamReader reader = this.m_ffmpeg.StandardError;//.StandardOutput; + string line = ""; + while ( !this.m_ffmpeg.HasExited ) { + char ch = (char)reader.Read(); + if ( char.IsControl( ch ) ) { + if ( line.StartsWith( "frame=" ) ) { + line = line.Substring( 6 ); // line=" 151 fps= 7 q=12.5 Lsize= 568kB time=5.0 bitrate= 930.6kbits/s" + line = line.Replace( " ", "" );// line="151fps=7q=12.5Lsize=568kBtime=5.0bitrate=930.6kbits/s" + string[] spl = line.Split( "fps=".ToCharArray(), 2 ); + if ( spl.Length > 0 ) { + line = spl[0]; // s="151" + line = line.Trim(); + int current_frame = 1; + int i; + if ( int.TryParse( line, out i ) ) { + current_frame = i; + } + int percent = (int)(current_frame / (float)max_frames * 100f); + this.Invoke( new ChangeTitleTextDelegate( this.ChangeFormTitle ), new object[] { "ffmpeg", percent, current_frame, (int)max_frames } ); + } + } + line = ""; + } else { + line += ch.ToString(); + } + if ( m_avi_cancel ) { + this.m_ffmpeg.Kill(); + m_avi_cancel = false; + } + } + reader.Close(); + } + + private void MEncoderOutputRead( object start_args ) { + long max_frames = 1; + if ( start_args is long ) { + max_frames = (long)start_args; + } + StreamReader reader = this.m_mencoder.StandardOutput; + string line = ""; + while ( !this.m_mencoder.HasExited ) { + char ch = (char)reader.Read(); + if ( char.IsControl( ch ) ) { + if ( line.StartsWith( "Pos:" ) ) { + line = line.Substring( 4 ); // 1.4s 42f (13%) 3.04fps Trem: 1min 1mb A-V:0.000 [1516:0] + line = line.Replace( " ", "" );//1.4s42f(13%)3.04fpsTrem:1min1mbA-V:0.000[1516:0] + string[] spl = line.Split( "f".ToCharArray(), 2 ); + if ( spl.Length > 0 ) { + line = spl[0]; // s="1.4s42" + spl = line.Split( "s".ToCharArray(), 2 ); + if ( spl.Length > 1 ) { + line = spl[1]; // line="42" + int current_frame = 1; + int i; + if ( int.TryParse( line, out i ) ) { + current_frame = i; + } + int percent = (int)(current_frame / (float)max_frames * 100f); + this.Invoke( new ChangeTitleTextDelegate( this.ChangeFormTitle ), new object[] { "mencoder", percent, current_frame, (int)max_frames } ); + } + } + } + line = ""; + } else { + line += ch.ToString(); + } + //mencoderが出力する進捗の形式 + //Pos: 1.4s 42f (13%) 3.04fps Trem: 1min 1mb A-V:0.000 [1516:0] + if ( m_avi_cancel ) { + this.m_mencoder.Kill(); + m_avi_cancel = false; + } + } + reader.Close(); + } + + /// + /// m_curveとproperty1のリストボックスの中身を更新します + /// + public void UpdateObjectList() { + List adding = new List(); + bool exist = false; + ZorderItem zi = property.Editing; + foreach ( ZorderItem item in AppManager.SaveData.GetZorderItemEnumerator() ) { + if ( zi != null ) { + if ( zi.Type == item.Type && zi.Index == item.Index ) { + exist = true; + } + } + if ( item.Type == ZorderItemType.character ) { + int i = item.Index; + float start = 0f; + string[] titles = new string[] { start.ToString(), "character", AppManager.SaveData.m_groups_character[i].Text }; + ListViewItem add_item = new ListViewItem( titles ); + item.Start = start; + add_item.Tag = (ZorderItem)item.Clone(); + adding.Add( add_item ); + } else if ( item.Type == ZorderItemType.another ) { + int i = item.Index; + float start = AppManager.SaveData.m_group_another.GetFirstOn( i ); + string[] titles = new string[] { start.ToString(), + "another", + AppManager.SaveData.m_group_another[i].Text }; + ListViewItem add_item = new ListViewItem( titles ); + item.Start = start; + add_item.Tag = (ZorderItem)item.Clone(); + adding.Add( add_item ); + } else if ( item.Type == ZorderItemType.telop ) { + int i = item.Index; + float start = AppManager.SaveData[i].Start; + string[] titles = new string[]{ start.ToString(), + "telop", + AppManager.SaveData[i].Text }; + ListViewItem add_item = new ListViewItem( titles ); + item.Start = start; + add_item.Tag = (ZorderItem)item.Clone(); + adding.Add( add_item ); + } + } + property.ListView.Items.Clear(); + property.ListView.Items.AddRange( adding.ToArray() ); + property.Sort(); + if ( !exist ) { + property.Editing = null; + property.SelectedObject = null; + } + + m_curve.comboObjects.Items.Clear(); + for ( int i = 0; i < AppManager.SaveData.m_groups_character.Count; i++ ) { + m_curve.comboObjects.Items.Add( new TagForTreeNode( ZorderItemType.character, i ) ); + } + for ( int i = 0; i < AppManager.SaveData.m_group_another.Count; i++ ) { + m_curve.comboObjects.Items.Add( new TagForTreeNode( ZorderItemType.another, i ) ); + } + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + m_curve.comboObjects.Items.Add( new TagForTreeNode( ZorderItemType.telop, AppManager.SaveData.m_telop_ex2[i].ID ) ); + } + + } + + /// + /// マウスの現在位置を元に、ハイライトするべき部分のRectangleを取得します + /// mouse_positionまたはX, Yには、pictureBox1上のマウス位置を与えなければならない + /// + /// + /// ハイライトするべき範囲を表すRectangle。Paintイベントで素直に描けばOK + private Rectangle GetHilightRect( int X, int Y ) { + int start_to_draw_x = m_startToDrawX;// StartToDrawX; + int start_to_draw_y = m_startToDrawY;// StartToDrawY; + Item clicked = GetGroupItem( X + start_to_draw_x, Y + start_to_draw_y ); + TimeTableType type = clicked.type; + int group = clicked.group; + int track = clicked.track; + int row_index = clicked.row_index; + if ( group < 0 ) { + return new Rectangle(); + } + bool vsq_fixed = menuVisualVsqTrack.Checked; + if ( track < 0 ) { + int group_tracks = 0; + if ( clicked.type == TimeTableType.telop ) { + if ( AppManager.SaveData.TelopListFolded ) { + group_tracks = 0; + } else { + group_tracks = AppManager.MaxTelopLanes; + } + } else { + if ( AppManager.SaveData[clicked.type, group].Folded ) { + group_tracks = 0; + } else { + group_tracks = AppManager.SaveData[clicked.type, group].Count; + } + } + if ( clicked.type == TimeTableType.vsq && vsq_fixed ) { + return new Rectangle( 0, row_index * AppManager.Config.TrackHeight, pictureBox1.Width, (group_tracks + 1) * AppManager.Config.TrackHeight ); + } else { + return new Rectangle( 0, row_index * AppManager.Config.TrackHeight - start_to_draw_y, pictureBox1.Width, (group_tracks + 1) * AppManager.Config.TrackHeight ); + } + } else { + int y = row_index * AppManager.Config.TrackHeight - start_to_draw_y; + Rectangle current; + switch ( clicked.type ) { + case TimeTableType.vsq: + int yy = y + m_startToDrawY; + for ( int entry = 0; entry < AppManager.SaveData.m_group_vsq[track].Count; entry++ ) { + int x = (int)(AppManager.SaveData.m_group_vsq[track][entry].begin * AppManager.Config.PixelPerSec) - start_to_draw_x; + int xend = (int)(AppManager.SaveData.m_group_vsq[track][entry].end * AppManager.Config.PixelPerSec) - start_to_draw_x; + if ( vsq_fixed ) { + current = new Rectangle( x, yy, xend - x, AppManager.Config.TrackHeight ); + if ( AppManager.IsInRectangle( new Point( X, Y ), current ) ) { + return current; + } + } else { + current = new Rectangle( x, y, xend - x, AppManager.Config.TrackHeight ); + if ( AppManager.IsInRectangle( new Point( X, Y ), current ) ) { + return current; + } + } + } + if ( vsq_fixed ) { + return new Rectangle( 0, yy, pictureBox1.Width, AppManager.Config.TrackHeight ); + } else { + return new Rectangle( 0, y, pictureBox1.Width, AppManager.Config.TrackHeight ); + } + case TimeTableType.character: + case TimeTableType.another: + case TimeTableType.plugin: + for ( int entry = 0; entry < AppManager.SaveData[type, group][track].Count; entry++ ) { + int x = (int)(AppManager.SaveData[type, group][track][entry].begin * AppManager.Config.PixelPerSec) - start_to_draw_x; + int xend = (int)(AppManager.SaveData[type, group][track][entry].end * AppManager.Config.PixelPerSec) - start_to_draw_x; + current = new Rectangle( x, y, xend - x, AppManager.Config.TrackHeight ); + if ( AppManager.IsInRectangle( new Point( X, Y ), current ) ) { + return current; + } + } + return new Rectangle( 0, y, pictureBox1.Width, AppManager.Config.TrackHeight ); + case TimeTableType.telop: + for ( int i = 0; i < AppManager.SaveData.m_telop_ex2.Count; i++ ) { + if ( AppManager.SaveData.m_telop_ex2[i].ID == clicked.entry ) { + int x = (int)(AppManager.SaveData.m_telop_ex2[i].Start * AppManager.Config.PixelPerSec) - start_to_draw_x; + int xend = (int)(AppManager.SaveData.m_telop_ex2[i].End * AppManager.Config.PixelPerSec) - start_to_draw_x; + return new Rectangle( x, y, xend - x, AppManager.Config.TrackHeight ); + } + } + return new Rectangle(); + default: + return new Rectangle(); + } + + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Form1_EventHandler.cs b/trunk/LipSync/LipSync/Editor/Form1_EventHandler.cs new file mode 100644 index 0000000..d267851 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Form1_EventHandler.cs @@ -0,0 +1,1183 @@ +/* + * Form1_EventHandler.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +namespace LipSync { + + partial class Form1 : Form { + /// + /// テロップを追加します + /// + /// + /// + private void h_addTelop( object sender, EventArgs e ) { + if ( m_text_edit && m_text != null ) { + Command run = Command.GCommandEditTelop( m_text_id, AppManager.SaveData[m_text_id] ); + AppManager.SaveData[m_text_id].Text = m_text_original; + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + + m_text.Dispose(); + m_text = null; + m_text_edit = false; + } + + int id = AppManager.SaveData.GetNextID(); + Telop work = new Telop( id ); + work.Text = "(none)"; + work.Start = Now; + work.End = work.Start + 1f; + Command run2 = Command.GCommandAddTelop( work ); + Command inv = AppManager.SaveData.Execute( run2 ); + Telop.DecideLane( AppManager.SaveData.m_telop_ex2 ); + property.Editing = new ZorderItem( work.Text, ZorderItemType.telop, id ); + AppManager.Register( inv ); + UpdateObjectList(); + UpdateEditHandle(); + SetVScrollRange(); + AppManager.Edited = true; + } + + /// + /// エントリのON/OFFを反転してコピーします + /// + /// + /// + void h_copyTimeTableInvert( object sender, EventArgs e ) { + int group = m_clicked.group; + int track = m_clicked.track; + if ( m_copied_timetable != null ) { + m_copied_timetable.Dispose(); + m_copied_timetable = null; + } + TimeTableType type = m_clicked.type; + if( type != TimeTableType.vsq && type != TimeTableType.character && type != TimeTableType.another && type != TimeTableType.plugin ){ + return; + } + TimeTable table = (TimeTable)AppManager.SaveData[m_clicked.type, m_clicked.group][m_clicked.track].Clone(); + table.Type = TimeTableType.another; + m_copied_timetable = (TimeTable)table.Clone(); + m_copied_timetable.Clear(); + for ( int i = 0; i < table.Count; i++ ) { + if ( i > 0 ) { + m_copied_timetable.Add( new TimeTableEntry( table[i - 1].end, table[i].begin, "" ) ); + } else { + if ( table[0].begin > 0f ) { + m_copied_timetable.Add( new TimeTableEntry( 0f, table[0].begin, "" ) ); + } + } + } + if ( table[table.Count - 1].end < AppManager.SaveData.m_totalSec ) { + m_copied_timetable.Add( new TimeTableEntry( table[table.Count - 1].end, AppManager.SaveData.m_totalSec, "" ) ); + } + } + + private void h_shiftEntries( object sender, EventArgs e ) { + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + TimeTableType type = m_clicked.type; + if ( type != TimeTableType.vsq && + type != TimeTableType.character && + type != TimeTableType.another && + type != TimeTableType.plugin && + type != TimeTableType.telop ) { + return; + } + using ( InputBox ib = new InputBox( _( "Shift all time-tables" ), _( "Input shift time in second (you can enter minus value)" ) ) ) { + if ( ib.ShowDialog() == DialogResult.OK ) { + float shift; + try { + shift = float.Parse( ib.rText ); + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + return; + } + Command run = Command.GCommandShiftTimeTable( type, (type == TimeTableType.character ? group : track), shift ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + + private void h_splitEntry( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + if ( type != TimeTableType.character && + type != TimeTableType.another && + type != TimeTableType.plugin && + type != TimeTableType.telop ) { + return; + } + if ( type == TimeTableType.telop ) { + Telop edit = (Telop)AppManager.SaveData[entry].Clone(); + float split_position = SecFromXCoord( m_mousePosition.X ); + edit.End = split_position; + Telop adding = (Telop)AppManager.SaveData[entry].Clone(); + adding.Start = split_position; + Command run = Command.GCommandEditTelop( entry, edit ); + run.child = Command.GCommandAddTelop( adding ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + TimeTable table = (TimeTable)AppManager.SaveData[type, group][track].Clone(); + float begin = SecFromXCoord( m_mousePosition.X ); + float buf = table[entry].end; + table[entry].end = begin; + table.Add( new TimeTableEntry( begin, buf, table[entry].body ) ); + table.Sort(); + Command run = Command.GCommandEditTimeTable( m_clicked.type, group, track, table ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + table.Dispose(); + } + } + + /// + /// テキストからのインポート + /// + /// + /// + private void h_importFromText( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + using ( OpenFileDialog dlg = new OpenFileDialog() ) { + try { + dlg.Filter = _( "Text file(*.txt)|*.txt" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Text file(*.txt)|*.txt|All Files(*.*)|*.*"; + } + if ( dlg.ShowDialog() == DialogResult.OK ) { + string file = dlg.FileName; + // 編集対象をコピー + if ( type != TimeTableType.vsq && type != TimeTableType.another && type != TimeTableType.character && type != TimeTableType.plugin ) { + return; + } + TimeTableGroup table = (TimeTableGroup)AppManager.SaveData[type, group].Clone(); + //int target_group = -1; + using ( StreamReader sr = new StreamReader( file ) ) { + float begin, end; + string line; + while ( sr.Peek() > -1 ) { + line = sr.ReadLine(); + string[] spl = line.Split( new char[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries ); + if ( spl.Length >= 2 ) { + if ( m_clicked.type == TimeTableType.vsq ) { + try { + begin = float.Parse( spl[0] ); + end = float.Parse( spl[1] ); + } catch { + continue; + } + string body = ""; + if ( spl.Length >= 3 ) { + body = spl[2]; + } + table.Interrup( track, begin, end, body ); + } else { + try { + begin = float.Parse( spl[0] ); + end = float.Parse( spl[1] ); + table.Interrup( track, begin, end ); + } catch { + } + } + } + } + } + Command run = Command.GCommandEditGroup( m_clicked.type, group, table ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + table.Dispose(); + table = null; + } + } + } + + /// + /// テキストへの出力 + /// + /// + /// + private void h_exportToText( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + using ( SaveFileDialog dlg = new SaveFileDialog() ) { + try { + dlg.Filter = _( "Text file(*.txt)|*.txt" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Text file(*.txt)|*.txt|All Files(*.*)|*.*"; + } + dlg.AddExtension = true; + if ( dlg.ShowDialog() == DialogResult.OK ) { + string file = dlg.FileName; + TimeTable table = null; + using ( StreamWriter sw = new StreamWriter( file ) ) { + table = AppManager.SaveData[type, group][track]; + if ( table == null ) { + return; + } + for ( int entry = 0; entry < table.Count; entry++ ) { + if ( m_clicked.type == TimeTableType.vsq ) { + sw.WriteLine( table[entry].begin + "\t" + table[entry].end + "\t" + table[entry].body ); + } else { + sw.WriteLine( table[entry].begin + "\t" + table[entry].end ); + } + } + } + } + } + + } + + /// + /// エントリの貼付け + /// + /// + /// + private void h_pasteEntry( object sender, EventArgs e ) { + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + float begin = SecFromXCoord( m_mousePosition.X ); + switch ( m_clicked.type ) { + case TimeTableType.another: + if ( m_copied.type == TimeTableType.telop ) { + TimeTableEntry ent = new TimeTableEntry(); + ent.end = begin + m_copied_telop.End - m_copied_telop.Start; + ent.begin = begin; + ent.body = AppManager.SaveData.m_group_another[track].Text; + TimeTableGroup ttg = (TimeTableGroup)AppManager.SaveData.m_group_another.Clone(); + ttg.Interrup( track, ent.begin, ent.end, ent.body ); + Command run = Command.GCommandEditTimeTable( TimeTableType.another, -1, track, ttg[track] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + using ( TimeTableEntry ent = (TimeTableEntry)m_copied_entry.Clone() ) + using ( TimeTableGroup tablegroup = (TimeTableGroup)AppManager.SaveData.m_group_another.Clone() ) { + ent.end = begin + (ent.end - ent.begin); + ent.begin = begin; + ent.body = AppManager.SaveData.m_group_another[track].Text; + tablegroup.Interrup( track, ent.begin, ent.end, ent.body ); + Command run = Command.GCommandEditTimeTable( TimeTableType.another, -1, track, tablegroup[track] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + break; + case TimeTableType.character: + if ( m_copied.type == TimeTableType.telop ) { + TimeTableEntry tte = new TimeTableEntry(); + tte.end = begin + m_copied_telop.End - m_copied_telop.Start; + tte.begin = begin; + TimeTableGroup ttg = (TimeTableGroup)AppManager.SaveData.m_groups_character[group].Clone(); + ttg.Interrup( track, tte.begin, tte.end ); + Command run = Command.GCommandEditGroup( TimeTableType.character, group, ttg ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + using ( TimeTableEntry ent = (TimeTableEntry)m_copied_entry.Clone() ) + using ( TimeTableGroup tablegroup = (TimeTableGroup)AppManager.SaveData.m_groups_character[group].Clone() ) { + ent.end = begin + (ent.end - ent.begin); + ent.begin = begin; + tablegroup.Interrup( track, ent.begin, ent.end ); + Command run = Command.GCommandEditGroup( TimeTableType.character, group, tablegroup ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + break; + case TimeTableType.plugin: + if ( m_copied.type == TimeTableType.telop ) { + TimeTableEntry tte = new TimeTableEntry(); + tte.end = begin + m_copied_telop.End - m_copied_telop.Start; + tte.begin = begin; + TimeTableGroup ttg = (TimeTableGroup)AppManager.SaveData.m_group_plugin.Clone(); + ttg.Interrup( track, tte.begin, tte.end ); + Command run = Command.GCommandEditTimeTable( TimeTableType.plugin, -1, track, ttg[track] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + using ( TimeTableEntry ent = (TimeTableEntry)m_copied_entry.Clone() ) + using ( TimeTableGroup tablegroup = (TimeTableGroup)AppManager.SaveData.m_group_plugin.Clone() ) { + ent.end = begin + (ent.end - ent.begin); + ent.begin = begin; + if ( m_copied.track == m_clicked.track && m_copied.type == TimeTableType.plugin ) { + ent.body = m_copied_entry.body; + } else { + ent.body = ""; + } + tablegroup.Interrup( track, ent.begin, ent.end, ent.body ); + Command run = Command.GCommandEditTimeTable( TimeTableType.plugin, -1, track, tablegroup[track] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + break; + case TimeTableType.telop: + if ( m_copied.type == TimeTableType.telop ) { + Telop edited = (Telop)m_copied_telop.Clone(); + edited.End = begin + m_copied_telop.End - m_copied_telop.Start; + edited.Start = begin; + Command run = Command.GCommandAddTelop( edited ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + break; + } + UpdateObjectList(); + } + + /// + /// エントリの切取 + /// + /// + /// + private void h_cutEntry( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + if ( type == TimeTableType.telop ) { + m_copied_telop = (Telop)AppManager.SaveData[entry].Clone(); + m_copied = m_clicked; + Command run = Command.GCommandDeleteTelop( m_copied_telop ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } else { + m_copied_entry = (TimeTableEntry)AppManager.SaveData[type, group][track][entry].Clone(); + m_copied = m_clicked; + Command run = Command.GCommandDeleteTimeTableEntry( type, group, track, AppManager.SaveData[type, group][track][entry] ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + UpdateObjectList(); + AppManager.Edited = true; + } + + /// + /// エントリのコピー + /// + /// + /// + private void h_copyEntry( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + if ( type == TimeTableType.telop ) { + m_copied_telop = (Telop)AppManager.SaveData[entry].Clone(); + } else { + m_copied_entry = (TimeTableEntry)AppManager.SaveData[type, group][track][entry].Clone(); + } + m_copied = m_clicked; + } + + /// + /// タイムラインのグループごとの折りたたみを行う + /// + /// + /// + private void h_foldAll( object sender, EventArgs e ) { + AppManager.SaveData.m_group_vsq.Folded = true; + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + AppManager.SaveData.m_groups_character[group].Folded = true; + } + AppManager.SaveData.m_group_another.Folded = true; + AppManager.SaveData.m_group_plugin.Folded = true; + AppManager.SaveData.TelopListFolded = true; + this.Invalidate(); + } + + /// + /// 折りたたまれたタイムライン・グループを展開する + /// + /// + /// + private void h_expandAll( object sender, EventArgs e ) { + AppManager.SaveData.m_group_vsq.Folded = false; + for ( int group = 0; group < AppManager.SaveData.m_groups_character.Count; group++ ) { + AppManager.SaveData.m_groups_character[group].Folded = false; + } + AppManager.SaveData.m_group_another.Folded = false; + AppManager.SaveData.m_group_plugin.Folded = false; + AppManager.SaveData.TelopListFolded = false; + SetVScrollRange(); + this.Invalidate(); + } + + /// + /// 選択されたエントリを可能な限り拡張する + /// + /// + /// + private void h_expandEntry( object sender, EventArgs e ) { + PointF px; + float time = SecFromXCoord( m_mousePosition.X ); + if ( m_clicked.type == TimeTableType.character ) { + px = GetEntryLimit( m_clicked, time, true ); + } else { + px = GetEntryLimitSingle( m_clicked, time, true ); + } + Command run, inv; + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + TimeTableEntry item = new TimeTableEntry( px.X, px.Y, "" ); + if ( type != TimeTableType.another && type != TimeTableType.character && type != TimeTableType.plugin ) { + return; + } + if ( type == TimeTableType.plugin ) { + item.body = ""; + } else { + item.body = AppManager.SaveData[type, group][track].Text; + } + run = Command.GCommandEditTimeTableEntry( type, group, track, entry, item ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + + /// + /// タイムテーブルの貼付け + /// + /// + /// + private void h_pasteTimeTable( object sender, EventArgs e ) { + if ( m_copied_timetable == null ) { + return; + } + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + + bool overwrite = false; + TimeTableGroup tmp; + TimeTableType command_target; + int target_group; + if ( AppManager.SaveData[type, group][track].Count > 0 ) { + overwrite = true; + } + command_target = type; + if ( type == TimeTableType.character ) { + target_group = group; + } else { + target_group = -1; + } + tmp = (TimeTableGroup)AppManager.SaveData[type, group].Clone(); + + if ( overwrite ) { + using ( PasteModeDialog dlg = new PasteModeDialog() ) { + dlg.ShowDialog(); + PasteModeDialogResult result = dlg.DialogResult; + switch ( result ) { + case PasteModeDialogResult.Cancel: + tmp.Dispose(); + tmp = null; + return; + case PasteModeDialogResult.Overwrite: + tmp[track].Clear(); + break; + } + } + } + + for ( int entry = 0; entry < m_copied_timetable.Count; entry++ ) { + if ( command_target == TimeTableType.vsq && m_copied_timetable.Type == TimeTableType.vsq ) { + tmp.Interrup( + track, + m_copied_timetable[entry].begin, + m_copied_timetable[entry].end, + m_copied_timetable[entry].body ); + } else { + tmp.Interrup( track, m_copied_timetable[entry].begin, m_copied_timetable[entry].end ); + } + } + Command run = Command.GCommandEditGroup( command_target, target_group, tmp ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + + if ( tmp != null ) { + tmp.Dispose(); + tmp = null; + } + this.Invalidate(); + } + + /// + /// タイムテーブルのコピー + /// + /// + /// + private void h_copyTimeTable( object sender, EventArgs e ){ + int group = m_clicked.group; + int track = m_clicked.track; + if ( m_copied_timetable != null ) { + m_copied_timetable.Dispose(); + m_copied_timetable = null; + } + m_copied_timetable = (TimeTable)AppManager.SaveData[m_clicked.type, group][track].Clone(); + } + + /// + /// 表示倍率の設定 + /// + /// + /// + private void h_setScale( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + if ( type != TimeTableType.character && type != TimeTableType.another ) { + return; + } + using ( InputBox ib = new InputBox( _( "Scale setting" ), _( "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" ) ) ) { + float sscale; + switch ( m_clicked.type ) { + case TimeTableType.character: + sscale = AppManager.SaveData.m_groups_character[group].Scale; + break; + case TimeTableType.another: + sscale = AppManager.SaveData.m_group_another[track].Scale; + break; + default: + return; + } + ib.rText = sscale.ToString(); + if ( ib.ShowDialog() == DialogResult.OK ) { + //float scale = 1.0f; + try { + sscale = float.Parse( ib.rText ); + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), _( "Error" ), MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + return; + } + Command run = Command.GCommandChangeScale( type, group, track, sscale ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + UpdateEditHandle(); + } + } + } + + /// + /// クリックされたトラック上のエントリをクリアします + /// + /// + /// + private void h_clearEntry( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + if ( MessageBox.Show( _( "...clearing entries of selected time-table.\nWould you like to continue?" ), _( "Confirmation" ), MessageBoxButtons.OKCancel, MessageBoxIcon.Question ) == DialogResult.OK ) { + if ( type == TimeTableType.telop ) { + Telop[] edit = AppManager.SaveData.m_telop_ex2.ToArray(); + Command run = Command.GCommandDeleteTelopRange( edit ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + using ( TimeTable table = (TimeTable)AppManager.SaveData[type, group][track].Clone() ) { + table.Clear(); + Command run = Command.GCommandEditTimeTable( type, group, track, table ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + } + + private void h_editEntry( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + if ( type != TimeTableType.character && + type != TimeTableType.another && + type != TimeTableType.plugin && + type != TimeTableType.telop ) { + return; + } + PointF bound; + float begin, end; + if ( type == TimeTableType.telop ) { + begin = AppManager.SaveData[entry].Start; + end = AppManager.SaveData[entry].End; + } else { + begin = AppManager.SaveData[type, group][track][entry].begin; + end = AppManager.SaveData[type, group][track][entry].end; + } + if ( type == TimeTableType.character ) { + bound = GetEntryLimit( m_clicked, (begin + end) / 2f, true ); + } else if ( type == TimeTableType.telop ) { + bound = new PointF( 0f, AppManager.SaveData.m_totalSec ); + } else { + bound = GetEntryLimitSingle( m_clicked, (begin + end) / 2f, true ); + } + using ( EditEntry eden = new EditEntry( begin, end, bound.X, bound.Y ) ) { + if ( eden.ShowDialog() == DialogResult.OK ) { + if ( type == TimeTableType.telop ) { + Telop edited = (Telop)AppManager.SaveData[entry].Clone(); + edited.Start = eden.Start; + edited.End = eden.End; + Command run = Command.GCommandEditTelop( entry, edited ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } else { + using ( TimeTableEntry item = new TimeTableEntry( eden.Start, eden.End, AppManager.SaveData[type, group][track][entry].body ) ) { + Command run = Command.GCommandEditTimeTableEntry( type, group, track, entry, item ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + } + } + + private void h_pluginSetting( object sender, EventArgs e ) { + ToolStripDropDownItem item = (ToolStripDropDownItem)sender; + string plugin_name = item.Text; + for ( int i = 0; i < AppManager.SaveData.m_plugins_config.Count; i++ ) { + if ( plugin_name == AppManager.SaveData.m_plugins_config[i].ID ) { + string old_config = AppManager.SaveData.m_plugins[i].Instance.Config; + if ( AppManager.SaveData.m_plugins[i].Instance.BaseSetting() == DialogResult.OK ) { + string new_config = AppManager.SaveData.m_plugins[i].Instance.Config; + AppManager.SaveData.m_plugins[i].Instance.Config = old_config; //ちょっとセコイなw + if ( old_config != new_config ) { + Command run = Command.GCommandChangePluginConfig( i, new_config ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.SaveData.m_plugins[i].Instance.Config = new_config; + AppManager.Edited = true; + } + } + break; + } + } + } + + private void h_entrySetting( object sender, EventArgs e ) { + int track = m_clicked.track; + int entry = m_clicked.entry; + string current = AppManager.SaveData.m_group_plugin[track][entry].body; + if ( AppManager.SaveData.m_plugins[track].Instance.EntrySetting( ref current ) == DialogResult.OK ) { + using ( TimeTableEntry tmp = new TimeTableEntry( AppManager.SaveData.m_group_plugin[track][entry].begin, AppManager.SaveData.m_group_plugin[track][entry].end, current ) ) { + Command run = Command.GCommandEditTimeTableEntry( TimeTableType.plugin, -1, track, entry, tmp ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + + /// + /// 目パチを自動で追加します。 + /// + /// + /// + private void h_addWink( object sender, EventArgs e ) { + List titles = new List(); + foreach ( ImageEntry img in AppManager.SaveData.m_groups_character[m_clicked.group].Character ) { + titles.Add( img.title ); + } + using ( Winker winkconfig = new Winker( titles.ToArray(), AppManager.SaveData.m_totalSec ) ) { + if ( winkconfig.ShowDialog() != DialogResult.OK ) { + return; + } + bool randomize = winkconfig.Randomize; + + float interval = winkconfig.WinkInterval; + float begin; + if ( winkconfig.BeginForced ) { + begin = winkconfig.ForcedBegin; + } else { + begin = 0.0f; + } + float end; + if ( winkconfig.EndForced ) { + end = winkconfig.ForcedEnd; + } else { + end = AppManager.SaveData.m_totalSec; + } + string closed = winkconfig.ClosedEye; + string in_between = winkconfig.InBetween; + float close_frames = winkconfig.CloseFrames; + + Random rnd = new Random(); + float total; + if ( begin == 0.0f ) { + total = nextInterval( ref rnd, interval, randomize ); + } else { + total = begin; + } + + //titleがclosedであるImagesのインデクスを検索 + int track = -1; + for ( int i = 0; i < AppManager.SaveData.m_groups_character[m_clicked.group].Count; i++ ) { + if ( AppManager.SaveData.m_groups_character[m_clicked.group][i].Text == closed ) { + track = i; + break; + } + } + if ( track < 0 ) { + winkconfig.Dispose(); + return; + } + + //titleがin_betweenであるImagesのインデクスを検索 + int bet_track = -1; + for ( int i = 0; i < AppManager.SaveData.m_groups_character[m_clicked.group].Count; i++ ) { + if ( AppManager.SaveData.m_groups_character[m_clicked.group][i].Text == in_between ) { + bet_track = i; + break; + } + } + + using ( TimeTableGroup temp = (TimeTableGroup)AppManager.SaveData.m_groups_character[m_clicked.group].Clone() ) { + float unit_frame; + if ( bet_track < 0 ) { + unit_frame = close_frames / AppManager.SaveData.FrameRate; + } else { + unit_frame = close_frames / 2f / AppManager.SaveData.FrameRate; + } + while ( total <= end ) { + temp.Interrup( track, total, total + unit_frame ); + if ( bet_track >= 0 ) { + temp.Interrup( bet_track, total + unit_frame, total + 2f * unit_frame ); + } + total += (close_frames / AppManager.SaveData.FrameRate + nextInterval( ref rnd, interval, randomize )); + } + temp[track].Sort(); + if ( bet_track >= 0 ) { + temp[bet_track].Sort(); + } + Command run = Command.GCommandEditGroup( TimeTableType.character, m_clicked.group, temp ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + this.Invalidate(); + } + } + + /// + /// 新しいトラックを追加します + /// + /// + /// + private void h_addTrack( object sender, EventArgs e ) { + switch ( m_clicked.type ) { + case TimeTableType.another: + using ( TimeTable temp = new TimeTable( "test track", 0, TimeTableType.another, null ) ) { + Command run = Command.GCommandAddTimeTable( TimeTableType.another, -1, AppManager.SaveData.m_group_another.Count, temp ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + AppManager.SaveData.UpdateZorder(); + AppManager.Edited = true; + UpdateObjectList(); + SetVScrollRange(); + break; + } + } + + /// + /// クリックされた位置のトラックが担当する画像を変更します + /// + /// + /// + private void h_setImage( object sender, EventArgs e ) { + int group = m_clicked.group; + int track = m_clicked.track; + if ( group < 0 ) { + return; + } + + switch ( m_clicked.type ) { + case TimeTableType.another: + if ( dialogImage.ShowDialog() == DialogResult.OK ) { + if ( track >= 0 ) { + string file = dialogImage.FileName; + if ( Path.GetExtension( file ).ToLower() == ".avi" ) { + Command run = Command.GCommandSetAvi( track, file ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); +#if DEBUG + Common.DebugWriteLine( "Form1.h_setImage; mode avi" ); +#endif + } else { + Command run = Command.GCommandSetImage( track, new Bitmap( Common.ImageFromFile( dialogImage.FileName ) ) ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); +#if DEBUG + Common.DebugWriteLine( "Form1.h_setImage; mode image" ); +#endif + } + AppManager.Edited = true; + } + } + UpdateEditHandle(); + break; + } + } + + private void h_previewImage( object sender, EventArgs e ) { + int group = m_clicked.group; + int track = m_clicked.track; + if ( group < 0 ) { + return; + } + switch ( m_clicked.type ) { + case TimeTableType.character: + if ( track < 0 ) { + ShowPreviewPictureBox( AppManager.SaveData.m_groups_character[group].Character.DefaultFace, m_mousePosition ); + } else { + string title = AppManager.SaveData[m_clicked.type, group][track].Text; + Character3 ch = AppManager.SaveData.m_groups_character[group].Character; + if ( ch == null ) { + return; + } + List list = new List(); + list.Add( track ); + string tag = ch[title].tag; + foreach ( ImageEntry ie in ch ) { + if ( tag != "" ) { + if ( ie.IsDefault ) { + list.Add( ie.Z ); + } + } else { + if ( ie.IsDefault && (tag != "" && ie.tag == tag) ) { + list.Add( ie.Z ); + } + } + } + /*for ( int i = 0; i < ch.Count; i++ ) { + if ( tag != "" ) { + if ( ch[i].IsDefault ) { + list.Add( i ); + } + } else { + if ( ch[i].IsDefault && (tag != "" && ch[i].tag == tag) ) { + list.Add( i ); + } + } + }*/ + Image img = AppManager.SaveData.m_groups_character[group].Character.Face( list.ToArray() ); + ShowPreviewPictureBox( img, m_mousePosition ); + } + break; + case TimeTableType.another: + if ( track >= 0 ) { + ShowPreviewPictureBox( AppManager.SaveData.m_group_another[track].Image, m_mousePosition ); + //showPreviewPictureBox( s.m_group_another[track].GetImage( 0f ), m_mousePosition ); + } + break; + default: + break; + } + } + + /// + /// time_tableに格納されている歌詞の情報から、口パクトラックを作成し、追加します + /// アンドゥ・リドゥ用の処理はgenMouthFromVsqでやってる。 + /// + /// + /// + private void h_genMouthFromVsq( object sender, EventArgs e ) { + if ( m_clicked.type != TimeTableType.vsq ) { + return; + } + List plugins = new List(); + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + if ( (AppManager.SaveData.m_plugins[i].Instance.Type & Plugin.Constants.LS_TYPE_CHARACTER) == Plugin.Constants.LS_TYPE_CHARACTER ) { + plugins.Add( AppManager.SaveData.m_plugins_config[i].ID ); + } + } + using ( SelectCharacater sc = new SelectCharacater( plugins ) ) { + if ( sc.ShowDialog() == DialogResult.OK ) { + //if ( sc.SaveCharacterConfigOutside ) { + // genMouthFromVsq( s.m_group_vsq[m_clicked.track], sc.Character, true, sc.Path ); + //} else { + GenerateLipsyncFromVsq( AppManager.SaveData.m_group_vsq[m_clicked.track], sc.Character, true ); + //} + AppManager.Edited = true; + SetVScrollRange(); + this.Invalidate(); + } + } + } + + /// + /// vsqファイルから、トラックを読み込みます + /// + /// + /// + private void h_readVsq( object sender, EventArgs e ) { + openVsqDialog.FileName = AppManager.Config.LastVsqPath; + try { + openVsqDialog.Filter = _( "VOCALOID2 Sequence File(*.vsq)|*.vsq" ) + "|" + + _( "UTAU Script File(*.ust)|*.ust" ) + "|" + + _( "All Files(*.*)|*.*" ); + } catch { + openVsqDialog.Filter = "VOCALOID2 Sequence File(*.vsq)|*.vsq|UTAU Script File(*.ust)|*.ust|All Files(*.*)|*.*"; + } + if ( openVsqDialog.ShowDialog() == DialogResult.OK ) { + AppManager.Config.LastVsqPath = openVsqDialog.FileName; + string file_name = openVsqDialog.FileName; + ReadVsq( file_name ); + } + } + + /// + /// + /// + /// + /// + private void h_setVideoSize( object sender, EventArgs e ) { + sizeChange(); + } + + private void h_setImagePosition( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + Point point; + if ( type == TimeTableType.another ) { + point = AppManager.SaveData.m_group_another[m_clicked.track].Position; + } else if ( type == TimeTableType.character ) { + point = AppManager.SaveData.m_groups_character[m_clicked.group].Position; + } else { + return; + } + + using ( SetSize setsize = new SetSize( _( "Image placement" ), "X", "Y", point.X, point.Y ) ) { + if ( setsize.ShowDialog() == DialogResult.OK ) { + Point point_new = new Point( setsize.ResultWidth, setsize.ResultHeight ); + Command run = Command.GCommandSetPosition( type, m_clicked.group, m_clicked.track, point_new ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + + private void h_editCharacter( object sender, EventArgs e ) { + if ( AppManager.SaveData.m_groups_character[m_clicked.group].Character.Type == CharacterType.def ) { + int prev = AppManager.SaveData.m_groups_character[m_clicked.group].Character.Count; + int group = m_clicked.group; + using ( GenerateCharacter gc = new GenerateCharacter( AppManager.SaveData.m_groups_character[group] ) ) { + gc.LastPath = AppManager.Config.LastCharacterPath; + if ( gc.ShowDialog() == DialogResult.OK ) { + AppManager.Config.LastCharacterPath = gc.LastPath; + /*List old = new List(); + for ( int i = 0; i < AppManager.SaveData.m_groups_character[group].Count; i++ ) { + old.Add( (TimeTable)AppManager.SaveData.m_groups_character[group][i].Clone() ); + } + TimeTableGroup ttg = (TimeTableGroup)AppManager.SaveData.m_groups_character[group].Clone(); + ttg.list.Clear(); + foreach ( ImageEntry ie in gc.EditedResult.Character ) { + for ( int j = 0; j < old.Count; j++ ) { + if ( ie.title == old[j].Text ) { + ttg.list.Add( old[j] ); + break; + } + } + }*/ + /*for ( int i = 0; i < gc.EditedResult.Count; i++ ) { + for ( int j = 0; j < old.Count; j++ ) { + if ( gc.EditedResult[i].title == old[j].Text ) { + ttg.list.Add( old[j] ); + break; + } + } + }*/ + /*using ( TimeTableGroup temp = (TimeTableGroup)AppManager.SaveData.m_groups_character[group].Clone() ) { + temp.Character = gc.EditedResult.Character; + //temp.Character = (Character3)gc.Character.Clone(); + temp.Clear(); + bool found = false; + // Images + foreach ( ImageEntry item in temp.Character ) { + found = false; + for ( int track = 0; track < AppManager.SaveData.m_groups_character[group].Count; track++ ) { + if ( AppManager.SaveData.m_groups_character[group][track].Text == item.title ) { + temp.Add( (TimeTable)AppManager.SaveData.m_groups_character[group][track].Clone() ); + found = true; + break; + } + } + if ( !found ) { + temp.Add( new TimeTable( item.title, 0, TimeTableType.character, null ) ); + } + } + + temp.Text = gc.Character.Name; + Command run = Command.GCommandEditGroup( TimeTableType.character, group, temp ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + }*/ + TimeTableGroup ttg = gc.EditedResult; + ttg.Text = ttg.Character.Name; + Command run = Command.GCommandEditGroup( TimeTableType.character, group, ttg ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + SetVScrollRange(); + this.Invalidate(); + AppManager.Edited = true; + } + } + } else { + string id = AppManager.SaveData.m_groups_character[m_clicked.group].Character.PluginConfig.ID; + int index = -1; + for ( int i = 0; i < AppManager.SaveData.m_plugins_config.Count; i++ ) { + if ( id == AppManager.SaveData.m_plugins_config[i].ID ) { + index = i; + break; + } + } + if ( index >= 0 ) { + if ( AppManager.SaveData.m_plugins[index].Instance.BaseSetting() == DialogResult.OK ) { + Command run = Command.GCommandChangePluginConfig( index, AppManager.SaveData.m_plugins[index].Instance.Config ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + } + } + } + } + + /// + /// m_clickedで指定されたトラック、またはトラックグループを削除します。 + /// + /// + /// + private void h_deleteTrack( object sender, EventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "Form1+h_deleteTrack" ); + Common.DebugWriteLine( " m_curve.comboObjects.SelectedIndex=" + m_curve.comboObjects.SelectedIndex ); +#endif + if ( m_curve.comboObjects.SelectedIndex < 0 ) { + m_curve.SetSelectedNone(); + } + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + bool deleted = false; + StopPauseCore(); + m_player.Pause(); + if ( type == TimeTableType.character ) { + if ( track < 0 ) { + if ( MessageBox.Show( _( "...deleting selected character.\nWould you like to continue?" ), _( "Confirmation" ), MessageBoxButtons.OKCancel, MessageBoxIcon.Question ) == DialogResult.OK ) { + Command run = Command.GCommandDeleteTimeTableGroup( TimeTableType.character, group ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + deleted = true; + } + } + } else if ( type == TimeTableType.another || type == TimeTableType.vsq ) { + if ( MessageBox.Show( _( "...deleting selected track.\nWould you like to continue?" ), _( "Confirmation" ), MessageBoxButtons.OKCancel, MessageBoxIcon.Question ) == DialogResult.OK ) { + Command run = Command.GCommandDeleteTimeTable( type, -1, track ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + deleted = true; + } + } +#if DEBUG + Common.DebugWriteLine( " deleted=" + deleted ); +#endif + if ( deleted ) { + if ( m_curve.comboObjects.SelectedItem != null ) { + bool clear_required = false; + TagForTreeNode t = (TagForTreeNode)m_curve.comboObjects.SelectedItem; + if ( type == TimeTableType.character && t.type == ZorderItemType.character && t.id_or_index == group ) { + clear_required = true; + } else if ( type == TimeTableType.another && t.type == ZorderItemType.character && t.id_or_index == track ) { + clear_required = true; + } + if ( clear_required ) { + m_curve.SetSelectedNone(); + } + } + AppManager.SaveData.UpdateZorder(); + AppManager.Edited = true; + UpdateObjectList(); + this.Invalidate(); + } + } + + private void h_noteON( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + float begin = SecFromXCoord( m_mousePosition.X ); + PointF bound; + string body; + if ( type == TimeTableType.character ) { + body = AppManager.SaveData.m_groups_character[group][track].Text; + bound = GetEntryLimit( m_clicked, begin, false ); + } else if ( type == TimeTableType.another || type == TimeTableType.plugin ) { + body = AppManager.SaveData[type, -1][track].Text; + bound = GetEntryLimitSingle( m_clicked, begin, false ); + } else { + return; + } + if ( bound.Y > begin ) { + Command run = Command.GCommandAddTimeTableEntry( type, group, track, new TimeTableEntry( begin, bound.Y, body ) ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + AppManager.Edited = true; + this.Invalidate(); + } + } + + private void h_pluginInfo( object sender, EventArgs e ) { + ToolStripMenuItem c_sender = (ToolStripMenuItem)sender; + int index = -1; + for ( int i = 0; i < AppManager.SaveData.m_plugins.Length; i++ ) { + if ( AppManager.SaveData.m_plugins[i].Instance.Name == c_sender.Text ) { + index = i; + break; + } + } + if ( index >= 0 ) { + VersionBox info = new VersionBox( AppManager.SaveData.m_plugins[index].Instance.Name, AppManager.SaveData.m_plugins[index].Instance.Abstract ); + info.ShowDialog(); + info.Dispose(); + } + } + + private void h_noteOFF( object sender, EventArgs e ) { + TimeTableType type = m_clicked.type; + int group = m_clicked.group; + int track = m_clicked.track; + int entry = m_clicked.entry; + float end = (m_mousePosition.X + m_startToDrawX) / AppManager.Config.PixelPerSec; + if ( type != TimeTableType.character && + type != TimeTableType.another && + type != TimeTableType.plugin && + type != TimeTableType.telop ) { + return; + } + if ( type == TimeTableType.telop ) { + Telop item = (Telop)AppManager.SaveData[entry].Clone(); + item.End = end; + Command run = Command.GCommandEditTelop( entry, item ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } else { + TimeTableEntry item; + item = (TimeTableEntry)AppManager.SaveData[type, group][track][entry].Clone(); + item.end = end; + Command run = Command.GCommandEditTimeTableEntry( type, group, track, entry, item ); + AppManager.Register( AppManager.SaveData.Execute( run ) ); + } + AppManager.Edited = true; + this.Invalidate(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormCommandHistory.Designer.cs b/trunk/LipSync/LipSync/Editor/FormCommandHistory.Designer.cs new file mode 100644 index 0000000..59210ef --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormCommandHistory.Designer.cs @@ -0,0 +1,113 @@ +/* + * FormCommandHistory.Designer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class FormCommandHistory { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.panel = new System.Windows.Forms.Panel(); + this.lblLookMe = new System.Windows.Forms.Label(); + this.pictCommands = new System.Windows.Forms.PictureBox(); + this.vScrollBar1 = new System.Windows.Forms.VScrollBar(); + this.panel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictCommands)).BeginInit(); + this.SuspendLayout(); + // + // panel + // + this.panel.Controls.Add( this.pictCommands ); + this.panel.Controls.Add( this.vScrollBar1 ); + this.panel.Controls.Add( this.lblLookMe ); + this.panel.Dock = System.Windows.Forms.DockStyle.Fill; + this.panel.Location = new System.Drawing.Point( 0, 0 ); + this.panel.Name = "panel"; + this.panel.Size = new System.Drawing.Size( 169, 431 ); + this.panel.TabIndex = 0; + // + // lblLookMe + // + this.lblLookMe.AutoSize = true; + this.lblLookMe.Location = new System.Drawing.Point( 29, 8 ); + this.lblLookMe.Name = "lblLookMe"; + this.lblLookMe.Size = new System.Drawing.Size( 0, 12 ); + this.lblLookMe.TabIndex = 1; + // + // pictCommands + // + this.pictCommands.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pictCommands.Dock = System.Windows.Forms.DockStyle.Top; + this.pictCommands.Location = new System.Drawing.Point( 0, 0 ); + this.pictCommands.Margin = new System.Windows.Forms.Padding( 0 ); + this.pictCommands.Name = "pictCommands"; + this.pictCommands.Size = new System.Drawing.Size( 153, 20 ); + this.pictCommands.TabIndex = 0; + this.pictCommands.TabStop = false; + this.pictCommands.MouseDown += new System.Windows.Forms.MouseEventHandler( this.pictCommands_MouseDown ); + this.pictCommands.Paint += new System.Windows.Forms.PaintEventHandler( this.pictCommands_Paint ); + // + // vScrollBar1 + // + this.vScrollBar1.Dock = System.Windows.Forms.DockStyle.Right; + this.vScrollBar1.Location = new System.Drawing.Point( 153, 0 ); + this.vScrollBar1.Name = "vScrollBar1"; + this.vScrollBar1.Size = new System.Drawing.Size( 16, 431 ); + this.vScrollBar1.TabIndex = 2; + // + // FormCommandHistory + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 169, 431 ); + this.Controls.Add( this.panel ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; + this.Name = "FormCommandHistory"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "Command History"; + this.Load += new System.EventHandler( this.FormCommandHistory_Load ); + this.panel.ResumeLayout( false ); + this.panel.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.pictCommands)).EndInit(); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.Panel panel; + private System.Windows.Forms.PictureBox pictCommands; + private System.Windows.Forms.Label lblLookMe; + private System.Windows.Forms.VScrollBar vScrollBar1; + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/FormCommandHistory.cs b/trunk/LipSync/LipSync/Editor/FormCommandHistory.cs new file mode 100644 index 0000000..4668e53 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormCommandHistory.cs @@ -0,0 +1,154 @@ +/* + * FormCommandHistory.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class FormCommandHistory : Form, IMultiLanguageControl { + private const int _LABEL_HEIGT = 15; + private ToolStripMenuItem m_redo; + private ToolStripMenuItem m_undo; + private MenuStrip m_menu; + + public FormCommandHistory() { + InitializeComponent(); + + m_redo = new ToolStripMenuItem(); + m_undo = new ToolStripMenuItem(); + + m_menu = new MenuStrip(); + m_menu.Visible = false; + m_menu.Items.AddRange( new ToolStripItem[] { m_redo, m_undo } ); + + m_redo.Visible = false; + m_redo.ShortcutKeys = Keys.Control | Keys.Shift | Keys.Z; + m_redo.Click += new EventHandler( m_redo_Click ); + + m_undo.Visible = false; + m_undo.ShortcutKeys = Keys.Control | Keys.Z; + m_undo.Click += new EventHandler( m_undo_Click ); + + this.Controls.Add( m_menu ); + + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + pictCommands.Height = _LABEL_HEIGT; + SettingsEx.CommandExecuted += new CommandExecutedEventHandler( SettingsEx_CommandExecuted ); + pictCommands.MouseWheel += new MouseEventHandler( pictCommands_MouseWheel ); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + private void m_undo_Click( object sender, EventArgs e ) { + if ( AppManager.IsUndoAvailable ) { + AppManager.Undo(); + } + } + + private void m_redo_Click( object sender, EventArgs e ) { + if ( AppManager.IsRedoAvailable ) { + AppManager.Redo(); + } + } + + public void ApplyLanguage() { + this.Text = _( "Command History" ); + this.Invalidate(); + } + + private static string _( string id ) { + return Messaging.GetMessage( id ); + } + + private void SettingsEx_CommandExecuted( TimeTableType command_target, CommandType command_type ) { + pictCommands.Height = (AppManager.m_commands.Count + 2) * _LABEL_HEIGT; + //lblLookMe.Location = new Point( 0, (AppManager.m_command_position + 2) * _LABEL_HEIGT ); + //panel.ScrollControlIntoView( lblLookMe ); + pictCommands.Invalidate(); + } + + private void pictCommands_Paint( object sender, PaintEventArgs e ) { + e.Graphics.FillRectangle( Brushes.Pink, new Rectangle( 0, 0, pictCommands.Width, _LABEL_HEIGT ) ); + e.Graphics.DrawString( _( "Command History" ), SystemFonts.MenuFont, Brushes.Black, new PointF( 0, 0 ) ); + + e.Graphics.FillRectangle( Brushes.White, new Rectangle( 0, _LABEL_HEIGT, pictCommands.Width, _LABEL_HEIGT ) ); + Font font = SystemFonts.MenuFont; + if ( AppManager.m_command_position < 0 ) { + font = new Font( font.FontFamily, font.Size, FontStyle.Bold ); + } + e.Graphics.DrawString( "Root", font, Brushes.Black, new PointF( 0, _LABEL_HEIGT ) ); + + for ( int i = 0; i < AppManager.m_commands.Count; i++ ) { + Brush brs; + if ( i % 2 == 0 ) { + brs = Brushes.LightGray; + } else { + brs = Brushes.White; + } + font = SystemFonts.MenuFont; + if ( i == AppManager.m_command_position ) { + font = new Font( font.FontFamily, font.Size, FontStyle.Bold ); + } + e.Graphics.FillRectangle( brs, new Rectangle( 0, (i + 2) * _LABEL_HEIGT, pictCommands.Width, _LABEL_HEIGT ) ); + e.Graphics.DrawString( StringFromCommand( AppManager.m_commands[i] ), + font, + Brushes.Black, + new PointF( 0, (i + 2) * _LABEL_HEIGT ) ); + } + } + + private void pictCommands_MouseWheel( object sender, MouseEventArgs e ) { + + } + + private void pictCommands_MouseDown( object sender, MouseEventArgs e ) { + pictCommands.Focus(); + } + + private string StringFromCommand( Command command ) { + if ( command.target == TimeTableType.another ) { + if ( command.type == CommandType.addEntry ) { + return string.Format( _( "Delete entry of 'Another Image' at Index {0}" ), command.track ); + } else if ( command.type == CommandType.deleteEntry ) { + return string.Format( _( "Add entry of 'Another Image' at Index {0}" ), command.track ); + } else if ( command.type == CommandType.editEntry ) { + return string.Format( _( "Edit entry of 'Another Image' at Track {0}, Index {1}" ), command.track, command.entry ); + } + } else if ( command.target == TimeTableType.telop ) { + if ( command.type == CommandType.addTelop ) { + return string.Format( _( "Delete telop '{0}'" ), command.telop.Text ); + } else if ( command.type == CommandType.editTelop ) { + return string.Format( _( "Edit telop '{0}' at Index {1}" ), command.telop.Text, command.entry ); + } else if ( command.type == CommandType.deleteTelop ) { + return string.Format( _( "Add telop '{0}'" ), command.telop.Text ); + } + } + return command.target + ", " + command.type; + } + + private void FormCommandHistory_Load( object sender, EventArgs e ) { + SettingsEx_CommandExecuted( TimeTableType.none, CommandType.nothing ); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormObjectList.Designer.cs b/trunk/LipSync/LipSync/Editor/FormObjectList.Designer.cs new file mode 100644 index 0000000..c18dcc3 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormObjectList.Designer.cs @@ -0,0 +1,64 @@ +/* + * FormObjectList.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class FormObjectList { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.SuspendLayout(); + // + // FormObjectList + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 292, 273 ); + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormObjectList"; + this.ShowIcon = false; + this.Text = "FormObjectList"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler( this.FormObjectList_FormClosing ); + this.ResumeLayout( false ); + + } + + #endregion + + public void ApplyLanguage() { + this.Text = _( "List of object" ); + } + + } +} diff --git a/trunk/LipSync/LipSync/Editor/FormObjectList.cs b/trunk/LipSync/LipSync/Editor/FormObjectList.cs new file mode 100644 index 0000000..f8bb231 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormObjectList.cs @@ -0,0 +1,55 @@ +/* + * FormObjectList.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class FormObjectList : Form { + ListView m_listview; + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + protected override void WndProc( ref Message m ) { + const int WM_NCLBUTTONDBLCLK = 0xa3; + if ( m.Msg == WM_NCLBUTTONDBLCLK ) { + this.Close(); + } else { + base.WndProc( ref m ); + } + } + + public FormObjectList() { + InitializeComponent(); + } + + public new void Show( ListView listView ) { + m_listview = listView; + m_listview.Parent = this; + this.Controls.Add( m_listview ); + m_listview.Dock = DockStyle.Fill; + this.Text = _( "List of object" ); + base.Show(); + } + + private void FormObjectList_FormClosing( object sender, FormClosingEventArgs e ) { + e.Cancel = true; + this.Hide(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormPreview.Designer.cs b/trunk/LipSync/LipSync/Editor/FormPreview.Designer.cs new file mode 100644 index 0000000..3f9f173 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormPreview.Designer.cs @@ -0,0 +1,55 @@ +/* + * FormPreview.Designer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class FormPreview { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.SuspendLayout(); + // + // FormPreview + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 465, 320 ); + this.Name = "FormPreview"; + this.StartPosition = System.Windows.Forms.FormStartPosition.Manual; + this.Text = "FormPreview"; + this.ResumeLayout( false ); + + } + + #endregion + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/FormPreview.cs b/trunk/LipSync/LipSync/Editor/FormPreview.cs new file mode 100644 index 0000000..12fc37a --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormPreview.cs @@ -0,0 +1,87 @@ +/* + * FormPreview.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace LipSync { + + public partial class FormPreview : Form, IMultiLanguageControl { + public FormPreview() { + InitializeComponent(); + Rectangle r = AppManager.Config.PreviewWindowPos; + Point pt_lt = new Point( r.Left, r.Top ); + Point pt_lb = new Point( r.Left, r.Bottom ); + Point pt_rt = new Point( r.Right, r.Top ); + Point pt_rb = new Point( r.Right, r.Bottom ); + bool visible = false; + foreach ( Screen s in Screen.AllScreens ) { + visible = visible | (IsInRectangle( pt_lt, s.Bounds ) | IsInRectangle( pt_lb, s.Bounds ) | IsInRectangle( pt_rt, s.Bounds ) | IsInRectangle( pt_rb, s.Bounds )); + } + if ( visible ) { + this.Left = r.Left; + this.Top = r.Top; + this.Width = r.Width; + this.Height = r.Height; + } else { + this.Width = Screen.PrimaryScreen.Bounds.Width / 2; + this.Height = Screen.PrimaryScreen.Bounds.Height / 2; + this.Left = this.Width / 2; + this.Top = this.Height / 2; + } + if ( AppManager.Config.PreviewMaximized ) { + this.WindowState = FormWindowState.Maximized; + } else { + this.WindowState = FormWindowState.Normal; + } + this.SizeChanged += new EventHandler( FormPreview_LocationOrSizeChanged ); + this.LocationChanged += new EventHandler( FormPreview_LocationOrSizeChanged ); + } + + /// + /// rectの中にpointが入っているかどうかを判定 + /// + /// + /// + /// + private static bool IsInRectangle( Point point, Rectangle rect ) { + if ( rect.X <= point.X && point.X <= rect.X + rect.Width ) { + if ( rect.Y <= point.Y && point.Y <= rect.Y + rect.Height ) { + return true; + } + } + return false; + } + + public void ApplyLanguage() { + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + private void FormPreview_LocationOrSizeChanged( object sender, EventArgs e ) { + if ( AppManager.Config != null ) { + if ( this.WindowState == FormWindowState.Normal ) { + AppManager.Config.PreviewWindowPos = this.Bounds; + } + AppManager.Config.PreviewMaximized = (this.WindowState == FormWindowState.Maximized); + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormSeriesImage.Designer.cs b/trunk/LipSync/LipSync/Editor/FormSeriesImage.Designer.cs new file mode 100644 index 0000000..92689b2 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormSeriesImage.Designer.cs @@ -0,0 +1,293 @@ +/* + * FormSeriesImage.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class FormSeriesImage { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.txtDirectory = new System.Windows.Forms.TextBox(); + this.lblFileName = new System.Windows.Forms.Label(); + this.btnFile = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.chkStart = new System.Windows.Forms.CheckBox(); + this.groupStartEnd = new System.Windows.Forms.GroupBox(); + this.txtEnd = new System.Windows.Forms.TextBox(); + this.txtStart = new System.Windows.Forms.TextBox(); + this.chkEnd = new System.Windows.Forms.CheckBox(); + this.groupFileName = new System.Windows.Forms.GroupBox(); + this.chkAutomaticallyAddExtension = new System.Windows.Forms.CheckBox(); + this.lblFormat = new System.Windows.Forms.Label(); + this.txtParser = new System.Windows.Forms.TextBox(); + this.comboFormat = new System.Windows.Forms.ComboBox(); + this.lblParser = new System.Windows.Forms.Label(); + this.txtPreview = new System.Windows.Forms.TextBox(); + this.groupStartEnd.SuspendLayout(); + this.groupFileName.SuspendLayout(); + this.SuspendLayout(); + // + // txtDirectory + // + this.txtDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtDirectory.BackColor = System.Drawing.SystemColors.Window; + this.txtDirectory.Location = new System.Drawing.Point( 73, 14 ); + this.txtDirectory.Name = "txtDirectory"; + this.txtDirectory.Size = new System.Drawing.Size( 346, 19 ); + this.txtDirectory.TabIndex = 0; + // + // lblFileName + // + this.lblFileName.AutoSize = true; + this.lblFileName.Location = new System.Drawing.Point( 15, 17 ); + this.lblFileName.Name = "lblFileName"; + this.lblFileName.Size = new System.Drawing.Size( 51, 12 ); + this.lblFileName.TabIndex = 4; + this.lblFileName.Text = "ファイル名"; + // + // btnFile + // + this.btnFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnFile.Location = new System.Drawing.Point( 425, 12 ); + this.btnFile.Name = "btnFile"; + this.btnFile.Size = new System.Drawing.Size( 24, 23 ); + this.btnFile.TabIndex = 1; + this.btnFile.Text = "..."; + this.btnFile.UseVisualStyleBackColor = true; + this.btnFile.Click += new System.EventHandler( this.btnFile_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 371, 283 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 13; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 272, 283 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 12; + this.btnOK.Text = "保存"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // chkStart + // + this.chkStart.AutoSize = true; + this.chkStart.Location = new System.Drawing.Point( 19, 27 ); + this.chkStart.Name = "chkStart"; + this.chkStart.Size = new System.Drawing.Size( 48, 16 ); + this.chkStart.TabIndex = 8; + this.chkStart.Text = "開始"; + this.chkStart.UseVisualStyleBackColor = true; + this.chkStart.CheckedChanged += new System.EventHandler( this.chkStart_CheckedChanged ); + // + // groupStartEnd + // + this.groupStartEnd.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupStartEnd.Controls.Add( this.txtEnd ); + this.groupStartEnd.Controls.Add( this.txtStart ); + this.groupStartEnd.Controls.Add( this.chkEnd ); + this.groupStartEnd.Controls.Add( this.chkStart ); + this.groupStartEnd.Location = new System.Drawing.Point( 14, 41 ); + this.groupStartEnd.Name = "groupStartEnd"; + this.groupStartEnd.Size = new System.Drawing.Size( 432, 89 ); + this.groupStartEnd.TabIndex = 7; + this.groupStartEnd.TabStop = false; + this.groupStartEnd.Text = "出力範囲を指定"; + // + // txtEnd + // + this.txtEnd.Enabled = false; + this.txtEnd.Location = new System.Drawing.Point( 90, 53 ); + this.txtEnd.Name = "txtEnd"; + this.txtEnd.Size = new System.Drawing.Size( 144, 19 ); + this.txtEnd.TabIndex = 11; + this.txtEnd.Text = "0"; + // + // txtStart + // + this.txtStart.Enabled = false; + this.txtStart.Location = new System.Drawing.Point( 90, 25 ); + this.txtStart.Name = "txtStart"; + this.txtStart.Size = new System.Drawing.Size( 144, 19 ); + this.txtStart.TabIndex = 9; + this.txtStart.Text = "0"; + // + // chkEnd + // + this.chkEnd.AutoSize = true; + this.chkEnd.Location = new System.Drawing.Point( 19, 55 ); + this.chkEnd.Name = "chkEnd"; + this.chkEnd.Size = new System.Drawing.Size( 48, 16 ); + this.chkEnd.TabIndex = 10; + this.chkEnd.Text = "終了"; + this.chkEnd.UseVisualStyleBackColor = true; + this.chkEnd.CheckedChanged += new System.EventHandler( this.checkBox1_CheckedChanged ); + // + // groupFileName + // + this.groupFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupFileName.Controls.Add( this.chkAutomaticallyAddExtension ); + this.groupFileName.Controls.Add( this.lblFormat ); + this.groupFileName.Controls.Add( this.txtParser ); + this.groupFileName.Controls.Add( this.comboFormat ); + this.groupFileName.Controls.Add( this.lblParser ); + this.groupFileName.Controls.Add( this.txtPreview ); + this.groupFileName.Location = new System.Drawing.Point( 14, 136 ); + this.groupFileName.Name = "groupFileName"; + this.groupFileName.Size = new System.Drawing.Size( 432, 132 ); + this.groupFileName.TabIndex = 20; + this.groupFileName.TabStop = false; + this.groupFileName.Text = "File Name"; + // + // chkAutomaticallyAddExtension + // + this.chkAutomaticallyAddExtension.AutoSize = true; + this.chkAutomaticallyAddExtension.Checked = true; + this.chkAutomaticallyAddExtension.CheckState = System.Windows.Forms.CheckState.Checked; + this.chkAutomaticallyAddExtension.Location = new System.Drawing.Point( 19, 60 ); + this.chkAutomaticallyAddExtension.Name = "chkAutomaticallyAddExtension"; + this.chkAutomaticallyAddExtension.Size = new System.Drawing.Size( 172, 16 ); + this.chkAutomaticallyAddExtension.TabIndex = 5; + this.chkAutomaticallyAddExtension.Text = "Automatically Add Extension"; + this.chkAutomaticallyAddExtension.UseVisualStyleBackColor = true; + this.chkAutomaticallyAddExtension.CheckedChanged += new System.EventHandler( this.chkAutomaticallyAddExtension_CheckedChanged ); + // + // lblFormat + // + this.lblFormat.AutoSize = true; + this.lblFormat.Location = new System.Drawing.Point( 17, 99 ); + this.lblFormat.Name = "lblFormat"; + this.lblFormat.Size = new System.Drawing.Size( 75, 12 ); + this.lblFormat.TabIndex = 4; + this.lblFormat.Text = "Image Format"; + // + // txtParser + // + this.txtParser.Location = new System.Drawing.Point( 124, 22 ); + this.txtParser.Name = "txtParser"; + this.txtParser.Size = new System.Drawing.Size( 137, 19 ); + this.txtParser.TabIndex = 3; + this.txtParser.Text = "{0}"; + this.txtParser.TextChanged += new System.EventHandler( this.txtParser_TextChanged ); + // + // comboFormat + // + this.comboFormat.FormattingEnabled = true; + this.comboFormat.Location = new System.Drawing.Point( 124, 96 ); + this.comboFormat.Name = "comboFormat"; + this.comboFormat.Size = new System.Drawing.Size( 121, 20 ); + this.comboFormat.TabIndex = 0; + this.comboFormat.SelectedIndexChanged += new System.EventHandler( this.comboFormat_SelectedIndexChanged ); + // + // lblParser + // + this.lblParser.AutoSize = true; + this.lblParser.Location = new System.Drawing.Point( 17, 25 ); + this.lblParser.Name = "lblParser"; + this.lblParser.Size = new System.Drawing.Size( 72, 12 ); + this.lblParser.TabIndex = 2; + this.lblParser.Text = "Parser String"; + // + // txtPreview + // + this.txtPreview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtPreview.Location = new System.Drawing.Point( 267, 22 ); + this.txtPreview.Multiline = true; + this.txtPreview.Name = "txtPreview"; + this.txtPreview.ReadOnly = true; + this.txtPreview.Size = new System.Drawing.Size( 159, 94 ); + this.txtPreview.TabIndex = 1; + // + // FormSeriesImage + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 460, 323 ); + this.Controls.Add( this.groupFileName ); + this.Controls.Add( this.groupStartEnd ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnFile ); + this.Controls.Add( this.lblFileName ); + this.Controls.Add( this.txtDirectory ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormSeriesImage"; + this.ShowInTaskbar = false; + this.Text = "Series Image"; + this.groupStartEnd.ResumeLayout( false ); + this.groupStartEnd.PerformLayout(); + this.groupFileName.ResumeLayout( false ); + this.groupFileName.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtDirectory; + private System.Windows.Forms.Label lblFileName; + private System.Windows.Forms.Button btnFile; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.CheckBox chkStart; + private System.Windows.Forms.GroupBox groupStartEnd; + private System.Windows.Forms.TextBox txtEnd; + private System.Windows.Forms.TextBox txtStart; + private System.Windows.Forms.CheckBox chkEnd; + private System.Windows.Forms.GroupBox groupFileName; + private System.Windows.Forms.ComboBox comboFormat; + private System.Windows.Forms.TextBox txtPreview; + private System.Windows.Forms.TextBox txtParser; + private System.Windows.Forms.Label lblParser; + private System.Windows.Forms.Label lblFormat; + private System.Windows.Forms.CheckBox chkAutomaticallyAddExtension; + } +} diff --git a/trunk/LipSync/LipSync/Editor/FormSeriesImage.cs b/trunk/LipSync/LipSync/Editor/FormSeriesImage.cs new file mode 100644 index 0000000..7d6f38e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormSeriesImage.cs @@ -0,0 +1,207 @@ +/* + * FormSeriesImage.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Drawing; +using System.Windows.Forms; +using System.Reflection; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class FormSeriesImage : Form, IMultiLanguageControl { + float m_start = 0f; + float m_end = 0f; + + public FormSeriesImage() { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + Type type = typeof( System.Drawing.Imaging.ImageFormat ); + PropertyInfo[] properties = type.GetProperties(); + int i = -1; + foreach ( PropertyInfo pi in properties ) { + if ( pi.PropertyType.Equals( typeof( System.Drawing.Imaging.ImageFormat ) ) ) { + System.Drawing.Imaging.ImageFormat ifm = (System.Drawing.Imaging.ImageFormat)pi.GetValue( null, null ); + string ext = Misc.GetExtensionFromImageFormat( ifm ); + if ( ext.Length > 0 ) { + i++; + comboFormat.Items.Add( pi.Name ); + if ( i == 0 ) { + comboFormat.SelectedIndex = 0; + } + if ( ext == "bmp" ) { + comboFormat.SelectedIndex = i; + } + } + } + } + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public string ParserString { + get { + if ( chkAutomaticallyAddExtension.Checked ) { + return txtParser.Text + "." + Misc.GetExtensionFromImageFormat( ImageFormat ); + } else { + return txtParser.Text; + } + } + } + + public System.Drawing.Imaging.ImageFormat ImageFormat { + get { + if ( comboFormat.SelectedItem == null ){ + return System.Drawing.Imaging.ImageFormat.Bmp; + } + string title = (string)comboFormat.SelectedItem; +#if DEBUG + Console.WriteLine( "ImageFormat.get()" ); + Console.WriteLine( " System.Drawing.Imaging.ImageFormat.Bmp.ToString()=" + System.Drawing.Imaging.ImageFormat.Bmp.ToString() ); +#endif + PropertyInfo[] properties = typeof( System.Drawing.Imaging.ImageFormat ).GetProperties(); + foreach ( PropertyInfo pi in properties ) { + if ( pi.PropertyType.Equals( typeof( System.Drawing.Imaging.ImageFormat ) ) ) { + if ( pi.Name == title ) { + return (System.Drawing.Imaging.ImageFormat)pi.GetValue( null, null ); + } + } + } + return System.Drawing.Imaging.ImageFormat.Bmp; + } + } + + public string DirectoryName { + get { + return txtDirectory.Text; + } + } + + public void ApplyLanguage() { + this.Text = _( "Series Image" ); + btnCancel.Text = _( "Cancel" ); + btnOK.Text = _( "Save" ); + lblFileName.Text = _( "Directory" ); + groupStartEnd.Text = _( "Specify output range" ); + chkStart.Text = _( "Start" ); + chkEnd.Text = _( "End" ); + groupFileName.Text = _( "File Name" ); + lblParser.Text = _( "Parser String" ); + chkAutomaticallyAddExtension.Text = _( "Automatically Add Extension" ); + lblFormat.Text = _( "Image Format" ); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public float Start { + get { + return m_start; + } + } + + public float End { + get { + return m_end; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + try { + m_start = float.Parse( txtStart.Text ); + m_end = float.Parse( txtEnd.Text ); + this.DialogResult = DialogResult.OK; + } catch ( Exception ex ) { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation + ); + Common.LogPush( ex ); + } + } + + private void btnFile_Click( object sender, EventArgs e ) { + using ( FolderBrowserDialog fbd = new FolderBrowserDialog() ) { + if ( fbd.ShowDialog() == DialogResult.OK ) { + txtDirectory.Text = fbd.SelectedPath; + } + } + } + + private void chkStart_CheckedChanged( object sender, EventArgs e ) { + txtStart.Enabled = chkStart.Checked; + if ( txtStart.Enabled ) { + txtStart.Focus(); + } + } + + private void checkBox1_CheckedChanged( object sender, EventArgs e ) { + txtEnd.Enabled = chkEnd.Checked; + if ( txtEnd.Enabled ) { + txtEnd.Focus(); + } + } + + public bool StartSpecified { + get { + return chkStart.Checked; + } + } + + public bool EndSpecified { + get { + return chkEnd.Checked; + } + } + + private void txtParser_TextChanged( object sender, EventArgs e ) { + UpdateSampleFileNames(); + } + + private void comboFormat_SelectedIndexChanged( object sender, EventArgs e ) { + UpdateSampleFileNames(); + } + + private void UpdateSampleFileNames() { + string ret = _( "Sample File Name" ) + Environment.NewLine; + System.Drawing.Imaging.ImageFormat ifm = ImageFormat; + string ext = Misc.GetExtensionFromImageFormat( ifm ); + string parser = ParserString; + try { + ret += string.Format( parser, 0 ) + Environment.NewLine; + ret += string.Format( parser, 1 ) + Environment.NewLine; + ret += " ... " + Environment.NewLine; + ret += string.Format( parser, 1234 ); + } catch { + ret += _( "Error: Invalid parser string." ); + } + txtPreview.Text = ret; + } + + private void chkAutomaticallyAddExtension_CheckedChanged( object sender, EventArgs e ) { + UpdateSampleFileNames(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormSetFrameRate.Designer.cs b/trunk/LipSync/LipSync/Editor/FormSetFrameRate.Designer.cs new file mode 100644 index 0000000..ecb3f33 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormSetFrameRate.Designer.cs @@ -0,0 +1,197 @@ +/* + * FormSetFrameRate.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + partial class FormSetFrameRate { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.btnExpand = new System.Windows.Forms.Button(); + this.txtFrameRate = new System.Windows.Forms.TextBox(); + this.lblFrameRate = new System.Windows.Forms.Label(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.txtNumerator = new System.Windows.Forms.TextBox(); + this.lblNumerator = new System.Windows.Forms.Label(); + this.lblDenominator = new System.Windows.Forms.Label(); + this.txtDenominator = new System.Windows.Forms.TextBox(); + this.btnImport = new System.Windows.Forms.Button(); + this.toolTipImport = new System.Windows.Forms.ToolTip( this.components ); + this.SuspendLayout(); + // + // btnExpand + // + this.btnExpand.FlatStyle = System.Windows.Forms.FlatStyle.Popup; + this.btnExpand.Image = global::LipSync.Properties.Resources.closed; + this.btnExpand.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.btnExpand.Location = new System.Drawing.Point( 12, 96 ); + this.btnExpand.Name = "btnExpand"; + this.btnExpand.Size = new System.Drawing.Size( 308, 23 ); + this.btnExpand.TabIndex = 3; + this.btnExpand.Text = " 詳細な設定"; + this.btnExpand.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText; + this.btnExpand.UseVisualStyleBackColor = true; + this.btnExpand.Click += new System.EventHandler( this.btnExpand_Click ); + // + // txtFrameRate + // + this.txtFrameRate.Location = new System.Drawing.Point( 87, 15 ); + this.txtFrameRate.Name = "txtFrameRate"; + this.txtFrameRate.Size = new System.Drawing.Size( 189, 19 ); + this.txtFrameRate.TabIndex = 0; + this.txtFrameRate.Text = "30"; + this.txtFrameRate.TextChanged += new System.EventHandler( this.txtFrameRate_TextChanged ); + // + // lblFrameRate + // + this.lblFrameRate.AutoSize = true; + this.lblFrameRate.Location = new System.Drawing.Point( 12, 18 ); + this.lblFrameRate.Name = "lblFrameRate"; + this.lblFrameRate.Size = new System.Drawing.Size( 69, 12 ); + this.lblFrameRate.TabIndex = 2; + this.lblFrameRate.Text = "フレームレート"; + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 245, 58 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 151, 58 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // txtNumerator + // + this.txtNumerator.Location = new System.Drawing.Point( 151, 137 ); + this.txtNumerator.Name = "txtNumerator"; + this.txtNumerator.Size = new System.Drawing.Size( 60, 19 ); + this.txtNumerator.TabIndex = 4; + this.txtNumerator.Text = "30"; + this.txtNumerator.TextChanged += new System.EventHandler( this.txtNumerator_TextChanged ); + // + // lblNumerator + // + this.lblNumerator.AutoSize = true; + this.lblNumerator.Location = new System.Drawing.Point( 12, 140 ); + this.lblNumerator.Name = "lblNumerator"; + this.lblNumerator.Size = new System.Drawing.Size( 103, 12 ); + this.lblNumerator.TabIndex = 6; + this.lblNumerator.Text = "フレームレートの分子"; + // + // lblDenominator + // + this.lblDenominator.AutoSize = true; + this.lblDenominator.Location = new System.Drawing.Point( 12, 165 ); + this.lblDenominator.Name = "lblDenominator"; + this.lblDenominator.Size = new System.Drawing.Size( 103, 12 ); + this.lblDenominator.TabIndex = 8; + this.lblDenominator.Text = "フレームレートの分母"; + // + // txtDenominator + // + this.txtDenominator.Location = new System.Drawing.Point( 151, 162 ); + this.txtDenominator.Name = "txtDenominator"; + this.txtDenominator.Size = new System.Drawing.Size( 60, 19 ); + this.txtDenominator.TabIndex = 5; + this.txtDenominator.Text = "1"; + this.txtDenominator.TextChanged += new System.EventHandler( this.txtDenominator_TextChanged ); + // + // btnImport + // + this.btnImport.Location = new System.Drawing.Point( 234, 147 ); + this.btnImport.Name = "btnImport"; + this.btnImport.Size = new System.Drawing.Size( 75, 23 ); + this.btnImport.TabIndex = 6; + this.btnImport.Text = "引用"; + this.toolTipImport.SetToolTip( this.btnImport, "AVIファイルからフレームレートの設定を引用します" ); + this.btnImport.UseVisualStyleBackColor = true; + this.btnImport.Click += new System.EventHandler( this.btnImport_Click ); + // + // FormSetFrameRate + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 332, 192 ); + this.Controls.Add( this.btnImport ); + this.Controls.Add( this.lblDenominator ); + this.Controls.Add( this.txtDenominator ); + this.Controls.Add( this.lblNumerator ); + this.Controls.Add( this.txtNumerator ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.lblFrameRate ); + this.Controls.Add( this.txtFrameRate ); + this.Controls.Add( this.btnExpand ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormSetFrameRate"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "FormSetFrameRate"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnExpand; + private System.Windows.Forms.TextBox txtFrameRate; + private System.Windows.Forms.Label lblFrameRate; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.TextBox txtNumerator; + private System.Windows.Forms.Label lblNumerator; + private System.Windows.Forms.Label lblDenominator; + private System.Windows.Forms.TextBox txtDenominator; + private System.Windows.Forms.Button btnImport; + private System.Windows.Forms.ToolTip toolTipImport; + + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormSetFrameRate.cs b/trunk/LipSync/LipSync/Editor/FormSetFrameRate.cs new file mode 100644 index 0000000..32acf77 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormSetFrameRate.cs @@ -0,0 +1,188 @@ +/* + * FormSetFrameRate.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; +using Boare.Lib.Media; + +namespace LipSync { + + public partial class FormSetFrameRate : Form, IMultiLanguageControl { + private uint m_dwRate = 30; + private uint m_dwScale = 1; + private bool m_expanded = false; + private bool m_forbid_text_change = false; + + const int HEIGHT_EXPANDED = 224; + const int HEIGHT_FOLDED = 160; + + public FormSetFrameRate( uint rate, uint scale ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + m_expanded = false; + txtFrameRate.Enabled = !m_expanded; + txtNumerator.Enabled = m_expanded; + txtDenominator.Enabled = m_expanded; + btnImport.Enabled = m_expanded; + this.Height = HEIGHT_FOLDED; + m_dwRate = rate; + m_dwScale = scale; + txtDenominator.Text = m_dwScale + ""; + txtNumerator.Text = m_dwRate + ""; + m_forbid_text_change = true; // 最初に約分が発生するのを防ぐ + txtFrameRate.Text = (float)m_dwRate / (float)m_dwScale + ""; + m_forbid_text_change = false; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public void ApplyLanguage() { + btnExpand.Text = " " + _( "detail" ); + this.Text = _( "configure frame rate" ); + lblFrameRate.Text = _( "Frame rate" ); + btnOK.Text = _( "OK" ); + btnCancel.Text = _( "Cancel" ); + lblDenominator.Text = _( "denominator of frame rate" ); + lblNumerator.Text = _( "numerator of frame rate" ); + btnImport.Text = _( "Import" ); + toolTipImport.SetToolTip( btnImport, _( "import frame rate from AVI file" ) ); + } + + /// + /// 有理数で表したフレームレートの分子の値を取得または設定します + /// + public uint DwRate { + get { + return m_dwRate; + } + } + + /// + /// 有理数で表したフレームレートの分母の値を取得または設定します + /// + public uint DwScale { + get { + return m_dwScale; + } + } + + private void btnExpand_Click( object sender, EventArgs e ) { + m_expanded = !m_expanded; + txtFrameRate.Enabled = !m_expanded; + txtNumerator.Enabled = m_expanded; + txtDenominator.Enabled = m_expanded; + btnImport.Enabled = m_expanded; + if ( m_expanded ) { + btnExpand.Image = LipSync.Properties.Resources.opened; + this.Height = HEIGHT_EXPANDED; + } else { + btnExpand.Image = LipSync.Properties.Resources.closed; + this.Height = HEIGHT_FOLDED; + } + } + + private void txtFrameRate_TextChanged( object sender, EventArgs e ) { + if ( m_forbid_text_change ) { + return; + } + if ( !m_expanded ) { + try { + float fps = Math.Abs( float.Parse( txtFrameRate.Text ) ); + m_dwScale = 1000; + m_dwRate = (uint)(fps * m_dwScale); + uint gcd = (uint)Common.GetGCD( m_dwRate, m_dwScale ); + if ( gcd > 1 ) { + m_dwScale = m_dwScale / gcd; + m_dwRate = m_dwRate / gcd; + } + txtNumerator.Text = m_dwRate + ""; + txtDenominator.Text = m_dwScale + ""; + }catch{ + } + } + } + + private void txtNumerator_TextChanged( object sender, EventArgs e ) { + try { + uint num = uint.Parse( txtNumerator.Text ); + m_dwRate = num; + m_forbid_text_change = true; + txtFrameRate.Text = ((float)m_dwRate / (float)m_dwScale) + ""; + m_forbid_text_change = false; + } catch { + } + } + + private void txtDenominator_TextChanged( object sender, EventArgs e ) { + try { + uint den = uint.Parse( txtDenominator.Text ); + m_dwScale = den; + m_forbid_text_change = true; + txtFrameRate.Text = ((float)m_dwRate / (float)m_dwScale) + ""; + m_forbid_text_change = false; + } catch { + } + } + + private void btnImport_Click( object sender, EventArgs e ) { + using ( OpenFileDialog dlg = new OpenFileDialog() ) { + try { + dlg.Filter = _( "Avi file(*.avi)|*.avi" ) + "|" + + _( "All Files(*.*)|*.*" ); + } catch { + dlg.Filter = "Avi file(*.avi)|*.avi|All Files(*.*)|*.*"; + } + if ( dlg.ShowDialog() == DialogResult.OK ) { + AviReader ar = new AviReader(); + try { + ar.Open( dlg.FileName ); + m_dwRate = ar.dwRate; + m_dwScale = ar.dwScale; + ar.Close(); + txtNumerator.Text = m_dwRate + ""; + txtDenominator.Text = m_dwScale + ""; + } catch { + MessageBox.Show( + _( "failed getting frame rate" ), + _( "Error" ), + MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + if ( ar.Opened ) { + try { + ar.Close(); + } catch { + } + } + } + } + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + DialogResult = DialogResult.OK; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/FormVocalomark.Designer.cs b/trunk/LipSync/LipSync/Editor/FormVocalomark.Designer.cs new file mode 100644 index 0000000..511dc27 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormVocalomark.Designer.cs @@ -0,0 +1,729 @@ +namespace LipSync { + partial class FormVocalomark { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.lblLipA = new System.Windows.Forms.Label(); + this.lblLipE = new System.Windows.Forms.Label(); + this.lblLipI = new System.Windows.Forms.Label(); + this.lblLipO = new System.Windows.Forms.Label(); + this.lblLipU = new System.Windows.Forms.Label(); + this.groupLip = new System.Windows.Forms.GroupBox(); + this.label5 = new System.Windows.Forms.Label(); + this.label6 = new System.Windows.Forms.Label(); + this.txtLipBlendToDefault = new System.Windows.Forms.TextBox(); + this.lblLipBlendToDefault = new System.Windows.Forms.Label(); + this.txtLipBlendFromDefault = new System.Windows.Forms.TextBox(); + this.lblLipBlendFromDefault = new System.Windows.Forms.Label(); + this.comboLipU = new System.Windows.Forms.ComboBox(); + this.comboLipO = new System.Windows.Forms.ComboBox(); + this.comboLipI = new System.Windows.Forms.ComboBox(); + this.comboLipE = new System.Windows.Forms.ComboBox(); + this.comboLipA = new System.Windows.Forms.ComboBox(); + this.groupEye = new System.Windows.Forms.GroupBox(); + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtEyeBlendToDefault = new System.Windows.Forms.TextBox(); + this.lblEyeBlendToDefault = new System.Windows.Forms.Label(); + this.txtEyeBlendFromDefault = new System.Windows.Forms.TextBox(); + this.lblEyeBlendFromDefault = new System.Windows.Forms.Label(); + this.comboEyeWinkL = new System.Windows.Forms.ComboBox(); + this.comboEyeWinkR = new System.Windows.Forms.ComboBox(); + this.lblEyeWinkR = new System.Windows.Forms.Label(); + this.lblEyeWinkL = new System.Windows.Forms.Label(); + this.comboEyeSad = new System.Windows.Forms.ComboBox(); + this.comboEyeSerious = new System.Windows.Forms.ComboBox(); + this.comboEyeSurprise = new System.Windows.Forms.ComboBox(); + this.comboEyeSmile = new System.Windows.Forms.ComboBox(); + this.comboEyeClose = new System.Windows.Forms.ComboBox(); + this.lblEyeSad = new System.Windows.Forms.Label(); + this.lblEyeClose = new System.Windows.Forms.Label(); + this.lblEyeSerious = new System.Windows.Forms.Label(); + this.lblEyeSmile = new System.Windows.Forms.Label(); + this.lblEyeSurprise = new System.Windows.Forms.Label(); + this.groupEyebrow = new System.Windows.Forms.GroupBox(); + this.label9 = new System.Windows.Forms.Label(); + this.label10 = new System.Windows.Forms.Label(); + this.txtEyebrowBlendToDefault = new System.Windows.Forms.TextBox(); + this.lblEyebrowBlendToDefault = new System.Windows.Forms.Label(); + this.txtEyebrowBlendFromDefault = new System.Windows.Forms.TextBox(); + this.lblEyebrowBlendFromDefault = new System.Windows.Forms.Label(); + this.comboEyebrowSad = new System.Windows.Forms.ComboBox(); + this.comboEyebrowConfuse = new System.Windows.Forms.ComboBox(); + this.comboEyebrowSerious = new System.Windows.Forms.ComboBox(); + this.comboEyebrowSurprise = new System.Windows.Forms.ComboBox(); + this.lblEyebrowSurprise = new System.Windows.Forms.Label(); + this.lblEyebrowSad = new System.Windows.Forms.Label(); + this.lblEyebrowSerious = new System.Windows.Forms.Label(); + this.lblEyebrowConfuse = new System.Windows.Forms.Label(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.groupLip.SuspendLayout(); + this.groupEye.SuspendLayout(); + this.groupEyebrow.SuspendLayout(); + this.SuspendLayout(); + // + // lblLipA + // + this.lblLipA.AutoSize = true; + this.lblLipA.Location = new System.Drawing.Point( 17, 26 ); + this.lblLipA.Name = "lblLipA"; + this.lblLipA.Size = new System.Drawing.Size( 23, 12 ); + this.lblLipA.TabIndex = 2; + this.lblLipA.Text = "L_A"; + // + // lblLipE + // + this.lblLipE.AutoSize = true; + this.lblLipE.Location = new System.Drawing.Point( 17, 53 ); + this.lblLipE.Name = "lblLipE"; + this.lblLipE.Size = new System.Drawing.Size( 22, 12 ); + this.lblLipE.TabIndex = 3; + this.lblLipE.Text = "L_E"; + // + // lblLipI + // + this.lblLipI.AutoSize = true; + this.lblLipI.Location = new System.Drawing.Point( 17, 80 ); + this.lblLipI.Name = "lblLipI"; + this.lblLipI.Size = new System.Drawing.Size( 18, 12 ); + this.lblLipI.TabIndex = 4; + this.lblLipI.Text = "L_I"; + // + // lblLipO + // + this.lblLipO.AutoSize = true; + this.lblLipO.Location = new System.Drawing.Point( 17, 107 ); + this.lblLipO.Name = "lblLipO"; + this.lblLipO.Size = new System.Drawing.Size( 23, 12 ); + this.lblLipO.TabIndex = 5; + this.lblLipO.Text = "L_O"; + // + // lblLipU + // + this.lblLipU.AutoSize = true; + this.lblLipU.Location = new System.Drawing.Point( 17, 134 ); + this.lblLipU.Name = "lblLipU"; + this.lblLipU.Size = new System.Drawing.Size( 23, 12 ); + this.lblLipU.TabIndex = 6; + this.lblLipU.Text = "L_U"; + // + // groupLip + // + this.groupLip.Controls.Add( this.label5 ); + this.groupLip.Controls.Add( this.label6 ); + this.groupLip.Controls.Add( this.txtLipBlendToDefault ); + this.groupLip.Controls.Add( this.lblLipBlendToDefault ); + this.groupLip.Controls.Add( this.txtLipBlendFromDefault ); + this.groupLip.Controls.Add( this.lblLipBlendFromDefault ); + this.groupLip.Controls.Add( this.comboLipU ); + this.groupLip.Controls.Add( this.comboLipO ); + this.groupLip.Controls.Add( this.comboLipI ); + this.groupLip.Controls.Add( this.comboLipE ); + this.groupLip.Controls.Add( this.comboLipA ); + this.groupLip.Controls.Add( this.lblLipU ); + this.groupLip.Controls.Add( this.lblLipA ); + this.groupLip.Controls.Add( this.lblLipO ); + this.groupLip.Controls.Add( this.lblLipE ); + this.groupLip.Controls.Add( this.lblLipI ); + this.groupLip.Location = new System.Drawing.Point( 12, 12 ); + this.groupLip.Name = "groupLip"; + this.groupLip.Size = new System.Drawing.Size( 211, 319 ); + this.groupLip.TabIndex = 7; + this.groupLip.TabStop = false; + this.groupLip.Text = "Lip Assignment"; + // + // label5 + // + this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label5.AutoSize = true; + this.label5.Location = new System.Drawing.Point( 173, 287 ); + this.label5.Name = "label5"; + this.label5.Size = new System.Drawing.Size( 23, 12 ); + this.label5.TabIndex = 24; + this.label5.Text = "sec"; + // + // label6 + // + this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label6.AutoSize = true; + this.label6.Location = new System.Drawing.Point( 173, 241 ); + this.label6.Name = "label6"; + this.label6.Size = new System.Drawing.Size( 23, 12 ); + this.label6.TabIndex = 23; + this.label6.Text = "sec"; + // + // txtLipBlendToDefault + // + this.txtLipBlendToDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtLipBlendToDefault.Location = new System.Drawing.Point( 47, 284 ); + this.txtLipBlendToDefault.Name = "txtLipBlendToDefault"; + this.txtLipBlendToDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtLipBlendToDefault.TabIndex = 22; + this.txtLipBlendToDefault.Text = "0.2"; + this.txtLipBlendToDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtLipBlendToDefault.TextChanged += new System.EventHandler( this.txtLipBlendToDefault_TextChanged ); + // + // lblLipBlendToDefault + // + this.lblLipBlendToDefault.AutoSize = true; + this.lblLipBlendToDefault.Location = new System.Drawing.Point( 17, 269 ); + this.lblLipBlendToDefault.Name = "lblLipBlendToDefault"; + this.lblLipBlendToDefault.Size = new System.Drawing.Size( 165, 12 ); + this.lblLipBlendToDefault.TabIndex = 21; + this.lblLipBlendToDefault.Text = "Blend time for L_* -> L_Default"; + // + // txtLipBlendFromDefault + // + this.txtLipBlendFromDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtLipBlendFromDefault.Location = new System.Drawing.Point( 47, 238 ); + this.txtLipBlendFromDefault.Name = "txtLipBlendFromDefault"; + this.txtLipBlendFromDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtLipBlendFromDefault.TabIndex = 20; + this.txtLipBlendFromDefault.Text = "0.1"; + this.txtLipBlendFromDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtLipBlendFromDefault.TextChanged += new System.EventHandler( this.txtLipBlendFromDefault_TextChanged ); + // + // lblLipBlendFromDefault + // + this.lblLipBlendFromDefault.AutoSize = true; + this.lblLipBlendFromDefault.Location = new System.Drawing.Point( 17, 223 ); + this.lblLipBlendFromDefault.Name = "lblLipBlendFromDefault"; + this.lblLipBlendFromDefault.Size = new System.Drawing.Size( 165, 12 ); + this.lblLipBlendFromDefault.TabIndex = 19; + this.lblLipBlendFromDefault.Text = "Blend time for L_Default -> L_*"; + // + // comboLipU + // + this.comboLipU.FormattingEnabled = true; + this.comboLipU.Location = new System.Drawing.Point( 75, 131 ); + this.comboLipU.Name = "comboLipU"; + this.comboLipU.Size = new System.Drawing.Size( 121, 20 ); + this.comboLipU.TabIndex = 12; + // + // comboLipO + // + this.comboLipO.FormattingEnabled = true; + this.comboLipO.Location = new System.Drawing.Point( 75, 104 ); + this.comboLipO.Name = "comboLipO"; + this.comboLipO.Size = new System.Drawing.Size( 121, 20 ); + this.comboLipO.TabIndex = 11; + // + // comboLipI + // + this.comboLipI.FormattingEnabled = true; + this.comboLipI.Location = new System.Drawing.Point( 75, 77 ); + this.comboLipI.Name = "comboLipI"; + this.comboLipI.Size = new System.Drawing.Size( 121, 20 ); + this.comboLipI.TabIndex = 10; + // + // comboLipE + // + this.comboLipE.FormattingEnabled = true; + this.comboLipE.Location = new System.Drawing.Point( 75, 50 ); + this.comboLipE.Name = "comboLipE"; + this.comboLipE.Size = new System.Drawing.Size( 121, 20 ); + this.comboLipE.TabIndex = 9; + // + // comboLipA + // + this.comboLipA.FormattingEnabled = true; + this.comboLipA.Location = new System.Drawing.Point( 75, 23 ); + this.comboLipA.Name = "comboLipA"; + this.comboLipA.Size = new System.Drawing.Size( 121, 20 ); + this.comboLipA.TabIndex = 8; + // + // groupEye + // + this.groupEye.Controls.Add( this.label1 ); + this.groupEye.Controls.Add( this.label2 ); + this.groupEye.Controls.Add( this.txtEyeBlendToDefault ); + this.groupEye.Controls.Add( this.lblEyeBlendToDefault ); + this.groupEye.Controls.Add( this.txtEyeBlendFromDefault ); + this.groupEye.Controls.Add( this.lblEyeBlendFromDefault ); + this.groupEye.Controls.Add( this.comboEyeWinkL ); + this.groupEye.Controls.Add( this.comboEyeWinkR ); + this.groupEye.Controls.Add( this.lblEyeWinkR ); + this.groupEye.Controls.Add( this.lblEyeWinkL ); + this.groupEye.Controls.Add( this.comboEyeSad ); + this.groupEye.Controls.Add( this.comboEyeSerious ); + this.groupEye.Controls.Add( this.comboEyeSurprise ); + this.groupEye.Controls.Add( this.comboEyeSmile ); + this.groupEye.Controls.Add( this.comboEyeClose ); + this.groupEye.Controls.Add( this.lblEyeSad ); + this.groupEye.Controls.Add( this.lblEyeClose ); + this.groupEye.Controls.Add( this.lblEyeSerious ); + this.groupEye.Controls.Add( this.lblEyeSmile ); + this.groupEye.Controls.Add( this.lblEyeSurprise ); + this.groupEye.Location = new System.Drawing.Point( 229, 12 ); + this.groupEye.Name = "groupEye"; + this.groupEye.Size = new System.Drawing.Size( 219, 319 ); + this.groupEye.TabIndex = 8; + this.groupEye.TabStop = false; + this.groupEye.Text = "Eye Assignment"; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 173, 287 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 23, 12 ); + this.label1.TabIndex = 30; + this.label1.Text = "sec"; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point( 173, 241 ); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size( 23, 12 ); + this.label2.TabIndex = 29; + this.label2.Text = "sec"; + // + // txtEyeBlendToDefault + // + this.txtEyeBlendToDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtEyeBlendToDefault.Location = new System.Drawing.Point( 47, 284 ); + this.txtEyeBlendToDefault.Name = "txtEyeBlendToDefault"; + this.txtEyeBlendToDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtEyeBlendToDefault.TabIndex = 28; + this.txtEyeBlendToDefault.Text = "0.1"; + this.txtEyeBlendToDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtEyeBlendToDefault.TextChanged += new System.EventHandler( this.txtEyeBlendToDefault_TextChanged ); + // + // lblEyeBlendToDefault + // + this.lblEyeBlendToDefault.AutoSize = true; + this.lblEyeBlendToDefault.Location = new System.Drawing.Point( 17, 269 ); + this.lblEyeBlendToDefault.Name = "lblEyeBlendToDefault"; + this.lblEyeBlendToDefault.Size = new System.Drawing.Size( 167, 12 ); + this.lblEyeBlendToDefault.TabIndex = 27; + this.lblEyeBlendToDefault.Text = "Blend time for E_* -> E_Default"; + // + // txtEyeBlendFromDefault + // + this.txtEyeBlendFromDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtEyeBlendFromDefault.Location = new System.Drawing.Point( 47, 238 ); + this.txtEyeBlendFromDefault.Name = "txtEyeBlendFromDefault"; + this.txtEyeBlendFromDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtEyeBlendFromDefault.TabIndex = 26; + this.txtEyeBlendFromDefault.Text = "0.05"; + this.txtEyeBlendFromDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtEyeBlendFromDefault.TextChanged += new System.EventHandler( this.txtEyeBlendFromDefault_TextChanged ); + // + // lblEyeBlendFromDefault + // + this.lblEyeBlendFromDefault.AutoSize = true; + this.lblEyeBlendFromDefault.Location = new System.Drawing.Point( 17, 223 ); + this.lblEyeBlendFromDefault.Name = "lblEyeBlendFromDefault"; + this.lblEyeBlendFromDefault.Size = new System.Drawing.Size( 167, 12 ); + this.lblEyeBlendFromDefault.TabIndex = 25; + this.lblEyeBlendFromDefault.Text = "Blend time for E_Default -> E_*"; + // + // comboEyeWinkL + // + this.comboEyeWinkL.FormattingEnabled = true; + this.comboEyeWinkL.Location = new System.Drawing.Point( 81, 185 ); + this.comboEyeWinkL.Name = "comboEyeWinkL"; + this.comboEyeWinkL.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeWinkL.TabIndex = 18; + // + // comboEyeWinkR + // + this.comboEyeWinkR.FormattingEnabled = true; + this.comboEyeWinkR.Location = new System.Drawing.Point( 81, 158 ); + this.comboEyeWinkR.Name = "comboEyeWinkR"; + this.comboEyeWinkR.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeWinkR.TabIndex = 17; + // + // lblEyeWinkR + // + this.lblEyeWinkR.AutoSize = true; + this.lblEyeWinkR.Location = new System.Drawing.Point( 17, 161 ); + this.lblEyeWinkR.Name = "lblEyeWinkR"; + this.lblEyeWinkR.Size = new System.Drawing.Size( 48, 12 ); + this.lblEyeWinkR.TabIndex = 15; + this.lblEyeWinkR.Text = "E_WinkR"; + // + // lblEyeWinkL + // + this.lblEyeWinkL.AutoSize = true; + this.lblEyeWinkL.Location = new System.Drawing.Point( 17, 188 ); + this.lblEyeWinkL.Name = "lblEyeWinkL"; + this.lblEyeWinkL.Size = new System.Drawing.Size( 46, 12 ); + this.lblEyeWinkL.TabIndex = 14; + this.lblEyeWinkL.Text = "E_WinkL"; + // + // comboEyeSad + // + this.comboEyeSad.FormattingEnabled = true; + this.comboEyeSad.Location = new System.Drawing.Point( 81, 131 ); + this.comboEyeSad.Name = "comboEyeSad"; + this.comboEyeSad.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeSad.TabIndex = 12; + // + // comboEyeSerious + // + this.comboEyeSerious.FormattingEnabled = true; + this.comboEyeSerious.Location = new System.Drawing.Point( 81, 104 ); + this.comboEyeSerious.Name = "comboEyeSerious"; + this.comboEyeSerious.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeSerious.TabIndex = 11; + // + // comboEyeSurprise + // + this.comboEyeSurprise.FormattingEnabled = true; + this.comboEyeSurprise.Location = new System.Drawing.Point( 81, 77 ); + this.comboEyeSurprise.Name = "comboEyeSurprise"; + this.comboEyeSurprise.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeSurprise.TabIndex = 10; + // + // comboEyeSmile + // + this.comboEyeSmile.FormattingEnabled = true; + this.comboEyeSmile.Location = new System.Drawing.Point( 81, 50 ); + this.comboEyeSmile.Name = "comboEyeSmile"; + this.comboEyeSmile.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeSmile.TabIndex = 9; + // + // comboEyeClose + // + this.comboEyeClose.FormattingEnabled = true; + this.comboEyeClose.Location = new System.Drawing.Point( 81, 23 ); + this.comboEyeClose.Name = "comboEyeClose"; + this.comboEyeClose.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyeClose.TabIndex = 8; + // + // lblEyeSad + // + this.lblEyeSad.AutoSize = true; + this.lblEyeSad.Location = new System.Drawing.Point( 17, 134 ); + this.lblEyeSad.Name = "lblEyeSad"; + this.lblEyeSad.Size = new System.Drawing.Size( 35, 12 ); + this.lblEyeSad.TabIndex = 6; + this.lblEyeSad.Text = "E_Sad"; + // + // lblEyeClose + // + this.lblEyeClose.AutoSize = true; + this.lblEyeClose.Location = new System.Drawing.Point( 17, 26 ); + this.lblEyeClose.Name = "lblEyeClose"; + this.lblEyeClose.Size = new System.Drawing.Size( 45, 12 ); + this.lblEyeClose.TabIndex = 2; + this.lblEyeClose.Text = "E_Close"; + // + // lblEyeSerious + // + this.lblEyeSerious.AutoSize = true; + this.lblEyeSerious.Location = new System.Drawing.Point( 17, 107 ); + this.lblEyeSerious.Name = "lblEyeSerious"; + this.lblEyeSerious.Size = new System.Drawing.Size( 54, 12 ); + this.lblEyeSerious.TabIndex = 5; + this.lblEyeSerious.Text = "E_Serious"; + // + // lblEyeSmile + // + this.lblEyeSmile.AutoSize = true; + this.lblEyeSmile.Location = new System.Drawing.Point( 17, 53 ); + this.lblEyeSmile.Name = "lblEyeSmile"; + this.lblEyeSmile.Size = new System.Drawing.Size( 44, 12 ); + this.lblEyeSmile.TabIndex = 3; + this.lblEyeSmile.Text = "E_Smile"; + // + // lblEyeSurprise + // + this.lblEyeSurprise.AutoSize = true; + this.lblEyeSurprise.Location = new System.Drawing.Point( 17, 80 ); + this.lblEyeSurprise.Name = "lblEyeSurprise"; + this.lblEyeSurprise.Size = new System.Drawing.Size( 58, 12 ); + this.lblEyeSurprise.TabIndex = 4; + this.lblEyeSurprise.Text = "E_Surprise"; + // + // groupEyebrow + // + this.groupEyebrow.Controls.Add( this.label9 ); + this.groupEyebrow.Controls.Add( this.label10 ); + this.groupEyebrow.Controls.Add( this.txtEyebrowBlendToDefault ); + this.groupEyebrow.Controls.Add( this.lblEyebrowBlendToDefault ); + this.groupEyebrow.Controls.Add( this.txtEyebrowBlendFromDefault ); + this.groupEyebrow.Controls.Add( this.lblEyebrowBlendFromDefault ); + this.groupEyebrow.Controls.Add( this.comboEyebrowSad ); + this.groupEyebrow.Controls.Add( this.comboEyebrowConfuse ); + this.groupEyebrow.Controls.Add( this.comboEyebrowSerious ); + this.groupEyebrow.Controls.Add( this.comboEyebrowSurprise ); + this.groupEyebrow.Controls.Add( this.lblEyebrowSurprise ); + this.groupEyebrow.Controls.Add( this.lblEyebrowSad ); + this.groupEyebrow.Controls.Add( this.lblEyebrowSerious ); + this.groupEyebrow.Controls.Add( this.lblEyebrowConfuse ); + this.groupEyebrow.Location = new System.Drawing.Point( 454, 12 ); + this.groupEyebrow.Name = "groupEyebrow"; + this.groupEyebrow.Size = new System.Drawing.Size( 228, 319 ); + this.groupEyebrow.TabIndex = 9; + this.groupEyebrow.TabStop = false; + this.groupEyebrow.Text = "Eyebrow Assignment"; + // + // label9 + // + this.label9.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label9.AutoSize = true; + this.label9.Location = new System.Drawing.Point( 173, 287 ); + this.label9.Name = "label9"; + this.label9.Size = new System.Drawing.Size( 23, 12 ); + this.label9.TabIndex = 30; + this.label9.Text = "sec"; + // + // label10 + // + this.label10.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label10.AutoSize = true; + this.label10.Location = new System.Drawing.Point( 173, 241 ); + this.label10.Name = "label10"; + this.label10.Size = new System.Drawing.Size( 23, 12 ); + this.label10.TabIndex = 29; + this.label10.Text = "sec"; + // + // txtEyebrowBlendToDefault + // + this.txtEyebrowBlendToDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtEyebrowBlendToDefault.Location = new System.Drawing.Point( 47, 284 ); + this.txtEyebrowBlendToDefault.Name = "txtEyebrowBlendToDefault"; + this.txtEyebrowBlendToDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtEyebrowBlendToDefault.TabIndex = 28; + this.txtEyebrowBlendToDefault.Text = "0.1"; + this.txtEyebrowBlendToDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtEyebrowBlendToDefault.TextChanged += new System.EventHandler( this.txtEyebrowBlendToDefault_TextChanged ); + // + // lblEyebrowBlendToDefault + // + this.lblEyebrowBlendToDefault.AutoSize = true; + this.lblEyebrowBlendToDefault.Location = new System.Drawing.Point( 17, 269 ); + this.lblEyebrowBlendToDefault.Name = "lblEyebrowBlendToDefault"; + this.lblEyebrowBlendToDefault.Size = new System.Drawing.Size( 183, 12 ); + this.lblEyebrowBlendToDefault.TabIndex = 27; + this.lblEyebrowBlendToDefault.Text = "Blend time for EB_* -> EB_Default"; + // + // txtEyebrowBlendFromDefault + // + this.txtEyebrowBlendFromDefault.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtEyebrowBlendFromDefault.Location = new System.Drawing.Point( 47, 238 ); + this.txtEyebrowBlendFromDefault.Name = "txtEyebrowBlendFromDefault"; + this.txtEyebrowBlendFromDefault.Size = new System.Drawing.Size( 120, 19 ); + this.txtEyebrowBlendFromDefault.TabIndex = 26; + this.txtEyebrowBlendFromDefault.Text = "0.1"; + this.txtEyebrowBlendFromDefault.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + this.txtEyebrowBlendFromDefault.TextChanged += new System.EventHandler( this.txtEyebrowBlendFromDefault_TextChanged ); + // + // lblEyebrowBlendFromDefault + // + this.lblEyebrowBlendFromDefault.AutoSize = true; + this.lblEyebrowBlendFromDefault.Location = new System.Drawing.Point( 17, 223 ); + this.lblEyebrowBlendFromDefault.Name = "lblEyebrowBlendFromDefault"; + this.lblEyebrowBlendFromDefault.Size = new System.Drawing.Size( 183, 12 ); + this.lblEyebrowBlendFromDefault.TabIndex = 25; + this.lblEyebrowBlendFromDefault.Text = "Blend time for EB_Default -> EB_*"; + // + // comboEyebrowSad + // + this.comboEyebrowSad.FormattingEnabled = true; + this.comboEyebrowSad.Location = new System.Drawing.Point( 90, 102 ); + this.comboEyebrowSad.Name = "comboEyebrowSad"; + this.comboEyebrowSad.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyebrowSad.TabIndex = 11; + // + // comboEyebrowConfuse + // + this.comboEyebrowConfuse.FormattingEnabled = true; + this.comboEyebrowConfuse.Location = new System.Drawing.Point( 90, 76 ); + this.comboEyebrowConfuse.Name = "comboEyebrowConfuse"; + this.comboEyebrowConfuse.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyebrowConfuse.TabIndex = 10; + // + // comboEyebrowSerious + // + this.comboEyebrowSerious.FormattingEnabled = true; + this.comboEyebrowSerious.Location = new System.Drawing.Point( 90, 50 ); + this.comboEyebrowSerious.Name = "comboEyebrowSerious"; + this.comboEyebrowSerious.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyebrowSerious.TabIndex = 9; + // + // comboEyebrowSurprise + // + this.comboEyebrowSurprise.FormattingEnabled = true; + this.comboEyebrowSurprise.Location = new System.Drawing.Point( 90, 23 ); + this.comboEyebrowSurprise.Name = "comboEyebrowSurprise"; + this.comboEyebrowSurprise.Size = new System.Drawing.Size( 121, 20 ); + this.comboEyebrowSurprise.TabIndex = 8; + // + // lblEyebrowSurprise + // + this.lblEyebrowSurprise.AutoSize = true; + this.lblEyebrowSurprise.Location = new System.Drawing.Point( 17, 26 ); + this.lblEyebrowSurprise.Name = "lblEyebrowSurprise"; + this.lblEyebrowSurprise.Size = new System.Drawing.Size( 66, 12 ); + this.lblEyebrowSurprise.TabIndex = 2; + this.lblEyebrowSurprise.Text = "EB_Surprise"; + // + // lblEyebrowSad + // + this.lblEyebrowSad.AutoSize = true; + this.lblEyebrowSad.Location = new System.Drawing.Point( 17, 107 ); + this.lblEyebrowSad.Name = "lblEyebrowSad"; + this.lblEyebrowSad.Size = new System.Drawing.Size( 43, 12 ); + this.lblEyebrowSad.TabIndex = 5; + this.lblEyebrowSad.Text = "EB_Sad"; + // + // lblEyebrowSerious + // + this.lblEyebrowSerious.AutoSize = true; + this.lblEyebrowSerious.Location = new System.Drawing.Point( 17, 53 ); + this.lblEyebrowSerious.Name = "lblEyebrowSerious"; + this.lblEyebrowSerious.Size = new System.Drawing.Size( 62, 12 ); + this.lblEyebrowSerious.TabIndex = 3; + this.lblEyebrowSerious.Text = "EB_Serious"; + // + // lblEyebrowConfuse + // + this.lblEyebrowConfuse.AutoSize = true; + this.lblEyebrowConfuse.Location = new System.Drawing.Point( 17, 80 ); + this.lblEyebrowConfuse.Name = "lblEyebrowConfuse"; + this.lblEyebrowConfuse.Size = new System.Drawing.Size( 66, 12 ); + this.lblEyebrowConfuse.TabIndex = 4; + this.lblEyebrowConfuse.Text = "EB_Confuse"; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 518, 353 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 10; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 607, 353 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 11; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // FormVocalomark + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 693, 388 ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.groupEye ); + this.Controls.Add( this.groupLip ); + this.Controls.Add( this.groupEyebrow ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FormVocalomark"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "FormVocalomark"; + this.groupLip.ResumeLayout( false ); + this.groupLip.PerformLayout(); + this.groupEye.ResumeLayout( false ); + this.groupEye.PerformLayout(); + this.groupEyebrow.ResumeLayout( false ); + this.groupEyebrow.PerformLayout(); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.Label lblLipA; + private System.Windows.Forms.Label lblLipE; + private System.Windows.Forms.Label lblLipI; + private System.Windows.Forms.Label lblLipO; + private System.Windows.Forms.Label lblLipU; + private System.Windows.Forms.GroupBox groupLip; + private System.Windows.Forms.ComboBox comboLipA; + private System.Windows.Forms.ComboBox comboLipU; + private System.Windows.Forms.ComboBox comboLipO; + private System.Windows.Forms.ComboBox comboLipI; + private System.Windows.Forms.ComboBox comboLipE; + private System.Windows.Forms.GroupBox groupEye; + private System.Windows.Forms.ComboBox comboEyeSad; + private System.Windows.Forms.ComboBox comboEyeSerious; + private System.Windows.Forms.ComboBox comboEyeSurprise; + private System.Windows.Forms.ComboBox comboEyeSmile; + private System.Windows.Forms.ComboBox comboEyeClose; + private System.Windows.Forms.Label lblEyeSad; + private System.Windows.Forms.Label lblEyeClose; + private System.Windows.Forms.Label lblEyeSerious; + private System.Windows.Forms.Label lblEyeSmile; + private System.Windows.Forms.Label lblEyeSurprise; + private System.Windows.Forms.GroupBox groupEyebrow; + private System.Windows.Forms.ComboBox comboEyebrowSad; + private System.Windows.Forms.ComboBox comboEyebrowConfuse; + private System.Windows.Forms.ComboBox comboEyebrowSerious; + private System.Windows.Forms.ComboBox comboEyebrowSurprise; + private System.Windows.Forms.Label lblEyebrowSurprise; + private System.Windows.Forms.Label lblEyebrowSad; + private System.Windows.Forms.Label lblEyebrowSerious; + private System.Windows.Forms.Label lblEyebrowConfuse; + private System.Windows.Forms.Label lblEyeWinkR; + private System.Windows.Forms.Label lblEyeWinkL; + private System.Windows.Forms.ComboBox comboEyeWinkR; + private System.Windows.Forms.ComboBox comboEyeWinkL; + private System.Windows.Forms.Label label5; + private System.Windows.Forms.Label label6; + private System.Windows.Forms.TextBox txtLipBlendToDefault; + private System.Windows.Forms.Label lblLipBlendToDefault; + private System.Windows.Forms.TextBox txtLipBlendFromDefault; + private System.Windows.Forms.Label lblLipBlendFromDefault; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtEyeBlendToDefault; + private System.Windows.Forms.Label lblEyeBlendToDefault; + private System.Windows.Forms.TextBox txtEyeBlendFromDefault; + private System.Windows.Forms.Label lblEyeBlendFromDefault; + private System.Windows.Forms.Label label9; + private System.Windows.Forms.Label label10; + private System.Windows.Forms.TextBox txtEyebrowBlendToDefault; + private System.Windows.Forms.Label lblEyebrowBlendToDefault; + private System.Windows.Forms.TextBox txtEyebrowBlendFromDefault; + private System.Windows.Forms.Label lblEyebrowBlendFromDefault; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/FormVocalomark.cs b/trunk/LipSync/LipSync/Editor/FormVocalomark.cs new file mode 100644 index 0000000..c6ae596 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/FormVocalomark.cs @@ -0,0 +1,198 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class FormVocalomark : Form, IMultiLanguageControl { + private string[] m_image_titles; + public float BlendLipFromDefault = 0.1f; + public float BlendLipToDefault = 0.2f; + public float BlendEyeFromDefault = 0.05f; + public float BlendEyeToDefault = 0.1f; + public float BlendEyebrowFromDefault = 0.1f; + public float BlendEyebrowToDefault = 0.1f; + + public FormVocalomark( Character3 character ) { + InitializeComponent(); + ApplyFont( AppManager.Config.Font.GetFont() ); + ApplyLanguage(); + m_image_titles = new string[character.Count + 1]; + m_image_titles[0] = ""; + for ( int i = 0; i < character.Count; i++ ) { + m_image_titles[i + 1] = character[i].title; + } + comboLipA.Items.AddRange( m_image_titles ); + comboLipE.Items.AddRange( m_image_titles ); + comboLipI.Items.AddRange( m_image_titles ); + comboLipO.Items.AddRange( m_image_titles ); + comboLipU.Items.AddRange( m_image_titles ); + for ( int i = 0; i < m_image_titles.Length; i++ ) { + switch ( m_image_titles[i] ) { + case "a": + comboLipA.SelectedIndex = i; + break; + case "e": + comboLipE.SelectedIndex = i; + break; + case "i": + comboLipI.SelectedIndex = i; + break; + case "o": + comboLipO.SelectedIndex = i; + break; + case "u": + comboLipU.SelectedIndex = i; + break; + } + } + + comboEyeClose.Items.AddRange( m_image_titles ); + comboEyeSad.Items.AddRange( m_image_titles ); + comboEyeSerious.Items.AddRange( m_image_titles ); + comboEyeSmile.Items.AddRange( m_image_titles ); + comboEyeSurprise.Items.AddRange( m_image_titles ); + comboEyeWinkL.Items.AddRange( m_image_titles ); + comboEyeWinkR.Items.AddRange( m_image_titles ); + + comboEyebrowConfuse.Items.AddRange( m_image_titles ); + comboEyebrowSad.Items.AddRange( m_image_titles ); + comboEyebrowSerious.Items.AddRange( m_image_titles ); + comboEyebrowSurprise.Items.AddRange( m_image_titles ); + + txtLipBlendFromDefault.Text = BlendLipFromDefault.ToString(); + txtLipBlendToDefault.Text = BlendLipToDefault.ToString(); + txtEyeBlendFromDefault.Text = BlendEyeFromDefault.ToString(); + txtEyeBlendToDefault.Text = BlendEyeToDefault.ToString(); + txtEyebrowBlendFromDefault.Text = BlendEyebrowFromDefault.ToString(); + txtEyebrowBlendToDefault.Text = BlendEyebrowToDefault.ToString(); + } + + private static string _( string id ) { + return Messaging.GetMessage( id ); + } + + public void ApplyLanguage() { + groupLip.Text = _( "Lip Assignment" ); + groupEye.Text = _( "Eye Assignment" ); + groupEyebrow.Text = _( "Eyebrow Assignment" ); + btnOK.Text = _( "OK" ); + btnCancel.Text = _( "Cancel" ); + lblEyeBlendFromDefault.Text = _( "Blend time for E_Default -> E_*" ); + lblEyeBlendToDefault.Text = _( "Blend time for E_* -> E_Default" ); + lblEyebrowBlendFromDefault.Text = _( "Blend time for EB_Default -> EB_*" ); + lblEyebrowBlendToDefault.Text = _( "Blend time for EB_* -> EB_Default" ); + lblLipBlendFromDefault.Text = _( "Blend time for L_Default -> L_*" ); + lblLipBlendToDefault.Text = _( "Blend time for L_* -> L_Default" ); + } + + public void ApplyFont( Font font ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( this, font ); + } + + public KeyValuePair[] Assignment { + get { + List> ret = new List>(); + if ( comboLipA.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "L_A", m_image_titles[comboLipA.SelectedIndex] ) ); + } + if ( comboLipE.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "L_E", m_image_titles[comboLipE.SelectedIndex] ) ); + } + if ( comboLipI.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "L_I", m_image_titles[comboLipI.SelectedIndex] ) ); + } + if ( comboLipO.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "L_O", m_image_titles[comboLipO.SelectedIndex] ) ); + } + if ( comboLipU.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "L_U", m_image_titles[comboLipU.SelectedIndex] ) ); + } + if ( comboEyebrowConfuse.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "EB_Confuse", m_image_titles[comboEyebrowConfuse.SelectedIndex] ) ); + } + if ( comboEyebrowSad.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "EB_Sad", m_image_titles[comboEyebrowSad.SelectedIndex] ) ); + } + if ( comboEyebrowSerious.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "EB_Serious", m_image_titles[comboEyebrowSerious.SelectedIndex] ) ); + } + if ( comboEyebrowSurprise.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "EB_Surprise", m_image_titles[comboEyebrowSurprise.SelectedIndex] ) ); + } + if ( comboEyeClose.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_Close", m_image_titles[comboEyeClose.SelectedIndex] ) ); + } + if ( comboEyeSad.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_Sad", m_image_titles[comboEyeSad.SelectedIndex] ) ); + } + if ( comboEyeSerious.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_Serious", m_image_titles[comboEyeSerious.SelectedIndex] ) ); + } + if ( comboEyeSmile.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_Smile", m_image_titles[comboEyeSmile.SelectedIndex] ) ); + } + if ( comboEyeSurprise.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_Surprise", m_image_titles[comboEyeSurprise.SelectedIndex] ) ); + } + if ( comboEyeWinkL.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_WinkL", m_image_titles[comboEyeWinkL.SelectedIndex] ) ); + } + if ( comboEyeWinkR.SelectedIndex > 0 ) { + ret.Add( new KeyValuePair( "E_WinkR", m_image_titles[comboEyeWinkR.SelectedIndex] ) ); + } + return ret.ToArray(); + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + } + + private void txtLipBlendFromDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtLipBlendFromDefault.Text, out value ) ) { + BlendLipFromDefault = value; + } + } + + private void txtLipBlendToDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtLipBlendToDefault.Text, out value ) ) { + BlendLipToDefault = value; + } + } + + private void txtEyeBlendFromDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtEyeBlendFromDefault.Text, out value ) ) { + BlendEyeFromDefault = value; + } + } + + private void txtEyeBlendToDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtEyeBlendToDefault.Text, out value ) ){ + BlendEyeToDefault = value; + } + } + + private void txtEyebrowBlendFromDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtEyebrowBlendFromDefault.Text, out value ) ) { + BlendEyebrowFromDefault = value; + } + } + + private void txtEyebrowBlendToDefault_TextChanged( object sender, EventArgs e ) { + float value; + if ( float.TryParse( txtEyebrowBlendToDefault.Text, out value ) ) { + BlendEyebrowToDefault = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/GenerateCharacter.cs b/trunk/LipSync/LipSync/Editor/GenerateCharacter.cs new file mode 100644 index 0000000..d618445 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/GenerateCharacter.cs @@ -0,0 +1,931 @@ +/* + * GenerateCharacter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class GenerateCharacter : Form, IMultiLanguageControl { + //Character3 m_table_group.Character; + private TimeTableGroup m_table_group; + private bool m_setTrans = false; // 透過色を設定している時に立つフラグ + bool m_loading = true; + string m_last_path = ""; + PictureBox m_dlg_picture; + string m_selected_path; + string m_last_image_folder = ""; + ExtensibleDialogs.OpenFileDialog m_heavy_dialog; + bool m_abort_thread = false; + + public GenerateCharacter( TimeTableGroup table_group ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + //m_table_group.Character = (Character3)character.Clone(); + m_table_group = (TimeTableGroup)table_group.Clone(); + this.menuFileOpen.Enabled = false; + columnTag.Width = 50; + columnTitle.Width = 130; +#if DEBUG + menuEditDebugEditVersionInfo.Visible = true; +#endif + } + + public GenerateCharacter( Character3 character ) { + m_table_group = new TimeTableGroup( character.Name, 0, character ); + m_table_group.list.Clear(); + for ( int i = 0; i < character.Count; i++ ) { + m_table_group.list.Add( new TimeTable( character[i].title, 0, TimeTableType.character, null ) ); + } + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + this.menuFileOpen.Enabled = true; + columnTag.Width = 50; + columnTitle.Width = 130; +#if DEBUG + menuEditDebugEditVersionInfo.Visible = true; +#endif + } + + public void ApplyLanguage() { + this.lblTitle.Text = _( "Title" ); + this.lblTag.Text = _( "Tag" ); + this.columnTag.Text = _( "Tag" ); + this.columnTitle.Text = _( "Title" ); + this.btnUp.Text = _( "Up" ); + this.btnDown.Text = _( "Down" ); + this.btnAdd.Text = _( "Add" ); + this.btnOK.Text = _( "OK" ); + this.btnCancel.Text = _( "Cancel" ); + this.menuSetImage.Text = _( "Select image file" ); + this.menuTransparent.Text = _( "Select transparent color" ); + this.menuFile.Text = _( "File" ) + "(&F)"; + this.menuFileOpen.Text = _( "Open" ) + "(&O)"; + this.menuFileSave.Text = _( "Save" ) + "(&S)"; + this.label2.Text = _( "Character name" ); + this.Text = _( "Edit character" ); + this.menuEditTitle.Text = _( "Change title" ); + this.menuDelete.Text = _( "Delete" ); + this.groupBox1.Text = _( "Selected image" ); + + this.menuFileImport.Text = _( "Import" ) + "(&I)"; + this.menuFileImportRsi.Text = _( "Open *.rsi" ) + "(&R)"; + + this.menuFileExport.Text = _( "Export" ) + "(&E)"; + this.menuFileExportRsi.Text = _( "Save as *.rsi" ) + "(&R)"; + this.menuFileExportXml.Text = _( "Save as XML" ) + "(&X)"; + + try { + this.openLsc.Filter = _( "LipSync Character Config(*.lsc)|*.lsc" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + this.openLsc.Filter = "LipSync Character Config(*.lsc)|*.lsc|All Files(*.*)|*.*"; + } + try { + this.saveLsc.Filter = _( "LipSync Character Config(*.lsc)|*.lsc" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + this.saveLsc.Filter = "LipSync Character Config(*.lsc)|*.lsc|All Files(*.*)|*.*"; + } + this.menuReset.Text = _( "Reset image" ); + try { + this.openRsi.Filter = _( "RipSync Image(*.rsi)|*.rsi" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + this.openRsi.Filter = "RipSync Image(*.rsi)|*.rsi|All Files(*.*)|*.*"; + } + try { + this.saveRsi.Filter = _( "RipSync Image(*.rsi)|*.rsi" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + this.saveRsi.Filter = "RipSync Image(*.rsi)|*.rsi|All Files(*.*)|*.*" ; + } + this.menuEdit.Text = _( "Edit" ) + "(&E)"; + this.menuEditAdd.Text = _( "Add" ); + this.menuEditDelete.Text = _( "Delete" ); + this.menuEditDown.Text = _( "Down" ); + this.menuEditEditTitle.Text = _( "Change title" ); + this.menuEditReset.Text = _( "Reset image" ); + this.menuEditSetImage.Text = _( "Set image" ); + this.menuEditTransparent.Text = _( "Select transparent color" ); + this.menuEditUp.Text = _( "Up" ); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public TimeTableGroup EditedResult { + get { + return m_table_group; + } + } + /*public Character3 EditedResult { + get { + return m_table_group.Character; + } + }*/ + + public string LastPath { + get { + return m_last_path; + } + set { + m_last_path = value; + } + } + + private void picturePreview_DoubleClick( object sender, EventArgs e ) { + SetImage(); + } + + private void menuFileSave_Click( object sender, EventArgs e ) { + try { + saveLsc.Filter = _( "LipSync Character Config(*.lsc)|*.lsc" ) + "|" + _( "All Files(*.*)|*.*" ); + } catch { + saveLsc.Filter = "LipSync Character Config(*.lsc)|*.lsc|All Files(*.*)|*.*"; + } + if ( saveLsc.ShowDialog() == DialogResult.OK ) { + m_last_path = saveLsc.FileName; + using ( FileStream fs = new FileStream( saveLsc.FileName, FileMode.Create ) ) { + m_table_group.Character.Write( fs ); + } + } + } + + private void menuFileOpen_Click( object sender, EventArgs e ) { + bool dialog_result = false; + string f1 = _( "LipSync Character Config(*.lsc)|*.lsc" ); + string f2 = _( "LipSync Character Config(content.xml)|content.xml" ); + string f3 = _( "All Files(*.*)|*.*" ); + string filter = f1 + "|" + f2 + "|" + f3; + string def_filter = "LipSync Character Config(*.lsc)|*.lsc|LipSync Character Config(content.xml)|content.xml|All Files(*.*)|*.*"; + //string path = ""; + if ( AppManager.Config.UseHeavyDialogInOpeningCharacterSettings ) { + Panel p = new Panel(); + p.BorderStyle = BorderStyle.Fixed3D; + m_dlg_picture = new PictureBox(); + p.Controls.Add( m_dlg_picture ); + m_dlg_picture.Dock = DockStyle.Fill; + m_dlg_picture.SizeMode = PictureBoxSizeMode.Zoom; + + // filterの有効性をまずチェック + try { + OpenFileDialog d = new OpenFileDialog(); + d.Filter = filter; + } catch { + filter = def_filter; + } + + m_heavy_dialog = new ExtensibleDialogs.OpenFileDialog( p ); + m_heavy_dialog.DefaultExt = "lsc"; + m_heavy_dialog.FileName = m_last_path; + m_heavy_dialog.Filter = filter; + + m_heavy_dialog.SelectionChanged += new ExtensibleDialogs.OpenFileDialog.SelectionChangedHandler( dlg_SelectionChanged ); + m_heavy_dialog.FolderChanged += new ExtensibleDialogs.OpenFileDialog.FolderChangedHandler( dlg_FolderChanged ); + m_abort_thread = false; + bgWork.RunWorkerAsync( m_last_path ); + if ( m_heavy_dialog.ShowDialog() == DialogResult.OK ) { + dialog_result = true; + } else { + dialog_result = false; + } + m_abort_thread = true; + } else { + try { + openLsc.Filter = filter; + } catch { + openLsc.Filter = def_filter; + } + openLsc.FileName = m_last_path; + if ( openLsc.ShowDialog() == DialogResult.OK ) { + dialog_result = true; + } else { + dialog_result = false; + } + m_selected_path = openLsc.FileName; + } + if ( dialog_result ) { + Bitmap preview; + FileStream fs = null; + try { + if ( Path.GetFileName( m_selected_path ).ToLower() == "content.xml" ) { + m_table_group.Character = Character3.FromXml( m_selected_path ); + } else { + fs = new FileStream( m_selected_path, FileMode.Open ); + BinaryFormatter bf = new BinaryFormatter(); + m_table_group.Character = (Character3)bf.Deserialize( fs ); + fs.Close(); + } + } catch ( Exception ex1 ) { +#if DEBUG + MessageBox.Show( "GenerateCharacter.menuFileOpen_Click; ex1=" + ex1.ToString() ); +#endif + if ( fs != null ) { + fs.Close(); + } + try { + LipSync.Character t = LipSync.Character.FromFile( m_selected_path ); + m_table_group.Character = new Character3( t ); + } catch ( Exception ex3 ) { +#if DEBUG + MessageBox.Show( "GenerateCharacter.menuFileOpen_Click; ex3=" + ex3.ToString() ); +#endif + MessageBox.Show( _( "Failed file reading" ) ); + return; + } + } + if ( m_table_group.Character != null ) { + picturePreview.Image = m_table_group.Character.DefaultFace; + } + update(); + m_last_path = m_selected_path; + } + } + + private void bgWork_DoWork( object sender, DoWorkEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "bgWork_DoWork; start..." ); +#endif + string file = (string)e.Argument; + if ( file == "" ) { +#if DEBUG + Common.DebugWriteLine( "bgWork_DoWork; ...complete" ); +#endif + return; + } + string folder; + if ( Directory.Exists( file ) ) { + folder = file; + } else { + folder = Path.GetDirectoryName( file ); + } + if ( !Directory.Exists( folder ) ) { +#if DEBUG + Common.DebugWriteLine( "bgWork_DoWork; ...complete" ); +#endif + return; + } + string[] file_lsc = Directory.GetFiles( folder, "*.lsc", SearchOption.TopDirectoryOnly ); + string[] file_xml = Directory.GetFiles( folder, "content.xml", SearchOption.TopDirectoryOnly ); + List files = new List( file_lsc ); + files.AddRange( file_xml ); + //m_dictionaty.Clear(); + foreach ( string f in files ) { + if ( m_abort_thread ) { + break; + } + CharacterConfigCollection.Register( f ); + } + m_abort_thread = false; +#if DEBUG + Common.DebugWriteLine( "bgWork_DoWork; ...complete" ); +#endif + } + + void dlg_FolderChanged( string path ) { +#if DEBUG + Common.DebugWriteLine( "dlg_FolderChanged; path=" + path ); +#endif + if ( bgWork.IsBusy ) { + m_abort_thread = true; + while ( bgWork.IsBusy ) { + Application.DoEvents(); + } + } + m_abort_thread = false; + bgWork.RunWorkerAsync( path ); + } + + void dlg_SelectionChanged( string path ) { + if ( !File.Exists( path ) ) { + return; + } + m_selected_path = path; + string file = Path.GetFileName( path ); + StringFormat sf = new StringFormat(); + sf.Alignment = StringAlignment.Center; + sf.LineAlignment = StringAlignment.Center; + if ( CharacterConfigCollection.IsRegistered( path ) ) { + Image img = CharacterConfigCollection.GetPreviewImage( path ); + if ( img != null ) { + m_dlg_picture.Image = img; + } else { + m_dlg_picture.Image = new Bitmap( m_dlg_picture.Width, m_dlg_picture.Height ); + using ( Graphics g = Graphics.FromImage( m_dlg_picture.Image ) ) { + g.DrawString( + "preview unavailable", + new Font( "Arial", 11 ), + Brushes.Black, + new RectangleF( 0, 0, m_dlg_picture.Width, m_dlg_picture.Height ), + sf ); + } + } + } else { + m_dlg_picture.Image = new Bitmap( m_dlg_picture.Width, m_dlg_picture.Height ); + using ( Graphics g = Graphics.FromImage( m_dlg_picture.Image ) ) { + g.DrawString( + "loading ...", + new Font( "Arial", 11 ), + Brushes.Black, + new RectangleF( 0, 0, m_dlg_picture.Width, m_dlg_picture.Height ), + sf ); + } + } + } + + /// + /// 現在のm_table_group.Characterの内容を、listView1に適用します + /// + private void update() { + if ( m_table_group.Character == null ) { + return; + } + m_loading = true; + textBox1.Text = m_table_group.Character.Name; + string title = SelectedTitle; + + // 登録する. + listView1.Items.Clear(); + for ( int i = 0; i < m_table_group.Character.Count; i++ ) { + ListViewItem adding = new ListViewItem( new string[] { m_table_group.Character[i].title, m_table_group.Character[i].tag } ); + adding.Checked = m_table_group.Character[i].IsDefault; // AddしてからCheckedを変更すると,イベントが発生してめんどい. + listView1.Items.Add( adding ); + } + if ( title != "" ) { + for( int i = 0; i < listView1.Items.Count; i++ ){ + if ( listView1.Items[i].Text == title ) { + listView1.Items[i].EnsureVisible(); + break; + } + } + } + this.Invalidate(); + m_loading = false; + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + } + + private void textBox1_TextChanged( object sender, EventArgs e ) { + m_table_group.Character.Name = textBox1.Text; + } + + private void btnAdd_Click( object sender, EventArgs e ) { + Add(); + } + + private void menuSetImage_Click( object sender, EventArgs e ) { + SetImage(); + } + + private void GenerateCharacter_DragDrop( object sender, DragEventArgs e ) { +#if DEBUG + Common.DebugWriteLine( "GenerateCharacter_DragDrop" ); +#endif + if ( e.Data.GetDataPresent( DataFormats.FileDrop ) ) { + object data = e.Data.GetData( DataFormats.FileDrop ); + if ( data is string[] ) { + string[] filename = (string[])data; + for ( int i = 0; i < filename.Length; i++ ) { + Image img = Common.ImageFromFile( filename[i] ); + string title = Path.GetFileNameWithoutExtension( filename[i] ); +#if DEBUG + Common.DebugWriteLine( " filename[i]=" + filename[i] ); + Common.DebugWriteLine( " title=" + title ); +#endif + if ( title != "" ) { +#if DEBUG + Common.DebugWriteLine( " SetImage..." ); +#endif + if ( m_table_group.Character[title] != null ) { + m_table_group.Character.SetImage( img, title ); + picturePreview.Image = img; + int width = Math.Max( m_table_group.Character.Size.Width, img.Width ); + int height = Math.Max( m_table_group.Character.Size.Height, img.Height ); +#if DEBUG + Common.DebugWriteLine( " Character3+Size..set()" ); +#endif + m_table_group.Character.Size = new Size( width, height ); + } else { + m_table_group.Character.Add( new ImageEntry( title, null, "", false, m_table_group.Character.Count ) ); + m_table_group.Character.SetImage( img, title ); + m_table_group.list.Add( new TimeTable( title, 0, TimeTableType.character, null ) ); + int width = Math.Max( m_table_group.Character.Size.Width, img.Width ); + int height = Math.Max( m_table_group.Character.Size.Height, img.Height ); + m_table_group.Character.Size = new Size( width, height ); + listView1.Items.Add( new ListViewItem( new string[] { title, "" } ) ); + listView1.Items[listView1.Items.Count - 1].Selected = true; + } + } + } + this.Invalidate(); + } + } + } + + private void GenerateCharacter_DragEnter( object sender, DragEventArgs e ) { + e.Effect = DragDropEffects.All; + } + + private void menuTransparent_Click( object sender, EventArgs e ) { + Transparent(); + } + + /// + /// listView1にて現在選択されているアイテムの名前を取得します + /// + private string SelectedTitle { + get { + for( int i = 0; i < listView1.Items.Count; i++ ) { + if( listView1.Items[i].Selected ) { + return listView1.Items[i].Text; + } + } + return ""; + } + } + + private void pictureBox1_MouseClick( object sender, MouseEventArgs e ) { + if ( m_setTrans ) { + int x = e.X; + int y = e.Y; + string title = SelectedTitle; + Image img = null; + for ( int i = 0; i < m_table_group.Character.Count; i++ ) { + if ( m_table_group.Character[i].title == title ) { + m_table_group.Character[i].GetImage( m_table_group.Character.Size ); + } + } + if ( img != null ) { + if ( x <= img.Width && y <= img.Height ) { + Bitmap bmp = new Bitmap( img ); + Color tmp = bmp.GetPixel( x, y ); + bmp.MakeTransparent( tmp ); + m_table_group.Character.SetImage( bmp, title ); + if ( picturePreview.Image != null ) { + picturePreview.Image.Dispose(); + } + picturePreview.Image = (Image)bmp.Clone(); + bmp.Dispose(); + update(); + picturePreview.Invalidate(); + } + } + picturePreview.Cursor = Cursors.Arrow; + m_setTrans = false; + } + } + + private void txtTag_TextChanged( object sender, EventArgs e ) { + if ( txtTag.Enabled ) { + string title = SelectedTitle; + ImageEntry t = m_table_group.Character[title]; + if ( t != null ) { + t.tag = txtTag.Text; + for ( int i = 0; i < listView1.Items.Count; i++ ) { + if ( listView1.Items[i].Text == m_table_group.Character[title].title ) { + listView1.Items[i].SubItems[1].Text = txtTag.Text; + return; + } + } + } + } + } + + private void menuEditTitle_Click( object sender, EventArgs e ) { + Title(); + } + + private void menuDelete_Click( object sender, EventArgs e ) { + Delete(); + } + + private void listView1_SelectedIndexChanged( object sender, EventArgs e ) { + string title = SelectedTitle; + if ( title == "" ) { + List draw = new List(); + foreach ( ListViewItem item in listView1.Items ) { + if ( item.Checked ) { + ImageEntry ie = m_table_group.Character[item.Text]; + if ( ie != null ) { + draw.Add( ie.Z ); + } + } + } + picturePreview.Image = m_table_group.Character.Face( draw.ToArray() ); + return; + } + ImageEntry ie2 = m_table_group.Character[title]; + if ( ie2 != null ) { + int index = ie2.Z; + picturePreview.Image = m_table_group.Character.Face( new int[] { index } ); + lblThisTitle.Text = m_table_group.Character[title].title; + txtTag.Enabled = false; + txtTag.Text = m_table_group.Character[title].tag; + if ( 0 <= index && index < 9 ) { + txtTag.Text += "(" + _( "NOT editable" ) + ")"; + txtTag.Enabled = false; + } else { + txtTag.Enabled = true; + } + this.Invalidate(); + } + } + + private void mstripImage_Opening( object sender, CancelEventArgs e ) { + string title = SelectedTitle; + if ( title == "" ) { + menuDelete.Enabled = false; + menuEditTitle.Enabled = false; + menuSetImage.Enabled = false; + menuTransparent.Enabled = false; + } else { + int index = m_table_group.Character[title].Z; + if ( 9 <= index ) { + menuDelete.Enabled = true; + menuEditTitle.Enabled = true; + } else { + menuDelete.Enabled = false; + menuEditTitle.Enabled = false; + } + menuSetImage.Enabled = true; + menuTransparent.Enabled = true; + } + } + + private void listView1_ItemChecked( object sender, ItemCheckedEventArgs e ) { + if ( m_loading ) { + return; + } + int changed_item = e.Item.Index; + string title = listView1.Items[changed_item].Text; +#if DEBUG + Common.DebugWriteLine( "listView1_ItemChecked; title=" + title ); +#endif + string tag = m_table_group.Character[title].tag; + m_table_group.Character[title].IsDefault = e.Item.Checked; + if ( tag != "" && e.Item.Checked ) { + for ( int i = 0; i < listView1.Items.Count; i++ ) { + string temp_title = listView1.Items[i].Text; + string temp_tag = m_table_group.Character[temp_title].tag; + if ( temp_tag == tag && temp_title != title ) { + m_table_group.Character[temp_title].IsDefault = false; + listView1.Items[i].Checked = false; + } + } + } + if ( SelectedTitle == "" ) { + List draw = new List(); + foreach ( ListViewItem item in listView1.Items ) { + if ( item.Checked ) { + int index = m_table_group.Character[item.Text].Z; + if( index >= 0 ) { + draw.Add( index ); + } + } + } + picturePreview.Image = m_table_group.Character.Face( draw.ToArray() ); + } + this.Invalidate(); + //update(); //ここで呼ぶと、永久再帰呼び出しでStackOverFlowする + } + + private void GenerateCharacter_Load( object sender, EventArgs e ) { + update(); + } + + private void btnUp_Click( object sender, EventArgs e ) { + Up(); + } + + private void btnDown_Click( object sender, EventArgs e ) { + Down(); + } + + private void menuReset_Click( object sender, EventArgs e ) { + Reset(); + } + + private void menuFileImportRsi_Click( object sender, EventArgs e ) { + if( openRsi.ShowDialog() == DialogResult.OK ){ + CharacterEx character_ex = RsiReader.Read( openRsi.FileName ); + if ( character_ex.character != null ) { + m_table_group.Character = (Character3)character_ex.character.Clone(); + update(); + } + } + } + + private void menuFileExportRsi_Click( object sender, EventArgs e ) { + if ( saveRsi.ShowDialog() == DialogResult.OK ) { + RsiWriter.Write( m_table_group.Character, saveRsi.FileName ); + } + } + + private void bgWork_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e ) { + bgWork.CancelAsync(); + } + + private void menuEditSetImage_Click( object sender, EventArgs e ) { + SetImage(); + } + + private void menuEditTransparent_Click( object sender, EventArgs e ) { + Transparent(); + } + + #region Core of EditHandle + private void Add() { + using ( InputBox ib = new InputBox( _( "Title of image" ), + _( "Input the title of image" ) ) ) { + if ( ib.ShowDialog() == DialogResult.OK ) { + string new_title = ib.rText; + bool found = false; + foreach ( ImageEntry ie in m_table_group.Character ) { + if ( ie.title == new_title ) { + found = true; + break; + } + } + if ( !found ) { + m_table_group.Character.Add( new ImageEntry( ib.rText, null, "", false, m_table_group.Character.Count ) ); + m_table_group.list.Add( new TimeTable( ib.rText, 0, TimeTableType.character, null ) ); + listView1.Items.Add( new ListViewItem( new string[] { ib.rText, "" } ) ); + listView1.Items[listView1.Items.Count - 1].Selected = true; + } else { + MessageBox.Show( + _( "This image title has been already registered" ), + _( "Error" ) ); + } + } + } + update(); + } + + private void Up() { +#if DEBUG + Common.DebugWriteLine( "Up()" ); +#endif + string selected_title = SelectedTitle; + int selected_index = -1; + for ( int i = 0; i < listView1.Items.Count; i++ ) { + if ( listView1.Items[i].Text == selected_title ) { + selected_index = i; + break; + } + } + if ( selected_index >= 1 ) { + string upper_title = listView1.Items[selected_index - 1].Text; + ListViewItem b = (ListViewItem)listView1.Items[selected_index].Clone(); + listView1.Items[selected_index] = (ListViewItem)listView1.Items[selected_index - 1].Clone(); + listView1.Items[selected_index - 1] = b; + listView1.Items[selected_index].Selected = false; + listView1.Items[selected_index - 1].Selected = false; + + int upper_z = m_table_group.Character[upper_title].Z; + int selected_z = m_table_group.Character[selected_title].Z; +#if DEBUG + Common.DebugWriteLine( " selected_title=" + selected_title ); + Common.DebugWriteLine( " upper_title=" + upper_title ); +#endif + m_table_group.Character[selected_title].Z = upper_z; + m_table_group.Character[upper_title].Z = selected_z; + + update(); + listView1.Items[selected_index - 1].Selected = true; + listView1.Items[selected_index - 1].EnsureVisible(); + + TimeTable ttable_upper = (TimeTable)m_table_group[selected_index - 1].Clone(); + m_table_group[selected_index - 1] = (TimeTable)m_table_group[selected_index].Clone(); + m_table_group[selected_index] = ttable_upper; + } +#if DEBUG + Common.DebugWriteLine( "-------------------------------" ); +#endif + } + + private void Down() { +#if DEBUG + Common.DebugWriteLine( "Down()" ); +#endif + string selected_title = SelectedTitle; + int selected_index = -1; + for ( int i = 0; i < listView1.Items.Count; i++ ) { + if ( listView1.Items[i].Text == selected_title ) { + selected_index = i; + break; + } + } + if ( selected_index >= 0 && selected_index < listView1.Items.Count - 1 ) { + string lower_title = listView1.Items[selected_index + 1].Text; + ListViewItem b = (ListViewItem)listView1.Items[selected_index].Clone(); + listView1.Items[selected_index] = (ListViewItem)listView1.Items[selected_index + 1].Clone(); + listView1.Items[selected_index + 1] = b; + listView1.Items[selected_index].Selected = false; + listView1.Items[selected_index + 1].Selected = false; + + int lower_z = m_table_group.Character[lower_title].Z; + int selected_z = m_table_group.Character[selected_title].Z; +#if DEBUG + Common.DebugWriteLine( " selected_title=" + selected_title ); + Common.DebugWriteLine( " lower_title=" + lower_title ); +#endif + m_table_group.Character[lower_title].Z = selected_z; + m_table_group.Character[selected_title].Z = lower_z; + + update(); + listView1.Items[selected_index + 1].Selected = true; + listView1.Items[selected_index + 1].EnsureVisible(); + + TimeTable ttable_lower = (TimeTable)m_table_group.list[selected_index + 1].Clone(); + m_table_group.list[selected_index + 1] = (TimeTable)m_table_group.list[selected_index].Clone(); + m_table_group.list[selected_index] = ttable_lower; + } +#if DEBUG + Common.DebugWriteLine( "-------------------------------" ); +#endif + } + + private void SetImage() { + string title = SelectedTitle; + if ( title != "" ) { + openImage.FileName = ""; + if ( m_last_image_folder != "" ) { + openImage.InitialDirectory = m_last_image_folder; + } + if ( openImage.ShowDialog() == DialogResult.OK ) { + Image img = Common.ImageFromFile( openImage.FileName ); + m_table_group.Character.SetImage( img, title ); + picturePreview.Image = img; + if ( img != null ) { + int width = Math.Max( m_table_group.Character.Size.Width, img.Width ); + int height = Math.Max( m_table_group.Character.Size.Height, img.Height ); + m_table_group.Character.Size = new Size( width, height ); + } + this.Invalidate(); + m_last_image_folder = Path.GetDirectoryName( openImage.FileName ); + } else { + m_last_image_folder = openImage.InitialDirectory; + } + } + } + + private void Transparent() { + if ( SelectedTitle != "" ) { + m_setTrans = true; + picturePreview.Cursor = Cursors.Cross; + } + } + + private void Reset() { + string title = SelectedTitle; + if ( title != "" ) { + m_table_group.Character[title].ResetImage(); + picturePreview.Image = null; + } + } + + private void Delete() { + string title = SelectedTitle; + if ( title == "" ) { + return; + } + m_table_group.Character.Remove( title ); + for ( int i = 0; i < m_table_group.list.Count; i++ ) { + if ( m_table_group.list[i].Text == title ) { + m_table_group.list.RemoveAt( i ); + break; + } + } + UpdateZOrder(); + picturePreview.Image = null; + update(); + } + + /// + /// m_table_group.listの順序を元に、m_table_group.Characterのzオーダーを新たに幡番する + /// + private void UpdateZOrder() { + for ( int i = 0; i < m_table_group.list.Count; i++ ) { + foreach ( ImageEntry ie in m_table_group.Character ) { + if ( ie.title == m_table_group.list[i].Text ) { + ie.Z = i; + break; + } + } + } + } + + private void Title() { + string title = SelectedTitle; + if ( title == "" ) { + return; + } + string edited_title = ""; + using ( InputBox ib = new InputBox( + _( "Change title" ), + _( "Input new title" ) ) ) { + ib.rText = title; + if ( ib.ShowDialog() == DialogResult.OK ) { + edited_title = ib.rText; + foreach ( ImageEntry ie in m_table_group.Character ) { + if ( title == ie.title ) { + ie.title = edited_title; + break; + } + } + for ( int i = 0; i < m_table_group.list.Count; i++ ) { + if ( title == m_table_group.list[i].Text ) { + m_table_group.list[i].Text = edited_title; + break; + } + } + } + } + update(); + } + #endregion + + private void menuEditDelete_Click( object sender, EventArgs e ) { + Delete(); + } + + private void menuEditReset_Click( object sender, EventArgs e ) { + Reset(); + } + + private void menuEditEditTitle_Click( object sender, EventArgs e ) { + Title(); + } + + private void menuEditUp_Click( object sender, EventArgs e ) { + Up(); + } + + private void menuEditDown_Click( object sender, EventArgs e ) { + Down(); + } + + private void menuEditAdd_Click( object sender, EventArgs e ) { + Add(); + } + + private void menuEditDebugEditVersionInfo_Click( object sender, EventArgs e ) { +#if DEBUG + using ( InputBox ib = new InputBox( "", "input author" ) ) { + if ( ib.ShowDialog() == DialogResult.OK ) { + m_table_group.Character.Author = ib.rText; + } + } + using ( InputBox ib = new InputBox( "", "input version" ) ) { + if ( ib.ShowDialog() == DialogResult.OK ) { + m_table_group.Character.Version = ib.rText; + } + } +#endif + } + + private void menuFileExportXml_Click( object sender, EventArgs e ) { + saveLsc.FileName = m_last_path; + string f1 = _( "LipSync Character Config(content.xml)|content.xml" ); + string f2 = _( "All Files(*.*)|*.*" ); + string filter = f1 + "|" + f2; + string def_filter = "LipSync Character Config(content.xml)|content.xml|All Files(*.*)|*.*"; + try { + saveLsc.Filter = filter; + } catch { + saveLsc.Filter = def_filter; + } + if ( saveLsc.ShowDialog() == DialogResult.OK ) { + this.m_table_group.Character.WriteXml( saveLsc.FileName ); + m_last_path = saveLsc.FileName; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/GenerateCharacter.designer.cs b/trunk/LipSync/LipSync/Editor/GenerateCharacter.designer.cs new file mode 100644 index 0000000..b0da07e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/GenerateCharacter.designer.cs @@ -0,0 +1,641 @@ +/* + * GenerateCharacter.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class GenerateCharacter { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.btnAdd = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.mstripImage = new System.Windows.Forms.ContextMenuStrip( this.components ); + this.menuSetImage = new System.Windows.Forms.ToolStripMenuItem(); + this.menuTransparent = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditTitle = new System.Windows.Forms.ToolStripMenuItem(); + this.menuDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.menuReset = new System.Windows.Forms.ToolStripMenuItem(); + this.openLsc = new System.Windows.Forms.OpenFileDialog(); + this.menuStrip1 = new System.Windows.Forms.MenuStrip(); + this.menuFile = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileOpen = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileSave = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileImport = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileImportRsi = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileExport = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileExportRsi = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFileExportXml = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEdit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditSetImage = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditTransparent = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditEditTitle = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditDelete = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditReset = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.menuEditUp = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditDown = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditAdd = new System.Windows.Forms.ToolStripMenuItem(); + this.menuEditDebugEditVersionInfo = new System.Windows.Forms.ToolStripMenuItem(); + this.saveLsc = new System.Windows.Forms.SaveFileDialog(); + this.openImage = new System.Windows.Forms.OpenFileDialog(); + this.label2 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.listView1 = new System.Windows.Forms.ListView(); + this.columnTitle = new System.Windows.Forms.ColumnHeader(); + this.columnTag = new System.Windows.Forms.ColumnHeader(); + this.btnDown = new System.Windows.Forms.Button(); + this.btnUp = new System.Windows.Forms.Button(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.lblThisTitle = new System.Windows.Forms.Label(); + this.txtTag = new System.Windows.Forms.TextBox(); + this.lblTag = new System.Windows.Forms.Label(); + this.lblTitle = new System.Windows.Forms.Label(); + this.picturePreview = new System.Windows.Forms.PictureBox(); + this.splitContainer1 = new Boare.Lib.AppUtil.BSplitContainer(); + this.openRsi = new System.Windows.Forms.OpenFileDialog(); + this.saveRsi = new System.Windows.Forms.SaveFileDialog(); + this.bgWork = new System.ComponentModel.BackgroundWorker(); + this.mstripImage.SuspendLayout(); + this.menuStrip1.SuspendLayout(); + this.groupBox1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picturePreview)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.SuspendLayout(); + // + // btnAdd + // + this.btnAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnAdd.Location = new System.Drawing.Point( 143, 324 ); + this.btnAdd.Name = "btnAdd"; + this.btnAdd.Size = new System.Drawing.Size( 60, 23 ); + this.btnAdd.TabIndex = 4; + this.btnAdd.Text = "追加"; + this.btnAdd.UseVisualStyleBackColor = true; + this.btnAdd.Click += new System.EventHandler( this.btnAdd_Click ); + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 34, 324 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 6; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 123, 324 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 7; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // mstripImage + // + this.mstripImage.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuSetImage, + this.menuTransparent, + this.menuEditTitle, + this.menuDelete, + this.menuReset} ); + this.mstripImage.Name = "contextMenuStrip1"; + this.mstripImage.ShowImageMargin = false; + this.mstripImage.Size = new System.Drawing.Size( 115, 114 ); + this.mstripImage.Opening += new System.ComponentModel.CancelEventHandler( this.mstripImage_Opening ); + // + // menuSetImage + // + this.menuSetImage.Name = "menuSetImage"; + this.menuSetImage.Size = new System.Drawing.Size( 114, 22 ); + this.menuSetImage.Text = "画像を設定"; + this.menuSetImage.Click += new System.EventHandler( this.menuSetImage_Click ); + // + // menuTransparent + // + this.menuTransparent.Name = "menuTransparent"; + this.menuTransparent.Size = new System.Drawing.Size( 114, 22 ); + this.menuTransparent.Text = "透過色を設定"; + this.menuTransparent.Click += new System.EventHandler( this.menuTransparent_Click ); + // + // menuEditTitle + // + this.menuEditTitle.Name = "menuEditTitle"; + this.menuEditTitle.Size = new System.Drawing.Size( 114, 22 ); + this.menuEditTitle.Text = "タイトルを変更"; + this.menuEditTitle.Click += new System.EventHandler( this.menuEditTitle_Click ); + // + // menuDelete + // + this.menuDelete.Name = "menuDelete"; + this.menuDelete.Size = new System.Drawing.Size( 114, 22 ); + this.menuDelete.Text = "削除"; + this.menuDelete.Click += new System.EventHandler( this.menuDelete_Click ); + // + // menuReset + // + this.menuReset.Name = "menuReset"; + this.menuReset.Size = new System.Drawing.Size( 114, 22 ); + this.menuReset.Text = "画像をリセット"; + this.menuReset.Click += new System.EventHandler( this.menuReset_Click ); + // + // openLsc + // + this.openLsc.Filter = "Character setting|*.lsc;content.xml|All files|*.*"; + // + // menuStrip1 + // + this.menuStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuFile, + this.menuEdit} ); + this.menuStrip1.Location = new System.Drawing.Point( 0, 0 ); + this.menuStrip1.Name = "menuStrip1"; + this.menuStrip1.Size = new System.Drawing.Size( 422, 24 ); + this.menuStrip1.TabIndex = 6; + this.menuStrip1.Text = "menuStrip1"; + // + // menuFile + // + this.menuFile.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuFileOpen, + this.menuFileSave, + this.menuFileImport, + this.menuFileExport} ); + this.menuFile.Name = "menuFile"; + this.menuFile.Size = new System.Drawing.Size( 66, 20 ); + this.menuFile.Text = "ファイル(&F)"; + // + // menuFileOpen + // + this.menuFileOpen.Name = "menuFileOpen"; + this.menuFileOpen.Size = new System.Drawing.Size( 139, 22 ); + this.menuFileOpen.Text = "開く(&O)"; + this.menuFileOpen.Click += new System.EventHandler( this.menuFileOpen_Click ); + // + // menuFileSave + // + this.menuFileSave.Name = "menuFileSave"; + this.menuFileSave.Size = new System.Drawing.Size( 139, 22 ); + this.menuFileSave.Text = "保存(&S)"; + this.menuFileSave.Click += new System.EventHandler( this.menuFileSave_Click ); + // + // menuFileImport + // + this.menuFileImport.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuFileImportRsi} ); + this.menuFileImport.Name = "menuFileImport"; + this.menuFileImport.Size = new System.Drawing.Size( 139, 22 ); + this.menuFileImport.Text = "インポート(&I)"; + // + // menuFileImportRsi + // + this.menuFileImportRsi.Name = "menuFileImportRsi"; + this.menuFileImportRsi.Size = new System.Drawing.Size( 131, 22 ); + this.menuFileImportRsi.Text = "RSIを開く(&R)"; + this.menuFileImportRsi.Click += new System.EventHandler( this.menuFileImportRsi_Click ); + // + // menuFileExport + // + this.menuFileExport.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuFileExportRsi, + this.menuFileExportXml} ); + this.menuFileExport.Name = "menuFileExport"; + this.menuFileExport.Size = new System.Drawing.Size( 139, 22 ); + this.menuFileExport.Text = "エクスポート(&E)"; + // + // menuFileExportRsi + // + this.menuFileExportRsi.Name = "menuFileExportRsi"; + this.menuFileExportRsi.Size = new System.Drawing.Size( 165, 22 ); + this.menuFileExportRsi.Text = "RSIで保存(&R)"; + this.menuFileExportRsi.Click += new System.EventHandler( this.menuFileExportRsi_Click ); + // + // menuFileExportXml + // + this.menuFileExportXml.Name = "menuFileExportXml"; + this.menuFileExportXml.Size = new System.Drawing.Size( 165, 22 ); + this.menuFileExportXml.Text = "XML形式で保存(&X)"; + this.menuFileExportXml.Click += new System.EventHandler( this.menuFileExportXml_Click ); + // + // menuEdit + // + this.menuEdit.DropDownItems.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuEditSetImage, + this.menuEditTransparent, + this.menuEditEditTitle, + this.menuEditDelete, + this.menuEditReset, + this.toolStripMenuItem1, + this.menuEditUp, + this.menuEditDown, + this.menuEditAdd, + this.menuEditDebugEditVersionInfo} ); + this.menuEdit.Name = "menuEdit"; + this.menuEdit.Size = new System.Drawing.Size( 56, 20 ); + this.menuEdit.Text = "編集(&E)"; + // + // menuEditSetImage + // + this.menuEditSetImage.Name = "menuEditSetImage"; + this.menuEditSetImage.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditSetImage.Text = "画像を設定"; + this.menuEditSetImage.Click += new System.EventHandler( this.menuEditSetImage_Click ); + // + // menuEditTransparent + // + this.menuEditTransparent.Name = "menuEditTransparent"; + this.menuEditTransparent.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditTransparent.Text = "透明色を設定"; + this.menuEditTransparent.Click += new System.EventHandler( this.menuEditTransparent_Click ); + // + // menuEditEditTitle + // + this.menuEditEditTitle.Name = "menuEditEditTitle"; + this.menuEditEditTitle.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditEditTitle.Text = "タイトルを変更"; + this.menuEditEditTitle.Click += new System.EventHandler( this.menuEditEditTitle_Click ); + // + // menuEditDelete + // + this.menuEditDelete.Name = "menuEditDelete"; + this.menuEditDelete.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditDelete.Text = "削除"; + this.menuEditDelete.Click += new System.EventHandler( this.menuEditDelete_Click ); + // + // menuEditReset + // + this.menuEditReset.Name = "menuEditReset"; + this.menuEditReset.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditReset.Text = "画像をリセット"; + this.menuEditReset.Click += new System.EventHandler( this.menuEditReset_Click ); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size( 150, 6 ); + // + // menuEditUp + // + this.menuEditUp.Name = "menuEditUp"; + this.menuEditUp.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditUp.Text = "上"; + this.menuEditUp.Click += new System.EventHandler( this.menuEditUp_Click ); + // + // menuEditDown + // + this.menuEditDown.Name = "menuEditDown"; + this.menuEditDown.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditDown.Text = "下"; + this.menuEditDown.Click += new System.EventHandler( this.menuEditDown_Click ); + // + // menuEditAdd + // + this.menuEditAdd.Name = "menuEditAdd"; + this.menuEditAdd.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditAdd.Text = "追加"; + this.menuEditAdd.Click += new System.EventHandler( this.menuEditAdd_Click ); + // + // menuEditDebugEditVersionInfo + // + this.menuEditDebugEditVersionInfo.Name = "menuEditDebugEditVersionInfo"; + this.menuEditDebugEditVersionInfo.Size = new System.Drawing.Size( 153, 22 ); + this.menuEditDebugEditVersionInfo.Text = "edit version info"; + this.menuEditDebugEditVersionInfo.Visible = false; + this.menuEditDebugEditVersionInfo.Click += new System.EventHandler( this.menuEditDebugEditVersionInfo_Click ); + // + // saveLsc + // + this.saveLsc.Filter = "Character setting|*.lsc|All files|*.*"; + // + // openImage + // + this.openImage.Filter = "Image Files|*.bmp;*.png;*.jpg|All Files|*.*"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point( 13, 17 ); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size( 81, 12 ); + this.label2.TabIndex = 7; + this.label2.Text = "キャラクタの名前"; + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Location = new System.Drawing.Point( 100, 14 ); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 103, 19 ); + this.textBox1.TabIndex = 0; + this.textBox1.Text = "(character name)"; + this.textBox1.TextChanged += new System.EventHandler( this.textBox1_TextChanged ); + // + // listView1 + // + this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView1.CheckBoxes = true; + this.listView1.Columns.AddRange( new System.Windows.Forms.ColumnHeader[] { + this.columnTitle, + this.columnTag} ); + this.listView1.ContextMenuStrip = this.mstripImage; + this.listView1.Location = new System.Drawing.Point( 15, 51 ); + this.listView1.MultiSelect = false; + this.listView1.Name = "listView1"; + this.listView1.Size = new System.Drawing.Size( 188, 256 ); + this.listView1.TabIndex = 1; + this.listView1.UseCompatibleStateImageBehavior = false; + this.listView1.View = System.Windows.Forms.View.Details; + this.listView1.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler( this.listView1_ItemChecked ); + this.listView1.SelectedIndexChanged += new System.EventHandler( this.listView1_SelectedIndexChanged ); + // + // columnTitle + // + this.columnTitle.Text = "画像名"; + this.columnTitle.Width = 130; + // + // columnTag + // + this.columnTag.Text = "タグ"; + this.columnTag.Width = 50; + // + // btnDown + // + this.btnDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnDown.Location = new System.Drawing.Point( 81, 324 ); + this.btnDown.Name = "btnDown"; + this.btnDown.Size = new System.Drawing.Size( 60, 23 ); + this.btnDown.TabIndex = 3; + this.btnDown.Text = "下"; + this.btnDown.UseVisualStyleBackColor = true; + this.btnDown.Click += new System.EventHandler( this.btnDown_Click ); + // + // btnUp + // + this.btnUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnUp.Location = new System.Drawing.Point( 15, 324 ); + this.btnUp.Name = "btnUp"; + this.btnUp.Size = new System.Drawing.Size( 60, 23 ); + this.btnUp.TabIndex = 2; + this.btnUp.Text = "上"; + this.btnUp.UseVisualStyleBackColor = true; + this.btnUp.Click += new System.EventHandler( this.btnUp_Click ); + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add( this.lblThisTitle ); + this.groupBox1.Controls.Add( this.txtTag ); + this.groupBox1.Controls.Add( this.lblTag ); + this.groupBox1.Controls.Add( this.lblTitle ); + this.groupBox1.Controls.Add( this.picturePreview ); + this.groupBox1.Location = new System.Drawing.Point( 4, 4 ); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size( 194, 303 ); + this.groupBox1.TabIndex = 14; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "選択された画像"; + // + // lblThisTitle + // + this.lblThisTitle.AutoSize = true; + this.lblThisTitle.Location = new System.Drawing.Point( 58, 27 ); + this.lblThisTitle.Name = "lblThisTitle"; + this.lblThisTitle.Size = new System.Drawing.Size( 0, 12 ); + this.lblThisTitle.TabIndex = 9; + // + // txtTag + // + this.txtTag.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtTag.Location = new System.Drawing.Point( 58, 52 ); + this.txtTag.Name = "txtTag"; + this.txtTag.Size = new System.Drawing.Size( 130, 19 ); + this.txtTag.TabIndex = 5; + this.txtTag.TextChanged += new System.EventHandler( this.txtTag_TextChanged ); + // + // lblTag + // + this.lblTag.AutoSize = true; + this.lblTag.Location = new System.Drawing.Point( 11, 55 ); + this.lblTag.Name = "lblTag"; + this.lblTag.Size = new System.Drawing.Size( 22, 12 ); + this.lblTag.TabIndex = 6; + this.lblTag.Text = "タグ"; + // + // lblTitle + // + this.lblTitle.AutoSize = true; + this.lblTitle.Location = new System.Drawing.Point( 11, 27 ); + this.lblTitle.Name = "lblTitle"; + this.lblTitle.Size = new System.Drawing.Size( 41, 12 ); + this.lblTitle.TabIndex = 3; + this.lblTitle.Text = "画像名"; + // + // picturePreview + // + this.picturePreview.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.picturePreview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.picturePreview.ContextMenuStrip = this.mstripImage; + this.picturePreview.Location = new System.Drawing.Point( 6, 77 ); + this.picturePreview.Name = "picturePreview"; + this.picturePreview.Size = new System.Drawing.Size( 182, 220 ); + this.picturePreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.picturePreview.TabIndex = 5; + this.picturePreview.TabStop = false; + this.picturePreview.DoubleClick += new System.EventHandler( this.picturePreview_DoubleClick ); + this.picturePreview.MouseClick += new System.Windows.Forms.MouseEventHandler( this.pictureBox1_MouseClick ); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; + this.splitContainer1.IsSplitterFixed = false; + this.splitContainer1.Location = new System.Drawing.Point( 0, 24 ); + this.splitContainer1.Margin = new System.Windows.Forms.Padding( 0 ); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // + // + this.splitContainer1.Panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.splitContainer1.Panel1.BorderColor = System.Drawing.SystemColors.ControlDark; + this.splitContainer1.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.splitContainer1.Panel1.Controls.Add( this.label2 ); + this.splitContainer1.Panel1.Controls.Add( this.btnAdd ); + this.splitContainer1.Panel1.Controls.Add( this.textBox1 ); + this.splitContainer1.Panel1.Controls.Add( this.btnDown ); + this.splitContainer1.Panel1.Controls.Add( this.listView1 ); + this.splitContainer1.Panel1.Controls.Add( this.btnUp ); + this.splitContainer1.Panel1.Location = new System.Drawing.Point( 1, 1 ); + this.splitContainer1.Panel1.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 4 ); + this.splitContainer1.Panel1.Name = "m_panel1"; + this.splitContainer1.Panel1.Padding = new System.Windows.Forms.Padding( 1 ); + this.splitContainer1.Panel1.Size = new System.Drawing.Size( 208, 369 ); + this.splitContainer1.Panel1.TabIndex = 0; + this.splitContainer1.Panel1MinSize = 210; + // + // + // + this.splitContainer1.Panel2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.splitContainer1.Panel2.BorderColor = System.Drawing.SystemColors.ControlDark; + this.splitContainer1.Panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.splitContainer1.Panel2.Controls.Add( this.groupBox1 ); + this.splitContainer1.Panel2.Controls.Add( this.btnOK ); + this.splitContainer1.Panel2.Controls.Add( this.btnCancel ); + this.splitContainer1.Panel2.Location = new System.Drawing.Point( 215, 1 ); + this.splitContainer1.Panel2.Margin = new System.Windows.Forms.Padding( 0 ); + this.splitContainer1.Panel2.Name = "m_panel2"; + this.splitContainer1.Panel2.Padding = new System.Windows.Forms.Padding( 1 ); + this.splitContainer1.Panel2.Size = new System.Drawing.Size( 206, 369 ); + this.splitContainer1.Panel2.TabIndex = 1; + this.splitContainer1.Panel2MinSize = 25; + this.splitContainer1.Size = new System.Drawing.Size( 422, 371 ); + this.splitContainer1.SplitterDistance = 210; + this.splitContainer1.SplitterWidth = 4; + this.splitContainer1.TabIndex = 10; + this.splitContainer1.TabStop = false; + // + // bgWork + // + this.bgWork.WorkerSupportsCancellation = true; + this.bgWork.DoWork += new System.ComponentModel.DoWorkEventHandler( this.bgWork_DoWork ); + this.bgWork.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler( this.bgWork_RunWorkerCompleted ); + // + // GenerateCharacter + // + this.AllowDrop = true; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 422, 395 ); + this.Controls.Add( this.splitContainer1 ); + this.Controls.Add( this.menuStrip1 ); + this.MainMenuStrip = this.menuStrip1; + this.MinimizeBox = false; + this.MinimumSize = new System.Drawing.Size( 402, 327 ); + this.Name = "GenerateCharacter"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "キャラクタを編集"; + this.Load += new System.EventHandler( this.GenerateCharacter_Load ); + this.DragDrop += new System.Windows.Forms.DragEventHandler( this.GenerateCharacter_DragDrop ); + this.DragEnter += new System.Windows.Forms.DragEventHandler( this.GenerateCharacter_DragEnter ); + this.mstripImage.ResumeLayout( false ); + this.menuStrip1.ResumeLayout( false ); + this.menuStrip1.PerformLayout(); + this.groupBox1.ResumeLayout( false ); + this.groupBox1.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.picturePreview)).EndInit(); + this.splitContainer1.Panel1.ResumeLayout( false ); + this.splitContainer1.Panel1.PerformLayout(); + this.splitContainer1.Panel2.ResumeLayout( false ); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnAdd; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.PictureBox picturePreview; + private System.Windows.Forms.OpenFileDialog openLsc; + private System.Windows.Forms.MenuStrip menuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuFile; + private System.Windows.Forms.ToolStripMenuItem menuFileOpen; + private System.Windows.Forms.ToolStripMenuItem menuFileSave; + private System.Windows.Forms.SaveFileDialog saveLsc; + private System.Windows.Forms.OpenFileDialog openImage; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.ContextMenuStrip mstripImage; + private System.Windows.Forms.ToolStripMenuItem menuSetImage; + private System.Windows.Forms.ToolStripMenuItem menuTransparent; + private System.Windows.Forms.ListView listView1; + private System.Windows.Forms.ColumnHeader columnTitle; + private System.Windows.Forms.ColumnHeader columnTag; + private System.Windows.Forms.Button btnDown; + private System.Windows.Forms.Button btnUp; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label lblTitle; + private System.Windows.Forms.TextBox txtTag; + private System.Windows.Forms.Label lblTag; + private System.Windows.Forms.Label lblThisTitle; + private System.Windows.Forms.ToolStripMenuItem menuEditTitle; + private System.Windows.Forms.ToolStripMenuItem menuDelete; + //private System.Windows.Forms.SplitContainer splitContainer1; + private Boare.Lib.AppUtil.BSplitContainer splitContainer1; + private System.Windows.Forms.ToolStripMenuItem menuReset; + private System.Windows.Forms.OpenFileDialog openRsi; + private System.Windows.Forms.SaveFileDialog saveRsi; + private System.ComponentModel.BackgroundWorker bgWork; + private System.Windows.Forms.ToolStripMenuItem menuEdit; + private System.Windows.Forms.ToolStripMenuItem menuEditSetImage; + private System.Windows.Forms.ToolStripMenuItem menuEditTransparent; + private System.Windows.Forms.ToolStripMenuItem menuEditEditTitle; + private System.Windows.Forms.ToolStripMenuItem menuEditDelete; + private System.Windows.Forms.ToolStripMenuItem menuEditReset; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem menuEditUp; + private System.Windows.Forms.ToolStripMenuItem menuEditDown; + private System.Windows.Forms.ToolStripMenuItem menuEditAdd; + private System.Windows.Forms.ToolStripMenuItem menuEditDebugEditVersionInfo; + private System.Windows.Forms.ToolStripMenuItem menuFileExport; + private System.Windows.Forms.ToolStripMenuItem menuFileImport; + private System.Windows.Forms.ToolStripMenuItem menuFileImportRsi; + private System.Windows.Forms.ToolStripMenuItem menuFileExportRsi; + private System.Windows.Forms.ToolStripMenuItem menuFileExportXml; + + } + +} diff --git a/trunk/LipSync/LipSync/Editor/IDrawObject.cs b/trunk/LipSync/LipSync/Editor/IDrawObject.cs new file mode 100644 index 0000000..64c65b2 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/IDrawObject.cs @@ -0,0 +1,49 @@ +/* + * IDrawObject.cs + * Copyright (c) 2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.ComponentModel; + +namespace LipSync { + + public interface IDrawObject { + [Browsable( false )] + int ZOrder { + get; + set; + } + + bool PositionFixed { + get; + set; + } + + PointF GetPosition( float time ); + + float GetScale( float time ); + + float GetAlpha( float time ); + + float GetRotate( float time ); + + bool IsXFixedAt( float time ); + + bool IsYFixedAt( float time ); + + Size ImageSize { + get; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/IMultiLanguageControl.cs b/trunk/LipSync/LipSync/Editor/IMultiLanguageControl.cs new file mode 100644 index 0000000..74b3be5 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/IMultiLanguageControl.cs @@ -0,0 +1,24 @@ +/* + * IMultiLanguageControl.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; + +namespace LipSync { + + interface IMultiLanguageControl { + void ApplyLanguage(); + void ApplyFont( Font font ); + } + +} diff --git a/trunk/LipSync/LipSync/Editor/ImageEntry.cs b/trunk/LipSync/LipSync/Editor/ImageEntry.cs new file mode 100644 index 0000000..d065e33 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ImageEntry.cs @@ -0,0 +1,196 @@ +/* + * ImageEntry.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Runtime.Serialization; +using System.Xml.Serialization; + +namespace LipSync { + + [Serializable] + public class ImageEntry : IComparable, ICloneable { + [XmlElement("Title")] + public string title; + [XmlIgnore] + Image image; + [XmlElement("Tag")] + public string tag; + [OptionalField] + bool is_default; + [OptionalField, XmlIgnore] + int xoffset; + [OptionalField, XmlIgnore] + int yoffset; + [OptionalField] + int m_zorder; + + public ImageEntry( string title, Image image, string tag, bool is_default ) { + this.title = title; + if ( image != null ) { + this.image = (Image)image.Clone(); + } else { + this.image = null; + } + this.tag = tag; + this.IsDefault = is_default; + m_zorder = 0; + } + + public ImageEntry( string title, Image image, string tag, bool is_default, int zorder ) + : this( title, image, tag, is_default ) { + m_zorder = zorder; + } + + private ImageEntry() { + title = ""; + image = null; + tag = ""; + is_default = false; + xoffset = 0; + yoffset = 0; + m_zorder = 0; + } + + public Image Image { + get { + return image; + } + } + + public override string ToString() { + if ( image != null ) { + return "title=" + title + ";tag=" + tag + ";image.width=" + image.Width + ";image.height=" + image.Height + ";xoffset=" + xoffset + ";yoffset=" + yoffset + ";z=" + m_zorder; + } else { + return "title=" + title + ";tag=" + tag + ";image=null;xoffset=" + xoffset + ";yoffset=" + yoffset + ";z=" + m_zorder; + } + } + + public int XOffset { + get { + return xoffset; + } + } + + public int YOffset { + get { + return yoffset; + } + } + + public void ResetImage() { + if ( image != null ) { + image = null; + xoffset = 0; + yoffset = 0; + } + } + + public Bitmap GetImage() { + if ( image != null ) { + int width = xoffset + image.Width; + int height = yoffset + image.Height; + return GetImage( width, height ); + } else { + return null; + } + } + + public Bitmap GetImage( Size size ) { + return GetImage( size.Width, size.Height ); + } + + public Bitmap GetImage( int width, int height ) { + Bitmap res = new Bitmap( width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb ); + using ( Graphics g = Graphics.FromImage( res ) ) { + this.DrawTo( g ); + } + return res; + } + + public void DrawTo( Graphics g ) { + if ( image != null ) { + g.DrawImage( image, xoffset, yoffset, image.Width, image.Height ); + } + } + + public void SetImage( Image img ) { + if ( img == null ) { + return; + } + Bitmap t = new Bitmap( img ); + Rectangle rc = Common.GetNonTransparentRegion( t ); +#if DEBUG + Common.DebugWriteLine( "ImageEntry.SetImage; rc=" + rc ); +#endif + if ( image != null ) { + image = null; + } + image = new Bitmap( rc.Width, rc.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb ); + using ( Graphics g = Graphics.FromImage( image ) ) { + g.DrawImage( img, 0, 0, rc, GraphicsUnit.Pixel ); + } + xoffset = rc.X; + yoffset = rc.Y; + } + + public int CompareTo( ImageEntry item ) { + if ( this.Z > item.Z ) { + return 1; + } else if ( this.Z < item.Z ) { + return -1; + } else { + return 0; + } + } + + [XmlElement("FileId")] + public int Z { + get { + return m_zorder; + } + set { + m_zorder = value; + } + } + + public bool IsDefault { + get { + return is_default; + } + set { + is_default = value; + } + } + + [OnDeserializing] + private void onDeserializing( StreamingContext sc ) { + IsDefault = false; + xoffset = 0; + yoffset = 0; + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { + } + + public object Clone() { + ImageEntry result = new ImageEntry( title, image, tag, is_default ); + result.xoffset = this.xoffset; + result.yoffset = this.yoffset; + result.m_zorder = this.m_zorder; + return result; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/InputBox.cs b/trunk/LipSync/LipSync/Editor/InputBox.cs new file mode 100644 index 0000000..737a15e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/InputBox.cs @@ -0,0 +1,53 @@ +/* + * InputBox.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace LipSync { + + public partial class InputBox : Form, IMultiLanguageControl { + public InputBox( string title, string message ) { + InitializeComponent(); + ApplyFont( AppManager.Config.Font.GetFont() ); + this.message.Text = message; + this.Text = title; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + } + + public string rText { + get{ + return input.Text; + } + set { + input.Text = value; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + this.Close(); + } + } + +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/InputBox.designer.cs b/trunk/LipSync/LipSync/Editor/InputBox.designer.cs new file mode 100644 index 0000000..70b4456 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/InputBox.designer.cs @@ -0,0 +1,113 @@ +/* + * InputBox.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class InputBox { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.message = new System.Windows.Forms.Label(); + this.input = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 114, 73 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 208, 73 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // message + // + this.message.AutoEllipsis = true; + this.message.AutoSize = true; + this.message.Location = new System.Drawing.Point( 12, 9 ); + this.message.Name = "message"; + this.message.Size = new System.Drawing.Size( 50, 12 ); + this.message.TabIndex = 2; + this.message.Text = "message"; + // + // input + // + this.input.ImeMode = System.Windows.Forms.ImeMode.NoControl; + this.input.Location = new System.Drawing.Point( 29, 35 ); + this.input.Name = "input"; + this.input.Size = new System.Drawing.Size( 254, 19 ); + this.input.TabIndex = 0; + // + // InputBox + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 298, 113 ); + this.Controls.Add( this.input ); + this.Controls.Add( this.message ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "InputBox"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "InputBox"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label message; + private System.Windows.Forms.TextBox input; + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/Item.cs b/trunk/LipSync/LipSync/Editor/Item.cs new file mode 100644 index 0000000..b303e61 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Item.cs @@ -0,0 +1,35 @@ +/* + * Item.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + /// + /// + /// + public struct Item { + public TimeTableType type; + public int group; + public int track; + public int entry; + public int row_index; + + public Item( TimeTableType type, int group, int track, int entry, int row_index ) { + this.type = type; + this.group = group; + this.track = track; + this.entry = entry; + this.row_index = row_index; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/MListView.Designer.cs b/trunk/LipSync/LipSync/Editor/MListView.Designer.cs new file mode 100644 index 0000000..84d4fda --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/MListView.Designer.cs @@ -0,0 +1,97 @@ +/* + * MListView.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class MListView { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + System.Windows.Forms.ListViewGroup listViewGroup1 = new System.Windows.Forms.ListViewGroup( "ListViewGroup", System.Windows.Forms.HorizontalAlignment.Left ); + System.Windows.Forms.ListViewItem listViewItem1 = new System.Windows.Forms.ListViewItem( "dumyitem" ); + this.listView1 = new System.Windows.Forms.ListView(); + this.listView2 = new System.Windows.Forms.ListView(); + this.SuspendLayout(); + // + // listView1 + // + this.listView1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView1.BorderStyle = System.Windows.Forms.BorderStyle.None; + listViewGroup1.Header = "ListViewGroup"; + listViewGroup1.Name = "titleGroup"; + this.listView1.Groups.AddRange( new System.Windows.Forms.ListViewGroup[] { + listViewGroup1} ); + listViewItem1.Group = listViewGroup1; + this.listView1.Items.AddRange( new System.Windows.Forms.ListViewItem[] { + listViewItem1} ); + this.listView1.Location = new System.Drawing.Point( 0, 0 ); + this.listView1.Name = "listView1"; + this.listView1.OwnerDraw = true; + this.listView1.Scrollable = false; + this.listView1.Size = new System.Drawing.Size( 360, 26 ); + this.listView1.TabIndex = 0; + this.listView1.UseCompatibleStateImageBehavior = false; + // + // listView2 + // + this.listView2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listView2.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listView2.CheckBoxes = true; + this.listView2.Location = new System.Drawing.Point( 0, 24 ); + this.listView2.Name = "listView2"; + this.listView2.Size = new System.Drawing.Size( 360, 83 ); + this.listView2.TabIndex = 1; + this.listView2.UseCompatibleStateImageBehavior = false; + this.listView2.View = System.Windows.Forms.View.SmallIcon; + // + // MListView + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add( this.listView2 ); + this.Controls.Add( this.listView1 ); + this.Name = "MListView"; + this.Size = new System.Drawing.Size( 360, 107 ); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.ListView listView1; + private System.Windows.Forms.ListView listView2; + } +} diff --git a/trunk/LipSync/LipSync/Editor/MListView.cs b/trunk/LipSync/LipSync/Editor/MListView.cs new file mode 100644 index 0000000..7b45efe --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/MListView.cs @@ -0,0 +1,71 @@ +/* + * MListView.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Drawing; +using System.Windows.Forms; + +namespace LipSync { + + public partial class MListView : UserControl { + private Color m_back_color = SystemColors.Window; + + public MListView() { + InitializeComponent(); + } + + public ListView.ListViewItemCollection Items { + get { + return listView2.Items; + } + } + + public bool CheckBoxes { + get { + return listView2.CheckBoxes; + } + set { + listView2.CheckBoxes = value; + } + } + + new public Color BackColor { + get { + return m_back_color; + } + set { + m_back_color = value; + listView1.BackColor = m_back_color; + listView2.BackColor = m_back_color; + } + } + + public string Header { + get { + return listView1.Groups[0].Header; + } + set { + listView1.Groups[0].Header = value; + } + } + + public HorizontalAlignment HeaderAlignment { + get { + return listView1.Groups[0].HeaderAlignment; + } + set { + listView1.Groups[0].HeaderAlignment = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/PasteModeDialog.Designer.cs b/trunk/LipSync/LipSync/Editor/PasteModeDialog.Designer.cs new file mode 100644 index 0000000..2cbb014 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/PasteModeDialog.Designer.cs @@ -0,0 +1,114 @@ +/* + * PasteModeDialog.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class PasteModeDialog { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnInterrupt = new System.Windows.Forms.Button(); + this.btnOverwrite = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // btnInterrupt + // + this.btnInterrupt.Location = new System.Drawing.Point( 12, 56 ); + this.btnInterrupt.Name = "btnInterrupt"; + this.btnInterrupt.Size = new System.Drawing.Size( 88, 23 ); + this.btnInterrupt.TabIndex = 6; + this.btnInterrupt.Text = "割り込ませる"; + this.btnInterrupt.UseVisualStyleBackColor = true; + this.btnInterrupt.Click += new System.EventHandler( this.btnInterrupt_Click ); + // + // btnOverwrite + // + this.btnOverwrite.Location = new System.Drawing.Point( 119, 56 ); + this.btnOverwrite.Name = "btnOverwrite"; + this.btnOverwrite.Size = new System.Drawing.Size( 88, 23 ); + this.btnOverwrite.TabIndex = 7; + this.btnOverwrite.Text = "上書き"; + this.btnOverwrite.UseVisualStyleBackColor = true; + this.btnOverwrite.Click += new System.EventHandler( this.btnOverwrite_Click ); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 226, 56 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 88, 23 ); + this.btnCancel.TabIndex = 8; + this.btnCancel.Text = "キャンセル"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler( this.btnCancel_Click ); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 22, 23 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 151, 12 ); + this.label1.TabIndex = 9; + this.label1.Text = "貼付けモードを指定してください"; + // + // PasteModeDialog + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 329, 107 ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOverwrite ); + this.Controls.Add( this.btnInterrupt ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "PasteModeDialog"; + this.ShowInTaskbar = false; + this.Text = "PasteMode"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnInterrupt; + private System.Windows.Forms.Button btnOverwrite; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label label1; + } +} diff --git a/trunk/LipSync/LipSync/Editor/PasteModeDialog.cs b/trunk/LipSync/LipSync/Editor/PasteModeDialog.cs new file mode 100644 index 0000000..f48e14c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/PasteModeDialog.cs @@ -0,0 +1,77 @@ +/* + * PasteModeDialog.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public enum PasteModeDialogResult { + Interrupt, + Overwrite, + Cancel, + } + + public partial class PasteModeDialog : Form, IMultiLanguageControl { + PasteModeDialogResult m_result = PasteModeDialogResult.Cancel; + + public PasteModeDialog() { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.label1.Text = gettext( "Specify paste mode" ); + this.btnCancel.Text = gettext( "Cancel" ); + this.btnInterrupt.Text = gettext( "Interrupt" ); + this.btnOverwrite.Text = gettext( "Overwrite" ); + } + + public static string gettext( string s ) { + return Messaging.GetMessage( s ); + } + + new public PasteModeDialogResult DialogResult { + get { + return m_result; + } + } + + private void btnCancel_Click( object sender, EventArgs e ) { + this.m_result = PasteModeDialogResult.Cancel; + this.Close(); + } + + private void btnInterrupt_Click( object sender, EventArgs e ) { + this.m_result = PasteModeDialogResult.Interrupt; + this.Close(); + } + + private void btnOverwrite_Click( object sender, EventArgs e ) { + this.m_result = PasteModeDialogResult.Overwrite; + this.Close(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/PluginConfig.cs b/trunk/LipSync/LipSync/Editor/PluginConfig.cs new file mode 100644 index 0000000..528690d --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/PluginConfig.cs @@ -0,0 +1,39 @@ +/* + * PluginConfig.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + [Serializable] + public class PluginConfig { + public string ID; + public string Config; + public PluginConfig() { + ID = ""; + Config = ""; + } + public PluginConfig Clone() { + return new PluginConfig( ID, Config ); + } + public PluginConfig( string name, string config, string filename ) { + ID = name + "@" + filename; + Config = config; + } + public PluginConfig( string id, string config ) { + ID = id; + Config = config; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/PluginInfo.cs b/trunk/LipSync/LipSync/Editor/PluginInfo.cs new file mode 100644 index 0000000..3a6b3b1 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/PluginInfo.cs @@ -0,0 +1,142 @@ +/* + * PluginInfo.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; + +using Plugin; + +namespace LipSync { + + /// + /// プラグインに関する情報 + /// + public class PluginInfo : ICloneable { + private string _location; + private string _className; + private IPlugin _instance = null; + private string _id; + + public object Clone() { + return new PluginInfo( _location, _className ); + } + + /// + /// PluginInfoクラスのコンストラクタ + /// + /// アセンブリファイルのパス + /// クラスの名前 + private PluginInfo( string path, string full_name ) { + this._location = path; + this._className = full_name; + this._id = this.Instance.Name + "@" + Path.GetFileName( path ); + } + + public string ID { + get { + return _id; + } + } + + public IPlugin Instance { + get { + if ( _instance == null ) { + _instance = CreateInstance(); + } + return _instance; + } + } + + /// + /// アセンブリファイルのパス + /// + public string Location { + get { + return _location; + } + } + + /// + /// クラスの名前 + /// + public string ClassName { + get { + return _className; + } + } + + /// + /// 有効なプラグインを探す + /// + /// 有効なプラグインのPluginInfo配列 + public static PluginInfo[] FindPlugins() { + System.Collections.ArrayList plugins = + new System.Collections.ArrayList(); + //IPlugin型の名前 + string ipluginName = typeof( Plugin.IPlugin ).FullName; + + //プラグインフォルダ + string folder = System.IO.Path.GetDirectoryName( + System.Reflection.Assembly + .GetExecutingAssembly().Location ); + /*folder += "\\plugins"; + if ( !System.IO.Directory.Exists( folder ) ) + throw new ApplicationException( + "プラグインフォルダ\"" + folder + + "\"が見つかりませんでした。" );*/ + + //.dllファイルを探す + string[] dlls = + System.IO.Directory.GetFiles( folder, "*.dll" ); + + foreach ( string dll in dlls ) { + try { + //アセンブリとして読み込む + System.Reflection.Assembly asm = + System.Reflection.Assembly.LoadFrom( dll ); + foreach ( Type t in asm.GetTypes() ) { + //アセンブリ内のすべての型について、 + //プラグインとして有効か調べる + if ( t.IsClass && t.IsPublic && !t.IsAbstract && + t.GetInterface( ipluginName ) != null ) { + //PluginInfoをコレクションに追加する + plugins.Add( new PluginInfo( dll, t.FullName ) ); + } + } + } catch { + } + } + + //コレクションを配列にして返す + return (PluginInfo[])plugins.ToArray( typeof( PluginInfo ) ); + } + + /// + /// プラグインクラスのインスタンスを作成する + /// + /// プラグインクラスのインスタンス + private IPlugin CreateInstance() { + try { + //アセンブリを読み込む + System.Reflection.Assembly asm = + System.Reflection.Assembly.LoadFrom( this.Location ); + //クラス名からインスタンスを作成する + return (Plugin.IPlugin) + asm.CreateInstance( this.ClassName ); + } catch { + return null; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Position.cs b/trunk/LipSync/LipSync/Editor/Position.cs new file mode 100644 index 0000000..f554999 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Position.cs @@ -0,0 +1,47 @@ +/* + * Position.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.ComponentModel; + +namespace LipSync { + + [TypeConverter( typeof( PositionConverter ) )] + public class Position { + private float m_x = 0f; + private float m_y = 0f; + + public Position( float x, float y ) { + m_x = x; + m_y = y; + } + + public float X { + get { + return m_x; + } + set { + m_x = value; + } + } + + public float Y { + get { + return m_y; + } + set { + m_y = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/PositionConverter.cs b/trunk/LipSync/LipSync/Editor/PositionConverter.cs new file mode 100644 index 0000000..694f687 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/PositionConverter.cs @@ -0,0 +1,67 @@ +/* + * PositionConverter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.ComponentModel; + +namespace LipSync { + + public class PositionConverter : ExpandableObjectConverter { + //コンバータがオブジェクトを指定した型に変換できるか + //(変換できる時はTrueを返す) + //ここでは、CustomClass型のオブジェクトには変換可能とする + public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType ) { + if ( destinationType == typeof( Position ) ) { + return true; + } + return base.CanConvertTo( context, destinationType ); + } + + //指定した値オブジェクトを、指定した型に変換する + //CustomClass型のオブジェクトをString型に変換する方法を提供する + public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType ) { + if ( destinationType == typeof( string ) && value is Position ) { + Position cc = (Position)value; + return cc.X + ", " + cc.Y; + } + return base.ConvertTo( context, culture, value, destinationType ); + } + + //コンバータが特定の型のオブジェクトをコンバータの型に変換できるか + //(変換できる時はTrueを返す) + //ここでは、String型のオブジェクトなら変換可能とする + public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) { + if ( sourceType == typeof( string ) ) { + return true; + } + return base.CanConvertFrom( context, sourceType ); + } + + //指定した値をコンバータの型に変換する + //String型のオブジェクトをCustomClass型に変換する方法を提供する + public override object ConvertFrom( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value ) { + if ( value is string ) { + string[] ss = value.ToString().Split( new char[] { ',' }, 2 ); + Position cc = new Position( 0f, 0f ); + try { + cc.X = float.Parse( ss[0] ); + cc.Y = float.Parse( ss[1] ); + } catch { + } + return cc; + } + return base.ConvertFrom( context, culture, value ); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Previewer.Designer.cs b/trunk/LipSync/LipSync/Editor/Previewer.Designer.cs new file mode 100644 index 0000000..f66c6a9 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Previewer.Designer.cs @@ -0,0 +1,328 @@ +/* + * Previewer.Designer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class Previewer { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.panel1 = new System.Windows.Forms.Panel(); + this.btnSpeed = new System.Windows.Forms.Button(); + this.checkMute = new System.Windows.Forms.CheckBox(); + this.lblSpeed = new System.Windows.Forms.Label(); + this.trackSpeed = new System.Windows.Forms.TrackBar(); + this.play_pause = new System.Windows.Forms.Button(); + this.trackVolume = new System.Windows.Forms.TrackBar(); + this.stop = new System.Windows.Forms.Button(); + this.trackBar1 = new System.Windows.Forms.TrackBar(); + this.lblTime = new System.Windows.Forms.Label(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip( this.components ); + this.menuHundred = new System.Windows.Forms.ToolStripMenuItem(); + this.menuFit = new System.Windows.Forms.ToolStripMenuItem(); + this.menuSet = new System.Windows.Forms.ToolStripMenuItem(); + this.panel2 = new System.Windows.Forms.Panel(); + this.PreviewP = new System.Windows.Forms.PictureBox(); + this.splitContainer1 = new System.Windows.Forms.SplitContainer(); + this.panel1.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.trackSpeed)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackVolume)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).BeginInit(); + this.contextMenuStrip1.SuspendLayout(); + this.panel2.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.PreviewP)).BeginInit(); + this.splitContainer1.Panel1.SuspendLayout(); + this.splitContainer1.Panel2.SuspendLayout(); + this.splitContainer1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.panel1.BackColor = System.Drawing.Color.DarkGray; + this.panel1.Controls.Add( this.btnSpeed ); + this.panel1.Controls.Add( this.checkMute ); + this.panel1.Controls.Add( this.lblSpeed ); + this.panel1.Controls.Add( this.trackSpeed ); + this.panel1.Controls.Add( this.play_pause ); + this.panel1.Controls.Add( this.trackVolume ); + this.panel1.Controls.Add( this.stop ); + this.panel1.Location = new System.Drawing.Point( 0, 0 ); + this.panel1.Margin = new System.Windows.Forms.Padding( 0 ); + this.panel1.MinimumSize = new System.Drawing.Size( 82, 0 ); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size( 82, 389 ); + this.panel1.TabIndex = 13; + // + // btnSpeed + // + this.btnSpeed.BackColor = System.Drawing.SystemColors.Control; + this.btnSpeed.Location = new System.Drawing.Point( 2, 81 ); + this.btnSpeed.Name = "btnSpeed"; + this.btnSpeed.Size = new System.Drawing.Size( 36, 24 ); + this.btnSpeed.TabIndex = 17; + this.btnSpeed.Text = "spd."; + this.btnSpeed.UseVisualStyleBackColor = false; + this.btnSpeed.Click += new System.EventHandler( this.btnSpeed_Click ); + // + // checkMute + // + this.checkMute.Appearance = System.Windows.Forms.Appearance.Button; + this.checkMute.BackColor = System.Drawing.SystemColors.Control; + this.checkMute.Location = new System.Drawing.Point( 42, 81 ); + this.checkMute.Name = "checkMute"; + this.checkMute.Size = new System.Drawing.Size( 36, 24 ); + this.checkMute.TabIndex = 16; + this.checkMute.Text = "vol."; + this.checkMute.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + this.checkMute.UseVisualStyleBackColor = false; + this.checkMute.CheckedChanged += new System.EventHandler( this.checkMute_CheckedChanged ); + // + // lblSpeed + // + this.lblSpeed.Location = new System.Drawing.Point( 3, 222 ); + this.lblSpeed.Name = "lblSpeed"; + this.lblSpeed.Size = new System.Drawing.Size( 35, 21 ); + this.lblSpeed.TabIndex = 15; + this.lblSpeed.Text = "x1.0"; + this.lblSpeed.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // trackSpeed + // + this.trackSpeed.AutoSize = false; + this.trackSpeed.BackColor = System.Drawing.Color.DarkGray; + this.trackSpeed.Location = new System.Drawing.Point( 11, 105 ); + this.trackSpeed.Maximum = 1500; + this.trackSpeed.Minimum = 500; + this.trackSpeed.Name = "trackSpeed"; + this.trackSpeed.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trackSpeed.Size = new System.Drawing.Size( 20, 114 ); + this.trackSpeed.TabIndex = 12; + this.trackSpeed.TickFrequency = 50; + this.trackSpeed.Value = 1000; + this.trackSpeed.Scroll += new System.EventHandler( this.trackSpeed_Scroll ); + this.trackSpeed.MouseUp += new System.Windows.Forms.MouseEventHandler( this.trackSpeed_MouseUp ); + // + // play_pause + // + this.play_pause.BackColor = System.Drawing.SystemColors.Control; + this.play_pause.Location = new System.Drawing.Point( 11, 9 ); + this.play_pause.Name = "play_pause"; + this.play_pause.Size = new System.Drawing.Size( 61, 22 ); + this.play_pause.TabIndex = 8; + this.play_pause.Text = "再生"; + this.play_pause.UseVisualStyleBackColor = false; + this.play_pause.Click += new System.EventHandler( this.play_pause_Click ); + // + // trackVolume + // + this.trackVolume.AutoSize = false; + this.trackVolume.BackColor = System.Drawing.Color.DarkGray; + this.trackVolume.Location = new System.Drawing.Point( 52, 105 ); + this.trackVolume.Maximum = 2000; + this.trackVolume.Name = "trackVolume"; + this.trackVolume.Orientation = System.Windows.Forms.Orientation.Vertical; + this.trackVolume.Size = new System.Drawing.Size( 20, 114 ); + this.trackVolume.SmallChange = 100; + this.trackVolume.TabIndex = 10; + this.trackVolume.TickFrequency = 100; + this.trackVolume.Value = 1000; + this.trackVolume.Scroll += new System.EventHandler( this.trackVolume_Scroll ); + // + // stop + // + this.stop.BackColor = System.Drawing.SystemColors.Control; + this.stop.Location = new System.Drawing.Point( 11, 39 ); + this.stop.Name = "stop"; + this.stop.Size = new System.Drawing.Size( 61, 22 ); + this.stop.TabIndex = 9; + this.stop.Text = "停止"; + this.stop.UseVisualStyleBackColor = false; + this.stop.Click += new System.EventHandler( this.stop_Click ); + // + // trackBar1 + // + this.trackBar1.AutoSize = false; + this.trackBar1.Dock = System.Windows.Forms.DockStyle.Fill; + this.trackBar1.Location = new System.Drawing.Point( 0, 0 ); + this.trackBar1.Margin = new System.Windows.Forms.Padding( 0 ); + this.trackBar1.Name = "trackBar1"; + this.trackBar1.Size = new System.Drawing.Size( 559, 22 ); + this.trackBar1.TabIndex = 5; + this.trackBar1.TickStyle = System.Windows.Forms.TickStyle.None; + this.trackBar1.Scroll += new System.EventHandler( this.trackBar1_Scroll ); + // + // lblTime + // + this.lblTime.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.lblTime.BackColor = System.Drawing.Color.DarkGray; + this.lblTime.Location = new System.Drawing.Point( 82, 0 ); + this.lblTime.Margin = new System.Windows.Forms.Padding( 0 ); + this.lblTime.Name = "lblTime"; + this.lblTime.Size = new System.Drawing.Size( 477, 16 ); + this.lblTime.TabIndex = 18; + this.lblTime.Text = "0.0s"; + this.lblTime.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.lblTime.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.lblTime_MouseDoubleClick ); + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuHundred, + this.menuFit, + this.menuSet} ); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.ShowImageMargin = false; + this.contextMenuStrip1.Size = new System.Drawing.Size( 120, 70 ); + // + // menuHundred + // + this.menuHundred.Name = "menuHundred"; + this.menuHundred.Size = new System.Drawing.Size( 119, 22 ); + this.menuHundred.Text = "100%"; + this.menuHundred.Click += new System.EventHandler( this.menuHundred_Click ); + // + // menuFit + // + this.menuFit.Name = "menuFit"; + this.menuFit.Size = new System.Drawing.Size( 119, 22 ); + this.menuFit.Text = "画面に合わせる"; + this.menuFit.Click += new System.EventHandler( this.menuFit_Click ); + // + // menuSet + // + this.menuSet.Enabled = false; + this.menuSet.Name = "menuSet"; + this.menuSet.Size = new System.Drawing.Size( 119, 22 ); + this.menuSet.Text = "指定サイズ"; + // + // panel2 + // + this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel2.Controls.Add( this.PreviewP ); + this.panel2.Location = new System.Drawing.Point( 82, 17 ); + this.panel2.Margin = new System.Windows.Forms.Padding( 0 ); + this.panel2.Name = "panel2"; + this.panel2.Size = new System.Drawing.Size( 477, 372 ); + this.panel2.TabIndex = 19; + // + // PreviewP + // + this.PreviewP.ContextMenuStrip = this.contextMenuStrip1; + this.PreviewP.Dock = System.Windows.Forms.DockStyle.Fill; + this.PreviewP.Location = new System.Drawing.Point( 0, 0 ); + this.PreviewP.Margin = new System.Windows.Forms.Padding( 0 ); + this.PreviewP.Name = "PreviewP"; + this.PreviewP.Size = new System.Drawing.Size( 477, 372 ); + this.PreviewP.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; + this.PreviewP.TabIndex = 4; + this.PreviewP.TabStop = false; + this.PreviewP.MouseMove += new System.Windows.Forms.MouseEventHandler( this.PreviewP_MouseMove ); + this.PreviewP.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler( this.PreviewP_MouseDoubleClick ); + this.PreviewP.MouseDown += new System.Windows.Forms.MouseEventHandler( this.PreviewP_MouseDown ); + this.PreviewP.Paint += new System.Windows.Forms.PaintEventHandler( this.PreviewP_Paint ); + this.PreviewP.MouseUp += new System.Windows.Forms.MouseEventHandler( this.PreviewP_MouseUp ); + this.PreviewP.SizeChanged += new System.EventHandler( this.PreviewP_SizeChanged ); + // + // splitContainer1 + // + this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill; + this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel2; + this.splitContainer1.Location = new System.Drawing.Point( 0, 0 ); + this.splitContainer1.Name = "splitContainer1"; + this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal; + // + // splitContainer1.Panel1 + // + this.splitContainer1.Panel1.Controls.Add( this.panel1 ); + this.splitContainer1.Panel1.Controls.Add( this.lblTime ); + this.splitContainer1.Panel1.Controls.Add( this.panel2 ); + // + // splitContainer1.Panel2 + // + this.splitContainer1.Panel2.Controls.Add( this.trackBar1 ); + this.splitContainer1.Panel2MinSize = 22; + this.splitContainer1.Size = new System.Drawing.Size( 559, 412 ); + this.splitContainer1.SplitterDistance = 389; + this.splitContainer1.SplitterWidth = 1; + this.splitContainer1.TabIndex = 20; + // + // Previewer + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add( this.splitContainer1 ); + this.Name = "Previewer"; + this.Size = new System.Drawing.Size( 559, 412 ); + this.Paint += new System.Windows.Forms.PaintEventHandler( this.Previewer_Paint ); + this.FontChanged += new System.EventHandler( this.Previewer_FontChanged ); + this.panel1.ResumeLayout( false ); + ((System.ComponentModel.ISupportInitialize)(this.trackSpeed)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackVolume)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.trackBar1)).EndInit(); + this.contextMenuStrip1.ResumeLayout( false ); + this.panel2.ResumeLayout( false ); + ((System.ComponentModel.ISupportInitialize)(this.PreviewP)).EndInit(); + this.splitContainer1.Panel1.ResumeLayout( false ); + this.splitContainer1.Panel2.ResumeLayout( false ); + this.splitContainer1.ResumeLayout( false ); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button btnSpeed; + private System.Windows.Forms.CheckBox checkMute; + private System.Windows.Forms.Label lblSpeed; + private System.Windows.Forms.TrackBar trackSpeed; + private System.Windows.Forms.TrackBar trackVolume; + private System.Windows.Forms.Button stop; + private System.Windows.Forms.TrackBar trackBar1; + private System.Windows.Forms.Label lblTime; + private System.Windows.Forms.Button play_pause; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem menuHundred; + private System.Windows.Forms.ToolStripMenuItem menuFit; + private System.Windows.Forms.ToolStripMenuItem menuSet; + private System.Windows.Forms.PictureBox PreviewP; + private System.Windows.Forms.Panel panel2; + private System.Windows.Forms.SplitContainer splitContainer1; + } +} diff --git a/trunk/LipSync/LipSync/Editor/Previewer.cs b/trunk/LipSync/LipSync/Editor/Previewer.cs new file mode 100644 index 0000000..b206a3c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Previewer.cs @@ -0,0 +1,318 @@ +/* + * Previewer.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class Previewer : UserControl { + /// + /// プレビュー用のイメージ.PreviewP.Imageの本体として指定される + /// + Bitmap m_preview = null; + + public event EventHandler PlayPauseClicked; + public event EventHandler StopClicked; + public event EventHandler SpeedClicked; + public event EventHandler CheckMuteCheckedChanged; + public event MouseEventHandler TrackSpeedMouseUp; + public event EventHandler TrackSpeedScroll; + public event EventHandler TrackVolumeScroll; + public event EventHandler TrackBarScroll; + public event MouseEventHandler PreviewMouseDoubleClick; + public event MouseEventHandler PreviewMouseDown; + public event MouseEventHandler PreviewMouseMove; + public event MouseEventHandler PreviewMouseUp; + public event PaintEventHandler PreviewPaint; + public event EventHandler MenuHundredClick; + public event EventHandler MenuFitClick; + public event EventHandler LabelTimeMouseDoubleClick; + public event EventHandler PreviewSizeChanged; + + public Previewer() { + InitializeComponent(); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public void ApplyLanguage() { + this.play_pause.Text = _( "Play" ); + this.stop.Text = _( "Stop" ); + this.menuFit.Text = _( "Stretch image" ); + this.menuSet.Text = _( "Specified size" ); + } + + public Bitmap Image { + get { + return m_preview; + } + set { + m_preview = value; + PreviewP.Image = m_preview; + } + } + + #region PropertyProxy + public string PlayPauseText { + get { + return play_pause.Text; + } + set { + play_pause.Text = value; + } + } + + public bool PlayPauseEnabled { + get { + return play_pause.Enabled; + } + set { + play_pause.Enabled = value; + } + } + + public bool CheckMuteChecked { + get { + return checkMute.Checked; + } + set { + checkMute.Checked = value; + } + } + + public int TrackSpeedValue { + get { + return trackSpeed.Value; + } + set { + trackSpeed.Value = value; + } + } + + public int TrackVolumeValue { + get { + return trackVolume.Value; + } + set { + trackVolume.Value = value; + } + } + + public int TrackBarValue { + get { + return trackBar1.Value; + } + set { + trackBar1.Value = value; + } + } + + public int TrackBarMaximum { + get { + return trackBar1.Maximum; + } + set { + trackBar1.Maximum = value; + } + } + + public int TrackBarMinimum { + get { + return trackBar1.Minimum; + } + set { + trackBar1.Minimum = value; + } + } + + public bool TrackBarEnabled { + get { + return trackBar1.Enabled; + } + set { + trackBar1.Enabled = value; + } + } + + public string LabelTimeText { + get { + return lblTime.Text; + } + set { + lblTime.Text = value; + } + } + + public string LabelSpeedText { + get { + return lblSpeed.Text; + } + set { + lblSpeed.Text = value; + } + } + + public PictureBoxSizeMode PreviewSizeMode { + get { + return PreviewP.SizeMode; + } + set { + PreviewP.SizeMode = value; + } + } + + public int PreviewWidth { + get { + return PreviewP.Width; + } + } + + + public int PreviewHeight { + get { + return PreviewP.Height; + } + } + + public PictureBox Preview { + get { + return PreviewP; + } + } + #endregion + + #region EventHandlerProxy + private void play_pause_Click( object sender, EventArgs e ) { + if ( PlayPauseClicked != null ) { + PlayPauseClicked( sender, e ); + } + } + + private void stop_Click( object sender, EventArgs e ) { + if ( StopClicked != null ) { + StopClicked( sender, e ); + } + } + + private void btnSpeed_Click( object sender, EventArgs e ) { + if ( SpeedClicked != null ) { + SpeedClicked( sender, e ); + } + } + + private void checkMute_CheckedChanged( object sender, EventArgs e ) { + if ( CheckMuteCheckedChanged != null ) { + CheckMuteCheckedChanged( sender, e ); + } + } + + private void trackSpeed_MouseUp( object sender, MouseEventArgs e ) { + if ( TrackSpeedMouseUp != null ) { + TrackSpeedMouseUp( sender, e ); + } + } + + private void trackSpeed_Scroll( object sender, EventArgs e ) { + if ( TrackSpeedScroll != null ) { + TrackSpeedScroll( sender, e ); + } + } + + private void trackVolume_Scroll( object sender, EventArgs e ) { + if ( TrackVolumeScroll != null ) { + TrackVolumeScroll( sender, e ); + } + } + + private void trackBar1_Scroll( object sender, EventArgs e ) { + if ( TrackBarScroll != null ) { + TrackBarScroll( sender, e ); + } + } + + private void PreviewP_MouseDoubleClick( object sender, MouseEventArgs e ) { + if ( PreviewMouseDoubleClick != null ) { + PreviewMouseDoubleClick( sender, e ); + } + } + + private void PreviewP_MouseDown( object sender, MouseEventArgs e ) { + if ( PreviewMouseDown != null ) { + PreviewMouseDown( sender, e ); + } + } + + private void PreviewP_MouseMove( object sender, MouseEventArgs e ) { + if ( AppManager.Playing ) { + return; + } + if ( PreviewMouseMove != null ) { + PreviewMouseMove( sender, e ); + } + PreviewP.Invalidate(); + } + + private void PreviewP_MouseUp( object sender, MouseEventArgs e ) { + if ( PreviewMouseUp != null ) { + PreviewMouseUp( sender, e ); + } + } + + private void PreviewP_Paint( object sender, PaintEventArgs e ) { + if ( PreviewPaint != null ) { + PreviewPaint( sender, e ); + } + } + + private void menuHundred_Click( object sender, EventArgs e ) { + if ( MenuHundredClick != null ) { + MenuHundredClick( sender, e ); + } + } + + private void menuFit_Click( object sender, EventArgs e ) { + if ( MenuFitClick != null ) { + MenuFitClick( sender, e ); + } + } + + private void lblTime_MouseDoubleClick( object sender, MouseEventArgs e ) { + if ( LabelTimeMouseDoubleClick != null ) { + LabelTimeMouseDoubleClick( sender, e ); + } + } + #endregion + + private void Previewer_Paint( object sender, PaintEventArgs e ) { + PreviewP.Refresh(); + } + + private void Previewer_FontChanged( object sender, EventArgs e ) { + contextMenuStrip1.Font = this.Font; + } + + private void PreviewP_SizeChanged( object sender, EventArgs e ) { + + if ( PreviewSizeChanged != null ) { + PreviewSizeChanged( sender, e ); + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Property.Designer.cs b/trunk/LipSync/LipSync/Editor/Property.Designer.cs new file mode 100644 index 0000000..edd406a --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Property.Designer.cs @@ -0,0 +1,273 @@ +/* + * Property.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class Property { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region コンポーネント デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); + this.cmenu = new System.Windows.Forms.ContextMenuStrip( this.components ); + this.menuAddTelop = new System.Windows.Forms.ToolStripMenuItem(); + this.menuDeleteTelop = new System.Windows.Forms.ToolStripMenuItem(); + this.sContainer = new Boare.Lib.AppUtil.BSplitContainer(); + this.panelListView = new System.Windows.Forms.Panel(); + this.listView = new System.Windows.Forms.ListView(); + this.columnHeaderStart = new System.Windows.Forms.ColumnHeader(); + this.columnHeaderType = new System.Windows.Forms.ColumnHeader(); + this.columnHeaderAbst = new System.Windows.Forms.ColumnHeader(); + this.titleUpper = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.PropertyGrid = new System.Windows.Forms.PropertyGrid(); + this.titleLower = new System.Windows.Forms.Label(); + this.cmenu.SuspendLayout(); + this.sContainer.Panel1.SuspendLayout(); + this.sContainer.Panel2.SuspendLayout(); + this.panelListView.SuspendLayout(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // cmenu + // + this.cmenu.Items.AddRange( new System.Windows.Forms.ToolStripItem[] { + this.menuAddTelop, + this.menuDeleteTelop} ); + this.cmenu.Name = "cmenu"; + this.cmenu.ShowImageMargin = false; + this.cmenu.Size = new System.Drawing.Size( 104, 48 ); + // + // menuAddTelop + // + this.menuAddTelop.Name = "menuAddTelop"; + this.menuAddTelop.Size = new System.Drawing.Size( 103, 22 ); + this.menuAddTelop.Text = "テロップ追加"; + this.menuAddTelop.Click += new System.EventHandler( this.menuAddTelop_Click ); + // + // menuDeleteTelop + // + this.menuDeleteTelop.Name = "menuDeleteTelop"; + this.menuDeleteTelop.Size = new System.Drawing.Size( 103, 22 ); + this.menuDeleteTelop.Text = "テロップ削除"; + this.menuDeleteTelop.Click += new System.EventHandler( this.menuDeleteTelop_Click ); + // + // sContainer + // + this.sContainer.BackColor = System.Drawing.SystemColors.Control; + this.sContainer.Dock = System.Windows.Forms.DockStyle.Fill; + this.sContainer.ForeColor = System.Drawing.SystemColors.ControlText; + this.sContainer.IsSplitterFixed = false; + this.sContainer.Location = new System.Drawing.Point( 0, 0 ); + this.sContainer.Name = "sContainer"; + this.sContainer.Orientation = System.Windows.Forms.Orientation.Vertical; + // + // + // + this.sContainer.Panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.sContainer.Panel1.AutoScroll = true; + this.sContainer.Panel1.BorderColor = System.Drawing.SystemColors.ControlDark; + this.sContainer.Panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.sContainer.Panel1.Controls.Add( this.panelListView ); + this.sContainer.Panel1.Controls.Add( this.titleUpper ); + this.sContainer.Panel1.Location = new System.Drawing.Point( 1, 1 ); + this.sContainer.Panel1.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 4 ); + this.sContainer.Panel1.Name = "m_panel1"; + this.sContainer.Panel1.Padding = new System.Windows.Forms.Padding( 1 ); + this.sContainer.Panel1.Size = new System.Drawing.Size( 192, 124 ); + this.sContainer.Panel1.TabIndex = 0; + this.sContainer.Panel1.Enter += new System.EventHandler( this.splitContainer1_Panel1_Enter ); + this.sContainer.Panel1.Leave += new System.EventHandler( this.splitContainer1_Panel1_Leave ); + this.sContainer.Panel1MinSize = 0; + // + // + // + this.sContainer.Panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.sContainer.Panel2.BorderColor = System.Drawing.SystemColors.ControlDark; + this.sContainer.Panel2.Controls.Add( this.panel1 ); + this.sContainer.Panel2.Controls.Add( this.titleLower ); + this.sContainer.Panel2.Location = new System.Drawing.Point( 0, 130 ); + this.sContainer.Panel2.Margin = new System.Windows.Forms.Padding( 0 ); + this.sContainer.Panel2.Name = "m_panel2"; + this.sContainer.Panel2.Size = new System.Drawing.Size( 194, 199 ); + this.sContainer.Panel2.TabIndex = 1; + this.sContainer.Panel2.Enter += new System.EventHandler( this.splitContainer1_Panel2_Enter ); + this.sContainer.Panel2.Leave += new System.EventHandler( this.splitContainer1_Panel2_Leave ); + this.sContainer.Panel2MinSize = 25; + this.sContainer.Size = new System.Drawing.Size( 194, 329 ); + this.sContainer.SplitterDistance = 126; + this.sContainer.SplitterWidth = 4; + this.sContainer.TabIndex = 0; + // + // panelListView + // + this.panelListView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panelListView.Controls.Add( this.listView ); + this.panelListView.Location = new System.Drawing.Point( 1, 20 ); + this.panelListView.Margin = new System.Windows.Forms.Padding( 0 ); + this.panelListView.Name = "panelListView"; + this.panelListView.Size = new System.Drawing.Size( 190, 103 ); + this.panelListView.TabIndex = 3; + // + // listView + // + this.listView.AllowColumnReorder = true; + this.listView.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.listView.Columns.AddRange( new System.Windows.Forms.ColumnHeader[] { + this.columnHeaderStart, + this.columnHeaderType, + this.columnHeaderAbst} ); + this.listView.ContextMenuStrip = this.cmenu; + this.listView.Dock = System.Windows.Forms.DockStyle.Fill; + this.listView.ForeColor = System.Drawing.SystemColors.WindowText; + this.listView.FullRowSelect = true; + this.listView.GridLines = true; + this.listView.Location = new System.Drawing.Point( 0, 0 ); + this.listView.Margin = new System.Windows.Forms.Padding( 0 ); + this.listView.MultiSelect = false; + this.listView.Name = "listView"; + this.listView.ShowGroups = false; + this.listView.Size = new System.Drawing.Size( 190, 103 ); + this.listView.TabIndex = 2; + this.listView.UseCompatibleStateImageBehavior = false; + this.listView.View = System.Windows.Forms.View.Details; + this.listView.SelectedIndexChanged += new System.EventHandler( this.listView_SelectedIndexChanged ); + this.listView.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler( this.listView_ColumnClick ); + // + // columnHeaderStart + // + this.columnHeaderStart.Text = "start"; + this.columnHeaderStart.Width = 50; + // + // columnHeaderType + // + this.columnHeaderType.Text = "type"; + this.columnHeaderType.Width = 50; + // + // columnHeaderAbst + // + this.columnHeaderAbst.Text = "abstract"; + this.columnHeaderAbst.Width = 88; + // + // titleUpper + // + this.titleUpper.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.titleUpper.BackColor = System.Drawing.SystemColors.InactiveCaption; + this.titleUpper.ForeColor = System.Drawing.SystemColors.InactiveCaptionText; + this.titleUpper.Location = new System.Drawing.Point( 1, 0 ); + this.titleUpper.Margin = new System.Windows.Forms.Padding( 0, 2, 0, 2 ); + this.titleUpper.Name = "titleUpper"; + this.titleUpper.Size = new System.Drawing.Size( 190, 15 ); + this.titleUpper.TabIndex = 1; + this.titleUpper.Text = "label1"; + this.titleUpper.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.titleUpper.DoubleClick += new System.EventHandler( this.titleUpper_DoubleClick ); + this.titleUpper.MouseDown += new System.Windows.Forms.MouseEventHandler( this.titleUpper_MouseDown ); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Controls.Add( this.PropertyGrid ); + this.panel1.Location = new System.Drawing.Point( 0, 17 ); + this.panel1.Margin = new System.Windows.Forms.Padding( 0 ); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size( 194, 182 ); + this.panel1.TabIndex = 3; + // + // PropertyGrid + // + this.PropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill; + this.PropertyGrid.Location = new System.Drawing.Point( 0, 0 ); + this.PropertyGrid.Margin = new System.Windows.Forms.Padding( 0 ); + this.PropertyGrid.Name = "PropertyGrid"; + this.PropertyGrid.Size = new System.Drawing.Size( 194, 182 ); + this.PropertyGrid.TabIndex = 0; + this.PropertyGrid.Click += new System.EventHandler( this.PropertyGrid_Click ); + this.PropertyGrid.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler( this.PropertyGrid_PropertyValueChanged ); + // + // titleLower + // + this.titleLower.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.titleLower.BackColor = System.Drawing.SystemColors.InactiveCaption; + this.titleLower.ForeColor = System.Drawing.SystemColors.InactiveCaptionText; + this.titleLower.Location = new System.Drawing.Point( 0, 0 ); + this.titleLower.Margin = new System.Windows.Forms.Padding( 0, 0, 0, 2 ); + this.titleLower.Name = "titleLower"; + this.titleLower.Size = new System.Drawing.Size( 194, 15 ); + this.titleLower.TabIndex = 2; + this.titleLower.Text = "label2"; + this.titleLower.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; + this.titleLower.MouseDown += new System.Windows.Forms.MouseEventHandler( this.titleLower_MouseDown ); + // + // Property + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.Controls.Add( this.sContainer ); + this.Name = "Property"; + this.Size = new System.Drawing.Size( 194, 329 ); + this.FontChanged += new System.EventHandler( this.Property_FontChanged ); + this.cmenu.ResumeLayout( false ); + this.sContainer.Panel1.ResumeLayout( false ); + this.sContainer.Panel2.ResumeLayout( false ); + this.panelListView.ResumeLayout( false ); + this.panel1.ResumeLayout( false ); + this.ResumeLayout( false ); + + } + + #endregion + + private Boare.Lib.AppUtil.BSplitContainer sContainer; + public System.Windows.Forms.Label titleUpper; + public System.Windows.Forms.Label titleLower; + private System.Windows.Forms.ContextMenuStrip cmenu; + private System.Windows.Forms.ToolStripMenuItem menuAddTelop; + private System.Windows.Forms.ToolStripMenuItem menuDeleteTelop; + private System.Windows.Forms.ListView listView; + private System.Windows.Forms.ColumnHeader columnHeaderStart; + private System.Windows.Forms.ColumnHeader columnHeaderType; + private System.Windows.Forms.ColumnHeader columnHeaderAbst; + private System.Windows.Forms.Panel panelListView; + private System.Windows.Forms.PropertyGrid PropertyGrid; + private System.Windows.Forms.Panel panel1; + } +} diff --git a/trunk/LipSync/LipSync/Editor/Property.cs b/trunk/LipSync/LipSync/Editor/Property.cs new file mode 100644 index 0000000..0cfa3a8 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Property.cs @@ -0,0 +1,389 @@ +/* + * Property.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public delegate void TelopAddingEventHandler(); + public delegate void TelopDeletingEventHandler( ZorderItem e ); + public delegate void EditingItemChangedEventHandler( ZorderItem e ); + public delegate void ListUpdateRequiredEventHandler(); + + public partial class Property : UserControl { + private ZorderItem m_editing = null; + FormObjectList m_form_objectlist; + int m_last_splitter_distance = 126; + bool[] m_sort_ascend = new bool[] { true, true, true }; // start, type, abstの各項目が昇順で並べ替えられているかどうかを表す + int[] m_sort_order = new int[] { 0, 1, 2 }; // start, type, abstの列のデータが,項目を並べ替える際に順番の判定に使用される順位. + private static Property m_instance = null; + + /// + /// プロパティ・ビューの値が変更されたときに発生します + /// + public event PropertyValueChangedEventHandler PropertyValueChanged; + /// + /// テロップの追加が要求されたときに発生します + /// + public event TelopAddingEventHandler TelopAdding; + /// + /// テロップの削除が要求されたときに発生します + /// + public event TelopDeletingEventHandler TelopDeleting; + /// + /// オブジェクトリストで選択アイテムが変更されたとき発生します + /// + public event EventHandler SelectedIndexChanged; + public event EditingItemChangedEventHandler EditingItemChanged; + /// + /// オブジェクトリストの更新が必要となったとき発生します + /// + public event ListUpdateRequiredEventHandler ListUpdateRequired; + + public void UpdateLayout() { + // panel1 + titleUpper.Left = 0; + titleUpper.Top = 0; + titleUpper.Width = sContainer.Panel1.Width; + panelListView.Left = 0; + panelListView.Top = titleUpper.Height; + panelListView.Width = sContainer.Panel1.Width; + panelListView.Height = sContainer.Panel1.Height - titleUpper.Height; + + // panel2 + titleLower.Left = 0; + titleLower.Top = 0; + titleLower.Width = sContainer.Panel2.Width; + panel1.Left = 0; + panel1.Top = titleLower.Height; + panel1.Width = sContainer.Panel2.Width; + panel1.Height = sContainer.Panel2.Height - titleLower.Height; + } + + public void ApplyLanguage() { + menuAddTelop.Text = _( "Add Telop" ) + "(&A)"; + menuDeleteTelop.Text = _( "Delte Delop" ) + "(&D)"; + m_form_objectlist.ApplyLanguage(); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public static Property Instance { + get { + return m_instance; + } + } + + public void Sort() { + if ( listView.Items.Count < 2 ) { + return; + } + bool changed = true; + List sorting = new List(); + for ( int i = 0; i < listView.Items.Count; i++ ) { + sorting.Add( listView.Items[i] ); + } + while ( changed ) { + changed = false; + for ( int i = 0; i < sorting.Count - 1; i++ ) { + if ( Compare( sorting[i], sorting[i + 1] ) > 0 ) { + ListViewItem cp = (ListViewItem)sorting[i].Clone(); + sorting[i] = (ListViewItem)sorting[i + 1].Clone(); + sorting[i + 1] = cp; + changed = true; + } + } + } + listView.Items.Clear(); + listView.Items.AddRange( sorting.ToArray() ); + } + + /// + /// 第index1項目が第index2項目より順位が低いときtrue,そうでないときfalse + /// + /// + /// + /// + public int Compare( ListViewItem item1, ListViewItem item2 ) { + int[] order = new int[3]; + order[0] = CompareWithStart( item1, item2 ); + order[1] = CompareWithType( item1, item2 ); + order[2] = CompareWithAbst( item1, item2 ); + if ( order[m_sort_order[0]] == 0 ) { + if ( order[m_sort_order[1]] == 0 ) { + return order[m_sort_order[2]]; + } else { + return order[m_sort_order[1]]; + } + } else { + return order[m_sort_order[0]]; + } + } + + private int CompareWithAbst( ListViewItem item1, ListViewItem item2 ) { + string t1 = item1.SubItems[2].Text; + string t2 = item2.SubItems[2].Text; + int res = t1.CompareTo( t2 ); + if ( !m_sort_ascend[2] ) { + res = -1 * res; + } + return res; + } + + private int CompareWithType( ListViewItem item1, ListViewItem item2 ) { + if ( !(item1.Tag is ZorderItem) || !(item2.Tag is ZorderItem) ) { + return 0; + } + ZorderItem zitem1 = (ZorderItem)item1.Tag; + ZorderItem zitem2 = (ZorderItem)item2.Tag; + ZorderItemType t1 = zitem1.Type; + ZorderItemType t2 = zitem2.Type; + int res = t1.CompareTo( t2 ); + if ( !m_sort_ascend[1] ) { + res = -1 * res; + } + return res; + } + + private int CompareWithStart( ListViewItem item1, ListViewItem item2 ) { + float titem1 = ((ZorderItem)item1.Tag).Start; + float titem2 = ((ZorderItem)item2.Tag).Start; + int res = 0; + if ( titem1 > titem2 ) { + res = 1; + } else if ( titem1 < titem2 ) { + res = -1; + } else { + res = 0; + } + if ( !m_sort_ascend[0] ) { + res = -1 * res; + } + return res; + } + + public ZorderItem this[int index] { + get { + return (ZorderItem)listView.Items[index].Tag; + } + } + + public int Count { + get { + return listView.Items.Count; + } + } + + public int SelectedIndex { + get { + if ( listView.SelectedItems.Count > 0 ) { + foreach ( ListViewItem item in listView.SelectedItems ) { + return item.Index; + } + } + return -1; + } + set { + for ( int i = 0; i < listView.Items.Count; i++ ) { + if ( i == value ) { + listView.Items[i].Selected = true; + } else { + listView.Items[i].Selected = false; + } + } + } + } + + public ZorderItem SelectedItem { + get { + int index = SelectedIndex; + if ( index < 0 || listView.Items.Count <= index ) { + return null; + } else { + return (ZorderItem)listView.Items[index].Tag; + } + } + } + + public ListView ListView { + get { + return listView; + } + } + + public ZorderItem Editing { + get { + return m_editing; + } + set { + m_editing = value; + if ( this.EditingItemChanged != null ) { + this.EditingItemChanged( m_editing ); + } + } + } + + public object SelectedObject { + get { + return PropertyGrid.SelectedObject; + } + set { + PropertyGrid.SelectedObject = value; + } + } + + public Property() { + InitializeComponent(); + m_form_objectlist = new FormObjectList(); + m_form_objectlist.FormClosing += new FormClosingEventHandler( m_form_objectlist_FormClosing ); + m_instance = this; + } + + void m_form_objectlist_FormClosing( object sender, FormClosingEventArgs e ) { + listView.Parent = panelListView; + listView.Dock = DockStyle.Fill; + sContainer.SplitterDistance = m_last_splitter_distance; + sContainer.IsSplitterFixed = false; + } + + private void PropertyGrid_Click( object sender, EventArgs e ) { + this.sContainer.Panel2.Focus(); + } + + private void splitContainer1_Panel2_Enter( object sender, EventArgs e ) { + this.titleLower.BackColor = SystemColors.ActiveCaption; + this.titleLower.ForeColor = SystemColors.ActiveCaptionText; + } + + private void splitContainer1_Panel2_Leave( object sender, EventArgs e ) { + this.titleLower.BackColor = SystemColors.InactiveCaption; + this.titleLower.ForeColor = SystemColors.InactiveCaptionText; + } + + private void splitContainer1_Panel1_Leave( object sender, EventArgs e ) { + this.titleUpper.BackColor = SystemColors.InactiveCaption; + this.titleUpper.ForeColor = SystemColors.InactiveCaptionText; + } + + private void splitContainer1_Panel1_Enter( object sender, EventArgs e ) { + this.titleUpper.BackColor = SystemColors.ActiveCaption; + this.titleUpper.ForeColor = SystemColors.ActiveCaptionText; + } + + private void titleUpper_MouseDown( object sender, MouseEventArgs e ) { + this.sContainer.Panel1.Focus(); + } + + private void titleLower_MouseDown( object sender, MouseEventArgs e ) { + this.sContainer.Panel2.Focus(); + } + + private void ListView_Enter( object sender, EventArgs e ) { + this.titleUpper.BackColor = SystemColors.ActiveCaption; + this.titleUpper.ForeColor = SystemColors.ActiveCaptionText; + } + + private void PropertyGrid_PropertyValueChanged( object s, PropertyValueChangedEventArgs e ) { + if ( this.PropertyValueChanged != null ) { + this.PropertyValueChanged( s, e ); + } + if ( ListUpdateRequired != null ) { + ListUpdateRequired(); + } + } + + private void menuAddTelop_Click( object sender, EventArgs e ) { + if ( this.TelopAdding != null ) { + this.TelopAdding(); + } + if ( ListUpdateRequired != null ) { + ListUpdateRequired(); + } + } + + private void menuDeleteTelop_Click( object sender, EventArgs e ) { + if ( this.SelectedIndex < 0 ) { + return; + } + if ( this.TelopDeleting != null ) { + this.TelopDeleting( this.SelectedItem ); + } + if ( ListUpdateRequired != null ) { + ListUpdateRequired(); + } + } + + public ZorderItem Selected { + get { + return m_editing; + } + } + + void listView_SelectedIndexChanged( object sender, EventArgs e ) { + if ( listView.SelectedItems.Count > 0 && this.EditingItemChanged != null ) { + ZorderItem zi = (ZorderItem)listView.SelectedItems[0].Tag; + Editing = zi; + } + } + + private void TreeView_MouseDown( object sender, MouseEventArgs e ) { + if ( this.PropertyValueChanged != null ) { + this.PropertyValueChanged( sender, null ); + } + } + + private void titleUpper_DoubleClick( object sender, EventArgs e ) { + m_form_objectlist.Show( listView ); + m_last_splitter_distance = sContainer.SplitterDistance; + sContainer.SplitterDistance = 0; + sContainer.IsSplitterFixed = true; + } + + private void listView_ColumnClick( object sender, ColumnClickEventArgs e ) { + int column = e.Column; + if ( m_sort_order[0] == column ) { + m_sort_ascend[column] = !m_sort_ascend[column]; + List coll = new List(); + for ( int i = listView.Items.Count - 1; i >= 0; i-- ) { + coll.Add( listView.Items[i] ); + } + listView.Items.Clear(); + listView.Items.AddRange( coll.ToArray() ); + this.Sort(); + } else { + List list = new List(); + for ( int i = 0; i < 3; i++ ) { + if ( m_sort_order[i] != column ) { + list.Add( m_sort_order[i] ); + } + } + m_sort_order[0] = column; + m_sort_order[1] = list[0]; + m_sort_order[2] = list[1]; + this.Sort(); + } + } + + private void Property_FontChanged( object sender, EventArgs e ) { + cmenu.Font = this.Font; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/QuantizeMode.cs b/trunk/LipSync/LipSync/Editor/QuantizeMode.cs new file mode 100644 index 0000000..1e143f8 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/QuantizeMode.cs @@ -0,0 +1,28 @@ +/* + * QuantizeMode.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + /// + /// 音符の量子化設定 + /// + public enum QuantizeMode { + q04, + q08, + q16, + q32, + q64, + off + } + +} diff --git a/trunk/LipSync/LipSync/Editor/RipSync/RsiImporter.cs b/trunk/LipSync/LipSync/Editor/RipSync/RsiImporter.cs new file mode 100644 index 0000000..095bf0d --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/RipSync/RsiImporter.cs @@ -0,0 +1,28 @@ +/* + * RsiImporter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace LipSync { + + public class CharacterEx{ + public Character3 character; + public List exclusion; + public CharacterEx(){ + character = new Character3(); + exclusion = new List(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/RipSync/RsiReader.cs b/trunk/LipSync/LipSync/Editor/RipSync/RsiReader.cs new file mode 100644 index 0000000..e70b293 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/RipSync/RsiReader.cs @@ -0,0 +1,162 @@ +/* + * RsiReader.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Web; +using System.Xml; + +namespace LipSync { + + /// + /// RipSyncのキャラクタ設定ファイル*.rsiを読込むためのクラス + /// + public class RsiReader { + public static CharacterEx Read( string filepath ) { + CharacterEx result = new CharacterEx(); + filepath = HttpUtility.UrlDecode( filepath ); + XmlDocument doc = new XmlDocument(); + doc.Load( filepath ); + string base_path = Path.GetDirectoryName( filepath ); + List exclusion = new List(); + + foreach ( XmlNode level0 in doc.DocumentElement.ChildNodes ) { + switch ( level0.LocalName ) { + case "Title": + result.character.Name = level0.InnerText; + break; + case "Size": + string t_string = level0.InnerText; + string[] spl = t_string.Split( ",".ToCharArray() ); + int width = int.Parse( spl[0] ); + int height = int.Parse( spl[1] ); + result.character.Size = new Size( width, height ); + break; + case "Triggers": + // 排他設定だけ読み取る + foreach ( XmlNode level1 in level0.ChildNodes ) { + if ( level1.LocalName == "Selection" ) { + foreach ( XmlNode level2 in level1.ChildNodes ) { + if ( level2.LocalName == "Item" ) { + foreach ( XmlAttribute attr in level2.Attributes ) { + if ( attr.LocalName == "Trigger" ) { + result.exclusion.Add( attr.InnerText ); + } + } + } + } + } + } + break; + } + } + + foreach ( XmlNode level0 in doc.DocumentElement.ChildNodes ) { + if ( level0.LocalName == "Images" ) { + foreach ( XmlNode level1 in level0.ChildNodes ) { + switch ( level1.LocalName ) { + case "Image": + string image_path = ""; + string name = ""; + string trigger = ""; + Point center = new Point( 0, 0 ); + foreach ( XmlAttribute attr in level1.Attributes ) { + switch ( attr.LocalName ) { + case "name": + name = attr.InnerText; + break; + case "path": + image_path = Path.Combine( base_path, attr.InnerText ); + break; + case "trigger": + trigger = attr.InnerText; + break; + case "center": + string tmp = attr.InnerText; + tmp = tmp.Replace( " ", "" ); + tmp = tmp.Trim(); + string[] spl = tmp.Split( ",".ToCharArray() ); + center = new Point( -int.Parse( spl[0] ), -int.Parse( spl[1] ) ); + break; + } + } + Image img = null; + if ( File.Exists( image_path ) ) { + img = Common.ImageFromFile( image_path ); + } + bool found = false; +#if DEBUG + Common.DebugWriteLine( "RsiReader.Read(String); name=" + name ); + Common.DebugWriteLine( "RsiReader.Read(String); center=" + center ); +#endif + for ( int i = 0; i < result.character.Count; i++ ) { + if ( result.character[i].title == name ) { + found = true; + if ( img != null ) { + if ( center.X == 0 && center.Y == 0 ) { + result.character.SetImage( img, name ); + } else { + int width = result.character.Size.Width; + int height = result.character.Size.Height; + using ( Bitmap bmp = new Bitmap( width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb ) ) + using ( Graphics g = Graphics.FromImage( bmp ) ) { + g.DrawImage( img, center.X, center.Y, img.Width, img.Height ); +#if DEBUG + string temp = @"C:\" + name + ".png"; + Common.DebugWriteLine( "temp=" + temp ); + bmp.Save( temp, System.Drawing.Imaging.ImageFormat.Png ); +#endif + result.character.SetImage( bmp, name ); + } + } + } else { + result.character.SetImage( null, name ); + } + } + } + if ( !found ) { + result.character.Add( new ImageEntry( name, null, "", false ) ); + if ( center.X == 0 && center.Y == 0 ) { + result.character.SetImage( img, name ); + } else { + int width = result.character.Size.Width; + int height = result.character.Size.Height; + using ( Bitmap bmp = new Bitmap( width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb ) ) + using ( Graphics g = Graphics.FromImage( bmp ) ) { + g.DrawImage( img, center.X, center.Y, img.Width, img.Height ); +#if DEBUG + string temp = @"C:\" + name + ".png"; + Common.DebugWriteLine( "temp=" + temp ); + bmp.Save( temp, System.Drawing.Imaging.ImageFormat.Png ); +#endif + result.character.SetImage( bmp, name ); + } + } + } + break; + } + + } + } + } +#if DEBUG + Common.DebugWriteLine( "RsiReader.Read(String); result.character.Size=" + result.character.Size ); +#endif + return result; + } + + } + +} diff --git a/trunk/LipSync/LipSync/Editor/RipSync/RsiWriter.cs b/trunk/LipSync/LipSync/Editor/RipSync/RsiWriter.cs new file mode 100644 index 0000000..7fa119c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/RipSync/RsiWriter.cs @@ -0,0 +1,530 @@ +/* + * RsiWriter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Windows.Forms; +using System.Xml; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public class RsiWriter { + #region Constant String + static readonly string[] mouth_set = new string[]{ + "a", + "aa", + "i", + "u", + "e", + "o", + "xo", + "nn" + }; + static readonly string[] mouth_set_ja = new string[]{ + "あ", + "ああ", + "い", + "う", + "え", + "お", + "ぉ", + "ん" + }; // mouth_setと同順で対応して無いとNG + static readonly string[] dict_text = new string[]{ + "あ,a", + "か,a", + "が,a", + "さ,a", + "ざ,a", + "た,a", + "だ,a", + "な,a", + "は,a", + "ば,a", + "ぱ,a", + "ま,a", + "や,a", + "ら,a", + "わ,a", + "い,i", + "き,i", + "ぎ,i", + "し,i", + "じ,i", + "ち,i", + "ぢ,i", + "に,i", + "ひ,i", + "び,i", + "ぴ,i", + "み,i", + "り,i", + "う,u", + "く,u", + "ぐ,u", + "す,u", + "ず,u", + "つ,u", + "づ,u", + "ぬ,u", + "ふ,u", + "ぶ,u", + "む,u", + "ゆ,u", + "る,u", + "え,e", + "け,e", + "げ,e", + "せ,e", + "ぜ,e", + "て,e", + "で,e", + "ね,e", + "へ,e", + "べ,e", + "め,e", + "れ,e", + "お,o", + "こ,o", + "ご,o", + "そ,o", + "ぞ,o", + "と,o", + "ど,o", + "の,o", + "ほ,o", + "ぼ,o", + "ぽ,o", + "も,o", + "よ,o", + "ろ,o", + "を,xo", + "ん,nn" + }; + static readonly string[] dict_symbol = new string[]{ + "a,a", + "i,i", + "M,u", + "e,e", + "o,o", + "k,xo", + "k',i", + "g,e", + "g',i", + "s,a", + "S,i", + "z,u", + "Z,i", + "dz,u", + "dZ,i", + "t,e", + "t',i", + "ts,u", + "tS,i", + "d,a", + "d',i", + "n,a", + "J,i", + "h,a", + @"h\,xo", + "C,i", + @"p\,u", + @"p\',i", + "b,o", + "b',i", + "p,o", + "p',i", + "m,a", + "m',i", + "j,u", + "4,aa", + "4',i", + "w,a", + @"N\,nn" + }; + #endregion + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + /// + /// a, aa, i, u, e, o, xo, nnを、あ・ああ・い・う・え・お・ぉ・んに変換します。それ以外は""を返す + /// + /// + /// + private static string Translate( string symbol ) { + for ( int i = 0; i < mouth_set.Length; i++ ) { + if ( mouth_set[i] == symbol ) { + return mouth_set_ja[i]; + } + } + return ""; + } + + + /// + /// 与えられたタイトルの画像が口パク用の基本画像セットの物かどうかを判定します + /// + /// + /// + private static bool IsImageNameForMouth( string name ) { + foreach ( string s in mouth_set ) { + if ( s == name ) { + return true; + } + } + return false; + } + + + public static void Write( Character3 character, string fpath ) { + string image_folder_name = Path.GetFileNameWithoutExtension( fpath ); + string image_folder = Path.Combine( Path.GetDirectoryName( fpath ), image_folder_name ); + if ( Directory.Exists( image_folder ) ) { + DialogResult res = MessageBox.Show( + _( "Image directory already exists. Would you like to overwrite them?" ), + _( "warning" ), + MessageBoxButtons.YesNoCancel, + MessageBoxIcon.Exclamation, + MessageBoxDefaultButton.Button2 ); + if ( res == DialogResult.No ) { + using ( OpenFileDialog dlg = new OpenFileDialog() ) { + dlg.FileName = Path.GetDirectoryName( fpath ); + if ( dlg.ShowDialog() == DialogResult.OK ) { + image_folder = dlg.FileName; + image_folder_name = Path.GetFileName( image_folder ); + } else { + return; + } + } + } else if ( res == DialogResult.Cancel ) { + return; + } + } else { + Directory.CreateDirectory( image_folder ); + } +#if DEBUG + Common.DebugWriteLine( "image_folder_name=" + image_folder_name ); + Common.DebugWriteLine( "image_folder=" + image_folder ); +#endif + XmlTextWriter doc = new XmlTextWriter( fpath, Encoding.UTF8 ); + doc.Formatting = Formatting.Indented; + doc.Indentation = 2; + doc.IndentChar = ' '; + + // タグが未指定な物のgroup名を決めておく + string group_name_for_empty = "Another"; + bool found = true; + int count = 0; + while ( found ) { + found = false; + foreach ( ImageEntry img in character ) { + if ( img.tag == group_name_for_empty ) { + found = true; + break; + } + } + if ( found ) { + count++; + group_name_for_empty = "Another" + count; + } + } + + doc.WriteStartElement( "SingerConfig" ); + { + doc.WriteElementString( "Title", character.Name ); + doc.WriteElementString( "Size", character.Size.Width + "," + character.Size.Height ); + doc.WriteElementString( "RootImageName", "root" ); + List sets = new List(); // root以下のsetのリスト + + #region "SingerConfig/Images" + doc.WriteStartElement( "Images" ); + { + // トリガー込み + foreach ( ImageEntry img in character ) { + if ( IsImageNameForMouth( img.title ) ) { + continue; + } + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "center", (-img.XOffset) + ", " + (-img.YOffset) ); + doc.WriteAttributeString( "name", img.title ); + doc.WriteAttributeString( "size", img.Image.Width + ", " + img.Image.Height ); + string img_fname = img.title + ".png"; + img.Image.Save( Path.Combine( image_folder, img_fname ), System.Drawing.Imaging.ImageFormat.Png ); + doc.WriteAttributeString( "path", image_folder_name + "/" + img_fname ); + doc.WriteAttributeString( "trigger", img.title ); + } + doc.WriteEndElement(); + } + // 基本口画像。トリガー指定の無い奴も出力しないといけない?(未確認 + foreach ( ImageEntry img in character ) { + if ( !IsImageNameForMouth( img.title ) ) { + continue; + } + + // 自動用 + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "center", (-img.XOffset) + ", " + (-img.YOffset) ); + doc.WriteAttributeString( "name", img.title ); + doc.WriteAttributeString( "size", img.Image.Width + ", " + img.Image.Height ); + string img_fname = img.title + ".png"; + img.Image.Save( Path.Combine( image_folder, img_fname ), System.Drawing.Imaging.ImageFormat.Png ); + doc.WriteAttributeString( "path", image_folder_name + "/" + "mouth_" + img_fname ); + } + doc.WriteEndElement(); + + // トリガー用 + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "center", (-img.XOffset) + ", " + (-img.YOffset) ); + doc.WriteAttributeString( "name", "mouth_" + img.title ); + doc.WriteAttributeString( "size", img.Image.Width + ", " + img.Image.Height ); + string img_fname = "mouth_" + img.title + ".png"; + img.Image.Save( Path.Combine( image_folder, img_fname ), System.Drawing.Imaging.ImageFormat.Png ); + doc.WriteAttributeString( "path", image_folder_name + "/" + img_fname ); + doc.WriteAttributeString( "trigger", Translate( img.title ) ); + } + doc.WriteEndElement(); + } + + // root/mouth_auto_set + doc.WriteStartElement( "Set" ); + { + doc.WriteAttributeString( "name", "mouth_auto_set" ); + doc.WriteAttributeString( "size", character.Size.Width + "," + character.Size.Height ); + doc.WriteAttributeString( "count", 1 + "" ); + doc.WriteAttributeString( "trigger", "mouth_auto" ); + + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "index", 0 + "" ); + doc.WriteAttributeString( "imageName", "mouth" ); + doc.WriteAttributeString( "offset", "0,0" ); + } + doc.WriteEndElement(); + sets.Add( "mouth_auto" ); + } + doc.WriteEndElement(); + + // root/{tag}_manual + List listed_tag = new List(); // 出力済みのタグのリスト + bool added = true; + while ( added ) { + added = false; + // 次に出力すべきタグを検索 + string next_tag = ""; + List print = new List(); + foreach ( ImageEntry img in character ) { + bool found2 = false; + foreach ( string s in listed_tag ) { + if ( s == img.tag ) { + found2 = true; + break; + } + } + if ( !found2 ) { + if ( img.tag == "" ) { + next_tag = group_name_for_empty; + } else { + next_tag = img.tag; + } + break; + } + } + + if ( next_tag != "" ) { + added = true; + if ( next_tag == group_name_for_empty ) { + listed_tag.Add( "" ); + } else { + listed_tag.Add( next_tag ); + } + foreach ( ImageEntry img in character ) { + if ( img.tag == next_tag ) { + print.Add( img.title ); + } + } + foreach ( string s in print ) { + // 本体画像が含まれてたらキャンセル + if ( s == "base" ) { + print.Clear(); + break; + } + } + if ( print.Count > 0 ) { + doc.WriteStartElement( "Set" ); + { + doc.WriteAttributeString( "name", next_tag + "_manual_set" ); + doc.WriteAttributeString( "trigger", next_tag + "_manual" ); + sets.Add( next_tag + "_manual" ); + doc.WriteAttributeString( "size", character.Size.Width + ", " + character.Size.Height ); + doc.WriteAttributeString( "count", print.Count + "" ); + for ( int i = 0; i < print.Count; i++ ) { + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "index", i + "" ); + if ( IsImageNameForMouth( print[i] ) ) { + doc.WriteAttributeString( "imageName", "mouth_" + print[i] ); + } else { + doc.WriteAttributeString( "imageName", print[i] ); + } + doc.WriteAttributeString( "offset", "0,0" ); + } + doc.WriteEndElement(); + } + } + doc.WriteEndElement(); + } + } else { + break; + } + } + + // root + doc.WriteStartElement( "Set" ); + { + doc.WriteAttributeString( "name", "root" ); + doc.WriteAttributeString( "size", character.Size.Width + ", " + character.Size.Height ); + doc.WriteAttributeString( "count", (1 + sets.Count) + "" ); + + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "index", 0 + "" ); + doc.WriteAttributeString( "imageName", "base" ); + doc.WriteAttributeString( "offset", "0,0" ); + } + doc.WriteEndElement(); + + for ( int i = 0; i < sets.Count; i++ ) { + doc.WriteStartElement( "Image" ); + { + doc.WriteAttributeString( "index", (i + 1) + "" ); + doc.WriteAttributeString( "imageName", sets[i] + "_set" ); + doc.WriteAttributeString( "offset", "0,0" ); + } + doc.WriteEndElement(); + } + + } + doc.WriteEndElement(); + } + doc.WriteEndElement(); + #endregion + + #region "SingerConfig/Triggers" + doc.WriteStartElement( "Triggers" ); + { + foreach ( string s in sets ) { + doc.WriteStartElement( "Trigger" ); + { + doc.WriteAttributeString( "group", s + "_control" ); + doc.WriteAttributeString( "name", s ); + if ( s == "mouth_auto" ) { + doc.WriteAttributeString( "default", "on" ); + } + } + doc.WriteEndElement(); + } + + foreach ( ImageEntry img in character ) { + if ( img.title == "base" ) { + continue; + } + doc.WriteStartElement( "Trigger" ); + { + if ( img.tag == "" ) { + doc.WriteAttributeString( "group", group_name_for_empty ); + } else { + doc.WriteAttributeString( "group", img.tag ); + } + if ( IsImageNameForMouth( img.title ) ) { + doc.WriteAttributeString( "name", Translate( img.title ) ); + } else { + doc.WriteAttributeString( "name", img.title ); + } + } + doc.WriteEndElement(); + } + + Dictionary dic = new Dictionary(); + foreach ( ImageEntry img in character ) { + if ( img.tag == "" || img.title == "base" ) { + continue; + } + if ( dic.ContainsKey( img.tag ) ) { + dic[img.tag] = dic[img.tag] + "\n" + img.title; + } else { + dic[img.tag] = img.title; + } + } + foreach ( string key in dic.Keys ) { + string items = dic[key]; + string[] spl = items.Split( "\n".ToCharArray() ); + doc.WriteStartElement( "Selection" ); + { + foreach ( string s in spl ) { + doc.WriteStartElement( "Item" ); + { + doc.WriteAttributeString( "Trigger", s ); + } + doc.WriteEndElement(); + } + } + doc.WriteEndElement(); + } + } + doc.WriteEndElement(); + #endregion + + #region "SingerConfig/Mouths" + doc.WriteStartElement( "Mouths" ); + { + doc.WriteStartElement( "Default" ); + { + doc.WriteAttributeString( "imageName", "nn" ); + } + doc.WriteEndElement(); + foreach ( string s in dict_text ) { + string[] spl = s.Split( ",".ToCharArray() ); + doc.WriteStartElement( "Attach" ); + { + doc.WriteAttributeString( "text", spl[0] ); + doc.WriteAttributeString( "imageName", spl[1] ); + } + doc.WriteEndElement(); + } + foreach ( string s in dict_symbol ) { + string[] spl = s.Split( ",".ToCharArray() ); + doc.WriteStartElement( "Attach" ); + { + doc.WriteAttributeString( "symbol", spl[0] ); + doc.WriteAttributeString( "imageName", spl[1] ); + } + doc.WriteEndElement(); + } + } + doc.WriteEndElement(); + #endregion + + } + doc.WriteEndElement(); + doc.Close(); + } + } +} diff --git a/trunk/LipSync/LipSync/Editor/RipSync/RspImporter.cs b/trunk/LipSync/LipSync/Editor/RipSync/RspImporter.cs new file mode 100644 index 0000000..53ac631 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/RipSync/RspImporter.cs @@ -0,0 +1,692 @@ +/* + * RspImporter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Web; +using System.Xml; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + class RspTriggerEvent : IComparable{ + public float time; + public string triggerName; + public RspTriggerStatus status; + public RspTriggerEvent( float time, string triggerName, string status ){ + this.time = time; + this.triggerName = triggerName.Trim(); + if( status.Trim() == "ON" ){ + this.status = RspTriggerStatus.ON; + }else{ + this.status = RspTriggerStatus.OFF; + } + } + public int CompareTo( object obj ) { + RspTriggerEvent item = (RspTriggerEvent)obj; + if ( this.time > item.time ) { + return 1; + } else if ( this.time < item.time ) { + return -1; + } else { + if ( this.status == RspTriggerStatus.OFF && item.status == RspTriggerStatus.ON ) { + return -1; + } else if ( this.status == RspTriggerStatus.ON && item.status == RspTriggerStatus.OFF ) { + return 1; + } + return 0; + } + } + new public string ToString() { + return time.ToString() + "," + triggerName + "," + status.ToString(); + } + } + + enum RspTriggerStatus{ + ON, + OFF, + } + + public class RspImporter { + + private static XmlDocument doc; + + private static TimeTableGroup group_vsq; + private static List groups_character; + private static TimeTableGroup group_another; + private static List telop = new List(); + private static float optional_length; + private static int width; + private static int height; + private static int back_color; + private static string sound_file; + + public static string gettext( string s ) { + return Messaging.GetMessage( s ); + } + + + public static string _( string s ) { + return gettext( s ); + } + + + public static bool Import( string filepath, ref SettingsEx save ) { + string rsp_path = Path.GetDirectoryName( filepath ); + + doc = new XmlDocument(); + doc.Load( filepath ); + + group_vsq = new TimeTableGroup( _( "VSQ Tracks" ), 0, null ); + groups_character = new List(); + group_another = new TimeTableGroup( _( "Another images" ), 0, null ); + + // 最初にtotal_lengthを取得 + foreach( XmlNode level1 in doc.DocumentElement.ChildNodes ){ + if( level1.LocalName == "View" ){ + optional_length = -1f; + foreach ( XmlNode level2 in level1.ChildNodes ) { + if ( level2.LocalName == "OptionalLength" ) { + optional_length = float.Parse( level2.InnerText ); + break; + } + } + break; + } + } + + foreach ( XmlNode level1 in doc.DocumentElement.ChildNodes ) { + switch ( level1.LocalName ) { + case "Canvas": + #region Canvas + width = 100; + height = 100; + back_color = -1; + foreach ( XmlNode level2 in level1.ChildNodes ) { + switch ( level2.LocalName ) { + case "Width": + width = int.Parse( level2.InnerText ); + break; + + case "Height": + height = int.Parse( level2.InnerText ); + break; + + case "BackColor": + back_color = int.Parse( level2.InnerText ); + break; + } + } + #endregion + break; + case "Sound": + #region Sound + sound_file = ""; + foreach ( XmlNode level2 in level1.ChildNodes ) { + switch ( level2.LocalName ) { + case "FileName": + sound_file = level2.InnerText; + break; + } + } + #endregion + break; + case "TimeTable": + #region TimeTable + foreach ( XmlNode level2 in level1.ChildNodes ) { + if ( level2.LocalName == "Table" ) { + group_vsq.Add( new TimeTable( "", 0, TimeTableType.vsq, null ) ); + int index = group_vsq.Count - 1; + foreach ( XmlNode level3 in level2.ChildNodes ) { + switch ( level3.LocalName ) { + case "Name": + group_vsq[index].Text = level3.InnerText; + break; + case "Unit": + float start = 0f; + float end = 0f; + string lyric = ""; + string symbol = ""; + foreach ( XmlNode level4 in level3.ChildNodes ) { + switch ( level4.LocalName ) { + case "Start": + start = float.Parse( level4.InnerText ); + break; + case "End": + end = float.Parse( level4.InnerText ); + break; + case "Text": + lyric = level4.InnerText; + break; + case "Symbol": + symbol = level4.InnerText; + break; + } + } + group_vsq[index].Add( new TimeTableEntry( start, end, lyric + "(" + symbol + ")" ) ); + break; + } + } + } + } + #endregion + break; + case "DrawObject": + #region DrawObject + foreach ( XmlNode level2 in level1.ChildNodes ) { + if ( level2.LocalName == "Object" ) { + // まずtypeを調べる + string type_name = ""; + foreach ( XmlNode level3 in level2.ChildNodes ) { + if ( level3.LocalName == "TypeName" ) { + type_name = level3.InnerText; + break; + } + } + + // typeで動作を切り替え + switch ( type_name ) { + case "RipSync.Plugins.Extensions.RipSyncImage.RipSyncImage": + #region RipSync.Plugins.Extensions.RipSyncImage.RipSyncImage + string source_table = ""; + CharacterEx cex = new CharacterEx(); + List events = new List(); + groups_character.Add( new TimeTableGroup( "", 0, null ) ); + int index = groups_character.Count - 1; + foreach ( XmlNode level3 in level2.ChildNodes ) { + switch( level3.LocalName ){ + case "Name": + groups_character[index].Text = level3.InnerText; + break; + case "Parameter": + //MessageBox.Show( "Parameter node" ); + foreach( XmlNode level4 in level3.ChildNodes ){ + switch( level4.LocalName ){ + case "FileName": + string rsi_path = Path.Combine( rsp_path, level4.InnerText ); + cex = RsiReader.Read( rsi_path ); + groups_character[index].Character = cex.character; + break; + case "Table": + source_table = level4.InnerText; + break; + case "Triggers": + foreach( XmlNode level5 in level4.ChildNodes ){ + if ( level5.LocalName == "TriggerEvent" ) { + float time = 0f; + string trigger_name = ""; + string status = ""; + foreach ( XmlNode level6 in level5.ChildNodes ) { + switch ( level6.LocalName ) { + case "Time": + time = float.Parse( level6.InnerText ); + break; + case "TriggerName": + trigger_name = level6.InnerText; + break; + case "Status": + status = level6.InnerText; + break; + } + } + events.Add( new RspTriggerEvent( time, trigger_name, status ) ); + } + } + break; + } + } + break; + } + } + // source_tableから、口パクを作成 + // group_vsqから、タイトルがsource_tableで或るやつを検索 + int source = -1; + for ( int i = 0; i < group_vsq.Count; i++ ) { + if ( group_vsq[i].Text == source_table ) { + source = i; + break; + } + } + if ( source >= 0 ) { + // 口パク用のタイムテーブルが指定されていた場合 + TimeTableGroup temp = (TimeTableGroup)groups_character[index].Clone(); + TimeTableGroup.GenerateLipSyncFromVsq( + group_vsq[source], + ref temp, + groups_character[index].Character, + optional_length, + true, + save.FrameRate, + 0f ); //todo: ここのoptional_lengthが怪しい + groups_character[index] = temp; + } else { + //口パク用タイムテーブルが指定されていなかった場合 + // 画像分だけトラックを用意 + /*groups_character[index].Add( new TimeTable( "base", 0, TimeTableType.eye, cex.character.Base ) ); + groups_character[index].Add( new TimeTable( "a", 0, TimeTableType.mouth, cex.character.a ) ); + groups_character[index].Add( new TimeTable( "aa", 0, TimeTableType.mouth, cex.character.aa ) ); + groups_character[index].Add( new TimeTable( "i", 0, TimeTableType.mouth, cex.character.i ) ); + groups_character[index].Add( new TimeTable( "u", 0, TimeTableType.mouth, cex.character.u ) ); + groups_character[index].Add( new TimeTable( "e", 0, TimeTableType.mouth, cex.character.e ) ); + groups_character[index].Add( new TimeTable( "o", 0, TimeTableType.mouth, cex.character.o ) ); + groups_character[index].Add( new TimeTable( "xo", 0, TimeTableType.mouth, cex.character.xo ) ); + groups_character[index].Add( new TimeTable( "nn", 0, TimeTableType.mouth, cex.character.nn ) );*/ + for ( int k = 0; k < groups_character[index].Character.Count; k++ ) { + groups_character[index].Add( new TimeTable( groups_character[index].Character[k].title, 0, TimeTableType.character, null ) ); + } + } + + // triggerから、表情を追加。 + // まず、排他も考慮して、OFFのイベントを追加 + events.Sort(); + //MessageBox.Show( "events.Cocunt=" + events.Count ); + #region 排他を考慮して、OFFイベントを追加 + int ii = -1; + while( (ii + 1) < events.Count ){ + ii++; + //for ( int i = 0; i < events.Count; i++ ) { + string trigger_name = events[ii].triggerName; + //MessageBox.Show( "trigger_name=" + trigger_name ); + float begin = events[ii].time; + float end = begin - 10f; // begin > endであれば-10じゃなくてもいい + // 排他に該当して無いかどうか検査 + bool exclusion = isExclusionTrigger( cex, trigger_name ); + bool defined = false; // 排他制御で、OFF位置が定義できたか否か + if ( exclusion ) { + // 排他制御をする必要がある場合 + // 他の排他要素の中で、beginより後にONしていて、かつそれがもっとも早いものを検索 + float first_begin = end; + //bool int_exclusion = false; + for ( int j = ii + 1; j < events.Count; j++ ) { + if ( isExclusionTrigger( cex, events[j].triggerName ) ) { + defined = true; + end = events[j].time; + break; + } + } + } + //MessageBox.Show( "defined=" + defined ); + if ( !defined ) { + // この後で同じトリガが再びON指定になってたり、作為的にOFFにされて無いかどうかを検査 + for ( int j = ii + 1; j < events.Count; j++ ) { + if ( events[j].triggerName == trigger_name ) { + end = events[j].time; + defined = true; + break; + } + } + } + if ( defined ) { + events.Add( new RspTriggerEvent( end, trigger_name, "OFF" ) ); + events.Sort(); + ii++; //++しないと∞ループだな + } + } + #endregion + + for ( int i = 0; i < events.Count; i++ ) { + float begin, end; + if ( events[i].status == RspTriggerStatus.ON ){ + // まず、開始と終了の時刻を設定 + begin = events[i].time; + end = -1f; + if ( i + 1 < events.Count ) { + if ( events[i + 1].triggerName == events[i].triggerName && events[i + 1].status == RspTriggerStatus.OFF ) { + end = events[i + 1].time; + } + } + + // どのタイムラインに追加するのかを決定 + string trigger = events[i].triggerName; + int target = -1; + for ( int j = 0; j < groups_character[index].Count; j++ ) { + if ( groups_character[index][j].Text == trigger ) { + target = j; + break; + } + } + + // 追加を実行 + if ( target >= 0 ) { + groups_character[index][target].Add( new TimeTableEntry( begin, end, trigger ) ); + } + } + } + + #endregion + break; + case "RipSync.Plugins.Extensions.SimpleImage.SimpleImage": + #region RipSync.Plugins.Extensions.SimpleImage.SimpleImage + string image_file = ""; + string name = ""; + foreach ( XmlNode level3 in level2.ChildNodes ) { + switch ( level3.LocalName ) { + case "Parameter": + foreach ( XmlNode level4 in level3.ChildNodes ) { + if ( level4.LocalName == "FileName" ) { + image_file = level3.InnerText; + break; + } + } + break; + case "Name": + name = level3.InnerText; + break; + } + } + + image_file = HttpUtility.UrlDecode( image_file ); + string file = Path.Combine( rsp_path, image_file ); + if ( File.Exists( file ) ) { + Bitmap img = new Bitmap( Common.ImageFromFile( file ) ); + group_another.Add( new TimeTable( name, 0, TimeTableType.another, img ) ); + } else { + group_another.Add( new TimeTable( name, 0, TimeTableType.another, null ) ); + } + + #endregion + break; + case "RipSync.Plugins.Extensions.TextObject.TextObject": + #region RipSync.Plugins.Extensions.TextObject.TextObject + string tname = ""; + string text = ""; + Color color = Color.Black; + Font font = new Font( "MS UI Gothc", 10 ); + foreach ( XmlNode level3 in level2.ChildNodes ) { + switch ( level3.LocalName ) { + case "Name": + tname = level3.InnerText; + break; + case "Parameter": + foreach ( XmlNode level4 in level3.ChildNodes ) { + switch ( level4.LocalName ) { + case "Text": + text = level4.InnerText; + break; + case "Color": + int col = int.Parse( level4.InnerText ); + color = Color.FromArgb( col ); + break; + case "Font": + string font_name = level4.InnerText; + //Microsoft Sans Serif, 12pt, style=Bold + string[] spl = font_name.Split( new string[] { ", " }, StringSplitOptions.RemoveEmptyEntries ); + string font_family = spl[0]; + string font_size = spl[1]; + font_size = font_size.Replace( "pt", "" ); + int em_size = int.Parse( font_size ); + string font_style = ""; + //style=Bold, Italic, Underline, Strikeout + FontStyle t_font_style = FontStyle.Regular; + if ( spl.Length >= 3 ) { + //spl[2]のみ、Style=がついてるのでそれをはずす + string[] spl2 = spl[2].Split( new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries ); + font_style = spl2[1]; + } + for ( int ic = 3; ic < spl.Length; ic++ ) { + font_style += "," + spl[ic]; + } + spl = font_style.Split( new string[] { "," }, StringSplitOptions.RemoveEmptyEntries ); + foreach ( string style_name in spl ) { + switch ( style_name ) { + case "Bold": + t_font_style = t_font_style | FontStyle.Bold; + break; + case "Italic": + t_font_style = t_font_style | FontStyle.Italic; + break; + case "Underline": + t_font_style = t_font_style | FontStyle.Underline; + break; + case "Strikeout": + t_font_style = t_font_style | FontStyle.Strikeout; + break; + } + } + font = new Font( font_family, em_size, t_font_style ); + break; + } + } + break; + } + } + Telop temp_telop = new Telop( save.GetNextID() ); + temp_telop.Text = text; + temp_telop.Color = color; + temp_telop.Font = font; + temp_telop.Tag = tname; + telop.Add( temp_telop ); + #endregion + break; + } + } + } + #endregion + break; + case "TimeLine": + #region TimeLine + foreach ( XmlNode level2 in level1.ChildNodes ) { + if ( level2.LocalName == "Unit" ) { + int zindex = 0; + float start = 0f; + float end = -10f; + int position_x = 0; + int position_y = 0; + float scale = 1f; + string draw_object = ""; + bool fadein = false; + bool fadeout = false; + foreach ( XmlNode level3 in level2.ChildNodes ) { + switch ( level3.LocalName ) { + case "ZIndex": + zindex = int.Parse( level3.InnerText ); + break; + case "Start": + start = float.Parse( level3.InnerText ); + break; + case "End": + end = float.Parse( level3.InnerText ); + break; + case "PositionX": + position_x = int.Parse( level3.InnerText ); + break; + case "PositionY": + position_y = int.Parse( level3.InnerText ); + break; + case "Scale": + scale = float.Parse( level3.InnerText ); + break; + case "DrawObject": + draw_object = level3.InnerText; + break; + case "FadeIn": + if( level3.InnerText == "True" ){ + fadein = true; + } + break; + case "FadeOut": + if( level3.InnerText == "True" ){ + fadeout = true; + } + break; + } + } + + // 名前がdraw_objectであるトラック(orキャラクタ)を検索 + // group_another + for ( int i = 0; i < group_another.Count; i++ ) { + if ( draw_object == group_another[i].Text ) { + group_another[i].ZOrder = zindex; + group_another[i].Clear(); + group_another[i].Add( new TimeTableEntry( start, end, draw_object ) ); + group_another[i].Position = new Point( position_x, position_y ); + group_another[i].Scale = scale; + } + } + + // group_character + for ( int i = 0; i < groups_character.Count; i++ ) { + if ( draw_object == groups_character[i].Text ) { + groups_character[i].ZOrder = zindex; + groups_character[i].Position = new Point( position_x, position_y ); + } + } + + // telop + for ( int i = 0; i < telop.Count; i++ ) { + if ( draw_object == (string)telop[i].Tag ) { + telop[i].Start = start; + telop[i].End = end; + telop[i].FadeIn = fadein; + telop[i].FadeOut = fadeout; + telop[i].Position = new Point( position_x, position_y ); + if ( scale != 1 ) { + Font tnew = new Font( telop[i].Font.FontFamily, telop[i].Font.SizeInPoints * scale, telop[i].Font.Style ); + telop[i].Font.Dispose(); + telop[i].Font = null; + telop[i].Font = tnew; + } + } + } + } + } + #endregion + break; + } + } + //MessageBox.Show( "tables=" + group_vsq.Count ); + if ( optional_length < 0 ) { + float thismax = -1; + for ( int track = 0; track < group_vsq.Count; track++ ) { + int last = group_vsq[track].Count - 1; + if ( last >= 0 ) { + thismax = group_vsq[track][last].end; + optional_length = Math.Max( optional_length, thismax ); + } + } + + for ( int group = 0; group < groups_character.Count; group++ ) { + for ( int track = 0; track < groups_character[group].Count; track++ ) { + int last = groups_character[group][track].Count - 1; + if ( last >= 0 ) { + thismax = groups_character[group][track][last].end; + optional_length = Math.Max( optional_length, thismax ); + } + } + } + } + + // 時間が負になってる表情用エントリを整理 + for ( int group = 0; group < groups_character.Count; group++ ) { + for ( int track = 0; track < groups_character[group].Count; track++ ) { + for( int entry = 0; entry < groups_character[group][track].Count; entry++ ){ + if ( groups_character[group][track][entry].end < 0 ) { + groups_character[group][track][entry].end = optional_length; + } + } + } + } + // 時間が負になっているその他のイメージのエントリを整理 + for ( int track = 0; track < group_another.Count; track++ ) { + for ( int entry = 0; entry < group_another[track].Count; entry++ ) { + if ( group_another[track][entry].end < 0f ) { + group_another[track][entry].end = optional_length; + } + } + } + // 時間が負になっているテロップのエントリを整理 + for ( int i = 0; i < telop.Count; i++ ) { + if ( telop[i].End < 0f ) { + telop[i].End = optional_length; + } + } + + // base画像エントリの修正。genMouthFromVsqCore実行時にはoptional_length == 0なので、修正。 + for ( int group = 0; group < groups_character.Count; group++ ) { + int index_base = -1; + for ( int track = 0; track < groups_character[group].Count; track++ ) { + if ( groups_character[group][track].Text == "base" ) { + index_base = track; + break; + } + } + if ( index_base >= 0 ) { + groups_character[group][index_base].Clear(); + groups_character[group][index_base].Add( new TimeTableEntry( 0.0f, optional_length, "base" ) ); + } + } + + // zorderの数値がrip syncでは逆なので修正 + // まずzorderの最大値を探す + int zmax = -100; + for ( int i = 0; i < group_another.Count; i++ ) { + zmax = Math.Max( zmax, group_another[i].ZOrder ); + } + for ( int i = 0; i < groups_character.Count; i++ ) { + zmax = Math.Max( zmax, groups_character[i].ZOrder ); + } + // 修正 + for ( int i = 0; i < group_another.Count; i++ ) { + group_another[i].ZOrder = zmax - group_another[i].ZOrder; + } + for ( int i = 0; i < groups_character.Count; i++ ) { + groups_character[i].ZOrder = zmax - groups_character[i].ZOrder; + } + + if ( optional_length > 0 ) { + save.m_totalSec = optional_length; + } else { + save.m_totalSec = 0; + } + save.m_group_vsq = (TimeTableGroup)group_vsq.Clone(); + save.m_groups_character.Clear(); + for ( int i = 0; i < groups_character.Count; i++ ) { + save.m_groups_character.Add( groups_character[i] ); + } + save.m_group_another = (TimeTableGroup)group_another.Clone(); + save.m_movieSize = new Size( width, height ); + save.m_telop_ex2.Clear(); + save.m_telop_ex2 = new List(); + for ( int i = 0; i < telop.Count; i++ ) { + save.m_telop_ex2.Add( telop[i] ); + } + save.UpdateZorder(); + save.m_audioFile = sound_file; + //s.InvertZOrder(); + return true; + } + + + /// + /// 指定された名前のトリガーが、排他指定されているか否かを判定します + /// + /// 判定に使用されるCharacterEx + /// 検査するトリガーの名前 + /// + private static bool isExclusionTrigger( CharacterEx cex, string name ) { + for ( int i = 0; i < cex.exclusion.Count; i++ ) { + if ( cex.exclusion[i] == name ) { + return true; + } + } + return false; + } + + } + + + +} diff --git a/trunk/LipSync/LipSync/Editor/ScoreUnit.cs b/trunk/LipSync/LipSync/Editor/ScoreUnit.cs new file mode 100644 index 0000000..11451a6 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ScoreUnit.cs @@ -0,0 +1,52 @@ +/* + * ScoreUnit.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +using Boare.Lib.Vsq; + +namespace LipSync { + + /// + /// 楽譜の一部分を取り扱います。ただし単一の拍子で表現できる部分のみ + /// + [Serializable, Obsolete] + public class ScoreUnit { + /// + /// このインスタンスが表す楽譜の、曲頭からの時刻を表します + /// + public float Start; + /// + /// 拍子の分子 + /// + public int Numerator; + /// + /// 拍子の分母 + /// + public int Denominator; + /// + /// テンポの変更情報を格納したリスト + /// + public List TempoList; + + public ScoreUnit() { + Start = 0f; + Numerator = 4; + Denominator = 4; + TempoList = new List(); + TempoList.Add( new TempoTableEntry( 0, 480000, 0.0 ) ); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/SelectCharacter.cs b/trunk/LipSync/LipSync/Editor/SelectCharacter.cs new file mode 100644 index 0000000..55a0be1 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/SelectCharacter.cs @@ -0,0 +1,132 @@ +/* + * SelectCharacter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class SelectCharacater : Form, IMultiLanguageControl { + Character3 m_character; + string m_path; + + public SelectCharacater( List plugins ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + m_character = Character3.Miku; + comboBox1.Items.Clear(); + for ( int i = 0; i < plugins.Count; i++ ) { + comboBox1.Items.Add( plugins[i] ); + } + if ( comboBox1.Items.Count == 0 ) { + radioPlugin.Enabled = false; + } + chkImport.Checked = !AppManager.Config.SaveCharacterConfigOutside; + chkImport.Enabled = false; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.radioPlugin.Text = _( "Plugin" ); + this.radioCustom.Text = _( "Custom" ); + this.radioBuiltIn.Text = _( "Built-in" ) + " (Miku)"; + this.label1.Text = _( "Select character to generate lip-sync" ); + this.btnOK.Text = _( "OK" ); + this.btnCancel.Text = _( "Cancel" ); + this.radioRin.Text = _( "Built-in" ) + " (Rin)"; + this.radioLen.Text = _( "Built-in" ) + " (Len)"; + this.Text = _( "Character selection" ); + } + + private static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public string Path { + get { + return m_path; + } + } + + public Character3 Character { + get { + return m_character; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + if ( radioBuiltIn.Checked ) { + chkImport.Checked = false; + this.DialogResult = DialogResult.OK; + this.Close(); + } else if ( radioRin.Checked ) { + chkImport.Checked = false; + m_character = Character3.Rin; + this.DialogResult = DialogResult.OK; + this.Close(); + } else if ( radioLen.Checked ) { + chkImport.Checked = false; + m_character = Character3.Len; + this.DialogResult = DialogResult.OK; + this.Close(); + } else if ( radioCustom.Checked ) { + GenerateCharacter gc = new GenerateCharacter( new Character3() ); + gc.LastPath = AppManager.Config.LastCharacterPath; + if ( gc.ShowDialog() == DialogResult.OK ) { + //Form1.Instatnce.Config.LAST_CHARACTER_PATH = gc.LastPath; + m_character = gc.EditedResult.Character; + m_path = gc.LastPath; + this.DialogResult = DialogResult.OK; + this.Close(); + } + gc.Dispose(); + } else { + string id = (string)comboBox1.SelectedItem; + int index = -1; + for ( int i = 0; i < AppManager.SaveData.m_plugins_config.Count; i++ ) { + if ( id == AppManager.SaveData.m_plugins_config[i].ID ) { + index = i; + break; + } + } + if ( index >= 0 ) { + m_character = new Character3( AppManager.SaveData.m_plugins_config[index] ); + this.DialogResult = DialogResult.OK; + } else { + this.DialogResult = DialogResult.Cancel; + } + this.Close(); + } + } + + private void radioPlugin_CheckedChanged( object sender, EventArgs e ) { + comboBox1.Enabled = radioPlugin.Checked; + } + + private void radioCustom_CheckedChanged( object sender, EventArgs e ) { + chkImport.Enabled = radioCustom.Checked; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/SelectCharacter.designer.cs b/trunk/LipSync/LipSync/Editor/SelectCharacter.designer.cs new file mode 100644 index 0000000..f03f79c --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/SelectCharacter.designer.cs @@ -0,0 +1,219 @@ +/* + * SelectCharacter.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class SelectCharacater { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.panel1 = new System.Windows.Forms.Panel(); + this.radioLen = new System.Windows.Forms.RadioButton(); + this.radioRin = new System.Windows.Forms.RadioButton(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.radioPlugin = new System.Windows.Forms.RadioButton(); + this.radioCustom = new System.Windows.Forms.RadioButton(); + this.radioBuiltIn = new System.Windows.Forms.RadioButton(); + this.label1 = new System.Windows.Forms.Label(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.chkImport = new System.Windows.Forms.CheckBox(); + this.panel1.SuspendLayout(); + this.SuspendLayout(); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.AutoSize = true; + this.panel1.Controls.Add( this.radioLen ); + this.panel1.Controls.Add( this.radioRin ); + this.panel1.Controls.Add( this.comboBox1 ); + this.panel1.Controls.Add( this.radioPlugin ); + this.panel1.Controls.Add( this.radioCustom ); + this.panel1.Controls.Add( this.radioBuiltIn ); + this.panel1.Location = new System.Drawing.Point( 12, 41 ); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size( 254, 140 ); + this.panel1.TabIndex = 0; + // + // radioLen + // + this.radioLen.AutoSize = true; + this.radioLen.Location = new System.Drawing.Point( 16, 56 ); + this.radioLen.Name = "radioLen"; + this.radioLen.Size = new System.Drawing.Size( 97, 16 ); + this.radioLen.TabIndex = 3; + this.radioLen.Text = "ビルトイン(Len)"; + this.radioLen.UseVisualStyleBackColor = true; + // + // radioRin + // + this.radioRin.AutoSize = true; + this.radioRin.Location = new System.Drawing.Point( 16, 34 ); + this.radioRin.Name = "radioRin"; + this.radioRin.Size = new System.Drawing.Size( 96, 16 ); + this.radioRin.TabIndex = 2; + this.radioRin.Text = "ビルトイン(Rin)"; + this.radioRin.UseVisualStyleBackColor = true; + // + // comboBox1 + // + this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.comboBox1.Enabled = false; + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point( 99, 109 ); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size( 141, 20 ); + this.comboBox1.TabIndex = 6; + // + // radioPlugin + // + this.radioPlugin.AutoSize = true; + this.radioPlugin.Location = new System.Drawing.Point( 16, 100 ); + this.radioPlugin.Name = "radioPlugin"; + this.radioPlugin.Size = new System.Drawing.Size( 67, 16 ); + this.radioPlugin.TabIndex = 5; + this.radioPlugin.Text = "プラグイン"; + this.radioPlugin.UseVisualStyleBackColor = true; + this.radioPlugin.CheckedChanged += new System.EventHandler( this.radioPlugin_CheckedChanged ); + // + // radioCustom + // + this.radioCustom.AutoSize = true; + this.radioCustom.Location = new System.Drawing.Point( 16, 78 ); + this.radioCustom.Name = "radioCustom"; + this.radioCustom.Size = new System.Drawing.Size( 59, 16 ); + this.radioCustom.TabIndex = 4; + this.radioCustom.Text = "カスタム"; + this.radioCustom.UseVisualStyleBackColor = true; + this.radioCustom.CheckedChanged += new System.EventHandler( this.radioCustom_CheckedChanged ); + // + // radioBuiltIn + // + this.radioBuiltIn.AutoSize = true; + this.radioBuiltIn.Checked = true; + this.radioBuiltIn.Location = new System.Drawing.Point( 16, 12 ); + this.radioBuiltIn.Name = "radioBuiltIn"; + this.radioBuiltIn.Size = new System.Drawing.Size( 103, 16 ); + this.radioBuiltIn.TabIndex = 1; + this.radioBuiltIn.TabStop = true; + this.radioBuiltIn.Text = "ビルトイン(Miku)"; + this.radioBuiltIn.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.AutoEllipsis = true; + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 10, 9 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 237, 12 ); + this.label1.TabIndex = 1; + this.label1.Text = "口パク生成に使用するキャラクタを選択してください"; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 99, 223 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 8; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 195, 223 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 9; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // chkImport + // + this.chkImport.AutoSize = true; + this.chkImport.Location = new System.Drawing.Point( 26, 195 ); + this.chkImport.Name = "chkImport"; + this.chkImport.Size = new System.Drawing.Size( 206, 16 ); + this.chkImport.TabIndex = 7; + this.chkImport.Text = "LSEファイルにキャラクタ設定を埋め込む"; + this.chkImport.UseVisualStyleBackColor = true; + this.chkImport.Visible = false; + // + // SelectCharacater + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 282, 262 ); + this.Controls.Add( this.chkImport ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.panel1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SelectCharacater"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "キャラクタの選択"; + this.panel1.ResumeLayout( false ); + this.panel1.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.RadioButton radioCustom; + private System.Windows.Forms.RadioButton radioBuiltIn; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.RadioButton radioPlugin; + private System.Windows.Forms.RadioButton radioLen; + private System.Windows.Forms.RadioButton radioRin; + private System.Windows.Forms.CheckBox chkImport; + + } +} diff --git a/trunk/LipSync/LipSync/Editor/SetSize.cs b/trunk/LipSync/LipSync/Editor/SetSize.cs new file mode 100644 index 0000000..d8bf04e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/SetSize.cs @@ -0,0 +1,133 @@ +/* + * SetSize.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Collections.Generic; +using System.Windows.Forms; +using System.Reflection; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class SetSize : Form, IMultiLanguageControl { + private T x; + private T y; + private MethodInfo m_parse_method_info = null; + + public SetSize( string dialog_title, string title_x, string title_y, T def_x, T def_y ) { + Assembly a = Assembly.GetAssembly( typeof( T ) ); + Type[] ts = a.GetTypes(); + bool found = false; + foreach ( Type t in ts ) { + if ( t.Equals( typeof( T ) ) ) { + MethodInfo[] mis = t.GetMethods(); + foreach ( MethodInfo mi in mis ) { + if ( mi.ReturnType.Equals( typeof( T ) ) && mi.Name == "Parse" && mi.IsStatic && mi.IsPublic ) { + ParameterInfo[] pis = mi.GetParameters(); + if ( pis.Length == 1 ) { + if ( pis[0].ParameterType.Equals( typeof( string ) ) ) { + m_parse_method_info = mi; + found = true; + break; + } + } + } + } + if ( found ) { + break; + } + } + } + if ( !found ) { + throw new NotSupportedException( "generic type T must support 'public static T Parse( string ){...}' method" ); + } + InitializeComponent(); + ApplyFont( AppManager.Config.Font.GetFont() ); + label1.Text = title_x; + label2.Text = title_y; + txtHeight.Text = def_y.ToString(); + txtWidth.Text = def_x.ToString(); + x = def_x; + y = def_y; + this.Text = dialog_title; + } + + public void ApplyLanguage() { + this.btnCancel.Text = _( "Cancel" ); + this.btnOK.Text = _( "OK" ); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public T ResultWidth { + get { + return x; + } + } + + public T ResultHeight { + get { + return y; + } + } + + public string Title { + get { + return this.Text; + } + set { + this.Text = value; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + T xx = x; + T yy = y; + try { + xx = (T)m_parse_method_info.Invoke( typeof( T ), new object[]{ txtWidth.Text } ); + yy = (T)m_parse_method_info.Invoke( typeof( T ), new object[]{ txtHeight.Text } ); + } catch { + MessageBox.Show( + _( "Invalid value has been entered" ), + _( "Error" ), + MessageBoxButtons.OK, + MessageBoxIcon.Exclamation ); + xx = x; + yy = y; + return; + } finally { + x = xx; + y = yy; + } + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnCancel_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/SetSize.designer.cs b/trunk/LipSync/LipSync/Editor/SetSize.designer.cs new file mode 100644 index 0000000..76a3735 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/SetSize.designer.cs @@ -0,0 +1,136 @@ +/* + * SetSize.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class SetSize { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.label1 = new System.Windows.Forms.Label(); + this.label2 = new System.Windows.Forms.Label(); + this.txtWidth = new System.Windows.Forms.TextBox(); + this.txtHeight = new System.Windows.Forms.TextBox(); + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 21, 19 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 17, 12 ); + this.label1.TabIndex = 0; + this.label1.Text = "幅"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point( 21, 48 ); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size( 25, 12 ); + this.label2.TabIndex = 1; + this.label2.Text = "高さ"; + // + // txtWidth + // + this.txtWidth.Location = new System.Drawing.Point( 67, 16 ); + this.txtWidth.Name = "txtWidth"; + this.txtWidth.Size = new System.Drawing.Size( 114, 19 ); + this.txtWidth.TabIndex = 2; + // + // txtHeight + // + this.txtHeight.Location = new System.Drawing.Point( 67, 45 ); + this.txtHeight.Name = "txtHeight"; + this.txtHeight.Size = new System.Drawing.Size( 114, 19 ); + this.txtHeight.TabIndex = 3; + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 123, 87 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 71, 24 ); + this.btnCancel.TabIndex = 5; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler( this.btnCancel_Click ); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 12, 87 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 71, 24 ); + this.btnOK.TabIndex = 4; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // SetSize + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 206, 123 ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.txtHeight ); + this.Controls.Add( this.txtWidth ); + this.Controls.Add( this.label2 ); + this.Controls.Add( this.label1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "SetSize"; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "SetSize"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtWidth; + private System.Windows.Forms.TextBox txtHeight; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Settings.cs b/trunk/LipSync/LipSync/Editor/Settings.cs new file mode 100644 index 0000000..4ca1952 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Settings.cs @@ -0,0 +1,214 @@ +/* + * Settings.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Runtime.Serialization; + +using Boare.Lib.AppUtil; +using Boare.Lib.Vsq; + +namespace LipSync { + + [Serializable] + public class Settings : IDisposable/*, ICloneable*/ { + const double tpq_sec = 480000000.0; + + public TimeTableGroup m_group_vsq; //ok + public List m_groups_character; //ok + public TimeTableGroup m_group_another; //ok + public TimeTableGroup m_group_plugin; //ok + [Obsolete] + //public float fps = 30.0f; //ok + float fps = 30f; + public int m_screenWidth; //ok + public int m_screenHeight; //ok + public float m_totalSec = 0.0f; //ok + public Size m_movieSize; // = new Size( 512, 384 ); //ok + public List m_plugins_config; //ok + public string m_audioFile = ""; //ok + [OptionalField] + public Color CANVAS_BACKGROUND; // = Color.White; //ok + [OptionalField, Obsolete] + public List m_telop; //ok + [OptionalField] + public float REPEAT_START; //ok + [OptionalField] + public float REPEAT_END; //ok + [OptionalField, Obsolete]//[OptionalField] + public SortedDictionary m_telop_ex = new SortedDictionary(); //OK + [OptionalField, Obsolete] + public List m_score_unit; + [OptionalField, Obsolete] + public List m_timesig; + [OptionalField] + public List m_timesig_ex; + [OptionalField] + public List m_tempo; + [OptionalField] + public int m_base_tempo; + [OptionalField] + public uint m_dwRate = 30; + [OptionalField] + public uint m_dwScale = 1; + [NonSerialized] + private float m_fps_buffer = 30f; + [NonSerialized] + public PluginInfo[] m_plugins; + [OptionalField] + public List m_telop_ex2 = new List(); + + /// + /// 描画順序で格納された描画物のリスト + /// + [NonSerialized] + public List m_zorder = new List(); + [NonSerialized] + public List m_commands = new List(); + [NonSerialized] + public int m_command_position = -1; + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public Settings() { + m_zorder = new List(); + m_commands = new List(); + m_command_position = -1; + m_group_vsq = new TimeTableGroup( _( "VSQ Tracks" ), -1, null ); + m_groups_character = new List(); + m_group_another = new TimeTableGroup( _( "Another images" ), -1, null ); + m_group_plugin = new TimeTableGroup( _( "Plugin" ), -1, null ); + m_telop_ex2 = new List(); + m_screenWidth = 512; + m_screenHeight = 384; + m_totalSec = 0.0f; + m_movieSize = new Size( 512, 384 ); + m_plugins_config = new List(); + m_audioFile = ""; + CANVAS_BACKGROUND = Color.White; + //m_telop = new List(); + //m_telop_ex = new SortedDictionary(); + m_telop_ex2 = new List(); + m_score_unit = new List(); + m_score_unit.Add( new ScoreUnit() ); + m_timesig_ex = new List(); + m_tempo = new List(); + m_base_tempo = 480000; + m_dwRate = 30; + m_dwScale = 1; + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; + } + + [OnSerializing] + private void onSerializing( StreamingContext sc ) { + m_telop = null; + m_telop_ex = null; + } + + [OnDeserializing] + private void onDeserializing( StreamingContext sc ) { + CANVAS_BACKGROUND = Color.White; + m_telop_ex2 = new List(); + REPEAT_START = 0f; + REPEAT_END = -1f; + m_score_unit = new List(); + m_dwRate = 0; + m_dwScale = 0; + } + + + [OnDeserialized] + void onDeserialized( StreamingContext sc ) { +#if DEBUG + Console.WriteLine( "Settings.onDeserialized(StreamingContext)" ); +#endif + m_score_unit = new List(); + m_score_unit.Add( new ScoreUnit() ); + if ( m_telop != null ) { + if ( m_telop_ex2 != null ) { + m_telop_ex2.Clear(); + m_telop_ex2 = null; + } + m_telop_ex2 = new List(); + for ( int i = 0; i < m_telop.Count; i++ ) { + m_telop_ex2.Add( (Telop)m_telop[i].Clone( i ) ); + } + m_telop.Clear(); + m_telop = null; + } + if ( m_telop_ex != null ) { + if ( m_telop_ex2 != null ) { + m_telop_ex2.Clear(); + m_telop_ex2 = null; + } + m_telop_ex2 = new List(); + int index = -1; + foreach ( KeyValuePair telop in m_telop_ex ) { + index++; + m_telop_ex2.Add( (Telop)telop.Value.Clone( index ) ); + } + m_telop_ex.Clear(); + m_telop_ex = null; + } + m_commands = new List(); + m_command_position = -1; + m_zorder = new List(); + if ( m_timesig_ex == null ) { + m_timesig_ex = new List(); + } + if ( m_tempo == null ) { + m_tempo = new List(); + } + if ( m_dwRate == 0 ) { + m_dwScale = 1000; + m_dwRate = (uint)(fps * m_dwScale); + } + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; +#if DEBUG + Common.DebugWriteLine( "----------" ); + Common.DebugWriteLine( "Settings.onDeserialized(StreamingContext)" ); + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + Common.DebugWriteLine( "i=" + i + "; ID=" + m_telop_ex2[i].ID + "; Text=" + m_telop_ex2[i].Text ); + } + Common.DebugWriteLine( "----------" ); +#endif + } + + public void Dispose() { + if ( m_group_vsq != null ) { + m_group_vsq.Dispose(); + m_group_vsq = null; + } + if ( m_groups_character != null ) { + m_groups_character.Clear(); + m_groups_character = null; + } + if ( m_group_another != null ) { + m_group_another.Dispose(); + m_group_another = null; + } + if ( m_group_plugin != null ) { + m_group_plugin.Dispose(); + m_group_plugin = null; + } + if ( m_plugins_config != null ) { + m_plugins_config.Clear(); + m_plugins_config = null; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/SettingsEx.cs b/trunk/LipSync/LipSync/Editor/SettingsEx.cs new file mode 100644 index 0000000..edf315e --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/SettingsEx.cs @@ -0,0 +1,1115 @@ +/* + * SettingsEx.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Runtime.Serialization; + +using Boare.Lib.AppUtil; +using Boare.Lib.Vsq; + +namespace LipSync { + + public delegate void CommandExecutedEventHandler( TimeTableType command_target, CommandType command_type ); + + [Serializable] + public class SettingsEx : IDisposable, ICloneable { + const double tpq_sec = 480000000.0; + + public TimeTableGroup m_group_vsq; //ok + public List m_groups_character; //ok + public TimeTableGroup m_group_another; //ok + public TimeTableGroup m_group_plugin; //ok + public int m_screenWidth = 512; //ok + public int m_screenHeight = 384; //ok + public float m_totalSec = 0.0f; //ok + public Size m_movieSize; // = new Size( 512, 384 ); //ok + public List m_plugins_config; //ok + public string m_audioFile = ""; //ok + [OptionalField] + public Color CANVAS_BACKGROUND; // = Color.White; //ok + [OptionalField] + public float REPEAT_START; //ok + [OptionalField] + public float REPEAT_END; //ok + [OptionalField] + public List m_timesig_ex; + [OptionalField] + public List m_tempo; + [OptionalField] + public int m_base_tempo; + [OptionalField] + public uint m_dwRate = 30; + [OptionalField] + public uint m_dwScale = 1; + [NonSerialized] + private float m_fps_buffer = 30f; + [NonSerialized] + public PluginInfo[] m_plugins; + [OptionalField] + public List m_telop_ex2 = new List(); + [OptionalField] + public bool TelopListFolded = false; + /// + /// 描画順序で格納された描画物のリスト + /// + [NonSerialized] + public List m_zorder = new List(); + [OptionalField] + public string VersionMarker = AppManager.VERSION;// "2.4.4"; + + public static event CommandExecutedEventHandler CommandExecuted; + + private static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public void DrawTo( Graphics g, Size mSize, float now, bool is_transparent ) { + DrawTo( g, mSize, now, is_transparent, "", 0 ); + } + + public void DrawTo( Graphics g, Size mSize, float now, bool is_transparent, string mouth, int mouth_force_group_index ) { + if ( mouth.Length == 0 ) { + mouth_force_group_index = -1; + } +#if DEBUG + //Common.DebugWriteLine( "SettingsEx+DrawTo(Graphics,Size,float,bool)" ); + int chrpos = 10; +#endif + g.SmoothingMode = SmoothingMode.AntiAlias; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + + if ( is_transparent ) { + g.Clear( Color.Transparent ); + } else { + g.Clear( CANVAS_BACKGROUND ); + } + + ColorMatrix cm = new ColorMatrix(); + cm.Matrix00 = 1; + cm.Matrix11 = 1; + cm.Matrix22 = 1; + cm.Matrix33 = 1f; + cm.Matrix44 = 1; + + for ( int z = 0; z < m_zorder.Count; z++ ) { + ZorderItemType type = m_zorder[z].Type; + int index = m_zorder[z].Index; + + Bitmap tmp = null; + PointF position = new PointF(); + float scale = 1f; + float alpha = 1f; + float rotate = 0f; + Size size = new Size(); + + if ( type == ZorderItemType.another ) { + if ( !m_group_another[index].IsAviMode ) { + if ( m_group_another[index].Image == null ) { + continue; + } + int start_entry = m_group_another[index].Value; + for ( int entry = start_entry; entry < m_group_another[index].Count; entry++ ) { + if ( m_group_another[index][entry].begin <= now && now <= m_group_another[index][entry].end ) { + m_group_another[index].Value = entry; + tmp = m_group_another[index].Image; + break; + } + } + } else { + tmp = m_group_another[index].GetImage( now ); + } + position = m_group_another[index].GetPosition( now ); + size = m_group_another[index].ImageSize; + scale = m_group_another[index].GetScale( now ); + alpha = m_group_another[index].GetAlpha( now ); + rotate = m_group_another[index].GetRotate( now ); + } else if ( type == ZorderItemType.character ) { + if ( m_groups_character[index].Character.Type == CharacterType.def ) { + int[] draw; + if ( mouth_force_group_index == index ) { + draw = m_groups_character[index].GetDrawObjectIndex( now, mouth ); + } else { + draw = m_groups_character[index].GetDrawObjectIndex( now, "" ); + } + position = m_groups_character[index].GetPosition( now ); + size = m_groups_character[index].Character.Size; + scale = m_groups_character[index].GetScale( now ); + float tscale = Math.Abs( scale ); + if ( tscale == 0.0f ) { + continue; + } + alpha = m_groups_character[index].GetAlpha( now ); + if ( alpha <= 0.0f ) { + continue; + } + rotate = m_groups_character[index].GetRotate( now ); +#if DEBUG + chrpos += 10; + g.DrawString( "character: position=" + position + ", m_groups_character[group].Position=" + m_groups_character[index].Position, AppManager.Config.Font.GetFont(), Brushes.Black, new PointF( 0, chrpos ) ); +#endif + tmp = m_groups_character[index].Character.Face( draw ); + } else { + string[] draw = m_groups_character[index].GetDrawObjectNames( now ); + int target_plugin = -1; + for ( int i = 0; i < m_plugins_config.Count; i++ ) { + if ( m_plugins_config[i].ID == m_groups_character[index].Character.PluginConfig.ID ) { + target_plugin = i; + break; + } + } + if ( target_plugin >= 0 ) { + string s = ""; + bool first = true; + for ( int i = 0; i < draw.Length; i++ ) { + if ( first ) { + s += draw[i]; + first = false; + } else { + s += "\n" + draw[i]; + } + } + m_plugins[target_plugin].Instance.Render( g, mSize, now, s, "" ); + } + continue; + } + } else if ( type == ZorderItemType.plugin ) { + int start_entry = m_group_plugin[index].Value; + for ( int entry = start_entry; entry < m_group_plugin[index].Count; entry++ ) { + if ( m_group_plugin[index][entry].begin <= now && now <= m_group_plugin[index][entry].end ) { + m_group_plugin[index].Value = entry; +#if DEBUG + chrpos += 10; + g.DrawString( "plugin", AppManager.Config.Font.GetFont(), Brushes.Black, new PointF( 0, chrpos ) ); +#endif + tmp = new Bitmap( mSize.Width, mSize.Height ); + TimeTableEntry tmptt = m_group_plugin[index][entry]; + m_plugins[index].Instance.Apply( ref tmp, now, tmptt.begin, tmptt.end, ref tmptt.body ); + m_group_plugin[index][entry] = tmptt; + size = mSize; + position = new PointF( 0f, 0f ); + alpha = 1f; + scale = 1f; + rotate = 0f; + break; + } + } + } else { + continue; + } + + if ( tmp != null ) { + float tscale = Math.Abs( scale ); + if ( scale < 0 ) { + tmp.RotateFlip( RotateFlipType.RotateNoneFlipX ); + } + if ( scale != 0.0f ) { + g.ResetTransform(); + float half_width = size.Width / 2f; + float half_height = size.Height / 2f; + g.TranslateTransform( position.X + half_width * tscale, position.Y + half_height * tscale ); + if ( scale != 1f ) { + g.ScaleTransform( tscale, tscale ); + } + InterpolationMode im = g.InterpolationMode; + SmoothingMode sm = g.SmoothingMode; + if ( scale == 1f && rotate == 0f ) { + g.InterpolationMode = InterpolationMode.Default; + g.SmoothingMode = SmoothingMode.Default; + } + if ( rotate != 0f ) { + g.RotateTransform( rotate ); + } + if ( 0 < alpha && alpha < 1f ) { + cm.Matrix33 = alpha; + ImageAttributes ia = new ImageAttributes(); + ia.SetColorMatrix( cm ); + g.DrawImage( tmp, + new PointF[]{ new PointF( -half_width, - half_height ), + new PointF( half_width, -half_height ), + new PointF( -half_width, half_height ) }, + new RectangleF( 0f, 0f, size.Width, size.Height ), + GraphicsUnit.Pixel, + ia ); + } else if ( alpha != 0f ) { + g.DrawImage( tmp, -half_width, -half_height, (float)size.Width, (float)size.Height ); + } + g.InterpolationMode = im; + g.SmoothingMode = sm; + g.ResetTransform(); + } + } + } + + //最後に字幕を入れる + foreach ( Telop telop in m_telop_ex2 ) { + if ( telop.Start <= now && now <= telop.End ) { + float alpha = 1f; + if ( telop.FadeIn ) { + float diff = now - telop.Start; + if ( 0f <= diff && diff <= telop.FadeInSpan ) { + alpha = 1.0f / telop.FadeInSpan * diff; + } + } + if ( telop.FadeOut ) { + float diff = telop.End - now; + if ( 0f <= diff && diff <= telop.FadeOutSpan ) { + alpha = 1.0f / telop.FadeOutSpan * diff; + } + } + PointF position = telop.GetPosition( now ); + Size size = telop.ImageSize; + float scale = telop.GetScale( now ); + float talpha = telop.GetAlpha( now ); + float rotate = telop.GetRotate( now ); + g.ResetTransform(); + if ( scale != 0.0f ) { + g.TranslateTransform( position.X + size.Width / 2f * scale, position.Y + size.Height / 2f * scale ); + if ( scale != 1f ) { + g.ScaleTransform( scale, scale ); + } + if ( rotate != 0f ) { + g.RotateTransform( rotate ); + } + g.DrawString( telop.Text, + telop.Font, + new SolidBrush( Color.FromArgb( (int)(talpha * alpha * 255), telop.Color ) ), + (int)(-size.Width / 2), + (int)(-size.Height / 2) ); + g.ResetTransform(); + } + } + } + //} + //return bmp; + } + + + /// + /// Settingsからのコンバート + /// + /// + public SettingsEx( Settings s ) { +#if DEBUG + Common.DebugWriteLine( "SettingsEx..ctor(Settings)" ); +#endif + m_group_vsq = (TimeTableGroup)s.m_group_vsq.Clone(); + m_groups_character = new List(); + for( int i = 0; i < s.m_groups_character.Count; i++ ){ + m_groups_character.Add( (TimeTableGroup)s.m_groups_character[i].Clone() ); + } + m_group_another = (TimeTableGroup)s.m_group_another.Clone(); + m_group_plugin = (TimeTableGroup)s.m_group_plugin.Clone(); + m_screenWidth = s.m_screenWidth; + m_screenHeight = s.m_screenHeight; + m_totalSec = s.m_totalSec; + m_movieSize = s.m_movieSize; + m_plugins_config = new List(); + for( int i = 0; i < s.m_plugins_config.Count; i++ ){ + m_plugins_config.Add( s.m_plugins_config[i].Clone() ); + } + m_audioFile = s.m_audioFile; + CANVAS_BACKGROUND = s.CANVAS_BACKGROUND; + REPEAT_START = s.REPEAT_START; + REPEAT_END = s.REPEAT_START; + m_timesig_ex = new List(); + for( int i = 0; i < s.m_timesig_ex.Count; i++ ){ + if ( s.m_timesig_ex[i].Numerator == 0 || s.m_timesig_ex[i].Denominator == 0 ) { + m_timesig_ex.Clear(); + break; + } + m_timesig_ex.Add( (TimeSigTableEntry)s.m_timesig_ex[i].Clone() ); + } + m_tempo = new List(); + for( int i = 0; i < s.m_tempo.Count; i++ ){ + m_tempo.Add( (TempoTableEntry)s.m_tempo[i].Clone() ); + } + m_base_tempo = s.m_base_tempo; + m_dwRate = s.m_dwRate; + m_dwScale = s.m_dwScale; + m_fps_buffer = m_dwRate / (float)m_dwScale; + m_telop_ex2 = new List(); + for ( int i = 0; i < s.m_telop_ex2.Count; i++ ) { + m_telop_ex2.Add( (Telop)s.m_telop_ex2[i].Clone() ); + } + } + + public Telop this[int id] { + get { + foreach ( Telop item in m_telop_ex2 ) { + if ( item.ID == id ) { + return item; + } + } + return null; + } + set { + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + if ( m_telop_ex2[i].ID == id ) { + m_telop_ex2[i] = value; + break; + } + } + } + } + + public float FrameRate { + get { + return m_fps_buffer; + } + } + + public uint DwRate { + get { + return m_dwRate; + } + set { + m_dwRate = value; + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; + } + } + + public uint DwScale { + get { + return m_dwScale; + } + set { + m_dwScale = value; + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; + } + } + + public object Clone() { + SettingsEx res = new SettingsEx(); + res.m_group_vsq = (TimeTableGroup)m_group_vsq.Clone(); + res.m_groups_character = new List(); + for ( int i = 0; i < m_groups_character.Count; i++ ) { + res.m_groups_character.Add( (TimeTableGroup)m_groups_character[i].Clone() ); + } + res.m_group_another = (TimeTableGroup)m_group_another.Clone(); + res.m_group_plugin = (TimeTableGroup)m_group_plugin.Clone(); + //res.fps = fps; + res.m_screenWidth = m_screenWidth; + res.m_screenHeight = m_screenHeight; + res.m_totalSec = m_totalSec; + res.m_movieSize = m_movieSize; + res.m_plugins_config = new List(); + for ( int i = 0; i < m_plugins_config.Count; i++ ) { + res.m_plugins_config.Add( m_plugins_config[i].Clone() ); + } + res.m_audioFile = m_audioFile; + res.CANVAS_BACKGROUND = CANVAS_BACKGROUND; + res.REPEAT_START = REPEAT_START; + res.REPEAT_END = REPEAT_END; + res.m_telop_ex2 = new List(); + foreach ( Telop item in m_telop_ex2 ) { + res.m_telop_ex2.Add( (Telop)item.Clone() ); + } + res.m_timesig_ex = new List(); + for ( int i = 0; i < m_timesig_ex.Count; i++ ) { + res.m_timesig_ex.Add( (TimeSigTableEntry)m_timesig_ex[i].Clone() ); + } + res.m_tempo = new List(); + for ( int i = 0; i < m_tempo.Count; i++ ) { + res.m_tempo.Add( (TempoTableEntry)m_tempo[i].Clone() ); + } + res.m_base_tempo = m_base_tempo; + res.m_zorder = new List(); + for ( int i = 0; i < m_zorder.Count; i++ ) { + res.m_zorder.Add( (ZorderItem)m_zorder[i].Clone() ); + } + /*res.m_commands = new List(); + for ( int i = 0; i < m_commands.Count; i++ ) { + res.m_commands.Add( m_commands[i].Clone() ); + } + res.m_command_position = m_command_position;*/ + res.DwRate = m_dwRate; + res.DwScale = m_dwScale; + return res; + } + + + public TimeTableGroup this[TimeTableType type, int group] { + get { + if ( type == TimeTableType.character ) { + return m_groups_character[group]; + } else { + switch ( type ) { + case TimeTableType.another: + return m_group_another; + case TimeTableType.plugin: + return m_group_plugin; + case TimeTableType.vsq: + return m_group_vsq; + default: + return null; + } + } + } + set { + if ( type == TimeTableType.character ) { + m_groups_character[group] = value; + } else { + switch ( type ) { + case TimeTableType.another: + m_group_another = value; + break; + case TimeTableType.plugin: + m_group_plugin = value; + break; + case TimeTableType.vsq: + m_group_vsq = value; + break; + } + } + } + } + + public SettingsEx() { + m_zorder = new List(); + m_group_vsq = new TimeTableGroup( _( "VSQ Tracks" ), -1, null ); + m_groups_character = new List(); + m_group_another = new TimeTableGroup( _( "Another images" ), -1, null ); + m_group_plugin = new TimeTableGroup( _( "Plugin" ), -1, null ); + m_telop_ex2 = new List(); + m_screenWidth = 512; + m_screenHeight = 384; + m_totalSec = 0.0f; + m_movieSize = new Size( 512, 384 ); + m_plugins_config = new List(); + m_audioFile = ""; + CANVAS_BACKGROUND = Color.White; + m_telop_ex2 = new List(); + m_timesig_ex = new List(); + m_tempo = new List(); + m_base_tempo = 480000; + m_dwRate = 30; + m_dwScale = 1; + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; + } + + [OnDeserializing] + private void onDeserializing( StreamingContext sc ) { + CANVAS_BACKGROUND = Color.White; + m_telop_ex2 = new List(); + REPEAT_START = 0f; + REPEAT_END = -1f; + m_dwRate = 0; + m_dwScale = 0; + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { +#if DEBUG + Common.DebugWriteLine( "SettingsEx.onDeserialized(StreamingContext)" ); + Common.DebugWriteLine( " m_timesig_ex" ); +#endif + m_zorder = new List(); + if ( m_timesig_ex == null ) { + m_timesig_ex = new List(); + } else { + for ( int i = 0; i < m_timesig_ex.Count; i++ ) { +#if DEBUG + Common.DebugWriteLine( " " + m_timesig_ex[i].ToString() ); +#endif + if ( m_timesig_ex[i].Numerator == 0 || m_timesig_ex[i].Denominator == 0 ) { + m_timesig_ex.Clear(); + break; + } + } + } + if( m_tempo == null ) { + m_tempo = new List(); + } + if ( m_dwRate == 0 ) { + m_dwScale = 1; + m_dwRate = 30; + } + m_fps_buffer = (float)m_dwRate / (float)m_dwScale; +#if DEBUG + Common.DebugWriteLine( " m_telop_ex2" ); + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + Common.DebugWriteLine( " i=" + i + "; ID=" + m_telop_ex2[i].ID + "; Text=" + m_telop_ex2[i].Text ); + } +#endif + } + + public void Dispose() { + if ( m_group_vsq != null ) { + m_group_vsq.Dispose(); + m_group_vsq = null; + } + if ( m_groups_character != null ) { + m_groups_character.Clear(); + m_groups_character = null; + } + if ( m_group_another != null ) { + m_group_another.Dispose(); + m_group_another = null; + } + if ( m_group_plugin != null ) { + m_group_plugin.Dispose(); + m_group_plugin = null; + } + if ( m_plugins_config != null ) { + m_plugins_config.Clear(); + m_plugins_config = null; + } + } + + /// + /// m_telop_ex用。次に利用可能なIDを調べます + /// + /// + public int GetNextID() { + return GetNextID( 0 ); + } + + public int GetNextID( int skip ) { + int draft = -1; + while ( true ) { + draft++; + bool found = false; + foreach ( Telop item in m_telop_ex2 ) { + if ( draft == item.ID ) { + found = true; + } + } + if ( !found ) { + break; + } + } + return draft + skip; + } + + public void SetZorder( ZorderItem item, int zorder ) { + switch ( item.Type ) { + case ZorderItemType.plugin: + m_group_plugin[item.Index].ZOrder = zorder; + break; + case ZorderItemType.another: + m_group_another[item.Index].ZOrder = zorder; + break; + case ZorderItemType.character: + m_groups_character[item.Index].ZOrder = zorder; + break; + } + } + + public int GetZorder( ZorderItem item ) { + switch ( item.Type ) { + case ZorderItemType.plugin: + return m_group_plugin[item.Index].ZOrder; + case ZorderItemType.another: + return m_group_another[item.Index].ZOrder; + case ZorderItemType.character: + return m_groups_character[item.Index].ZOrder; + } + return 0; + } + + public void UpdateZorder() { + m_zorder.Clear(); + for ( int i = 0; i < m_plugins_config.Count; i++ ) { + m_zorder.Add( new ZorderItem( m_plugins_config[i].ID, ZorderItemType.plugin, i ) ); + } + for ( int i = 0; i < m_groups_character.Count; i++ ) { + m_zorder.Add( new ZorderItem( m_groups_character[i].Text, ZorderItemType.character, i ) ); + } + for ( int i = 0; i < m_group_another.Count; i++ ) { + m_zorder.Add( new ZorderItem( m_group_another[i].Text, ZorderItemType.another, i ) ); + } + + bool changed = true; + ZorderItem tmp; + while ( changed ) { + changed = false; + for ( int i = 0; i < m_zorder.Count - 1; i++ ) { + int order_i = GetZorder( m_zorder[i] ); + int order_ipp = GetZorder( m_zorder[i + 1] ); + if ( order_i < order_ipp || (order_i == order_ipp && m_zorder[i + 1].Type.CompareTo( m_zorder[i].Type ) > 0) ) { + tmp = (ZorderItem)m_zorder[i].Clone(); + m_zorder[i] = (ZorderItem)m_zorder[i + 1].Clone(); + m_zorder[i + 1] = (ZorderItem)tmp.Clone(); + changed = true; + } + } + } + + for ( int i = 0; i < m_zorder.Count; i++ ) { + SetZorder( m_zorder[i], m_zorder.Count - 1 - i ); + } + + } + + /// + /// 指定されたコマンドを実行します + /// + /// + public Command Execute( Command command ) { + int group = command.group; + int track = command.track; + int entry = command.entry; + TimeTableType target = command.target; + + Command ret = null; + switch ( command.target ) { + case TimeTableType.telop: + #region telop + switch ( command.type ) { + case CommandType.addTelop: + Telop adding = (Telop)command.telop.Clone( GetNextID() ); + ret = Command.GCommandDeleteTelop( adding ); + m_telop_ex2.Add( adding ); + break; + case CommandType.editTelop: + ret = Command.GCommandEditTelop( command.telop.ID, this[command.telop.ID] ); + this[command.telop.ID] = (Telop)command.telop.Clone(); + break; + case CommandType.deleteTelop: + ret = Command.GCommandAddTelop( this[command.telop.ID] ); + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + if ( m_telop_ex2[i].ID == command.telop.ID ) { + m_telop_ex2.RemoveAt( i ); + break; + } + } + Property.Instance.Editing = null; //dirty... + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( target, -1, -command.floatValue ); + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + m_telop_ex2[i].Start += command.floatValue; + m_telop_ex2[i].End += command.floatValue; + } + break; + case CommandType.addTelopRange: + Telop[] adding2 = (Telop[])command.args[0]; + for ( int i = 0; i < adding2.Length; i++ ) { + adding2[i] = (Telop)adding2[i].Clone( GetNextID( i ) ); + } + ret = Command.GCommandDeleteTelopRange( adding2 ); + m_telop_ex2.AddRange( adding2 ); + break; + case CommandType.deleteTelopRange: + Telop[] adding3 = (Telop[])command.args[0]; + ret = Command.GCommandAddTelopRange( adding3 ); + for ( int i = 0; i < adding3.Length; i++ ) { + for ( int j = 0; j < m_telop_ex2.Count; j++ ) { + if ( m_telop_ex2[j].ID == adding3[i].ID ) { + m_telop_ex2.RemoveAt( j ); + break; + } + } + } + break; + } + Telop.DecideLane( m_telop_ex2 ); + #endregion + break; + case TimeTableType.another: + #region another + switch ( command.type ) { + case CommandType.addEntry: + ret = Command.GCommandDeleteTimeTableEntry( target, -1, track, command.item ); + m_group_another[track].Add( (TimeTableEntry)command.item.Clone() ); + m_group_another[track].Sort(); + break; + case CommandType.deleteEntry: + ret = Command.GCommandAddTimeTableEntry( target, -1, track, command.item ); + m_group_another[track].Remove( command.item ); + break; + case CommandType.editEntry: + ret = Command.GCommandEditTimeTableEntry( target, -1, track, entry, m_group_another[track][entry] ); + m_group_another[track][entry] = (TimeTableEntry)command.item.Clone(); + break; + case CommandType.addTimeTable: + ret = Command.GCommandDeleteTimeTable( target, -1, m_group_another.Count ); + m_group_another.Insert( command.track, (TimeTable)command.table.Clone() ); + UpdateZorder(); + break; + case CommandType.deleteTimeTable: + ret = Command.GCommandAddTimeTable( target, -1, track, m_group_another[track] ); + m_group_another.RemoveAt( command.track ); + UpdateZorder(); + break; + case CommandType.editTimeTable: + ret = Command.GCommandEditTimeTable( target, -1, track, m_group_another[track] ); + m_group_another[command.track].Clear(); + m_group_another[command.track] = (TimeTable)command.table.Clone(); + break; + case CommandType.setImage: + if ( m_group_another[track].IsAviMode ) { + ret = Command.GCommandSetAvi( track, m_group_another[track].AviConfig ); + } else { + ret = Command.GCommandSetImage( track, m_group_another[track].Image ); + } + m_group_another[command.track].SetImage( command.image ); + break; + case CommandType.setPosition: + ret = Command.GCommandSetPosition( target, -1, track, m_group_another[track].Position ); + m_group_another[command.track].Position = command.position; + break; + case CommandType.changeScale: + ret = Command.GCommandChangeScale( target, -1, track, m_group_another[track].Scale ); + m_group_another[command.track].Scale = command.floatValue; + break; + case CommandType.editGroup: + ret = Command.GCommandEditGroup( target, -1, m_group_another ); + m_group_another = null; + m_group_another = (TimeTableGroup)command.tablegroup.Clone(); + break; + case CommandType.setAvi: + if ( m_group_another[track].IsAviMode ) { + ret = Command.GCommandSetAvi( track, m_group_another[track].AviConfig ); + } else { + ret = Command.GCommandSetImage( track, m_group_another[track].Image ); + } + m_group_another[command.track].SetAvi( command.str ); + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( target, track, -command.floatValue ); + for ( int i = 0; i < m_group_another[track].Count; i++ ) { + m_group_another[track][i].begin += command.floatValue; + m_group_another[track][i].end += command.floatValue; + } + break; + } + #endregion + break; + case TimeTableType.character: + #region character + switch ( command.type ) { + case CommandType.addEntry: + ret = Command.GCommandDeleteTimeTableEntry( target, group, track, command.item ); + m_groups_character[group][track].Add( (TimeTableEntry)command.item.Clone() ); + m_groups_character[group][track].Sort(); + break; + case CommandType.deleteEntry: + ret = Command.GCommandAddTimeTableEntry( target, group, track, command.item ); + m_groups_character[group][track].Remove( command.item ); + break; + case CommandType.editEntry: + ret = Command.GCommandEditTimeTableEntry( target, group, track, entry, m_groups_character[group][track][entry] ); + m_groups_character[group][track][entry] = (TimeTableEntry)command.item.Clone(); + break; + case CommandType.addTimeTable: + ret = Command.GCommandDeleteTimeTable( target, group, m_groups_character[group].Count ); + m_groups_character[group].Insert( command.track, (TimeTable)command.table.Clone() ); + UpdateZorder(); + break; + case CommandType.deleteTimeTable: + ret = Command.GCommandAddTimeTable( target, group, track, m_groups_character[group][track] ); + m_groups_character[group].RemoveAt( command.track ); + UpdateZorder(); + break; + case CommandType.editTimeTable: + ret = Command.GCommandEditTimeTable( target, group, track, m_groups_character[group][track] ); + m_groups_character[command.group][command.track].Clear(); + m_groups_character[command.group][command.track] = (TimeTable)command.table.Clone(); + break; + case CommandType.addGroup: + ret = Command.GCommandDeleteTimeTableGroup( target, m_groups_character.Count ); + m_groups_character.Insert( command.group, (TimeTableGroup)command.tablegroup.Clone() ); + UpdateZorder(); + break; + case CommandType.deleteGroup: + ret = Command.GCommandAddGroup( target, group, m_groups_character[group] ); + m_groups_character.RemoveAt( command.group ); + Property.Instance.Editing = null; + UpdateZorder(); + break; + case CommandType.editGroup: + ret = Command.GCommandEditGroup( target, group, m_groups_character[group] ); + m_groups_character[command.group].Dispose(); + m_groups_character[command.group] = (TimeTableGroup)command.tablegroup.Clone(); + break; + case CommandType.setPosition: + ret = Command.GCommandSetPosition( target, group, track, m_groups_character[group].Position ); + m_groups_character[command.group].Position = command.position; + break; + case CommandType.changeScale: + ret = Command.GCommandChangeScale( target, group, -1, m_groups_character[group].Scale ); + m_groups_character[command.group].Scale = command.floatValue; + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( target, group, -command.floatValue ); + for ( int i = 0; i < m_groups_character[group].Count; i++ ) { + for ( int j = 0; j < m_groups_character[group][i].Count; j++ ) { + m_groups_character[group][i][j].begin += command.floatValue; + m_groups_character[group][i][j].end += command.floatValue; + } + } + break; + } + #endregion + break; + case TimeTableType.plugin: + #region plugin + switch ( command.type ) { + case CommandType.addEntry: + ret = Command.GCommandDeleteTimeTableEntry( target, -1, track, command.item ); + m_group_plugin[track].Add( (TimeTableEntry)command.item.Clone() ); + m_group_plugin[track].Sort(); + break; + case CommandType.deleteEntry: + ret = Command.GCommandAddTimeTableEntry( target, -1, track, command.item ); + m_group_plugin[track].Remove( command.item ); + break; + case CommandType.editEntry: + ret = Command.GCommandEditTimeTableEntry( target, -1, track, entry, m_group_plugin[track][entry] ); + m_group_plugin[track][entry] = (TimeTableEntry)command.item.Clone(); + break; + case CommandType.addTimeTable: + ret = Command.GCommandDeleteTimeTable( target, -1, m_group_plugin.Count ); + m_group_plugin.Insert( command.track, (TimeTable)command.table.Clone() ); + UpdateZorder(); + break; + case CommandType.deleteTimeTable: + ret = Command.GCommandAddTimeTable( target, -1, track, m_group_plugin[track] ); + m_group_plugin.RemoveAt( command.track ); + UpdateZorder(); + break; + case CommandType.editTimeTable: + ret = Command.GCommandEditTimeTable( target, -1, track, m_group_plugin[track] ); + m_group_plugin[command.track].Clear(); + m_group_plugin[command.track] = (TimeTable)command.table.Clone(); + break; + case CommandType.editGroup: + ret = Command.GCommandEditGroup( target, -1, m_group_plugin ); + m_group_plugin = null; + m_group_plugin = (TimeTableGroup)command.tablegroup.Clone(); + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( target, track, -command.floatValue ); + for ( int i = 0; i < m_group_plugin[track].Count; i++ ) { + m_group_plugin[track][i].begin += command.floatValue; + m_group_plugin[track][i].end += command.floatValue; + } + break; + } + #endregion + break; + case TimeTableType.vsq: + #region vsq + switch ( command.type ) { + case CommandType.addEntry: + ret = Command.GCommandDeleteTimeTableEntry( target, -1, track, command.item ); + m_group_vsq[track].Add( (TimeTableEntry)command.item.Clone() ); + m_group_vsq[track].Sort(); + break; + case CommandType.deleteEntry: + ret = Command.GCommandAddTimeTableEntry( target, -1, track, command.item ); + m_group_vsq[track].Remove( command.item ); + break; + case CommandType.editEntry: + ret = Command.GCommandEditTimeTableEntry( target, -1, track, entry, m_group_vsq[track][entry] ); + m_group_vsq[track][entry] = (TimeTableEntry)command.item.Clone(); + break; + case CommandType.addTimeTable: + ret = Command.GCommandDeleteTimeTable( target, -1, m_group_vsq.Count ); + m_group_vsq.Insert( command.track, (TimeTable)command.table.Clone() ); + break; + case CommandType.deleteTimeTable: + ret = Command.GCommandAddTimeTable( target, -1, track, m_group_vsq[track] ); + m_group_vsq.RemoveAt( command.track ); + break; + case CommandType.editTimeTable: + ret = Command.GCommandEditTimeTable( target, -1, track, m_group_vsq[track] ); + m_group_vsq[command.track].Clear(); + m_group_vsq[command.track] = (TimeTable)command.table.Clone(); + break; + case CommandType.editGroup: + ret = Command.GCommandEditGroup( target, -1, m_group_vsq ); + m_group_vsq = null; + m_group_vsq = (TimeTableGroup)command.tablegroup.Clone(); + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( target, track, -command.floatValue ); + for ( int i = 0; i < m_group_vsq[track].Count; i++ ) { + m_group_vsq[track][i].begin += command.floatValue; + m_group_vsq[track][i].end += command.floatValue; + } + break; + } + #endregion + break; + case TimeTableType.whole: + #region whole + switch ( command.type ) { + case CommandType.changePluginConfig: + ret = Command.GCommandChangePluginConfig( track, m_plugins_config[track].Config ); + m_plugins_config[command.track].Config = command.str; + // キャラクタ描画用プラグインの場合は、該当キャラクタトラックのグループ番号に応じて、command.group(>=0)に値がセットされる + if ( command.group >= 0 ) { + m_groups_character[command.group].Character.PluginConfig.Config = command.str; + } + m_plugins[command.track].Instance.Config = command.str; + break; + case CommandType.changeFps: + ret = Command.GCommandChangeFps( m_dwRate, m_dwScale ); + DwRate = command.dwRate; + DwScale = command.dwScale; + break; + case CommandType.changeVideoSize: + ret = Command.GCommandChangeVideoSize( m_movieSize ); + m_movieSize = command.size; + break; + case CommandType.shiftTimeTable: + ret = Command.GCommandShiftTimeTable( TimeTableType.whole, -1, -command.floatValue ); + float shift = command.floatValue; + // vsq + shiftTimeTable( ref m_group_vsq, shift ); + // character + for ( int i = 0; i < m_groups_character.Count; i++ ) { + TimeTableGroup tmp = m_groups_character[i]; + shiftTimeTable( ref tmp, shift ); + m_groups_character[i] = tmp; + } + // another + shiftTimeTable( ref m_group_another, shift ); + // plugin + shiftTimeTable( ref m_group_plugin, shift ); + // telop + for ( int i = 0; i < m_telop_ex2.Count; i++ ) { + m_telop_ex2[i].Start += shift; + m_telop_ex2[i].End += shift; + } + break; + case CommandType.setMP3: + ret = Command.GCommandSetMp3( m_audioFile ); + m_audioFile = command.str; + break; + case CommandType.changeBackgroundColor: + ret = Command.GCommandChangeBackgroundColor( CANVAS_BACKGROUND ); + CANVAS_BACKGROUND = command.color; + break; + } + #endregion + break; + } + if ( command.child != null ) { + ret.child = Execute( command.child ); + } + if ( CommandExecuted != null ) { + CommandExecuted( command.target, command.type ); + } + return ret; + } + + private void shiftTimeTable( ref TimeTableGroup table, float shift ) { + for ( int track = 0; track < table.Count; track++ ) { + for ( int entry = 0; entry < table[track].Count; entry++ ) { + table[track][entry].begin += shift; + table[track][entry].end += shift; + } + } + } + + public IEnumerable GetZorderItemEnumerator() { + for( int i = 0; i < m_groups_character.Count; i++ ) { + yield return new ZorderItem( m_groups_character[i].Text, ZorderItemType.character, i ); + } + for( int i = 0; i < m_group_another.Count; i++ ) { + yield return new ZorderItem( m_group_another[i].Text, ZorderItemType.another, i ); + } + for( int i = 0; i < m_telop_ex2.Count; i++ ) { + yield return new ZorderItem( m_telop_ex2[i].Text, ZorderItemType.telop, m_telop_ex2[i].ID ); + } + } + + public IEnumerable GetBarLineTypeEnumerator( QuantizeMode mode, bool triplet ) { + int local_denominator; + int local_numerator; + int local_clock; + int local_bar_count; + int clock_step; + int end_clock; + int clock_per_bar; + for( int i = 0; i < m_timesig_ex.Count; i++ ) { + local_denominator = m_timesig_ex[i].Denominator; + local_numerator = m_timesig_ex[i].Numerator; + local_clock = m_timesig_ex[i].Clock; + local_bar_count = m_timesig_ex[i].BarCount; + clock_per_bar = 480 * 4 * local_numerator / local_denominator; + clock_step = 480 * 4 / local_denominator; + switch( mode ) { + case QuantizeMode.off: + clock_step = 480 * 4 / local_denominator; + break; + case QuantizeMode.q04: + clock_step = 480 * 4 / 4; + break; + case QuantizeMode.q08: + clock_step = 480 * 4 / 8; + break; + case QuantizeMode.q16: + clock_step = 480 * 4 / 16; + break; + case QuantizeMode.q32: + clock_step = 480 * 4 / 32; + break; + case QuantizeMode.q64: + clock_step = 480 * 4 / 64; + break; + } + if ( mode != QuantizeMode.off && triplet ) { + clock_step = clock_step * 4 / 3; + } + if( i == m_timesig_ex.Count - 1 ) { + double tempo; + if( m_tempo.Count > 0 ) { + tempo = m_tempo[m_tempo.Count - 1].Tempo; + } else { + tempo = m_base_tempo; + } + end_clock = (int)((m_totalSec - SecFromClock( m_timesig_ex[i].Clock ) + 1.0) * tpq_sec / tempo); + } else { + end_clock = m_timesig_ex[i + 1].Clock; + } + // todo: SettingsEx+GetBarLineTypeEnumerator; clock_per_barがclock_stepの整数倍とならない場合の処理 + for( int clock = local_clock; clock < end_clock; clock += clock_step ) { + if( (clock - local_clock) % clock_per_bar == 0 ) { + yield return new BarLineType( SecFromClock( clock ), true, false ); + } else { + yield return new BarLineType( SecFromClock( clock ), false, false ); + } + } + } + } + + /// + /// 指定したクロックにおける、clock=0からの演奏経過時間(sec) + /// + /// + /// + private double SecFromClock( int clock ) { + if( m_tempo.Count == 0 ) { + return (double)m_base_tempo * (double)clock / tpq_sec; + } else { + int index = 0; + for( int i = 0; i < m_tempo.Count; i++ ) { + if( clock <= m_tempo[i].Clock ) { + index = i; + break; + } + } + return m_tempo[index].Time + (double)(m_tempo[index].Tempo) * (clock - m_tempo[index].Clock) / tpq_sec; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TagForTreeNode.cs b/trunk/LipSync/LipSync/Editor/TagForTreeNode.cs new file mode 100644 index 0000000..5d99da7 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TagForTreeNode.cs @@ -0,0 +1,45 @@ +/* + * TagForTreeNode.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + [Obsolete] + public class TagForTreeNode { + public ZorderItemType type; + public int id_or_index; + public bool is_checked; // チェック済みかどうかを表す + + public TagForTreeNode( ZorderItemType type, int id_or_index ) { + this.type = type; + this.id_or_index = id_or_index; + this.is_checked = false; + } + + public override string ToString() { + switch( type ) { + case ZorderItemType.another: + return AppManager.SaveData.m_group_another[id_or_index].Text; + case ZorderItemType.character: + return AppManager.SaveData.m_groups_character[id_or_index].Text; + case ZorderItemType.plugin: + return AppManager.SaveData.m_group_plugin[id_or_index].Text; + case ZorderItemType.telop: + return AppManager.SaveData.m_telop_ex2[id_or_index].Text; + } + return ""; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Telop.cs b/trunk/LipSync/LipSync/Editor/Telop.cs new file mode 100644 index 0000000..eeadd0d --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Telop.cs @@ -0,0 +1,444 @@ +/* + * Telop.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.Serialization; + +using CurveEditor; + +namespace LipSync { + + [Serializable] + public class Telop : IComparable, ICloneable, IDrawObject { + string m_text = ""; + float m_start = 0f; + float m_end = 0f; + Font m_font = null; + bool m_fadein = false; + bool m_fadeout = false; + float m_alpha = 1.0f; + Point m_position = new Point( 0, 0 ); + Color m_fore_color; + Size m_size; + float m_fadein_ratio = 1f; + float m_fadeout_ratio = 1f; + [NonSerialized] + object m_tag; + [OptionalField] + public BezierChain mc_x; + [OptionalField] + public BezierChain mc_y; + [OptionalField] + public BezierChain mc_scale; + [OptionalField] + public BezierChain mc_alpha; + [OptionalField] + public BezierChain mc_rotate; + [OptionalField] + private int m_id; + [NonSerialized] + public int Lane; + [OptionalField] + private bool m_position_fixed = false; + [OptionalField] + private int m_z_order; + + private static Color m_telop_default_color = Color.Black; + private static Font m_default_font; + + [Browsable(false)] + public int ZOrder { + get { + return m_z_order; + } + set { + m_z_order = value; + } + } + + public bool IsXFixedAt( float time ) { + float min, max; + if ( mc_x.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + public bool IsYFixedAt( float time ) { + float min, max; + if ( mc_y.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + /// + /// 描画オブジェクトの位置が固定されるかどうかを示す値を取得,または設定します + /// + public bool PositionFixed { + get { + return m_position_fixed; + } + set { + m_position_fixed = value; + } + } + + public static void DecideLane( List list ) { + if ( list.Count <= 0 ) { + AppManager.MaxTelopLanes = 0; + return; + } + list.Sort(); + list[0].Lane = 0; + int max = 0; + for ( int i = 1; i < list.Count; i++ ) { + int decided_lane = 0; + for ( int index = 0; index < int.MaxValue; index++ ) { + decided_lane = index; + int count = 0; + for ( int j = 0; j < i; j++ ) { + if ( list[j].Lane == index ){ + if ( Boare.Lib.AppUtil.Misc.IsOverwrapped( list[i].Start, list[i].End, list[j].Start, list[j].End ) ) { + count++; + break; + } + } + } + if ( count == 0 ) { + break; + } + } + max = Math.Max( max, decided_lane ); + list[i].Lane = decided_lane; + } + AppManager.MaxTelopLanes = max + 1; + } + + [Browsable(false)] + public int ID { + get { + return m_id; + } + } + + public PointF GetPosition( float time ) { + return new PointF( mc_x.GetValue( time ), mc_y.GetValue( time ) ); + } + + public float GetScale( float time ) { + return mc_scale.GetValue( time ); + } + + public float GetAlpha( float time ) { + float a = mc_alpha.GetValue( time ); + if ( a > 1f ) { + a = 1f; + } else if ( a < 0f ) { + a = 0f; + } + return a; + } + + public float GetRotate( float time ) { + float r = mc_rotate.GetValue( time ); + if ( r > 360f ) { + r = r % 360f; + } else if ( r < 0f ) { + r = r % 360f + 360f; + } + return r; + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { + if ( mc_x == null ) { + mc_x = new BezierChain( Common.CURVE_X ); + mc_x.Default = m_position.X; + } + if ( mc_y == null ) { + mc_y = new BezierChain( Common.CURVE_Y ); + mc_y.Default = m_position.Y; + } + if ( mc_scale == null ) { + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = 1f; + } + if ( mc_alpha == null ) { + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = m_alpha; + } + if ( mc_rotate == null ) { + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + } + mc_x.Color = Common.CURVE_X; + mc_y.Color = Common.CURVE_Y; + mc_scale.Color = Common.CURVE_SCALE; + mc_alpha.Color = Common.CURVE_ALPHA; + if ( m_font != null ) { + m_size = Boare.Lib.AppUtil.Misc.MeasureString( m_text, m_font ); + } + } + + public Telop( int id ) { + mc_x = new BezierChain( Common.CURVE_X ); + mc_y = new BezierChain( Common.CURVE_Y ); + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = 1f; + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = 1f; + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + if ( m_default_font != null ) { + m_font = (Font)m_default_font.Clone(); + } else { + m_default_font = new Font( "MS UI Gothic", 18 ); + m_font = (Font)m_default_font.Clone(); + } + m_size = Boare.Lib.AppUtil.Misc.MeasureString( m_text, m_font ); + m_id = id; + m_fore_color = m_telop_default_color; + } + + [Browsable( false )] + public object Tag { + get { + return m_tag; + } + set { + m_tag = value; + } + } + + public float FadeInSpan { + get { + return m_fadein_ratio; + } + set { + m_fadein_ratio = value; + if ( m_fadein_ratio <= 0f ) { + m_fadein_ratio = 1f; + m_fadein = false; + } + } + } + + public float FadeOutSpan { + get { + return m_fadeout_ratio; + } + set { + m_fadeout_ratio = value; + if ( m_fadeout_ratio <= 0f ) { + m_fadeout_ratio = 1f; + m_fadeout = false; + } + } + + } + + [Browsable( false )] + public Size ImageSize { + get { + return m_size; + } + } + + public int CompareTo( Telop item ) { + if ( item.m_start < this.m_start ) { + return 1; + } else if ( item.m_start > this.m_start ) { + return -1; + } else { + if ( item.m_end > this.m_end ) { + return 1; + } else if ( item.m_end < this.m_end ) { + return -1; + } else { + if ( item.m_id < this.m_id ) { + return 1; + } else if ( item.m_id > this.m_id ) { + return -1; + } else { + return 0; + } + } + } + } + + [Browsable(false)] + public Point Position { + get { + return new Point( (int)mc_x.Default, (int)mc_y.Default ); + } + set { + mc_x.Default = value.X; + mc_y.Default = value.Y; + } + } + + public Position Location { + get { + return new Position( mc_x.Default, mc_y.Default ); + } + set { + mc_x.Default = value.X; + mc_y.Default = value.Y; + } + } + + public Color Color { + get { + return m_fore_color; + } + set { + m_fore_color = value; + m_telop_default_color = value; + } + } + + /// + /// IDを変更して実施するクローン + /// + /// + /// + public object Clone( int change_id ) { + Telop result = new Telop( change_id ); + result.m_text = this.m_text; + result.m_start = this.m_start; + result.m_end = this.m_end; + result.m_font = (Font)this.m_font.Clone(); + result.m_fadein = this.m_fadein; + result.m_fadeout = this.m_fadeout; + result.m_alpha = this.m_alpha; + result.m_position = this.m_position; + result.m_fore_color = this.m_fore_color; + result.m_fadein_ratio = this.m_fadein_ratio; + result.m_fadeout_ratio = this.m_fadeout_ratio; + result.mc_alpha = (BezierChain)this.mc_alpha.Clone(); + result.mc_rotate = (BezierChain)this.mc_rotate.Clone(); + result.mc_scale = (BezierChain)this.mc_scale.Clone(); + result.mc_x = (BezierChain)this.mc_x.Clone(); + result.mc_y = (BezierChain)this.mc_y.Clone(); + result.Lane = this.Lane; + result.m_position_fixed = this.m_position_fixed; + result.m_size = this.m_size; + return result; + } + + /// + /// 通常のクローニング操作 + /// + /// + public object Clone() { + return this.Clone( m_id ); + } + + public string Text { + get { + return m_text; + } + set { + m_text = value; + if ( m_font != null ) { + m_size = Boare.Lib.AppUtil.Misc.MeasureString( this.m_text, this.m_font ); + } else { + m_size = new Size(); + } + } + } + + public float Start { + get { + return m_start; + } + set { + m_start = value; + } + } + + public float Length { + get { + return m_end - m_start; + } + set { + m_end = m_start + value; + } + } + + [Browsable(false)] + public float End { + get { + return m_end; + } + set { + m_end = value; + } + } + + public Font Font { + get { + return m_font; + } + set { + m_font = value; + m_default_font = (Font)m_font.Clone(); + if ( m_font != null ) { + m_size = Boare.Lib.AppUtil.Misc.MeasureString( m_text, m_font ); + } else { + m_size = new Size(); + } + } + } + + public bool FadeIn { + get { + return m_fadein; + } + set { + m_fadein = value; + } + } + + public bool FadeOut { + get { + return m_fadeout; + } + set { + m_fadeout = value; + } + } + + public float Alpha { + get { + return m_alpha; + } + set { + if ( value > 1.0f ) { + m_alpha = 1.0f; + } else if ( value < 0.0f ) { + m_alpha = 0.0f; + } else { + m_alpha = value; + } + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeSig.cs b/trunk/LipSync/LipSync/Editor/TimeSig.cs new file mode 100644 index 0000000..8c968c3 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeSig.cs @@ -0,0 +1,50 @@ +/* + * TimeSig.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + /// + /// 旧バージョン用。現在は使われていない。 + /// + [Serializable, Obsolete] + public class TimeSig { + public TimeSigType Type; + /// + /// 拍子・またはテンポが変更される時間位置 + /// + public float Start; + /// + /// 拍子変更後の4分音符の長さ + /// + public float Length; + /// + /// 拍子の分母 + /// + public int Denominator; + /// + /// 拍子の分子 + /// + public int Numerator; + + public TimeSig( TimeSigType type, float start, float length, int denominator, int numerator ) { + Type = type; + Start = start; + Length = length; + Denominator = denominator; + Numerator = numerator; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeSigType.cs b/trunk/LipSync/LipSync/Editor/TimeSigType.cs new file mode 100644 index 0000000..44a6d94 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeSigType.cs @@ -0,0 +1,27 @@ +/* + * TimeSigType.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + /// + /// 旧バージョン用。 + /// + [Obsolete] + public enum TimeSigType { + Tempo, + TimeSig, + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeTable/TimeTable.cs b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTable.cs new file mode 100644 index 0000000..4bb3331 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTable.cs @@ -0,0 +1,538 @@ +/* + * TimeTable.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.IO; +using System.Runtime.Serialization; + +using CurveEditor; + +namespace LipSync { + + [Serializable] + public class TimeTable : IDisposable, ICloneable, IDrawObject { + private List list; + private string stringValue; + private int type; + [Obsolete] + private Image image; + private Point position; + private int intValue; + private int m_zOrder; + private float scale; + [OptionalField] + public BezierChain mc_x; + [OptionalField] + public BezierChain mc_y; + [OptionalField] + public BezierChain mc_scale; + [OptionalField] + public BezierChain mc_alpha; + [OptionalField] + public BezierChain mc_rotate; + /// + /// aviをはっつけるモード + /// + [OptionalField] + private bool m_avi_mode = false; + [OptionalField] + private string m_avi_config = ""; + [NonSerialized] + private AviReaderEx m_avi_reader; + [NonSerialized] + private bool m_avi_reader_opened = false; + [OptionalField] + private bool m_position_fixed = false; + [OptionalField] + private Bitmap m_image; + + /// + /// aviファイルのOpen時に許される失敗回数 + /// + const int THRESHOLD_FAILED = 10; + + public bool IsXFixedAt( float time ) { + float min, max; + if ( mc_x.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + public bool IsYFixedAt( float time ) { + float min, max; + if ( mc_y.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + /// + /// 描画オブジェクトの位置が固定されるかどうかを示す値を取得,または設定します + /// + public bool PositionFixed { + get { + return m_position_fixed; + } + set { + m_position_fixed = value; + } + } + + [Browsable(false)] + public Size ImageSize { + get { + if ( m_avi_mode ) { + if ( m_avi_reader.Opened ) { + return m_avi_reader.BitmapSize; + } + } else { + if ( m_image != null ) { + return m_image.Size; + } + } + return new Size(); + } + } + + public string GetAviPath() { + if ( !m_avi_mode ) { + return ""; + } else { + string[] spl = m_avi_config.Split( "\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); + if ( spl.Length > 0 ) { + return spl[0]; + } else { + return ""; + } + } + } + + [Browsable(false)] + public string AviConfig { + get { + return m_avi_config; + } + } + + [Browsable(false)] + public bool IsAviMode { + get { + return m_avi_mode; + } + } + + public void SetAvi( string avi_config ) { + m_avi_mode = true; + m_avi_config = avi_config; + string avi_file = GetAviPath(); + /*if ( m_bmp != null ) { + m_bmp = null; //.Dispose(); + }*/ + if ( m_avi_reader != null ) { + if ( m_avi_reader.Opened ) { + m_avi_reader.Close(); + m_avi_reader = null; + m_avi_reader = new AviReaderEx(); + } + } else { + m_avi_reader = new AviReaderEx(); + } + if ( m_avi_reader.NumFailed < THRESHOLD_FAILED ) { + if ( File.Exists( avi_file ) ) { + m_avi_reader.Open( avi_file ); + m_avi_reader_opened = true; +#if DEBUG + Common.DebugWriteLine( "TimeTable.SetAvi; avi_file exists" ); +#endif + } + } + } + + public void SetImage( Image img ) { + /*if ( m_bmp != null ) { + //m_bmp.Dispose(); + m_bmp = null; + }*/ +#if DEBUG + Common.DebugWriteLine( "TimeTable.SetImage; before clone from argument \"img\"" ); + try { + int i = image.Width; + } catch { + } +#endif + if ( img != null ) { + m_image = new Bitmap( img ); + } +#if DEBUG + Common.DebugWriteLine( "TimeTable.SetImage; after cloned from argument \"img\"" ); + try { + int i = image.Width; + } catch { + } +#endif + m_avi_mode = false; + if ( m_avi_reader_opened ) { + if ( m_avi_reader.Opened ) { + m_avi_reader.Close(); + } + m_avi_reader_opened = false; + } + } + + public Bitmap GetImage( float time ) { +#if DEBUG + Common.DebugWriteLine( "TimeTable.GetImage(float); m_avi_mode=" + m_avi_mode ); +#endif + if ( m_avi_mode ) { +#if DEBUG + Common.DebugWriteLine( "TimeTable.GetImage(float); m_avi_reader_opened=" + m_avi_reader_opened ); +#endif + if ( !m_avi_reader_opened ) { + if ( m_avi_reader == null ) { + m_avi_reader = new AviReaderEx(); + } + if ( File.Exists( GetAviPath() ) ) { + try { + m_avi_reader.Open( GetAviPath() ); + m_avi_reader_opened = m_avi_reader.Opened; + } catch { + + } + } + } + if ( m_avi_reader_opened ) { + bool found = false; + float dt = 0f; + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].begin <= time && time <= list[i].end ) { + dt = time - list[i].begin; + found = true; + break; + } + } +#if DEBUG + Common.DebugWriteLine( "TimeTable.GetImage(float); found=" + found ); +#endif + if ( found ) { + int frame = (int)((double)m_avi_reader.dwRate / (double)m_avi_reader.dwScale * dt); + if ( 0 <= frame && frame < m_avi_reader.CountFrames ) { + return m_avi_reader.Export( frame ); + } + } + } + return null; + } else { + if ( m_image != null ) { + return m_image; + } else { + return null; + } + } + } + + public PointF GetPosition( float time ) { + return new PointF( mc_x.GetValue( time ), mc_y.GetValue( time ) ); + } + + public float GetScale( float time ) { + return mc_scale.GetValue( time ); + } + + public float GetAlpha( float time ) { + float a = mc_alpha.GetValue( time ); + if ( a > 1f ) { + a = 1f; + } else if ( a < 0f ) { + a = 0f; + } + return a; + } + + public float GetRotate( float time ) { + float r = mc_rotate.GetValue( time ); + if ( r > 360f ) { + r = r % 360f; + } else if ( r < 0f ) { + r = r % 360f + 360f; + } + return r; + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { + if ( type == 3 ) { + type = (int)TimeTableType.character; + } + + if ( mc_x == null ) { + mc_x = new BezierChain( Common.CURVE_X ); + mc_x.Default = position.X; + } + if ( mc_y == null ) { + mc_y = new BezierChain( Common.CURVE_Y ); + mc_y.Default = position.Y; + } + if ( mc_scale == null ) { + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = scale; + } + if ( mc_alpha == null ) { + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = 1.0f; + } + if ( mc_rotate == null ) { + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + } + mc_x.Color = Common.CURVE_X; + mc_y.Color = Common.CURVE_Y; + mc_scale.Color = Common.CURVE_SCALE; + mc_alpha.Color = Common.CURVE_ALPHA; + if ( image != null ) { + m_image = new Bitmap( image ); + image.Dispose(); + } + } + + public float Scale { + get { + return mc_scale.Default; + } + set { + mc_scale.Default = value; + } + } + + /// + /// 時刻nowにOnとなっているエントリが存在するかどうかを判定します + /// + /// + /// + public bool IsOn( float now ) { + foreach ( TimeTableEntry entry in list ) { + if ( entry.begin <= now && now <= entry.end ) { + return true; + } + } + return false; + } + + public void Dispose() { + if ( list != null ) { + list.Clear(); + } + if ( image != null ) { + image.Dispose(); + } + if ( m_image != null ) { + m_image.Dispose(); + } + if ( mc_x != null ) { + mc_x.Dispose(); + } + if ( mc_y != null ) { + mc_y.Dispose(); + } + if ( mc_alpha != null ) { + mc_alpha.Dispose(); + } + if ( mc_rotate != null ) { + mc_rotate.Dispose(); + } + if ( mc_scale != null ) { + mc_scale.Dispose(); + } + if ( m_avi_reader != null ) { + if ( m_avi_reader.Opened ) { + m_avi_reader.Close(); + } + } + } + + public void Remove( TimeTableEntry item ) { + int index = -1; + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].begin == item.begin && list[i].end == item.end && list[i].body == item.body ) { + index = i; + break; + } + } + if ( index >= 0 ) { + list.RemoveAt( index ); + } + } + + public object Clone() { + TimeTable tmp = new TimeTable( stringValue, intValue, this.Type, m_image ); + for ( int i = 0; i < list.Count; i++ ) { + tmp.list.Add( (TimeTableEntry)list[i].Clone() ); + } + tmp.position = position; + tmp.intValue = intValue; + tmp.m_zOrder = m_zOrder; + tmp.scale = scale; + tmp.mc_alpha = (BezierChain)this.mc_alpha.Clone(); + tmp.mc_rotate = (BezierChain)this.mc_rotate.Clone(); + tmp.mc_scale = (BezierChain)this.mc_scale.Clone(); + tmp.mc_x = (BezierChain)this.mc_x.Clone(); + tmp.mc_y = (BezierChain)this.mc_y.Clone(); + tmp.m_avi_config = this.m_avi_config; + tmp.m_avi_mode = this.m_avi_mode; + tmp.m_avi_reader = new AviReaderEx(); + tmp.m_avi_reader_opened = false; + tmp.m_position_fixed = this.m_position_fixed; + return tmp; + } + + [Browsable(false)] + public TimeTableType Type { + get { + foreach ( TimeTableType t in Enum.GetValues( System.Type.GetType( "LipSync.TimeTableType" ) ) ) { + if ( (int)t == type ) { + return t; + } + } + return TimeTableType.none; + } + set { + type = (int)value; + } + } + + public void Sort() { + list.Sort(); + } + + public void RemoveAt( int entry ) { + list.RemoveAt( entry ); + } + + public TimeTable( string stringValue, int intValue, TimeTableType type, Bitmap image ) + : this( stringValue, intValue, type, image, 1f ) { + } + + public TimeTable( string stringValue, int intValue, TimeTableType type, Bitmap img, float scale ) { + this.list = new List(); + this.stringValue = stringValue; + this.type = (int)type; + if ( img != null ) { + m_image =(Bitmap)img.Clone(); + } else { + m_image = null; + } + this.intValue = intValue; + this.position = new Point( 0, 0 ); + this.scale = scale; + this.m_zOrder = 0; + mc_x = new BezierChain( Common.CURVE_X ); + mc_y = new BezierChain( Common.CURVE_Y ); + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = 1f; + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = 1f; + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + m_avi_reader = new AviReaderEx(); + m_avi_reader_opened = false; + } + + [Browsable(false)] + public int ZOrder { + get { + return m_zOrder; + } + set { + m_zOrder = value; + } + } + + [Browsable(false)] + public int Value { + get { + return intValue; + } + set { + intValue = value; + } + } + + public string Text { + get { + return stringValue; + } + set { + stringValue = value; + } + } + + [Browsable(false)] + public Bitmap Image { + get { + return m_image; + } + } + + [Browsable(false)] + public int Count { + get { + return list.Count; + } + } + + public void Clear() { + list.Clear(); + } + + [Browsable(false)] + public TimeTableEntry this[int entry] { + get { + return list[entry]; + } + set { + list[entry] = (TimeTableEntry)value; + } + } + + public void Add( TimeTableEntry entry ) { + list.Add( entry ); + } + + [Browsable(false)] + public Point Position { + get { + return new Point( (int)mc_x.Default, (int)mc_y.Default ); + } + set { + mc_x.Default = value.X; + mc_y.Default = value.Y; + } + } + + public Position Location { + get { + return new Position( mc_x.Default, mc_y.Default ); + } + set { + mc_x.Default = value.X; + mc_y.Default = value.Y; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableEntry.cs b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableEntry.cs new file mode 100644 index 0000000..c8db695 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableEntry.cs @@ -0,0 +1,70 @@ +/* + * TimeTableEntry.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + [Serializable] + public class TimeTableEntry : IComparable, IDisposable, ICloneable { + public float begin; + public float end; + public string body; + + public TimeTableEntry() { + begin = 0.0f; + end = 0.0f; + body = ""; + } + + public float Length { + get { + return end - begin; + } + } + + public void Dispose() { + this.body = null; + } + + public object Clone() { + return new TimeTableEntry( begin, end, body ); + } + + public int CompareTo( TimeTableEntry obj ) { + double diff = this.begin - obj.begin; + if ( this.begin == obj.begin ) { + return 0; + } else if ( diff > 0.0f ) { + return 1; + } else { + return -1; + } + } + + public bool Equals( TimeTableEntry obj ) { + if ( this.begin == obj.begin ) { + return true; + } else { + return false; + } + } + + public TimeTableEntry( float begin, float end, string body ) { + this.begin = begin; + this.end = end; + this.body = body; + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableGroup.cs b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableGroup.cs new file mode 100644 index 0000000..e34e250 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableGroup.cs @@ -0,0 +1,1087 @@ +/* + * TimeTableGroup.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Runtime.Serialization; +using System.Windows.Forms; + +using CurveEditor; + +namespace LipSync { + + /// + /// TimeTableをグループ化して取り扱うためのクラス + /// + [Serializable] + public class TimeTableGroup : IDisposable, ICloneable, IDrawObject { + [Obsolete] + private Character m_character; + internal List list; + private string m_Text; + private int m_intValue; + [Obsolete] + private Point position; + private int m_zOrder; + [Obsolete] + private float scale; + [OptionalField] + private bool folded; + [OptionalField] + public BezierChain mc_x; + [OptionalField] + public BezierChain mc_y; + [OptionalField] + public BezierChain mc_scale; + [OptionalField] + public BezierChain mc_alpha; + [OptionalField] + public BezierChain mc_rotate; + [OptionalField] + private Character3 m_character3; + [OptionalField] + private string m_character_path; + [OptionalField] + private bool m_position_fixed = false; + + public Size ImageSize { + get { + if ( m_character3 != null ) { + return m_character3.Size; + } else { + return new Size(); + } + } + } + + public bool IsXFixedAt( float time ) { + float min, max; + if ( mc_x.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + public bool IsYFixedAt( float time ) { + float min, max; + if ( mc_y.GetKeyMinMax( out min, out max ) ) { + if ( min <= time && time <= max ) { + return true; + } + } + return false; + } + + /// + /// 描画オブジェクトの位置が固定されるかどうかを示す値を取得,または設定します + /// + public bool PositionFixed { + get { + return m_position_fixed; + } + set { + m_position_fixed = value; + } + } + + public static void GenerateLipSyncFromVsq( + TimeTable a_time_table, + ref TimeTableGroup temp, + Character3 character, + float total_sec, + bool close_mouth_when_same_vowel_repeated, + float frame_rate, + float combine_threshold ) + { + TimeTable time_table = (TimeTable)a_time_table.Clone(); + for ( int i = 0; i < time_table.Count - 1; i++ ) { + if ( time_table[i + 1].begin - time_table[i].end <= combine_threshold ) { + time_table[i].end = time_table[i + 1].begin; + } + } + const float CLOSE_LENGTH = 2.99f; + const float CLOSE_LENGTH_SHORT = 1.99f; + if ( time_table.Type != TimeTableType.vsq ) { + return; + } + + // 口パクの母音トラックを追加 + int base_image = -1; + for ( int k = 0; k < character.Count; k++ ) { + switch ( character[k].title ) { + case "a": + case "aa": + case "i": + case "u": + case "e": + case "o": + case "xo": + case "nn": + temp.Add( new TimeTable( character[k].title, 0, TimeTableType.character, null ) ); + break; + case "base": + temp.Add( new TimeTable( character[k].title, 0, TimeTableType.character, null ) ); + base_image = temp.Count - 1; + break; + default: + temp.Add( new TimeTable( character[k].title, 0, TimeTableType.character, null ) ); + break; + } + } + + float begin; + float end; + float last_end = -1f; + string body; + string lyric;//歌詞 + string phonetics;//発音記号 + VowelType last_vowel = VowelType.def; + for ( int entry = 0; entry < time_table.Count; entry++ ) { + #region エントリを追加 + begin = time_table[entry].begin; + end = time_table[entry].end; + body = time_table[entry].body; + string[] spl = body.Split( new char[] { '(' } ); + + phonetics = spl[1].Replace( ")", "" ); + lyric = spl[0].Replace( " ", "" ); + + VowelType type = VowelType.Attach( lyric ); + if ( entry > 0 && lyric == "ー" ) { + type = last_vowel; + } + if ( phonetics == "br1" || phonetics == "br2" || phonetics == "br3" || phonetics == "br4" || phonetics == "br5" ) { + type = VowelType.aa; + } + string separate = ""; + if ( type.Equals( VowelType.def ) ) { + // VowelType.Attachでは判定できなかったとき。 + MouthSet mouth_set = VowelType.AttachEx( phonetics ); + type = mouth_set.main; + separate = mouth_set.prep.ToString(); + if ( separate == "def" ) { + separate = ""; + } + } else { + switch ( lyric ) { + #region NN + //b + case "ば": + case "ぶ": + case "べ": + case "ぼ": + if ( VowelType.IsRegisteredToNN( "b" ) ) { + separate = "nn"; + } + break; + //p + case "ぱ": + case "ぷ": + case "ぺ": + case "ぽ": + if ( VowelType.IsRegisteredToNN( "p" ) ) { + separate = "nn"; + } + break; + //m + case "ま": + case "む": + case "め": + case "も": + if ( VowelType.IsRegisteredToNN( "m" ) ) { + separate = "nn"; + } + break; + //b' + case "びゃ": + case "び": + case "びゅ": + case "びぇ": + case "びょ": + if ( VowelType.IsRegisteredToNN( "b'" ) ) { + separate = "nn"; + } + break; + //p' + case "ぴゃ": + case "ぴ": + case "ぴゅ": + case "ぴぇ": + case "ぴょ": + if ( VowelType.IsRegisteredToNN( "p'" ) ) { + separate = "nn"; + } + break; + //m' + case "みゃ": + case "み": + case "みゅ": + case "みぇ": + case "みょ": + if ( VowelType.IsRegisteredToNN( "m'" ) ) { + separate = "nn"; + } + break; + #endregion + + #region U + //p\ + case "ふぁ": + //case "ふ": + case "ふぇ": + case "ふぉ": + if ( VowelType.IsRegisteredToU( @"p\" ) ) { + separate = "u"; + } + break; + //p\' + case "ふぃ": + case "ふゅ": + if ( VowelType.IsRegisteredToU( @"p\'" ) ) { + separate = "u"; + } + break; + //w + case "わ": + case "うぃ": + case "うぇ": + //case "を": + case "うぉ": + if ( VowelType.IsRegisteredToU( "w" ) ) { + separate = "u"; + } + break; + //ts + case "つぁ": + case "つぃ": + //case "つ": + case "つぇ": + case "つぉ": + if ( VowelType.IsRegisteredToU( "ts" ) ) { + separate = "u"; + } + break; + //dz + case "づぁ": + case "づぃ": + //case "づ": + case "づぇ": + case "づぉ": + if ( VowelType.IsRegisteredToU( "dz" ) ) { + separate = "u"; + } + break; + #endregion + + #region I + //k' + case "きゃ": + //case "き": + case "きゅ": + case "きょ": + if ( VowelType.IsRegisteredToI( "k'" ) ) { + separate = "i"; + } + break; + //g' + case "ぎゃ": + //case "ぎ": + case "ぎゅ": + case "ぎょ": + if ( VowelType.IsRegisteredToI( "g'" ) ) { + separate = "i"; + } + break; + //S + case "しゃ": + //case "し": + case "しゅ": + case "しぇ": + case "しょ": + if ( VowelType.IsRegisteredToI( "S" ) ) { + separate = "i"; + } + break; + //dZ + //case "ぢ": + case "ぢゅ": + case "ぢぇ": + case "ぢょ": + if ( VowelType.IsRegisteredToI( "dZ" ) ) { + separate = "i"; + } + break; + //tS + case "ちゃ": + //case "ち": + case "ちゅ": + case "ちぇ": + case "ちょ": + if ( VowelType.IsRegisteredToI( "tS" ) ) { + separate = "i"; + } + break; + //J + case "にゃ": + //case "に": + case "にゅ": + case "にぇ": + case "にょ": + if ( VowelType.IsRegisteredToI( "J" ) ) { + separate = "i"; + } + break; + //C + case "ひゃ": + //case "ひ": + case "ひゅ": + case "ひぇ": + case "ひょ": + if ( VowelType.IsRegisteredToI( "C" ) ) { + separate = "i"; + } + break; + // another + case "いぇ": + separate = "i"; + break; + #endregion + } + } + + bool mode_sp = false; + if ( close_mouth_when_same_vowel_repeated ) { + // 母音が連続する場合を検出 + if ( separate == "" && begin == last_end && last_vowel.Equals( type ) && lyric != "ー" ) { + if ( type.Equals( VowelType.a ) ) { + if ( lyric != "あ" && !phonetics.StartsWith( "a" ) ) { + separate = "nn"; + mode_sp = true; + } + } else if ( type.Equals( VowelType.i ) ) { + if ( lyric != "い" && !phonetics.StartsWith( "i" ) ) { + separate = "nn"; + mode_sp = true; + } + } else if ( type.Equals( VowelType.u ) ) { + if ( lyric != "う" && !phonetics.StartsWith( "u" ) ) { + separate = "nn"; + mode_sp = true; + } + } else if ( type.Equals( VowelType.e ) ) { + if ( lyric != "え" && !phonetics.StartsWith( "e" ) ) { + separate = "nn"; + mode_sp = true; + } + } else if ( type.Equals( VowelType.o ) ) { + if ( lyric != "お" && !phonetics.StartsWith( "o" ) ) { + separate = "nn"; + mode_sp = true; + } + } + } + } + + last_end = end; + last_vowel = type; + + if ( separate != "" ) { + float total = end - begin; + float tmp_begin = begin; + float tmp_end; + float close_length; + if ( mode_sp ) { + close_length = CLOSE_LENGTH_SHORT; + } else { + close_length = CLOSE_LENGTH; + } + if ( total > 2f * close_length / frame_rate ) { + //エントリの長さが、十分長い場合 + tmp_end = begin + close_length / frame_rate; + } else { + tmp_end = begin + total / 2f; + } + begin = tmp_end; + //for ( int base_track = 0; base_track < s.m_groups_character[mouth_group].Count; base_track++ ) { + for ( int base_track = 0; base_track < temp.Count; base_track++ ) { + if ( temp[base_track].Text == separate ) { + //temp[base_track].Add( new TimeTableEntry( tmp_begin, tmp_end, separate ) ); + temp.Interrup( base_track, tmp_begin, tmp_end ); + break; + } + } + } + for ( int base_track = 0; base_track < temp.Count; base_track++ ) { + if ( temp[base_track].Text == type.ToString() ) { + //temp[base_track].Add( new TimeTableEntry( begin, end, type.ToString() ) ); + temp.Interrup( base_track, begin, end ); + break; + } + } + #endregion + } + + // 連続しているやつがあればマージする + bool change = true; + while ( change ) { + change = false; + for ( int track = 0; track < temp.Count; track++ ) { + for ( int entry = 0; entry < temp[track].Count - 1; entry++ ) { + if ( temp[track][entry].body == temp[track][entry + 1].body && temp[track][entry].end == temp[track][entry + 1].begin ) { + temp[track][entry].end = temp[track][entry + 1].end; + temp[track].RemoveAt( entry + 1 ); + change = true; + break; + } + } + } + } + + // is_defaultな画像用のエントリを追加 + for ( int k = 0; k < character.Count; k++ ) { + if ( character[k].IsDefault ) { + temp.Fill( k, total_sec ); + } + } + + } + + /// + /// 画面上に表示されるトラックの数 + /// + [Browsable(false)] + public int VisibleTracks { + get { + if ( folded ) { + return 0; + } else { + return list.Count; + } + } + } + + /// + /// 第track番目のトラックの、最初のエントリのON時刻を返します。エントリが未だ無い場合、負の値を返します + /// + /// + /// + public float GetFirstOn( int track ) { + if ( list[track].Count > 0 ) { + return list[track][0].begin; + } else { + return -1f; + } + } + + public float GetFirstOn() { + if ( list.Count > 0 ) { + float[] first = new float[list.Count]; + for ( int i = 0; i < list.Count; i++ ) { + if ( list[i].Count > 0 ) { + first[i] = list[i][0].begin; + } else { + first[i] = -1f; + } + } + float res = float.MaxValue; + foreach ( float val in first ) { + if ( val >= 0f ) { + res = Math.Min( res, val ); + } + } + if ( res == float.MaxValue ) { + return -1f; + } else { + return res; + } + } else { + return -1f; + } + } + + [Browsable(false)] + public Character3 Character { + get { + return m_character3; + } + set { + m_character3 = value; + } + } + + /// + /// 指定した時刻における、このオブジェクトの位置を取得します + /// + /// + /// + public PointF GetPosition( float time ) { + return new PointF( mc_x.GetValue( time ), mc_y.GetValue( time ) ); + } + + /// + /// 指定した時刻における、このオブジェクトのスケールを取得します + /// + /// + /// + public float GetScale( float time ) { + return mc_scale.GetValue( time ); + } + + /// + /// 指定した時刻における、このオブジェクトのアルファ値を取得します + /// + /// + /// + public float GetAlpha( float time ) { + float a = mc_alpha.GetValue( time ); + if( a > 1f ) { + a = 1f; + } else if( a < 0f ) { + a = 0f; + } + return a; + } + + /// + /// 指定した時刻における、このオブジェクトの回転角度を取得します + /// + /// + /// + public float GetRotate( float time ) { + float r = mc_rotate.GetValue( time ); + if( r > 360f ) { + r = r % 360f; + } else if( r < 0f ) { + r = r % 360f + 360f; + } + return r; + } + + [OnDeserializing] + private void onDeserializing( StreamingContext sc ) { + folded = false; + } + + [OnDeserialized] + private void onDeserialized( StreamingContext sc ) { +#if DEBUG + Console.WriteLine( "TimeTableGroup.onDeserialized(StreamingContext)" ); +#endif + if( mc_x == null ) { + mc_x = new BezierChain( Common.CURVE_X ); + mc_x.Default = position.X; + } + if( mc_y == null ) { + mc_y = new BezierChain( Common.CURVE_Y ); + mc_y.Default = position.Y; + } + if( mc_scale == null ) { + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = scale; + } + if( mc_alpha == null ) { + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = 1.0f; + } + if( mc_rotate == null ) { + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + } + mc_x.Color = Common.CURVE_X; + mc_y.Color = Common.CURVE_Y; + mc_scale.Color = Common.CURVE_SCALE; + mc_alpha.Color = Common.CURVE_ALPHA; +#if DEBUG + Common.DebugWriteLine( "TimeTableGroup.onDeserialized; (m_character==null);" + (m_character == null) ); +#endif + if( m_character != null ) { + m_character3 = new Character3( m_character ); + m_character.Dispose(); + m_character = null; + } + if ( list != null ) { + if ( list.Count > 0 ) { + if ( list[0].Type == TimeTableType.character && m_character3 != null ) { + List buf = new List(); + for ( int i = 0; i < list.Count; i++ ) { + buf.Add( (TimeTable)list[i].Clone() ); + } + list.Clear(); + for ( int i = 0; i < m_character3.Count; i++ ) { + for ( int j = 0; j < buf.Count; j++ ) { + if ( buf[j].Text == m_character3[i].title ) { + list.Add( buf[j] ); + } + } + } + } + } + } + } + + public void Dispose() { + if( m_character != null ) { + m_character.Dispose(); + } + if( list != null ) { + list.Clear(); + } + } + + public void Fill( int target, float total_sec ) { + string title = list[target].Text; + string tag = m_character3[title].tag; + + //同じタグを持つタイムテーブルのインデクスを列挙 + List same_tag = new List(); + for( int i = 0; i < list.Count; i++ ) { + if( i != target ) { + string t_title = list[i].Text; + string t_tag = m_character3[t_title].tag; + if( t_tag == tag ) { + same_tag.Add( i ); + } + } + } + list[target].Clear(); + if( same_tag.Count == 0 || tag == "" ) { + list[target].Add( new TimeTableEntry( 0f, total_sec, title ) ); + return; + } + + //まず開始時間の中から一番速いエントリを探す + float min = float.MaxValue; + int track_of_min = -1; + foreach( int index in same_tag ) { + if( list[index].Count > 0 ) { + min = Math.Min( min, list[index][0].begin ); + track_of_min = index; + } + } + if( track_of_min < 0 ) { + // 排他のかかるタグはあるが、そのうちのいづれにもまだエントリが含まれていない場合 + list[target].Add( new TimeTableEntry( 0f, total_sec, title ) ); + return; + } +#if DEBUG + MessageBox.Show( "min=" + min ); +#endif + + if( min != 0f ) { + list[target].Add( new TimeTableEntry( 0f, min, title ) ); + list[target].Sort(); + } + + bool added = true; + while( added ) { + added = false; + // 終了時刻がminより後で、かつ開始時刻がminと同じか速いが無いかどうか検索 + bool found = true; + while( found ) { + found = false; + foreach( int index in same_tag ) { + for( int entry = 0; entry < list[index].Count; entry++ ) { + if( list[index][entry].end > min && list[index][entry].begin <= min ) { + found = true; + //track_of_min = index; + //entry_of_min = entry; + min = list[index][entry].end; + break; + } + } + if( found ) { + break; + } + } + } + + // 新しいminを検索 + float begin = min; + + // 開始時刻がbeginより後のエントリのうち一番早いものを検索 + min = float.MaxValue; + found = false; + foreach( int index in same_tag ) { + for( int entry = 0; entry < list[index].Count; entry++ ) { + if( begin < list[index][entry].begin ) { + min = Math.Min( min, list[index][entry].begin ); + //track_of_min = index; + //entry_of_min = entry; + found = true; + break; + } + } + } + + float end; + if( found ) { + end = min; + added = true; + } else { + end = total_sec; + } + + list[target].Add( new TimeTableEntry( begin, end, title ) ); +#if DEBUG + Common.DebugWriteLine( "" + (end - begin) ); +#endif + list[target].Sort(); + + } + } + + /// + /// 指定したTimeTableGroupの、第track番目のTimeTableに、エントリitemを割り込ませます + /// 排他制御がかかる場合は、挿入されたitem以外の部分が削られます + /// Undo, redo用の処理は、この関数の呼び出し元で行われる + /// + /// + /// + /// + public void Interrup( int target, float t1, float t2 ) { + InterrupCore( target, t1, t2, "", false ); + } + + public void Interrup( int target, float t1, float t2, string str ) { + InterrupCore( target, t1, t2, str, true ); + } + + private void InterrupCore( int target, float t1, float t2, string str, bool body_specified ) { + if( target < 0 ) { + return; + } + + float begin, end; + if( t1 > t2 ) { + begin = t2; + end = t1; + } else if( t2 > t1 ) { + begin = t1; + end = t2; + } else { + return; + } + + string title; + if( body_specified ) { + title = str; + } else { + title = list[target].Text; + } + using( TimeTableEntry item = new TimeTableEntry( begin, end, title ) ) { + + // タグが設定されているか? + string tag;// = ""; + if( m_character3 != null ) { + tag = m_character3[title].tag; + } else { + tag = ""; + } + + trimToInterrup( target, item ); + + // タグ設定がある場合。排他のかかるほかのエントリも調節 + if( tag != "" ) { + for( int track = 0; track < list.Count; track++ ) { + if( track != target ) { + string this_tag = m_character3[list[track].Text].tag; + if( this_tag == tag ) { + trimToInterrup( track, item ); + } + } + } + } + + list[target].Add( (TimeTableEntry)item.Clone() ); + list[target].Sort(); + } + } + + private void trimToInterrup( int track, TimeTableEntry item ) { + // 割り込み対象のタイムテーブルでかぶっているエントリを調節 + bool changed = true; + while( changed ) { + changed = false; + for( int entry = 0; entry < list[track].Count; entry++ ) { + float list_begin = list[track][entry].begin; + float list_end = list[track][entry].end; + if( item.begin <= list_begin && list_begin < item.end && item.end < list_end ) { + // list : [***********] + // item : [*****] + // ↓↓結果 + // list : [*****][*******] + list[track][entry].begin = item.end; + changed = true; + break; + } else if( item.begin <= list_begin && list_end <= item.end/*item.begin < list_begin && list_begin <= item.end && list_end <= item.end*/ ) { + // list : [***********] + // item : [*****************] + // ↓↓結果 + // list : [*****************] + list[track].RemoveAt( entry ); + changed = true; + break; + } else if( list_begin < item.begin && item.begin < list_end && item.end < list_end ) { + // list : [***********] + // item : [*****] + // ↓↓結果 + // list : [*][*****][*] + float old_end = list[track][entry].end; + list[track][entry].end = item.begin; + list[track].Add( new TimeTableEntry( item.end, old_end, list[track][entry].body ) ); + list[track].Sort(); + changed = true; + break; + } else if( list_begin < item.begin && item.begin < list_end && list_end < item.end ) { + // list : [***********] + // item : [***********] + // ↓↓結果 + // list : [*][***********] + list[track][entry].end = item.begin; + changed = true; + break; + } else if( Math.Abs( list_begin - item.begin ) <= float.Epsilon && Math.Abs( list_end - item.end ) <= float.Epsilon ) { + // list : [***********] + // item : [***********] + // ↓↓結果 + // list : [***********] + list[track].RemoveAt( entry ); + changed = true; + break; + } + } + } + } + + /// + /// このタイムテーブルグループの、時刻timeの時点でONとなっているエントリ名 + /// のリストを、\n区切りの文字列で返します + /// + /// + /// + public string[] GetDrawObjectNames( float time ) { + List draw = new List(); + for( int track = 0; track < list.Count; track++ ) { + int start_entry = list[track].Value; + for( int entry = start_entry; entry < list[track].Count; entry++ ) { + if( list[track][entry].begin <= time && time <= list[track][entry].end ) { + draw.Add( list[track].Text ); + } + } + } + return draw.ToArray(); + } + + public int[] GetDrawObjectIndex( float time, string mouth ) { + string exclude_tag = ""; + if ( mouth.Length > 0 && m_character3 != null ) { + int index_of_mouth = m_character3[mouth].Z; + if ( index_of_mouth >= 0 ) { + exclude_tag = m_character3[index_of_mouth].tag; + } + } + List draw = new List(); + for( int track = 0; track < list.Count; track++ ) { + if ( exclude_tag.Length > 0 && m_character3 != null ) { + if ( m_character3[list[track].Text].tag == exclude_tag ) { + if ( m_character3[list[track].Text].title == mouth ) { + draw.Add( track ); + } + continue; + } + } + int start_entry = list[track].Value; + for( int entry = start_entry; entry < list[track].Count; entry++ ) { + if( list[track][entry].begin <= time && time < list[track][entry].end ) { + draw.Add( track ); + break; + } + } + } + return draw.ToArray(); + } + + /// + /// このタイムテーブルグループが、画面上で折りたたみ表示されているかどうかを表す値を取得または設定します + /// + [Browsable( false )] + public bool Folded { + get { + return folded; + } + set { + folded = value; + } + } + + /// + /// このタイムテーブルグループのデフォルトの表示スケールを取得または設定します + /// + public float Scale { + get { + return mc_scale.Default; + } + set { + mc_scale.Default = value; + } + } + + public void Insert( int index, TimeTable table ) { + list.Insert( index, table ); + } + + public object Clone() { + TimeTableGroup tmp = new TimeTableGroup( m_Text, m_intValue, m_character3 ); + for( int i = 0; i < list.Count; i++ ) { + tmp.list.Add( (TimeTable)list[i].Clone() ); + } + //tmp.position = position; + tmp.m_zOrder = m_zOrder; + //tmp.scale = scale; + tmp.folded = folded; + tmp.mc_alpha = (BezierChain)this.mc_alpha.Clone(); + tmp.mc_rotate = (BezierChain)this.mc_rotate.Clone(); + tmp.mc_scale = (BezierChain)this.mc_scale.Clone(); + tmp.mc_x = (BezierChain)this.mc_x.Clone(); + tmp.mc_y = (BezierChain)this.mc_y.Clone(); + tmp.m_position_fixed = this.m_position_fixed; + return tmp; + } + + /// + /// このタイムテーブルグループのZオーダーを取得または設定します + /// + [Browsable( false )] + public int ZOrder { + get { + return m_zOrder; + } + set { + m_zOrder = value; + } + } + + public void RemoveAt( int track ) { + list.RemoveAt( track ); + } + + /// + /// このタイムテーブルグループの表示位置を取得または設定します + /// + [Browsable( false )] + public Point Position { + get { + return new Point( (int)mc_x.Default, (int)mc_y.Default ); + } + set { + PointF t = value; + mc_x.Default = t.X; + mc_y.Default = t.Y; + } + } + + /// + /// このタイムテーブルグループの表示位置を取得または設定します。 + /// このプロパティはプロパティビューでの表示用です。 + /// + public Position Location { + get { + return new Position( mc_x.Default, mc_y.Default ); + } + set { + mc_x.Default = value.X; + mc_y.Default = value.Y; + } + } + + [Browsable( false )] + public int Value { + get { + return m_intValue; + } + set { + m_intValue = value; + } + } + + public string Text { + get { + return m_Text; + } + set { + m_Text = value; + } + } + + public void Clear() { + for( int i = 0; i < list.Count; i++ ) { + list[i].Clear(); + } + list.Clear(); + } + + [Browsable( false )] + public TimeTable this[int track] { + get { + return list[track]; + } + set { + list[track] = (TimeTable)value; + } + } + + public TimeTableGroup( string text, int value, Character3 character/*, Image baseImage*/ ) { + list = new List(); + m_Text = text; + /*m_baseImage = baseImage;*/ + if( character != null ) { + m_character3 = (Character3)character.Clone(); + } else { + m_character3 = null; + } + m_intValue = value; + //position = new Point( 0, 0 ); + m_zOrder = 0; + scale = 1.0f; + mc_x = new BezierChain( Common.CURVE_X ); + mc_y = new BezierChain( Common.CURVE_Y ); + mc_scale = new BezierChain( Common.CURVE_SCALE ); + mc_scale.Default = 1f; + mc_alpha = new BezierChain( Common.CURVE_ALPHA ); + mc_alpha.Default = 1f; + mc_rotate = new BezierChain( Common.CURVE_ROTATE ); + folded = false; + } + + + public void Add( TimeTable new_time_table ) { + list.Add( (TimeTable)new_time_table.Clone() ); + } + + [Browsable( false )] + public int Count { + get { + if( list != null ) { + return list.Count; + } else { + return 0; + } + } + } + + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableType.cs b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableType.cs new file mode 100644 index 0000000..0a32672 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TimeTable/TimeTableType.cs @@ -0,0 +1,27 @@ +/* + * TimeTableType.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + public enum TimeTableType { + vsq = 0, + another = 1, + character = 2, + plugin = 4, + none = 5, + top = 6, + telop = 7, + whole = 8, + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TrackSelecter.cs b/trunk/LipSync/LipSync/Editor/TrackSelecter.cs new file mode 100644 index 0000000..bc9d231 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TrackSelecter.cs @@ -0,0 +1,98 @@ +/* + * TrackSelecter.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class TrackSelecter : Form, IMultiLanguageControl { + public TrackSelecter( string file_name, string[] track_names ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + checkedListBox1.Items.Clear(); + for ( int i = 0; i < track_names.Length; i++ ) { + if ( track_names[i] != "Master Track" ) { + checkedListBox1.Items.Add( track_names[i], true ); + } else { + checkedListBox1.Items.Add( track_names[i], false ); + } + } + textBox1.Text = file_name; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.button1.Text = _( "Cancel" ); + this.button2.Text = _( "OK" ); + this.Text = _( "Select track" ); + this.checkImportTempoAndTimesig.Text = _( "import tempo and time-signal information" ); + } + + public string _( string s ) { + return Messaging.GetMessage( s ); + } + + public bool ImportTempoAndTimesig { + get { + return checkImportTempoAndTimesig.Checked; + } + set { + checkImportTempoAndTimesig.Checked = value; + } + } + + public int[] CheckedItem { + get { + int count = 0; + for ( int i = 0; i < checkedListBox1.Items.Count; i++ ) { + if ( checkedListBox1.GetItemChecked( i ) ) { + count++; + } + } + int[] list = new int[count]; + //MessageBox.Show( "count=" + count ); + count = -1; + for ( int i = 0; i < checkedListBox1.Items.Count; i++ ) { + //MessageBox.Show( "item no." + i + " GetItemChecked=" + checkedListBox1.GetItemChecked( i ) ); + if ( checkedListBox1.GetItemChecked( i ) ) { + count++; + list[count] = i; + } + } + return list; + } + } + + private void button2_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void button1_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/TrackSelecter.designer.cs b/trunk/LipSync/LipSync/Editor/TrackSelecter.designer.cs new file mode 100644 index 0000000..ed1654f --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/TrackSelecter.designer.cs @@ -0,0 +1,139 @@ +/* + * TrackSelecter.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class TrackSelecter { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.checkedListBox1 = new System.Windows.Forms.CheckedListBox(); + this.button1 = new System.Windows.Forms.Button(); + this.button2 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.Label(); + this.checkImportTempoAndTimesig = new System.Windows.Forms.CheckBox(); + this.SuspendLayout(); + // + // checkedListBox1 + // + this.checkedListBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.checkedListBox1.FormattingEnabled = true; + this.checkedListBox1.HorizontalScrollbar = true; + this.checkedListBox1.Items.AddRange( new object[] { + "a"} ); + this.checkedListBox1.Location = new System.Drawing.Point( 12, 68 ); + this.checkedListBox1.Name = "checkedListBox1"; + this.checkedListBox1.Size = new System.Drawing.Size( 264, 200 ); + this.checkedListBox1.TabIndex = 0; + // + // button1 + // + this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.button1.Location = new System.Drawing.Point( 201, 311 ); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size( 75, 23 ); + this.button1.TabIndex = 3; + this.button1.Text = "Cancel"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler( this.button1_Click ); + // + // button2 + // + this.button2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.button2.Location = new System.Drawing.Point( 100, 311 ); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size( 75, 23 ); + this.button2.TabIndex = 2; + this.button2.Text = "OK"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler( this.button2_Click ); + // + // textBox1 + // + this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.textBox1.Location = new System.Drawing.Point( 12, 9 ); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 264, 56 ); + this.textBox1.TabIndex = 4; + this.textBox1.Text = "file path"; + // + // checkImportTempoAndTimesig + // + this.checkImportTempoAndTimesig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkImportTempoAndTimesig.AutoSize = true; + this.checkImportTempoAndTimesig.Checked = true; + this.checkImportTempoAndTimesig.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkImportTempoAndTimesig.Location = new System.Drawing.Point( 14, 279 ); + this.checkImportTempoAndTimesig.Name = "checkImportTempoAndTimesig"; + this.checkImportTempoAndTimesig.Size = new System.Drawing.Size( 169, 16 ); + this.checkImportTempoAndTimesig.TabIndex = 1; + this.checkImportTempoAndTimesig.Text = "テンポと拍子の情報を取り込む"; + this.checkImportTempoAndTimesig.UseVisualStyleBackColor = true; + // + // TrackSelecter + // + this.AcceptButton = this.button2; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button1; + this.ClientSize = new System.Drawing.Size( 288, 346 ); + this.Controls.Add( this.checkImportTempoAndTimesig ); + this.Controls.Add( this.textBox1 ); + this.Controls.Add( this.button2 ); + this.Controls.Add( this.button1 ); + this.Controls.Add( this.checkedListBox1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "TrackSelecter"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "TrackSelecter"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.CheckedListBox checkedListBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Label textBox1; + private System.Windows.Forms.CheckBox checkImportTempoAndTimesig; + + } +} diff --git a/trunk/LipSync/LipSync/Editor/VersionBox.cs b/trunk/LipSync/LipSync/Editor/VersionBox.cs new file mode 100644 index 0000000..efd30a6 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/VersionBox.cs @@ -0,0 +1,44 @@ +/* + * VersionBox.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace LipSync { + + public partial class VersionBox : Form, IMultiLanguageControl { + public VersionBox( string title, string message ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + label1.Text = message; + this.Text = title; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + } + + private void button1_Click( object sender, EventArgs e ) { + this.Close(); + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/VersionBox.designer.cs b/trunk/LipSync/LipSync/Editor/VersionBox.designer.cs new file mode 100644 index 0000000..a2a71bb --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/VersionBox.designer.cs @@ -0,0 +1,89 @@ +/* + * VersionInfo.designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class VersionBox { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.label1 = new System.Windows.Forms.Label(); + this.button1 = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // label1 + // + this.label1.Font = new System.Drawing.Font( "Verdana", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)) ); + this.label1.Location = new System.Drawing.Point( 53, 9 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 212, 43 ); + this.label1.TabIndex = 0; + this.label1.Text = "Lip Sync version 0.0\r\nby kbinani"; + this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // button1 + // + this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.button1.Location = new System.Drawing.Point( 115, 60 ); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size( 83, 25 ); + this.button1.TabIndex = 1; + this.button1.Text = "OK"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler( this.button1_Click ); + // + // VersionBox + // + this.AcceptButton = this.button1; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.button1; + this.ClientSize = new System.Drawing.Size( 323, 111 ); + this.Controls.Add( this.button1 ); + this.Controls.Add( this.label1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "VersionBox"; + this.ShowInTaskbar = false; + this.Text = "VersionInfo"; + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button button1; + } +} \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Editor/VowelType.cs b/trunk/LipSync/LipSync/Editor/VowelType.cs new file mode 100644 index 0000000..f2f83da --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/VowelType.cs @@ -0,0 +1,552 @@ +/* + * VowelType.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace LipSync { + + public struct MouthSet { + public VowelType prep; + public VowelType main; + } + + /// + /// 口の形の種類を定義するクラス。javaぽい + /// + public struct VowelType { + public static List m_list_nn = new List( new string[] { "b", "p", "m", "b'", "p'", "m'" } ); + public static List m_list_i = new List( new string[] { "k'", "g'", "S", "dZ", "tS", "J", "C" } ); + public static List m_list_u = new List( new string[] { @"p\", @"p\'", "w", "ts", "dz" } ); + public static VowelType def = new VowelType( -1 ); + public static VowelType a = new VowelType( 0 ); + public static VowelType aa = new VowelType( 1 ); + public static VowelType i = new VowelType( 2 ); + public static VowelType u = new VowelType( 3 ); + public static VowelType e = new VowelType( 4 ); + public static VowelType o = new VowelType( 5 ); + public static VowelType xo = new VowelType( 6 ); + public static VowelType nn = new VowelType( 7 ); + + private int m_iValue; + + public static bool IsRegisteredToNN( string type ) { + foreach ( string s in m_list_nn ) { + if ( type == s ) { + return true; + } + } + return false; + } + + public bool Equals( VowelType item ) { + if ( this.m_iValue == item.m_iValue ) { + return true; + } else { + return false; + } + } + + public static bool IsRegisteredToI( string type ) { + foreach ( string s in m_list_i ) { + if ( type == s ) { + return true; + } + } + return false; + } + + public static bool IsRegisteredToU( string type ) { + foreach ( string s in m_list_u ) { + if ( type == s ) { + return true; + } + } + return false; + } + + private VowelType( int value ) { + this.m_iValue = value; + } + + public int value { + get { + return m_iValue; + } + } + + new public string ToString() { + switch ( m_iValue ) { + case -1: + return "def"; + case 0: + return "a"; + case 1: + return "aa"; + case 2: + return "i"; + case 3: + return "u"; + case 4: + return "e"; + case 5: + return "o"; + case 6: + return "xo"; + case 7: + return "nn"; + default: + return "def"; + } + } + + /// + /// + /// + /// + /// + public static MouthSet AttachEx( string lyric ) { + string[] spl = lyric.Split( " ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries ); + string vowel, consonant; + MouthSet result = new MouthSet(); + result.main = VowelType.def; + result.prep = VowelType.def; + if ( spl.Length == 0 ) { + return result; + } + if ( spl.Length == 1 ) { + vowel = spl[0]; + consonant = ""; + } else { + consonant = spl[0]; + vowel = spl[1]; + } + switch ( vowel ) { + case "a": + result.main = VowelType.a; + break; + case "i": + result.main = VowelType.i; + break; + case "M": + result.main = VowelType.u; + break; + case "e": + result.main = VowelType.e; + break; + case "o": + result.main = VowelType.o; + break; + // 以下、子音のみの発音が指定される場合 + case "n": + case "N": + case "J": + case "m": + case "N\\\\": + case "N\\": + case "N'": + case "m'": + result.main = VowelType.nn; + break; + case "ts": + case "s": + result.main = VowelType.u; + break; + case "@": //the sun + case "V": //strut + case "{": //trap + case "aI": //buy + case "aU": //loud + case "Q@": //star + result.main = VowelType.a; + break; + case "I": //kit + case "i:": //beef + case "I@": //beer + result.main = VowelType.i; + break; + case "U": //put + case "u:": //boot + case "U@": //poor + result.main = VowelType.u; + break; + //case "e": //them + case "@r": //maker + case "eI": //pay + case "e@": //bear + result.main = VowelType.e; + break; + case "O:": //taught + case "Q": //lot + case "OI": //boy + case "@U": //boat + case "O@": //pour + result.main = VowelType.o; + break; + } + switch ( consonant ) { + case "g": + case "N": + case "s": + case "z": + case "t": + case "d": + case "k": + case "Z": + case "t'": + case "d'": + case "h": + case "h\\\\": + case "j": + case "4'": + case "N'": + case "n": + break; + case "b": + case "p": + case "m": + case "b'": + case "p'": + case "m'": + //foreach ( string s in Form1.Instatnce.Config.LIST_NN ) { + foreach ( string s in m_list_i ) { + if ( s == consonant ) { + result.prep = VowelType.nn; + break; + } + } + break; + case "p\\\\": + case "p\\\\'": + case "w": + case "ts": + case "dz": + //foreach ( string s in Form1.Instatnce.Config.LIST_U ) { + foreach ( string s in m_list_u ) { + if ( s == consonant ) { + result.prep = VowelType.u; + break; + } else { + if ( s == @"p\" && consonant == "p\\\\" ) { + result.prep = VowelType.u; + } else if ( s == @"p\'" && consonant == "p\\\\'" ) { + result.prep = VowelType.u; + } + } + } + break; + case "k'": + case "g'": + case "S": + case "dZ": + case "tS": + case "J": + case "C": + //foreach ( string s in Form1.Instatnce.Config.LIST_I ) { + foreach ( string s in m_list_i ) { + if ( s == consonant ) { + result.prep = VowelType.i; + } + } + break; + case "y": //[en] yellow + result.prep = VowelType.i; + break; + //case "w": //[en] way + // result.prep = VowelType.u; + // break; + case "bh": //[en] big + case "v": //[en] vote + //case "m": //[en] mind + case "ph": //[en] peace + result.prep = VowelType.nn; + break; + } + return result; + } + + public static VowelType Attach( string alyric ) { + string lyric = RemoveNonKanaLetter( alyric ); + switch ( lyric ) { + case "あ": + case "か": + case "が": + case "さ": + case "ざ": + case "た": + case "だ": + case "な": + case "は": + case "ば": + case "ぱ": + case "ま": + case "や": + case "ら": + case "わ": + case "a": + /*case "s": + case "d": + case "n": + case "h": + case "m": + case "w": + case "na":*/ + case "しゃ": + case "ふぁ": + case "ちゃ": + case "りゃ": + case "じゃ": + return VowelType.a; + + /*case "4": + return VowelType.aa;*/ + + case "い": + case "き": + case "ぎ": + case "し": + case "じ": + case "ち": + case "ぢ": + case "に": + case "ひ": + case "び": + case "ぴ": + case "み": + case "り": + case "i": + /*case "k'": + case "g'": + case "S": + case "Z": + case "dZ": + case "t'": + case "tS": + case "d'": + case "J": + case "C": + case "p\\\\'": + case "b'": + case "p'": + case "m'": + case "4'":*/ + case "ふぃ": + return VowelType.i; + + case "う": + case "く": + case "ぐ": + case "す": + case "ず": + case "つ": + case "づ": + case "ぬ": + case "ふ": + case "ぶ": + case "む": + case "ゆ": + case "る": + case "M": + /*case "z": + case "dz": + case "ts": + case "p\\\\": + case "j": + case "u":*/ + case "ちゅ": + case "りゅ": + //case "U": + case "しゅ": + case "じゅ": + return VowelType.u; + + case "え": + case "け": + case "げ": + case "せ": + case "ぜ": + case "て": + case "で": + case "ね": + case "へ": + case "べ": + case "め": + case "れ": + case "e": + /*case "g": + case "t":*/ + case "いぇ": + return VowelType.e; + + case "お": + case "こ": + case "ご": + case "そ": + case "ぞ": + case "と": + case "ど": + case "の": + case "ほ": + case "ぼ": + case "ぽ": + case "も": + case "よ": + case "ろ": + case "o": + /*case "b": + case "p": + case "yo": + case "wo":*/ + case "うぉ": + case "しょ": + case "ちょ": + case "りょ": + case "じょ": + return VowelType.o; + + //case "k": + case "を": + //case "h\\\\": + return VowelType.xo; + + case "ん": + //case "N\\\\": + return VowelType.nn; + + default: + /*if ( lyric != "ー" ) { + Form1.Instatnce.ErrorLog( "LipSync.VowelType.attach", "error", "cannot attach: \"" + lyric + "\"" ); + }*/ + return VowelType.def; + } + } + + /// + /// 文字列strから、平仮名でない文字を除去します。カタカナの場合は平仮名に変換します。 + /// VOCALOIDが使用する発音記号の場合はそのまま残ります + /// + /// + /// + private static string RemoveNonKanaLetter( string str ) { + bool changed = true; + string result = str; + while ( changed ) { + changed = false; + for ( int i = 0; i < result.Length; i++ ) { + char ch = result[i]; + bool iskatakana = IsKatakana( ch ); + bool ishiragana = IsHiragana( ch ); + bool isphonetic = IsPhoneticSymbol( ch ); + //System.Windows.Forms.MessageBox.Show( "ch,IsKatakana,IsHiragana=" + ch + "," + iskatakana + "," + ishiragana ); + if ( !iskatakana && !ishiragana && !isphonetic ) { + string sch = new string( ch, 1 ); + result = result.Replace( sch, "" ); + changed = true; + break; + } else if ( iskatakana ) { + result = result.Replace( ch, (char)((int)ch - 96) ); + changed = true; + break; + } + } + } + return result; + } + + /// + /// 文字letterが平仮名かどうかを判定します。 + /// + /// + /// + private static bool IsHiragana( char letter ) { + int code = (int)letter; + if ( 0x3041 <= code && code <= 0x3093 ) { + return true; + } else { + return false; + } + } + + /// + /// 文字letterがカタカナかどうかを判定します + /// + /// + /// + private static bool IsKatakana( char letter ) { + int code = (int)letter; + if ( 0x30A1 <= code && code <= 0x30F6 ) { + return true; + } else { + return false; + } + } + + /// + /// 文字letterがvocaloidの発音記号かどうかを判定します + /// + /// + /// + private static bool IsPhoneticSymbol( char letter ) { + switch ( letter ) { + case 'a': + case 'i': + case 'M': + case 'e': + case 'o': + case 'k': + case 'g': + case 'N': + case 's': + case 'z': + case 't': + case 'd': + case '\'': + case 'S': + case 'Z': + case 'n': + case 'h': + case '\\': + case 'p': + case 'b': + case 'm': + case 'j': + case '4': + case 'w': + case 'J': + case 'C': + case 'r'://br1-5 + case '1': + case '2': + case '3': + case '5': + return true; + default: + return false; + } + } + + /// + /// 文字letterがかな文字かどうかを判定します。 + /// + /// + /// + private static bool IsKana( char letter ) { + if ( IsHiragana( letter ) && IsKatakana( letter ) ) { + return true; + } else { + return false; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/Winker.Designer.cs b/trunk/LipSync/LipSync/Editor/Winker.Designer.cs new file mode 100644 index 0000000..e591fd3 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Winker.Designer.cs @@ -0,0 +1,266 @@ +/* + * Winker.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class Winker { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnCancel = new System.Windows.Forms.Button(); + this.btnOK = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.checkBox1 = new System.Windows.Forms.CheckBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.label2 = new System.Windows.Forms.Label(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.label3 = new System.Windows.Forms.Label(); + this.comboBox2 = new System.Windows.Forms.ComboBox(); + this.checkForceBegin = new System.Windows.Forms.CheckBox(); + this.checkForceEnd = new System.Windows.Forms.CheckBox(); + this.txtForceBegin = new System.Windows.Forms.TextBox(); + this.txtForceEnd = new System.Windows.Forms.TextBox(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 270, 249 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 11; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 156, 249 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 10; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 12, 15 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 100, 12 ); + this.label1.TabIndex = 7; + this.label1.Text = "まばたきの間隔(秒)"; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point( 118, 12 ); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 100, 19 ); + this.textBox1.TabIndex = 0; + this.textBox1.Text = "4"; + // + // checkBox1 + // + this.checkBox1.AutoSize = true; + this.checkBox1.Checked = true; + this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked; + this.checkBox1.Location = new System.Drawing.Point( 230, 14 ); + this.checkBox1.Name = "checkBox1"; + this.checkBox1.Size = new System.Drawing.Size( 121, 16 ); + this.checkBox1.TabIndex = 1; + this.checkBox1.Text = "間隔をランダムにする"; + this.checkBox1.UseVisualStyleBackColor = true; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point( 139, 44 ); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size( 82, 19 ); + this.textBox2.TabIndex = 2; + this.textBox2.Text = "4"; + this.textBox2.TextChanged += new System.EventHandler( this.textBox2_TextChanged ); + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point( 12, 47 ); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size( 121, 12 ); + this.label4.TabIndex = 14; + this.label4.Text = "閉じ目の表示フレーム数"; + // + // groupBox1 + // + this.groupBox1.Controls.Add( this.label2 ); + this.groupBox1.Controls.Add( this.comboBox1 ); + this.groupBox1.Controls.Add( this.label3 ); + this.groupBox1.Controls.Add( this.comboBox2 ); + this.groupBox1.Location = new System.Drawing.Point( 17, 78 ); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size( 328, 85 ); + this.groupBox1.TabIndex = 3; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "画像を指定"; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point( 14, 21 ); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size( 72, 12 ); + this.label2.TabIndex = 11; + this.label2.Text = "閉じ目の画像"; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point( 121, 18 ); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size( 174, 20 ); + this.comboBox1.TabIndex = 4; + this.comboBox1.SelectedIndexChanged += new System.EventHandler( this.comboBox1_SelectedIndexChanged ); + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point( 14, 54 ); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size( 61, 12 ); + this.label3.TabIndex = 13; + this.label3.Text = "中割り画像"; + // + // comboBox2 + // + this.comboBox2.FormattingEnabled = true; + this.comboBox2.Location = new System.Drawing.Point( 121, 51 ); + this.comboBox2.Name = "comboBox2"; + this.comboBox2.Size = new System.Drawing.Size( 173, 20 ); + this.comboBox2.TabIndex = 5; + this.comboBox2.SelectedIndexChanged += new System.EventHandler( this.comboBox2_SelectedIndexChanged ); + // + // checkForceBegin + // + this.checkForceBegin.AutoSize = true; + this.checkForceBegin.Location = new System.Drawing.Point( 36, 184 ); + this.checkForceBegin.Name = "checkForceBegin"; + this.checkForceBegin.Size = new System.Drawing.Size( 105, 16 ); + this.checkForceBegin.TabIndex = 6; + this.checkForceBegin.Text = "開始時刻を指定"; + this.checkForceBegin.UseVisualStyleBackColor = true; + this.checkForceBegin.CheckedChanged += new System.EventHandler( this.checkForceBegin_CheckedChanged ); + // + // checkForceEnd + // + this.checkForceEnd.AutoSize = true; + this.checkForceEnd.Location = new System.Drawing.Point( 206, 184 ); + this.checkForceEnd.Name = "checkForceEnd"; + this.checkForceEnd.Size = new System.Drawing.Size( 105, 16 ); + this.checkForceEnd.TabIndex = 8; + this.checkForceEnd.Text = "終了時刻を指定"; + this.checkForceEnd.UseVisualStyleBackColor = true; + this.checkForceEnd.CheckedChanged += new System.EventHandler( this.checkForceEnd_CheckedChanged ); + // + // txtForceBegin + // + this.txtForceBegin.Enabled = false; + this.txtForceBegin.Location = new System.Drawing.Point( 59, 206 ); + this.txtForceBegin.Name = "txtForceBegin"; + this.txtForceBegin.Size = new System.Drawing.Size( 82, 19 ); + this.txtForceBegin.TabIndex = 7; + this.txtForceBegin.Text = "4"; + // + // txtForceEnd + // + this.txtForceEnd.Enabled = false; + this.txtForceEnd.Location = new System.Drawing.Point( 229, 206 ); + this.txtForceEnd.Name = "txtForceEnd"; + this.txtForceEnd.Size = new System.Drawing.Size( 82, 19 ); + this.txtForceEnd.TabIndex = 9; + this.txtForceEnd.Text = "4"; + // + // Winker + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 362, 287 ); + this.Controls.Add( this.txtForceEnd ); + this.Controls.Add( this.txtForceBegin ); + this.Controls.Add( this.checkForceEnd ); + this.Controls.Add( this.checkForceBegin ); + this.Controls.Add( this.groupBox1 ); + this.Controls.Add( this.textBox2 ); + this.Controls.Add( this.label4 ); + this.Controls.Add( this.checkBox1 ); + this.Controls.Add( this.textBox1 ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "Winker"; + this.Text = "Winker"; + this.groupBox1.ResumeLayout( false ); + this.groupBox1.PerformLayout(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.CheckBox checkBox1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.ComboBox comboBox2; + private System.Windows.Forms.CheckBox checkForceBegin; + private System.Windows.Forms.CheckBox checkForceEnd; + private System.Windows.Forms.TextBox txtForceBegin; + private System.Windows.Forms.TextBox txtForceEnd; + + } +} diff --git a/trunk/LipSync/LipSync/Editor/Winker.cs b/trunk/LipSync/LipSync/Editor/Winker.cs new file mode 100644 index 0000000..0ac0c46 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/Winker.cs @@ -0,0 +1,197 @@ +/* + * Winker.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class Winker : Form, IMultiLanguageControl { + private string m_closedeye; + private string m_in_between; + public bool Randomize; + private float m_winkInterval; + private int m_close_frames = 3; + private float m_forced_begin; + private float m_forced_end; + private float m_max_end; + + public Winker( string[] titles, float total_sec ) { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + comboBox1.Items.Clear(); + comboBox2.Items.Clear(); + for ( int i = 0; i < titles.Length; i++ ) { + comboBox1.Items.Add( titles[i] ); + comboBox2.Items.Add( titles[i] ); + } + m_closedeye = ""; + m_in_between = ""; + m_forced_begin = 0f; + m_forced_end = total_sec; + m_max_end = total_sec; + txtForceBegin.Text = m_forced_begin.ToString(); + txtForceEnd.Text = m_forced_end.ToString(); + Randomize = false; + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.btnCancel.Text = _( "Cancel" ); + this.btnOK.Text = _( "OK" ); + this.label1.Text = _( "Wink interval (sec)" ); + this.checkBox1.Text = _( "Randomize" ); + this.label2.Text = _( "Closed Eye" ); + this.label3.Text = _( "In-between Image" ); + this.label4.Text = _( "Eye-closing frames" ); + this.Text = _( "Generate wink" ); + this.groupBox1.Text = _( "Set image" ); + this.checkForceBegin.Text = _( "Limit start time" ); + this.checkForceEnd.Text = _( "Limit end time" ); + } + + private static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public float WinkInterval { + get { + return m_winkInterval; + } + } + + /// + /// 閉じ目用画像のタイトル + /// + public string ClosedEye { + get { + return m_closedeye; + } + } + + /// + /// 閉じ目の中割り用画像のタイトル + /// + public string InBetween { + get { + return m_in_between; + } + } + + /// + /// 目が閉じて表示されるフレーム数 + /// + public int CloseFrames { + get { + return m_close_frames; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + try { + m_winkInterval = float.Parse( textBox1.Text ); + if ( checkForceBegin.Checked ) { + m_forced_begin = float.Parse( txtForceBegin.Text ); + } + if ( checkForceEnd.Checked ) { + m_forced_end = float.Parse( txtForceEnd.Text ); + } + if ( m_forced_begin < 0.0f ) { + MessageBox.Show( _( "Invalid value has been entered" ), _( "Error" ), MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + this.DialogResult = DialogResult.Cancel; + } else if ( m_max_end < m_forced_end ) { + MessageBox.Show( _( "Invalid value has been entered" ), _( "Error" ), MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + this.DialogResult = DialogResult.Cancel; + } else { + this.DialogResult = DialogResult.OK; + } + } catch { + MessageBox.Show( _( "Invalid value has been entered" ), _( "Error" ), MessageBoxButtons.OK, MessageBoxIcon.Exclamation ); + this.DialogResult = DialogResult.Cancel; + } + Randomize = checkBox1.Checked; + } + + private void comboBox1_SelectedIndexChanged( object sender, EventArgs e ) { + m_closedeye = (string)comboBox1.Items[comboBox1.SelectedIndex]; + } + + private void comboBox2_SelectedIndexChanged( object sender, EventArgs e ) { + m_in_between = (string)comboBox2.Items[comboBox2.SelectedIndex]; + } + + private void textBox2_TextChanged( object sender, EventArgs e ) { + int old = m_close_frames; + try { + m_close_frames = int.Parse( textBox2.Text ); + } catch { + m_close_frames = old; + } + } + + private void checkForceBegin_CheckedChanged( object sender, EventArgs e ) { + txtForceBegin.Enabled = checkForceBegin.Checked; + if ( txtForceBegin.Enabled ) { + txtForceBegin.Focus(); + } + } + + private void checkForceEnd_CheckedChanged( object sender, EventArgs e ) { + txtForceEnd.Enabled = checkForceEnd.Checked; + if ( txtForceEnd.Enabled ) { + txtForceEnd.Focus(); + } + } + + public bool BeginForced { + get { + return checkForceBegin.Checked; + } + } + + public bool EndForced { + get { + return checkForceEnd.Checked; + } + } + + public float ForcedBegin { + get { + return m_forced_begin; + } + set { + m_forced_begin = value; + } + } + + public float ForcedEnd { + get { + return m_forced_end; + } + set { + m_forced_end = value; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/ZOrder.Designer.cs b/trunk/LipSync/LipSync/Editor/ZOrder.Designer.cs new file mode 100644 index 0000000..f1dc754 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ZOrder.Designer.cs @@ -0,0 +1,150 @@ +/* + * ZOrder.Designer.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +namespace LipSync { + + partial class ZOrder { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.listBox1 = new System.Windows.Forms.ListBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.btnUp = new System.Windows.Forms.Button(); + this.btnDown = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // listBox1 + // + this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.listBox1.FormattingEnabled = true; + this.listBox1.ItemHeight = 12; + this.listBox1.Location = new System.Drawing.Point( 12, 39 ); + this.listBox1.Name = "listBox1"; + this.listBox1.ScrollAlwaysVisible = true; + this.listBox1.Size = new System.Drawing.Size( 293, 268 ); + this.listBox1.TabIndex = 0; + // + // btnOK + // + this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnOK.Location = new System.Drawing.Point( 188, 320 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 3; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 289, 320 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 4; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // label1 + // + this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label1.AutoEllipsis = true; + this.label1.Location = new System.Drawing.Point( 12, 9 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 352, 17 ); + this.label1.TabIndex = 6; + this.label1.Text = "描画順序を変更したいオブジェクトを選択し、上・下ボタンで移動させます"; + // + // btnUp + // + this.btnUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnUp.Location = new System.Drawing.Point( 311, 39 ); + this.btnUp.Name = "btnUp"; + this.btnUp.Size = new System.Drawing.Size( 60, 23 ); + this.btnUp.TabIndex = 1; + this.btnUp.Text = "上"; + this.btnUp.UseVisualStyleBackColor = true; + this.btnUp.Click += new System.EventHandler( this.btnUp_Click ); + // + // btnDown + // + this.btnDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnDown.Location = new System.Drawing.Point( 311, 68 ); + this.btnDown.Name = "btnDown"; + this.btnDown.Size = new System.Drawing.Size( 60, 23 ); + this.btnDown.TabIndex = 2; + this.btnDown.Text = "下"; + this.btnDown.UseVisualStyleBackColor = true; + this.btnDown.Click += new System.EventHandler( this.btnDown_Click ); + // + // ZOrder + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 376, 355 ); + this.Controls.Add( this.btnDown ); + this.Controls.Add( this.btnUp ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.btnOK ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.listBox1 ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "ZOrder"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.Text = "描画順序の設定"; + this.Load += new System.EventHandler( this.ZOrder_Load ); + this.ResumeLayout( false ); + + } + + #endregion + + private System.Windows.Forms.ListBox listBox1; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.Button btnUp; + private System.Windows.Forms.Button btnDown; + } +} diff --git a/trunk/LipSync/LipSync/Editor/ZOrder.cs b/trunk/LipSync/LipSync/Editor/ZOrder.cs new file mode 100644 index 0000000..b812b31 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ZOrder.cs @@ -0,0 +1,117 @@ +/* + * ZOrder.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +using Boare.Lib.AppUtil; + +namespace LipSync { + + public partial class ZOrder : Form, IMultiLanguageControl { + private List m_list; + + public ZOrder() { + InitializeComponent(); + ApplyLanguage(); + ApplyFont( AppManager.Config.Font.GetFont() ); + m_list = new List(); + listBox1.Items.Clear(); + } + + public void ApplyFont( Font font ) { + this.Font = font; + foreach ( Control c in this.Controls ) { + Boare.Lib.AppUtil.Misc.ApplyFontRecurse( c, font ); + } + } + + public void ApplyLanguage() { + this.btnOK.Text = _( "OK" ); + this.btnCancel.Text = _( "Cancel" ); + this.label1.Text = _( "Select target item, and push [Up] or [Down] button" ); + this.btnUp.Text = _( "Up" ); + this.btnDown.Text = _( "Down" ); + this.Text = _( "Z order" ); + } + + public static string _( string s ) { + return Messaging.GetMessage( s ); + } + + public void itemAdd( ZorderItem item ) { + m_list.Add( item ); + } + + public ZorderItem this[int index] { + get { + return m_list[index]; + } + } + + public void Clear() { + m_list.Clear(); + } + + public int Count { + get { + return m_list.Count; + } + } + + private void btnOK_Click( object sender, EventArgs e ) { + this.DialogResult = DialogResult.OK; + } + + private void ZOrder_Load( object sender, EventArgs e ) { + listBox1.Items.Clear(); + for ( int i = 0; i < m_list.Count; i++ ) { + listBox1.Items.Add( m_list[i].Name ); + } + } + + private void btnUp_Click( object sender, EventArgs e ) { + int index = listBox1.SelectedIndex; + if ( index > 0 ) { + string upper_item = (string)listBox1.Items[index - 1]; + string selected_item = (string)listBox1.Items[index]; + listBox1.Items[index] = upper_item; + listBox1.Items[index - 1] = selected_item; + + ZorderItem zupper_item = m_list[index - 1]; + ZorderItem zselected_item = m_list[index]; + m_list[index] = zupper_item; + m_list[index - 1] = zselected_item; + listBox1.SelectedIndex = index - 1; + } + } + + private void btnDown_Click( object sender, EventArgs e ) { + int index = listBox1.SelectedIndex; + if ( index < listBox1.Items.Count - 1 ) { + string lower_item = (string)listBox1.Items[index + 1]; + string selected_item = (string)listBox1.Items[index]; + listBox1.Items[index] = lower_item; + listBox1.Items[index + 1] = selected_item; + ZorderItem zlower_item = m_list[index + 1]; + ZorderItem zselected_item = m_list[index]; + m_list[index] = zlower_item; + m_list[index + 1] = zselected_item; + listBox1.SelectedIndex = index + 1; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/Editor/ZorderItem.cs b/trunk/LipSync/LipSync/Editor/ZorderItem.cs new file mode 100644 index 0000000..5768f61 --- /dev/null +++ b/trunk/LipSync/LipSync/Editor/ZorderItem.cs @@ -0,0 +1,75 @@ +/* + * ZorderItem.cs + * Copyright (c) 2007-2009 kbinani + * + * This file is part of LipSync. + * + * LipSync is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * LipSync is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace LipSync { + + public enum ZorderItemType { + plugin, + character, + another, + telop, + } + + public class ZorderItem : IComparable, ICloneable { + private string m_name; + private ZorderItemType m_type; + private int m_index; + public float Start; + + public object Clone() { + return new ZorderItem( this.m_name, this.m_type, this.m_index, this.Start ); + } + + public int CompareTo( ZorderItem item ) { + if( this.Index > item.Index ){ + return 1; + } else if ( this.Index < item.Index ) { + return -1; + } else { + return this.Type.CompareTo( item.Type ); + } + } + + public ZorderItem( string name, ZorderItemType type, int index ) + : this( name, type, index, 0f ) { + } + + public ZorderItem( string name, ZorderItemType type, int index, float start ) { + m_name = name; + m_type = type; + m_index = index; + Start = start; + } + + public string Name { + get { + return m_name; + } + } + + public ZorderItemType Type { + get { + return m_type; + } + } + + public int Index { + get { + return m_index; + } + } + } + +} diff --git a/trunk/LipSync/LipSync/LipSync.csproj b/trunk/LipSync/LipSync/LipSync.csproj new file mode 100644 index 0000000..34c5e76 --- /dev/null +++ b/trunk/LipSync/LipSync/LipSync.csproj @@ -0,0 +1,444 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {15B51EEA-0D7F-4B59-AC7B-879A7BDB4A56} + WinExe + Properties + LipSync + LipSync + DD70A36EF76DD2E2B895E5CEB906324CE8147A67 + LipSync_TemporaryKey.pfx + false + false + false + LocalIntranet + + + 2.0 + v2.0 + + + false + true + LipSync.AppManager + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + http://www32.atwiki.jp/lipsync/ + LipSync + LipSync + true + 1 + 1.1.0.1 + false + true + + + true + full + false + bin\Debug\ + TRACE;DEBUG;NO_OBSOLETE_MODE + prompt + 4 + true + true + + + pdbonly + true + bin\Release\ + TRACE;NO_OBSOLETE_MODE + prompt + 4 + true + true + + + + + + + + + + + + + + + + + + + + + + + Form + + + AviOutput.cs + + + + + UserControl + + + CurveEditor.cs + + + + Component + + + NumericUpDownEx.cs + + + + + Form + + + BugReport.cs + + + + Form + + + DisplacementControl.cs + + + Form + + + EditEntry.cs + + + + Form + + + Form1.cs + + + Form + + + Form + + + GenerateCharacter.cs + + + + + UserControl + + + Property.cs + + + + + + + + Form + + + ZOrder.cs + + + Form + + + EnvConfiguration.cs + + + UserControl + + + MListView.cs + + + Form + + + PasteModeDialog.cs + + + Form + + + InputBox.cs + + + + + + + + + + Form + + + FormObjectList.cs + + + Form + + + FormSetFrameRate.cs + + + + Form + + + FormPreview.cs + + + UserControl + + + Previewer.cs + + + Form + + + Form + + + FormCommandHistory.cs + + + Form + + + FormSeriesImage.cs + + + + Form + + + FormVocalomark.cs + + + + Previewer.cs + + + PublicResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + Form + + + SelectCharacter.cs + + + Form + + + SetSize.cs + + + Form + + + TrackSelecter.cs + + + + + + Form + + + Winker.cs + + + + + + + + + + + + + Form + + + VersionBox.cs + + + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + + + + Always + + + PreserveNewest + + + PreserveNewest + + + + + Always + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {0C58B068-272F-4390-A14F-3D72AFCF3DFB} + Boare.Lib.AppUtil + + + {F4F8F601-4E3D-43F5-A8A8-AA1FB7F48452} + Boare.Lib.Media + + + {D861973B-3BC6-4F52-83BE-49A8C269C09F} + Boare.Lib.Swf + + + {673347F3-6FC2-4F82-9273-BF158E0F8CB1} + Boare.Lib.Vsq + + + {C8AAE632-9C6C-4372-8175-811528A66742} + bocoree + + + {F3B0AB64-CEEE-4003-9DA1-BCD4109ECBA9} + Background + + + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00} + IPlugin + + + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1} + NicoComment + + + {E5F9AD85-0C02-4286-AC4C-F5B34EA10650} + VFlip + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Properties/AssemblyInfo.cs b/trunk/LipSync/LipSync/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4cc4ccd --- /dev/null +++ b/trunk/LipSync/LipSync/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "LipSync" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "LipSync" )] +[assembly: AssemblyCopyright( "Copyright (C) 2007-2009 kbinani. All Rights Reserved." )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "5e752734-c724-41db-a919-931aea7770b7" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "2.4.8" )] diff --git a/trunk/LipSync/LipSync/Properties/Resources.Designer.cs b/trunk/LipSync/LipSync/Properties/Resources.Designer.cs new file mode 100644 index 0000000..e1b9940 --- /dev/null +++ b/trunk/LipSync/LipSync/Properties/Resources.Designer.cs @@ -0,0 +1,448 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:2.0.50727.3053 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace LipSync.Properties { + using System; + + + /// + /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 + /// + // このクラスは StronglyTypedResourceBuilder クラスが ResGen + // または Visual Studio のようなツールを使用して自動生成されました。 + // メンバを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に + // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LipSync.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 + /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + public static System.Drawing.Bitmap b_len100_a { + get { + object obj = ResourceManager.GetObject("b_len100_a", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_aa { + get { + object obj = ResourceManager.GetObject("b_len100_aa", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_base { + get { + object obj = ResourceManager.GetObject("b_len100_base", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_e { + get { + object obj = ResourceManager.GetObject("b_len100_e", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_e1 { + get { + object obj = ResourceManager.GetObject("b_len100_e1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_eyeclose { + get { + object obj = ResourceManager.GetObject("b_len100_eyeclose", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_eyethin { + get { + object obj = ResourceManager.GetObject("b_len100_eyethin", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_i { + get { + object obj = ResourceManager.GetObject("b_len100_i", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_kisisi { + get { + object obj = ResourceManager.GetObject("b_len100_kisisi", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_nn { + get { + object obj = ResourceManager.GetObject("b_len100_nn", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_o { + get { + object obj = ResourceManager.GetObject("b_len100_o", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_shakin { + get { + object obj = ResourceManager.GetObject("b_len100_shakin", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_smile { + get { + object obj = ResourceManager.GetObject("b_len100_smile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_u { + get { + object obj = ResourceManager.GetObject("b_len100_u", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_winkleft { + get { + object obj = ResourceManager.GetObject("b_len100_winkleft", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_winkright { + get { + object obj = ResourceManager.GetObject("b_len100_winkright", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_len100_xo { + get { + object obj = ResourceManager.GetObject("b_len100_xo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_a { + get { + object obj = ResourceManager.GetObject("b_miku175_a", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_aa { + get { + object obj = ResourceManager.GetObject("b_miku175_aa", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_base { + get { + object obj = ResourceManager.GetObject("b_miku175_base", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_bee { + get { + object obj = ResourceManager.GetObject("b_miku175_bee", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_e { + get { + object obj = ResourceManager.GetObject("b_miku175_e", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_eyeclose { + get { + object obj = ResourceManager.GetObject("b_miku175_eyeclose", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_eyethin { + get { + object obj = ResourceManager.GetObject("b_miku175_eyethin", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_i { + get { + object obj = ResourceManager.GetObject("b_miku175_i", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_konata { + get { + object obj = ResourceManager.GetObject("b_miku175_konata", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_kudo { + get { + object obj = ResourceManager.GetObject("b_miku175_kudo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_neko { + get { + object obj = ResourceManager.GetObject("b_miku175_neko", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_nn { + get { + object obj = ResourceManager.GetObject("b_miku175_nn", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_o { + get { + object obj = ResourceManager.GetObject("b_miku175_o", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_smile { + get { + object obj = ResourceManager.GetObject("b_miku175_smile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_u { + get { + object obj = ResourceManager.GetObject("b_miku175_u", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_winkleft { + get { + object obj = ResourceManager.GetObject("b_miku175_winkleft", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_winkright { + get { + object obj = ResourceManager.GetObject("b_miku175_winkright", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_miku175_xo { + get { + object obj = ResourceManager.GetObject("b_miku175_xo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_a { + get { + object obj = ResourceManager.GetObject("b_rin100_a", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_aa { + get { + object obj = ResourceManager.GetObject("b_rin100_aa", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_base { + get { + object obj = ResourceManager.GetObject("b_rin100_base", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_bee { + get { + object obj = ResourceManager.GetObject("b_rin100_bee", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_e { + get { + object obj = ResourceManager.GetObject("b_rin100_e", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_eyeclose { + get { + object obj = ResourceManager.GetObject("b_rin100_eyeclose", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_eyethin { + get { + object obj = ResourceManager.GetObject("b_rin100_eyethin", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_i { + get { + object obj = ResourceManager.GetObject("b_rin100_i", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_kisisi { + get { + object obj = ResourceManager.GetObject("b_rin100_kisisi", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_kudo { + get { + object obj = ResourceManager.GetObject("b_rin100_kudo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_neko { + get { + object obj = ResourceManager.GetObject("b_rin100_neko", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_nn { + get { + object obj = ResourceManager.GetObject("b_rin100_nn", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_o { + get { + object obj = ResourceManager.GetObject("b_rin100_o", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_smile { + get { + object obj = ResourceManager.GetObject("b_rin100_smile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_u { + get { + object obj = ResourceManager.GetObject("b_rin100_u", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_winkleft { + get { + object obj = ResourceManager.GetObject("b_rin100_winkleft", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_winkright { + get { + object obj = ResourceManager.GetObject("b_rin100_winkright", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap b_rin100_xo { + get { + object obj = ResourceManager.GetObject("b_rin100_xo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap closed { + get { + object obj = ResourceManager.GetObject("closed", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + public static System.Drawing.Bitmap opened { + get { + object obj = ResourceManager.GetObject("opened", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/trunk/LipSync/LipSync/Properties/Resources.resx b/trunk/LipSync/LipSync/Properties/Resources.resx new file mode 100644 index 0000000..dcd49f0 --- /dev/null +++ b/trunk/LipSync/LipSync/Properties/Resources.resx @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\resources\sanari_len\b_len100_a.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_aa.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_base.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_e.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_e.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_eyeclose.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_eyethin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_i.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_kisisi.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_nn.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_o.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_shakin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_smile.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_u.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_winkleft.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_winkright.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_len\b_len100_xo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_a.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_aa.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_base.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_bee.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_e.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_eyeclose.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_eyethin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_i.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_konata.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_kudo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_neko.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_nn.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_o.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_smile.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_u.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_winkleft.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_winkright.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_miku\b_miku175_xo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_a.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_aa.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_base.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_bee.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_e.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_eyeclose.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_eyethin.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_i.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_kisisi.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_kudo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_neko.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_nn.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_o.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_smile.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_u.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_winkleft.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_winkright.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\sanari_rin\b_rin100_xo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\closed.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + ..\resources\opened.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/trunk/LipSync/LipSync/Properties/Settings.Designer.cs b/trunk/LipSync/LipSync/Properties/Settings.Designer.cs new file mode 100644 index 0000000..e031fe4 --- /dev/null +++ b/trunk/LipSync/LipSync/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:2.0.50727.1433 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace LipSync.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/trunk/LipSync/LipSync/Resources/author_list.png b/trunk/LipSync/LipSync/Resources/author_list.png new file mode 100644 index 0000000000000000000000000000000000000000..7e52a7fc88f414ab92f4a635ad59628c528293e2 GIT binary patch literal 8610 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/closed.png b/trunk/LipSync/LipSync/Resources/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd315e8af5e0d1b0410c701c87e19ddcc2304a9 GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1SIo6Pjm-TjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP{P2| z#W6%8JUJ&LBjEsRL(%_@j1%NiEEm-6FnaXlLJrF-H9z?yQZ?TccZ+AKO*q8GkSaL4 Ut0?O!4^S_Ir>mdKI;Vst0JqpO4FCWD literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/cursor.cur b/trunk/LipSync/LipSync/Resources/cursor.cur new file mode 100644 index 0000000000000000000000000000000000000000..277f368e5f0bc12cfbfe37a1d164c63583476233 GIT binary patch literal 766 zcmd5)F%H5o47^rIjAde_Bfo&3;f-(Q2YdlGMkE#n#Bo+krCJm=grl>3XUB1(04*By zJ+RO^x4;s>T9AaT&|oGHm~!vTT$Hm2EJ!Iunt`5|V+0JsDtPwath1SIo6Pjm-TjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCijSl0AZa85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP(sbq z#W6%8JUJ&LBjEsRL(%_@j1%NeJ-Lv>66LgW<_x{oS)5BYFfq6{FR!~RFWCpw!QkoY K=d#Wzp$P!N7cKSx literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_a.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_a.png new file mode 100644 index 0000000000000000000000000000000000000000..466cfcd8fc7484219e3f1e2f84fd7f4bd10c3d49 GIT binary patch literal 1788 zcmeAS@N?(olHy`uVBq!ia0vp^Z43;I@f>VGR=53@LqLkLILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zV5{wBKiv@}~sct)px82NnWf`1qwRAyAy4l>W@aHl!er#LHa&YE;_Ph#< zJLfIG|E>NP^Zlr%R*|5BLjwaN6AOpHFl00y66^T&D^Wcv%B^Jkd%3$)y?U&t`q|ws zUGVYeo4<$E`OU@SeU`R~f8$&GZyD>Z+mroMnLmW8O|`f=)o;$(C6h0j@49sI^Um{| z7B95E`{Rjk{Z4i+Z-sEiPmLbxS(_Gr|75^ZG2biiH0zSh#)avLZ*OGfdngnuL>3)R z+_9!9W|hiHm#e&gCwR6hPw-S!-6%Lu-#*Wwe~M zqF;A@xXaH=t%loEvZnaVli2$Dl>S%Q>F3Xzt~|ls=%9A@M^ydPMO*8<&s0?g`N;h) z(V1(ex-ZhezO3#~qRRC(JwJ_?#hOdZ3@Q4pkg&1!PWKyq32yInx3`PFC)N9gzFEDl z=h~`I8F9O<_|~oN6kVDhXD+ex)#TMqDclhc);D)fyqPfPmA=H%_4`D2hp#=+uDJ2n z?s< zhpGNAvwr=8#VJ1@l_y<3#CkC*vd;DBjqqT}(A1^OGOD_Llbrm|I-E_vTrR!1wyc$10Fw98TEN!*h z?d76B3*M}Z5WZix!Q$Rr)4yE_Uu3d6yZ3LO|9fZN;TZ=XB=JW!em;Kd*j&3ScW&Rk zSK=#bF)OFTHGjXHedwC5ZTi<;-QQl{So*dr<9A(jUEaHy7W?e`OiW`U_7~mcc3_`* zV191zWWADYUysPYJki^I{QJ?Li>nuZ_sE{}@`kW&d-S9CIiWA4)2-`Ho`3l_H$NvX zzA){MaKElpipsXj>IR92S{|vU=7(O>ss4Xw+4*ZOhmU=|xGA}KN!it-AE(VNOgi6x z@#ZIIncS?7ySL4cw7r_TG3A`}*7ZH|_2NgPogd76W2W8CBe|*c#)XB|?S sU8rq!!+5x6>rsDEz0Cel&+&&j^T?gkTDjeSfz=a(r>mdKI;Vst034k`E&u=k literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_aa.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_aa.png new file mode 100644 index 0000000000000000000000000000000000000000..a302ed558e7ee2c246302ff75831639ce212e3fd GIT binary patch literal 1852 zcmeAS@N?(olHy`uVBq!ia0vp^Z43;I@f>VGR=53@LqLkLILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zVB6*C;uum9_x46^#?({^_79ztrnYo9+5NIz(l5H#K`^q@l5?U_PQt98m*$-IwU>A_ zEhF>ct!K~fIQ6`0PT-u%r_-MLqU@Z_EdAS-!PSMr%~x`hem0e#FV0FT?yBQF_eXZe z&6|fU)4%_%{ugt-blUXijtvZqOe`D%3J$}OQ53E4=7!-T7cJ9O>o=$7_*)r1^ilg+ zVm)8_eIH()b#>vQH5ya)*y*0BF7=x6 z_tTSrxL;uwSML>tc6YAwN&nP)$8zi3djSg8F?=(WA2sCUt>JQQ4L;nYIoa9Sv+%~Y zJvMLF{V`Z_Ev)@8?`x;8cWx#go+TRIbWwg)g@>yh3rm&pT4T1bF8*nHT%xU)ofhpf z+G4(roBeh6;eEGWT?qRe=;3xfD0}rG|5DS$lXE1mvn)2Bd&i6=LPl}lMCN9}@UFiX zd;1ShSP?ZjcJ2Rl|L$8$y*~W=Xz_YZx0u>TS}tbotbVedJ$+4uX$b~m=X7|g7i|*^ z@A#*{^XI1A*2%M4k6sV!S;3pBZYk4M@%lRVu}MGk+uq-co|r3no!>2Xg?6lhgyp=( z*Ln3D!Zy{Fy8g&1j4a#M5q;u7!IA4$i@E}>Jq-S3s%oxPxz22S<3r_|r?(A$FZH~* zy?>XZwwsy6#hyUJ{A=}EZeQXr7QFo7csPAsyVAY-{9SJkW*mDVX_3CBYPn9d>7_u1 zU+m}qy%MYs{`u@~>cT}^UU(Utll5&qt!}OVChwL>p2iLfXO)7FKNfPP_rJ5ffBk0J zQ@8nd_G|mhx6#b$WhzKH6I3MSJ+&zvu9Otad7|{;_oJ&r8Qn zh3YfOCNb5^WYsrdYuet6}fZQ|2MtP4NAT@(->Hc8ej{M>xuY5H1x zcdN_O;*0-XXHGnQ?3TT{&DSHB6x|+K{AFTgW&QbdscR|kYAwB*ixIN3%=39xzKwRO z3J-qaS1a%L=C@+W(z3Suw`Mt?-sYQl`PZp{IHUKcUka<=bN={Epu)^5?e2!e!~3KR zYkoBDcDq;jt?~DJ>(3vYldIz^K7E{j-1ggvZ!6FD{$8?bjY{3z<8L(#($37VUOaXF z^z!#Fezvy$RG&4=?QS36IiKNJ9t_uVZh-yuN1mykS)qF87YEkD$-wH3!PC{xWt~$( F69DbmT3rAD literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_base.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_base.png new file mode 100644 index 0000000000000000000000000000000000000000..db9492342de0369a13811e804f54ae7d513e3b2c GIT binary patch literal 57574 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_e.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_e.png new file mode 100644 index 0000000000000000000000000000000000000000..06236f33bc8e24881b2d9e3e7ec673257bcdfd9b GIT binary patch literal 1782 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_eyethin.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_eyethin.png new file mode 100644 index 0000000000000000000000000000000000000000..818067592fa224787d3259e557180248d22560ab GIT binary patch literal 5713 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 AR{#J2 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_o.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_o.png new file mode 100644 index 0000000000000000000000000000000000000000..0a7b16ee8982eca3a947b8f531a793c280d89201 GIT binary patch literal 1747 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 X-Tu_Q literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkleft.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkleft.png new file mode 100644 index 0000000000000000000000000000000000000000..e83f7e68f570b698cd99990efcd5d1bbabd05c92 GIT binary patch literal 5334 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkright.png b/trunk/LipSync/LipSync/Resources/sanari_len/b_len100_winkright.png new file mode 100644 index 0000000000000000000000000000000000000000..6bf0d12ea65c9e4acb0c9791c0dda8957c6358f1 GIT binary patch literal 5273 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 Pf?)7;^>bP0l+XkKX!rk! literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_a.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_a.png new file mode 100644 index 0000000000000000000000000000000000000000..95a30698dcabd4073fab0b5d14a2ca1d11c5a363 GIT binary patch literal 4228 zcmeAS@N?(olHy`uVBq!ia0vp^PZ$^&Jvi8aEQfzVYk(9>x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+TL4e=W#WAE}PST(M z|LqTJNU$zWC}3z{NRrB6?`aA&;1Xa^XmB%r0+eXxU|_kB(Ix{_A;8$cAa!=a;sg;M zB?bY9#gauLJxz`*3``j&&V4{#9SjZ(y=fjV)2_I>udPjfGM(s+ZZBXz-{`i37i0`^a)1nn~l$dhKh!py*U zdV-t z{1lRqkl5X5vZ5{J2Y*YC14okKf(r=+j2({~XMPg;8*9zAf)Sj-_>vgbNXj-`sS648 zn3mFz?!$9)yF+1U!m=8Fe)B$vsc)V6@&dRPPRMq2Ydd`0-{8&7>V}86pRebcwJVC} zq~XL9RV|IHq#H`?Y-O#uRxkt2-O?trgdxJZifLu;gfkpWJv`NXGHDU}>x7%N?CqQ9 zZZm6E;O9R)sg_+Lr@2N#W{s}IgjpN5H@3)anD)mo;GI0{6HuA3R*_wkL2Symo}L9f zY%3+j*T)<#czr{&jVIcgtxis_?Y(`S(Vu^x+Z9jTnw0o=;o=KCocb|K8*=y*Y-cI9 zOF+ts2u9_@@hs2n4?pz|mk5fTBiZ09)pq{=zQd_McJ7d9iM%N(5%7ERe~ArW^xY3W zUo`o<4zvVH{@Z_8bLpq4b$+s} zS0IHKyXJ!_LH}5mtV*bHkIrsm4qtD$VdEwvhhNhK4jeghcbEZyRg=vfS=rk{C)I0pH__-uYMTLZe;BlTaGv@EFPyfL&Z#K)-Sr29z zOU#(Loqxe%cScr_=H<3*mOuWz(UYE##r%jRA%^pO^rktDUtjaHRmbMC@#*Qc-OpLW zvu4pDo<~WG#2ZbYtMGX)tz>@tEYQIY5|}Or){B4t*=U%``6ft=;rCRr1?yCejX(RR zsV&=C|No!$m*3~-*UAWW?Pt3+cX5LeBw#q2q}BO9{r~l|`{C8w+yBQfDZ7bJ=2u27 z>PrIBM@#+DN^i8zA8qoCw)jRHyrb>?(eBP@Z*Qn~b`LPzX1>?`e}CmZ1|aZs^>bP0 Hl+XkKMT+x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+TLBQA3#WAE}PST(M z|LqTJNU$zWC}3z{NRrB6?`aA&;1Xa^XmB%r0+eXxU|_kB(Ix{_A;8$cAa!=a;sg;M zB?bY9#gauLJxz`*3``j&&V4{#9SjZ(y=fjV)2_I>udPjfGM(s+ZZBXz-{`i37i0`^a)1nn~l$dhKh!py*U zdV-t z{1lRqkl5X5vZ5{J2Y*YC14okKf(r=+j2({~XMPg;8*9zAf)Sj-_>vgbNXj-`sY}@? zZ(naP$D(-N!#6*>dDh48N&4~qyMFVweSFR}E*cSXGZODJ8L!bY2;L{ppx)2K#R$xm z-xS%+HCh8EM18ojlbgp|OfU6B&Da%*k7%GxG+_f%{w@GLQ>*_ zS8NJ%?Gx6?v8FHs-MdziU6bKj-#mvbX$|9lKYmV5y!JE*NtYiLl0P2&^)#5kw8^sJ z3$P?g0-5k!kzG3>g^7 zc?}6CNXetX+QZXR{;zrS!+JL3WaqZi{qlwz7-la&@xb0i@vwbDTZ-G+`uB~S_P>07 zE6_m~QpSB~+Iqm}r=ZEvg(~{TKg{I35zb;3I?-5Fc}fb~slPw_V~YRnKdia*)6{eC zWLZOiWi+s~W7m8zCFmc^l2r~lYHDh2A5I9gRqp<7uwk>q?!W*4H)nf@Ex0p(f4#&! z=igHuK5)nQ)9PFLU z{MPRkUc(hI!trACD1fvb2(e@yuQW|m%qS4;KXlH1& hFF4v2hK~d!FjOc1(b!tmu$=)2JYD@<);T3K0RYj8De(XR literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_base.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_base.png new file mode 100644 index 0000000000000000000000000000000000000000..3289d47b0a53a56794eee3f5019f0dbfe4971b2b GIT binary patch literal 91575 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%0Ak(?x?M%Pm6eU0uX? zU_XgN(rECZBg#q=lzkCbCc;IJnmY?wS7jyX-cv*??~!)}{_QKEk~w8j!q`(GN;XuC zkwQg_O2-M4WX0Qew1RxD@t_V&Shxjv4S~4;)??73EJ^R$Sppi@laX7tW&3+3d1wvQ z|I_~`zkif#Yin68*7+K45cprU7t9r(7LBFz_zAM$3@jI(XT5SMN-gcDPnYNgvk@<@ zx0E<6r4E2H1(v*0%Ld}wG(!RbLjRe%rJOxhoSI}vDfCNDsva$80m`(Bo>J1Q8ZxvS zr1qxuGU?EpeKY8y#nGQk#T~`8b_PLAFd;fl! z1-1?UuU7astgY_W+9rQ&TwK0>0WH(wEUDGIr*xP$O(yKvt!kahMb?jHA?lLDHf$2_ zb}fR|odnEbOlicDy=Jw%P@WLp4tc z95Yhl;HEa;zEzzQ<5%7!=*rT4wfFZWAV0w(nLY23cLo0R6=+WD$Yjp=pj4?<%1Nf~ z+9PWaFKVR+jWv@ahO-5y4Y)MmSXnp(;MCLSR4uO~EDATW21?Wawn+eGD}(6oM}|*_ z@#7__Wpf#`b%(Nq3&8lXEsf9$&%*z!-k`RGOdf;Uqy|bOmNZ=06j-*1<#WV7)K97p z?<4-R$7#tO#F8FeT8S%S$@y-Pat^8j8Px)$Vn(_o<9{)eJnGm9#L(J#%s6vi>h0JH zx?Mex(ZTWk+uvsX=}#i>51#ugpqh4HL9FOj(OnWMd&$I&n`JfJ)CIYe7;NJ|!!l~_ zXHI5~8N_r|GmjoqfHbnOQ%;?eMS7hww;JQ4>XuW%fu)sPh)k~q&?fiSu)K?}-jwF^ z=S#(=wIyoBd=*O?%p40t2d-=Unxzsrcf6EKh>$>JSp(p*(o*^Xl%;BTNeiD)BzJ;j zTIC2S>64ST}g=w@oMAVJ9tEMv*sEb1Zvs5cTItly=;!qDw&ymhm( zECj0oEVHGvuy~9Nt$s|(HKlb`R@2JpF~^(yp6@yG#3}LW-d?;X4UvefSpX%NIf|WQ zBzo`_H;LedQ>4bYK~kcc2jWS9l2#JdvTRD6l&|D2^D9Tm$>Kp0>{?06hK1->a+M4_ za!kdM^dxxQ`W!zlWzoID>xxz9PkkDBFMjT?z*5#3?d;3QAPaT)ZmF9WO!LcNOcUo<5cU5;J86aux3I$3do=ib4 zF=qJ!34(R>9@Jgzqk=8v5Z~#eq!_rl$^Ph-ED$wUUe(+wB3vW%V+tl#wD;8)ir{;;=-3fmzE5 zCr_*Q$(HER0h(JZX#t<9#+k!1<9CaZ+-bgasW{e3P?=P}8KWe0!4y>jNg*h43>v!# zuJoemlDK@fRO!}QDq|_)z}#_gdFzUsx3?^Hihz!5ki=E<6ZggqU?n#w_j~m5lPZ?v z`}1p`0|%u-Tr>gs6_(r6ePoDs=11aM~Y22{pd-l*|HgGmSt@(zR>>5`Hl<>JENnvw`GRzl{( z!mVDaK&kOs*GlZN`4R|MHE7`^BzgSBciIRQPu75yv;%vmmp8J|XkgB)8ZLHKt4Pek zxe^byPLF;2WHAU5#<4QV>qSVeqg5~eoN`B7_^%izODR7_?r%o~Xux~Rj~gPqgAzv@vmCwt6*YPNHm z0%YjOVUoUgr+D}7BvtCy0vOi8eMMUnKrtF+627+)mm2S9u34H13fX{fOG;-Pi5twQ z(`OaEjf|rz-P=ge;wj2f2F;zIx;zvpvEo29XEKM09iLJCrF2jY30gD-<&be=7aK0_ z$hfWq;rvj^5UB#OWv7&yQj4g@H}aY-j(h zCDL!vVs!uC%pPN!N+u0qWn)0>4jVC4QQDF=u9oTpx=M|%?Ijg%D?!P)Za8iPDyFpQ zm&}%R)e}iMETbtqtV%D6T6ac~->b&QNohNKack8;ixI(N4MOcPZslUt8A5Ods#+wT z$M385Y%lKZnn(bWJl+$ANHMfpHSrHuC6I}(K~fU3ACVv)#I0MQxUB@gL2_7%8m=QG zM{upFU_d5R-Xre{e<>F}{zUfQeOK0j9>@5QmMk8? zsNAf9#PsSei(mnbqPwzKHmn`i2Kz2tEED$Z)7({4BF6gKE0O`)S=9Vl5;cB|q@h)c zmN8+&3aQkhuGHuN>Kh99i6n?`fTcuSrZ%{8QM1=VjbpG)^jLc-tqCE%mYLi-dv>5V zvJD!k)1{O{1@W7bsVH-_lmuZCKt)h8>Enm)4}Z9-LHK>KD()Z%xJ&hs{Sb#Hil?u? ztagl$V~8b#s`*G|NP5%+6R0-U3=kePi;mb8H>QR|hC)C~b<5;U)ye~7u2+CUQ<6Du zoP7AhPx8)#hjR0a2Xgt-&*bC>AIa)#*QMLu-BJsbvVi_QB@(XXM6zm3$(9^R7i>T# zaeB|2FH;U4%?8|T77dmvZS4|?oHs+Nqnp3xniZ-oimqblqG?jOQ!@z}J{Xp4tKx<- zu45vJoYCAYqj4MrA<5pB3~eqMV!D#8ab96FCX1^_6-k1!K{00s@fpz}VqB~O2N zANP#PHHLyWb zRxOr@MYE(^o7R%hppF7$D*6oL@Vq}Vn(htLk?liVEnC@?HbY}2>mZ<0=(a-=23X7DI)vHLb9wX9H1_PW403{PS0Xnah@up); zsKmwAl<2r5p=zBkM%iscd)kh2q2lD|B$Zna2AHsWpTwixX*QTQ1|ZEvdi6K3Qpqb9N(fxSX~T!g2mAI&a{Jbjjz(g( zL`5u}Ej1<$6_4h1B?>jZRJ2nOKxwd`cGATQb0Hnm6X2Ro)Yv(*Ml1DzKoA0qb}S}%YK$KuE{F%C zA+8(}8YM+hD(V&-D;Ej{O8+W>QW6cyQA-x0DSLzB=^E}muT6tK{iT35o}f?Oe$2Z9 z#ub=F>sT{AT|WBpXSwt6YXwNI+YcVd@%P_Fmi2Af{PqoLJ#3H+LTl2Tix*Lsya@|= zO~rC5`)YvGRQscnT&sZtC8J(lMQ5`Rye(8Vqa);s)C3?|3mn?Nk9>LTu&kLdUVK|O zlXNr{tAq+Hl<(Bxkj1DcNh_8r>&e7YeZ-bCU4B7Ds2v%~Il(wwYrjZ0Mo@#AUHZ?3O*A-=u z(!o%n13|z$DoV;bIEjyMfNTTle0HHKQoMY534~?m4P?NfLppN@$9eIJ3`7&RoueZG zc?HWXOPRMjpVKSA*&KJvl(m;D?|mTeqs*be_|-$Xiwx_zk3N*c@7|GPAG|A_h7OSa zv!==Vw{Ob+d+*AQ+jnH+ja#xBl8Y>fWTE#^vzVIIWW8YQW9=&{sPdMb#j%Uv{VV5 zG+t$g*?UP{pKR_jk~_|xo`(KV_;b1k^G@4z1%}c(_8v4?9{lSMxTs$#K;8v2=dI5^ zlVk7QlhYr6Br6Z@mzF&`%l>!o%E=Eulymn#l_T$dAp4Mg-F8a{CM+f`5H~k1W)_k; zgO{(8owH}k;J$s7tcSrdRfGXO!NRX}Woxa@Qh==6s+oL!>VyL2m&cDtuXczj=g&rl zbtPgq#By0vrDCIW@oC#qYVX~l>V(|vZFcTZK+MAb(tvnf0dNB(MRwi33#*7e$V(S- zP9Mrq9Q%R0@5xq_A68zyj_2Q!?kM0V1CZ4_v_*2Ks#JyOb9iimc>4uOF?ScK3a}A` z%)Tsv6(b$PPvn$ zR;>(fE5|3~J)Yw$;DB@g@=YiKoVtF~Vjb_oWxf9S=W^oxdupBiRM&&a9! z9|EXf%GJ+4SLKk?AAT%HU|IKr$+I26h`au&VdFDq zBb$f4k1RLPT_kvx;%}Ox?w9~8claC@`!wl@4KS8Hz{kOL@k?x7!E*~ zIzrN*lN#Nnqtrs2$yhQ48@?^1K^DR?(j{H<)=k;+_H9)|Jq!RIe)oMme^CzJyQjzw z$KL-?9rG$3kb@9s)`|-LpHTSbcpy2>nV0<$0}T* zoD{Jutu16_i?}(9J4CQlM+mw@{NT@lpWc`A_dinESC&Jr zA=z{J)6enTC)nJY#o2)kPPvVhuuQ8EKlbU_U0J#Ta9Nk(xupOK0XrWV*32V^mCLvu z_00_!1uy_wsjb&77T>z*a(wv`SjpoGkaS(&+q+BBx_3c5xk-Wm$PiehmK|El48)tU zAZuqJu1!ZKGZiI~!2s4;SnG8FB;8XU*9m}+$I0Z>wzsd#MIDgaZfO>hMcPkRL#GlPVbOTA2&(tq1gJ9pIuC1ly-#tA+ri zHSuFm@CeL!Sn^&6_A6q8QIni~`ho-`CK8ZTQs-E_yvK8R1zy5ApDI$ch+KH*uDt*K zk1C_exbfO&pDN3E>ZA8%@3kw^1li85=T6IMSjQUxA>+&2Uuq>00`vI$@54&Ihp!)k z^LkIkl^br|mGPUm%J^PA6rhHKSiXkf!|xcoZMg}Z9k`<#Zro57_6Xd_MQ2aSgoE3q z;eZ}8586B5o<1QDP9Bx7FP~NaWBFLPhP}E<)Y4fBke(fz%l4VmrF(~VlFTe7EM*2j zSs!sFv#M(WNV=rt;U2~RKl9PYaJN5#MZ6@NZ{C2Vd|z2~CV6PN$3ezX^+aylAZ`t7 zNlCDF+^c$7z(_zkRjee1FvykPyWw|kRjL7yKH`b#Sf0qrx;VN@A&f_;F?pCpLNaFg zLPc^=fCRU->9#GV)-b5lp)8cxyd@+v^H@92Ar394%r1lP>o#sAU;N`=mL$$Cfb1l) zs>cDyi(h;u{gE9UIdhs^dhmtNYLZSz;L=Lo#@Dyty6(DtQ_i4Hc>?4C0&){Tx8>dk z(hMLxnzdMgY5d@U0N*Xyj#!QsOSzAiF8~nN;QD?lmp=JicEED2ICo42&z&lLTegtz z&z@Em@`rbC%ENP~dRGUT*LnbC zT>x|3i4$;Hk-&i!JaF$l1^kmA+=qp}ETfMe#Mi4TQ_MsV8Av3@E8Z#+ME>K3NEsw^ zX!#85$gj?B9!iCsF=n+I{-{?*VTMVv#3rRlWI~#RMwkig|AHq4@L3_GgAKcH^%gNkLU0TOr^UzXZZ^GnC>dABVxx(pM0!b z)sx7o9=&%*`i~nehi<XJLJqe$1>?eUNBwPQCoIMl_1r)%z2oclbQE;j;;U)ioRO_Gc7Ix zAn$$qowASw+o=!UQ-D18>Bq8S{~nov=}u=q`xsftyNcJ!bro^rHLQd8?jk#R9xmt& zfQ;4=8CO`O%}An*+O%0l>*WhtxvbG6Wg}v>!@BEu1%H1O@3ZgjEyQ*o%01i+E_{4n z_FlgvyRMy=1oR93dg%fHc}Tv)bH9G^zI=1#y!x5{*DtfTge{u^>BX+ns(u|=J$|fA zfT&e8TDKbP1}Kr)tcwIq8&K^QU%ag1NoHL6l^|_~nqvlD!;TdumW(#B765!AXnAq# zmr41=NEIW}EoJOzxT>L1&|t-sV3GJ@4=#+k_jh{V57fzQ@;i`*xl7OrY5Of9Wht`O0BEiSi5pHf0$n0#5;+O%ttaKr}LbV`) zjnOEvRBY2w>@aGtc*)YpvX&LU;BZ(&%_>I2MGcOKkzll7MMQ*3#|EB~k{E>fn0^uy znZIcup*(WmMyS*NN!+^s?GjbgSzQ?i{vH8=hg1qRbG1eWrA{C-Y$K}i3RKwdK7Ch#lGc*I>j&U@_wE3y-4vNN zeS(TJnE+ymr9Mg|b>WiMLM*5K zn52!X#Ah^UZAFS8S>p@vMJphNC8tU_=3Z9!@qt_IDedZbNR1lRB`qah+(1k(1edmk zf3TFtSUZm{EfsOV7(+mEx*-ihOF0I|pz4u&`6F}fMk$E*!&c--_Pob)as`-OJ#Am1 zJlxJt6^Wd&;333IG?p;if~^u9De!jtP(j7vP#AHe^YIHNGx;cB*V< zQ@DQIP_#OWQBULqTPY89<4(4DRWOPN+Y&X)a-? zTlO5%SGlx5zW27W#v7+hk}wSTNk@Vw6@XM7{{R5%e+H9>s(CFLkJ4)4ckCP?QJ!RV zS}_*!L*`DD;*RAdA+@%|!bJ^;jh6)1s#3kYtN8hQ$(U||l92@R09@FL9@QWQRuGe< z^NTwYKCbQ_;)qcMtVdEdk{u!x(K52FtVa$)Q@0_BVvx zKS^uUP~Q9LCspJ>gW~?&b7y7n!M)NSt2^qBbw>}EzHnDNqrTS)?%x!+bxWx}4&V)h zwNX=~uxaaoN6N$m*)~)Rn0WZ8bVln`C$MXb8Y0;?KYjR){Pe*s>EErJocQ>2)Ga?! zNub3S&&!mf2V}zGy>NZ6$sD-B1Glc0UTd>tP{;Q2!?`oc%Kr4hZ3W07eY(rIA^qXb z9+iohzvu@mmeHjRe)k?g`JQ}pO^Z8sz(o%1*j8%q-lpU~5>al*zzt*$5;umGBoTnt zkl-M(U@FM(yt!~P7l#8yuAC=MX>nldBuXH$B7GoXjis8 zYLG6lZpC0xi-`lQV>QH{b{IFn;XK*|Ei^Uj3Ix1C@J7%D9*SA!l48zvyZ0asoaVJU<{SNGv)}W2Gq^mb)h9r$2CC$KkVYae9GLO@B zIYxr70m=*9#9R#kUL#Yu5P%%Ed$+U%&5h*=<*w4@L_N`PIkzpCBNNxImp$*_S1g$+ zr%y@`%xG*201nu{SBApnY`Sv3)L$}FQj+537bK00(nr>;$ue?a9|gXzFQ1d^8`q0( zJ-Ct0>&v$vX@KSW8djaz*)e^4OZ?*b5JBE#sR6b}?5K%N!EJ>#r0dAoj`EZ3cI{Mg z@F-YW%7sL&Tp-o@bri?SRV2#EL$((60U(2Apo6zmM@E!c*L>itmPUN(f>G#&F%7Ih z;i6Io0QCboy|{;)a1Myk8N%dFG<12G+~KvW2Mf*{gh3%>`J?ZmB_Ow}$Cidl)%Bn>eb6}Xj@p{|%lNk&>n zCM8(pZVB}OQqP#BoCVPK1V}Q550N>81}Y$Z32ViKi*h$Ve@}kCe^=TQ?{Iv6q>QlU?hOp{XqdN%P2co$q=1N$Lq&yON}6-pOdAR3A^@*8{$*!#S>TzFY+GG z_!Zdv>T9pcG$dJeqgcKkERo*Od!hT8icK323+CCdwvu4vot&-}yCAq}ltP>C<{55R zJCqn$N?1UPgQ-uQ*MX1Pxr6MVKUcGmuvD~W%6c&|gIMp@(f!i8Ygbu$>z=Cp)d%3C zv*t*|f@w&?te5B|v!VVrNt}{n<>=DI^6>aknKY=s+yZGpf$r0L>i;k<-38*hUwo9j zd*zHA+qp@`z@7E=_LA4ML9%LKtV_)VNzxj*cM6b5PTU7K2$x#yU(saO1F}LQ8~bgIAfMRBRLcZot+p(g~I+ zymqRL?A%GM%nt2keE+_(c;;l;i_GOa=a0jJy(4RU7Xu~+r}on-*z62B#<^}=aoVKqQ%mXKwTdq^%Nqh=ZGU&H8_P+wnu^%W^twyYFK zYf}+7H;J4)Uea|?YVP7jMQ~@U7~SqrSZKbl8Z4{JK2qF@iU2`%GGu@8Kn&FZAi3~; zYquIwv`iVv2LKi+UQ()oHdne#Iq+NyN(s9%;_O^eN?=4?=nSK|Ss(feaK4dwCJMMmUcF&;5>l#xH;q&hJO30ACq$>?lapH=*-#!s4!Ru#67~ z+p&lNInvu8L-z(5n#ml-krXYal_7u)>&d2L#zNhYmF>84sf0#F$eh806d!fwfPOL+ zF6{6DeWX+C=F+TwhO}imzhUSNDm~5=t>45BguMQA}mM{bW#1MkCe!$ zaQXS-IeBpE7&5JQ6%Y+jvJA3j##AX*M0MO-R{oMD#LmwT3ggjYhgB*pT#Xf{^;c7z zEjOCIvJ9n=UKn8z1#1|w7;&p!yjR`<0Lq5x>RsE&s^UJdjaGcm`3K$SnPT* z+)~!?_*&NJ2*R2GBdrI&Z>`+ft1=z)5IaKtzb%UL9UxMr;zyDKkPT&q)d12Di0|IL zd|FQJ+a_-v-w%3S0~wDvlB2&v7fcnu=_4e1={yj~=Sm>lMR$}AK0bIrzC?29hkG|v zEz$tw3=DmJ8J2`A0~3miV5(GpJ3Dc&Ur#DEYbwsQYm0qMtdx#`K2C6ml*3F7WhDVN z-c)#g_t5K0RN9AjbC)PmGNT!d~ZteV#Q?3rj4=% zNh+S3M}xW&3imWSiP^)NFPYHoi9yM4AMjn4N#Egt5GvGQ#;+!I~ zG%Kmb2LLpIC{_4R8;Mefn;b<#hk!hSHMo$wR79*;pjZhh2tXEqrF2B1r!c-}`J)Wn z*OIW1p%ccc*qpOL{Lsj(xUI03QQ*pQW(co+Pt3$ztZTN?b)_4h(WNWT=VvUJ=X%FJ z<0sz=!|f#qa*7>cb$C~13`o#X$t?(l`{J%nu#kumu~`h4RjHEWwT&>1O7T2l9m5w+ zR}?cQd{}=Rckr-u03aJ-6x+h#!&CXm2J^{*0symyzTd3u%z9%a-F9Ht25M zXst6JVBjY1jhf~U==}KV49h3?+X@yjr@1#4njI32>VO z;3hjkBghWc(EudB7IbisXtpkzs9A@jpkb#Qf4@gz$hB}unq3<*H;S`y&=UrN&zR+0*K z^fVYpHpNU7BZg#5&%{p8S#zXVY1Ooxr`h@pgR;{LFTNll6GloqxTNU-bT4UPTA=K)2yxHoeft$4>x~&9 zo2O0DNCB{r-`==vaWl<8G+WGXKD;GuTDOo|t5!(lvbm~dNgE#yP=cUcJtRPW1VP{d z2?ihtY+SZLS;JY-+c6#^hYgdWfj&q^ZIZ}EbERsh4&snl6M&4e0J2nAgcS1+6#I~1 zNdq7a*OiGCvUo_bM9!XJnGF(;#Ffgp>RH!#%nmV*fmA+&Y)<0B`0cyJ!{49h zdH5OLkI((7b$;=cmn3`!y6r*GWSRG|U#uzU}qxH;~#bzk}OZ?K?Wqps+So<_Qp zOzs5eo0hXPoYNEKNY*0x8oIDQpcSie-P+O)*;n&p@!UC5CNT=LG&aao#H}qxkCrm= ziBcxg3P?L7cRb<~Bs?`$f>9nx2MK}+9?kXM0mAuiaAOh20+bv{M>n2yH%_?nhHOXQ zqHdanWa*=Hpm-K5Bl%JKARtK)D1$^!p`u{xzh74xHCYwNoSsS=4?Q)Ke40gmN{LrHmd!77qy%uas0-ykdpizI|Jo0MOA;&`U)O zORzA((gdz!?8-&ri#RrX@eDOjBzoCArHvDS0)ON39?Ck>N*>2ozhd@~>;ND^5Xc9q zk5cyKR9A?TQ$;C`5%AUfbORw_gFcm61EuD=Le3HyWLjb+(1q*B#%e_}SGuv6WvQ+r zK&@PSCjFk#{rKFURwsVIob*%&K;m%KR1UBKC}Sbv&)OXUS+!XsNe7)x1LP`|_@Njv zHxxms;;K0lEY!JqsO9zByiqzK_G~z0fZWE$W>V*KtgA=%%Dzo&WDDZ69VlmqyS%F{IgI$~T|L3XT%!(pEyy>u40xsUGeT7ojq?o1tD%39;j^zy6vHkUxL-og`v> zT`cOL(W{nis(N$tsboo(h)no7bAF)y!$=2mL#B-SH+QGQ_=Byr7h70U*LAP^lJ zD+hIQ!0A$7BqPz?G}7|9|x!aD{1s`5w&d zrs8Lk5xQZbn3B+>t}MU8V!C)%<>zu0>y>A8Pd?YD)rg=78rWBABAGMj&;jsIPfD|W zyTrRodw%eLVEyxTCh|D3)67CxQ^dpRd}v^@1Mx>=e zXsH=M*@6^f_)U1xWVzVZ+8i`k(P9W%?B$ zv9W4*?<%epDkw14t5aKn<~%@T?^aRO1k1+8DT`$n8m5Z)c92bMR3|-0tx|sYLYhGc z*&FdA*)rs|I>dy@#dT}s{F+tr!^1CgTFKvk#~jM}5(TTq8lV550U!x9P@r^#r7R2g z)sDc#a*WaHleN>+BmvFNoT_Cct(Xlp3i-5_A@ipIU=yWU+orNlr_h}QIbfK5H7Q-L zyf_1lRjT_!S)i1ZMW)xac|DaKX1$Rl2Lq6X+nP={mbyLQ?9w%+Oe86L)B<9n&6q#3 zgl_BXc~T752-maYGrA|A>(gSk?w4|*fvP+}_lb2d#!=32A@RFUvAWPodUxxDO{(!( zDRt2du5B7Nxduqq2S=(5B!m5iF|kDJjI1x*=W1}9M-{6gr!ceQROwI|UDit~LP*&SLRckA*@M!lfsuUfH zPM1!KvBYy$nNU;P6t!{uFb=O!sZ!!x-A5`^t)?tvDbyRwM+GC+ohCKFdG+Yj0y;Xd zsCugvuMrbNiXW?IT6rz|fG)@ED#1@hI>zH{|58oMNRn|J0*3{yLeFS&3yLVe!0X!U zx!$?Y=*f2_V1hs`Q*0H~3~3?DhAKeb($9G|v#}w_ylNRpZ8K>x7VD5xRMLZ1GHS_O z6-PE+k);5ciWrjrf5h4I6-Q@cEEv!*yNzjPA+j`n2fw{N|3>j7$~Ahy-K>v`pzSB)bc05mY5A zxv3e9=FP0&XdLr{_=z=TAtWecSX${w{*_Tb;PfTFnhF=753@tZSUYCyr<0R{U~ z;F#8G-$9N+UHr<`EAr_F0G_F}DmO;YKOcM~58t~fKH))9!OKJ5L)Xa9AKsDQ9)6Mo zl>hwY7ikHCgUAyENs2V~4~W7Ca8_t#{kzsxOql z2>~0)LQnuWgW$H7g#tmv${1ZjY9)I1Fh zkgVXd~vg|U^sfz4BrQ6EV#}Y_aE(a6Jy?QlX*K1gL-5<{we5s0ky(mcJ z>_Q;GNCK#sp283O7c6J}e9uxNG@4dMF9{fB0kT&#zA1&9CL+-TR~DO&;#PG>43*cR zNKg**CO?G=y79Pmn{;Vw74PjX^(8{yp=2E_uqb%UjUx>?%t7~KC`w~S*@i; zLN|W?`2zymeuL;+Et9Z3&B;n(a)5*(|XDWGhS`ZiLYT-{N_-s~k@DyYory^U~p#%7-wI#Sw zBk74^{e;Vpq8s4+J7piC&!csbSV8;i7az($e)wAc`OA;;ufPAQ z*3SR2sUde>zSyH1zE3F+3 zZlsaeQ3M5KTHPDhk{YA>Nzfu%Pgp|oZUH)nv;?j8s7UdKIsgGVTDka!bu_@o_yDj# zPrs4%Te_`=aI!|cVBL4UQW2nJN*1i+N{nC_Jb#gtw71KPBcDUbj#q%Hb?!^u5@Xs8y_b= zAXmQ!y;tLLAH!eM#$<}$$V~BQ)L2{qN{6@vDT^{lQDj?3A+CKA5Ocb+T8x>!-_qvi z`*$!O*eWNM&y(ZmEZIJ5qU@eHTD;<;r5?&WEPaGz4w4w~edE`G zrK1CkRx%J-Wsl}{m9z-UAZnaBfay{m(cS%DVO6YA-27AqoNgS%VYRRzp!mJ)F+tgRMDY9$a_LMjEYyMrYqL%~2R zjZl(uhl(Q!NDc(r40S+%TqArooc$5{-0s|G_{3}A+*Q~7e` zWLm#I^4U8#Ek*nz7*!sM3B}P1=ZbHiUg8CHfl4i!Nx8%%3671H?;(KoD6knB*C&C| zXnt1U{^TyCKdwRf4nkP~YW_7-U5& zHLER&BZo@p;%Sz|4gpxDeG~LrHdo+eLZ=`mC%^pa%Tf{jl7T4l8}X*uS}HFByjb%X z0VZ?$9yqAPr2`;dj{gF5N{22x2URp`FS}BsT zf47wJS9+j7Vv#qw#vS^g12%0@r2}`+;50oNt*?)&0j$$SfVC5>50v4gr*IU-D~1KB zVWt%-dWat^<%YSla@)8LcgAO0USU&&~F6(*-IM3L=3yK8A_)Y>Z0dow#`@3)WbE$fK!`&*BVZ`vs@c=E!a3qdrs=u)Y9e6~#&}Y9(b!Pz0VQ!~ zfRVEmi3R>N)ugb;z{#?PMl4zG_NlS%*pm zeLG3`G$d`{wyN`^i`uz`vXH(LkWDV4l;Oyrd63_(r1(x8YI0jay)(2}^=qR_8#+ON zl*RgRkI7wSMwM(QT1gGC8eNf=lW`<1X_Z=2z?pO zO>|dNhbu`UtlzIFYcTuC$4Q86Rg8oje}fDu4^l!+XsbTBb4`JVZsy~XH2)qb@5qlI zB9?sb25OHtp@er^C6KUaUx~+&KRm|9> z1!Bn7QrO+uNP^A4^_u@O=z?x-8!O_y)m_y}AjV=g+HhM*o1>+i2(>=OicIb>jx;PN zzjE|B+p%aRS3@0s2c}YY&Kx1HyrSIJsAqIP=AD)vlgJxIi^!`Wh0_Il4ZzG8Fi;T# z)Fy%D2*CiJ%9z_ot47yOQ&Q8U@-2%=5TyDYpo3a7y^cgB)Ks7(#VivPIr;7jtt9b} z-{cZze$0hT;>^)Q<+CfNP#3(U${4>r_ynqSRu|M7J3cC#YCQjFw>1ZdK|=Tm+1Iae z3_EAflE(c9$RZ58Ne4)jMWl5DJI4*oAfKVVRKiLDvRf-D7wjW1XbG_G`tE7L4jFqi zB?qBaneBS$R#Kbmp%DZO&@qmr#3nhb6cKBSL=H&FM)W9)+9M`Z3ZtF}; zT6RPB8t=O@Z|6R{SKv*Y8t?SK6O3G??8`_;H1H;v8f!VUrYaaXF_6B{r1>$j4c3IQ zq7(7nKY7@ZwSV^yFUo_!yWo znDh9{=O4vC~bb5SKQ{*Rh9i8+*1vx|bLa@$d3BN;GF})_q#F^GR*%#`7D?y)Ib?rKa;l3?fFa_F28(GKB9Q$W?OXi&! zuRvq0X;?pnqD`qQv{EVIVXl!e)9QfEkT?*w8Bbc8d5w5U)#j#%TdRgr0{wxBX>}wX zpp1x1!pJsfX@|z+-vN}b5y#!!xlUG&%apZ~M#`%3nR0H;A|zS%%GXycK!p_Ma zL)u!woOMV8bXrZ*%JRtuYFOa!Fbi|dxUupQtXroElVk}1S$pj=se#rqL#d#0>xSYK zAE7KJYmQYqG{yXm{01P6(c|#&|8}%!WjCpT7BO?l!%U$IM5D7d#!n;Zt1cSwW~sQq z9!Ls_k$6sbmVl(ZN@Lsv7b4lT8bDkRKpyzuz9ctnER^%adyVbgN2bWp^X>A{3CNgsR z6eK(vD?J$2B(-)dJ(k2q_MI?9+|nT9@8%*ga9!Q2RFeuw^w?oQ&EX9zKwUc~=K#Vx zu#%r1-2nlsJ(_g{rS1E7E^8B$bwILV`OhVC4B(o9X{Oh`uk>PeWIC>GDsF$X(!_U8MuU5?!3yvH+o1$eiAyD~};!}cD?RvXhem`0rpqwC+M7Us?1!dNfFt8obG*$0@MY7&}N_(Gp<)!1BZ@_97%uoI#@_X}}hcnuTOj_hbt% z*dUX0W(t!!9Ba;z0)~|&Ie-?j1IiyOk<{VXzin^7BPTKSx>@JWM$Opa8QqI{r-dt! zjwJyQ818Yzh#zfSRvnZ~PEcjsseYP7OoSK|te%-lM?hBV)m}VW)>FdArQ9)|4gG^Y znY}Or!$kyL8$WlxA{paL#*nq~x~91KEk?64W5}&<-NwCe0sNZ6M8Q*F~f2cT_)%pNEluc?T$#&?w-aoicJS)1&>xjo@pFA%!P!p^RW=;)QGA5=R>#3GBE_T6) zBgz^CrBa~7`H?zTw34gw8ghVl7KA*C|CHgHCXXr6m2F@vreP@sKfV946%-3BQ)Uw!mTUna_uRQBTaXCy2@K?WU&6|hh<|4?$~Nj<4zQA*u#!xO_)Qvy zQc78|cX3g#aR~L7Yo`v0eDmp3w_H8Z9eoVtj$r)c?Mo7ap*dr_c9DlCkIM;+-*a=Q zpyqPSJ99~9o;WF8*Dg_I4_d%d{%R!LU99$4KNSEQhf|$Z2L~IIaeg(%43O6fsH`g) zJ73X__3YQlQp>dM0MSMWEL8DfT{KOzw88JGBF{`Ktt8!74me5#Tc;KhI|O7`sIfD# zvjw%tUEsBz{^WCsMx(cW!{Ai2yvH+k1&ZT*zKnt@TtD26IWy8IU>n^D>`G8|G^z%m zW5V3LORM2ZD~LH96nj$jI3{-xhgHl-R2$eCJ%b+5qNxNfD6OY`)k>JGJVoTk2TEnm z?3NmFqqX1haTYW;!hrQTHZ>pKzCjwKB*|KoIUZt0$X8H7-!fymIHQre5JuXOzBY0% zXo7Pf^H1xBQRJ@|QnDFzN7?RlMol#aca_PTN^P5{8w-K!o!Ljo)FC)tz-yf9rK;XZ zGq2U!BZ0Q+L$)T z?X$DNRO(Qhj}5$VQJphtstrlYNw=<2lMJcarIi|f>QuS1l!ZoXFrKH?EP(gyjP|Y{ z0my%S{W09i_W(|7?a-{N^Jgq10nQQVzX6OZ=S`Q88s4%E0DOQMARKc*P_98@CqLX( zXU}S~5G3#ZTQ(~|`Xeb*rE^Qe`b^Sy$2^n!`a79A<)Ji3YZvsgFO9sjYL7~t_jhE1+)1?UHFj(Xc@%NQ(?OV&~ zecR<JOrzSG&d}3R+Eb8%Pq4~ zc&+Q{BFUVSqFKl*sy<0kWrDUL0NiK)UfFcxmh8BFM-JY5Pp*Catu$$;l+D?p!*TU_ zk7wixMB_aE@J4sX1Z)CZ%g7Cr30fDMW=W-E>y=gf3F&-GMo}kI1C&+KDUq*aF{z3c zrO*|#rTW0GDk0(vtLTJL;EtGC5xQ!QI3&jy8(;Fh@rIN{q23)?*d~zepD}j09NV!$ zZk#?W@0>d>cOmg{?+Vt{v)Wgz+vkp9H2MKKxMi)(#)$KQT{}o^XvzlrcuNb6IX}K+ zv6{a8#gRj5UL|KtJ~)0D>gN#T0uW;pQY0WDNv7evJ1oO+oki26+VDPT)`oiu_6^oc zkNAvB;rWqRRC|}AZcgHhSlKSXTM7cq#`Ur7k2K03)Fra&>}d7K(a5ecxkC#{Q1bik zaHBc5l7Q?0o!r%+(CvVQ+<*67IrH(SGIIq;8i@OG45OZry_k0zxB^pI9IxB0yYz(w zp|uT26ZWOWWV0-j4{CZ7bnYu%`;U-R%+DB! z8JO)L0U5V+mQ+C2SU;u~Pq915V?D*!(>mrWSzHR2wG%g-zb1IaY^#=WHOG-*Q0p^v zZW$KvnsbV?sz;(F%NR{J19ZCj0AqcO*=vsS$IP?m;IiJ8eRtlKWAA?`2S6C`*SM|k zU=?_Z}rWJb}|yh@kZ1NHSsMO->^_U1o2D)h}Yail*cy!nOka~g>fgu zk#I$6J#KTe=CdmW#!DA*Z&F)n%-C1)kbux|^i4utplmrM#a{q}YdC(5B!c{yx5$Z7 z9AxtvEawX^DvOotdhPW$q(td5Qn`}5a$o=P)rXop%Ub6rcjP*v3NPDX9i|KD*`+0BHYTcM2opLLo7EGi=x}kU2w8q-S8;LkkZLvj zB`_>XeEb5HOuvJp3ku-nrBIQg3b49@x7E$fpI@TllBIIB8d57c39;wr@)@|YE9cLY z?j71l7c?HXY}H;Gw&*DBdkvF*Bc{mUF*9W7*qJhX(mV+V>AmN|1rT{&D;>~??c1Zh z@gD2`&CfOH)i+-M-JQLWx)4^*7*ccdORe3@}>V)`_Q3A4OuPDW-b0 zM}2tdPrM9BP&(&R^ZHEu%JQeR)7QvUYyX@ zRkN{{5e@eBmQEP#Qw5paU`$MI(z1gL7%^2cC(f72b63f{RmDdKqM$fPFWx| zkYF0IeTQ_y^yl^~mr4of)#}#f4!*MIuoKp!;>g@S$Aa(-K6OZqQ-lZujD`xj@iXg@ z6uvS;J&H?yjlfeE&YSSB&uE`DSmUzl*N=3i7N(a?Y=cWNL7q`_Spv=iw)^@CsAeyuMVRl>j z^CVbF1xUn^Lk}O6ov1}J(|YoQkL1?3KS;mK;XGC{iXxx#IP+fi7rX+L?+{<8h%W*Q zgc>gf8Gv!*fI|l%9dT22wJUd34H?zk)!f9Kl(j_MR0YzAue|vNH;B1lO}$r0U!ePA z^+Gl8g1~0H$tGZZ<9`b4@MdJ#o|0XMF3WBJkc;2%ICx2|o%nv!u2V8>{A^_*hhQZ(Yc4|( zBX^}Ra>IJ^K1vH89@r~qSFMm%wbI3@Y+2)d591i0Ru6Sg!SbNcO&eiJ?3mqFtzp?J zd}XN3@n+Z&^+=KwEP#XyJ0Ja!OQ5aO7fGMy_>6jhwX@;IO*w#8tP@D=T>RuSS-W?? zc%p2DV>DC@{({>r?~tB!1(veYq0PwAG8NoNqf6Z&11v+~c?$~BEO*2MkcMKpk;t*7 zg{e9u;wDFQbm(P+fi?$lkOg%w%)v<5uu_|y0gK9bQm3Dhmq{0KH`aHCHDuiQD&!Ae zg2gISxQMjt+8-Ix-r@rN*J_A0+qdf_l`sIdVoI{iS++%X>HypUYiM2s=eq63WeDO& z#*m$Q4V5D(D`US~*oB)s%vdD^7OQfd@= zp(j*J>{v@f*^*%Fj|3s!XvgABkgDb6vJ#MURXlk~v397>ItiXiGgwH*k@L@=hlPA! zjv=vg_Ws9m?X%C(1RlrZWcP{hlRo&o-~aWl0Ar2Y&Q+_*e7L1O&~wKPK~VB*VoZ)uky*4yr$!mXi>?^l zQ{2G;v1yD9nLJN+9lWeuQw7F@#@9>ATCUl8L;*5$>?~>2x})@hCG3Pml@}&qJ%ncL zm#9^Kf#Ew3FPuiB^ac6h@_CsxaDbH8#v^=;JgjxFBdJ4ma;vD7b*PL2CpQ=u zST59-!T)}U#SE+Y!LEc81ZBC%5T!T}w{npJWMz%2Mok~aYu~?#Sgvkdth|c}Q9ra>PfH78zlvQyKwk0`4)hDaQe9XKwTg9O@al)cCha+oRezE z1oODDo<=r9iC&cl>A{?7wWZRT-Bu%1U{b9sq&F93D}OMtgNACT&y7EMN+ouB?qQGQ zRb?She|TT6e*T5*Id>in;L4h_F8XH@QGcWv*BwW6zl!8Gz{nO_?GdswIgc%(*>iVQ#R;Fb4A;(|2xzsyCW~ zF$|T@anrv7_cYYcSAN6H$Oor1?&)<<%R08{DBT7@DZOdtNSkl{fkyUHLRJvp*!Y5HkHV<6zL8Zv1OZ<@)f#2zJL3w zY6T+)*4jV$p8OM3yp90xi<)f5(~K6UD*W#ynb_d~9!o!@=2>Jf6H@)F|6cYpXvT6XNfWBd(^$B_5< zAGrbnIL?1o$G}v6z&)W$nv7N-0+J$3beX8AJ>i6wU8TDkyJC@Yv9d98RC2;P3y~RC z&w<^fkW+bXipNp8nh&B*vL1fj_%v&Mc@EoP|ZiXgfu0&#v9``&S>yo~#A(hNfBjA=Z-^ zF-7p2Pm6g~R#K9WszVw&JES5S4a>a#?5bhchbn*Qu_OV>o8dIS zi5+BGFMRxo+<5SnEZdCXyI?Tk{pb9T?8Usp#1)v$*^eBUy7I>yk}s-Us% zNGS<+veR8*BBBlSMKeb8VMTP_|bgfSsI{gDkU)oB#lF1x2+euAYXCC zJdsOB_bJjit<+a%Ps+m+N2E_{aAKnp#T8Svf&i$c$o^*GrZMu^ab?vL;p$bbS4Y|m z8!1y~uaG^67gz2-Bi**`kO_N^$d>IVrAx0N;@_a5q%?0Lvj+{32uO*H?9o+mT)%^L z{6(KNY1>uucaYmZJab&^OO)V7{|T$YQ|zMsMXR`BW@P3gEhK@;Ofxl!tn!dr31sYv zQ#Ns=21v&BSs-xqf`E0u{d!fS37~Kl(R&=4%_&Jt4Ozvt9K(c8Ug>a|ZNlfT` zgZE(V@o^9KUoxu-nZ;Pl7TE(K=3$Z!jUM^_3vCJ(#I3$UO!p93&j7FL5|ErO_FmP* z1&OHE6DP^gO`BD$n~dX+hMrCllu4Qo8Y&ZKFO#f2CnXIxlGM#mZNqCOP0x~;rY$iC zGFH~3%cBGIWotF8E1w+N4}q;CP`Sg9A4}U;cI5%KaQ$-cZSjJ-0FIaLV3nu%jAs@G z;oJ-A=jJS{Es=sGi_rPm=ST7;*d1OAZ;D1@#~_>Yv!PDwq*JG)8zz#?KYvb+gBZX} z>t(vF-~TABI(0VKM&qC2IP+fee|!bP@&5nJfOXu2$-EPgB&dV-9=fY7&@^i>L*}3i zQcop%p!>3FNw&;tZWErk(KunaM0J(Wc?;`lMsHK-m(#W&0n$`5_U@9vn(^`n8kRZU zoFI9CM&hfO&|I=)39%0fl7QGG@c?tD5IX%!AOea23c zx!VqcWwae#94BPP(hU+{ud&27Z7M^0b(i-Lqq$b~kolQI<#Tj_JcPUY3*$yLQXT6P z4Uj(rplp<;EBmjH?n=#2MdD`S$^R)n!{!C;OG}kL9dpP+=8PjrqtnVCM!Or`R+c|B zw^hrw@+L`=0K<$`0OfEntA-ywAiI%mWu}#JH#=dhl(cKQ^jl=qVV z7gu0)StmyswPLlbgS*-bh49*tiJ&zZ0!y+4VoS{Mjf2aiv2zT%oHdzauBBP-_=q2C zj2oo79dOWpW;#=S0`ko_UKg*nEhQR5e~#_mBL6@iD7C6Q(8TpyAF`{s84zZhe(@&nX+*84q1Zi=;lM`q-D2$=;&xK zz1p^s@9_V!Mh%zIT{~ku-4W%kQWEkv^iwjK^DC_3-@p1;{{Ah-87LPP@g%RBjPK!mE{k*tt>C;O7V<~M;z5u1Pqb@lWYr- z*rD4>Nys_Ks`fju8y545ocZu$6-QqC>^{ZNf3z(9m6dBtwVsBM8+mzor;9GylXX zc2gD-vp^P1n<$m*q)SZAIH(7FBHvyVxoe=ueTiO3DhJ%% zy#w{e!zzQz5qO_%-6rqOntAD2iKRvVVbJ>8kIS2h7iIie;8JBAzWDAFxAXRsL&CNqd{ai4A#zBxUE+{{YV2dOrFC~a+Fdp7`au9>@#OZ^rd(1;r@F+&Dv1Aq|o#w?jH<=ot*KMMV%!VMcYTbj1+EE!$9OB_h& zbvt#JsEm422}~YOj4(L4Bul9Wd`VDZDL_J7=Qq6H`wN%Jm#2@)?crnPhuhcWIvSU+ z4j(GN<0irQ^6z(UN^jIIbwJj6ij!lX>FHus+?BS_<7<(++nP1o5=YWn8r>gSkE9+) z>VRB|WZW7wCvyPLM4ZFgYuDtQiX%Ujx8SzE``!1_6>^^X=(pWV^wlQ+;PjGuK%V1uXp zTsIdeQ%cE}m~~oh89Q3}W3;-~hRaGmu_2wp8|8eR)5;_de_jGW(q*Mi>*9+SWje;{ z(QUm5Sr5jMw@{P30GW@9?r!`{C{bDMDUUhtW&edMz&5KhRiHC79V5!OK>}jY#mkC< z#V+)jXU|(o9dwN-XvGbY00CkpKatCv3bm>DJQoQ8Py;B0Q2}_LF;96uDZD{cbas+U z(8Qs2WM-2hR!gR14kP3uyAK|(N*GJl?3S3++R|~#bXkPjBc=7@VI^HslO-}K4VDq^ zDgepF?|lM6%j?)l{3F0^9X>@G^c^fg&6+^IqqPF$_#WNl^vdPRZT;%Z31uN496uyi zkb%95S&%oTWyZ9kik$G)Pj@##BzG=!u;b03_Yk4cBkVM3io}+`I`uex~Y? zH@^5%J^*uP`1lF(x+YOM_$iM$?`8jmE5JLtgvKYxUQn$#A7bqBXic&>TZz7o{FjkG{g<{QXBZl5__dNggK5;|YOvi$rpOB>*=eul}-pE0Wnjab$s zSqee?_ygvKe1GPY3~ATa=#k{uzNdMNdJ!IgE9RR7U_^Ru<)Um!GRBdLwWGz62Dg|~ zmbK)L*7?E28xuRr5l61&ybp+8Exd3Zgn{#lAi#R$4aAVNl1DCIl^Te%aj?|fDf%=A zo%fpm_g7#$yYYKMSa&ai|Fwucx`LeC7CcgZ$ZYM=vUk@|klw3zeXLa+Q`_vSxnsfj zo+8N(HDmdqQyP&4|0g|y@q&L9fb}@GbCY7_P>c22@%<7Q5G0dktpN9wJ&jjo4^{+R z)~+*VgIi12?TXC7F(*N6}Bnb$bj_doHrB(xZs1K_F@*45|C@Fr`L(Tr+xoh%}ym=CktVgavJ#sTN zc6Qu)2j!3pAPIaRmyN^@tR!Q}rmfpZL8vX@fTupqLFc{Z|LqkhgMa_P7e#FjY1#G8 zJq!p%Z4T^~5m1<02|lPAsZEhywENUEMwnwW1kZz*@gvCO*|LUU@#r%yo_5Z}09waX zWK)@0B>+CbY>uW48^{#U-q=X2b!%Lf>2p>}TB|lPm-2{4I}(mH86}FOMone^k+)>; zvA1N|y1fA9On`El#eFs0SXxTY1`VWfpPusW)~%}a(XLL0EJB9|V@Ngb&cxEmHkBFA zvlWY-Amh<5`MOrtVPp5xJObeg{FCiyEPXtxk2D9_9J;rLA{|RlEy0*tUx(A=@y0_kfBHb-zA>Tsx$J<{%kaxa%DErQw6K7Y&G9rVj{L>tG-fRBf zU4hvp%aoR3vu4WyP^>s#a3nH}?5UdrX?nKws3ZZbB$cvBZdN^!h#w6d7+acLwvC0@ zh>f_q?Ec!PI1LB9<|7x!3UcklL5Luu5D(X|QT_U=j;Q(=^#t^o8s@M*t=Ydg7jFUhBgNws*2^W;nDEqu;)G)~ic zR19gpz6=rAD{3??lg`L_k>nQ>h_sT5v7_@^nb_e}EPk##ZoeZdu3Q3Z=e}G+9C`DL z2Xgz%ujHejevvv28yXqnKU0!=%G1ny+0$MDl8b-w!wkgj_~1CCg|i|0fH&G7a)K+a zTvzTY0ZA8#WB`^sQo-C&Ls+pnaw}$ApBt<9}M^0QMxFE(*afziHZ-^xW7w+H<<@4%}ACY??J&ncNu;p=#EN zH42?ZH0Ni>&yaB>r6DPvy!IO0{C94vOzRC;$y)&A-G|@E>6^F2qe^8S`x&gfA+Jxd zQU71OB#TA&1`q;1cK=i5)=-wCCpra~WnGRBld%cKd3o2>va4E?GMOW`WPqHO5(;yO zA4{Q2gCN6tQbMN!Uh`!M47Zsv9z}Op$ImgKwL!i5vToZ6i)ADrcOSYUk#RMp%Zypd zI$A}aF2m)%C_ym^(xzPx89lz2+`PR}Zrs`|S8r^V^OrZs-h)eJ^|~q0-DxF#hK^N) zfeuLiIHKh$0EwUdKis{cC2%a$vrO$*ir{`iz5yVoqmj7)VsV^9 zmp}1gWfg&rkT<4e*-D<|>cVpJ7Fjzw`9aIJu0&tzR^_&87SaHume}D`tj(w^?|$bl z+Ogh6Jb6p2N78LItmKcsNJofI_M#0U7FdTBxYqjwz3bP`|_LAwdhe+14F|uplT)BE3+B9>=s00s_JuH7jckU`)aWS%fJd#`U zW=rP=^)X`LpnQAtvP$UWHq3|Qa$3lT$j&YqHA0F*-45rF`6oW4zJ(pjNj3C|YF042 z{D}rqtFpOKVoFeCbFCFisQ|)CGP|rA$91=rpB+PvRq%c`>N7tMBa6Q84$0qh7@xx`nWg zY~f*X*#Kl0NM&eKdogMbIxpr?bB`iLa}J~z>UM=)9r+ClnFDIY1UDX9~nC)Wi*fuQ>Ljg<7VqfK(-k(UZPQdT!#AOh%r+j$uU~`4H*fG z*k5|~8zSvHb&wVq8PFC?opoD}E7`}P0A&U=biy!rr$dv*at?LK4)yA)nIB(+Gn*?Q z+3f+I>x0u6UkBHAD>$&_ODk=ir#V;STGY%B!hL1TH8BLQY@57oU0GiH@WnIrre%#L z$ZRVW-|Qm$gx8v5uROB?IwX zm+k|lI+7dds7an)x>&jcm;@w~Hn~|xGIV~pcN1>yVMQo7yLy#4ms8{i>Hdm;}Y&jw;H|&>(~}VfiDR*WLkf+WLk9z50V4$+(UqsaVALw?<4m10J8|^^7)_G%!N?;_?+`2%}VCB zHOZWy93?T!=IbN@&28o9GZ})(BnB9g9vVU5y5hBRR2>s{hj9ZYjqU_$lGhMN-b6i; zfaLlR?48cN`$!=OP2(I^Jg4~hubwtL^*?dN;F=C(cMjYMQJ9i-)f_iy-d+ zICmi#M3C-cOiICI0CGM?2n-xG6=Z=K(x`1$%&Kf5m4kyM43Ay6y;~Og9!nr( z>ahOE7?WV+`u5C8sR7wZoC}+jeV+1D<#oALE;XOIbx{i?zig!$o ztLIamN8Zc+%`32?6vU%OPM;x{zxWEwjSm$dS6sQGW(%@rr2wh4S+1#W^!iW+NTJ*X zr5=%T*Sb4$2ciX>aH+^&MH4PRSYu?sqYhb3A8uMdLk(eNy!I1H4c98J+#@#!pgi8IR3kA$3=6DOV5NHbvi19w%Sxia zz|6@KnNeSY(WD#?F6`$ZnSTklmCeuwQ-^UQ<4U@-sxt)cD!+aQ4 zMX_S6u@Wv0KSa8%91^O55t=$+h)_F6Sw8|2q;X9dP5)WX67qMP80-Kyj9g8;=d{Nh zlox*YQ$?s0+($O^?+-qdpFYy$9q*vb5*ZpHtM!t{C^Q*+V?^C--95F$j)uF68%Xy# zb1}c8GuS!T6(9{z=Jvgs=>dzmcH1$45kvtje(lw71XKqy#LeGN?!)2`kl)?BBER9- z2u8+~nq?#qt?gQzy4<&Ab2Wz&=k#Yv2OIO-l~fAtRBC@zEiy-o7G6t&KeMey7f39` zrTb9#h@~o(*wGXONHkxEq}?`jf9$<;4|=U1Wbco(08+D*_fVURg6=KO<6ErCd9eC_ za|L$44kk&@Aw%T`E;#RyR3u~k$U7&C$1EbVm`s%7C^sHbmMl6xMcRxSlP$AqSV(?dfcUXq_a4#>>T%?`=CFs0a8!wkoZABGO@#? z4jY!u^+jQ{k^%yV!qZ!n>tp0zq9iQ+2noe-UCnrPb=qnJ6KZm3P0r{aygYN<; z2}o+O&}AhkCt_AaEwFN^sl#z|5r|m=4M5`V90je^PHPrPvlVkKEm#Iv{U#5WqG-Ow zdy-Jj8I#6CNphH1Sxi6Po3#*9{l}H%Vb+qH{fi?9BoR!UtabZjB^1RI>Nm8^wJ_pG zv&%XU@ls@3Eo4$>Yx6sF;3+rNR5md`Z$1FcMyfegp+n;^KTT#*2S?Dh8tR@X_ zGo1rfbxU&`nPbQfCSKvWy+^OfbUo8Lbev`( z`(tpcKl(%OY~3v1;COCt-6UIPOqD^XVb+CyPegc_RE8!^sIR~H*YJZi^%FPDu6!NS zo$YE=7e`q9B9MiAHUFEu28@v(_h|nD7*qB!VY$xwcvM|d8_zIG&5>jW2t65w7pxa^ zsxrl_jnW6h5Z0Mh42jv1%pIKj=o47T&$E?23_u!n$)RJ$pkGq4cb%|lhStf(hh0>K8PhJ9Xe_SqruKG${zSS zY{Mq0?jJ1M_9825#E%9D^>K5Y1If%P7c;Hf_Fs_oJ5I=yxhqvC2>T@|^$`{sue3{B zLMLY!5*!U%wU*i_6UCyV!)NF~30<;4!ZBjNtE!jSySRyidu4F}APZpBdd1r5k^mjp z@JZvPu!B-*-}Qto7KQivqXb-hqYW#Y;=5_oKn{8x+|~$)j442>SW+v2Q1giOV_HWo zsiS9EZ!^nEHFJtyeXRBYlR6sFoCJY~Rx63`?|t=+q|~m>bNB_z@7adRf9LEP5(KW0 zYPj^?`%oNvsJg|etHL%Mekc^u<><2As8Lb!fu#>}SzB-4B8{OK&s(j;3zc^8+u1XNjzjX z+AmomaXU6k*s{eE(Yd|&2M5CP_)1sEGx`LC;n*unYY@W?R*rdku%+~Yn5pH6(GruC zs=!89)Bqn7H>^c&!0g9WTMny%Ity3sQ1!<#nB}1oI(h^1Ky-fig+_{ZSh&2D^&&I2~Fi{Qk#c(5wyOO>U+}q00uoY^n?z(cDmF2!)rTtfQ_jPb*0`mi1#M z<|uf@n=F%dfLX?Q|WEq4d23D@d`eS3$T)OTMa9@6Y?Fjlw&aeuq~!fwZ)8xrcj1F_+q-8{qz zmc`MfqLguR7Wbrh2^`oD3T*S#H~=Pa214o0FE9*KjALXr?)KK1h}J`U#Fnj; zh!ugjY4>T2mIFx~z?(X6wTzs+Kv_S!ql^_v1mM!*Mng?twzL7mr?P*5jM}6}&v8=KVPEx_i6}^M*;^62k_T?%_=`v-d0={>Jbu0t1Eqez?SoN~vfKlp| zDp$iK=OWz5Ut`%$`Z8}d)*^2dt5#Y3ri`>C%?uu^wav`{q6v_C#ye^4GS!8Xf^iS2 zkoX`#+hF1~0ZDh2xdF{xwPsii!7HU6V3TE~r6eHlAiTK(_f{YF%9xnV<9UyN;|lOY z-jg4rx7&5=Cij2-MFs6#Wcbrcazq*HP|UV+^fm9C9L};4({~3Q+$TMdVWe_E3k*+9 zTL?LOWKPqT%$9m!>%=2&jDzbM3->ezU!wqNK$gD&RJD+Gtq!`}tNB#yv`jy4YWAFe z1&Ip>Cl^V8{!MUXjClI^i+h!7&TBNA1FykMKC8IHKvXhL(**}7_~)?>&Qt{&KqJV|fF_@o;G0#MMlb zgp^tmlb9lvy?n$So4k@|by!WfdTy1a4@Sz-nsx6xT&hB{WBlF&76O2+yJ{(WAe$JR zm?R6AVnQ-3q#92SD>-r2G8r&(O12EDrmd43Am>Uc#H_Es@us-oI4V~5RL5p49wV1q z6;A-IsN^qHSOKtb(c(}?uLN+Gl#=*+j#PJm<>$E-DOTK=qmllE&vA003T2TDgWwgs zjojH!hAW%B#H5DW!aE_Yk)UJ(E(6w*0@r=f*Gh&C6Lx!G9gXpH7twx2ca_$WH|WO! zl9uu=V#(Bu41T5@CX_d%=TCyN0$%@?v#X1&-@RAf`|bxzuuf3&;*(HJE6EldmO$vb zGQq>Tllkpj5rL&iHJ>98{AmV6)Q<)%;gw1ezt0h z^6?LmS{*yf0wg9Zvk*;59CMe)q=QE!wpMM~v;#zRUE+f^#_dSjELycwMk7|#Eai+` z!8m;4JRDmcp+`};Xfg3da;O^Wke)t%uynr4+IawAoEyU9wJ+}=rQojeE5YaC=`H2q z&K56aCq-d7?aEfbYki~`;z~{u!*zJlAlJ49N|lhRz1k~qJ&uxSTk}1;LDguqRZjd$zI~H9;JPqr}#N9DiN8Wsuj0c;Pu?M&ptbo+4quD~zO0q85KNF>_ zqD6Tw>;B|^e6C+k_wX#q!2^*9p*(}x4S7d*TMaA83>!0Tj3)?6)~6PnKcjR!C!qu} z;@}?XzAj5Tu38{Hc5aql`*umQmGh-R)=a67RR^HdfH@6r?KFu;3{UfbTqBW1k@khobNkm*CVk%!LWnWf`!DXde>QvD~fiYi!g34trg#SegNo)DC zMx~qegk2f&%ImNG;nun#SWXjjbz2_=Qa(>WMk3pq1~9S?Sr34uglFsRo6skD6xI=K zR|rWMnrQB-VI8&jkqUHHm(}FD>Tc^@bb?#}2Uf33(gpW@u2J?UPM)gSYF5P!+y(C< zC^znS##e*c&*TmPsjMV=A};}u+i$(C06F{YDM&sZm(1N5kG(cax~*S=Udi3kW7k$` zwrq|xTrvxQoS^_&3t%K5(@~oY>yP?lSv5ABLREb1qlG9_wwz`i0h;)l>1tz}-Bkxy zHz|fpW!)xily+)jdR=LUzDCA|+4>!Gv5*T;Z|k>YsYE5E$l_JI)M#>RyOzdhB}m!* zu^L&{DRVKX1{TqXA(`-TL6V8rjf;t=_~cp&kOnAe(T$aumVvm^P4eY0s9aXMu6BqS znb0W+_q9;55|SU~4;RFp7HGe5r8HUs>xe}#ro$>Kmlg43`m)(lt#JloCeEE->{Ajt`)@zfNa*Pv&x8e2bVMiV**&{x2OS_fM^>>E<%m1#n7P= zpHdr%oVl`Q+fk+0YBV&PN#@MJ?mG^xAV@>1x+7fU4m}1Vt*?fy^0>d{_XZfXV@|bL zcFnriMmI!dWepYhU=iu2Isl|h^b`Up-^gD;%A&kOQ0jm*XPk4}p!x9R$K~U~Ro90t z=q&usH(i`T~`CGuK*p?}8DE!duP;+*rhF&{KtT6OFwAOG^JrNC=uUl`w;6Fan!bYUod zl!f?lJ}l%6v=WWlzf*dzTOvI+u24z>JrO@PT`^zkDmPUFVohXTlduwz*h#`@|*?$hctQgPzUMe9|j)t1X@Sjw&Y&dKbYG>gi}59-4(D zLF8={C>cj8_tmnre1l;+byjzO{$h|4GF?{xJa?8 ztT;aJ&JTnKAcK`@D;;%mYZXcpZ7qq?EMl?@Dw5?7Q&io>-nS-Ol$?yx?| z5{?sGU;fTbWsbd766n>}lvF>NF7z56^ASk*e`N(ZPq`Bu>@#1 zRO=WsYA&`0O2d7v>W$&B0G!IWVi}oNbH>>CzB012ETiCm{{!nu&Ayx7zzxj@H@3%R zTBCUFaT7FD8Vrl6(HBQc60)rvLr*}`Lb7}{9)M&h!mxxfBt0T}Mg%3v z+ycoX{K`e(YM^}}A3&k58I%fn!^LXH8yw~ zcQ{3x)48m4T{y&(({)!M#+U#gjz+0tD8^v-*s)0(!3Ax$Zke>gIJzeIfRi9@6{)jx z$jnjPRxHLYp_p-4D!_*y&<|LPuzu%w0#2r~x_+sud{73ll`EzickeyS+P4S`wsrSe zNy3=83HuKtvzpT)T9oBX){?3QV=;EULe;9$fACnv(osBCqd{5k^3XD`7nF<2Ssw)C zD3n6VW6Zg}v5fx3es6#v9s=TmO5&IjJMs8AEIMAde%5jg-EYGMw*_TouNsQqiuWMP zg~|wzd(3$m*0gfh*68A(OiC_I;INLZk>zfI8)cwQr!xbRT;o_I*BXKp&IMLv%lCv7DlgYUud?ySu+O6*MLwe=aS5Z@}t`Z;y5g-6^ z9OXbiD~a;Jz|4uVmu{-=QZfnCvBy9OM`Q3jb4P~>e3r6@{v2g0lmHi~eD)~Jj~+i) ziyd_k8Y<`Hwi1xDA!=nFB`^Zu^aVAK#Csg`ME!bpri&Q>GCKiiBy^O!3QO;2D%BX^ zdpsb0q&RAkI_No`{c(?8FCvz8uAin#AC_T7Ho#24=Max&3s~M5$uEvVIMD!!otEGt zcVT+~r*;>>NGc1GVKz5G5RNYX+S8di#TXu62VL7F1Jg z&;SWeF+f=x+}0NGY&v4fbRT3{GjX$J969;qQFMM>LBSS9W81%)Y)6$QNw$IW6l`$p@(_~J|Ag=1EL#LdJ2q#qRUEJTLKxT&_lBqvsnBcD`@ zWQ_TDD!m8gl4;EjP_t}`we^h_G7O(j61^LQ8SU_Sl9N0Tp3ew0e2+zw^$bkv+IRP! zx*1b(@DO!cjfFkIY^=84Q_bsKeBBYeo;PulM+n@D2!R422czH6IM4IBevm2gJ3Ben z@7bqZRmP5*i>hVJ3>FTDbZX7W_Z4-D7nrggyU~<9=iGVefMP!>R{Q{&E{|bn2gu3< zA~$?8fJx~`HGEZX`!UN)aPyS(Rh{K(mDCICKK?-frjLY0VEzU*P%(wdtZ`#;S0P?i zyGctKf;+A)3Bc^88Z}93k5b4f9XAV(FZUhPU);coSpY&gEwA=}FUcxMK8~5TNawOn zQzPl>H*E{uQD1e#NJ_6SW2Y~HTb+Tqj>>}3rA#BuuL@W~WD}_vlGZVyrb^xzyxT`v z$lPK{4}iCTChPGX*5fj*%<|qZj?xEja!*SR;Af)sq9V(xx5P!E>xNALjQ@F~?YVcC z@`8qfBrp_N*9DjtNh%!)16(_>wj*@e4l(8IOZz>kcWm8aBReHP*fnwpx=gb%;MY#m zqJ8dVK4!g!$+unm_EYpYb2)=)YzE&9*qKo?v~zfeqjL2wTwu21tc46DFGColGcoj4v*RmS|IVFN+0iGO=q*P2g))A zAZaN>B4c44b9YrAmC$joN=jgL#erpa2!W3O-{vu9gnC0KiemJ;|8#2`*3$x$SysBN zp|jZzH&#-XFOX)4BYCs!j8?4fu#~+)edOv7HNBP4;H7K}`(L>>pd*Bf>U3P{XEdy{ zX`Py`o3Z%%tytVYTzl@mFL4^_oF$OwR_3EQH-FtmjbItSRXjx2if9#8tcYwF+o~A2 z)9*iqJDFw`@9C-l_yEuWFzVPbMX_oCAlAWGjx~!$CN&n#$RsJV;g#J3;frSKlakSG zpwIEJ02AtRju|!OZ`f?F!DS^6)EC6;I@si_2P*wjxTOT7c^rTmm;>pI(EtQ32<1E) z_UR`rKw$2K5dj01u9TT4&nj?I?$H1xv#KMHo>0?+)xa4Xqet^5YCL(?>Rk$uW`#K; zmSj?A{f^_R`-2*+gH-85YsDhroK!g7!qavA!v#sAM4it{D@kS%yFci%5}4*L5Zi8$ z+^i?-l{#aGlc68?Sjsl68si4%C~FwNd{nZ>Na`q1qFFo+1P*3fNuguLmA$R)v1l>b z>zWBQJ?iWz$rfEliCRh&#L^bN*MG;?P}`M_&RqOEu8ja?CkT%fFQe#^6!v=V9&B`d zw@lfxGIPl?x%2h6ifv)Bibzv4gKG3R(kjw5p@c%KQ;`m)^rAc@~iYx^k&K8hnDG$b%1nW`^Z=DRu4q8YxRT*FVA?wSViQ#rTRdlle zlBDt)fuX7c#2apSb(~{$zd!|2PrW0AwMlb5($;FaK=nWe<{bnb3d>AY(5r$4%1#4cxePq#jm#-VoWFn50tRj4U4q2hgVQ8*Wz-kINHa2q_EFi5QEn*ZBH&L*VDU2KOL8>|S04e84 z_@m&QeeMMHL&u6c#E@SvSxg*J&ui7bhf1m#8=qE*$raZBEJ|;>*3JGCHzg{zCJ5yv zF_*9!x(K|*%iB+CVABT%M@TgeCaYRHOUF_M(T|b+k_09}$*gOuPQ8@^0IzQaXBPkxbU&S`W97DzI;Yhq zEp$4(hFMs}K!QquDua-z19#Oz5I{Zhb@YSkfKPwSrp+i&rj%6e)6v4#$;~1@ircDU zN#(i{oMR*r2|7-_u7`NLKCxqZ+mfpz`-FXjys_nlr`9mzUz@%1O!cki>9skTNI} zlm_c4e~}_GWan;`QKhRo{OED*CZW%$R5uN5t_qmxSgT=kj1SQCTeDf@T(nq?n*&Fk zFUO3JK~NK*`#NIMd}LOc;CTuCjO7#{4eFekY@XZqj5Ga1A}m>0Tep>QWNG}*7qsNj z<3yBwF>U&Hk4`O=_wgiBd2Xcm9iMp}B<`l3KC4a5 z0vUr|h&HgtI&0GMybe$WSOrpTEe0s(96v1{pl#yZE@E-i;WPhWjqFTu$V&_!J5FxH zRV9mpEmN9R)ar_cRb-}&f%;ki(GWgX^8x|LAs9_gmyaN%28$X|4pliOZwNwT<{+OB z!=x*YKeGrf;m%uWU{`TXOO#M>RHsZ|D*KPIlws{bBeM4U0KZ5sEpXKCN@s{UAq9rW6FJ|T)xsD zH9!gCLV3KlamxJacOr)1M-H7S|Xb*3d>g$Y?kEXjD1Odcy{EP&og-ED36h)w$@ zSmqx%ro>6mqRBbb=L~%vv(AnN)Z7Ok1yJ1_vm{x*G5~4*s*NF74N+`P&C&)KS%Ig4 z()ig7Ok0pHz`p9YXsMKhr-Sq2a3z*-p4kV};YaMs+RN+}tKPo1{tcP7I+@&n;~h*-F$nswARdkU1wqnFNA*;RAR z(WzNo@vT`?I*gtGqV|q#a~q9VZQK6yO684~hi~4Tuh?GfWZ@kuU=rnIF*Gw20_1Yt}1I-ZW5+3-o{ApB*aFJp}`=f4^jH6yU~P9 z5ON4>KL}h+nzK@6cx^#xxV3yOT~&%;u`EJBHb*Q>HN5CVC>)r2AT>kl{OZG^ySi|CHg}c4^qMeOT!R9oao+*bd)Ro{u|NBSDP}pD#bkRE-9K)4%}qTo z)8?<1A&}7U4~ozfz9Ii;k9e_yi>tVz4a*%(zZIeI=1|^A>;wEH6&XPzxuktHyQ|vI zw4Tmkq0(pIXxRweRlfhM#TzX0jy#UZb5@`pc|M!8hb5kcWuG*AxrO6OK(_AOR|BLj zIg%}bqbz3jhGo^sqN^Z0uJc0^$f{-l@^O-ihl*5m(np!wYP4E^wyg=9%ObYlCxZHD z$(*YUy7n1!QNy(^V)5x1KVVqNoGJ|(_%vW@R#SV8)q*ZY8(fcBbESYb*4^L+|4#!i zw}WRQ=O-suSDC+YlbnWSq;eQ(O=Q}zI7?MA%a9yBX``&70-**(T1N`!#$!5?CH^uc zM+|@(mWP|23gmuzxx=_qdyX9_C7d0lZuef&8dHe3W0t1v)$EkJK$> z+phhg@8hfhX|!DB1f`+3qxX3#HczsWC8_inuB)a*r_>3!Mm}P8Wc(Dr&kn*@Wv_O3@qjd*azILz0ZDj(5 zR*+yM_@>QYqnI+&7pzs!F=>(s$qWz7!SLzZOOoMkrXc;Eg8Eo0YGeF40RW3zvdG37 zTHUN{#|uD4XDyJ*7;uvb4Oc46F-b%BlkPGFtqi$GzWxSwndx=8v3Oh*w^eDJGPzSBmmNFrwF3F2 z+MsThX;`_9j<+hCYh-g<(3*i6gj@hK=*GB#?0Y~+Ngmx= zE=JCxR;MnK57V%pMJvf7>$kztQF0J&DOJN*S7Zj2bwy zA%UYYV5km04X)x!;Z!N3A()%JOSgei0f{M2`!!o-%lAqS-&zMXyQ)U)V^~YRE^^*% z@rsND<7b|-kh>3GR;mHUds@YiXDCkVG-&qFQd(-I$PRBp$%Z1y#yEj){YOYS^lVaU zBnKc(&C1r8($u^R%Alqe@aTR?TFF9?Q`D(+S-Ajm#Ea-Sack2^O~ZQRu$^26x!R5( zFp@va1w?_LY-G{1CB}5GgYN&JLx)v~DF?w{@4DfBGP-W8aiuAi#EpOWhAmPSVF=Fa zN31H(iiu<*XGbB(Nwfo{?D+jpwZx5X71uyVM#YMkkwMjCMI&`>4#3r7Mdre6VaaFrJMjx>n>PR&01bn&C7;c-3Q64@&HVD zOq{OEYE_<7V6?4A>e@Rbqx%Gat)pwrD!ti9l|bOyQc*#VCHvXz#0V1H%S4At&;qR% zX?9t2izjoC{!Q6g?RS_Z38|HuDrB+Nnr*!ldM*PF9>Pstvy!>%7+GtRhQx~5qEgs; z*t!i;s=O+JoW)|_?*IHFt1z-vLubsCgJ_#F4^t(lkd!5|CCpaQRuqaLW#+6Fio)53 zdYTg>rtBp*zviya(#hobAmOUIG)Ncs>eVG4F_Ix1ObL$ICQYSXCZ0AOnkZGkx$ zu58;L1H>sRQj%~yj{=|h`P}Z}*#L_F6Fdowlz0#nAY8@rh9UxB(QP#bu-XFB7`QWY z@p?t=qg6F)?eqs=>9U4I#afa&wzbIITv;mBQSCfi3<>%i2?4esWj59kwN5H4V5hRn z#M!iC)ikUUe%|Pdw3a^1z|3u!Ywj_m*-Ao{4jmx8=~}3V=9;cPTe3a~=^PtxcvrUC zM&?FwV*rw^?h!#5l9tAErfK z!N|4_eTS&QI0gvK08siha9t-Y-yn5cwiCy=7$k3?Kwv6iSl`=7-dIZH~QkoZZwA9`a&KL*<;mGrO`XmSkI&MyK0v+O$-kzg4uF2X2T) z)--!PGWV=&&XP#BvFJ$r1fwQtd($(AFZ>-zBcqUW;6BTy(qJn(_9!(6JWoJ288}4j z9MsU>rT@!-ER2J{R;o-H88Q>2x#6l3jAY%=GHRSdt(0M;o^1h1{ZixiDzj=Dd2Mx5 zt;0RdR;MOhTa8RUMtqS7DCJc}f+2foD~TA6f_}wnUJ}%)qeM4vrLvqk015U>=EONN ze&H&auw<>G%Gn3{OA7A5IbBh6Ce>8hu(9CTYLSRTYjo=*QLs#$fULE8X`=&{Z$Rc$ zm+W|)8%+>$Qr4=?M=XpTN_=oiR}jYL*%AQEmeR12RMQK^_25)2c6Cs#yeKG+rOMb# zATq#pn>Q5)%vs?a5L*|Pb3yc2k{g%8(#B&CN5a>@X!ys)hS`6of!DmuB@^{LXMn6+ ztXoNI*kHY`Yt#+A>)yQ@AoV1UF{#>82GPeln1#obhh{v_Ch|kaq>`^6&+A*P%KxjN zRC5&l!y{xrq&CP$Wm$tU<09O36c`yVT4F}4mDB=k4X6Yz$6B+#WEA_e-x&=nWG#Ep zU5$lH!vui;{PE%t7a^XAf#MQP*1$;lV}4^rZ*QsEwUc;b$ju-&{F+9*4I0I^rkS$r zz%l8W35B|5EyTN1dnw~z1KlJ!T~^z>wArPya#u~1IRG_c?o4qH3X)!9rl`^i$>K)K z7gG8t#Z9D5xBgNbBj%{Ko`Wi9GhQGD*QN&IMiL2Jpx)qA z5!_tR08{GJL2{@+q(TNt%g!Ao3^Ol_VpM{4mWkH9Y)r_apfqp9SO&*+W)U}MHJ&cF z81hjrt8J`l`#NS@!!QFRXC~Wv6C`<`<&nv!NT)-cR>hLp#EwFw&_`3zy_bYOlB?H zAQ`RNi+9ZwBwwaTF%1lvZ8NRevb`3nob{$*AvM5VE#-roMeTYrX~T9I zH+!k9fK_DXlyycH{7Gy#vaRNuh2h3ppM!M=5C=g?AhAwk@owH+N>}rgK!|Qx&fVN@ zrC$$kzW@x|DS?pz6(lGsLed&FlsYY&OLLGK`V1Zf(XE*>cj0{LHxwh$+q8nkETaYr z<;=i(VYZ|t!LvZ$xScrk)^k8t3pv2n+C4pCz+^RHA?dc}WIbi~N@yiJ?LnuF4#>yV zC5_}y4l+7Irp)!5q)16cggA~xG3fuPM=$o2H34gWAFLyb{>-SdX_Sqm7IwW!+QPUS zSyI&a9bJvgW5*>PX>2RQMWdZ*;LOD(BpCoIbG)N^PaGm;s(45kTvemffiA0&?hk~V zBeSfIh_kArQzN8*Kj_mm&^9$(z{v|%!aAW34;>i(?b;zpG+)a4)(|J^v3hwzPI8uh zhqk(@xm)p^KvXw4Gx389?wdJ83fYwwKlEm*SWzbfXx7po2Bc#^kGli|i1nH`gC;Xq~?&5{g2A)KXkPtOxIY(<253TrAp8C z5`YjQn`>%PZFrPBYwNb!zAj<)QX99`xCHP5-Jk)_i4q_GQ#DD_jP92~Z{Wn0t7RLA04)5|IvVVo9LxxlA8)>3ysME0Wh8U5 z#fZ5vbCeXuT8Sc=97%*y)vAaOvV}%-u9=PE4s|ywj)y}qI0kh(mjHi>oPtTp>GfnJ zT)s*3mdWBxJ0-DhV~Ob13k}cnr7$cA^>yN7qNTE@hXf2CtXMgZN-ktiXy_<>N;bV z6t`Du3={sB%;OB+9czS!%0VcJlZms6u_J1bTCLHR&ScG|TBZo&PDU_}g*>96IrAu& zFgu@Bvznocri){vT2c}j!8lWiL%D6(fL>ss*x`4Pkako$rBEd=4X_0a9Ux(NP1c%i zNRX_TBs2?qG;J&iplTI&L6)(ClOkW&uUkvp(Z%7_qA}=l265bMC3T&g$83@m43M#_ zUJV3v2c>ovFk*;QhdbCE^BrgHIsi~&Fe|gGu+|IUvd&nzE*I906`Vs+8?71#OWV6U z2GuN(e8q}Md32&s1IHT@9XU9xIw+Y{t%59RSa_%mA2~uMjUOiG)(?}Z@Gkm}8ZGON zos_k3tJiPYB4@7SbA(P&(++Jh&%_Dk4)+{ZlJR6E2upK}oo*#B!N2>8SvZt zc^r-IQ3;*w?k?3I#-iPBxw3+0{<1my&Kr8$T{~1p-?rXpDRY?lt|lUZ8Jy#H?H5n% zYn;~utg`9NUh9axCiD;mr`WgwNqI~+hj;i zB7hYD1Z0iLnILyplgLP;Ag(2I$kC*(YDHua2}VPwl*3hvVT^ax)-5ElM{gN2c)ZkY z)lnjb50mhjQ!u#I15=U;N({75lTvF*B1X))z(P1jgbIO`{dgY1tF^e<_&ww&sx)Z` z$q!iDXtZvDtYBZQssv9SFV!LaKXk$@896gcjS8Tf%Ei{IM_I=neMd+Hl+^=a)q=;5 zk=Q^yvZJb#Z$?y`8=a2Yv#sBBp{RAx*XiuiG$OkS~C_8i

h#809V}iJ2#mLebl^xPkvDp9s-py$vhZM2 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 P8Gyjk)z4*}Q$iB}S{VrO literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_eyeclose.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_eyeclose.png new file mode 100644 index 0000000000000000000000000000000000000000..be1b149662c20ef52306b9705d54f295ed53f9ff GIT binary patch literal 9392 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 k*G$7cD3gr?SdL|-oisp_?4(&~sj2BX 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_konata.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_konata.png new file mode 100644 index 0000000000000000000000000000000000000000..25bef88ca95485b8b5193e8084fef259a7910952 GIT binary patch literal 9445 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_kudo.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_kudo.png new file mode 100644 index 0000000000000000000000000000000000000000..efda155e2a46bd18d56780cc30a6c6a80c79bf34 GIT binary patch literal 9532 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 YU=2VWy8`K2fc)dRb?26f&BTQN2Y%ydw*UYD literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_neko.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_neko.png new file mode 100644 index 0000000000000000000000000000000000000000..86f188e064c09bd97036fba8998e892bb4e83845 GIT binary patch literal 4102 zcmeAS@N?(olHy`uVBq!ia0vp^PZ$^&Jvi8aEQfzVYk(9>x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+Tfq$Z>i(^Q|oTNYh z|JxtdkYHV$P{7c@kR+AC-qRFlz$L(-(BNkL1SrwW!N77MqfG{=LV&S>LF(*;#R(!j zN(=%HizSOhdYT+r7??6locn;fIv5-ndecq-wX+E_a4fjUW69-qP=Seo(PWmQ`#}u} zmr+AU!*s|cDS^`t)(Ij4?ECC@pXOfjr11t*N9uw@^$kC41ni$o3EF2AkSEQ0g_(iz z$dCX3|2LK$)=*$*n0b-KBbPO)P9g31q9^JC?^zy6BpmzWnbKq{VQiUn0t6So@w#?ai8{)<<;{AJC)rTuQGx&up?JPEN3+b_q3lI7+Ze) zZSR+yV6;MHg6%BDb_Gbjj$l+i9MAIHo;fYIBdU1b{+g+bnxFq2p4;huFo6x2->vv9 zJs3AEuXt{MxIW=nQi7BGp30xEcn`m8ZkK$sR!5@l->;(^3UB+d6&ePnsJ?HM{AO-@ z7wA=HpjS(#lulquke|TsVat%@DDeNo$6%hQS6V#V-`gid?60(L-ZDky@M3j;iHI4I z5;ie12WL*6C^)U~|NF;Nf(qp{w)ZoAf_j6eVWttYhcEla@;7(S7reOP$z~~;$>yKH zHf8$MgG=9v3$Pb>Y347VZtc$a6;gCL@&IG`Fjvl=b<9S!2C0E!EC^J}kvGTY#Q)dN z_1nVp@Bb_2?2(A|vFkxAR_#WM<x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+Tfxp7j#WAE}PST(M z|LqTJNU$zWC}3z{NRrB6?`aA&;1Xa^XmB%r0+eXxU|_kB(Ix{_A;8$cAa!=a;sg;M zB?bY9#gauLJxz`*3``j&&V4{#9SjZ(y=fjV)2_I>udPjfGM(s+ZZBXz-{`i37i0`^a)1nn~l$dhKh!py*U zdV-t z{1lRqkl5X5vZ5{J2Y*YC14okKf(r=+j2({~XMPg;8*9zAf)Sj-_>vgbNXj-`sS648 zn3mFz?!$9)yF+1U!m=8Fe)B$vsj^oj?<^2;QWT%HAm@j?cUTK^;(}LfQC3+Z7x*B# zcnL#*paItmb03Jd)m(pj2%BV z2B#{C{-gbX~z2Tp~zxyA)Yi{T14qM0QWnkFC_QT*t z}Nl4b8&+csFYc}rdfpHcSDWCD@FnCrXSH|?-FlRzu;iz<~D9#(7@2V zbfsbQ+^Lq##=^#8cmIDc^jc|g`SRYy4OWoSMuF{s&rHT8%ODI~#MMzQBIhsi`iH4dYT$ zQoPvG++-vxM0i+1Zu7mS$W*s?$9eu9P49$r+6-xS+yQkdX=(pXo;hOj{r&y=_PYN+ zH}^X`eZ20lyI3TE4HA`(1&^ON{)@M-H{4V8``di)gd;DKJ|&_Rq~Au%%+V@iw8k8* vF^61@IoeztZ7q*>7DoF@qg_Reo-z-^3jMW{?yfPP%K!wPu6{1-oD!M<)ljR% literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_o.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_o.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7f4a0bc3ad31ea43604f5f03e27842aa5ed4ca GIT binary patch literal 4196 zcmeAS@N?(olHy`uVBq!ia0vp^PZ$^&Jvi8aEQfzVYk(9>x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+Tf&aayi(^Q|oTNYh z|JxtdkYHV$P{7c@kR+AC-qRFlz$L(-(BNkL1SrwW!N77MqfG{=LV&S>LF(*;#R(!j zN(=%HizSOhdYT+r7??6locn;fIv5-ndecq-wX+E_a4fjUW69-qP=Seo(PWmQ`#}u} zmr+AU!*s|cDS^`t)(Ij4?ECC@pXOfjr11t*N9uw@^$kC41ni$o3EF2AkSEQ0g_(iz z$dCX3|2LK$)=*$*n0b-KBbPO)P9g31q9^JC?^zy6BpmzW=@W;!|JhQjGNl0LM=Eh$x&Svdx%;r)ox|Fk8+T#Ud_DT6K z$PcETeHRa`LX$#g|&&8hqo<%u5X-kcdz(5#zx71h7Yo@ z^ffthL-YkPywSY(^ZbYZ_vJ%B<{O|8G++bjA+>mu<|ARHZ`W+jl zigsW7Uv9B9WZ$K$TNgKIL5d{>);U3^<~M|h_Pl@m@Ysg0cP!cX%*@!-+&t7+pLw!{ zvGr*DVOyt6WM|^(m6v&%_So>$#Kb&Md$at$ zy`t7Z-{=nu{0t0?^W_bIZtMaTl77`ZMIZj&j5SlZdW<1%<6#Ax{F7X5-}~nobubt| z+5P^$M2g8(2`Ai zRSl9#41XG+mCx*@Zlgu@XiYU*`;Rt$M%#X)P2bU$|7gc&wBI+>yS+RNrpGRAH0*xb P!vF-Hu6{1-oD!M<&-Ukl literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_smile.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_smile.png new file mode 100644 index 0000000000000000000000000000000000000000..74e49d4260450cc28711e0c7c212058027e9c782 GIT binary patch literal 9346 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkleft.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkleft.png new file mode 100644 index 0000000000000000000000000000000000000000..3a537430f2076b32d5f007d4a1f21e83d8afa45f GIT binary patch literal 9813 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkright.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_winkright.png new file mode 100644 index 0000000000000000000000000000000000000000..82fae49645dd77f3197ae1d0536625f25f028897 GIT binary patch literal 9632 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 J4>pmL{|Cl_n_K_@ literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_xo.png b/trunk/LipSync/LipSync/Resources/sanari_miku/b_miku175_xo.png new file mode 100644 index 0000000000000000000000000000000000000000..b3796114550674b8c69e16528f1753180f8dfc30 GIT binary patch literal 4118 zcmeAS@N?(olHy`uVBq!ia0vp^PZ$^&Jvi8aEQfzVYk(9>x}&cn1H;C?n%{wwfqaEz zk04(LhALGChK6PahM)g|^a}=tQUeBtR|yOZR?`_6#Pg@GoOy+Tfq$W=i(^Q|oTNYh z|JxtdkYHV$P{7c@kR+AC-qRFlz$L(-(BNkL1SrwW!N77MqfG{=LV&S>LF(*;#R(!j zN(=%HizSOhdYT+r7??6locn;fIv5-ndecq-wX+E_a4fjUW69-qP=Seo(PWmQ`#}u} zmr+AU!*s|cDS^`t)(Ij4?ECC@pXOfjr11t*N9uw@^$kC41ni$o3EF2AkSEQ0g_(iz z$dCX3|2LK$)=*$*n0b-KBbPO)P9g31q9^JC?^zy6BpmzWnbKq{VQiUn0t6So@w#?ai8{)<<;{AJC)rTuQCENaNj1rAci+yH;j!A8OgEi z`TwCY@zEDcp80k)DF%jyNgX_#2?;JMwH``_aGhXFJt1FG{6S*@7bw3=6>VU0YunFp zuHImtO}1UL;eG|@X=`~8cXNkJJkyJ8T*TNY`Ook{_LaUSM{bCxfHrB~`+5Gu|NHen zG_;fte}8{p@`;P9#0<%q5=?7#CC|;X>Gl3yoxt|b*Zz7RQx>EIY8GF^ns%!Hg!0OL z^Vabcm%mN?@%g*{;r{sj691Cl#y1`KZ#^eSEB@u;5(kb?}^<~?+ zPR!vG-fU!?`s2@2?ZZ=attI~b{d-(MT)fx!wSGeGEobxgKBiTmNSfO&bL7GA&DLuU zoY~5E;>*D)u8{%^^XIa3{bVx!EcR*wQn*5BLr_qmXS;jS4q5@^M6?P!TRTH%b=x1-IC r(bm>zV{^2vJ=)b6?P(4DjwUk$_x#;U&l@*pFaUw4tDnm{r-UW|?RCg3 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_a.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_a.png new file mode 100644 index 0000000000000000000000000000000000000000..6e7eaf382be1256c69f8a1b7253ed28d095e2027 GIT binary patch literal 1678 zcmeAS@N?(olHy`uVBq!ia0vp^O$-c-$sBAz*2kR7c|eM>ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zVB_(0aSW-5dwcVIwoIx7`-d)tZwuo7u)FNxcze=${Ub+K&8B%*JVXMelN~*Iret|X zyQpSdHrbdh)TH6EqGE+>boVr+e+?43o*QS~RGr~7>DZAK8-FHdek)BgpDmxghwJ7~ zmbi+@X{zU+|NV5v*f@II4`qi221X_p4grN>&6p|9p%@cBM{ZZ;vVa|`u`liZ>U=hc zWc1*#&D-Z~Fc zZhCfXQOf*vSISFiepVpI{|JU4YoX)pji{*5qht;uk?)^M><6i5{ zT$Nu~^Wxl+zyEiBT)3XsskFS~Tzj{8{t1yVU2$u1e$zj@g+q27JSLm?^pc>vb@oj) zvBnadsa?doSI6U)?!JAW#78p+-L9$)NG_h9vf(jUDWexE#kxVW^x zrMY_6;gY(7zYk`d5qO!OQ`gxOKB1)PZ{}=&Yp0#sQ@+>6%09fwUf%XSde-6Xx%q9} z`SQH)x0k?i#G_0%p}B*Vq!@9=H+lJ>$p1&3i=}{(U>V^lNarUWv(m4UXA=FPQ)O zf7~{BVW&dwWfOc~PfD5SQ~U z!MMzdw67nFWptOmm*cqB;qWQ!Y{}Od-QAm z=9T~0V7~p=+)k%;ZX8nr1tsjNza4wBHaULAT%MydH-7m3^x+1BdG`cWwEgmQCx^b1 zT6+A<(WNhc%zbp?L|Bul#)l7mveDo7UD@)!TUh>Yp`{eh^|WKoQawxWKPt%0QfX09 zIC``5{(8S&yV&NZ+AE_T%*)-LyZiULx9w7|Os;A*gx-?{xe+LpWbp`@#s2Wg~8zI>gTe~DWM4f?q>;g literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_aa.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_aa.png new file mode 100644 index 0000000000000000000000000000000000000000..8c0166211f376382ddef78c7dfc60696774f3d6f GIT binary patch literal 1726 zcmeAS@N?(olHy`uVBq!ia0vp^O$-c-$sBAz*2kR7c|eM>ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zV6*XbaSW-5dwcV2en_YUdqPj=#MWIO1br^!JDkru98S5`-z zW3F45#$UK}Ov1EnhJ@>)2Kkm&uP4qOGcKL;@p!pKG&)eLwe7;bd)5|Tn6IhLtyHs| zIXlzpx0fk}BNYxh*EcfmEa<5)^3OBY;h%5XANzFkVu{E)_D!YXY)1ZmeC7AU_2g0`pWFZ4*&5EiN%>^Q zBMIpfD%W4m_@%>nv~!E|6xE=W;x2CcDzcA1Y~6RS-TUs+ zHLs-Q-_)99{-6Hd=H=yPgWc9Ce#dWa{ys%COjF!?+WWP8_6m#aJ~-F<(AuTS^DB2v z$vw4fTgl^c)A>6ss`V#We@(9Wml%F!|4!Ac>+AZqYEL`J7;=rvXg(hnwW#e<|mFqHA^e6AW*Zufx@5c9A&jx{p_1kJDdQAW1 zi+i`_tXEw-d&6bf{lI5E#ryvx33Mf{h}x;-rzTtn46B9AXXI=>9i&#TPLok*O?>w} z;ocX8C5bmSRtC$|?bh?#ZhGI4txS z#l0&6>S?8|@6Op?46-%m_{O0+sq2Z~!-J15T_}GRv8FoB^Ut-7)_&XW?6dizBD*m0 z@|8;yWNi7TaWosPd%9Wl^6o?IxxE*6JUe<~-+jxiHY#@&WA)Cx$?Md8eO+W)+mm;X zTzfmmapFXA#Qh0=EHwZ z5BD7oShv@OV@jZiMg5Z#drt-*_fPtgTqQd9fDqb%=m9h4&gzrhV!tAH3 zZd|`QO-@!_-R+a?WO2PS>Jd#$-eS75_AlL5b^H5o``^F6pIKk{_)@}>gEM{@%bU09 zyQnbEl#%`Q`d7jKRYE%Po|{?cMSQr>bX-0gTe~DWM4fdaElS literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_base.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_base.png new file mode 100644 index 0000000000000000000000000000000000000000..6aea17a5eccee11c6aa5efecc0f6423927edb4df GIT binary patch literal 60137 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 C%NMHv literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_kudo.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_kudo.png new file mode 100644 index 0000000000000000000000000000000000000000..06c2714c4f6ac314ce2917660e2d0283590d517e GIT binary patch literal 7080 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 literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_nn.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_nn.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c5170d074c69f12293959e008512e113f4329c GIT binary patch literal 1559 zcmeAS@N?(olHy`uVBq!ia0vp^O$-c-$sBAz*2kR7c|eM>ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zV4dpe;uum9_x9%5?2vE~h7Tf+uMX{cX&>Na-n4F4fp+Yc)p>6&xgH2wD_^>JUDPet z1zeF^gE}s_ItGa79O;)@du)ehlx8c}+Dc=V$>zeBm#kdoH>qpp>)Ou8H6=^dwe0!M zEwf|K(E~s4PX2su@A~D(XATdg;lBKev2I*VR3nx^d6CDZk{xCY8UwynnrZm%HNUKk1A1RPGC!)hQ?y zxLT!fuIuMWov!G}b`6!Fdz0hlXzUd=|Lb+TO+UZRUC>6i4r}8&i z?K0fu6NPM#BQ$Qruz|pg;>uklr`yZ z;yrJ5$SXV|(!BdY<@&Z~pWm2so!jy2a=wVuW(lePAMbWQ{4`Ve;p~6)cklnl-;*Cc*cY34zJ2fM!WWbK4_{QS-Du%gzBk-J`N|+&Q_RJ7w%hXx2^q#o2;+FEhirqV=)K)9Z5N`YtT6lKx%8dt)o-8`O@*%6$;gm`R zb(TvR96h}J`=$0<&EqHzUT7E1`Tw3YH}};y8j{Mr?x!WRW0QZ*+PTkUvfS$a{`JZ; zoE!PKBgr?wrx{8;e_)5`O{|NdrFJz6ZYOn<3g zW4YPhjhU}+&;DKZJ#YVqx7YtV+sE3Ompp$yQQqy`yni_h_Wv(U8VNaJ*k^TWdvH%l aqq=)?=a!2ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zVEymu;uum9_x9%5?3hpq_6HpbWefBEu)Eyhczeoq`y(gTmE5snFORJX# z!pe)+maO%g)xf>9yUQcmXH~|fR+lwvyN=#C!*lS7TBc8r)NFol8LD@G>bjEo|E5*X z*u$`--Of0wE=f&OZjP_l{G+SDch?)MH@};- z`qwje_ILen|F7@m-)qM4dbjh(_JW_Ea(5m&RkYFgq{H8{a~Is=HG9XQ-QTxlhw^E& zohx-^|D;WR^rLOF!`qk*o8s;DMUJcU^v|}}zwXxE|L3|)!N%p*CVM~RWYoNSd7=8* zoF72N_Y zXXiKXx}|W1ugCYiz3{KTJ+gYT*}USn`dYN-wqCe(W5dJ8jsivkElVXAK1;p$Y2VMI zwhNzMnEmkg&EIQhS5Z~BW=~PJhxOs>vGd#Z7CPwc`BYS4dyXe|xn0a} z-lR1#Cpa37Rxvf(+HOC-zEAz|mx>iWy)E_Y_}X?}{GufpF0_7Hp>ApO(d%cXww_$F z*T`f`YXTeVygU19PiOn~{@!Qx_vHNWZu?g0;Kho(#}2*s++k=a;>6>TTJ@&?weaEH z#u57_UE{Xd@^#)?e!C5C9saJHJHK?>);X_#KYFuMTl`%4T>IixJ1<-+GB+IV*=^XD iC$#Y3zw*X<#w%%gx6bsRodB#O7(8A5T-G@yGywoVcnK2# literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_smile.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_smile.png new file mode 100644 index 0000000000000000000000000000000000000000..4f9b94d0ebed07efa31efb1d2e0f0e10e058c452 GIT binary patch literal 7031 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 dVeYSxox)>qz=Qw* literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_u.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_u.png new file mode 100644 index 0000000000000000000000000000000000000000..76412601b917309e34b00d2713042c403f56ea15 GIT binary patch literal 1630 zcmeAS@N?(olHy`uVBq!ia0vp^O$-c-$sBAz*2kR7c|eM>ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zV7=q%;uum9_x9%5?3hpyh7TPIWefBEu)Eyhczeoq`y;1tuF&$P=4<`iI)ZWoR&MPU zbYZ$W>qbxRg;oKV6N|dGiRs3AZslG(@!B3qr^z!tlP;~uRPS6m^L6!1pXY~PhMlP1 z-+20tWE=bQ^7C`5-&NPv#<6e+C^$4QFft8mhQeni#g^z-+`{F0)4a-6m1nBoPnA>C zW;nU%`l_YJv!A}W`?Tm|f7H$$Q+mEuE}gMIs#9*=`S=~m+Hx~{KA$Sdyj`?(hd}=Y znXO(T=OyQyZp zQMLDek>#w{H@UZbXElFz_pg(Q`TEK`e|{Eim9j0`Y`36%YDTt{c~!>~soC*Lj|GoR zeUPx}fv0OmNb511%KcwX-~8~Z+xqb7^Un@FS9Z7Z=gaj?DeCPp&inUacIO4JwrBQs zT<`bXlt0GzhW~j#PixJ)mj*xL_C42hQp)*f^CH{7<=k3@uGI&NA09v4e(2}Jg#mw_ zL|E*2-nwqp1rMpt2~92;UpVgmu6z7>d2{=r2lHYR_k0N4VG+dP{QKLtH5^qfA}UTo zPBqIvxU4qMn9HTLe=hg#G8-{HIqep1_x8gD|L^twTljVMj~A6nsyv4xG{uX}S99%D zFK^lW@tcA5ugHr3Q>R;PYy0u;QPih5jR{^XkCu0BkDEQ)W}j7XmbIzLzpu-WxgD0a zp3mtXe_!10g#3#dHp5`8B`ppTzKtg@FVF9vZ`IefbZ0>PnwI)B^}}AKnJkY3`}(JS z%n0fIdi%`Rt*xJqe_gp!mnB%^!;x=qqrZLM|LxoNaF9wF1}jPvuEq+rvOqo=%me@RKIp6Osob_#=rOPkU|{fc^>bP0l+XkKgpmAE literal 0 HcmV?d00001 diff --git a/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_winkleft.png b/trunk/LipSync/LipSync/Resources/sanari_rin/b_rin100_winkleft.png new file mode 100644 index 0000000000000000000000000000000000000000..8c834b9d05abde6966f3ee66df6a2b967911fd66 GIT binary patch literal 7517 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 z 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 l|1bIfjsILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFK)ynLqiJ#!!Mvv!wUw6QUeBtR|yOZRx=nF#0%!^3bbKh zVBPQO;uum9_x7e^c1)-U!-EcmvW0nnn3eKc%APKYE?lTB9_6z1N?70q)rc)o6Rt^U zteD`d8L~V|U{`@6N7%)%i$MZ05rG+7t@4j0d`i1CL&CIdQp7CFTK&l{eIButA3F1! zP47-+cjM=~#?R+f-@h<{pOJ}$LqNfyfniuPH1;^S+_^AE_r6v5+I!RbYv$Q&+xP@B zd~(gdvYOxg(vz>PTRufAuRZfTIW=yz%&r*kclqaH_AJ$qYwh{`{^YA^tx>6F(ii1= zqb8mGe6ezx>d~EhoJ52&FEq!^T61Tr?l19dv6|G6*HsT@Ii-j`-h4FvbUEKH?}d+| zS51F^?$rPIz2bYV1+Rs-Kl#0*;Ndc-MBbtey<7JDzCU$AEN@kK%j;4E5#V5U#Je&Og`RS)spANXyI=t7qc-3UxH-Vq|U-r8kR6e0~ zaP`lo=b{TkMWa6Z3FT}tEt&Uxe_+9}fBgIBa?DN1`2TqFivK@yWojPol&DLp-edTw z=*-_w&gX+$TweUQk$C0TvNhUKNcs1-W1WBXj~(6a{qfm{c@lU3|GD+Mx=(B z8DBYGfB$>!`$P5eBjxV>M}A(q_~Yf=Ae*gk7tRxP?7#58a)Xd#S#ZUw%hDy^{t4&H z_A&R{OHD2BKiRjp2*2C+2k8SR^6{?uemWBI&$f59v9Mrdlgabt|8^J||2)IcroZGX)A!tc$)ERr&#~N6 z{rsDMpS+~?->=W*=l}aTd-MExe_#A" . $listname; + +%hash; +%defined; + +open( FILE, $listname ); +while( $line = ){ + chomp $line; + # MessageID̒`C`ς݂enum + if( index( $line, "MessageID.cs" ) >= 0 ){ + open( CS, $line ); + $mode = 0; + while( $cs_line = ){ + if( $mode == 1 && index( $cs_line, "}" ) >= 0 ){ + $mode = 2; + next; + } + if( $mode == 1 ){ + $line2 = "" . $cs_line; + chomp $line2; + $line2 =~ s/ //g; + $line2 =~ s/,//g; + $line3 = $line2; + $defined{$line3} = 0; + } + if( $mode == 0 && index( $cs_line, "enum MessageID" ) >= 0 ){ + $mode = 1; + } + } + close( CS ); + next; + }else{ + open( CS, $line ); + while( $cs_line = ){ + $index = index( $cs_line, "MessageID." ); + while( $index >= 0 ){ + $spl = substr( $cs_line, $index + 10 ); + $index2 = index( $spl, ")" ); + $cs_line = substr( $spl, $index2 ); + $spl2 = substr( $spl, 0, $index2 ); + $spl2 =~ s/ //g; + $hash{$spl2} = $hash{$spl2} + 1; + $index = index( $cs_line, "MessageID." ); + } + } + close( CS ); + } +} +close( FILE ); + +@keys = keys( %hash ); +foreach $entry( @keys ){ + $defined{$entry} = 1; +} +open( RESULT, ">result.txt" ); +@keys2 = keys( %defined ); +foreach $entry( @keys2 ){ + if( $defined{$entry} == 0 ){ + print RESULT $entry . "," . $defined{$entry} . "\n"; + } +} +close( RESULT ); + +system "del " . $listname; diff --git a/trunk/LipSync/LipSync/de.po b/trunk/LipSync/LipSync/de.po new file mode 100644 index 0000000..9d93910 --- /dev/null +++ b/trunk/LipSync/LipSync/de.po @@ -0,0 +1,1033 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-10-15 21:07+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" +"X-Poedit-Country: GERMANY\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Basepath: .\\\n" +"X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: Editor\n" +"X-Poedit-SearchPath-1: Common\n" +"X-Poedit-SearchPath-2: AviFile\n" + +#: Editor/AviOutput.cs:111 +msgid "Directory" +msgstr "" + +#: Editor/AviOutput.cs:111 +msgid "does not exist." +msgstr "" + +#: Editor/AviOutput.cs:112 +#: Editor/AviOutput.cs:137 +msgid "Error" +msgstr "" + +#: Editor/AviOutput.cs:122 +msgid "already exists." +msgstr "" + +#: Editor/AviOutput.cs:122 +msgid "Do you want to replace it?" +msgstr "" + +#: Editor/AviOutput.cs:136 +msgid "Invalid value has been entered" +msgstr "" + +#: Editor/AviOutput.cs:159 +msgid "Avi file(*.avi)|*.avi" +msgstr "" + +#: Editor/AviOutput.cs:159 +msgid "All Files(*.*)|*.*" +msgstr "" + +#: Editor/AviOutput.designer.cs:302 +msgid "Cancel" +msgstr "" + +#: Editor/AviOutput.designer.cs:303 +msgid "Save" +msgstr "Speichern" + +#: Editor/AviOutput.designer.cs:304 +msgid "file name" +msgstr "" + +#: Editor/AviOutput.designer.cs:305 +#, fuzzy +msgid "Video" +msgstr "Anzeige" + +#: Editor/AviOutput.designer.cs:306 +msgid "Audio" +msgstr "" + +#: Editor/AviOutput.designer.cs:307 +msgid "Convert to FLV" +msgstr "" + +#: Editor/AviOutput.designer.cs:308 +msgid "Merge wave to AVI" +msgstr "" + +#: Editor/AviOutput.designer.cs:309 +msgid "Delete intermediate file" +msgstr "" + +#: Editor/AviOutput.designer.cs:310 +msgid "Video Compression" +msgstr "" + +#: Editor/AviOutput.designer.cs:311 +msgid "Specify output range" +msgstr "" + +#: Editor/AviOutput.designer.cs:312 +msgid "Start" +msgstr "" + +#: Editor/AviOutput.designer.cs:313 +msgid "End" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:187 +msgid "Edit motion curve" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:188 +msgid "Close" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:189 +msgid "File" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:190 +msgid "Redo" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:191 +msgid "Undo" +msgstr "" + +#: Editor/DisplacementControl.designer.cs:192 +#, fuzzy +msgid "Edit" +msgstr "Beenden" + +#: Editor/EditEntry.Designer.cs:207 +msgid "ON time (sec)" +msgstr "" + +#: Editor/EditEntry.Designer.cs:208 +msgid "OFF time (sec)" +msgstr "" + +#: Editor/EditEntry.Designer.cs:210 +#: Editor/EnvConfiguration.Designer.cs:827 +msgid "OK" +msgstr "" + +#: Editor/EditEntry.Designer.cs:211 +msgid "Use this value" +msgstr "" + +#: Editor/EditEntry.Designer.cs:212 +msgid "Expandable range of this entry" +msgstr "" + +#: Editor/EditEntry.Designer.cs:213 +#: Editor/Form1.cs:1348 +msgid "Numeric entry" +msgstr "" + +#: Editor/EnvConfiguration.cs:250 +#: Editor/EnvConfiguration.cs:268 +msgid "Executable file(*.exe)|*.exe" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:829 +msgid "Language" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:830 +#: Editor/Form1.designer.cs:1160 +#, fuzzy +msgid "Option" +msgstr "Offnen" + +#: Editor/EnvConfiguration.Designer.cs:832 +msgid "User Config" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:833 +msgid "Appearance" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:834 +msgid "lip-sync Option" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:835 +msgid "System" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:837 +msgid "Title of timeline" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:838 +msgid "VSQ Entry" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:839 +msgid "Plugin Entry" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:840 +msgid "Another Entry" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:841 +msgid "Entry height (pixel)" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:842 +#: Editor/EnvConfiguration.Designer.cs:843 +#: Editor/EnvConfiguration.Designer.cs:844 +#: Editor/EnvConfiguration.Designer.cs:845 +#: Editor/EnvConfiguration.Designer.cs:855 +msgid "Change" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:846 +msgid "Check phonetic symbol to configure detailed mouth shape control" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:847 +msgid "Close mouth before pronunciation" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:848 +msgid "\"i\" shaped mouth before pronunciation" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:849 +msgid "\"u\" shaped mouth before pronunciation" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:850 +msgid "Color" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:851 +msgid "Design" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:852 +msgid "Path of ffmpeg" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:853 +msgid "Path of mencoder" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:854 +msgid "Font" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:856 +#: Editor/EnvConfiguration.Designer.cs:861 +msgid "Another settings" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:857 +msgid "Close mouth when same vowels repeated" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:858 +msgid "Encoder/Decoder" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:859 +msgid "Generate character automaticaly when importing vsq" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:860 +msgid "Threshold silence length(sec)" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:862 +msgid "Use preview-enabled dialog in character selection" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:863 +msgid "Reload language configurations" +msgstr "" + +#: Editor/EnvConfiguration.Designer.cs:864 +#, fuzzy +msgid "Operation" +msgstr "Offnen" + +#: Editor/EnvConfiguration.Designer.cs:865 +msgid "mouse wheel rate" +msgstr "" + +#: Editor/Form1.cs:853 +msgid " has been changed. Do you wish to save changes to file?" +msgstr "" + +#: Editor/Form1.cs:855 +msgid "Do you wish to save changes to file?" +msgstr "" + +#: Editor/Form1.cs:1206 +#: Editor/Form1.cs:2936 +#: Editor/Form1.cs:3859 +msgid "Video size configuration" +msgstr "" + +#: Editor/Form1.cs:1215 +msgid "Read from VSQ file" +msgstr "" + +#: Editor/Form1.cs:1219 +#: Editor/Form1.designer.cs:1143 +msgid "Edit character" +msgstr "" + +#: Editor/Form1.cs:1222 +#: Editor/Form1.cs:1260 +#: Editor/Form1.cs:1280 +#: Editor/Form1.cs:1343 +#: Editor/Form1.cs:1366 +msgid "Preview image" +msgstr "" + +#: Editor/Form1.cs:1223 +#: Editor/Form1.cs:1292 +#: Editor/Form1.cs:1378 +#: Editor/Form1_EventHandler.cs:975 +msgid "Image placement" +msgstr "" + +#: Editor/Form1.cs:1224 +#: Editor/Form1.cs:1296 +#: Editor/Form1.cs:1382 +#: Editor/Form1_EventHandler.cs:506 +msgid "Scale setting" +msgstr "" + +#: Editor/Form1.cs:1226 +msgid "Generate wink" +msgstr "" + +#: Editor/Form1.cs:1230 +#: Editor/Form1.cs:1459 +msgid "Delete" +msgstr "" + +#: Editor/Form1.cs:1233 +msgid "Add track" +msgstr "" + +#: Editor/Form1.cs:1247 +msgid "Generate Lipsync from this track" +msgstr "" + +#: Editor/Form1.cs:1256 +#: Editor/Form1.cs:1269 +#: Editor/Form1.cs:1308 +msgid "Note ON from here" +msgstr "" + +#: Editor/Form1.cs:1275 +#: Editor/Form1.cs:1361 +msgid "Set image" +msgstr "" + +#: Editor/Form1.cs:1284 +#: Editor/Form1.cs:1370 +msgid "Change image" +msgstr "" + +#: Editor/Form1.cs:1289 +#: Editor/Form1.cs:1375 +msgid "Image" +msgstr "" + +#: Editor/Form1.cs:1320 +#: Editor/Form1.cs:1435 +msgid "Paste" +msgstr "" + +#: Editor/Form1.cs:1338 +msgid "Note OFF" +msgstr "" + +#: Editor/Form1.cs:1351 +msgid "Expand" +msgstr "" + +#: Editor/Form1.cs:1391 +msgid "Plugin config. of this entry" +msgstr "" + +#: Editor/Form1.cs:1398 +#: Editor/Form1.cs:1421 +msgid "Copy" +msgstr "" + +#: Editor/Form1.cs:1402 +msgid "Cut" +msgstr "" + +#: Editor/Form1.cs:1406 +msgid "Split entry" +msgstr "" + +#: Editor/Form1.cs:1418 +msgid "Timeline" +msgstr "" + +#: Editor/Form1.cs:1428 +msgid "Copy On/Off inverted" +msgstr "" + +#: Editor/Form1.cs:1442 +msgid "Import from TEXT" +msgstr "" + +#: Editor/Form1.cs:1446 +msgid "Export to TEXT" +msgstr "" + +#: Editor/Form1.cs:1464 +msgid "Delete entries" +msgstr "" + +#: Editor/Form1.cs:1471 +msgid "Shift this time-line" +msgstr "" + +#: Editor/Form1.cs:1957 +#: Editor/Form1.cs:1997 +#: Editor/Form1.cs:2707 +msgid "VSQ Tracks" +msgstr "" + +#: Editor/Form1.cs:1969 +msgid "Character" +msgstr "" + +#: Editor/Form1.cs:1977 +#: Editor/Form1.cs:2709 +#: Editor/Form1.cs:3305 +msgid "Another images" +msgstr "" + +#: Editor/Form1.cs:1984 +#: Editor/Form1.cs:2681 +msgid "Plugin" +msgstr "" + +#: Editor/Form1.cs:2936 +msgid "Input video length in second" +msgstr "" + +#: Editor/Form1.cs:2964 +#: Editor/Form1.designer.cs:1152 +#: Editor/Form1_EventHandler.cs:78 +msgid "Shift all time-tables" +msgstr "" + +#: Editor/Form1.cs:2964 +#: Editor/Form1_EventHandler.cs:78 +msgid "Input shift time in second (you can enter minus value)" +msgstr "" + +#: Editor/Form1.cs:3223 +#: Editor/Form1.cs:3490 +msgid "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" +msgstr "" + +#: Editor/Form1.cs:3223 +msgid "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" +msgstr "" + +#: Editor/Form1.cs:3224 +#: Editor/Form1.cs:3491 +#: Editor/Form1_EventHandler.cs:548 +#: Editor/Form1_EventHandler.cs:925 +#: Editor/Form1_EventHandler.cs:1090 +#: Editor/Form1_EventHandler.cs:1100 +msgid "Confirmation" +msgstr "" + +#: Editor/Form1.cs:3239 +#: Editor/Form1.designer.cs:1187 +#: Editor/Form1_EventHandler.cs:898 +msgid "VOCALOID2 Sequence File(*.vsq)|*.vsq" +msgstr "" + +#: Editor/Form1.cs:3509 +#: Editor/Form1.cs:4408 +#: Editor/Form1.designer.cs:1169 +#: Editor/Form1.designer.cs:1224 +#: Editor/Form1_Preview.cs:352 +msgid "Play" +msgstr "" + +#: Editor/Form1.cs:3514 +msgid "File not found" +msgstr "" + +#: Editor/Form1.cs:3538 +#: Editor/Form1.cs:3569 +#: Editor/Form1.cs:3583 +msgid "Extension must be *.lse" +msgstr "" + +#: Editor/Form1.cs:3650 +msgid "Failed file saving" +msgstr "" + +#: Editor/Form1.cs:3748 +msgid "Failed file reading" +msgstr "" + +#: Editor/Form1.cs:3859 +msgid "Width" +msgstr "" + +#: Editor/Form1.cs:3859 +msgid "Height" +msgstr "" + +#: Editor/Form1.cs:3992 +msgid "Expand all" +msgstr "" + +#: Editor/Form1.cs:3993 +msgid "Fold all" +msgstr "" + +#: Editor/Form1.cs:4028 +msgid "(no name)" +msgstr "" + +#: Editor/Form1.cs:4048 +#: Editor/Form1.designer.cs:1164 +msgid "Disable preview" +msgstr "" + +#: Editor/Form1.cs:4054 +#: Editor/Form1.designer.cs:1162 +msgid "Enable preview" +msgstr "" + +#: Editor/Form1.cs:4168 +#: Editor/Form1.designer.cs:1183 +msgid "Hide object list" +msgstr "" + +#: Editor/Form1.cs:4174 +#: Editor/Form1.designer.cs:1181 +msgid "Show object list" +msgstr "" + +#: Editor/Form1.cs:4412 +msgid "Audio file(*.mp3;*.wav)|*.mp3;*.wav" +msgstr "" + +#: Editor/Form1.cs:4430 +#: Editor/Form1.designer.cs:1173 +msgid "Go to specified frame" +msgstr "" + +#: Editor/Form1.cs:4430 +msgid "please input frame index" +msgstr "" + +#: Editor/Form1.cs:4446 +msgid "invalid frame index" +msgstr "" + +#: Editor/Form1.designer.cs:1129 +msgid "Open" +msgstr "Offnen" + +#: Editor/Form1.designer.cs:1131 +#, fuzzy +msgid "Save As" +msgstr "Speichern" + +#: Editor/Form1.designer.cs:1132 +msgid "Import" +msgstr "" + +#: Editor/Form1.designer.cs:1133 +msgid "from RipSync data" +msgstr "" + +#: Editor/Form1.designer.cs:1134 +msgid "Open VSQ file" +msgstr "" + +#: Editor/Form1.designer.cs:1135 +msgid "Exit" +msgstr "Beenden" + +#: Editor/Form1.designer.cs:1139 +msgid "Help" +msgstr "" + +#: Editor/Form1.designer.cs:1140 +msgid "Plugin information" +msgstr "" + +#: Editor/Form1.designer.cs:1141 +msgid "About LipSync" +msgstr "" + +#: Editor/Form1.designer.cs:1142 +msgid "Debug" +msgstr "" + +#: Editor/Form1.designer.cs:1144 +msgid "Flip images horizontaly" +msgstr "" + +#: Editor/Form1.designer.cs:1148 +msgid "Video size" +msgstr "" + +#: Editor/Form1.designer.cs:1149 +msgid "Frame rate" +msgstr "" + +#: Editor/Form1.designer.cs:1150 +msgid "Z order" +msgstr "" + +#: Editor/Form1.designer.cs:1151 +msgid "Video length" +msgstr "" + +#: Editor/Form1.designer.cs:1153 +msgid "View" +msgstr "Anzeige" + +#: Editor/Form1.designer.cs:1154 +msgid "Zoom" +msgstr "" + +#: Editor/Form1.designer.cs:1155 +msgid "Mooz" +msgstr "" + +#: Editor/Form1.designer.cs:1156 +msgid "Set default scale" +msgstr "" + +#: Editor/Form1.designer.cs:1157 +#: Editor/Form1.designer.cs:1219 +msgid "Move to Top" +msgstr "" + +#: Editor/Form1.designer.cs:1158 +#: Editor/Form1.designer.cs:1218 +msgid "Move to End" +msgstr "" + +#: Editor/Form1.designer.cs:1159 +msgid "Tool" +msgstr "" + +#: Editor/Form1.designer.cs:1166 +msgid "Plugin config" +msgstr "" + +#: Editor/Form1.designer.cs:1167 +msgid "Sync with Time table" +msgstr "" + +#: Editor/Form1.designer.cs:1168 +msgid "Add empty character" +msgstr "" + +#: Editor/Form1.designer.cs:1169 +#: Editor/Form1.designer.cs:1224 +#: Editor/Form1_Preview.cs:295 +msgid "Pause" +msgstr "" + +#: Editor/Form1.designer.cs:1171 +msgid "Generate AVI" +msgstr "" + +#: Editor/Form1.designer.cs:1172 +msgid "Chose sound file" +msgstr "" + +#: Editor/Form1.designer.cs:1174 +msgid "Stop writing avi" +msgstr "" + +#: Editor/Form1.designer.cs:1175 +msgid "Background color" +msgstr "" + +#: Editor/Form1.designer.cs:1177 +msgid "Generate raw AVI" +msgstr "" + +#: Editor/Form1.designer.cs:1178 +#, fuzzy +msgid "Export" +msgstr "Beenden" + +#: Editor/Form1.designer.cs:1179 +msgid "script for H@TWUNEBENCH" +msgstr "" + +#: Editor/Form1.designer.cs:1185 +msgid "Bug report" +msgstr "" + +#: Editor/Form1.designer.cs:1193 +msgid "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" +msgstr "" + +#: Editor/Form1.designer.cs:1202 +#: Editor/Form1.designer.cs:1209 +msgid "LipSync data file(*.lse)|*.lse" +msgstr "" + +#: Editor/Form1.designer.cs:1216 +msgid "Real time \"lipsync\"" +msgstr "" + +#: Editor/Form1.designer.cs:1217 +msgid "Repeat play" +msgstr "" + +#: Editor/Form1.designer.cs:1220 +msgid "End repeat at" +msgstr "" + +#: Editor/Form1.designer.cs:1221 +msgid "Start repeat from" +msgstr "" + +#: Editor/Form1.designer.cs:1222 +msgid "Reset repeat region" +msgstr "" + +#: Editor/Form1.designer.cs:1225 +msgid "Show VSQ tracks allways" +msgstr "" + +#: Editor/Form1.designer.cs:1226 +msgid "Show bars" +msgstr "" + +#: Editor/Form1.designer.cs:1227 +msgid "Quantize" +msgstr "" + +#: Editor/Form1.designer.cs:1228 +msgid "off" +msgstr "" + +#: Editor/Form1.designer.cs:1229 +msgid "triplet" +msgstr "" + +#: Editor/Form1.designer.cs:1231 +#: Editor/FormObjectList.cs:60 +#: Editor/FormObjectList.Designer.cs:62 +msgid "List of object" +msgstr "" + +#: Editor/Form1.designer.cs:1232 +msgid "Property" +msgstr "" + +#: Editor/Form1.designer.cs:1246 +msgid "Series bitmap" +msgstr "" + +#: Editor/Form1_AviOutput.cs:203 +msgid "insertion of wav file has failed" +msgstr "" + +#: Editor/Form1_AviOutput.cs:262 +msgid "" +"Initialization of video compression failed.\n" +"This video codec may require image width in multiples of certain number." +msgstr "" + +#: Editor/Form1_AviOutput.cs:293 +msgid "FLV Progress" +msgstr "" + +#: Editor/Form1_AviOutput.cs:332 +msgid "AVI Progress" +msgstr "" + +#: Editor/Form1_EventHandler.cs:144 +#: Editor/Form1_EventHandler.cs:210 +msgid "Text file(*.txt)|*.txt" +msgstr "" + +#: Editor/Form1_EventHandler.cs:506 +msgid "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" +msgstr "" + +#: Editor/Form1_EventHandler.cs:548 +msgid "" +"...clearing entries of selected time-table.\n" +"Would you like to continue?" +msgstr "" + +#: Editor/Form1_EventHandler.cs:924 +msgid "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" +msgstr "" + +#: Editor/Form1_EventHandler.cs:1090 +msgid "" +"...deleting selected character.\n" +"Would you like to continue?" +msgstr "" + +#: Editor/Form1_EventHandler.cs:1100 +msgid "" +"...deleting selected track.\n" +"Would you like to continue?" +msgstr "" + +#: Editor/FormSetFrameRate.cs:167 +msgid "failed getting frame rate" +msgstr "" + +#: Editor/FormSetFrameRate.Designer.cs:186 +msgid "detail" +msgstr "" + +#: Editor/FormSetFrameRate.Designer.cs:187 +msgid "configure frame rate" +msgstr "" + +#: Editor/FormSetFrameRate.Designer.cs:191 +msgid "denominator of frame rate" +msgstr "" + +#: Editor/FormSetFrameRate.Designer.cs:192 +msgid "numerator of frame rate" +msgstr "" + +#: Editor/FormSetFrameRate.Designer.cs:194 +msgid "import frame rate from AVI file" +msgstr "" + +#: Editor/GenerateCharacter.cs:121 +#: Editor/GenerateCharacter.cs:146 +#: Editor/GenerateCharacter.designer.cs:614 +#: Editor/GenerateCharacter.designer.cs:619 +msgid "LipSync Character Config(*.lsc)|*.lsc" +msgstr "" + +#: Editor/GenerateCharacter.cs:147 +#: Editor/GenerateCharacter.cs:879 +msgid "LipSync Character Config(content.xml)|content.xml" +msgstr "" + +#: Editor/GenerateCharacter.cs:512 +msgid "NOT editable" +msgstr "" + +#: Editor/GenerateCharacter.cs:636 +msgid "Title of image" +msgstr "" + +#: Editor/GenerateCharacter.cs:637 +msgid "Input the title of image" +msgstr "" + +#: Editor/GenerateCharacter.cs:653 +msgid "This image title has been already registered" +msgstr "" + +#: Editor/GenerateCharacter.cs:809 +#: Editor/GenerateCharacter.designer.cs:602 +#: Editor/GenerateCharacter.designer.cs:638 +msgid "Change title" +msgstr "" + +#: Editor/GenerateCharacter.cs:810 +msgid "Input new title" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:586 +#: Editor/GenerateCharacter.designer.cs:589 +msgid "Title" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:587 +#: Editor/GenerateCharacter.designer.cs:588 +msgid "Tag" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:590 +#: Editor/GenerateCharacter.designer.cs:642 +msgid "Up" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:591 +#: Editor/GenerateCharacter.designer.cs:637 +msgid "Down" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:592 +#: Editor/GenerateCharacter.designer.cs:635 +msgid "Add" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:595 +msgid "Select image file" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:596 +#: Editor/GenerateCharacter.designer.cs:641 +msgid "Select transparent color" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:600 +msgid "Character name" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:604 +msgid "Selected image" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:607 +msgid "Open *.rsi" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:610 +msgid "Save as *.rsi" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:611 +msgid "Save as XML" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:623 +#: Editor/GenerateCharacter.designer.cs:639 +msgid "Reset image" +msgstr "" + +#: Editor/GenerateCharacter.designer.cs:625 +#: Editor/GenerateCharacter.designer.cs:630 +msgid "RipSync Image(*.rsi)|*.rsi" +msgstr "" + +#: Editor/Previewer.Designer.cs:297 +msgid "Stop" +msgstr "" + +#: Editor/Previewer.Designer.cs:298 +msgid "Stretch image" +msgstr "" + +#: Editor/Previewer.Designer.cs:299 +msgid "Specified size" +msgstr "" + +#: Editor/Property.Designer.cs:241 +msgid "Add telop" +msgstr "" + +#: Editor/Property.Designer.cs:242 +msgid "Delte telop" +msgstr "" + +#: Editor/SelectCharacter.designer.cs:219 +msgid "Custom" +msgstr "" + +#: Editor/SelectCharacter.designer.cs:220 +#: Editor/SelectCharacter.designer.cs:224 +#: Editor/SelectCharacter.designer.cs:225 +msgid "Built-in" +msgstr "" + +#: Editor/SelectCharacter.designer.cs:221 +msgid "Select character to generate lip-sync" +msgstr "" + +#: Editor/SelectCharacter.designer.cs:226 +msgid "Character selection" +msgstr "" + +#: Editor/TrackSelecter.designer.cs:141 +msgid "Select track" +msgstr "" + +#: Editor/TrackSelecter.designer.cs:142 +msgid "import tempo and time-signal information" +msgstr "" + +#: Editor/VersionInfoEx.cs:191 +#: Editor/VersionInfoEx.Designer.cs:118 +msgid "credit" +msgstr "" + +#: Editor/Winker.Designer.cs:261 +msgid "Wink interval (sec)" +msgstr "" + +#: Editor/Winker.Designer.cs:262 +msgid "Randomize" +msgstr "" + +#: Editor/Winker.Designer.cs:263 +msgid "Closed Eye" +msgstr "" + +#: Editor/Winker.Designer.cs:264 +msgid "In-between Image" +msgstr "" + +#: Editor/Winker.Designer.cs:265 +msgid "Eye-closing frames" +msgstr "" + +#: Editor/Winker.Designer.cs:268 +msgid "Limit start time" +msgstr "" + +#: Editor/Winker.Designer.cs:269 +msgid "Limit end time" +msgstr "" + +#: Editor/RipSync/RsiWriter.cs:208 +msgid "Image directory already exists. Would you like to overwrite them?" +msgstr "" + +#: Editor/RipSync/RsiWriter.cs:209 +msgid "warning" +msgstr "" + diff --git a/trunk/LipSync/LipSync/en.lang b/trunk/LipSync/LipSync/en.lang new file mode 100644 index 0000000..865f43a --- /dev/null +++ b/trunk/LipSync/LipSync/en.lang @@ -0,0 +1,246 @@ +SERIES_BITMAP Series bitmap +SAVE_AS_XML Save as *.XML +TTIP_IMPORT_FRAME_RATE_FROM_AVI import frame rate from AVI file +IMPORT2 Import +DENOMINATOR_OF_FRAME_RATE denominator of frame rate +NUMERATOR_OF_FRAME_RATE numerator of frame rate +CONFIG_FRAME_RATE configure frame rate +DETAIL detail +FAILED_GETTING_FRAME_RATE failed getting frame rate +FILTER_ALLFILES All Files(*.*)|*.* +MOUSE_WHEEL_RATE mouse wheel rate +OPERATION Operation +CREDIT credit +RESET_IMAGE Reset image +FILTER_CHARACTER_XML LipSync Character Config(content.xml)|content.xml +FILTER_CHARACTER LipSync Character Config(*.lsc)|*.lsc +OFF off +APPEARANCE Appearance +IMPORT_TEMPO_AND_TIMESIG import tempo and time-signal information +WARN_OVERWRITE_TIMESIG This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue? +WARN_EXIST_SAME_FOLDER Image directory already exists. Would you like to overwrite them? +WARNING warning +SAVE_AS_RSI Save as *.RSI +OPEN_RSI Open *.RSI +TRIPLET triplet +QUANTIZE Quantize +SHOW_BARS Show bars +SHOW_VSQ_ALLWAYS Show VSQ tracks allways +RELOAD_LANG_CONFIG Reload language configurations +PLUGIN Plugin +VSQ_TRACK VSQ Tracks +CHARACTER Character +ANOTHER_IMAGE Another images +CONFIRMATION Confirmation +IMAGE Image +COPY_TIME_LINE Copy time-line +PASTE_TIME_LINE Paste time-line +NOTE_ON Note ON from here +NOTE_OFF Note OFF +SET_SCALE Scale setting +DELETING_TRACK ...deleting selected track.\nWould you like to continue? +DELETING_CHARACTER ...deleting selected character.\nWould you like to continue? +CLEAR_ENTRIES ...clearing entries of selected time-table.\nWould you like to continue? +ENTER_SCALE Please enter scale. (If entered value is minus, character or image will be flipped horizontally.) +INVALID_VALUE Invalid value has been entered +ERROR Error +SET_IMAGE_POSITION Image placement +AVI_INITIALIZATION_FAILED Initialization of video compression failed.\nThis video codec may require image width in multiples of certain number. +DELETE Delete +WARN_DELETE_ALL_TRACKS This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue? +INCASE_APPEND_TRACK ( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. ) +READ_VSQ Read from VSQ file +SET_VIDEO_SIZE Video size configuration +GEN_LIPSYNC_FROM_THIS Generate Lipsync from this track +SAVE_FILE has been changed. Do you wish to save changes to file? +SAVE_FILE_CREATE Do you wish to save changes to file? +TIMELINE Timeline +PREVIEW_IMAGE Preview image +FILE File +OPEN Open +SAVE Save +SAVE_AS Save As +IMPORT Import +RIPSYNC_DATA from RipSync data +OPEN_VSQ Open VSQ file +EXIT Exit +WINDOW Window +SHOW_PREVIEW Show preview +GOTO_PREVIEW Go to preview +HELP Help +PLUGIN_INFO Plugin information +VERSION_INFO About LipSync +DEBUG Debug +EDIT_CHARACTER Edit character +FLIP_HORIZONTALY Flip images horizontaly +EDIT Edit +UNDO Undo +REDO Redo +VIDEO_SIZE Video size +FRAME_RATE Frame rate +Z_ORDER Z order +CHANGE_VIDEO_LENGTH Video length +SHIFT_TIME_TABLE Shift all time-tables +VIEW View +ZOOM Zoom +MOOZ Mooz +DEFAULT_SCALE Set default scale +MOVE_TO_TOP Move to Top +MOVE_TO_END Move to End +TOOL Tool +OPTION Option +CANCEL Cancel +ON_TIME ON time (sec) +OFF_TIME OFF time (sec) +OK OK +USE_THIS_VALUE Use this value +EXPANDABLE_RANGE Expandable range of this entry +INPUT_NUMBER Numeric entry +LANGUAGE Language +SELECT_CONFIG_TARGET_BELOW select configuration item from the list box below +ADD Add +SELECT_IMAGE_FILE Select image file +SELECT_TRANSPARENT_COLOR Select transparent color +CHARACTER_NAME Character name +SHIFT_THIS_TIMELINE Shift this time-line +CLOSE Close +GENERATE_AVI Generate AVI +CHOSE_SOUND_FILE Chose sound file +GOTO_SPECIFIED_FRAME Go to specified frame +FILTER_TEXT Text file(*.txt)|*.txt +STRETCH_IMAGE Stretch image +SPECIFIED_SIZE Specified size +PLAY Play +STOP Stop +OVER_2GB AVI file size will exceed 2Gbyte.\nDo you wish to continue? +PAUSE Pause +REQUIRE_FRAME_INDEX please input frame index +INVALID_FRAME_INDEX invalid frame index +BUILT_IN Built-in +CUSTOM Custom +SELECT_CHARACTER Select character to generate lip-sync +CHARACTER_SELECTION Character selection +WIDTH Width +HEIGHT Height +SELECT_TRACK Select track +WINK_INTERVAL Wink interval (sec) +RANDOMIZE Randomize +CLOSED_EYE Closed Eye +IN_BETWEEN_IMAGE In-between Image +EYE_CLOSING_FRAME Eye-closing frames +GENERATE_WINK Generate wink +UP Up +DOWN Down +SELECT_TARGET_ITEM Select target item, and push [Up] or [Down] button +DELETE_ENTRIES Delete entries +ADD_TRACK Add track +SET_IMAGE Set image +CHANGE_IMAGE Change image +THIS_PLUGIN_CONFIG Plugin config. of this entry +EXPAND Expand +FAILED_FILE_SAVING Failed file saving +FAILED_FILE_READING Failed file reading +INPUT_VIDEO_LENGTH Input video length in second +INPUT_SHIFT_TIME Input shift time in second (you can enter minus value) +INPUT_FRAME_RATE Input frame rate +FILE_NOT_FOUND File not found +GENERATE_TELOP_FROM_VSQ Generate telop from VSQ +CHANGE_TITLE Change title +INPUT_NEW_TITLE Input new title +TITLE_OF_IMAGE Title of image +INPUT_IMAGE_TITLE Input the title of image +NOT_EDITABLE NOT editable +EXPAND_ALL Expand all +FOLD_ALL Fold all +NO_NAME (no name) +ENABLE_PREVIEW Enable preview +DISABLE_PREVIEW Disable preview +PLUGIN_CONFIG Plugin config +SYNC_WITH_TIMETABLE Sync with Time table +ADD_EMPTY_CHARACTER Add empty character +START_TIME_LIMITATION Limit start time +END_TIME_LIMITATION Limit end time +COPY Copy +PASTE Paste +CUT Cut +WAV_ADDITION_FAILED insertion of wav file has failed +STOP_WRITING_AVI Stop writing avi +FILE_NAME file name +BGCOLOR Background color +USER_CONFIG User Config +LIPSYNC_OPTION lip-sync Option +TITLE_OF_TIMELINE Title of timeline +VSQ_ENTRY VSQ Entry +PLUGIN_ENTRY Plugin Entry +ANOTHER_ENTRY Another Entry +ENTRY_HEIGHT Entry height (pixel) +CHANGE Change +CHECK_PHONETIC_SYMBOL Check phonetic symbol to configure detailed mouth shape control +U_SHAPED_MOUTH "u" shaped mouth before pronunciation +CLOSED_MOUTH Close mouth before pronunciation +I_SHAPED_MOUTH "i" shaped mouth before pronunciation +EXPORT_TO_TEXT Export to TEXT +IMPORT_FROM_TEXT Import from TEXT +COLOR Color +DESIGN Design +SYSTEM System +PATH_OF_FFMPEG Path of ffmpeg +PATH_OF_MENCODER Path of mencoder +INVALID_IMAGE_TITLE Image title can't be set to "base", "a", "aa", "i", "u", "e", "o", "xo", "nn" +TITLE_ALREADY_EXIST This image title has been already registered +PROGRESS AVI Progress +FILTER_AVI Avi file(*.avi)|*.avi +INVALID_EXTENSION Extension must be *.lse +SPECIFY_PASTE_MODE Specify paste mode +INTERRUPT Interrupt +OVERWRITE Overwrite +NON_COMPRESSED_AVI Generate raw AVI +VIDEO Video +AUDIO Audio +CONVERT_TO_FLV Convert to FLV +DELETE_INTERMEDIATE Delete intermediate file +MERGE_WAVE_TO_AVI Merge wave to AVI +VIDEO_COMPRESSION Video Compression +OUTPUT_RANGE Specify output range +START Start +END End +FILTER_AUDIO Audio file(*.mp3;*.wav)|*.mp3;*.wav +ALREADY_EXISTS already exists. +REPLACE_IT Do you want to replace it? +DIRECTORY Directory +DOES_NOT_EXIST does not exist. +TITLE Title +TAG Tag +SELECTED_IMAGE Selected Image +EXPORT Export +HATWUNE script for H@TWUNEBENCH +LIST_OF_OBJECTS List of object +PROPERTY Property +OBJECT_NAME Object name +ADD_TELOP Add telop +ENABLE_PROPERTY Show object list +DISABLE_PROPERTY Hide object list +BUG_REPORT Bug report +FONT Font +DELETE_TELOP Delte telop +SPLIT Split entry +ANOTHER_CONFIG Another settings +SERIAL_VOWEL Close mouth when same vowels repeated +FLV_PROGRESS FLV Progress +FILTER_EXE Executable file(*.exe)|*.exe +FILTER_VSQ VOCALOID2 Sequence File(*.vsq)|*.vsq +FILTER_IMAGE Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg +FILTER_LSE LipSync data file(*.lse)|*.lse +RAW (Non-compressed) +ENCODER_DECODER Encoder/Decoder +GEN_CHARACTER_AUTOMATICALY Generate character automaticaly when importing vsq +COMBINE_THRESHOLD Threshold silence length(sec) +REALTIME Real time "lipsync" +INVERSE_ON_OFF Copy On/Off inverted +REPEAT_PLAY Repeat play +MOTION_CURVE Edit motion curve +SET_REPEAT_START Start repeat from +SET_REPEAT_END End repeat at +RESET_REPEAT_REGION Reset repeat region +USE_PREVIEWABLE_DIALOG Use preview-enabled dialog in character selection +FILTER_RSI RipSync Image(*.rsi)|*.rsi \ No newline at end of file diff --git a/trunk/LipSync/LipSync/ja.po b/trunk/LipSync/LipSync/ja.po new file mode 100644 index 0000000..c5ebf11 --- /dev/null +++ b/trunk/LipSync/LipSync/ja.po @@ -0,0 +1,1301 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-03-09 00:16+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: kbinani \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Japanese\n" +"X-Poedit-Country: JAPAN\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Basepath: ..\\..\\\n" +"X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: lipsync\\LipSync\\Editor\n" +"X-Poedit-SearchPath-1: lipsync\\LipSync\\Common\n" +"X-Poedit-SearchPath-2: Boare.Lib.AppUtil\n" + +#: lipsync\LipSync\Editor/AviOutput.cs:59 +msgid "Cancel" +msgstr "キャンセル" + +#: lipsync\LipSync\Editor/AviOutput.cs:60 +msgid "Save" +msgstr "保存" + +#: lipsync\LipSync\Editor/AviOutput.cs:61 +msgid "File Name" +msgstr "ファイル名" + +#: lipsync\LipSync\Editor/AviOutput.cs:63 +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Audio" +msgstr "オーディオ" + +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Set the path of ffmpeg to enable this option" +msgstr "このオプションを使うにはffmpegへのパスを設定して下さい" + +#: lipsync\LipSync\Editor/AviOutput.cs:70 +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "FLV and MP4" +msgstr "FLVとMP4" + +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "Set the path of mencoder and ffmpeg to enable this option" +msgstr "このオプションを使うにはmencoderとffmpegへのパスを設定して下さい" + +#: lipsync\LipSync\Editor/AviOutput.cs:76 +msgid "Convert to FLV" +msgstr "flvに変換" + +#: lipsync\LipSync\Editor/AviOutput.cs:77 +msgid "Convert to MP4" +msgstr "mp4に変換" + +#: lipsync\LipSync\Editor/AviOutput.cs:78 +msgid "Merge WAVE to AVI" +msgstr "AVIに埋め込む" + +#: lipsync\LipSync\Editor/AviOutput.cs:79 +msgid "Delete Intermediate File" +msgstr "中間ファイルを削除する" + +#: lipsync\LipSync\Editor/AviOutput.cs:80 +msgid "Video Compression" +msgstr "ビデオ圧縮" + +#: lipsync\LipSync\Editor/AviOutput.cs:81 +msgid "Specify Output Range" +msgstr "出力範囲を指定" + +#: lipsync\LipSync\Editor/AviOutput.cs:82 +msgid "Start" +msgstr "開始" + +#: lipsync\LipSync\Editor/AviOutput.cs:83 +msgid "End" +msgstr "終了" + +#: lipsync\LipSync\Editor/AviOutput.cs:84 +msgid "Add Alpha" +msgstr "アルファ値を含める" + +#: lipsync\LipSync\Editor/AviOutput.cs:118 +#, csharp-format +msgid "Directory {0} does not exist." +msgstr "ディレクトリ {0} は存在しません。" + +#: lipsync\LipSync\Editor/AviOutput.cs:119 +#: lipsync\LipSync\Editor/AviOutput.cs:140 +msgid "Error" +msgstr "エラー" + +#: lipsync\LipSync\Editor/AviOutput.cs:127 +#, csharp-format +msgid "" +"{0} already exists.\n" +"Do you want to replace it?" +msgstr "" +"{0} は既に存在します\n" +"置き換えますか?" + +#: lipsync\LipSync\Editor/AviOutput.cs:139 +msgid "Invalid value has been entered" +msgstr "無効な値です" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "Avi file(*.avi)|*.avi" +msgstr "AVIファイル(*.avi)|*.avi" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "All Files(*.*)|*.*" +msgstr "全てのファイル|*.*" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:88 +msgid "Edit Motion Curve" +msgstr "変位の制御" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:89 +msgid "Close" +msgstr "閉じる" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:90 +msgid "File" +msgstr "ファイル" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:91 +msgid "Redo" +msgstr "やり直し" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:92 +msgid "Undo" +msgstr "元に戻す" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:93 +msgid "Edit" +msgstr "編集" + +#: lipsync\LipSync\Editor/EditEntry.cs:58 +msgid "ON time (sec)" +msgstr "ON時刻 (秒)" + +#: lipsync\LipSync\Editor/EditEntry.cs:59 +msgid "OFF time (sec)" +msgstr "OFF時刻 (秒)" + +#: lipsync\LipSync\Editor/EditEntry.cs:61 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:101 +msgid "OK" +msgstr "OK" + +#: lipsync\LipSync\Editor/EditEntry.cs:62 +msgid "Use this value" +msgstr "この値を使う" + +#: lipsync\LipSync\Editor/EditEntry.cs:63 +msgid "Expandable range of this entry" +msgstr "変更可能な値の範囲" + +#: lipsync\LipSync\Editor/EditEntry.cs:64 +msgid "Numeric entry" +msgstr "数値入力" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:103 +msgid "Language" +msgstr "言語" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:104 +#: lipsync\LipSync\Editor/Form1Util.cs:130 +msgid "Option" +msgstr "オプション" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:106 +msgid "User Config" +msgstr "ユーザー設定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:107 +msgid "Appearance" +msgstr "外観" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:108 +msgid "lip-sync Option" +msgstr "口パク生成" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:109 +msgid "System" +msgstr "システム" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:111 +msgid "Title of timeline" +msgstr "タイムラインのタイトル" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:112 +msgid "VSQ Entry" +msgstr "VSQエントリ" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:113 +msgid "Plugin Entry" +msgstr "プラグインエントリ" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:114 +msgid "Another Entry" +msgstr "その他のエントリ" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:115 +msgid "Entry height (pixel)" +msgstr "エントリの高さ (ピクセル)" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:116 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:117 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:118 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:119 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:129 +msgid "Change" +msgstr "変更" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:120 +msgid "Check phonetic symbol to configure detailed mouth shape control" +msgstr "発音の直前に口の形を変化させる発音記号を指定します" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:121 +msgid "Close mouth before pronunciation" +msgstr "発音の直前に口を閉じる" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:122 +msgid "\"i\" shaped mouth before pronunciation" +msgstr "発音の直前に\"い\"の口の形にする" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:123 +msgid "\"u\" shaped mouth before pronunciation" +msgstr "発音の直前に\"う\"の口の形にする" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:124 +msgid "Color" +msgstr "配色" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:125 +msgid "Design" +msgstr "表示" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:126 +msgid "Path of ffmpeg" +msgstr "ffmpegの場所" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:127 +msgid "Path of mencoder" +msgstr "mencoderの場所" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:128 +msgid "Font" +msgstr "フォント" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:130 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:135 +msgid "Another settings" +msgstr "その他の設定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:131 +msgid "Close mouth when same vowels repeated" +msgstr "同一母音が連続するとき、口を閉じる" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:132 +msgid "Encoder/Decoder" +msgstr "エンコーダ/デコーダ" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:133 +msgid "Generate character automaticaly when importing vsq" +msgstr "VSQ読込み時にキャラクタを自動生成する" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:134 +msgid "Threshold silence length(sec)" +msgstr "連続音とみなす無音時間(秒)" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:136 +msgid "Use preview-enabled dialog in character selection" +msgstr "プレビュー可能なキャラクタファイル選択ダイアログを使用" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:137 +msgid "Reload language configurations" +msgstr "言語設定ファイルをリロード" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:138 +msgid "Operation" +msgstr "操作" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:139 +msgid "mouse wheel rate" +msgstr "マウスホイール速度" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:140 +msgid "Fix cursor to center in Sync mode" +msgstr "シンクロ表示時にカーソルが中央に表示されるようにする" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:281 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:305 +msgid "Executable file(*.exe)|*.exe" +msgstr "実行可能ファイル(*.exe)|*.exe" + +#: lipsync\LipSync\Editor/Form1.cs:604 +#: lipsync\LipSync\Editor/Form1.cs:2011 +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Video size configuration" +msgstr "ビデオのサイズを設定" + +#: lipsync\LipSync\Editor/Form1.cs:612 +msgid "Read from VSQ file" +msgstr "VSQファイルから読込" + +#: lipsync\LipSync\Editor/Form1.cs:616 +msgid "Edit character" +msgstr "キャラクタを編集" + +#: lipsync\LipSync\Editor/Form1.cs:619 +#: lipsync\LipSync\Editor/Form1.cs:652 +#: lipsync\LipSync\Editor/Form1.cs:668 +msgid "Preview image" +msgstr "画像のプレビュー" + +#: lipsync\LipSync\Editor/Form1.cs:620 +#: lipsync\LipSync\Editor/Form1.cs:677 +#: lipsync\LipSync\Editor/Form1.cs:737 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:964 +msgid "Image placement" +msgstr "イメージ位置の設定" + +#: lipsync\LipSync\Editor/Form1.cs:621 +#: lipsync\LipSync\Editor/Form1.cs:680 +#: lipsync\LipSync\Editor/Form1.cs:740 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Scale setting" +msgstr "表示倍率の設定" + +#: lipsync\LipSync\Editor/Form1.cs:623 +msgid "Generate wink" +msgstr "目パチの生成" + +#: lipsync\LipSync\Editor/Form1.cs:627 +#: lipsync\LipSync\Editor/Form1.cs:791 +msgid "Delete" +msgstr "削除" + +#: lipsync\LipSync\Editor/Form1.cs:630 +msgid "Add Telop" +msgstr "テロップを追加" + +#: lipsync\LipSync\Editor/Form1.cs:633 +msgid "Add track" +msgstr "トラックを追加" + +#: lipsync\LipSync\Editor/Form1.cs:643 +msgid "Generate Lipsync from this track" +msgstr "このトラックから口パクを生成" + +#: lipsync\LipSync\Editor/Form1.cs:649 +#: lipsync\LipSync\Editor/Form1.cs:660 +#: lipsync\LipSync\Editor/Form1.cs:691 +msgid "Note ON from here" +msgstr "この位置でノートON" + +#: lipsync\LipSync\Editor/Form1.cs:664 +msgid "Set image" +msgstr "画像を指定" + +#: lipsync\LipSync\Editor/Form1.cs:671 +msgid "Change image" +msgstr "画像を変更" + +#: lipsync\LipSync\Editor/Form1.cs:675 +#: lipsync\LipSync\Editor/Form1.cs:735 +msgid "Image" +msgstr "画像" + +#: lipsync\LipSync\Editor/Form1.cs:702 +#: lipsync\LipSync\Editor/Form1.cs:775 +msgid "Paste" +msgstr "貼付" + +#: lipsync\LipSync\Editor/Form1.cs:716 +msgid "Note OFF" +msgstr "この位置でノートOFF" + +#: lipsync\LipSync\Editor/Form1.cs:718 +msgid "Image Preview" +msgstr "プレビューを表示" + +#: lipsync\LipSync\Editor/Form1.cs:720 +msgid "Numeric Entry" +msgstr "数値入力" + +#: lipsync\LipSync\Editor/Form1.cs:722 +msgid "Expand" +msgstr "拡張" + +#: lipsync\LipSync\Editor/Form1.cs:730 +msgid "Set Image" +msgstr "画像を指定" + +#: lipsync\LipSync\Editor/Form1.cs:732 +msgid "Preview Image" +msgstr "画像のプレビュー" + +#: lipsync\LipSync\Editor/Form1.cs:733 +msgid "Change Image" +msgstr "画像を変更" + +#: lipsync\LipSync\Editor/Form1.cs:749 +msgid "Plugin config. of this entry" +msgstr "このエントリのプラグイン設定" + +#: lipsync\LipSync\Editor/Form1.cs:755 +#: lipsync\LipSync\Editor/Form1.cs:767 +msgid "Copy" +msgstr "コピー" + +#: lipsync\LipSync\Editor/Form1.cs:756 +msgid "Cut" +msgstr "切取" + +#: lipsync\LipSync\Editor/Form1.cs:757 +msgid "Split Entry" +msgstr "エントリを分割" + +#: lipsync\LipSync\Editor/Form1.cs:765 +msgid "Timeline" +msgstr "タイムライン" + +#: lipsync\LipSync\Editor/Form1.cs:771 +msgid "Copy On/Off inverted" +msgstr "ON/OFF反転コピー" + +#: lipsync\LipSync\Editor/Form1.cs:779 +msgid "Import from TEXT" +msgstr "テキストからインポート" + +#: lipsync\LipSync\Editor/Form1.cs:780 +msgid "Export to TEXT" +msgstr "テキストにエクスポート" + +#: lipsync\LipSync\Editor/Form1.cs:793 +msgid "Delete entries" +msgstr "トラック上のエントリを削除" + +#: lipsync\LipSync\Editor/Form1.cs:797 +msgid "Shift this time-line" +msgstr "指定秒数シフト" + +#: lipsync\LipSync\Editor/Form1.cs:1367 +#: lipsync\LipSync\Editor/Form1.cs:1407 +#: lipsync\LipSync\Editor/Form1.cs:1603 +msgid "VSQ Tracks" +msgstr "VSQトラック" + +#: lipsync\LipSync\Editor/Form1.cs:1378 +msgid "Character" +msgstr "キャラクタ" + +#: lipsync\LipSync\Editor/Form1.cs:1385 +msgid "Telop" +msgstr "字幕" + +#: lipsync\LipSync\Editor/Form1.cs:1392 +msgid "Another Images" +msgstr "その他のイメージ" + +#: lipsync\LipSync\Editor/Form1.cs:1399 +#: lipsync\LipSync\Editor/Form1.cs:1577 +msgid "Plugin" +msgstr "プラグイン" + +#: lipsync\LipSync\Editor/Form1.cs:1540 +msgid "LipSync" +msgstr "LipSync" + +#: lipsync\LipSync\Editor/Form1.cs:1605 +#: lipsync\LipSync\Editor/Form1.cs:2394 +msgid "Another images" +msgstr "その他のイメージ" + +#: lipsync\LipSync\Editor/Form1.cs:1952 +msgid "" +"Initialization of video compression failed.\n" +"This video codec may require image width in multiples of certain number." +msgstr "" +"ビデオ圧縮の初期化に失敗しました\n" +"画像サイズを特定の倍数にしないと使用出来ないコーデックの可能性があります。" + +#: lipsync\LipSync\Editor/Form1.cs:1963 +msgid "AVI Progress" +msgstr "AVI出力中" + +#: lipsync\LipSync\Editor/Form1.cs:2011 +msgid "Input video length in second" +msgstr "ビデオの長さを秒単位で入力してください" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Shift all time-tables" +msgstr "全タイムラインをシフト" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Input shift time in second (you can enter minus value)" +msgstr "シフトする秒数を入力してください(マイナス可)" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +#: lipsync\LipSync\Editor/Form1.cs:2689 +msgid "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" +msgstr "この操作は既存のトラックを全て上書きします。また、やり直しもできません。よろしいですか?" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +msgid "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" +msgstr "" +"(現在のトラックに追加するときは、「VSQトラック」を右クリックし、\n" +"「VSQファイルから読込」を選択してください)" + +#: lipsync\LipSync\Editor/Form1.cs:2300 +#: lipsync\LipSync\Editor/Form1.cs:2690 +#: lipsync\LipSync\Editor/Form1Util.cs:249 +#: lipsync\LipSync\Editor/Form1Util.cs:283 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "Confirmation" +msgstr "確認" + +#: lipsync\LipSync\Editor/Form1.cs:2313 +#: lipsync\LipSync\Editor/Form1Util.cs:150 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:931 +msgid "VOCALOID2 Sequence File(*.vsq)|*.vsq" +msgstr "VOCALOID2 データファイル(*.vsq)|*.vsq" + +#: lipsync\LipSync\Editor/Form1.cs:2314 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:932 +msgid "UTAU Script File(*.ust)|*.ust" +msgstr "UTAUスクリプト形式(*.ust)|*.ust" + +#: lipsync\LipSync\Editor/Form1.cs:2436 +#: lipsync\LipSync\Editor/Form1.cs:2569 +msgid "Specify the index of target character" +msgstr "出力対象のキャラクタを番号で指定してください" + +#: lipsync\LipSync\Editor/Form1.cs:2707 +#: lipsync\LipSync\Editor/Form1.cs:3134 +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1907 +msgid "Play" +msgstr "再生" + +#: lipsync\LipSync\Editor/Form1.cs:2711 +msgid "File not found" +msgstr "ファイルがありません" + +#: lipsync\LipSync\Editor/Form1.cs:2730 +#: lipsync\LipSync\Editor/Form1.cs:2758 +#: lipsync\LipSync\Editor/Form1.cs:2770 +msgid "Extension must be *.lse" +msgstr "*.lse以外の拡張子にすることはできません" + +#: lipsync\LipSync\Editor/Form1.cs:2895 +msgid "Expand All" +msgstr "全て展開" + +#: lipsync\LipSync\Editor/Form1.cs:2896 +msgid "Fold All" +msgstr "全て折り畳み" + +#: lipsync\LipSync\Editor/Form1.cs:3138 +msgid "Audio File(*.mp3;*.wav)|*.mp3;*.wav" +msgstr "音声ファイル(*.mp3,*.wav)|*.mp3;*.wav" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "Go to specified frame" +msgstr "指定フレームに移動" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "please input frame index" +msgstr "フレームインデックスを入力してください" + +#: lipsync\LipSync\Editor/Form1.cs:3166 +msgid "invalid frame index" +msgstr "そのようなフレームはありません" + +#: lipsync\LipSync\Editor/Form1.cs:3702 +msgid "Series Image Progress" +msgstr "連番画像出力中" + +#: lipsync\LipSync\Editor/Form1Util.cs:104 +msgid "Open" +msgstr "開く" + +#: lipsync\LipSync\Editor/Form1Util.cs:106 +msgid "Save As" +msgstr "別名で保存" + +#: lipsync\LipSync\Editor/Form1Util.cs:107 +msgid "Import" +msgstr "インポート" + +#: lipsync\LipSync\Editor/Form1Util.cs:108 +msgid "from RipSync data" +msgstr "RipSyncデータ" + +#: lipsync\LipSync\Editor/Form1Util.cs:109 +msgid "Open VSQ/UST file" +msgstr "VSQ/USTを開く" + +#: lipsync\LipSync\Editor/Form1Util.cs:110 +msgid "Exit" +msgstr "終了" + +#: lipsync\LipSync\Editor/Form1Util.cs:111 +msgid "Script for VOCALOMARK" +msgstr "VOCALOMARK用スクリプト" + +#: lipsync\LipSync\Editor/Form1Util.cs:115 +msgid "Help" +msgstr "ヘルプ" + +#: lipsync\LipSync\Editor/Form1Util.cs:116 +msgid "Plugin Information" +msgstr "プラグイン情報" + +#: lipsync\LipSync\Editor/Form1Util.cs:117 +msgid "About LipSync" +msgstr "LipSyncについて" + +#: lipsync\LipSync\Editor/Form1Util.cs:118 +msgid "Debug" +msgstr "デバッグ" + +#: lipsync\LipSync\Editor/Form1Util.cs:119 +msgid "Edit Character" +msgstr "キャラクタを編集" + +#: lipsync\LipSync\Editor/Form1Util.cs:120 +msgid "Flip Images Horizontaly" +msgstr "イメージを左右反転" + +#: lipsync\LipSync\Editor/Form1Util.cs:124 +msgid "Video Size" +msgstr "ビデオサイズ" + +#: lipsync\LipSync\Editor/Form1Util.cs:125 +msgid "Frame Rate" +msgstr "フレームレート" + +#: lipsync\LipSync\Editor/Form1Util.cs:126 +msgid "Z order" +msgstr "描画順序" + +#: lipsync\LipSync\Editor/Form1Util.cs:127 +msgid "Video Length" +msgstr "ビデオの長さを変更" + +#: lipsync\LipSync\Editor/Form1Util.cs:128 +msgid "Shift All Time-tables" +msgstr "全タイムラインをシフト" + +#: lipsync\LipSync\Editor/Form1Util.cs:129 +msgid "Tool" +msgstr "ツール" + +#: lipsync\LipSync\Editor/Form1Util.cs:131 +msgid "Plugin Config" +msgstr "プラグイン設定" + +#: lipsync\LipSync\Editor/Form1Util.cs:132 +msgid "Add Empty Character" +msgstr "空のキャラクタを追加" + +#: lipsync\LipSync\Editor/Form1Util.cs:134 +msgid "Generate Avi" +msgstr "Avi出力" + +#: lipsync\LipSync\Editor/Form1Util.cs:135 +msgid "Chose Sound File" +msgstr "同時再生する曲" + +#: lipsync\LipSync\Editor/Form1Util.cs:136 +msgid "Go to Specified Frame" +msgstr "指定フレームに移動" + +#: lipsync\LipSync\Editor/Form1Util.cs:137 +msgid "Stop Writing Avi" +msgstr "出力の中断" + +#: lipsync\LipSync\Editor/Form1Util.cs:138 +msgid "Background Color" +msgstr "背景色" + +#: lipsync\LipSync\Editor/Form1Util.cs:140 +msgid "Generate Raw Avi" +msgstr "無圧縮のAviを出力" + +#: lipsync\LipSync\Editor/Form1Util.cs:141 +msgid "Export" +msgstr "エクスポート" + +#: lipsync\LipSync\Editor/Form1Util.cs:142 +msgid "Script for H@TWUNEBENCH" +msgstr "はとぅねベンチ用スクリプト" + +#: lipsync\LipSync\Editor/Form1Util.cs:144 +msgid "Show Object List" +msgstr "オブジェクトリストを表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:146 +msgid "Hide Object List" +msgstr "オブジェクトリストを非表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:148 +msgid "Bug Report" +msgstr "バグレポート" + +#: lipsync\LipSync\Editor/Form1Util.cs:158 +msgid "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" +msgstr "画像ファイル(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" + +#: lipsync\LipSync\Editor/Form1Util.cs:159 +msgid "Avi File(*.avi)|*.avi" +msgstr "Aviファイル(*.avi)|*.avi" + +#: lipsync\LipSync\Editor/Form1Util.cs:167 +msgid "LipSync Data File(*.lse)|*.lse" +msgstr "LipSyncデータ設定(*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:175 +msgid "LipSync Data file(*.lse)|*.lse" +msgstr "LipSyncデータ設定(*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:183 +msgid "Real Time \"lipsync\"" +msgstr "リアルタイム打ち込み" + +#: lipsync\LipSync\Editor/Form1Util.cs:184 +msgid "End Repeat Here" +msgstr "リピート終了位置に指定" + +#: lipsync\LipSync\Editor/Form1Util.cs:185 +msgid "Start Repeat Here" +msgstr "リピート開始位置に指定" + +#: lipsync\LipSync\Editor/Form1Util.cs:186 +msgid "Reset Repeat region" +msgstr "リピート範囲をリセット" + +#: lipsync\LipSync\Editor/Form1Util.cs:189 +msgid "View" +msgstr "表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:190 +msgid "Zoom" +msgstr "拡大" + +#: lipsync\LipSync\Editor/Form1Util.cs:191 +msgid "Mooz" +msgstr "縮小" + +#: lipsync\LipSync\Editor/Form1Util.cs:192 +msgid "Set Default Scale" +msgstr "元の倍率" + +#: lipsync\LipSync\Editor/Form1Util.cs:193 +#: lipsync\LipSync\Editor/Form1Util.cs:197 +msgid "Move to Top" +msgstr "先頭へ" + +#: lipsync\LipSync\Editor/Form1Util.cs:194 +#: lipsync\LipSync\Editor/Form1Util.cs:196 +msgid "Move to End" +msgstr "最後へ" + +#: lipsync\LipSync\Editor/Form1Util.cs:195 +msgid "Repeat play" +msgstr "リピート再生" + +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1850 +msgid "Pause" +msgstr "一時停止" + +#: lipsync\LipSync\Editor/Form1Util.cs:200 +msgid "Show VSQ Tracks Allways" +msgstr "VSQトラックを常に表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:201 +msgid "Show Bars" +msgstr "小節の境界を表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:202 +msgid "Preview" +msgstr "プレビュー" + +#: lipsync\LipSync\Editor/Form1Util.cs:204 +msgid "Sync with Time-table" +msgstr "タイムテーブルとシンクロ" + +#: lipsync\LipSync\Editor/Form1Util.cs:206 +#: lipsync\LipSync\Editor/Form1Util.cs:467 +msgid "Enable Preview" +msgstr "プレビューを表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:208 +#: lipsync\LipSync\Editor/Form1Util.cs:461 +msgid "Disable Preview" +msgstr "プレビューを非表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:210 +msgid "Separate Preview Window" +msgstr "プレビューをウィンドウに分離" + +#: lipsync\LipSync\Editor/Form1Util.cs:213 +msgid "Quantize" +msgstr "クオンタイズ" + +#: lipsync\LipSync\Editor/Form1Util.cs:214 +msgid "Off" +msgstr "オフ" + +#: lipsync\LipSync\Editor/Form1Util.cs:215 +msgid "Triplet" +msgstr "3連符" + +#: lipsync\LipSync\Editor/Form1Util.cs:217 +msgid "List of Object" +msgstr "オブジェクトリスト" + +#: lipsync\LipSync\Editor/Form1Util.cs:218 +msgid "Property" +msgstr "オブジェクトのプロパティ" + +#: lipsync\LipSync\Editor/Form1Util.cs:230 +msgid "Series Image" +msgstr "連番画像" + +#: lipsync\LipSync\Editor/Form1Util.cs:248 +#: lipsync\LipSync\Editor/Form1Util.cs:282 +msgid "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" +msgstr "テンポ・拍子情報を上書きします。この操作はやり直し出来ませんが、続けますか?" + +#: lipsync\LipSync\Editor/Form1Util.cs:411 +msgid "Hide object list" +msgstr "オブジェクトリストを非表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:417 +msgid "Show object list" +msgstr "オブジェクトリストを表示" + +#: lipsync\LipSync\Editor/Form1Util.cs:442 +msgid "(no name)" +msgstr "無題" + +#: lipsync\LipSync\Editor/Form1Util.cs:498 +msgid "Failed file saving" +msgstr "保存に失敗しました" + +#: lipsync\LipSync\Editor/Form1Util.cs:569 +msgid "Failed file reading" +msgstr "読み込みに失敗しました" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Width" +msgstr "幅" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Height" +msgstr "高さ" + +#: lipsync\LipSync\Editor/Form1Util.cs:1343 +msgid " has been changed. Do you wish to save changes to file?" +msgstr "への変更を保存しますか?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1345 +msgid "Do you wish to save changes to file?" +msgstr "ファイルに保存しますか?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1986 +msgid "Progress" +msgstr "進捗" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:167 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:229 +msgid "Text file(*.txt)|*.txt" +msgstr "テキストファイル(*.txt)|*.txt" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" +msgstr "倍率を入力してください(負の値を入れると左右が反転されます)" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +msgid "" +"...clearing entries of selected time-table.\n" +"Would you like to continue?" +msgstr "" +"選択したトラック上のエントリをクリアします。\n" +"よろしいですか?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +msgid "" +"...deleting selected character.\n" +"Would you like to continue?" +msgstr "" +"選択したキャラクタをクリアします。\n" +"よろしいですか?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "" +"...deleting selected track.\n" +"Would you like to continue?" +msgstr "" +"選択したトラックを削除します。\n" +"よろしいですか?" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:75 +#: lipsync\LipSync\Editor/FormCommandHistory.cs:92 +msgid "Command History" +msgstr "コマンドの履歴" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:131 +#, csharp-format +msgid "Delete entry of 'Another Image' at Index {0}" +msgstr "その他のイメージのエントリを削除: Index{0}" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:133 +#, csharp-format +msgid "Add entry of 'Another Image' at Index {0}" +msgstr "その他のイメージのエントリを追加: Index{0}" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:135 +#, csharp-format +msgid "Edit entry of 'Another Image' at Track {0}, Index {1}" +msgstr "その他のイメージのエントリを編集: Track{0}: Index {1}" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:139 +#, csharp-format +msgid "Delete telop '{0}'" +msgstr "字幕を削除: '{0}'" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:141 +#, csharp-format +msgid "Edit telop '{0}' at Index {1}" +msgstr "字幕を編集: '{0}': Index {1}" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:143 +#, csharp-format +msgid "Add telop '{0}'" +msgstr "字幕を追加 '{0}'" + +#: lipsync\LipSync\Editor/FormObjectList.cs:45 +msgid "List of object" +msgstr "オブジェクトリスト" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:102 +msgid "Directory" +msgstr "ディレクトリ" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:103 +msgid "Specify output range" +msgstr "出力範囲を指定" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:107 +msgid "Parser String" +msgstr "ファイル名の書式" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:108 +msgid "Automatically Add Extension" +msgstr "拡張子を自動で追加" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:109 +msgid "Image Format" +msgstr "画像フォーマット" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:187 +msgid "Sample File Name" +msgstr "ファイル名のサンプル" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:197 +msgid "Error: Invalid parser string." +msgstr "エラー: 無効な書式指定です" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:63 +msgid "detail" +msgstr "詳細" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:64 +msgid "configure frame rate" +msgstr "フレームレートの設定" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:65 +msgid "Frame rate" +msgstr "フレームレート" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:68 +msgid "denominator of frame rate" +msgstr "フレームレートの分母" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:69 +msgid "numerator of frame rate" +msgstr "フレームレートの分子" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:71 +msgid "import frame rate from AVI file" +msgstr "AVIファイルからフレームレートの設定を引用します" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:169 +msgid "failed getting frame rate" +msgstr "フレームレートが取得できませんでした" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:79 +msgid "Lip Assignment" +msgstr "口の画像割当て" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:80 +msgid "Eye Assignment" +msgstr "目の画像割当て" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:81 +msgid "Eyebrow Assignment" +msgstr "眉の画像割当て" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:84 +msgid "Blend time for E_Default -> E_*" +msgstr "E_DefaultからE_*へのブレンド時間" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:85 +msgid "Blend time for E_* -> E_Default" +msgstr "E_*からE_Defaultへのブレンド時間" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:86 +msgid "Blend time for EB_Default -> EB_*" +msgstr "EB_DefaultからEB_*へのブレンド時間" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:87 +msgid "Blend time for EB_* -> EB_Default" +msgstr "EB_*からEB_Defaultへのブレンド時間" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:88 +msgid "Blend time for L_Default -> L_*" +msgstr "L_DefaultからL_*へのブレンド時間" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:89 +msgid "Blend time for L_* -> L_Default" +msgstr "L_*からL_Defaultへのブレンド時間" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:70 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:73 +msgid "Title" +msgstr "タイトル" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:71 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:72 +msgid "Tag" +msgstr "タグ" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:74 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:126 +msgid "Up" +msgstr "上" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:75 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:121 +msgid "Down" +msgstr "下" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:76 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:119 +msgid "Add" +msgstr "追加" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:79 +msgid "Select image file" +msgstr "画像を読込み" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:80 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:125 +msgid "Select transparent color" +msgstr "透過色を設定" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:84 +msgid "Character name" +msgstr "キャラクタの名前" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:86 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:122 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:851 +msgid "Change title" +msgstr "タイトルを変更" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:88 +msgid "Selected image" +msgstr "選択された画像" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:91 +msgid "Open *.rsi" +msgstr "RSIを開く" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:94 +msgid "Save as *.rsi" +msgstr "RSIで保存" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:95 +msgid "Save as XML" +msgstr "XML形式で保存" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:98 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:103 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:166 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:180 +msgid "LipSync Character Config(*.lsc)|*.lsc" +msgstr "LipSyncキャラクタ設定(*.lsc)|*.lsc" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:107 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:123 +msgid "Reset image" +msgstr "画像をリセット" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:109 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:114 +msgid "RipSync Image(*.rsi)|*.rsi" +msgstr "RipSyncキャラクタ設定(*.rsi)|*.rsi" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:181 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:915 +msgid "LipSync Character Config(content.xml)|content.xml" +msgstr "LipSyncキャラクタ設定(content.xml)|content.xml" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:551 +msgid "NOT editable" +msgstr "変更できません" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:664 +msgid "Title of image" +msgstr "画像のタイトル" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:665 +msgid "Input the title of image" +msgstr "画像のタイトルを入力してください" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:682 +msgid "This image title has been already registered" +msgstr "既に登録済みの名前です" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:852 +msgid "Input new title" +msgstr "新しいタイトルを入力してください" + +#: lipsync\LipSync\Editor/Previewer.cs:56 +msgid "Stop" +msgstr "停止" + +#: lipsync\LipSync\Editor/Previewer.cs:57 +msgid "Stretch image" +msgstr "画面に合わせる" + +#: lipsync\LipSync\Editor/Previewer.cs:58 +msgid "Specified size" +msgstr "指定サイズ" + +#: lipsync\LipSync\Editor/Property.cs:80 +msgid "Delte Delop" +msgstr "テロップを削除" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:52 +msgid "Custom" +msgstr "カスタム" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:53 +#: lipsync\LipSync\Editor/SelectCharacter.cs:57 +#: lipsync\LipSync\Editor/SelectCharacter.cs:58 +msgid "Built-in" +msgstr "ビルトイン" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:54 +msgid "Select character to generate lip-sync" +msgstr "口パク生成に使用するキャラクタを選択してください" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:59 +msgid "Character selection" +msgstr "キャラクタの選択" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:48 +msgid "Select track" +msgstr "トラックの選択" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:49 +msgid "import tempo and time-signal information" +msgstr "テンポと拍子の情報を取り込む" + +#: lipsync\LipSync\Editor/Winker.cs:62 +msgid "Wink interval (sec)" +msgstr "まばたきの間隔(秒)" + +#: lipsync\LipSync\Editor/Winker.cs:63 +msgid "Randomize" +msgstr "間隔をランダムにする" + +#: lipsync\LipSync\Editor/Winker.cs:64 +msgid "Closed Eye" +msgstr "閉じ目の画像" + +#: lipsync\LipSync\Editor/Winker.cs:65 +msgid "In-between Image" +msgstr "中割り画像" + +#: lipsync\LipSync\Editor/Winker.cs:66 +msgid "Eye-closing frames" +msgstr "閉じ目の表示フレーム数" + +#: lipsync\LipSync\Editor/Winker.cs:69 +msgid "Limit start time" +msgstr "開始時刻を指定" + +#: lipsync\LipSync\Editor/Winker.cs:70 +msgid "Limit end time" +msgstr "終了時刻を指定" + +#: lipsync\LipSync\Editor/ZOrder.cs:44 +msgid "Select target item, and push [Up] or [Down] button" +msgstr "描画順序を変更したいオブジェクトを選択し、上・下ボタンで移動させます" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:199 +msgid "Image directory already exists. Would you like to overwrite them?" +msgstr "画像セーブ用のフォルダが既に存在します。上書きしますか?" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:200 +msgid "warning" +msgstr "警告" + +#: Boare.Lib.AppUtil/VersionInfo.cs:177 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:116 +#, csharp-format +msgid "About {0}" +msgstr "{0} について" + +#: Boare.Lib.AppUtil/VersionInfo.cs:186 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:117 +msgid "Credit" +msgstr "クレジット" + +#~ msgid "FLV" +#~ msgstr "FLV" +#~ msgid "FLV Progress" +#~ msgstr "FLV出力中" +#~ msgid "Video" +#~ msgstr "ビデオ" +#~ msgid "insertion of wav file has failed" +#~ msgstr "wavファイルの埋め込みに失敗しました" +#~ msgid "Disable preview" +#~ msgstr "プレビューを非表示" +#~ msgid "Enable preview" +#~ msgstr "プレビューを表示" +#~ msgid "Edit motion curve" +#~ msgstr "変位の制御" +#~ msgid "already exists." +#~ msgstr "は既に存在します。" +#~ msgid "Add telop at Index {0}" +#~ msgstr "字幕を追加: Index {0}" +#~ msgid "Copy time-line" +#~ msgstr "タイムラインをコピー" +#~ msgid "Generate telop from VSQ" +#~ msgstr "VSQから字幕生成" +#~ msgid "Go to preview" +#~ msgstr "プレビューに移動" +#~ msgid "Input frame rate" +#~ msgstr "ビデオのフレームレートを入力してください" +#~ msgid "Interrupt" +#~ msgstr "割り込ませる" +#~ msgid "" +#~ "Image title can't be set to \"base\", \"a\", \"aa\", \"i\", \"u\", \"e\", " +#~ "\"o\", \"xo\", \"nn\"" +#~ msgstr "" +#~ "キャラクタ画像のタイトルは、base, a, aa, i, u, e, o, xo, nn以外の名前であ" +#~ "る必要があります" +#~ msgid "Object name" +#~ msgstr "オブジェクト名" +#~ msgid "" +#~ "AVI file size will exceed 2Gbyte.\n" +#~ "Do you wish to continue?" +#~ msgstr "" +#~ "このままAVIを出力するとファイルサイズが2Gbyteを超える可能性があります。\n" +#~ "出力を続けますか?" +#~ msgid "Overwrite" +#~ msgstr "上書き" +#~ msgid "Paste time-line" +#~ msgstr "タイムラインを貼付" +#~ msgid "(Non-compressed)" +#~ msgstr "(無圧縮)" +#~ msgid "select configuration item from the list box below" +#~ msgstr "下のリストボックスから設定する項目を選択します" +#~ msgid "Show preview" +#~ msgstr "プレビュー表示" +#~ msgid "Specify paste mode" +#~ msgstr "貼付けモードを指定してください" +#~ msgid "Window" +#~ msgstr "ウィンドウ" + diff --git a/trunk/LipSync/LipSync/makefile b/trunk/LipSync/LipSync/makefile new file mode 100644 index 0000000..9b55edf --- /dev/null +++ b/trunk/LipSync/LipSync/makefile @@ -0,0 +1,17 @@ +OPT= +RM=rm +CP=cp +LipSync.exe: Boare.Lib.Media.dll Boare.Lib.Vsq.dll Boare.Lib.AppUtil.dll IPlugin.dll Boare.Lib.Swf.dll bocoree.dll Properties/Resources.resources + gmcs -unsafe+ -recurse:*.cs -target:exe -out:LipSync.exe -warn:0 -define:MONO -codepage:utf8 \ + -resource:Properties/Resources.resources,LipSync.Properties.Resources.resources \ + -r:System.Windows.Forms,System.Drawing,System.Web \ + -r:Boare.Lib.Media.dll,Boare.Lib.Vsq.dll,Boare.Lib.AppUtil.dll,IPlugin.dll,Boare.Lib.Swf,bocoree.dll + +Properties/Resources.resources: Properties/Resources.resx + perl EditResx.pl Properties/Resources.resx + cd Properties && resgen Resources_.resx Resources.resources + $(RM) Properties/Resources_.resx + +clean: + $(RM) LipSync.exe Boare.Lib.Media.dll Boare.Lib.Vsq.dll Boare.Lib.AppUtil.dll IPlugin.dll Boare.Lib.Swf.dll \ + bocoree.dll Background.dll NicoComment.dll VFlip.dll diff --git a/trunk/LipSync/LipSync/readme_ja.txt b/trunk/LipSync/LipSync/readme_ja.txt new file mode 100644 index 0000000..761c0a1 --- /dev/null +++ b/trunk/LipSync/LipSync/readme_ja.txt @@ -0,0 +1,31 @@ +*͂߂* + LipSynćANvgEt[`[EfBAЂDTMi + uVOCALOID2LN^[{[JV[YvŎgpV[PX + t@Ci*.vsqj͂ApN̍쐬xc[łB + +*CXg[* + .NET Framework version 2.0ȍ~̃^CC܂͑s‹ + KvłBʓrCXg[ĂA{c[gpB + ̋ŃA\ꂪpɂȂĂ̂ŁA{ɐ؂ւꍇ + uToolv->uOptionvƑI񂾌ɏoĂ_CAÓuUser Configv^u + uLanguagevujavɕύXĉB + +*s‹̓* + Windows: + .NET Framework : http://www.microsoft.com/japan/msdn/netframework/downloads/ + Windows, Macintosh, Linux, etc.: + mono .NET : http://www.mono-project.com/ + +*ACXg[* + fBNgƍ폜ĂB + +*ӎ* + LipSync̓t[\tgłB쌠kbinaniɂ܂B܂A + LipSync͗Lpł邱ƂĔЕz܂A S̖ۏ؂łBe + ̐ӔCŎgpĂB + +*A* + J_ : http://sourceforge.jp/projects/lipsync/ + ŐVŔzzURL : http://www32.atwiki.jp/lipsync/ + Apf : http://joy.atbbs.jp/lipsync/ + Lf‚gȂꍇ̘A : kbinani@msn.com diff --git a/trunk/LipSync/LipSync/zh-CN.po b/trunk/LipSync/LipSync/zh-CN.po new file mode 100644 index 0000000..124f970 --- /dev/null +++ b/trunk/LipSync/LipSync/zh-CN.po @@ -0,0 +1,1270 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-03-09 00:18+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: kbinani \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-Country: CHINA\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Basepath: ..\\..\\\n" +"X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: lipsync\\LipSync\\Editor\n" +"X-Poedit-SearchPath-1: lipsync\\LipSync\\Common\n" +"X-Poedit-SearchPath-2: Boare.Lib.AppUtil\n" + +#: lipsync\LipSync\Editor/AviOutput.cs:59 +msgid "Cancel" +msgstr "关闭" + +#: lipsync\LipSync\Editor/AviOutput.cs:60 +msgid "Save" +msgstr "保存" + +#: lipsync\LipSync\Editor/AviOutput.cs:61 +msgid "File Name" +msgstr "文件名" + +#: lipsync\LipSync\Editor/AviOutput.cs:63 +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Audio" +msgstr "音频" + +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Set the path of ffmpeg to enable this option" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:70 +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "FLV and MP4" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "Set the path of mencoder and ffmpeg to enable this option" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:76 +msgid "Convert to FLV" +msgstr "转为flv" + +#: lipsync\LipSync\Editor/AviOutput.cs:77 +msgid "Convert to MP4" +msgstr "转为mp4" + +#: lipsync\LipSync\Editor/AviOutput.cs:78 +msgid "Merge WAVE to AVI" +msgstr "合并WAVE和AVI" + +#: lipsync\LipSync\Editor/AviOutput.cs:79 +msgid "Delete Intermediate File" +msgstr "删除临时文件" + +#: lipsync\LipSync\Editor/AviOutput.cs:80 +msgid "Video Compression" +msgstr "视频压缩" + +#: lipsync\LipSync\Editor/AviOutput.cs:81 +msgid "Specify Output Range" +msgstr "指定输出范围" + +#: lipsync\LipSync\Editor/AviOutput.cs:82 +msgid "Start" +msgstr "开始" + +#: lipsync\LipSync\Editor/AviOutput.cs:83 +msgid "End" +msgstr "结束" + +#: lipsync\LipSync\Editor/AviOutput.cs:84 +msgid "Add Alpha" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:118 +#, csharp-format +msgid "Directory {0} does not exist." +msgstr "目录 {0} 不存在。" + +#: lipsync\LipSync\Editor/AviOutput.cs:119 +#: lipsync\LipSync\Editor/AviOutput.cs:140 +msgid "Error" +msgstr "错误" + +#: lipsync\LipSync\Editor/AviOutput.cs:127 +#, csharp-format +msgid "" +"{0} already exists.\n" +"Do you want to replace it?" +msgstr "" +"{0} 已经存在。\n" +"是否替换?" + +#: lipsync\LipSync\Editor/AviOutput.cs:139 +msgid "Invalid value has been entered" +msgstr "无效数值" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "Avi file(*.avi)|*.avi" +msgstr "AVI 文件 (*.avi)|*.avi" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "All Files(*.*)|*.*" +msgstr "所有的文件夹 (*.*)|*.*" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:88 +msgid "Edit Motion Curve" +msgstr "编辑移动曲线" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:89 +msgid "Close" +msgstr "关闭" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:90 +msgid "File" +msgstr "文件" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:91 +msgid "Redo" +msgstr "重做" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:92 +msgid "Undo" +msgstr "撤销" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:93 +msgid "Edit" +msgstr "编辑" + +#: lipsync\LipSync\Editor/EditEntry.cs:58 +msgid "ON time (sec)" +msgstr "ON 时间 (秒 )" + +#: lipsync\LipSync\Editor/EditEntry.cs:59 +msgid "OFF time (sec)" +msgstr "OFF 时间 (秒 )" + +#: lipsync\LipSync\Editor/EditEntry.cs:61 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:101 +msgid "OK" +msgstr "确定" + +#: lipsync\LipSync\Editor/EditEntry.cs:62 +msgid "Use this value" +msgstr "使用这个数值" + +#: lipsync\LipSync\Editor/EditEntry.cs:63 +msgid "Expandable range of this entry" +msgstr "可变更数值的范围" + +#: lipsync\LipSync\Editor/EditEntry.cs:64 +msgid "Numeric entry" +msgstr "数值输入" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:103 +msgid "Language" +msgstr "语言" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:104 +#: lipsync\LipSync\Editor/Form1Util.cs:130 +msgid "Option" +msgstr "选项" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:106 +msgid "User Config" +msgstr "用户设定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:107 +msgid "Appearance" +msgstr "表情" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:108 +msgid "lip-sync Option" +msgstr "嘴形同步选项" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:109 +msgid "System" +msgstr "系统" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:111 +msgid "Title of timeline" +msgstr "时间轴标题" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:112 +msgid "VSQ Entry" +msgstr "VSQ 项目" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:113 +msgid "Plugin Entry" +msgstr "插件项目" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:114 +msgid "Another Entry" +msgstr "其他项目" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:115 +msgid "Entry height (pixel)" +msgstr "项目高度 (象素)" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:116 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:117 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:118 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:119 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:129 +msgid "Change" +msgstr "变更" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:120 +msgid "Check phonetic symbol to configure detailed mouth shape control" +msgstr "检验发音符号,详细设定嘴形参数" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:121 +msgid "Close mouth before pronunciation" +msgstr "在发音之前闭上嘴" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:122 +msgid "\"i\" shaped mouth before pronunciation" +msgstr "在发音之前生成“i”的嘴形" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:123 +msgid "\"u\" shaped mouth before pronunciation" +msgstr "在发音之前生成“u”的嘴形" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:124 +msgid "Color" +msgstr "配色" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:125 +msgid "Design" +msgstr "设定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:126 +msgid "Path of ffmpeg" +msgstr "ffmpeg位置" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:127 +msgid "Path of mencoder" +msgstr "mencoder位置" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:128 +msgid "Font" +msgstr "字型" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:130 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:135 +msgid "Another settings" +msgstr "其他设定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:131 +msgid "Close mouth when same vowels repeated" +msgstr "同一元音连续的时候,闭上嘴" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:132 +msgid "Encoder/Decoder" +msgstr "编码器 /dekoda" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:133 +msgid "Generate character automaticaly when importing vsq" +msgstr "VSQ输入时自动生成字符" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:134 +msgid "Threshold silence length(sec)" +msgstr "判定是连续音时不发音的时间 (秒 )" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:136 +msgid "Use preview-enabled dialog in character selection" +msgstr "选择字符时使用可以预览的对话" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:137 +msgid "Reload language configurations" +msgstr "刷新语言设定文件夹" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:138 +msgid "Operation" +msgstr "操作" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:139 +msgid "mouse wheel rate" +msgstr "鼠标滑轮速度" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:140 +msgid "Fix cursor to center in Sync mode" +msgstr "" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:281 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:305 +msgid "Executable file(*.exe)|*.exe" +msgstr "可执行文件(*.exe)|*.exe" + +#: lipsync\LipSync\Editor/Form1.cs:604 +#: lipsync\LipSync\Editor/Form1.cs:2011 +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Video size configuration" +msgstr "设定视频图像大小" + +#: lipsync\LipSync\Editor/Form1.cs:612 +msgid "Read from VSQ file" +msgstr "从 VSQ 文件夹读取" + +#: lipsync\LipSync\Editor/Form1.cs:616 +msgid "Edit character" +msgstr "编辑角色" + +#: lipsync\LipSync\Editor/Form1.cs:619 +#: lipsync\LipSync\Editor/Form1.cs:652 +#: lipsync\LipSync\Editor/Form1.cs:668 +msgid "Preview image" +msgstr "图像预览" + +#: lipsync\LipSync\Editor/Form1.cs:620 +#: lipsync\LipSync\Editor/Form1.cs:677 +#: lipsync\LipSync\Editor/Form1.cs:737 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:964 +msgid "Image placement" +msgstr "设定图像位置" + +#: lipsync\LipSync\Editor/Form1.cs:621 +#: lipsync\LipSync\Editor/Form1.cs:680 +#: lipsync\LipSync\Editor/Form1.cs:740 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Scale setting" +msgstr "设定大小" + +#: lipsync\LipSync\Editor/Form1.cs:623 +msgid "Generate wink" +msgstr "眨眼的生成" + +#: lipsync\LipSync\Editor/Form1.cs:627 +#: lipsync\LipSync\Editor/Form1.cs:791 +msgid "Delete" +msgstr "删除" + +#: lipsync\LipSync\Editor/Form1.cs:630 +msgid "Add Telop" +msgstr "添加字幕" + +#: lipsync\LipSync\Editor/Form1.cs:633 +msgid "Add track" +msgstr "添加轨道" + +#: lipsync\LipSync\Editor/Form1.cs:643 +msgid "Generate Lipsync from this track" +msgstr "从这个轨道生成嘴形" + +#: lipsync\LipSync\Editor/Form1.cs:649 +#: lipsync\LipSync\Editor/Form1.cs:660 +#: lipsync\LipSync\Editor/Form1.cs:691 +msgid "Note ON from here" +msgstr "从这里输入音符" + +#: lipsync\LipSync\Editor/Form1.cs:664 +msgid "Set image" +msgstr "指定图像" + +#: lipsync\LipSync\Editor/Form1.cs:671 +msgid "Change image" +msgstr "变更图像" + +#: lipsync\LipSync\Editor/Form1.cs:675 +#: lipsync\LipSync\Editor/Form1.cs:735 +msgid "Image" +msgstr "图像" + +#: lipsync\LipSync\Editor/Form1.cs:702 +#: lipsync\LipSync\Editor/Form1.cs:775 +msgid "Paste" +msgstr "粘贴" + +#: lipsync\LipSync\Editor/Form1.cs:716 +msgid "Note OFF" +msgstr "撤销音符" + +#: lipsync\LipSync\Editor/Form1.cs:718 +msgid "Image Preview" +msgstr "显示预览" + +#: lipsync\LipSync\Editor/Form1.cs:720 +msgid "Numeric Entry" +msgstr "数值输入" + +#: lipsync\LipSync\Editor/Form1.cs:722 +msgid "Expand" +msgstr "放大" + +#: lipsync\LipSync\Editor/Form1.cs:730 +msgid "Set Image" +msgstr "指定图像" + +#: lipsync\LipSync\Editor/Form1.cs:732 +msgid "Preview Image" +msgstr "图像预览" + +#: lipsync\LipSync\Editor/Form1.cs:733 +msgid "Change Image" +msgstr "变更图像" + +#: lipsync\LipSync\Editor/Form1.cs:749 +msgid "Plugin config. of this entry" +msgstr "此项目的插件设定" + +#: lipsync\LipSync\Editor/Form1.cs:755 +#: lipsync\LipSync\Editor/Form1.cs:767 +msgid "Copy" +msgstr "复制" + +#: lipsync\LipSync\Editor/Form1.cs:756 +msgid "Cut" +msgstr "剪切" + +#: lipsync\LipSync\Editor/Form1.cs:757 +msgid "Split Entry" +msgstr "分离入口" + +#: lipsync\LipSync\Editor/Form1.cs:765 +msgid "Timeline" +msgstr "时间轴" + +#: lipsync\LipSync\Editor/Form1.cs:771 +msgid "Copy On/Off inverted" +msgstr "ON/OFF 翻转复制" + +#: lipsync\LipSync\Editor/Form1.cs:779 +msgid "Import from TEXT" +msgstr "从文本读取" + +#: lipsync\LipSync\Editor/Form1.cs:780 +msgid "Export to TEXT" +msgstr "输出文本" + +#: lipsync\LipSync\Editor/Form1.cs:793 +msgid "Delete entries" +msgstr "删除轨道上的内容" + +#: lipsync\LipSync\Editor/Form1.cs:797 +msgid "Shift this time-line" +msgstr "移动时间轴" + +#: lipsync\LipSync\Editor/Form1.cs:1367 +#: lipsync\LipSync\Editor/Form1.cs:1407 +#: lipsync\LipSync\Editor/Form1.cs:1603 +msgid "VSQ Tracks" +msgstr "VSQ 轨道" + +#: lipsync\LipSync\Editor/Form1.cs:1378 +msgid "Character" +msgstr "角色" + +#: lipsync\LipSync\Editor/Form1.cs:1385 +msgid "Telop" +msgstr "字幕" + +#: lipsync\LipSync\Editor/Form1.cs:1392 +msgid "Another Images" +msgstr "其他图像" + +#: lipsync\LipSync\Editor/Form1.cs:1399 +#: lipsync\LipSync\Editor/Form1.cs:1577 +msgid "Plugin" +msgstr "插件" + +#: lipsync\LipSync\Editor/Form1.cs:1540 +msgid "LipSync" +msgstr "LipSync" + +#: lipsync\LipSync\Editor/Form1.cs:1605 +#: lipsync\LipSync\Editor/Form1.cs:2394 +msgid "Another images" +msgstr "其他图像" + +#: lipsync\LipSync\Editor/Form1.cs:1952 +msgid "" +"Initialization of video compression failed.\n" +"This video codec may require image width in multiples of certain number." +msgstr "" +"视频压缩的初始化失败\n" +"此解码器可能需要特定比例的图像尺寸" + +#: lipsync\LipSync\Editor/Form1.cs:1963 +msgid "AVI Progress" +msgstr "AVI 输出中" + +#: lipsync\LipSync\Editor/Form1.cs:2011 +msgid "Input video length in second" +msgstr "输入影像的长度(秒)" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Shift all time-tables" +msgstr "整体移动时间轴" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Input shift time in second (you can enter minus value)" +msgstr "输入移动数量 (可以输入负值 )" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +#: lipsync\LipSync\Editor/Form1.cs:2689 +msgid "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" +msgstr "这个操作会覆盖所有现存轨道。并且无法撤销。继续吗?" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +msgid "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" +msgstr "(右击「VSQ 轨道」选择「从 VSQ 文件夹读取」添加一个新轨道)" + +#: lipsync\LipSync\Editor/Form1.cs:2300 +#: lipsync\LipSync\Editor/Form1.cs:2690 +#: lipsync\LipSync\Editor/Form1Util.cs:249 +#: lipsync\LipSync\Editor/Form1Util.cs:283 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "Confirmation" +msgstr "确认" + +#: lipsync\LipSync\Editor/Form1.cs:2313 +#: lipsync\LipSync\Editor/Form1Util.cs:150 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:931 +msgid "VOCALOID2 Sequence File(*.vsq)|*.vsq" +msgstr "VOCALOID2连续文件(*.vsq)|*.vsq" + +#: lipsync\LipSync\Editor/Form1.cs:2314 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:932 +msgid "UTAU Script File(*.ust)|*.ust" +msgstr "" + +#: lipsync\LipSync\Editor/Form1.cs:2436 +#: lipsync\LipSync\Editor/Form1.cs:2569 +msgid "Specify the index of target character" +msgstr "" + +#: lipsync\LipSync\Editor/Form1.cs:2707 +#: lipsync\LipSync\Editor/Form1.cs:3134 +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1907 +msgid "Play" +msgstr "播放" + +#: lipsync\LipSync\Editor/Form1.cs:2711 +msgid "File not found" +msgstr "文件未找到" + +#: lipsync\LipSync\Editor/Form1.cs:2730 +#: lipsync\LipSync\Editor/Form1.cs:2758 +#: lipsync\LipSync\Editor/Form1.cs:2770 +msgid "Extension must be *.lse" +msgstr "*.无法处理lse以外的文件格式" + +#: lipsync\LipSync\Editor/Form1.cs:2895 +msgid "Expand All" +msgstr "全部展开" + +#: lipsync\LipSync\Editor/Form1.cs:2896 +msgid "Fold All" +msgstr "全部合拢" + +#: lipsync\LipSync\Editor/Form1.cs:3138 +#, fuzzy +msgid "Audio File(*.mp3;*.wav)|*.mp3;*.wav" +msgstr "声音文件(*.mp3,*.wav)|*.mp3;*.wav" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "Go to specified frame" +msgstr "移动到指定帧" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "please input frame index" +msgstr "请输入时间轴索引" + +#: lipsync\LipSync\Editor/Form1.cs:3166 +msgid "invalid frame index" +msgstr "这个时间轴索引不存在" + +#: lipsync\LipSync\Editor/Form1.cs:3702 +msgid "Series Image Progress" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:104 +msgid "Open" +msgstr "打开" + +#: lipsync\LipSync\Editor/Form1Util.cs:106 +msgid "Save As" +msgstr "另存为" + +#: lipsync\LipSync\Editor/Form1Util.cs:107 +msgid "Import" +msgstr "导入" + +#: lipsync\LipSync\Editor/Form1Util.cs:108 +msgid "from RipSync data" +msgstr "RipSync 数据" + +#: lipsync\LipSync\Editor/Form1Util.cs:109 +msgid "Open VSQ/UST file" +msgstr "打开 VSQ/UST" + +#: lipsync\LipSync\Editor/Form1Util.cs:110 +msgid "Exit" +msgstr "退出" + +#: lipsync\LipSync\Editor/Form1Util.cs:111 +msgid "Script for VOCALOMARK" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:115 +msgid "Help" +msgstr "帮助" + +#: lipsync\LipSync\Editor/Form1Util.cs:116 +msgid "Plugin Information" +msgstr "插件信息" + +#: lipsync\LipSync\Editor/Form1Util.cs:117 +msgid "About LipSync" +msgstr "关于 LipSync" + +#: lipsync\LipSync\Editor/Form1Util.cs:118 +msgid "Debug" +msgstr "故障排除" + +#: lipsync\LipSync\Editor/Form1Util.cs:119 +msgid "Edit Character" +msgstr "编辑角色" + +#: lipsync\LipSync\Editor/Form1Util.cs:120 +msgid "Flip Images Horizontaly" +msgstr "左右翻转图像" + +#: lipsync\LipSync\Editor/Form1Util.cs:124 +msgid "Video Size" +msgstr "图像大小" + +#: lipsync\LipSync\Editor/Form1Util.cs:125 +msgid "Frame Rate" +msgstr "帧速率" + +#: lipsync\LipSync\Editor/Form1Util.cs:126 +msgid "Z order" +msgstr "z轴顺序" + +#: lipsync\LipSync\Editor/Form1Util.cs:127 +msgid "Video Length" +msgstr "视频长度" + +#: lipsync\LipSync\Editor/Form1Util.cs:128 +msgid "Shift All Time-tables" +msgstr "整体移动时间轴" + +#: lipsync\LipSync\Editor/Form1Util.cs:129 +msgid "Tool" +msgstr "工具" + +#: lipsync\LipSync\Editor/Form1Util.cs:131 +msgid "Plugin Config" +msgstr "插件设定" + +#: lipsync\LipSync\Editor/Form1Util.cs:132 +msgid "Add Empty Character" +msgstr "添加空白角色" + +#: lipsync\LipSync\Editor/Form1Util.cs:134 +msgid "Generate Avi" +msgstr "输出AVI" + +#: lipsync\LipSync\Editor/Form1Util.cs:135 +msgid "Chose Sound File" +msgstr "同时播放的音乐" + +#: lipsync\LipSync\Editor/Form1Util.cs:136 +msgid "Go to Specified Frame" +msgstr "移动到指定帧" + +#: lipsync\LipSync\Editor/Form1Util.cs:137 +msgid "Stop Writing Avi" +msgstr "中断输出avi" + +#: lipsync\LipSync\Editor/Form1Util.cs:138 +msgid "Background Color" +msgstr "背景颜色" + +#: lipsync\LipSync\Editor/Form1Util.cs:140 +msgid "Generate Raw Avi" +msgstr "输出无压缩的 AVI" + +#: lipsync\LipSync\Editor/Form1Util.cs:141 +msgid "Export" +msgstr "导出" + +#: lipsync\LipSync\Editor/Form1Util.cs:142 +msgid "Script for H@TWUNEBENCH" +msgstr "H@TWUNEBENCH脚本" + +#: lipsync\LipSync\Editor/Form1Util.cs:144 +msgid "Show Object List" +msgstr "显示对象列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:146 +msgid "Hide Object List" +msgstr "关闭对象列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:148 +msgid "Bug Report" +msgstr "错误报告" + +#: lipsync\LipSync\Editor/Form1Util.cs:158 +msgid "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" +msgstr "图片文件(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" + +#: lipsync\LipSync\Editor/Form1Util.cs:159 +msgid "Avi File(*.avi)|*.avi" +msgstr "AVI 文件 (*.avi)|*.avi" + +#: lipsync\LipSync\Editor/Form1Util.cs:167 +msgid "LipSync Data File(*.lse)|*.lse" +msgstr "LipSync 数据设定 (*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:175 +msgid "LipSync Data file(*.lse)|*.lse" +msgstr "LipSync 数据设定 (*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:183 +msgid "Real Time \"lipsync\"" +msgstr "即时口型同步" + +#: lipsync\LipSync\Editor/Form1Util.cs:184 +msgid "End Repeat Here" +msgstr "指定重播结束位置" + +#: lipsync\LipSync\Editor/Form1Util.cs:185 +msgid "Start Repeat Here" +msgstr "指定重播开始位置" + +#: lipsync\LipSync\Editor/Form1Util.cs:186 +msgid "Reset Repeat region" +msgstr "重置重播范围" + +#: lipsync\LipSync\Editor/Form1Util.cs:189 +msgid "View" +msgstr "视图" + +#: lipsync\LipSync\Editor/Form1Util.cs:190 +msgid "Zoom" +msgstr "扩大" + +#: lipsync\LipSync\Editor/Form1Util.cs:191 +msgid "Mooz" +msgstr "缩小" + +#: lipsync\LipSync\Editor/Form1Util.cs:192 +msgid "Set Default Scale" +msgstr "默认大小" + +#: lipsync\LipSync\Editor/Form1Util.cs:193 +#: lipsync\LipSync\Editor/Form1Util.cs:197 +msgid "Move to Top" +msgstr "回到开头" + +#: lipsync\LipSync\Editor/Form1Util.cs:194 +#: lipsync\LipSync\Editor/Form1Util.cs:196 +msgid "Move to End" +msgstr "转到结尾" + +#: lipsync\LipSync\Editor/Form1Util.cs:195 +msgid "Repeat play" +msgstr "重复播放" + +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1850 +msgid "Pause" +msgstr "暂停" + +#: lipsync\LipSync\Editor/Form1Util.cs:200 +msgid "Show VSQ Tracks Allways" +msgstr "总是显示 VSQ 轨道" + +#: lipsync\LipSync\Editor/Form1Util.cs:201 +msgid "Show Bars" +msgstr "显示格栅" + +#: lipsync\LipSync\Editor/Form1Util.cs:202 +msgid "Preview" +msgstr "预览" + +#: lipsync\LipSync\Editor/Form1Util.cs:204 +msgid "Sync with Time-table" +msgstr "与时间轴同步" + +#: lipsync\LipSync\Editor/Form1Util.cs:206 +#: lipsync\LipSync\Editor/Form1Util.cs:467 +msgid "Enable Preview" +msgstr "显示预览" + +#: lipsync\LipSync\Editor/Form1Util.cs:208 +#: lipsync\LipSync\Editor/Form1Util.cs:461 +msgid "Disable Preview" +msgstr "关闭预览" + +#: lipsync\LipSync\Editor/Form1Util.cs:210 +msgid "Separate Preview Window" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:213 +msgid "Quantize" +msgstr "量化" + +#: lipsync\LipSync\Editor/Form1Util.cs:214 +msgid "Off" +msgstr "关掉" + +#: lipsync\LipSync\Editor/Form1Util.cs:215 +msgid "Triplet" +msgstr "三连音" + +#: lipsync\LipSync\Editor/Form1Util.cs:217 +msgid "List of Object" +msgstr "对象列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:218 +msgid "Property" +msgstr "对象特性" + +#: lipsync\LipSync\Editor/Form1Util.cs:230 +msgid "Series Image" +msgstr "连续的图像文件" + +#: lipsync\LipSync\Editor/Form1Util.cs:248 +#: lipsync\LipSync\Editor/Form1Util.cs:282 +msgid "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" +msgstr "覆盖现有拍子和拍号,并且无法撤销,继续吗?" + +#: lipsync\LipSync\Editor/Form1Util.cs:411 +msgid "Hide object list" +msgstr "关闭对象列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:417 +msgid "Show object list" +msgstr "显示对象列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:442 +msgid "(no name)" +msgstr "无标题" + +#: lipsync\LipSync\Editor/Form1Util.cs:498 +msgid "Failed file saving" +msgstr "文件保存失败 " + +#: lipsync\LipSync\Editor/Form1Util.cs:569 +msgid "Failed file reading" +msgstr "文件读取失败" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Width" +msgstr "宽度" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Height" +msgstr "高度" + +#: lipsync\LipSync\Editor/Form1Util.cs:1343 +msgid " has been changed. Do you wish to save changes to file?" +msgstr "文件将被更改,是否保存变更?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1345 +msgid "Do you wish to save changes to file?" +msgstr "是否保存变更?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1986 +#, fuzzy +msgid "Progress" +msgstr "AVI 输出中" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:167 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:229 +msgid "Text file(*.txt)|*.txt" +msgstr "txt文件(*.txt)|*.txt" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" +msgstr "请输入放大倍数 (输入负的数值,就左右翻转 )" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +msgid "" +"...clearing entries of selected time-table.\n" +"Would you like to continue?" +msgstr "" +"清除选择的时间表条目。\n" +" 继续吗?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +msgid "" +"...deleting selected character.\n" +"Would you like to continue?" +msgstr "" +"删除选择的角色。\n" +" 继续吗?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "" +"...deleting selected track.\n" +"Would you like to continue?" +msgstr "" +"将要删除所选轨道。\n" +" 是否继续?" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:75 +#: lipsync\LipSync\Editor/FormCommandHistory.cs:92 +msgid "Command History" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:131 +#, csharp-format +msgid "Delete entry of 'Another Image' at Index {0}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:133 +#, csharp-format +msgid "Add entry of 'Another Image' at Index {0}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:135 +#, csharp-format +msgid "Edit entry of 'Another Image' at Track {0}, Index {1}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:139 +#, csharp-format +msgid "Delete telop '{0}'" +msgstr "删除字幕 '{0}'" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:141 +#, csharp-format +msgid "Edit telop '{0}' at Index {1}" +msgstr "编辑字幕: '{0}': Index {1}" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:143 +#, csharp-format +msgid "Add telop '{0}'" +msgstr "添加字幕 '{0}'" + +#: lipsync\LipSync\Editor/FormObjectList.cs:45 +msgid "List of object" +msgstr "对象列表" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:102 +msgid "Directory" +msgstr "目录" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:103 +msgid "Specify output range" +msgstr "指定输出范围" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:107 +msgid "Parser String" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:108 +msgid "Automatically Add Extension" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:109 +msgid "Image Format" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:187 +msgid "Sample File Name" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:197 +msgid "Error: Invalid parser string." +msgstr "" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:63 +msgid "detail" +msgstr "详情" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:64 +msgid "configure frame rate" +msgstr "FPS设定" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:65 +msgid "Frame rate" +msgstr "帧速率" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:68 +msgid "denominator of frame rate" +msgstr "FPS分母" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:69 +msgid "numerator of frame rate" +msgstr "FPS分子" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:71 +msgid "import frame rate from AVI file" +msgstr "使用AVI自身的FPS(帧率)" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:169 +msgid "failed getting frame rate" +msgstr "无法取得FPS" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:79 +msgid "Lip Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:80 +msgid "Eye Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:81 +msgid "Eyebrow Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:84 +msgid "Blend time for E_Default -> E_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:85 +msgid "Blend time for E_* -> E_Default" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:86 +msgid "Blend time for EB_Default -> EB_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:87 +msgid "Blend time for EB_* -> EB_Default" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:88 +msgid "Blend time for L_Default -> L_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:89 +msgid "Blend time for L_* -> L_Default" +msgstr "" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:70 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:73 +msgid "Title" +msgstr "标题" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:71 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:72 +msgid "Tag" +msgstr "标签" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:74 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:126 +msgid "Up" +msgstr "上移" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:75 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:121 +msgid "Down" +msgstr "下移" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:76 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:119 +msgid "Add" +msgstr "添加" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:79 +msgid "Select image file" +msgstr "选择图片文件夹" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:80 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:125 +msgid "Select transparent color" +msgstr "设定透过的颜色" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:84 +msgid "Character name" +msgstr "角色名" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:86 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:122 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:851 +msgid "Change title" +msgstr "变更标题" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:88 +msgid "Selected image" +msgstr "被选择的图像" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:91 +msgid "Open *.rsi" +msgstr "打开 RSI" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:94 +msgid "Save as *.rsi" +msgstr "保存为XML格式" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:95 +msgid "Save as XML" +msgstr "保存为XML格式" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:98 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:103 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:166 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:180 +msgid "LipSync Character Config(*.lsc)|*.lsc" +msgstr "LipSync 角色设定 (*.lsc)|*.lsc" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:107 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:123 +msgid "Reset image" +msgstr "重置图像" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:109 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:114 +msgid "RipSync Image(*.rsi)|*.rsi" +msgstr "RipSync 角色设定 (*.rsi)|*.rsi" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:181 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:915 +msgid "LipSync Character Config(content.xml)|content.xml" +msgstr "LipSync 角色设定 (content.xml)|content.xml" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:551 +msgid "NOT editable" +msgstr "无法更改" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:664 +msgid "Title of image" +msgstr "图像的标题" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:665 +msgid "Input the title of image" +msgstr "请输入图像的标题" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:682 +msgid "This image title has been already registered" +msgstr "已经被登记的名字" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:852 +msgid "Input new title" +msgstr "请输入新的标题" + +#: lipsync\LipSync\Editor/Previewer.cs:56 +msgid "Stop" +msgstr "停止" + +#: lipsync\LipSync\Editor/Previewer.cs:57 +msgid "Stretch image" +msgstr "伸展图像" + +#: lipsync\LipSync\Editor/Previewer.cs:58 +msgid "Specified size" +msgstr "指定尺寸" + +#: lipsync\LipSync\Editor/Property.cs:80 +msgid "Delte Delop" +msgstr "删除字幕" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:52 +msgid "Custom" +msgstr "自定义" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:53 +#: lipsync\LipSync\Editor/SelectCharacter.cs:57 +#: lipsync\LipSync\Editor/SelectCharacter.cs:58 +msgid "Built-in" +msgstr "内建" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:54 +msgid "Select character to generate lip-sync" +msgstr "请选择要生成嘴形的角色" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:59 +msgid "Character selection" +msgstr "角色的选择" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:48 +msgid "Select track" +msgstr "选择轨道" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:49 +msgid "import tempo and time-signal information" +msgstr "输入拍子和拍号" + +#: lipsync\LipSync\Editor/Winker.cs:62 +msgid "Wink interval (sec)" +msgstr "眨眼间隔(秒)" + +#: lipsync\LipSync\Editor/Winker.cs:63 +msgid "Randomize" +msgstr "随机间隔" + +#: lipsync\LipSync\Editor/Winker.cs:64 +msgid "Closed Eye" +msgstr "闭眼的图像" + +#: lipsync\LipSync\Editor/Winker.cs:65 +msgid "In-between Image" +msgstr "伴随的图像" + +#: lipsync\LipSync\Editor/Winker.cs:66 +msgid "Eye-closing frames" +msgstr "闭眼的图像" + +#: lipsync\LipSync\Editor/Winker.cs:69 +msgid "Limit start time" +msgstr "指定开始时间" + +#: lipsync\LipSync\Editor/Winker.cs:70 +msgid "Limit end time" +msgstr "指定结束时间" + +#: lipsync\LipSync\Editor/ZOrder.cs:44 +msgid "Select target item, and push [Up] or [Down] button" +msgstr "选择目标图像,点击向上移或向下移" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:199 +msgid "Image directory already exists. Would you like to overwrite them?" +msgstr "图像已存在,是否覆盖?" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:200 +msgid "warning" +msgstr "警告" + +#: Boare.Lib.AppUtil/VersionInfo.cs:177 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:116 +#, csharp-format +msgid "About {0}" +msgstr "" + +#: Boare.Lib.AppUtil/VersionInfo.cs:186 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:117 +#, fuzzy +msgid "Credit" +msgstr "制作群" + +#~ msgid "Video" +#~ msgstr "视频" +#~ msgid "insertion of wav file has failed" +#~ msgstr "wav文件夹插入失败" +#~ msgid "FLV Progress" +#~ msgstr "正在输出FLV" +#~ msgid "Disable preview" +#~ msgstr "关闭预览" +#~ msgid "Enable preview" +#~ msgstr "显示预览" +#~ msgid "Edit motion curve" +#~ msgstr "编辑移动曲线" +#~ msgid "already exists." +#~ msgstr "已经存在" +#~ msgid "Initialization of video compression failed" +#~ msgstr "" +#~ "视频压缩的初始化失败 \n" +#~ " 此解码器可能需要特定比例的图像尺寸" +#~ msgid "Specify paste mode" +#~ msgstr "请指定粘贴模式" +#~ msgid "Interrupt" +#~ msgstr "中断" +#~ msgid "Overwrite" +#~ msgstr "覆盖" + diff --git a/trunk/LipSync/LipSync/zh-TW.po b/trunk/LipSync/LipSync/zh-TW.po new file mode 100644 index 0000000..c161a34 --- /dev/null +++ b/trunk/LipSync/LipSync/zh-TW.po @@ -0,0 +1,1268 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-03-09 00:19+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: kbinani \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Chinese\n" +"X-Poedit-Country: TAIWAN\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-Basepath: ..\\..\\\n" +"X-Poedit-KeywordsList: _\n" +"X-Poedit-SearchPath-0: lipsync\\LipSync\\Editor\n" +"X-Poedit-SearchPath-1: lipsync\\LipSync\\Common\n" +"X-Poedit-SearchPath-2: Boare.Lib.AppUtil\n" + +#: lipsync\LipSync\Editor/AviOutput.cs:59 +msgid "Cancel" +msgstr "關閉" + +#: lipsync\LipSync\Editor/AviOutput.cs:60 +msgid "Save" +msgstr "保存" + +#: lipsync\LipSync\Editor/AviOutput.cs:61 +msgid "File Name" +msgstr "檔案名" + +#: lipsync\LipSync\Editor/AviOutput.cs:63 +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Audio" +msgstr "音頻" + +#: lipsync\LipSync\Editor/AviOutput.cs:66 +msgid "Set the path of ffmpeg to enable this option" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:70 +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "FLV and MP4" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:73 +msgid "Set the path of mencoder and ffmpeg to enable this option" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:76 +msgid "Convert to FLV" +msgstr "轉爲flv" + +#: lipsync\LipSync\Editor/AviOutput.cs:77 +msgid "Convert to MP4" +msgstr "轉爲mp4" + +#: lipsync\LipSync\Editor/AviOutput.cs:78 +msgid "Merge WAVE to AVI" +msgstr "合併WAVE和AVI" + +#: lipsync\LipSync\Editor/AviOutput.cs:79 +msgid "Delete Intermediate File" +msgstr "刪除暫存檔案" + +#: lipsync\LipSync\Editor/AviOutput.cs:80 +msgid "Video Compression" +msgstr "視頻壓縮" + +#: lipsync\LipSync\Editor/AviOutput.cs:81 +msgid "Specify Output Range" +msgstr "指定輸出範圍" + +#: lipsync\LipSync\Editor/AviOutput.cs:82 +msgid "Start" +msgstr "開始" + +#: lipsync\LipSync\Editor/AviOutput.cs:83 +msgid "End" +msgstr "結束" + +#: lipsync\LipSync\Editor/AviOutput.cs:84 +msgid "Add Alpha" +msgstr "" + +#: lipsync\LipSync\Editor/AviOutput.cs:118 +#, csharp-format +msgid "Directory {0} does not exist." +msgstr "目錄 {0} 不存在。" + +#: lipsync\LipSync\Editor/AviOutput.cs:119 +#: lipsync\LipSync\Editor/AviOutput.cs:140 +msgid "Error" +msgstr "錯誤" + +#: lipsync\LipSync\Editor/AviOutput.cs:127 +#, csharp-format +msgid "" +"{0} already exists.\n" +"Do you want to replace it?" +msgstr "" +"{0} 已經存在。\n" +"是否替換?" + +#: lipsync\LipSync\Editor/AviOutput.cs:139 +msgid "Invalid value has been entered" +msgstr "無效數值" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "Avi file(*.avi)|*.avi" +msgstr "AVI 文件 (*.avi)|*.avi" + +#: lipsync\LipSync\Editor/AviOutput.cs:166 +msgid "All Files(*.*)|*.*" +msgstr "所有的文件夾 (*.*)|*.*" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:88 +msgid "Edit Motion Curve" +msgstr "編輯移動曲線" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:89 +msgid "Close" +msgstr "關閉" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:90 +msgid "File" +msgstr "文件" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:91 +msgid "Redo" +msgstr "重做" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:92 +msgid "Undo" +msgstr "撤銷" + +#: lipsync\LipSync\Editor/DisplacementControl.cs:93 +msgid "Edit" +msgstr "編輯" + +#: lipsync\LipSync\Editor/EditEntry.cs:58 +msgid "ON time (sec)" +msgstr "ON 時間 (秒 )" + +#: lipsync\LipSync\Editor/EditEntry.cs:59 +msgid "OFF time (sec)" +msgstr "OFF 時間 (秒 )" + +#: lipsync\LipSync\Editor/EditEntry.cs:61 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:101 +msgid "OK" +msgstr "確定" + +#: lipsync\LipSync\Editor/EditEntry.cs:62 +msgid "Use this value" +msgstr "使用這個數值" + +#: lipsync\LipSync\Editor/EditEntry.cs:63 +msgid "Expandable range of this entry" +msgstr "可變更數值的範圍" + +#: lipsync\LipSync\Editor/EditEntry.cs:64 +msgid "Numeric entry" +msgstr "數值輸入" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:103 +msgid "Language" +msgstr "語言" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:104 +#: lipsync\LipSync\Editor/Form1Util.cs:130 +msgid "Option" +msgstr "選項" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:106 +msgid "User Config" +msgstr "用戶設定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:107 +msgid "Appearance" +msgstr "表情" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:108 +msgid "lip-sync Option" +msgstr "嘴形同步選項" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:109 +msgid "System" +msgstr "系統" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:111 +msgid "Title of timeline" +msgstr "時間軸標題" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:112 +msgid "VSQ Entry" +msgstr "VSQ 專案" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:113 +msgid "Plugin Entry" +msgstr "插件專案" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:114 +msgid "Another Entry" +msgstr "其他專案" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:115 +msgid "Entry height (pixel)" +msgstr "專案高度 (象素)" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:116 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:117 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:118 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:119 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:129 +msgid "Change" +msgstr "變更" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:120 +msgid "Check phonetic symbol to configure detailed mouth shape control" +msgstr "檢驗發音符號,詳細設定嘴形參數" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:121 +msgid "Close mouth before pronunciation" +msgstr "在發音之前閉上嘴" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:122 +msgid "\"i\" shaped mouth before pronunciation" +msgstr "在發音之前生成“i”的嘴形" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:123 +msgid "\"u\" shaped mouth before pronunciation" +msgstr "在發音之前生成“u”的嘴形" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:124 +msgid "Color" +msgstr "配色" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:125 +msgid "Design" +msgstr "設定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:126 +msgid "Path of ffmpeg" +msgstr "ffmpeg位置" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:127 +msgid "Path of mencoder" +msgstr "mencoder位置" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:128 +msgid "Font" +msgstr "字型" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:130 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:135 +msgid "Another settings" +msgstr "其他設定" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:131 +msgid "Close mouth when same vowels repeated" +msgstr "同一母音連續的時候,閉上嘴" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:132 +msgid "Encoder/Decoder" +msgstr "編碼器 /dekoda" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:133 +msgid "Generate character automaticaly when importing vsq" +msgstr "VSQ輸入時自動生成字元" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:134 +msgid "Threshold silence length(sec)" +msgstr "判定是連續音時不發音的時間 (秒 )" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:136 +msgid "Use preview-enabled dialog in character selection" +msgstr "選擇字元時使用可以預覽的對話" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:137 +msgid "Reload language configurations" +msgstr "刷新語言設定文件夾" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:138 +msgid "Operation" +msgstr "操作" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:139 +msgid "mouse wheel rate" +msgstr "滑鼠滑輪速度" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:140 +msgid "Fix cursor to center in Sync mode" +msgstr "" + +#: lipsync\LipSync\Editor/EnvConfiguration.cs:281 +#: lipsync\LipSync\Editor/EnvConfiguration.cs:305 +msgid "Executable file(*.exe)|*.exe" +msgstr "可執行文件(*.exe)|*.exe" + +#: lipsync\LipSync\Editor/Form1.cs:604 +#: lipsync\LipSync\Editor/Form1.cs:2011 +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Video size configuration" +msgstr "設定視頻圖像大小" + +#: lipsync\LipSync\Editor/Form1.cs:612 +msgid "Read from VSQ file" +msgstr "從 VSQ 文件夾讀取" + +#: lipsync\LipSync\Editor/Form1.cs:616 +msgid "Edit character" +msgstr "編輯角色" + +#: lipsync\LipSync\Editor/Form1.cs:619 +#: lipsync\LipSync\Editor/Form1.cs:652 +#: lipsync\LipSync\Editor/Form1.cs:668 +msgid "Preview image" +msgstr "圖像預覽" + +#: lipsync\LipSync\Editor/Form1.cs:620 +#: lipsync\LipSync\Editor/Form1.cs:677 +#: lipsync\LipSync\Editor/Form1.cs:737 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:964 +msgid "Image placement" +msgstr "設定圖像位置" + +#: lipsync\LipSync\Editor/Form1.cs:621 +#: lipsync\LipSync\Editor/Form1.cs:680 +#: lipsync\LipSync\Editor/Form1.cs:740 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Scale setting" +msgstr "設定大小" + +#: lipsync\LipSync\Editor/Form1.cs:623 +msgid "Generate wink" +msgstr "眨眼的生成" + +#: lipsync\LipSync\Editor/Form1.cs:627 +#: lipsync\LipSync\Editor/Form1.cs:791 +msgid "Delete" +msgstr "刪除" + +#: lipsync\LipSync\Editor/Form1.cs:630 +msgid "Add Telop" +msgstr "添加字幕" + +#: lipsync\LipSync\Editor/Form1.cs:633 +msgid "Add track" +msgstr "添加軌道" + +#: lipsync\LipSync\Editor/Form1.cs:643 +msgid "Generate Lipsync from this track" +msgstr "從這個軌道生成嘴形" + +#: lipsync\LipSync\Editor/Form1.cs:649 +#: lipsync\LipSync\Editor/Form1.cs:660 +#: lipsync\LipSync\Editor/Form1.cs:691 +msgid "Note ON from here" +msgstr "從這裏輸入音符" + +#: lipsync\LipSync\Editor/Form1.cs:664 +msgid "Set image" +msgstr "指定圖像" + +#: lipsync\LipSync\Editor/Form1.cs:671 +msgid "Change image" +msgstr "變更圖像" + +#: lipsync\LipSync\Editor/Form1.cs:675 +#: lipsync\LipSync\Editor/Form1.cs:735 +msgid "Image" +msgstr "圖像" + +#: lipsync\LipSync\Editor/Form1.cs:702 +#: lipsync\LipSync\Editor/Form1.cs:775 +msgid "Paste" +msgstr "粘貼" + +#: lipsync\LipSync\Editor/Form1.cs:716 +msgid "Note OFF" +msgstr "撤銷音符" + +#: lipsync\LipSync\Editor/Form1.cs:718 +msgid "Image Preview" +msgstr "顯示預覽" + +#: lipsync\LipSync\Editor/Form1.cs:720 +msgid "Numeric Entry" +msgstr "數值輸入" + +#: lipsync\LipSync\Editor/Form1.cs:722 +msgid "Expand" +msgstr "放大" + +#: lipsync\LipSync\Editor/Form1.cs:730 +msgid "Set Image" +msgstr "指定圖像" + +#: lipsync\LipSync\Editor/Form1.cs:732 +msgid "Preview Image" +msgstr "圖像預覽" + +#: lipsync\LipSync\Editor/Form1.cs:733 +msgid "Change Image" +msgstr "變更圖像" + +#: lipsync\LipSync\Editor/Form1.cs:749 +msgid "Plugin config. of this entry" +msgstr "此專案的插件設定" + +#: lipsync\LipSync\Editor/Form1.cs:755 +#: lipsync\LipSync\Editor/Form1.cs:767 +msgid "Copy" +msgstr "複製" + +#: lipsync\LipSync\Editor/Form1.cs:756 +msgid "Cut" +msgstr "剪切" + +#: lipsync\LipSync\Editor/Form1.cs:757 +msgid "Split Entry" +msgstr "分離入口" + +#: lipsync\LipSync\Editor/Form1.cs:765 +msgid "Timeline" +msgstr "時間軸" + +#: lipsync\LipSync\Editor/Form1.cs:771 +msgid "Copy On/Off inverted" +msgstr "ON/OFF 翻轉複製" + +#: lipsync\LipSync\Editor/Form1.cs:779 +msgid "Import from TEXT" +msgstr "從文本讀取" + +#: lipsync\LipSync\Editor/Form1.cs:780 +msgid "Export to TEXT" +msgstr "輸出文本" + +#: lipsync\LipSync\Editor/Form1.cs:793 +msgid "Delete entries" +msgstr "刪除軌道上的內容" + +#: lipsync\LipSync\Editor/Form1.cs:797 +msgid "Shift this time-line" +msgstr "移動時間軸" + +#: lipsync\LipSync\Editor/Form1.cs:1367 +#: lipsync\LipSync\Editor/Form1.cs:1407 +#: lipsync\LipSync\Editor/Form1.cs:1603 +msgid "VSQ Tracks" +msgstr "VSQ 軌道" + +#: lipsync\LipSync\Editor/Form1.cs:1378 +msgid "Character" +msgstr "角色" + +#: lipsync\LipSync\Editor/Form1.cs:1385 +msgid "Telop" +msgstr "字幕" + +#: lipsync\LipSync\Editor/Form1.cs:1392 +msgid "Another Images" +msgstr "其他圖像" + +#: lipsync\LipSync\Editor/Form1.cs:1399 +#: lipsync\LipSync\Editor/Form1.cs:1577 +msgid "Plugin" +msgstr "插件" + +#: lipsync\LipSync\Editor/Form1.cs:1540 +msgid "LipSync" +msgstr "LipSync" + +#: lipsync\LipSync\Editor/Form1.cs:1605 +#: lipsync\LipSync\Editor/Form1.cs:2394 +msgid "Another images" +msgstr "其他圖像" + +#: lipsync\LipSync\Editor/Form1.cs:1952 +msgid "" +"Initialization of video compression failed.\n" +"This video codec may require image width in multiples of certain number." +msgstr "" +"視頻壓縮的初始化失敗\n" +"此解碼器可能需要特定比例的圖像尺寸" + +#: lipsync\LipSync\Editor/Form1.cs:1963 +msgid "AVI Progress" +msgstr "AVI 輸出中" + +#: lipsync\LipSync\Editor/Form1.cs:2011 +msgid "Input video length in second" +msgstr "輸入影像的長度(秒)" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Shift all time-tables" +msgstr "整體移動時間軸" + +#: lipsync\LipSync\Editor/Form1.cs:2038 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:102 +msgid "Input shift time in second (you can enter minus value)" +msgstr "輸入移動數量 (可以輸入負值 )" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +#: lipsync\LipSync\Editor/Form1.cs:2689 +msgid "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" +msgstr "這個操作會覆蓋所有現存軌道。並且無法撤銷。繼續嗎?" + +#: lipsync\LipSync\Editor/Form1.cs:2299 +msgid "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" +msgstr "(右擊「VSQ 軌道」選擇「從 VSQ 文件夾讀取」添加一個新軌道)" + +#: lipsync\LipSync\Editor/Form1.cs:2300 +#: lipsync\LipSync\Editor/Form1.cs:2690 +#: lipsync\LipSync\Editor/Form1Util.cs:249 +#: lipsync\LipSync\Editor/Form1Util.cs:283 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "Confirmation" +msgstr "確認" + +#: lipsync\LipSync\Editor/Form1.cs:2313 +#: lipsync\LipSync\Editor/Form1Util.cs:150 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:931 +msgid "VOCALOID2 Sequence File(*.vsq)|*.vsq" +msgstr "VOCALOID2連續文件(*.vsq)|*.vsq" + +#: lipsync\LipSync\Editor/Form1.cs:2314 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:932 +msgid "UTAU Script File(*.ust)|*.ust" +msgstr "" + +#: lipsync\LipSync\Editor/Form1.cs:2436 +#: lipsync\LipSync\Editor/Form1.cs:2569 +msgid "Specify the index of target character" +msgstr "" + +#: lipsync\LipSync\Editor/Form1.cs:2707 +#: lipsync\LipSync\Editor/Form1.cs:3134 +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1907 +msgid "Play" +msgstr "播放" + +#: lipsync\LipSync\Editor/Form1.cs:2711 +msgid "File not found" +msgstr "文件未找到" + +#: lipsync\LipSync\Editor/Form1.cs:2730 +#: lipsync\LipSync\Editor/Form1.cs:2758 +#: lipsync\LipSync\Editor/Form1.cs:2770 +msgid "Extension must be *.lse" +msgstr "*.無法處理lse以外的文件格式" + +#: lipsync\LipSync\Editor/Form1.cs:2895 +msgid "Expand All" +msgstr "全部展開" + +#: lipsync\LipSync\Editor/Form1.cs:2896 +msgid "Fold All" +msgstr "全部合攏" + +#: lipsync\LipSync\Editor/Form1.cs:3138 +msgid "Audio File(*.mp3;*.wav)|*.mp3;*.wav" +msgstr "音效檔案(*.mp3,*.wav)|*.mp3;*.wav" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "Go to specified frame" +msgstr "移動到指定幀" + +#: lipsync\LipSync\Editor/Form1.cs:3152 +msgid "please input frame index" +msgstr "請輸入時間軸索引" + +#: lipsync\LipSync\Editor/Form1.cs:3166 +msgid "invalid frame index" +msgstr "這個時間軸索引不存在" + +#: lipsync\LipSync\Editor/Form1.cs:3702 +msgid "Series Image Progress" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:104 +msgid "Open" +msgstr "打開" + +#: lipsync\LipSync\Editor/Form1Util.cs:106 +msgid "Save As" +msgstr "另存爲" + +#: lipsync\LipSync\Editor/Form1Util.cs:107 +msgid "Import" +msgstr "導入" + +#: lipsync\LipSync\Editor/Form1Util.cs:108 +msgid "from RipSync data" +msgstr "RipSync 資料" + +#: lipsync\LipSync\Editor/Form1Util.cs:109 +msgid "Open VSQ/UST file" +msgstr "打開 VSQ/UST" + +#: lipsync\LipSync\Editor/Form1Util.cs:110 +msgid "Exit" +msgstr "退出" + +#: lipsync\LipSync\Editor/Form1Util.cs:111 +msgid "Script for VOCALOMARK" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:115 +msgid "Help" +msgstr "幫助" + +#: lipsync\LipSync\Editor/Form1Util.cs:116 +msgid "Plugin Information" +msgstr "插件資訊" + +#: lipsync\LipSync\Editor/Form1Util.cs:117 +msgid "About LipSync" +msgstr "關於 LipSync" + +#: lipsync\LipSync\Editor/Form1Util.cs:118 +msgid "Debug" +msgstr "故障排除" + +#: lipsync\LipSync\Editor/Form1Util.cs:119 +msgid "Edit Character" +msgstr "編輯角色" + +#: lipsync\LipSync\Editor/Form1Util.cs:120 +msgid "Flip Images Horizontaly" +msgstr "左右翻轉圖像" + +#: lipsync\LipSync\Editor/Form1Util.cs:124 +msgid "Video Size" +msgstr "圖像大小" + +#: lipsync\LipSync\Editor/Form1Util.cs:125 +msgid "Frame Rate" +msgstr "幀速率" + +#: lipsync\LipSync\Editor/Form1Util.cs:126 +msgid "Z order" +msgstr "z軸順序" + +#: lipsync\LipSync\Editor/Form1Util.cs:127 +msgid "Video Length" +msgstr "視頻長度" + +#: lipsync\LipSync\Editor/Form1Util.cs:128 +msgid "Shift All Time-tables" +msgstr "整體移動時間軸" + +#: lipsync\LipSync\Editor/Form1Util.cs:129 +msgid "Tool" +msgstr "工具" + +#: lipsync\LipSync\Editor/Form1Util.cs:131 +msgid "Plugin Config" +msgstr "插件設定" + +#: lipsync\LipSync\Editor/Form1Util.cs:132 +msgid "Add Empty Character" +msgstr "添加空白角色" + +#: lipsync\LipSync\Editor/Form1Util.cs:134 +msgid "Generate Avi" +msgstr "輸出AVI" + +#: lipsync\LipSync\Editor/Form1Util.cs:135 +msgid "Chose Sound File" +msgstr "同時播放的音樂" + +#: lipsync\LipSync\Editor/Form1Util.cs:136 +msgid "Go to Specified Frame" +msgstr "移動到指定幀" + +#: lipsync\LipSync\Editor/Form1Util.cs:137 +msgid "Stop Writing Avi" +msgstr "中斷輸出avi" + +#: lipsync\LipSync\Editor/Form1Util.cs:138 +msgid "Background Color" +msgstr "背景顔色" + +#: lipsync\LipSync\Editor/Form1Util.cs:140 +msgid "Generate Raw Avi" +msgstr "輸出無壓縮的 AVI" + +#: lipsync\LipSync\Editor/Form1Util.cs:141 +msgid "Export" +msgstr "導出" + +#: lipsync\LipSync\Editor/Form1Util.cs:142 +msgid "Script for H@TWUNEBENCH" +msgstr "H@TWUNEBENCH腳本" + +#: lipsync\LipSync\Editor/Form1Util.cs:144 +msgid "Show Object List" +msgstr "顯示物件列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:146 +msgid "Hide Object List" +msgstr "關閉物件列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:148 +msgid "Bug Report" +msgstr "錯誤報告" + +#: lipsync\LipSync\Editor/Form1Util.cs:158 +msgid "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" +msgstr "圖片文件(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" + +#: lipsync\LipSync\Editor/Form1Util.cs:159 +msgid "Avi File(*.avi)|*.avi" +msgstr "AVI 文件 (*.avi)|*.avi" + +#: lipsync\LipSync\Editor/Form1Util.cs:167 +msgid "LipSync Data File(*.lse)|*.lse" +msgstr "LipSync 資料設定 (*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:175 +msgid "LipSync Data file(*.lse)|*.lse" +msgstr "LipSync 資料設定 (*.lse)|*.lse" + +#: lipsync\LipSync\Editor/Form1Util.cs:183 +msgid "Real Time \"lipsync\"" +msgstr "即時口型同步" + +#: lipsync\LipSync\Editor/Form1Util.cs:184 +msgid "End Repeat Here" +msgstr "指定重播結束位置" + +#: lipsync\LipSync\Editor/Form1Util.cs:185 +msgid "Start Repeat Here" +msgstr "指定重播開始位置" + +#: lipsync\LipSync\Editor/Form1Util.cs:186 +msgid "Reset Repeat region" +msgstr "重置重播範圍" + +#: lipsync\LipSync\Editor/Form1Util.cs:189 +msgid "View" +msgstr "視圖" + +#: lipsync\LipSync\Editor/Form1Util.cs:190 +msgid "Zoom" +msgstr "擴大" + +#: lipsync\LipSync\Editor/Form1Util.cs:191 +msgid "Mooz" +msgstr "縮小" + +#: lipsync\LipSync\Editor/Form1Util.cs:192 +msgid "Set Default Scale" +msgstr "默認大小" + +#: lipsync\LipSync\Editor/Form1Util.cs:193 +#: lipsync\LipSync\Editor/Form1Util.cs:197 +msgid "Move to Top" +msgstr "回到開頭" + +#: lipsync\LipSync\Editor/Form1Util.cs:194 +#: lipsync\LipSync\Editor/Form1Util.cs:196 +msgid "Move to End" +msgstr "轉到結尾" + +#: lipsync\LipSync\Editor/Form1Util.cs:195 +msgid "Repeat play" +msgstr "重復播放" + +#: lipsync\LipSync\Editor/Form1Util.cs:199 +#: lipsync\LipSync\Editor/Form1Util.cs:203 +#: lipsync\LipSync\Editor/Form1Util.cs:1850 +msgid "Pause" +msgstr "暫停" + +#: lipsync\LipSync\Editor/Form1Util.cs:200 +msgid "Show VSQ Tracks Allways" +msgstr "總是顯示 VSQ 軌道" + +#: lipsync\LipSync\Editor/Form1Util.cs:201 +msgid "Show Bars" +msgstr "顯示格柵" + +#: lipsync\LipSync\Editor/Form1Util.cs:202 +msgid "Preview" +msgstr "圖像預覽" + +#: lipsync\LipSync\Editor/Form1Util.cs:204 +msgid "Sync with Time-table" +msgstr "與時間軸同步" + +#: lipsync\LipSync\Editor/Form1Util.cs:206 +#: lipsync\LipSync\Editor/Form1Util.cs:467 +msgid "Enable Preview" +msgstr "顯示預覽" + +#: lipsync\LipSync\Editor/Form1Util.cs:208 +#: lipsync\LipSync\Editor/Form1Util.cs:461 +msgid "Disable Preview" +msgstr "關閉預覽" + +#: lipsync\LipSync\Editor/Form1Util.cs:210 +msgid "Separate Preview Window" +msgstr "" + +#: lipsync\LipSync\Editor/Form1Util.cs:213 +msgid "Quantize" +msgstr "量化" + +#: lipsync\LipSync\Editor/Form1Util.cs:214 +msgid "Off" +msgstr "關掉" + +#: lipsync\LipSync\Editor/Form1Util.cs:215 +msgid "Triplet" +msgstr "三連音" + +#: lipsync\LipSync\Editor/Form1Util.cs:217 +msgid "List of Object" +msgstr "物件列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:218 +msgid "Property" +msgstr "物件特性" + +#: lipsync\LipSync\Editor/Form1Util.cs:230 +msgid "Series Image" +msgstr "連續的圖像文件" + +#: lipsync\LipSync\Editor/Form1Util.cs:248 +#: lipsync\LipSync\Editor/Form1Util.cs:282 +msgid "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" +msgstr "覆蓋現有拍子和拍號,並且無法撤銷,繼續嗎?" + +#: lipsync\LipSync\Editor/Form1Util.cs:411 +msgid "Hide object list" +msgstr "關閉物件列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:417 +msgid "Show object list" +msgstr "顯示物件列表" + +#: lipsync\LipSync\Editor/Form1Util.cs:442 +msgid "(no name)" +msgstr "無標題" + +#: lipsync\LipSync\Editor/Form1Util.cs:498 +msgid "Failed file saving" +msgstr "文件保存失敗 " + +#: lipsync\LipSync\Editor/Form1Util.cs:569 +msgid "Failed file reading" +msgstr "文件讀取失敗" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Width" +msgstr "寬度" + +#: lipsync\LipSync\Editor/Form1Util.cs:669 +msgid "Height" +msgstr "高度" + +#: lipsync\LipSync\Editor/Form1Util.cs:1343 +msgid " has been changed. Do you wish to save changes to file?" +msgstr "文件將被更改,是否保存變更?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1345 +msgid "Do you wish to save changes to file?" +msgstr "是否保存變更?" + +#: lipsync\LipSync\Editor/Form1Util.cs:1986 +#, fuzzy +msgid "Progress" +msgstr "AVI 輸出中" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:167 +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:229 +msgid "Text file(*.txt)|*.txt" +msgstr "txt文件(*.txt)|*.txt" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:554 +msgid "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" +msgstr "請輸入放大倍數 (輸入負的數值,就左右翻轉 )" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:592 +msgid "" +"...clearing entries of selected time-table.\n" +"Would you like to continue?" +msgstr "" +"清除選擇的時間表條目。\n" +" 繼續嗎?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1077 +msgid "" +"...deleting selected character.\n" +"Would you like to continue?" +msgstr "" +"刪除選擇的角色。\n" +" 繼續嗎?" + +#: lipsync\LipSync\Editor/Form1_EventHandler.cs:1084 +msgid "" +"...deleting selected track.\n" +"Would you like to continue?" +msgstr "" +"將要刪除所選軌道。\n" +" 是否繼續?" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:75 +#: lipsync\LipSync\Editor/FormCommandHistory.cs:92 +msgid "Command History" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:131 +#, csharp-format +msgid "Delete entry of 'Another Image' at Index {0}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:133 +#, csharp-format +msgid "Add entry of 'Another Image' at Index {0}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:135 +#, csharp-format +msgid "Edit entry of 'Another Image' at Track {0}, Index {1}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:139 +#, csharp-format +msgid "Delete telop '{0}'" +msgstr "刪除字幕: '{0}'" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:141 +#, csharp-format +msgid "Edit telop '{0}' at Index {1}" +msgstr "" + +#: lipsync\LipSync\Editor/FormCommandHistory.cs:143 +#, csharp-format +msgid "Add telop '{0}'" +msgstr "添加字幕: '{0}'" + +#: lipsync\LipSync\Editor/FormObjectList.cs:45 +msgid "List of object" +msgstr "物件列表" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:102 +msgid "Directory" +msgstr "目錄" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:103 +msgid "Specify output range" +msgstr "指定輸出範圍" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:107 +msgid "Parser String" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:108 +msgid "Automatically Add Extension" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:109 +msgid "Image Format" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:187 +msgid "Sample File Name" +msgstr "" + +#: lipsync\LipSync\Editor/FormSeriesImage.cs:197 +msgid "Error: Invalid parser string." +msgstr "" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:63 +msgid "detail" +msgstr "詳情" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:64 +msgid "configure frame rate" +msgstr "FPS設定" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:65 +msgid "Frame rate" +msgstr "幀速率" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:68 +msgid "denominator of frame rate" +msgstr "FPS分母" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:69 +msgid "numerator of frame rate" +msgstr "FPS分子" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:71 +msgid "import frame rate from AVI file" +msgstr "使用AVI自身的FPS(幀率)" + +#: lipsync\LipSync\Editor/FormSetFrameRate.cs:169 +msgid "failed getting frame rate" +msgstr "無法取得FPS" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:79 +msgid "Lip Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:80 +msgid "Eye Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:81 +msgid "Eyebrow Assignment" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:84 +msgid "Blend time for E_Default -> E_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:85 +msgid "Blend time for E_* -> E_Default" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:86 +msgid "Blend time for EB_Default -> EB_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:87 +msgid "Blend time for EB_* -> EB_Default" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:88 +msgid "Blend time for L_Default -> L_*" +msgstr "" + +#: lipsync\LipSync\Editor/FormVocalomark.cs:89 +msgid "Blend time for L_* -> L_Default" +msgstr "" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:70 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:73 +msgid "Title" +msgstr "標題" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:71 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:72 +msgid "Tag" +msgstr "標簽" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:74 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:126 +msgid "Up" +msgstr "上移" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:75 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:121 +msgid "Down" +msgstr "下移" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:76 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:119 +msgid "Add" +msgstr "添加" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:79 +msgid "Select image file" +msgstr "選擇圖片文件夾" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:80 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:125 +msgid "Select transparent color" +msgstr "設定透過的顔色" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:84 +msgid "Character name" +msgstr "角色名" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:86 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:122 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:851 +msgid "Change title" +msgstr "變更標題" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:88 +msgid "Selected image" +msgstr "被選擇的圖像" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:91 +msgid "Open *.rsi" +msgstr "打開 RSI" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:94 +msgid "Save as *.rsi" +msgstr "保存爲XML格式" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:95 +msgid "Save as XML" +msgstr "保存爲XML格式" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:98 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:103 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:166 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:180 +msgid "LipSync Character Config(*.lsc)|*.lsc" +msgstr "LipSync 角色設定 (*.lsc)|*.lsc" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:107 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:123 +msgid "Reset image" +msgstr "重置圖像" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:109 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:114 +msgid "RipSync Image(*.rsi)|*.rsi" +msgstr "RipSync 角色設定 (*.rsi)|*.rsi" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:181 +#: lipsync\LipSync\Editor/GenerateCharacter.cs:915 +msgid "LipSync Character Config(content.xml)|content.xml" +msgstr "LipSync 角色設定 (content.xml)|content.xml" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:551 +msgid "NOT editable" +msgstr "無法更改" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:664 +msgid "Title of image" +msgstr "圖像的標題" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:665 +msgid "Input the title of image" +msgstr "請輸入圖像的標題" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:682 +msgid "This image title has been already registered" +msgstr "已經被登記的名字" + +#: lipsync\LipSync\Editor/GenerateCharacter.cs:852 +msgid "Input new title" +msgstr "請輸入新的標題" + +#: lipsync\LipSync\Editor/Previewer.cs:56 +msgid "Stop" +msgstr "停止" + +#: lipsync\LipSync\Editor/Previewer.cs:57 +msgid "Stretch image" +msgstr "伸展圖像" + +#: lipsync\LipSync\Editor/Previewer.cs:58 +msgid "Specified size" +msgstr "指定尺寸" + +#: lipsync\LipSync\Editor/Property.cs:80 +msgid "Delte Delop" +msgstr "刪除字幕" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:52 +msgid "Custom" +msgstr "自定義" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:53 +#: lipsync\LipSync\Editor/SelectCharacter.cs:57 +#: lipsync\LipSync\Editor/SelectCharacter.cs:58 +msgid "Built-in" +msgstr "內建" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:54 +msgid "Select character to generate lip-sync" +msgstr "請選擇要生成嘴形的角色" + +#: lipsync\LipSync\Editor/SelectCharacter.cs:59 +msgid "Character selection" +msgstr "角色的選擇" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:48 +msgid "Select track" +msgstr "選擇軌道" + +#: lipsync\LipSync\Editor/TrackSelecter.cs:49 +msgid "import tempo and time-signal information" +msgstr "輸入拍子和拍號" + +#: lipsync\LipSync\Editor/Winker.cs:62 +msgid "Wink interval (sec)" +msgstr "眨眼間隔(秒)" + +#: lipsync\LipSync\Editor/Winker.cs:63 +msgid "Randomize" +msgstr "隨機間隔" + +#: lipsync\LipSync\Editor/Winker.cs:64 +msgid "Closed Eye" +msgstr "閉眼的圖像" + +#: lipsync\LipSync\Editor/Winker.cs:65 +msgid "In-between Image" +msgstr "伴隨的圖像" + +#: lipsync\LipSync\Editor/Winker.cs:66 +msgid "Eye-closing frames" +msgstr "閉眼的圖像" + +#: lipsync\LipSync\Editor/Winker.cs:69 +msgid "Limit start time" +msgstr "指定開始時間" + +#: lipsync\LipSync\Editor/Winker.cs:70 +msgid "Limit end time" +msgstr "指定結束時間" + +#: lipsync\LipSync\Editor/ZOrder.cs:44 +msgid "Select target item, and push [Up] or [Down] button" +msgstr "選擇目標圖像,點擊向上移或向下移" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:199 +msgid "Image directory already exists. Would you like to overwrite them?" +msgstr "圖像已存在,是否覆蓋?" + +#: lipsync\LipSync\Editor/RipSync/RsiWriter.cs:200 +msgid "warning" +msgstr "警告" + +#: Boare.Lib.AppUtil/VersionInfo.cs:177 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:116 +#, csharp-format +msgid "About {0}" +msgstr "" + +#: Boare.Lib.AppUtil/VersionInfo.cs:186 +#: Boare.Lib.AppUtil/VersionInfo.Designer.cs:117 +msgid "Credit" +msgstr "製作群" + +#~ msgid "Video" +#~ msgstr "視頻" +#~ msgid "insertion of wav file has failed" +#~ msgstr "wav文件夾插入失敗" +#~ msgid "FLV Progress" +#~ msgstr "正在輸出FLV" +#~ msgid "Edit motion curve" +#~ msgstr "編輯移動曲線" +#~ msgid "Disable preview" +#~ msgstr "關閉預覽" +#~ msgid "Enable preview" +#~ msgstr "顯示預覽" +#~ msgid "already exists." +#~ msgstr "已經存在" +#~ msgid "Initialization of video compression failed" +#~ msgstr "" +#~ "視頻壓縮的初始化失敗 \n" +#~ " 此解碼器可能需要特定比例的圖像尺寸" +#~ msgid "Specify paste mode" +#~ msgstr "請指定粘貼模式" +#~ msgid "Interrupt" +#~ msgstr "中斷" +#~ msgid "Overwrite" +#~ msgstr "覆蓋" + diff --git a/trunk/LipSync/NicoComment/Config.Designer.cs b/trunk/LipSync/NicoComment/Config.Designer.cs new file mode 100644 index 0000000..8d328df --- /dev/null +++ b/trunk/LipSync/NicoComment/Config.Designer.cs @@ -0,0 +1,41 @@ +namespace NicoComment { + partial class Config { + ///

+ /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.SuspendLayout(); + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 294, 206 ); + this.Name = "Form1"; + this.Text = "Form1"; + this.ResumeLayout( false ); + + } + + #endregion + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Config.cs b/trunk/LipSync/NicoComment/Config.cs new file mode 100644 index 0000000..6cb8727 --- /dev/null +++ b/trunk/LipSync/NicoComment/Config.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NicoComment { + public partial class Config : Form { + public Config() { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Config.resx b/trunk/LipSync/NicoComment/Config.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/trunk/LipSync/NicoComment/Config.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/FConfig.Designer.cs b/trunk/LipSync/NicoComment/FConfig.Designer.cs new file mode 100644 index 0000000..f77e180 --- /dev/null +++ b/trunk/LipSync/NicoComment/FConfig.Designer.cs @@ -0,0 +1,116 @@ +namespace NicoComment { + partial class FConfig { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog(); + this.button1 = new System.Windows.Forms.Button(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // btnOK + // + this.btnOK.Location = new System.Drawing.Point( 108, 63 ); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size( 75, 23 ); + this.btnOK.TabIndex = 1; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler( this.btnOK_Click ); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point( 207, 63 ); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size( 75, 23 ); + this.btnCancel.TabIndex = 2; + this.btnCancel.Text = "Cancel"; + this.btnCancel.UseVisualStyleBackColor = true; + // + // openFileDialog1 + // + this.openFileDialog1.Filter = "text file(*.txt)|*.txt|xml format(*.xml)|*.xml|all files(*.*)|*.*"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point( 258, 30 ); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size( 24, 23 ); + this.button1.TabIndex = 3; + this.button1.Text = "..."; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler( this.button1_Click ); + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point( 12, 32 ); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 240, 19 ); + this.textBox1.TabIndex = 4; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point( 10, 9 ); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size( 73, 12 ); + this.label1.TabIndex = 5; + this.label1.Text = "読込むファイル"; + // + // FConfig + // + this.AcceptButton = this.btnOK; + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size( 294, 97 ); + this.Controls.Add( this.label1 ); + this.Controls.Add( this.textBox1 ); + this.Controls.Add( this.button1 ); + this.Controls.Add( this.btnCancel ); + this.Controls.Add( this.btnOK ); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = "FConfig"; + this.Text = "Nico Commentの設定"; + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + private System.Windows.Forms.OpenFileDialog openFileDialog1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.Label label1; + + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/FConfig.cs b/trunk/LipSync/NicoComment/FConfig.cs new file mode 100644 index 0000000..cc4d9cf --- /dev/null +++ b/trunk/LipSync/NicoComment/FConfig.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; +using System.IO; + +namespace NicoComment { + public partial class FConfig : Form { + private string config = ""; + public string ConfigString { + get { + return config; + } + } + public FConfig( string configure ) { + InitializeComponent(); + string[] result = configure.Split( new char[] { '\n' } ); + textBox1.Text = result[0]; + //textBox2.Lines = configure.Split( new char[]{'\n'}); + } + private void btnOK_Click( object sender, EventArgs e ) { + string path = textBox1.Text; + if ( File.Exists( path ) ) { + config = path; + using ( StreamReader sr = new StreamReader( path ) ) { + while ( sr.Peek() >= 0 ) { + config += '\n' + sr.ReadLine(); + } + } + this.DialogResult = DialogResult.OK; + } else { + this.DialogResult = DialogResult.Cancel; + } + base.Close(); + } + + private void button1_Click( object sender, EventArgs e ) { + if ( openFileDialog1.ShowDialog() == DialogResult.OK ) { + textBox1.Text = openFileDialog1.FileName; + } + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/FConfig.resx b/trunk/LipSync/NicoComment/FConfig.resx new file mode 100644 index 0000000..8dc6b17 --- /dev/null +++ b/trunk/LipSync/NicoComment/FConfig.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Form1.Designer.cs b/trunk/LipSync/NicoComment/Form1.Designer.cs new file mode 100644 index 0000000..b29f1a4 --- /dev/null +++ b/trunk/LipSync/NicoComment/Form1.Designer.cs @@ -0,0 +1,100 @@ +namespace NicoComment { + partial class Form1 { + /// + /// 必要なデザイナ変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose( bool disposing ) { + if ( disposing && (components != null) ) { + components.Dispose(); + } + base.Dispose( disposing ); + } + + #region Windows フォーム デザイナで生成されたコード + + /// + /// デザイナ サポートに必要なメソッドです。このメソッドの内容を + /// コード エディタで変更しないでください。 + /// + private void InitializeComponent() { + this.pictureBox1 = new System.Windows.Forms.PictureBox(); + this.textBox1 = new System.Windows.Forms.TextBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.textBox3 = new System.Windows.Forms.TextBox(); + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); + this.SuspendLayout(); + // + // pictureBox1 + // + this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.pictureBox1.Location = new System.Drawing.Point( 12, 12 ); + this.pictureBox1.Name = "pictureBox1"; + this.pictureBox1.Size = new System.Drawing.Size( 512, 384 ); + this.pictureBox1.TabIndex = 0; + this.pictureBox1.TabStop = false; + // + // textBox1 + // + this.textBox1.Location = new System.Drawing.Point( 18, 450 ); + this.textBox1.Name = "textBox1"; + this.textBox1.Size = new System.Drawing.Size( 100, 19 ); + this.textBox1.TabIndex = 1; + // + // textBox2 + // + this.textBox2.Location = new System.Drawing.Point( 146, 453 ); + this.textBox2.Name = "textBox2"; + this.textBox2.Size = new System.Drawing.Size( 221, 19 ); + this.textBox2.TabIndex = 2; + // + // button1 + // + this.button1.Location = new System.Drawing.Point( 423, 453 ); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size( 75, 23 ); + this.button1.TabIndex = 3; + this.button1.Text = "button1"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler( this.button1_Click ); + // + // textBox3 + // + this.textBox3.Location = new System.Drawing.Point( 104, 478 ); + this.textBox3.Name = "textBox3"; + this.textBox3.Size = new System.Drawing.Size( 101, 19 ); + this.textBox3.TabIndex = 4; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 12F ); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size( 537, 509 ); + this.Controls.Add( this.textBox3 ); + this.Controls.Add( this.button1 ); + this.Controls.Add( this.textBox2 ); + this.Controls.Add( this.textBox1 ); + this.Controls.Add( this.pictureBox1 ); + this.Name = "Form1"; + this.Text = "Form1"; + ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); + this.ResumeLayout( false ); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.PictureBox pictureBox1; + private System.Windows.Forms.TextBox textBox1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox textBox3; + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Form1.cs b/trunk/LipSync/NicoComment/Form1.cs new file mode 100644 index 0000000..a8e01fa --- /dev/null +++ b/trunk/LipSync/NicoComment/Form1.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace NicoComment { + public partial class Form1 : Form { + public Form1() { + InitializeComponent(); + pictureBox1.Image = new Bitmap( 512, 384 ); + } + + private void button1_Click( object sender, EventArgs e ) { + using ( Graphics g = Graphics.FromImage( pictureBox1.Image ) ) { + g.Clear( Color.Black ); + double time = double.Parse( textBox3.Text ); + NComment entry = new NComment( 0.0f, textBox1.Text, textBox2.Text, 0 ); + NicoComment.drawString( g, entry, pictureBox1.Bounds, time, 1 ); + } + pictureBox1.Invalidate(); + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Form1.resx b/trunk/LipSync/NicoComment/Form1.resx new file mode 100644 index 0000000..ff31a6d --- /dev/null +++ b/trunk/LipSync/NicoComment/Form1.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/NicoComment.cs b/trunk/LipSync/NicoComment/NicoComment.cs new file mode 100644 index 0000000..858f6ff --- /dev/null +++ b/trunk/LipSync/NicoComment/NicoComment.cs @@ -0,0 +1,508 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Plugin; +using System.Drawing; +using System.Drawing.Imaging; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +namespace NicoComment { + + public class NicoComment : IPlugin{ + private List config = new List(); + private List comments = new List(); + + public void ApplyLanguage( string language_code ) { + + } + + + public string Name { + get { + return "Nico Comment"; + } + } + + public ulong Type { + get { + return 0; + } + } + + public string Abstract { + get { + return "ニコニコ動画ぽい字幕を、ニコニコ動画と同様なコマンドで追加できるプラグイン。"; + } + } + + public void Apply( ref Bitmap frame, float time, float e_begin, float e_end, ref string e_body ) { + using ( Graphics g = Graphics.FromImage( frame ) ) { + Rectangle rc = new Rectangle( 0, 0, frame.Width, frame.Height ); + int skip_count_def = 0; + bool first_def = true; + bool first_shita = true; + bool first_ue = true; + int y_def = 0; + int y_shita = rc.Height; + int y_ue = 0; + for ( int i = 0; i < comments.Count; i++ ) { + if ( comments[i].time <= time && time < comments[i].time + 3.0 ) { + double t = time - comments[i].time; + int height = (int)comments[i].type.Size.Size; + if ( comments[i].type.Position == NComTypePosition.def ) { + if ( !first_def ) { + y_def += height; + if ( y_def > rc.Height ) { + y_def -= rc.Height; + skip_count_def++; + } + t += 0.1 * skip_count_def; + } else { + first_def = false; + } + if ( comments[i].y == NComment.NULL ) { + comments[i].y = y_def; + } + + } else if ( comments[i].type.Position == NComTypePosition.shita ) { + if ( !first_shita ) { + y_shita -= (int)(1.1f * height); + if ( y_shita + height < 0 ) { + y_shita += rc.Height; + } + } else { + y_shita -= (int)(1.1f * height); + first_shita = false; + } + if ( comments[i].y == NComment.NULL ) { + comments[i].y = y_shita; + } + + } else if ( comments[i].type.Position == NComTypePosition.ue ) { + if ( !first_ue ) { + y_ue += (int)(1.1f * height); + if ( y_ue > rc.Height ) { + y_ue += rc.Height; + } + } else { + first_ue = false; + } + if ( comments[i].y == NComment.NULL ) { + comments[i].y = y_ue; + } + + } + NComment entry = comments[i]; + drawString( g, entry, rc, t, comments.Count ); + comments[i] = entry; + } + } + } + } + + public string Config { + get { + string result = ""; + if( config.Count > 0 ){ + result = config[0]; + } + for ( int i = 1; i < config.Count; i++ ) { + result += "\n" + config[i]; + } + return result; + } + set { + List work_config = new List(); + foreach ( string item in config ) { + work_config.Add( item ); + } + config.Clear(); + List work_comments = new List(); + foreach ( NComment item in comments ) { + work_comments.Add( item ); + } + comments.Clear(); + //timing.Clear(); + string[] result = value.Split( new char[] { '\n' } ); + config.Add( result[0] ); + for( int i = 1; i < result.Length; i++ ){ + config.Add( result[i] ); + string[] spl = result[i].Split( new char[] { '\t' } ); + if ( spl.Length < 3 ) { + config.Clear(); + foreach ( string item in work_config ) { + config.Add( item ); + } + work_config.Clear(); + comments.Clear(); + foreach ( NComment item in work_comments ) { + comments.Add( item ); + } + work_comments.Clear(); + MessageBox.Show( "コメントにエラーがありました。エラーのあった行は次の通りです\n" + i + "行目\n" + result[i] ); + return; + } + //timing.Add( double.Parse( spl[0] ) ); + float time; + try { + time = float.Parse( spl[0] ); + } catch { + config.Clear(); + foreach ( string item in work_config ) { + config.Add( item ); + } + work_config.Clear(); + comments.Clear(); + foreach ( NComment item in work_comments ) { + comments.Add( item ); + } + work_comments.Clear(); + MessageBox.Show( "コメントにエラーがありました。エラーのあった行は次の通りです\n" + i + "行目\n" + result[i] ); + return; + } + comments.Add( new NComment( float.Parse( spl[0] ), spl[1], spl[2], i ) ); + //MessageBox.Show( "Config::set; comments[i-1].type.Position.ToString()=" + comments[i - 1].type.Position.ToString() ); + } + comments.Sort(); + } + } + + public DialogResult EntrySetting( ref string entry_config ) { + return DialogResult.Cancel; + } + + public DialogResult BaseSetting() { + FConfig fconf = new FConfig( Config ); + DialogResult result = fconf.ShowDialog(); + if ( result == DialogResult.OK ) { + Config = fconf.ConfigString; + } + fconf.Dispose(); + return result; + } + + /// + /// comで指定されたコメント・タイプのニコニココメントを、 + /// Graphics gの位置xに描画します。 + /// + /// このコメントが表示され始めてからの経過時間 + /// + /// + /// + public static void drawString( Graphics g, NComment com, Rectangle rc, double time, int comment_num ) { + const string font_name = "MS ゴシック"; + Font font = new Font( font_name, com.type.Size.Size, FontStyle.Bold, GraphicsUnit.Pixel ); + Color color = com.type.Color.Color; + int axy = com.type.Position.getPosition( rc.Height, com.type.Size.Size ); + int x; + if ( com.type.Position == NComTypePosition.ue || com.type.Position == NComTypePosition.shita ) { + x = (int)(rc.Width / 2.0f - com.width / 2.0f); + } else { + x = (int)(rc.Width - time * ((com.width + rc.Width) / 3.0f)); + } + GraphicsPath path = new GraphicsPath(); + //FontFamily ff = new FontFamily( font_name ); + FontFamily ff = font.FontFamily; + path.AddString( com.message, ff, (int)FontStyle.Bold, com.type.Size.Size, new Point( 0, 0 ), StringFormat.GenericDefault ); + using ( Bitmap tmp = new Bitmap( com.width, com.height, PixelFormat.Format32bppArgb ) ) { + using ( Graphics gx = Graphics.FromImage( tmp ) ) { + gx.Clear( Color.FromArgb( 0, Color.White ) ); + Color shadow; + if ( color != Color.Black ) { + shadow = Color.Black; + } else { + shadow = Color.White; + } + gx.DrawPath( new Pen( Color.FromArgb( 50, shadow ), 3.5f ), path ); + gx.DrawPath( new Pen( Color.FromArgb( 180, shadow ), 2.5f ), path ); + gx.FillPath( new SolidBrush( color ), path ); + //gx.DrawString( com.message, font, new SolidBrush( color ), new PointF( 0, 0 ) ); + } + float alpha = 0.6f + 0.4f * ((float)com.count / (float)comment_num); + ColorMatrix cm = new ColorMatrix(); + cm.Matrix00 = 1; + cm.Matrix11 = 1; + cm.Matrix22 = 1; + cm.Matrix33 = alpha; + cm.Matrix44 = 1; + ImageAttributes ia = new ImageAttributes(); + ia.SetColorMatrix( cm ); + + g.DrawImage( tmp, new Rectangle( x, com.y, tmp.Width, tmp.Height ), + 0, 0, tmp.Width, tmp.Height, GraphicsUnit.Pixel, ia ); + } + } + public void Render( Graphics g, Size size, float time, string mouth, string reserved ) { + } + + } + + public class NComment : IComparable { + public const int NULL = -999; + public float time; + public NComType type; + public string message; + public int width; + public int height; + public int count; + public int y; + + public NComment( float time, string command, string message, int count ) { + this.time = time; + this.type = new NComType( command ); + this.message = message; + this.count = count; + this.y = NULL; + SizeF sizef; + Bitmap dumy = new Bitmap( 1, 1 ); + Font font = new Font( "MS ゴシック", this.type.Size.Size, FontStyle.Bold, GraphicsUnit.Pixel ); + using ( Graphics g = Graphics.FromImage( dumy ) ) { + sizef = g.MeasureString( message, font ); + } + this.width = (int)sizef.Width; + this.height = (int)sizef.Height; + dumy.Dispose(); + font.Dispose(); + } + + public int CompareTo( object obj ) { + NComment com = (NComment)obj; + if ( this.time > com.time ) { + return 1; + } else if ( this.time < com.time ) { + return -1; + } else { + return 0; + } + } + } + + public class NComType { + public NComTypePosition Position; + public NComTypeColor Color; + public NComTypeSize Size; + public NComType( string command ) { + Position = NComTypePosition.def; + Color = NComTypeColor.def; + Size = NComTypeSize.def; + string[] spl = command.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ); + for ( int i = spl.Length - 1; i >= 0; i-- ) { + NComTypePosition pos = NComTypePosition.fromCommand( spl[i] ); + if ( pos != NComTypePosition.INVALID ) { + Position = pos; + continue; + } + NComTypeColor col = NComTypeColor.fromCommand( spl[i] ); + if ( col != NComTypeColor.INVALID ) { + Color = col; + continue; + } + NComTypeSize size = NComTypeSize.fromCommand( spl[i] ); + if ( size != NComTypeSize.INVALID ) { + Size = size; + continue; + } + } + } + } + + public class NComTypePosition { + private int m_value; + public static NComTypePosition ue = new NComTypePosition( 0 ); + public static NComTypePosition shita = new NComTypePosition( 1 ); + public static NComTypePosition def = new NComTypePosition( 2 ); + public static NComTypePosition INVALID = new NComTypePosition( -1 ); + private NComTypePosition( int value ) { + m_value = value; + } + public static NComTypePosition fromCommand( string command ) { + switch ( command ) { + case "ue": + return ue; + case "shita": + return shita; + case "naka": + return def; + default: + return INVALID; + } + } + public int getPosition( float height, float fontsize ) { + switch ( m_value ) { + case 0: + return 0; + case 1: + return (int)(height - fontsize * 1.2f); + default: + return -1; + + } + } + new public string ToString() { + switch ( m_value ) { + case 0: + return "ue"; + case 1: + return "shita"; + case 2: + return "def"; + default: + return "INVALID"; + } + } + } + + public class NComTypeColor { + private int m_value; + public static NComTypeColor white = new NComTypeColor( 0 ); + public static NComTypeColor def = new NComTypeColor( 0 ); + public static NComTypeColor red = new NComTypeColor( 1 ); + public static NComTypeColor pink = new NComTypeColor( 2 ); + public static NComTypeColor orange = new NComTypeColor( 3 ); + public static NComTypeColor yellow = new NComTypeColor( 4 ); + public static NComTypeColor green = new NComTypeColor( 5 ); + public static NComTypeColor cyan = new NComTypeColor( 6 ); + public static NComTypeColor blue = new NComTypeColor( 7 ); + public static NComTypeColor purple = new NComTypeColor( 8 ); + public static NComTypeColor niconicowhite = new NComTypeColor( 9 ); + public static NComTypeColor truered = new NComTypeColor( 10 ); + public static NComTypeColor passionorange = new NComTypeColor( 11 ); + public static NComTypeColor madyellow = new NComTypeColor( 12 ); + public static NComTypeColor elementalgreen = new NComTypeColor( 13 ); + public static NComTypeColor marineblue = new NComTypeColor( 14 ); + public static NComTypeColor nobleviolet = new NComTypeColor( 15 ); + public static NComTypeColor black = new NComTypeColor( 16 ); + public static NComTypeColor INVALID = new NComTypeColor( -1 ); + private NComTypeColor( int value ) { + m_value = value; + } + public static NComTypeColor fromCommand( string command ) { + switch ( command ) { + case "white": + return white; + case "red": + return red; + case "pink": + return pink; + case "orange": + return orange; + case "yellow": + return yellow; + case "green": + return green; + case "cyan": + return cyan; + case "blue": + return blue; + case "purple": + return purple; + case "niconicowhite": + case "white2": + return niconicowhite; + case "truered": + case "red2": + return truered; + case "passionorange": + case "orange2": + return passionorange; + case "madyellow": + case "yellow2": + return madyellow; + case "elementalgree": + case "green2": + return elementalgreen; + case "marineblue": + case "blue2": + return marineblue; + case "nobleviolet": + case "purple2": + return nobleviolet; + case "black": + return black; + default: + return INVALID; + } + } + public Color Color { + get { + switch ( m_value ) { + case 0: + return Color.White; + case 1: + return Color.Red; + case 2: + return Color.Pink; + case 3: + return Color.Orange; + case 4: + return Color.Yellow; + case 5: + return Color.FromArgb( 0, 255, 0 ); + case 6: + return Color.Cyan; + case 7: + return Color.Blue; + case 8: + return Color.Purple; + case 9: + return Color.FromArgb( 204, 204, 153 ); + case 10: + return Color.FromArgb( 204, 0, 51 ); + case 11: + return Color.FromArgb( 255, 102, 0 ); + case 12: + return Color.FromArgb( 153, 153, 0 ); + case 13: + return Color.FromArgb( 0, 204, 102 ); + case 14: + return Color.FromArgb( 51, 255, 252 ); + case 15: + return Color.FromArgb( 102, 51, 204 ); + case 16: + return Color.Black; + } + return Color.White; + } + } + } + + public class NComTypeSize { + private int m_value; + public static NComTypeSize big = new NComTypeSize( 0 ); + public static NComTypeSize medium = new NComTypeSize( 1 ); + public static NComTypeSize small = new NComTypeSize( 2 ); + public static NComTypeSize def = new NComTypeSize( 1 ); + public static NComTypeSize INVALID = new NComTypeSize( -1 ); + private NComTypeSize( int value ) { + m_value = value; + } + public static NComTypeSize fromCommand( string command ) { + switch ( command ) { + case "big": + return big; + case "medium": + return medium; + case "small": + return small; + default: + return INVALID; + } + } + public float Size { + get { + switch ( m_value ) { + case 0: + return 39f; + case 1: + return 24f; + case 2: + return 15f; + default: + return 24f; + } + } + } + } + +} diff --git a/trunk/LipSync/NicoComment/NicoComment.csproj b/trunk/LipSync/NicoComment/NicoComment.csproj new file mode 100644 index 0000000..ebb042a --- /dev/null +++ b/trunk/LipSync/NicoComment/NicoComment.csproj @@ -0,0 +1,92 @@ + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {6CBD22A6-34C4-4444-8F90-9EE0D150CEC1} + Library + Properties + NicoComment + NicoComment + + + + + 2.0 + v3.5 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + Form + + + FConfig.cs + + + Form + + + Form1.cs + + + + + + + + Designer + FConfig.cs + + + Designer + Form1.cs + + + + + {FB0C1FBD-3CB7-46BF-8E39-57BE2C8D1F00} + IPlugin + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Program.cs b/trunk/LipSync/NicoComment/Program.cs new file mode 100644 index 0000000..5c18d4f --- /dev/null +++ b/trunk/LipSync/NicoComment/Program.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Windows.Forms; +using System.IO; + +namespace NicoComment { + static class Program { + /// + /// アプリケーションのメイン エントリ ポイントです。 + /// + [STAThread] + static void Main() { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault( false ); +#if !DEBUG + //DEBUGのときはIDEでエラーをハンドルしたいので。 + try { +#endif + Application.Run( new Form1() ); +#if !DEBUG + } catch ( Exception e ) { + using ( StreamWriter sw = new StreamWriter( "error.log", true ) ) { + sw.WriteLine( e.Message ); + sw.WriteLine( e.StackTrace ); + } + } +#endif + } + } +} \ No newline at end of file diff --git a/trunk/LipSync/NicoComment/Properties/AssemblyInfo.cs b/trunk/LipSync/NicoComment/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..995b9c8 --- /dev/null +++ b/trunk/LipSync/NicoComment/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "NicoComment" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "NicoComment" )] +[assembly: AssemblyCopyright( "Copyright (C) 2007" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "93627cb9-8b0e-49ee-aa9c-149d8e3e1a3f" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってリビジョンおよびビルド番号を +// 既定値にすることができます: +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/NicoComment/makefile b/trunk/LipSync/NicoComment/makefile new file mode 100644 index 0000000..9cc7a9e --- /dev/null +++ b/trunk/LipSync/NicoComment/makefile @@ -0,0 +1,11 @@ +RM=rm +CP=cp + +NicoComment.dll: FConfig.cs FConfig.Designer.cs Form1.cs Form1.Designer.cs NicoComment.cs Program.cs \ + IPlugin.dll + gmcs -target:library -out:NicoComment.dll \ + -r:System.Windows.Forms,System.Drawing,IPlugin.dll \ + FConfig.cs FConfig.Designer.cs Form1.cs Form1.Designer.cs NicoComment.cs Program.cs + +clean: + $(RM) NicoComment.dll IPlugin.dll diff --git a/trunk/LipSync/VFlip/Properties/AssemblyInfo.cs b/trunk/LipSync/VFlip/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3b01d8b --- /dev/null +++ b/trunk/LipSync/VFlip/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "VFlip" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "Boare" )] +[assembly: AssemblyProduct( "VFlip" )] +[assembly: AssemblyCopyright( "Copyright (C) 2007" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントには +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "4614ec4b-a485-47a6-a7ce-8e5d4869896f" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってリビジョンおよびビルド番号を +// 既定値にすることができます: +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/lang2po/Program.cs b/trunk/LipSync/lang2po/Program.cs new file mode 100644 index 0000000..2563939 --- /dev/null +++ b/trunk/LipSync/lang2po/Program.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +using Boare.Lib.AppUtil; + +namespace Boare { + class lang2po { + static void Main( string[] args ) { + Console.WriteLine( "input source *.lang file name" ); + string name = Console.ReadLine(); + Console.WriteLine( "input result file name" ); + string result = Console.ReadLine(); + if ( File.Exists( result ) ) { + Console.WriteLine( "error; file \"" + result + "\" already exists." ); + return; + } + Messaging.AppendFromFile( "template.po" ); + Messaging.Language = "template"; + Dictionary dict = new Dictionary(); + using ( StreamReader sr = new StreamReader( name ) ) { + string line; + while ( (line = sr.ReadLine()) != null ) { + string[] spl = line.Split( "\t".ToCharArray() ); + if ( spl.Length >= 2 ) { + string id = spl[0]; + string item = spl[1]; + item = item.Replace( "\"", "\\\"" ); + dict.Add( id, item ); + } + } + } + using ( StreamWriter sw = new StreamWriter( result, false, Encoding.UTF8 ) ) { + sw.WriteLine( "msgid \"\"" ); + sw.WriteLine( "msgstr \"\"" ); + sw.WriteLine( "\"Project-Id-Version: \\n\"" ); + sw.WriteLine( "\"Report-Msgid-Bugs-To: \\n\"" ); + DateTime now = DateTime.Now; + DateTime utc = now.ToUniversalTime(); + DateTime local = now.ToLocalTime(); + TimeSpan ts = local.Subtract( utc ); + int minutes = (int)ts.TotalMinutes; + int absmin = Math.Abs( minutes ); + int hours = absmin / 60; + int mins = absmin - hours * 60; + string dt = (minutes > 0) ? "+" : "-"; + dt += hours.ToString( "00" ) + mins.ToString( "00" ); + sw.WriteLine( "\"POT-Creation-Date: " + local.Year + "-" + local.Month.ToString( "00" ) + "-" + local.Day.ToString( "00" ) + " " + local.Hour.ToString( "00" ) + ":" + local.Minute.ToString( "00" ) + dt + "\\n\"" ); + sw.WriteLine( "\"PO-Revision-Date: \\n\"" ); + sw.WriteLine( "\"Last-Translator: \\n\"" ); + sw.WriteLine( "\"Language-Team: \\n\"" ); + sw.WriteLine( "\"MIME-Version: 1.0\\n\"" ); + sw.WriteLine( "\"Content-Type: text/plain; charset=UTF-8\\n\"" ); + sw.WriteLine( "\"Content-Transfer-Encoding: 8bit\\n\"" ); + sw.WriteLine( "\"X-Poedit-Language: \\n\"" ); + sw.WriteLine( "\"X-Poedit-Country: \\n\"" ); + sw.WriteLine( "\"X-Poedit-SourceCharset: utf-8\\n\"" ); + sw.WriteLine( "\"X-Poedit-Basepath: .\\\\" + "\\n\"" ); + sw.WriteLine( "\"X-Poedit-KeywordsList: _\\n\"" ); + sw.WriteLine( "\"X-Poedit-SearchPath-0: Editor\\n\"" ); + sw.WriteLine( "\"X-Poedit-SearchPath-1: Common\\n\"" ); + sw.WriteLine( "\"X-Poedit-SearchPath-2: AviFile\\n\"" ); + string[] keys = Messaging.GetKeys( "template" ); + foreach ( string key in keys ) { + string oldid = Messaging.GetMessage( key ); + if ( dict.ContainsKey( oldid ) ) { + string item = dict[oldid]; + item = item.Replace( "\"", "\\\"" ); + string key2 = key.Replace( "\"", "\\\"" ); + sw.WriteLine( "msgid \"" + key2 + "\"" ); + sw.WriteLine( "msgstr \"" + item + "\"" ); + sw.WriteLine(); + } + } + } + } + } +} diff --git a/trunk/LipSync/lang2po/Properties/AssemblyInfo.cs b/trunk/LipSync/lang2po/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..c488382 --- /dev/null +++ b/trunk/LipSync/lang2po/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle( "lang2po" )] +[assembly: AssemblyDescription( "" )] +[assembly: AssemblyConfiguration( "" )] +[assembly: AssemblyCompany( "" )] +[assembly: AssemblyProduct( "lang2po" )] +[assembly: AssemblyCopyright( "Copyright © 2008" )] +[assembly: AssemblyTrademark( "" )] +[assembly: AssemblyCulture( "" )] + +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible( false )] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid( "8154a642-4ae5-4ca6-83f9-95df9878de3d" )] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion( "1.0.0.0" )] +[assembly: AssemblyFileVersion( "1.0.0.0" )] diff --git a/trunk/LipSync/lang2po/lang2po.csproj b/trunk/LipSync/lang2po/lang2po.csproj new file mode 100644 index 0000000..bdb42a1 --- /dev/null +++ b/trunk/LipSync/lang2po/lang2po.csproj @@ -0,0 +1,70 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {D60A11E0-8FFA-4CBC-A2F9-7365AFDF47A9} + Exe + Properties + lang2po + lang2po + v3.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + 3.5 + + + 3.5 + + + 3.5 + + + + + + + + + + + PreserveNewest + + + + + {0C58B068-272F-4390-A14F-3D72AFCF3DFB} + Boare.Lib.AppUtil + + + + + \ No newline at end of file diff --git a/trunk/LipSync/lang2po/template.po b/trunk/LipSync/lang2po/template.po new file mode 100644 index 0000000..2737499 --- /dev/null +++ b/trunk/LipSync/lang2po/template.po @@ -0,0 +1,1076 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2008-11-03 23:44+0900\n" +"PO-Revision-Date: \n" +"Last-Translator: kbinani \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: English\n" +"X-Poedit-Country: UNITED STATES\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Poedit-KeywordsList: _;gettext\n" +"X-Poedit-Basepath: .\\\n" +"X-Poedit-SearchPath-0: Editor\n" +"X-Poedit-SearchPath-1: Common\n" +"X-Poedit-SearchPath-2: AviFile\n" + +#: Editor/AviOutput.cs:111 +msgid "Directory" +msgstr "DIRECTORY" + +#: Editor/AviOutput.cs:111 +msgid "does not exist." +msgstr "DOES_NOT_EXIST" + +#: Editor/AviOutput.cs:112 +#: Editor/AviOutput.cs:137 +msgid "Error" +msgstr "ERROR" + +#: Editor/AviOutput.cs:122 +msgid "already exists." +msgstr "ALREADY_EXISTS" + +#: Editor/AviOutput.cs:122 +msgid "Do you want to replace it?" +msgstr "REPLACE_IT" + +#: Editor/AviOutput.cs:136 +msgid "Invalid value has been entered" +msgstr "INVALID_VALUE" + +#: Editor/AviOutput.cs:159 +msgid "Avi file(*.avi)|*.avi" +msgstr "FILTER_AVI" + +#: Editor/AviOutput.cs:159 +msgid "All Files(*.*)|*.*" +msgstr "FILTER_ALLFILES" + +#: Editor/AviOutput.designer.cs:302 +msgid "Cancel" +msgstr "CANCEL" + +#: Editor/AviOutput.designer.cs:303 +msgid "Save" +msgstr "SAVE" + +#: Editor/AviOutput.designer.cs:304 +msgid "file name" +msgstr "FILE_NAME" + +#: Editor/AviOutput.designer.cs:305 +msgid "Video" +msgstr "VIDEO" + +#: Editor/AviOutput.designer.cs:306 +msgid "Audio" +msgstr "AUDIO" + +#: Editor/AviOutput.designer.cs:307 +msgid "Convert to FLV" +msgstr "CONVERT_TO_FLV" + +#: Editor/AviOutput.designer.cs:308 +msgid "Merge wave to AVI" +msgstr "MERGE_WAVE_TO_AVI" + +#: Editor/AviOutput.designer.cs:309 +msgid "Delete intermediate file" +msgstr "DELETE_INTERMEDIATE" + +#: Editor/AviOutput.designer.cs:310 +msgid "Video Compression" +msgstr "VIDEO_COMPRESSION" + +#: Editor/AviOutput.designer.cs:311 +msgid "Specify output range" +msgstr "OUTPUT_RANGE" + +#: Editor/AviOutput.designer.cs:312 +msgid "Start" +msgstr "START" + +#: Editor/AviOutput.designer.cs:313 +msgid "End" +msgstr "END" + +#: Editor/DisplacementControl.designer.cs:187 +msgid "Edit motion curve" +msgstr "MOTION_CURVE" + +#: Editor/DisplacementControl.designer.cs:188 +msgid "Close" +msgstr "CLOSE" + +#: Editor/DisplacementControl.designer.cs:189 +msgid "File" +msgstr "FILE" + +#: Editor/DisplacementControl.designer.cs:190 +msgid "Redo" +msgstr "REDO" + +#: Editor/DisplacementControl.designer.cs:191 +msgid "Undo" +msgstr "UNDO" + +#: Editor/DisplacementControl.designer.cs:192 +msgid "Edit" +msgstr "EDIT" + +#: Editor/EditEntry.Designer.cs:207 +msgid "ON time (sec)" +msgstr "ON_TIME" + +#: Editor/EditEntry.Designer.cs:208 +msgid "OFF time (sec)" +msgstr "OFF_TIME" + +#: Editor/EditEntry.Designer.cs:210 +#: Editor/EnvConfiguration.Designer.cs:827 +msgid "OK" +msgstr "OK" + +#: Editor/EditEntry.Designer.cs:211 +msgid "Use this value" +msgstr "USE_THIS_VALUE" + +#: Editor/EditEntry.Designer.cs:212 +msgid "Expandable range of this entry" +msgstr "EXPANDABLE_RANGE" + +#: Editor/EditEntry.Designer.cs:213 +#: Editor/Form1.cs:1348 +msgid "Numeric entry" +msgstr "INPUT_NUMBER" + +#: Editor/EnvConfiguration.cs:250 +#: Editor/EnvConfiguration.cs:268 +msgid "Executable file(*.exe)|*.exe" +msgstr "FILTER_EXE" + +#: Editor/EnvConfiguration.Designer.cs:829 +msgid "Language" +msgstr "LANGUAGE" + +#: Editor/EnvConfiguration.Designer.cs:830 +#: Editor/Form1.designer.cs:1160 +msgid "Option" +msgstr "OPTION" + +#: Editor/EnvConfiguration.Designer.cs:832 +msgid "User Config" +msgstr "USER_CONFIG" + +#: Editor/EnvConfiguration.Designer.cs:833 +msgid "Appearance" +msgstr "APPEARANCE" + +#: Editor/EnvConfiguration.Designer.cs:834 +msgid "lip-sync Option" +msgstr "LIPSYNC_OPTION" + +#: Editor/EnvConfiguration.Designer.cs:835 +msgid "System" +msgstr "SYSTEM" + +#: Editor/EnvConfiguration.Designer.cs:837 +msgid "Title of timeline" +msgstr "TITLE_OF_TIMELINE" + +#: Editor/EnvConfiguration.Designer.cs:838 +msgid "VSQ Entry" +msgstr "VSQ_ENTRY" + +#: Editor/EnvConfiguration.Designer.cs:839 +msgid "Plugin Entry" +msgstr "PLUGIN_ENTRY" + +#: Editor/EnvConfiguration.Designer.cs:840 +msgid "Another Entry" +msgstr "ANOTHER_ENTRY" + +#: Editor/EnvConfiguration.Designer.cs:841 +msgid "Entry height (pixel)" +msgstr "ENTRY_HEIGHT" + +#: Editor/EnvConfiguration.Designer.cs:842 +#: Editor/EnvConfiguration.Designer.cs:843 +#: Editor/EnvConfiguration.Designer.cs:844 +#: Editor/EnvConfiguration.Designer.cs:845 +#: Editor/EnvConfiguration.Designer.cs:855 +msgid "Change" +msgstr "CHANGE" + +#: Editor/EnvConfiguration.Designer.cs:846 +msgid "Check phonetic symbol to configure detailed mouth shape control" +msgstr "CHECK_PHONETIC_SYMBOL" + +#: Editor/EnvConfiguration.Designer.cs:847 +msgid "Close mouth before pronunciation" +msgstr "CLOSED_MOUTH" + +#: Editor/EnvConfiguration.Designer.cs:848 +msgid "\"i\" shaped mouth before pronunciation" +msgstr "I_SHAPED_MOUTH" + +#: Editor/EnvConfiguration.Designer.cs:849 +msgid "\"u\" shaped mouth before pronunciation" +msgstr "U_SHAPED_MOUTH" + +#: Editor/EnvConfiguration.Designer.cs:850 +msgid "Color" +msgstr "COLOR" + +#: Editor/EnvConfiguration.Designer.cs:851 +msgid "Design" +msgstr "DESIGN" + +#: Editor/EnvConfiguration.Designer.cs:852 +msgid "Path of ffmpeg" +msgstr "PATH_OF_FFMPEG" + +#: Editor/EnvConfiguration.Designer.cs:853 +msgid "Path of mencoder" +msgstr "PATH_OF_MENCODER" + +#: Editor/EnvConfiguration.Designer.cs:854 +msgid "Font" +msgstr "FONT" + +#: Editor/EnvConfiguration.Designer.cs:856 +#: Editor/EnvConfiguration.Designer.cs:861 +msgid "Another settings" +msgstr "ANOTHER_CONFIG" + +#: Editor/EnvConfiguration.Designer.cs:857 +msgid "Close mouth when same vowels repeated" +msgstr "SERIAL_VOWEL" + +#: Editor/EnvConfiguration.Designer.cs:858 +msgid "Encoder/Decoder" +msgstr "ENCODER_DECODER" + +#: Editor/EnvConfiguration.Designer.cs:859 +msgid "Generate character automaticaly when importing vsq" +msgstr "GEN_CHARACTER_AUTOMATICALY" + +#: Editor/EnvConfiguration.Designer.cs:860 +msgid "Threshold silence length(sec)" +msgstr "COMBINE_THRESHOLD" + +#: Editor/EnvConfiguration.Designer.cs:862 +msgid "Use preview-enabled dialog in character selection" +msgstr "USE_PREVIEWABLE_DIALOG" + +#: Editor/EnvConfiguration.Designer.cs:863 +msgid "Reload language configurations" +msgstr "RELOAD_LANG_CONFIG" + +#: Editor/EnvConfiguration.Designer.cs:864 +msgid "Operation" +msgstr "OPERATION" + +#: Editor/EnvConfiguration.Designer.cs:865 +msgid "mouse wheel rate" +msgstr "MOUSE_WHEEL_RATE" + +#: Editor/Form1.cs:853 +msgid " has been changed. Do you wish to save changes to file?" +msgstr "SAVE_FILE" + +#: Editor/Form1.cs:855 +msgid "Do you wish to save changes to file?" +msgstr "SAVE_FILE_CREATE" + +#: Editor/Form1.cs:1206 +#: Editor/Form1.cs:2936 +#: Editor/Form1.cs:3859 +msgid "Video size configuration" +msgstr "SET_VIDEO_SIZE" + +#: Editor/Form1.cs:1215 +msgid "Read from VSQ file" +msgstr "READ_VSQ" + +#: Editor/Form1.cs:1219 +#: Editor/Form1.designer.cs:1143 +msgid "Edit character" +msgstr "EDIT_CHARACTER" + +#: Editor/Form1.cs:1222 +#: Editor/Form1.cs:1260 +#: Editor/Form1.cs:1280 +#: Editor/Form1.cs:1343 +#: Editor/Form1.cs:1366 +msgid "Preview image" +msgstr "PREVIEW_IMAGE" + +#: Editor/Form1.cs:1223 +#: Editor/Form1.cs:1292 +#: Editor/Form1.cs:1378 +#: Editor/Form1_EventHandler.cs:975 +msgid "Image placement" +msgstr "SET_IMAGE_POSITION" + +#: Editor/Form1.cs:1224 +#: Editor/Form1.cs:1296 +#: Editor/Form1.cs:1382 +#: Editor/Form1_EventHandler.cs:506 +msgid "Scale setting" +msgstr "SET_SCALE" + +#: Editor/Form1.cs:1226 +msgid "Generate wink" +msgstr "GENERATE_WINK" + +#: Editor/Form1.cs:1230 +#: Editor/Form1.cs:1459 +msgid "Delete" +msgstr "DELETE" + +#: Editor/Form1.cs:1233 +msgid "Add track" +msgstr "ADD_TRACK" + +#: Editor/Form1.cs:1247 +msgid "Generate Lipsync from this track" +msgstr "GEN_LIPSYNC_FROM_THIS" + +#: Editor/Form1.cs:1256 +#: Editor/Form1.cs:1269 +#: Editor/Form1.cs:1308 +msgid "Note ON from here" +msgstr "NOTE_ON" + +#: Editor/Form1.cs:1275 +#: Editor/Form1.cs:1361 +msgid "Set image" +msgstr "SET_IMAGE" + +#: Editor/Form1.cs:1284 +#: Editor/Form1.cs:1370 +msgid "Change image" +msgstr "CHANGE_IMAGE" + +#: Editor/Form1.cs:1289 +#: Editor/Form1.cs:1375 +msgid "Image" +msgstr "IMAGE" + +#: Editor/Form1.cs:1320 +#: Editor/Form1.cs:1435 +msgid "Paste" +msgstr "PASTE" + +#: Editor/Form1.cs:1338 +msgid "Note OFF" +msgstr "NOTE_OFF" + +#: Editor/Form1.cs:1351 +msgid "Expand" +msgstr "EXPAND" + +#: Editor/Form1.cs:1391 +msgid "Plugin config. of this entry" +msgstr "THIS_PLUGIN_CONFIG" + +#: Editor/Form1.cs:1398 +#: Editor/Form1.cs:1421 +msgid "Copy" +msgstr "COPY" + +#: Editor/Form1.cs:1402 +msgid "Cut" +msgstr "CUT" + +#: Editor/Form1.cs:1406 +msgid "Split entry" +msgstr "SPLIT" + +#: Editor/Form1.cs:1418 +msgid "Timeline" +msgstr "TIMELINE" + +#: Editor/Form1.cs:1428 +msgid "Copy On/Off inverted" +msgstr "INVERSE_ON_OFF" + +#: Editor/Form1.cs:1442 +msgid "Import from TEXT" +msgstr "IMPORT_FROM_TEXT" + +#: Editor/Form1.cs:1446 +msgid "Export to TEXT" +msgstr "EXPORT_TO_TEXT" + +#: Editor/Form1.cs:1464 +msgid "Delete entries" +msgstr "DELETE_ENTRIES" + +#: Editor/Form1.cs:1471 +msgid "Shift this time-line" +msgstr "SHIFT_THIS_TIMELINE" + +#: Editor/Form1.cs:1957 +#: Editor/Form1.cs:1997 +#: Editor/Form1.cs:2707 +msgid "VSQ Tracks" +msgstr "VSQ_TRACK" + +#: Editor/Form1.cs:1969 +msgid "Character" +msgstr "CHARACTER" + +#: Editor/Form1.cs:1977 +#: Editor/Form1.cs:2709 +#: Editor/Form1.cs:3305 +msgid "Another images" +msgstr "ANOTHER_IMAGE" + +#: Editor/Form1.cs:1984 +#: Editor/Form1.cs:2681 +msgid "Plugin" +msgstr "PLUGIN" + +#: Editor/Form1.cs:2936 +msgid "Input video length in second" +msgstr "INPUT_VIDEO_LENGTH" + +#: Editor/Form1.cs:2964 +#: Editor/Form1.designer.cs:1152 +#: Editor/Form1_EventHandler.cs:78 +msgid "Shift all time-tables" +msgstr "SHIFT_TIME_TABLE" + +#: Editor/Form1.cs:2964 +#: Editor/Form1_EventHandler.cs:78 +msgid "Input shift time in second (you can enter minus value)" +msgstr "INPUT_SHIFT_TIME" + +#: Editor/Form1.cs:3223 +#: Editor/Form1.cs:3490 +msgid "This operation will overwrite all exisiting time-tables, and can NOT undo. Would you like to continue?" +msgstr "WARN_DELETE_ALL_TRACKS" + +#: Editor/Form1.cs:3223 +msgid "( In case you want to append new track, please right-click [VSQ Tracks] to select [Read from VSQ file]. )" +msgstr "INCASE_APPEND_TRACK" + +#: Editor/Form1.cs:3224 +#: Editor/Form1.cs:3491 +#: Editor/Form1_EventHandler.cs:548 +#: Editor/Form1_EventHandler.cs:925 +#: Editor/Form1_EventHandler.cs:1090 +#: Editor/Form1_EventHandler.cs:1100 +msgid "Confirmation" +msgstr "CONFIRMATION" + +#: Editor/Form1.cs:3239 +#: Editor/Form1.designer.cs:1187 +#: Editor/Form1_EventHandler.cs:898 +msgid "VOCALOID2 Sequence File(*.vsq)|*.vsq" +msgstr "FILTER_VSQ" + +#: Editor/Form1.cs:3509 +#: Editor/Form1.cs:4408 +#: Editor/Form1.designer.cs:1169 +#: Editor/Form1.designer.cs:1224 +#: Editor/Form1_Preview.cs:353 +msgid "Play" +msgstr "PLAY" + +#: Editor/Form1.cs:3514 +msgid "File not found" +msgstr "FILE_NOT_FOUND" + +#: Editor/Form1.cs:3538 +#: Editor/Form1.cs:3569 +#: Editor/Form1.cs:3583 +msgid "Extension must be *.lse" +msgstr "INVALID_EXTENSION" + +#: Editor/Form1.cs:3650 +msgid "Failed file saving" +msgstr "FAILED_FILE_SAVING" + +#: Editor/Form1.cs:3748 +msgid "Failed file reading" +msgstr "FAILED_FILE_READING" + +#: Editor/Form1.cs:3859 +msgid "Width" +msgstr "WIDTH" + +#: Editor/Form1.cs:3859 +msgid "Height" +msgstr "HEIGHT" + +#: Editor/Form1.cs:3992 +msgid "Expand all" +msgstr "EXPAND_ALL" + +#: Editor/Form1.cs:3993 +msgid "Fold all" +msgstr "FOLD_ALL" + +#: Editor/Form1.cs:4028 +msgid "(no name)" +msgstr "NO_NAME" + +#: Editor/Form1.cs:4048 +#: Editor/Form1.designer.cs:1164 +msgid "Disable preview" +msgstr "DISABLE_PREVIEW" + +#: Editor/Form1.cs:4054 +#: Editor/Form1.designer.cs:1162 +msgid "Enable preview" +msgstr "ENABLE_PREVIEW" + +#: Editor/Form1.cs:4168 +#: Editor/Form1.designer.cs:1183 +msgid "Hide object list" +msgstr "DISABLE_PROPERTY" + +#: Editor/Form1.cs:4174 +#: Editor/Form1.designer.cs:1181 +msgid "Show object list" +msgstr "ENABLE_PROPERTY" + +#: Editor/Form1.cs:4412 +msgid "Audio file(*.mp3;*.wav)|*.mp3;*.wav" +msgstr "FILTER_AUDIO" + +#: Editor/Form1.cs:4430 +#: Editor/Form1.designer.cs:1173 +msgid "Go to specified frame" +msgstr "GOTO_SPECIFIED_FRAME" + +#: Editor/Form1.cs:4430 +msgid "please input frame index" +msgstr "REQUIRE_FRAME_INDEX" + +#: Editor/Form1.cs:4446 +msgid "invalid frame index" +msgstr "INVALID_FRAME_INDEX" + +#: Editor/Form1.designer.cs:1129 +msgid "Open" +msgstr "OPEN" + +#: Editor/Form1.designer.cs:1131 +msgid "Save As" +msgstr "SAVE_AS" + +#: Editor/Form1.designer.cs:1132 +msgid "Import" +msgstr "IMPORT2" + +# msgid "Import" +# msgstr "IMPORT" +#: Editor/Form1.designer.cs:1133 +msgid "from RipSync data" +msgstr "RIPSYNC_DATA" + +#: Editor/Form1.designer.cs:1134 +msgid "Open VSQ file" +msgstr "OPEN_VSQ" + +#: Editor/Form1.designer.cs:1135 +msgid "Exit" +msgstr "EXIT" + +#: Editor/Form1.designer.cs:1139 +msgid "Help" +msgstr "HELP" + +#: Editor/Form1.designer.cs:1140 +msgid "Plugin information" +msgstr "PLUGIN_INFO" + +#: Editor/Form1.designer.cs:1141 +msgid "About LipSync" +msgstr "VERSION_INFO" + +#: Editor/Form1.designer.cs:1142 +msgid "Debug" +msgstr "DEBUG" + +#: Editor/Form1.designer.cs:1144 +msgid "Flip images horizontaly" +msgstr "FLIP_HORIZONTALY" + +#: Editor/Form1.designer.cs:1148 +msgid "Video size" +msgstr "VIDEO_SIZE" + +#: Editor/Form1.designer.cs:1149 +msgid "Frame rate" +msgstr "FRAME_RATE" + +#: Editor/Form1.designer.cs:1150 +msgid "Z order" +msgstr "Z_ORDER" + +#: Editor/Form1.designer.cs:1151 +msgid "Video length" +msgstr "CHANGE_VIDEO_LENGTH" + +#: Editor/Form1.designer.cs:1153 +msgid "View" +msgstr "VIEW" + +#: Editor/Form1.designer.cs:1154 +msgid "Zoom" +msgstr "ZOOM" + +#: Editor/Form1.designer.cs:1155 +msgid "Mooz" +msgstr "MOOZ" + +#: Editor/Form1.designer.cs:1156 +msgid "Set default scale" +msgstr "DEFAULT_SCALE" + +#: Editor/Form1.designer.cs:1157 +#: Editor/Form1.designer.cs:1219 +msgid "Move to Top" +msgstr "MOVE_TO_TOP" + +#: Editor/Form1.designer.cs:1158 +#: Editor/Form1.designer.cs:1218 +msgid "Move to End" +msgstr "MOVE_TO_END" + +#: Editor/Form1.designer.cs:1159 +msgid "Tool" +msgstr "TOOL" + +#: Editor/Form1.designer.cs:1166 +msgid "Plugin config" +msgstr "PLUGIN_CONFIG" + +#: Editor/Form1.designer.cs:1167 +msgid "Sync with Time table" +msgstr "SYNC_WITH_TIMETABLE" + +#: Editor/Form1.designer.cs:1168 +msgid "Add empty character" +msgstr "ADD_EMPTY_CHARACTER" + +#: Editor/Form1.designer.cs:1169 +#: Editor/Form1.designer.cs:1224 +#: Editor/Form1_Preview.cs:296 +msgid "Pause" +msgstr "PAUSE" + +#: Editor/Form1.designer.cs:1171 +msgid "Generate AVI" +msgstr "GENERATE_AVI" + +#: Editor/Form1.designer.cs:1172 +msgid "Chose sound file" +msgstr "CHOSE_SOUND_FILE" + +#: Editor/Form1.designer.cs:1174 +msgid "Stop writing avi" +msgstr "STOP_WRITING_AVI" + +#: Editor/Form1.designer.cs:1175 +msgid "Background color" +msgstr "BGCOLOR" + +#: Editor/Form1.designer.cs:1177 +msgid "Generate raw AVI" +msgstr "NON_COMPRESSED_AVI" + +#: Editor/Form1.designer.cs:1178 +msgid "Export" +msgstr "EXPORT" + +#: Editor/Form1.designer.cs:1179 +msgid "script for H@TWUNEBENCH" +msgstr "HATWUNE" + +#: Editor/Form1.designer.cs:1185 +msgid "Bug report" +msgstr "BUG_REPORT" + +#: Editor/Form1.designer.cs:1193 +msgid "Image Files(*.bmp,*.png,*.jpg,*.jpeg)|*.bmp;*.png;*.jpg;*.jpeg" +msgstr "FILTER_IMAGE" + +#: Editor/Form1.designer.cs:1202 +#: Editor/Form1.designer.cs:1209 +msgid "LipSync data file(*.lse)|*.lse" +msgstr "FILTER_LSE" + +#: Editor/Form1.designer.cs:1216 +msgid "Real time \"lipsync\"" +msgstr "REALTIME" + +#: Editor/Form1.designer.cs:1217 +msgid "Repeat play" +msgstr "REPEAT_PLAY" + +#: Editor/Form1.designer.cs:1220 +msgid "End repeat at" +msgstr "SET_REPEAT_END" + +#: Editor/Form1.designer.cs:1221 +msgid "Start repeat from" +msgstr "SET_REPEAT_START" + +#: Editor/Form1.designer.cs:1222 +msgid "Reset repeat region" +msgstr "RESET_REPEAT_REGION" + +#: Editor/Form1.designer.cs:1225 +msgid "Show VSQ tracks allways" +msgstr "SHOW_VSQ_ALLWAYS" + +#: Editor/Form1.designer.cs:1226 +msgid "Show bars" +msgstr "SHOW_BARS" + +#: Editor/Form1.designer.cs:1227 +msgid "Quantize" +msgstr "QUANTIZE" + +#: Editor/Form1.designer.cs:1228 +msgid "off" +msgstr "OFF" + +#: Editor/Form1.designer.cs:1229 +msgid "triplet" +msgstr "TRIPLET" + +#: Editor/Form1.designer.cs:1231 +#: Editor/FormObjectList.cs:60 +#: Editor/FormObjectList.Designer.cs:62 +msgid "List of object" +msgstr "LIST_OF_OBJECTS" + +#: Editor/Form1.designer.cs:1232 +msgid "Property" +msgstr "PROPERTY" + +#: Editor/Form1.designer.cs:1246 +msgid "Series bitmap" +msgstr "SERIES_BITMAP" + +#: Editor/Form1_AviOutput.cs:203 +msgid "insertion of wav file has failed" +msgstr "WAV_ADDITION_FAILED" + +#: Editor/Form1_AviOutput.cs:262 +msgid "" +"Initialization of video compression failed.\n" +"This video codec may require image width in multiples of certain number." +msgstr "AVI_INITIALIZATION_FAILED" + +#: Editor/Form1_AviOutput.cs:293 +msgid "FLV Progress" +msgstr "FLV_PROGRESS" + +#: Editor/Form1_AviOutput.cs:332 +msgid "AVI Progress" +msgstr "PROGRESS" + +#: Editor/Form1_EventHandler.cs:144 +#: Editor/Form1_EventHandler.cs:210 +msgid "Text file(*.txt)|*.txt" +msgstr "FILTER_TEXT" + +#: Editor/Form1_EventHandler.cs:506 +msgid "Please enter scale. (If entered value is minus, character or image will be flipped horizontally.)" +msgstr "ENTER_SCALE" + +#: Editor/Form1_EventHandler.cs:548 +msgid "" +"...clearing entries of selected time-table.\n" +"Would you like to continue?" +msgstr "CLEAR_ENTRIES" + +#: Editor/Form1_EventHandler.cs:924 +msgid "This operation will overwrite all exisiting tempo and time-signal information, and can NOT undo. Would you like to continue?" +msgstr "WARN_OVERWRITE_TIMESIG" + +#: Editor/Form1_EventHandler.cs:1090 +msgid "" +"...deleting selected character.\n" +"Would you like to continue?" +msgstr "DELETING_CHARACTER" + +#: Editor/Form1_EventHandler.cs:1100 +msgid "" +"...deleting selected track.\n" +"Would you like to continue?" +msgstr "DELETING_TRACK" + +#: Editor/FormSetFrameRate.cs:167 +msgid "failed getting frame rate" +msgstr "FAILED_GETTING_FRAME_RATE" + +#: Editor/FormSetFrameRate.Designer.cs:186 +msgid "detail" +msgstr "DETAIL" + +#: Editor/FormSetFrameRate.Designer.cs:187 +msgid "configure frame rate" +msgstr "CONFIG_FRAME_RATE" + +#: Editor/FormSetFrameRate.Designer.cs:191 +msgid "denominator of frame rate" +msgstr "DENOMINATOR_OF_FRAME_RATE" + +#: Editor/FormSetFrameRate.Designer.cs:192 +msgid "numerator of frame rate" +msgstr "NUMERATOR_OF_FRAME_RATE" + +#: Editor/FormSetFrameRate.Designer.cs:194 +msgid "import frame rate from AVI file" +msgstr "TTIP_IMPORT_FRAME_RATE_FROM_AVI" + +#: Editor/GenerateCharacter.cs:121 +#: Editor/GenerateCharacter.cs:146 +#: Editor/GenerateCharacter.designer.cs:614 +#: Editor/GenerateCharacter.designer.cs:619 +msgid "LipSync Character Config(*.lsc)|*.lsc" +msgstr "FILTER_CHARACTER" + +#: Editor/GenerateCharacter.cs:147 +#: Editor/GenerateCharacter.cs:883 +msgid "LipSync Character Config(content.xml)|content.xml" +msgstr "FILTER_CHARACTER_XML" + +#: Editor/GenerateCharacter.cs:516 +msgid "NOT editable" +msgstr "NOT_EDITABLE" + +#: Editor/GenerateCharacter.cs:640 +msgid "Title of image" +msgstr "TITLE_OF_IMAGE" + +#: Editor/GenerateCharacter.cs:641 +msgid "Input the title of image" +msgstr "INPUT_IMAGE_TITLE" + +#: Editor/GenerateCharacter.cs:657 +msgid "This image title has been already registered" +msgstr "TITLE_ALREADY_EXIST" + +#: Editor/GenerateCharacter.cs:813 +#: Editor/GenerateCharacter.designer.cs:602 +#: Editor/GenerateCharacter.designer.cs:638 +msgid "Change title" +msgstr "CHANGE_TITLE" + +#: Editor/GenerateCharacter.cs:814 +msgid "Input new title" +msgstr "INPUT_NEW_TITLE" + +#: Editor/GenerateCharacter.designer.cs:586 +#: Editor/GenerateCharacter.designer.cs:589 +msgid "Title" +msgstr "TITLE" + +#: Editor/GenerateCharacter.designer.cs:587 +#: Editor/GenerateCharacter.designer.cs:588 +msgid "Tag" +msgstr "TAG" + +#: Editor/GenerateCharacter.designer.cs:590 +#: Editor/GenerateCharacter.designer.cs:642 +msgid "Up" +msgstr "UP" + +#: Editor/GenerateCharacter.designer.cs:591 +#: Editor/GenerateCharacter.designer.cs:637 +msgid "Down" +msgstr "DOWN" + +#: Editor/GenerateCharacter.designer.cs:592 +#: Editor/GenerateCharacter.designer.cs:635 +msgid "Add" +msgstr "ADD" + +#: Editor/GenerateCharacter.designer.cs:595 +msgid "Select image file" +msgstr "SELECT_IMAGE_FILE" + +#: Editor/GenerateCharacter.designer.cs:596 +#: Editor/GenerateCharacter.designer.cs:641 +msgid "Select transparent color" +msgstr "SELECT_TRANSPARENT_COLOR" + +#: Editor/GenerateCharacter.designer.cs:600 +msgid "Character name" +msgstr "CHARACTER_NAME" + +#: Editor/GenerateCharacter.designer.cs:604 +msgid "Selected image" +msgstr "SELECTED_IMAGE" + +#: Editor/GenerateCharacter.designer.cs:607 +msgid "Open *.rsi" +msgstr "OPEN_RSI" + +#: Editor/GenerateCharacter.designer.cs:610 +msgid "Save as *.rsi" +msgstr "SAVE_AS_XML" + +#: Editor/GenerateCharacter.designer.cs:611 +msgid "Save as XML" +msgstr "SAVE_AS_XML" + +#: Editor/GenerateCharacter.designer.cs:623 +#: Editor/GenerateCharacter.designer.cs:639 +msgid "Reset image" +msgstr "RESET_IMAGE" + +#: Editor/GenerateCharacter.designer.cs:625 +#: Editor/GenerateCharacter.designer.cs:630 +msgid "RipSync Image(*.rsi)|*.rsi" +msgstr "FILTER_RSI" + +#: Editor/PasteModeDialog.Designer.cs:112 +msgid "Specify paste mode" +msgstr "SPECIFY_PASTE_MODE" + +#: Editor/PasteModeDialog.Designer.cs:114 +msgid "Interrupt" +msgstr "INTERRUPT" + +#: Editor/PasteModeDialog.Designer.cs:115 +msgid "Overwrite" +msgstr "OVERWRITE" + +#: Editor/Previewer.Designer.cs:297 +msgid "Stop" +msgstr "STOP" + +#: Editor/Previewer.Designer.cs:298 +msgid "Stretch image" +msgstr "STRETCH_IMAGE" + +#: Editor/Previewer.Designer.cs:299 +msgid "Specified size" +msgstr "SPECIFIED_SIZE" + +#: Editor/Property.Designer.cs:241 +msgid "Add telop" +msgstr "ADD_TELOP" + +#: Editor/Property.Designer.cs:242 +msgid "Delte telop" +msgstr "DELETE_TELOP" + +#: Editor/SelectCharacter.designer.cs:219 +msgid "Custom" +msgstr "CUSTOM" + +#: Editor/SelectCharacter.designer.cs:220 +#: Editor/SelectCharacter.designer.cs:224 +#: Editor/SelectCharacter.designer.cs:225 +msgid "Built-in" +msgstr "BUILT_IN" + +#: Editor/SelectCharacter.designer.cs:221 +msgid "Select character to generate lip-sync" +msgstr "SELECT_CHARACTER" + +#: Editor/SelectCharacter.designer.cs:226 +msgid "Character selection" +msgstr "CHARACTER_SELECTION" + +#: Editor/TrackSelecter.designer.cs:141 +msgid "Select track" +msgstr "SELECT_TRACK" + +#: Editor/TrackSelecter.designer.cs:142 +msgid "import tempo and time-signal information" +msgstr "IMPORT_TEMPO_AND_TIMESIG" + +#: Editor/VersionInfoEx.cs:191 +#: Editor/VersionInfoEx.Designer.cs:118 +msgid "credit" +msgstr "CREDIT" + +#: Editor/Winker.Designer.cs:261 +msgid "Wink interval (sec)" +msgstr "WINK_INTERVAL" + +#: Editor/Winker.Designer.cs:262 +msgid "Randomize" +msgstr "RANDOMIZE" + +#: Editor/Winker.Designer.cs:263 +msgid "Closed Eye" +msgstr "CLOSED_EYE" + +#: Editor/Winker.Designer.cs:264 +msgid "In-between Image" +msgstr "IN_BETWEEN_IMAGE" + +#: Editor/Winker.Designer.cs:265 +msgid "Eye-closing frames" +msgstr "EYE_CLOSING_FRAME" + +#: Editor/Winker.Designer.cs:268 +msgid "Limit start time" +msgstr "START_TIME_LIMITATION" + +#: Editor/Winker.Designer.cs:269 +msgid "Limit end time" +msgstr "END_TIME_LIMITATION" + +#: Editor/ZOrder.Designer.cs:156 +msgid "Select target item, and push [Up] or [Down] button" +msgstr "SELECT_TARGET_ITEM" + +#: Editor/RipSync/RsiWriter.cs:208 +msgid "Image directory already exists. Would you like to overwrite them?" +msgstr "WARN_EXIST_SAME_FOLDER" + +#: Editor/RipSync/RsiWriter.cs:209 +msgid "warning" +msgstr "WARNING" + +#~ msgid "Save as *.RSI" +#~ msgstr "SAVE_AS_RSI" +#~ msgid "Copy time-line" +#~ msgstr "COPY_TIME_LINE" +#~ msgid "Paste time-line" +#~ msgstr "PASTE_TIME_LINE" +#~ msgid "Window" +#~ msgstr "WINDOW" +#~ msgid "Show preview" +#~ msgstr "SHOW_PREVIEW" +#~ msgid "Go to preview" +#~ msgstr "GOTO_PREVIEW" +#~ msgid "select configuration item from the list box below" +#~ msgstr "SELECT_CONFIG_TARGET_BELOW" +#~ msgid "" +#~ "AVI file size will exceed 2Gbyte.\n" +#~ "Do you wish to continue?" +#~ msgstr "OVER_2GB" +#~ msgid "Input frame rate" +#~ msgstr "INPUT_FRAME_RATE" +#~ msgid "Generate telop from VSQ" +#~ msgstr "GENERATE_TELOP_FROM_VSQ" +#~ msgid "" +#~ "Image title can't be set to \"base\", \"a\", \"aa\", \"i\", \"u\", \"e\", " +#~ "\"o\", \"xo\", \"nn\"" +#~ msgstr "INVALID_IMAGE_TITLE" +#~ msgid "Object name" +#~ msgstr "OBJECT_NAME" +#~ msgid "(Non-compressed)" +#~ msgstr "RAW" + diff --git a/trunk/LipSync/makefile b/trunk/LipSync/makefile new file mode 100644 index 0000000..9def7aa --- /dev/null +++ b/trunk/LipSync/makefile @@ -0,0 +1,64 @@ +CP=cp +RM=rm + +all: IPlugin/IPlugin.dll ../Boare.Lib.Vsq/Boare.Lib.Vsq.dll ../Boare.Lib.Media/Boare.Lib.Media.dll \ + ../Boare.Lib.AppUtil/Boare.Lib.AppUtil.dll Background/Background.dll \ + NicoComment/NicoComment.dll VFlip/VFlip.dll ../Boare.Lib.Swf/Boare.Lib.Swf.dll ../bocoree/bocoree.dll + $(CP) IPlugin/IPlugin.dll LipSync/IPlugin.dll + $(CP) ../Boare.Lib.Vsq/Boare.Lib.Vsq.dll LipSync/Boare.Lib.Vsq.dll + $(CP) ../Boare.Lib.Media/Boare.Lib.Media.dll LipSync/Boare.Lib.Media.dll + $(CP) ../Boare.Lib.AppUtil/Boare.Lib.AppUtil.dll LipSync/Boare.Lib.AppUtil.dll + $(CP) Background/Background.dll LipSync/Background.dll + $(CP) NicoComment/NicoComment.dll LipSync/NicoComment.dll + $(CP) VFlip/VFlip.dll LipSync/VFlip.dll + $(CP) ../Boare.Lib.Swf/Boare.Lib.Swf.dll LipSync/Boare.Lib.Swf.dll + $(CP) ../bocoree/bocoree.dll LipSync/bocoree.dll + cd LipSync && $(MAKE) CP=$(CP) + +../bocoree/bocoree.dll: + cd ../bocoree && $(MAKE) + +../Boare.Lib.Swf/Boare.Lib.Swf.dll: + cd ../Boare.Lib.Swf && $(MAKE) + +VFlip/VFlip.dll: VFlip/IPlugin.dll + cd VFlip && $(MAKE) + +VFlip/IPlugin.dll: IPlugin/IPlugin.dll + cp IPlugin/IPlugin.dll VFlip/IPlugin.dll + +NicoComment/NicoComment.dll: NicoComment/IPlugin.dll + cd NicoComment && $(MAKE) + +NicoComment/IPlugin.dll: IPlugin/IPlugin.dll + cp IPlugin/IPlugin.dll NicoComment/IPlugin.dll + +Background/Background.dll: Background/IPlugin.dll + cd Background && $(MAKE) + +Background/IPlugin.dll: IPlugin/IPlugin.dll + cp IPlugin/IPlugin.dll Background/IPlugin.dll + +IPlugin/IPlugin.dll: + cd IPlugin && $(MAKE) + +../Boare.Lib.Vsq/Boare.Lib.Vsq.dll: + cd ../Boare.Lib.Vsq && $(MAKE) + +../Boare.Lib.Media/Boare.Lib.Media.dll: + cd ../Boare.Lib.Media && $(MAKE) + +../Boare.Lib.AppUtil/Boare.Lib.AppUtil.dll: + cd ../Boare.Lib.AppUtil && $(MAKE) + +clean: + cd LipSync && $(MAKE) RM=$(RM) clean + cd IPlugin && $(MAKE) RM=$(RM) clean + cd ../Boare.Lib.Vsq && $(MAKE) RM=$(RM) clean + cd ../Boare.Lib.Media && $(MAKE) RM=$(RM) clean + cd ../Boare.Lib.AppUtil && $(MAKE) RM=$(RM) clean + cd Background && $(MAKE) RM=$(RM) clean + cd NicoComment && $(MAKE) RM=$(RM) clean + cd VFlip && $(MAKE) RM=$(RM) clean + cd ../Boare.Lib.Swf && $(MAKE) RM=$(RM) clean + cd ../bocoree && $(MAKE) RM=$(RM) clean diff --git a/trunk/bocoree/Properties/AssemblyInfo.cs b/trunk/bocoree/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d859253 --- /dev/null +++ b/trunk/bocoree/Properties/AssemblyInfo.cs @@ -0,0 +1,25 @@ +/* + * AssemblyInfo.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +[assembly: System.Reflection.AssemblyTitle( "bocoree" )] +[assembly: System.Reflection.AssemblyDescription( "" )] +[assembly: System.Reflection.AssemblyConfiguration( "" )] +[assembly: System.Reflection.AssemblyCompany( "Boare" )] +[assembly: System.Reflection.AssemblyProduct( "bocoree" )] +[assembly: System.Reflection.AssemblyCopyright( "Copyright © 2008-2009" )] +[assembly: System.Reflection.AssemblyTrademark( "" )] +[assembly: System.Reflection.AssemblyCulture( "" )] +[assembly: System.Runtime.InteropServices.ComVisible( false )] +[assembly: System.Runtime.InteropServices.Guid( "9ea2c6a6-558e-4c38-9961-096e964d085e" )] +[assembly: System.Reflection.AssemblyVersion( "1.0.0.0" )] +[assembly: System.Reflection.AssemblyFileVersion( "1.0.0" )] diff --git a/trunk/bocoree/bocoree.csproj b/trunk/bocoree/bocoree.csproj new file mode 100644 index 0000000..971556f --- /dev/null +++ b/trunk/bocoree/bocoree.csproj @@ -0,0 +1,75 @@ + + + + Debug + AnyCPU + 9.0.21022 + 2.0 + {C8AAE632-9C6C-4372-8175-811528A66742} + Library + Properties + bocoree + bocoree + v2.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + x86 + bin\x86\Debug\ + true + DEBUG + bin\x86\Debug\bocoree.XML + + + x86 + bin\x86\Release\ + true + bin\x86\Release\bocoree.XML + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/trunk/bocoree/cp932.cs b/trunk/bocoree/cp932.cs new file mode 100644 index 0000000..7566113 --- /dev/null +++ b/trunk/bocoree/cp932.cs @@ -0,0 +1,9716 @@ +/* + * cp932.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of bocoree + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +#if !__cp932__ +#define __cp932__ +#if __cplusplus +//bool bocoree::cp932::m_initialized = false; +#else +using System; +using System.Text; +using System.Collections.Generic; +using System.IO; +#endif + +namespace bocoree { + +#if __cplusplus + class cp932 { +#else + public class cp932 { +#endif + + +#if __cplusplus + const static int _LEN_DICT = 9484; + static int _DICT_SRC[_LEN_DICT][2]; + static void init_cor(){ + int n[_LEN_DICT][2] = { +#else + private static readonly Dictionary _DICT = new Dictionary() { +#endif + { 0, 0 }, + { 1, 1 }, + { 2, 2 }, + { 3, 3 }, + { 4, 4 }, + { 5, 5 }, + { 6, 6 }, + { 7, 7 }, + { 8, 8 }, + { 9, 9 }, + { 10, 10 }, + { 11, 11 }, + { 12, 12 }, + { 13, 13 }, + { 14, 14 }, + { 15, 15 }, + { 16, 16 }, + { 17, 17 }, + { 18, 18 }, + { 19, 19 }, + { 20, 20 }, + { 21, 21 }, + { 22, 22 }, + { 23, 23 }, + { 24, 24 }, + { 25, 25 }, + { 26, 26 }, + { 27, 27 }, + { 28, 28 }, + { 29, 29 }, + { 30, 30 }, + { 31, 31 }, + { 32, 32 }, + { 33, 33 }, + { 34, 34 }, + { 35, 35 }, + { 36, 36 }, + { 37, 37 }, + { 38, 38 }, + { 39, 39 }, + { 40, 40 }, + { 41, 41 }, + { 42, 42 }, + { 43, 43 }, + { 44, 44 }, + { 45, 45 }, + { 46, 46 }, + { 47, 47 }, + { 48, 48 }, + { 49, 49 }, + { 50, 50 }, + { 51, 51 }, + { 52, 52 }, + { 53, 53 }, + { 54, 54 }, + { 55, 55 }, + { 56, 56 }, + { 57, 57 }, + { 58, 58 }, + { 59, 59 }, + { 60, 60 }, + { 61, 61 }, + { 62, 62 }, + { 64, 64 }, + { 65, 65 }, + { 66, 66 }, + { 67, 67 }, + { 68, 68 }, + { 69, 69 }, + { 70, 70 }, + { 71, 71 }, + { 72, 72 }, + { 73, 73 }, + { 74, 74 }, + { 75, 75 }, + { 76, 76 }, + { 77, 77 }, + { 78, 78 }, + { 79, 79 }, + { 80, 80 }, + { 81, 81 }, + { 82, 82 }, + { 83, 83 }, + { 84, 84 }, + { 85, 85 }, + { 86, 86 }, + { 87, 87 }, + { 88, 88 }, + { 89, 89 }, + { 90, 90 }, + { 91, 91 }, + { 92, 92 }, + { 93, 93 }, + { 94, 94 }, + { 95, 95 }, + { 96, 96 }, + { 97, 97 }, + { 98, 98 }, + { 99, 99 }, + { 100, 100 }, + { 101, 101 }, + { 102, 102 }, + { 103, 103 }, + { 104, 104 }, + { 105, 105 }, + { 106, 106 }, + { 107, 107 }, + { 108, 108 }, + { 109, 109 }, + { 110, 110 }, + { 111, 111 }, + { 112, 112 }, + { 113, 113 }, + { 114, 114 }, + { 115, 115 }, + { 116, 116 }, + { 117, 117 }, + { 118, 118 }, + { 119, 119 }, + { 120, 120 }, + { 121, 121 }, + { 122, 122 }, + { 123, 123 }, + { 124, 124 }, + { 125, 125 }, + { 126, 126 }, + { 127, 127 }, + { 128, 128 }, + { 161, 33 }, + { 162, 33169 }, + { 163, 33170 }, + { 165, 92 }, + { 166, 124 }, + { 167, 33176 }, + { 168, 33102 }, + { 169, 99 }, + { 170, 97 }, + { 171, 33249 }, + { 172, 33226 }, + { 173, 45 }, + { 174, 82 }, + { 175, 33104 }, + { 176, 33163 }, + { 177, 33149 }, + { 178, 50 }, + { 179, 51 }, + { 180, 33100 }, + { 181, 33738 }, + { 182, 33271 }, + { 183, 33093 }, + { 184, 33091 }, + { 185, 49 }, + { 186, 111 }, + { 187, 33250 }, + { 192, 65 }, + { 193, 65 }, + { 194, 65 }, + { 195, 65 }, + { 196, 65 }, + { 197, 65 }, + { 198, 65 }, + { 199, 67 }, + { 200, 69 }, + { 201, 69 }, + { 202, 69 }, + { 203, 69 }, + { 204, 73 }, + { 205, 73 }, + { 206, 73 }, + { 207, 73 }, + { 208, 68 }, + { 209, 78 }, + { 210, 79 }, + { 211, 79 }, + { 212, 79 }, + { 213, 79 }, + { 214, 79 }, + { 215, 33150 }, + { 216, 79 }, + { 217, 85 }, + { 218, 85 }, + { 219, 85 }, + { 220, 85 }, + { 221, 89 }, + { 222, 84 }, + { 223, 115 }, + { 224, 97 }, + { 225, 97 }, + { 226, 97 }, + { 227, 97 }, + { 228, 97 }, + { 229, 97 }, + { 230, 97 }, + { 231, 99 }, + { 232, 101 }, + { 233, 101 }, + { 234, 101 }, + { 235, 101 }, + { 236, 105 }, + { 237, 105 }, + { 238, 105 }, + { 239, 105 }, + { 240, 100 }, + { 241, 110 }, + { 242, 111 }, + { 243, 111 }, + { 244, 111 }, + { 245, 111 }, + { 246, 111 }, + { 247, 33152 }, + { 248, 111 }, + { 249, 117 }, + { 250, 117 }, + { 251, 117 }, + { 252, 117 }, + { 253, 121 }, + { 254, 116 }, + { 255, 121 }, + { 913, 33695 }, + { 914, 33696 }, + { 915, 33697 }, + { 916, 33698 }, + { 917, 33699 }, + { 918, 33700 }, + { 919, 33701 }, + { 920, 33702 }, + { 921, 33703 }, + { 922, 33704 }, + { 923, 33705 }, + { 924, 33706 }, + { 925, 33707 }, + { 926, 33708 }, + { 927, 33709 }, + { 928, 33710 }, + { 929, 33711 }, + { 931, 33712 }, + { 932, 33713 }, + { 933, 33714 }, + { 934, 33715 }, + { 935, 33716 }, + { 936, 33717 }, + { 937, 33718 }, + { 945, 33727 }, + { 946, 33728 }, + { 947, 33729 }, + { 948, 33730 }, + { 949, 33731 }, + { 950, 33732 }, + { 951, 33733 }, + { 952, 33734 }, + { 953, 33735 }, + { 954, 33736 }, + { 955, 33737 }, + { 956, 33738 }, + { 957, 33739 }, + { 958, 33740 }, + { 959, 33741 }, + { 960, 33742 }, + { 961, 33743 }, + { 963, 33744 }, + { 964, 33745 }, + { 965, 33746 }, + { 966, 33747 }, + { 967, 33748 }, + { 968, 33749 }, + { 969, 33750 }, + { 1025, 33862 }, + { 1040, 33856 }, + { 1041, 33857 }, + { 1042, 33858 }, + { 1043, 33859 }, + { 1044, 33860 }, + { 1045, 33861 }, + { 1046, 33863 }, + { 1047, 33864 }, + { 1048, 33865 }, + { 1049, 33866 }, + { 1050, 33867 }, + { 1051, 33868 }, + { 1052, 33869 }, + { 1053, 33870 }, + { 1054, 33871 }, + { 1055, 33872 }, + { 1056, 33873 }, + { 1057, 33874 }, + { 1058, 33875 }, + { 1059, 33876 }, + { 1060, 33877 }, + { 1061, 33878 }, + { 1062, 33879 }, + { 1063, 33880 }, + { 1064, 33881 }, + { 1065, 33882 }, + { 1066, 33883 }, + { 1067, 33884 }, + { 1068, 33885 }, + { 1069, 33886 }, + { 1070, 33887 }, + { 1071, 33888 }, + { 1072, 33904 }, + { 1073, 33905 }, + { 1074, 33906 }, + { 1075, 33907 }, + { 1076, 33908 }, + { 1077, 33909 }, + { 1078, 33911 }, + { 1079, 33912 }, + { 1080, 33913 }, + { 1081, 33914 }, + { 1082, 33915 }, + { 1083, 33916 }, + { 1084, 33917 }, + { 1085, 33918 }, + { 1086, 33920 }, + { 1087, 33921 }, + { 1088, 33922 }, + { 1089, 33923 }, + { 1090, 33924 }, + { 1091, 33925 }, + { 1092, 33926 }, + { 1093, 33927 }, + { 1094, 33928 }, + { 1095, 33929 }, + { 1096, 33930 }, + { 1097, 33931 }, + { 1098, 33932 }, + { 1099, 33933 }, + { 1100, 33934 }, + { 1101, 33935 }, + { 1102, 33936 }, + { 1103, 33937 }, + { 1105, 33910 }, + { 8208, 33117 }, + { 8213, 33116 }, + { 8216, 33125 }, + { 8217, 33126 }, + { 8220, 33127 }, + { 8221, 33128 }, + { 8224, 33269 }, + { 8225, 33270 }, + { 8229, 33124 }, + { 8230, 33123 }, + { 8240, 33265 }, + { 8242, 33164 }, + { 8243, 33165 }, + { 8251, 33190 }, + { 8451, 33166 }, + { 8470, 34690 }, + { 8481, 34692 }, + { 8491, 33264 }, + { 8544, 34644 }, + { 8545, 34645 }, + { 8546, 34646 }, + { 8547, 34647 }, + { 8548, 34648 }, + { 8549, 34649 }, + { 8550, 34650 }, + { 8551, 34651 }, + { 8552, 34652 }, + { 8553, 34653 }, + { 8560, 64064 }, + { 8561, 64065 }, + { 8562, 64066 }, + { 8563, 64067 }, + { 8564, 64068 }, + { 8565, 64069 }, + { 8566, 64070 }, + { 8567, 64071 }, + { 8568, 64072 }, + { 8569, 64073 }, + { 8592, 33193 }, + { 8593, 33194 }, + { 8594, 33192 }, + { 8595, 33195 }, + { 8658, 33227 }, + { 8660, 33228 }, + { 8704, 33229 }, + { 8706, 33245 }, + { 8707, 33230 }, + { 8711, 33246 }, + { 8712, 33208 }, + { 8715, 33209 }, + { 8721, 34708 }, + { 8730, 33251 }, + { 8733, 33253 }, + { 8734, 33159 }, + { 8735, 34712 }, + { 8736, 33242 }, + { 8741, 33121 }, + { 8743, 33224 }, + { 8744, 33225 }, + { 8745, 33215 }, + { 8746, 33214 }, + { 8747, 33255 }, + { 8748, 33256 }, + { 8750, 34707 }, + { 8756, 33160 }, + { 8757, 33254 }, + { 8765, 33252 }, + { 8786, 33248 }, + { 8800, 33154 }, + { 8801, 33247 }, + { 8806, 33157 }, + { 8807, 33158 }, + { 8810, 33249 }, + { 8811, 33250 }, + { 8834, 33212 }, + { 8835, 33213 }, + { 8838, 33210 }, + { 8839, 33211 }, + { 8869, 33243 }, + { 8895, 34713 }, + { 8978, 33244 }, + { 9312, 34624 }, + { 9313, 34625 }, + { 9314, 34626 }, + { 9315, 34627 }, + { 9316, 34628 }, + { 9317, 34629 }, + { 9318, 34630 }, + { 9319, 34631 }, + { 9320, 34632 }, + { 9321, 34633 }, + { 9322, 34634 }, + { 9323, 34635 }, + { 9324, 34636 }, + { 9325, 34637 }, + { 9326, 34638 }, + { 9327, 34639 }, + { 9328, 34640 }, + { 9329, 34641 }, + { 9330, 34642 }, + { 9331, 34643 }, + { 9472, 33951 }, + { 9473, 33962 }, + { 9474, 33952 }, + { 9475, 33963 }, + { 9484, 33953 }, + { 9487, 33964 }, + { 9488, 33954 }, + { 9491, 33965 }, + { 9492, 33956 }, + { 9495, 33967 }, + { 9496, 33955 }, + { 9499, 33966 }, + { 9500, 33957 }, + { 9501, 33978 }, + { 9504, 33973 }, + { 9507, 33968 }, + { 9508, 33959 }, + { 9509, 33980 }, + { 9512, 33975 }, + { 9515, 33970 }, + { 9516, 33958 }, + { 9519, 33974 }, + { 9520, 33979 }, + { 9523, 33969 }, + { 9524, 33960 }, + { 9527, 33976 }, + { 9528, 33981 }, + { 9531, 33971 }, + { 9532, 33961 }, + { 9535, 33977 }, + { 9538, 33982 }, + { 9547, 33972 }, + { 9632, 33185 }, + { 9633, 33184 }, + { 9650, 33187 }, + { 9651, 33186 }, + { 9660, 33189 }, + { 9661, 33188 }, + { 9670, 33183 }, + { 9671, 33182 }, + { 9675, 33179 }, + { 9678, 33181 }, + { 9679, 33180 }, + { 9711, 33276 }, + { 9733, 33178 }, + { 9734, 33177 }, + { 9792, 33162 }, + { 9794, 33161 }, + { 9834, 33268 }, + { 9837, 33267 }, + { 9839, 33266 }, + { 12288, 33088 }, + { 12289, 33089 }, + { 12290, 33090 }, + { 12291, 33110 }, + { 12293, 33112 }, + { 12294, 33113 }, + { 12295, 33114 }, + { 12296, 33137 }, + { 12297, 33138 }, + { 12298, 33139 }, + { 12299, 33140 }, + { 12300, 33141 }, + { 12301, 33142 }, + { 12302, 33143 }, + { 12303, 33144 }, + { 12304, 33145 }, + { 12305, 33146 }, + { 12306, 33191 }, + { 12307, 33196 }, + { 12308, 33131 }, + { 12309, 33132 }, + { 12317, 34688 }, + { 12319, 34689 }, + { 12353, 33439 }, + { 12354, 33440 }, + { 12355, 33441 }, + { 12356, 33442 }, + { 12357, 33443 }, + { 12358, 33444 }, + { 12359, 33445 }, + { 12360, 33446 }, + { 12361, 33447 }, + { 12362, 33448 }, + { 12363, 33449 }, + { 12364, 33450 }, + { 12365, 33451 }, + { 12366, 33452 }, + { 12367, 33453 }, + { 12368, 33454 }, + { 12369, 33455 }, + { 12370, 33456 }, + { 12371, 33457 }, + { 12372, 33458 }, + { 12373, 33459 }, + { 12374, 33460 }, + { 12375, 33461 }, + { 12376, 33462 }, + { 12377, 33463 }, + { 12378, 33464 }, + { 12379, 33465 }, + { 12380, 33466 }, + { 12381, 33467 }, + { 12382, 33468 }, + { 12383, 33469 }, + { 12384, 33470 }, + { 12385, 33471 }, + { 12386, 33472 }, + { 12387, 33473 }, + { 12388, 33474 }, + { 12389, 33475 }, + { 12390, 33476 }, + { 12391, 33477 }, + { 12392, 33478 }, + { 12393, 33479 }, + { 12394, 33480 }, + { 12395, 33481 }, + { 12396, 33482 }, + { 12397, 33483 }, + { 12398, 33484 }, + { 12399, 33485 }, + { 12400, 33486 }, + { 12401, 33487 }, + { 12402, 33488 }, + { 12403, 33489 }, + { 12404, 33490 }, + { 12405, 33491 }, + { 12406, 33492 }, + { 12407, 33493 }, + { 12408, 33494 }, + { 12409, 33495 }, + { 12410, 33496 }, + { 12411, 33497 }, + { 12412, 33498 }, + { 12413, 33499 }, + { 12414, 33500 }, + { 12415, 33501 }, + { 12416, 33502 }, + { 12417, 33503 }, + { 12418, 33504 }, + { 12419, 33505 }, + { 12420, 33506 }, + { 12421, 33507 }, + { 12422, 33508 }, + { 12423, 33509 }, + { 12424, 33510 }, + { 12425, 33511 }, + { 12426, 33512 }, + { 12427, 33513 }, + { 12428, 33514 }, + { 12429, 33515 }, + { 12430, 33516 }, + { 12431, 33517 }, + { 12432, 33518 }, + { 12433, 33519 }, + { 12434, 33520 }, + { 12435, 33521 }, + { 12436, 33684 }, + { 12443, 33098 }, + { 12444, 33099 }, + { 12445, 33108 }, + { 12446, 33109 }, + { 12449, 33600 }, + { 12450, 33601 }, + { 12451, 33602 }, + { 12452, 33603 }, + { 12453, 33604 }, + { 12454, 33605 }, + { 12455, 33606 }, + { 12456, 33607 }, + { 12457, 33608 }, + { 12458, 33609 }, + { 12459, 33610 }, + { 12460, 33611 }, + { 12461, 33612 }, + { 12462, 33613 }, + { 12463, 33614 }, + { 12464, 33615 }, + { 12465, 33616 }, + { 12466, 33617 }, + { 12467, 33618 }, + { 12468, 33619 }, + { 12469, 33620 }, + { 12470, 33621 }, + { 12471, 33622 }, + { 12472, 33623 }, + { 12473, 33624 }, + { 12474, 33625 }, + { 12475, 33626 }, + { 12476, 33627 }, + { 12477, 33628 }, + { 12478, 33629 }, + { 12479, 33630 }, + { 12480, 33631 }, + { 12481, 33632 }, + { 12482, 33633 }, + { 12483, 33634 }, + { 12484, 33635 }, + { 12485, 33636 }, + { 12486, 33637 }, + { 12487, 33638 }, + { 12488, 33639 }, + { 12489, 33640 }, + { 12490, 33641 }, + { 12491, 33642 }, + { 12492, 33643 }, + { 12493, 33644 }, + { 12494, 33645 }, + { 12495, 33646 }, + { 12496, 33647 }, + { 12497, 33648 }, + { 12498, 33649 }, + { 12499, 33650 }, + { 12500, 33651 }, + { 12501, 33652 }, + { 12502, 33653 }, + { 12503, 33654 }, + { 12504, 33655 }, + { 12505, 33656 }, + { 12506, 33657 }, + { 12507, 33658 }, + { 12508, 33659 }, + { 12509, 33660 }, + { 12510, 33661 }, + { 12511, 33662 }, + { 12512, 33664 }, + { 12513, 33665 }, + { 12514, 33666 }, + { 12515, 33667 }, + { 12516, 33668 }, + { 12517, 33669 }, + { 12518, 33670 }, + { 12519, 33671 }, + { 12520, 33672 }, + { 12521, 33673 }, + { 12522, 33674 }, + { 12523, 33675 }, + { 12524, 33676 }, + { 12525, 33677 }, + { 12526, 33678 }, + { 12527, 33679 }, + { 12528, 33680 }, + { 12529, 33681 }, + { 12530, 33682 }, + { 12531, 33683 }, + { 12532, 33684 }, + { 12533, 33685 }, + { 12534, 33686 }, + { 12539, 33093 }, + { 12540, 33115 }, + { 12541, 33106 }, + { 12542, 33107 }, + { 12849, 34698 }, + { 12850, 34699 }, + { 12857, 34700 }, + { 12964, 34693 }, + { 12965, 34694 }, + { 12966, 34695 }, + { 12967, 34696 }, + { 12968, 34697 }, + { 13059, 34661 }, + { 13069, 34665 }, + { 13076, 34656 }, + { 13080, 34659 }, + { 13090, 34657 }, + { 13091, 34667 }, + { 13094, 34666 }, + { 13095, 34660 }, + { 13099, 34668 }, + { 13110, 34662 }, + { 13115, 34670 }, + { 13129, 34655 }, + { 13130, 34669 }, + { 13133, 34658 }, + { 13137, 34663 }, + { 13143, 34664 }, + { 13179, 34686 }, + { 13180, 34703 }, + { 13181, 34702 }, + { 13182, 34701 }, + { 13198, 34674 }, + { 13199, 34675 }, + { 13212, 34671 }, + { 13213, 34672 }, + { 13214, 34673 }, + { 13217, 34677 }, + { 13252, 34676 }, + { 13261, 34691 }, + { 19968, 35050 }, + { 19969, 37530 }, + { 19971, 36533 }, + { 19975, 38556 }, + { 19976, 36836 }, + { 19977, 36431 }, + { 19978, 36835 }, + { 19979, 35258 }, + { 19981, 38259 }, + { 19982, 38750 }, + { 19984, 39072 }, + { 19985, 35150 }, + { 19988, 35470 }, + { 19989, 39073 }, + { 19990, 37026 }, + { 19991, 39360 }, + { 19992, 35701 }, + { 19993, 38328 }, + { 19998, 36837 }, + { 20001, 38844 }, + { 20006, 38336 }, + { 20008, 64104 }, + { 20010, 39074 }, + { 20013, 37510 }, + { 20017, 39075 }, + { 20018, 35832 }, + { 20022, 39076 }, + { 20024, 35547 }, + { 20025, 37455 }, + { 20027, 36581 }, + { 20028, 39077 }, + { 20031, 39078 }, + { 20034, 39079 }, + { 20035, 37972 }, + { 20037, 35702 }, + { 20043, 37974 }, + { 20045, 37857 }, + { 20046, 36033 }, + { 20047, 38482 }, + { 20053, 58728 }, + { 20054, 39080 }, + { 20055, 36838 }, + { 20056, 39081 }, + { 20057, 35251 }, + { 20061, 35811 }, + { 20062, 36078 }, + { 20063, 38631 }, + { 20066, 39844 }, + { 20081, 38800 }, + { 20083, 37883 }, + { 20094, 35491 }, + { 20096, 35668 }, + { 20098, 39082 }, + { 20101, 39083 }, + { 20102, 38841 }, + { 20104, 38748 }, + { 20105, 37256 }, + { 20106, 39085 }, + { 20107, 36502 }, + { 20108, 37873 }, + { 20110, 39088 }, + { 20113, 35165 }, + { 20114, 36061 }, + { 20116, 36060 }, + { 20117, 35044 }, + { 20120, 39018 }, + { 20121, 39017 }, + { 20123, 36273 }, + { 20124, 34975 }, + { 20126, 39089 }, + { 20127, 39090 }, + { 20128, 39091 }, + { 20129, 38483 }, + { 20130, 39092 }, + { 20132, 36080 }, + { 20133, 35045 }, + { 20134, 38546 }, + { 20136, 35740 }, + { 20139, 35741 }, + { 20140, 35742 }, + { 20141, 37600 }, + { 20142, 38842 }, + { 20144, 39093 }, + { 20147, 39094 }, + { 20150, 39095 }, + { 20154, 36972 }, + { 20160, 36697 }, + { 20161, 36973 }, + { 20162, 39100 }, + { 20164, 39098 }, + { 20166, 39099 }, + { 20167, 35703 }, + { 20170, 36257 }, + { 20171, 35310 }, + { 20173, 39097 }, + { 20174, 39096 }, + { 20175, 38311 }, + { 20180, 36453 }, + { 20181, 36452 }, + { 20182, 37308 }, + { 20183, 39101 }, + { 20184, 38260 }, + { 20185, 37093 }, + { 20189, 33111 }, + { 20190, 39102 }, + { 20191, 39104 }, + { 20193, 64105 }, + { 20195, 37347 }, + { 20196, 38879 }, + { 20197, 35016 }, + { 20205, 39103 }, + { 20206, 35260 }, + { 20208, 35778 }, + { 20210, 37511 }, + { 20214, 35983 }, + { 20215, 39105 }, + { 20219, 37955 }, + { 20220, 64106 }, + { 20224, 64107 }, + { 20225, 35561 }, + { 20227, 64108 }, + { 20233, 39106 }, + { 20234, 35017 }, + { 20237, 36062 }, + { 20238, 35562 }, + { 20239, 38298 }, + { 20240, 38064 }, + { 20241, 35704 }, + { 20250, 35311 }, + { 20252, 39141 }, + { 20253, 37728 }, + { 20271, 38028 }, + { 20272, 39108 }, + { 20276, 38074 }, + { 20278, 38880 }, + { 20280, 36940 }, + { 20281, 64109 }, + { 20282, 36454 }, + { 20284, 36503 }, + { 20285, 35262 }, + { 20291, 37583 }, + { 20294, 37441 }, + { 20295, 39112 }, + { 20301, 35018 }, + { 20302, 37601 }, + { 20303, 36698 }, + { 20304, 36274 }, + { 20305, 38723 }, + { 20307, 37324 }, + { 20309, 35261 }, + { 20310, 64110 }, + { 20311, 39111 }, + { 20313, 38749 }, + { 20314, 39107 }, + { 20315, 39109 }, + { 20316, 36332 }, + { 20317, 39110 }, + { 20318, 39747 }, + { 20329, 39118 }, + { 20335, 39121 }, + { 20336, 39119 }, + { 20339, 35264 }, + { 20341, 38329 }, + { 20342, 39113 }, + { 20347, 39117 }, + { 20348, 36081 }, + { 20351, 36455 }, + { 20355, 35492 }, + { 20358, 39122 }, + { 20360, 39114 }, + { 20362, 64112 }, + { 20363, 38881 }, + { 20365, 36504 }, + { 20367, 39115 }, + { 20369, 39120 }, + { 20370, 64111 }, + { 20372, 64114 }, + { 20374, 39123 }, + { 20376, 39116 }, + { 20378, 64113 }, + { 20379, 35743 }, + { 20381, 35019 }, + { 20384, 35744 }, + { 20385, 35263 }, + { 20395, 39748 }, + { 20397, 38553 }, + { 20398, 38286 }, + { 20399, 36082 }, + { 20405, 36942 }, + { 20406, 38837 }, + { 20415, 38358 }, + { 20418, 35927 }, + { 20419, 37283 }, + { 20420, 35298 }, + { 20425, 64097 }, + { 20426, 36722 }, + { 20429, 64115 }, + { 20430, 39127 }, + { 20432, 39132 }, + { 20433, 39130 }, + { 20436, 39125 }, + { 20439, 37293 }, + { 20440, 39128 }, + { 20442, 39131 }, + { 20443, 39129 }, + { 20445, 38363 }, + { 20447, 39126 }, + { 20449, 36941 }, + { 20451, 38547 }, + { 20452, 39133 }, + { 20453, 39134 }, + { 20462, 36675 }, + { 20463, 39147 }, + { 20467, 37999 }, + { 20469, 38229 }, + { 20470, 39142 }, + { 20472, 38382 }, + { 20474, 35252 }, + { 20478, 39146 }, + { 20479, 64118 }, + { 20485, 39140 }, + { 20486, 39149 }, + { 20489, 37233 }, + { 20491, 36034 }, + { 20493, 38011 }, + { 20495, 57541 }, + { 20497, 39148 }, + { 20498, 37756 }, + { 20500, 39137 }, + { 20502, 36084 }, + { 20505, 36083 }, + { 20506, 39135 }, + { 20510, 64119 }, + { 20511, 36568 }, + { 20513, 39143 }, + { 20514, 64117 }, + { 20515, 38381 }, + { 20516, 37484 }, + { 20517, 39139 }, + { 20518, 35985 }, + { 20520, 39136 }, + { 20521, 39144 }, + { 20522, 39138 }, + { 20523, 38863 }, + { 20524, 39145 }, + { 20525, 39008 }, + { 20534, 35812 }, + { 20537, 35984 }, + { 20544, 64116 }, + { 20546, 64122 }, + { 20547, 39150 }, + { 20550, 64120 }, + { 20551, 39151 }, + { 20552, 39155 }, + { 20553, 35020 }, + { 20559, 38350 }, + { 20560, 39154 }, + { 20565, 39153 }, + { 20566, 39157 }, + { 20570, 39156 }, + { 20572, 37602 }, + { 20581, 35986 }, + { 20588, 39158 }, + { 20592, 64121 }, + { 20594, 36547 }, + { 20596, 37284 }, + { 20597, 37603 }, + { 20598, 35828 }, + { 20600, 39159 }, + { 20605, 35669 }, + { 20608, 39160 }, + { 20613, 39162 }, + { 20621, 38484 }, + { 20625, 35974 }, + { 20628, 64123 }, + { 20632, 36432 }, + { 20633, 38133 }, + { 20634, 39161 }, + { 20652, 36291 }, + { 20653, 38754 }, + { 20658, 39164 }, + { 20659, 39234 }, + { 20660, 39163 }, + { 20661, 36290 }, + { 20663, 36765 }, + { 20670, 35928 }, + { 20674, 39235 }, + { 20677, 35789 }, + { 20681, 39232 }, + { 20682, 39233 }, + { 20685, 37805 }, + { 20687, 37276 }, + { 20689, 35745 }, + { 20693, 38508 }, + { 20694, 39236 }, + { 20696, 64125 }, + { 20698, 38843 }, + { 20702, 39237 }, + { 20707, 39240 }, + { 20709, 39238 }, + { 20711, 37229 }, + { 20717, 39239 }, + { 20718, 39241 }, + { 20724, 64124 }, + { 20725, 39243 }, + { 20729, 39242 }, + { 20731, 38342 }, + { 20736, 35670 }, + { 20737, 39245 }, + { 20738, 39246 }, + { 20740, 35245 }, + { 20745, 39244 }, + { 20754, 36594 }, + { 20756, 39249 }, + { 20757, 39248 }, + { 20758, 39247 }, + { 20760, 39124 }, + { 20762, 39250 }, + { 20767, 36766 }, + { 20769, 39251 }, + { 20778, 38724 }, + { 20786, 38615 }, + { 20791, 39253 }, + { 20794, 39252 }, + { 20795, 39255 }, + { 20796, 39254 }, + { 20799, 39256 }, + { 20800, 39257 }, + { 20801, 35058 }, + { 20803, 36019 }, + { 20804, 35930 }, + { 20805, 36699 }, + { 20806, 37531 }, + { 20807, 35746 }, + { 20808, 37094 }, + { 20809, 36085 }, + { 20810, 64126 }, + { 20811, 36238 }, + { 20812, 39259 }, + { 20813, 38598 }, + { 20814, 37733 }, + { 20816, 36505 }, + { 20818, 39258 }, + { 20820, 39260 }, + { 20826, 37757 }, + { 20828, 35477 }, + { 20834, 39261 }, + { 20836, 64128 }, + { 20837, 37884 }, + { 20840, 37203 }, + { 20841, 39263 }, + { 20842, 39264 }, + { 20843, 38058 }, + { 20844, 36086 }, + { 20845, 39002 }, + { 20846, 39265 }, + { 20849, 35748 }, + { 20853, 38330 }, + { 20854, 37300 }, + { 20855, 35823 }, + { 20856, 37716 }, + { 20860, 35987 }, + { 20864, 39266 }, + { 20866, 39267 }, + { 20869, 37856 }, + { 20870, 35198 }, + { 20873, 39270 }, + { 20874, 36347 }, + { 20876, 39269 }, + { 20877, 36292 }, + { 20879, 39271 }, + { 20880, 58348 }, + { 20881, 39272 }, + { 20882, 38496 }, + { 20883, 39273 }, + { 20885, 39274 }, + { 20886, 39275 }, + { 20887, 36839 }, + { 20889, 36554 }, + { 20893, 64129 }, + { 20896, 35493 }, + { 20898, 39278 }, + { 20900, 39276 }, + { 20901, 38587 }, + { 20902, 39277 }, + { 20904, 38265 }, + { 20905, 39279 }, + { 20906, 39280 }, + { 20907, 39281 }, + { 20908, 37758 }, + { 20912, 39285 }, + { 20913, 39283 }, + { 20914, 39284 }, + { 20915, 39282 }, + { 20916, 36321 }, + { 20917, 39286 }, + { 20918, 38632 }, + { 20919, 38882 }, + { 20925, 39287 }, + { 20926, 64130 }, + { 20932, 37030 }, + { 20933, 39288 }, + { 20934, 36729 }, + { 20937, 39289 }, + { 20939, 37532 }, + { 20940, 38845 }, + { 20941, 37760 }, + { 20950, 39363 }, + { 20955, 39290 }, + { 20956, 60067 }, + { 20957, 35779 }, + { 20960, 39291 }, + { 20961, 38525 }, + { 20966, 36744 }, + { 20967, 37370 }, + { 20969, 39293 }, + { 20970, 37858 }, + { 20972, 64131 }, + { 20973, 39294 }, + { 20976, 39296 }, + { 20977, 35405 }, + { 20981, 39297 }, + { 20982, 35749 }, + { 20984, 37834 }, + { 20985, 35226 }, + { 20986, 36719 }, + { 20989, 38047 }, + { 20990, 39298 }, + { 20992, 37761 }, + { 20995, 36974 }, + { 20996, 39299 }, + { 20998, 38314 }, + { 20999, 37080 }, + { 21000, 35488 }, + { 21002, 35495 }, + { 21003, 39300 }, + { 21006, 39302 }, + { 21009, 35929 }, + { 21012, 39301 }, + { 21013, 64132 }, + { 21015, 38897 }, + { 21021, 36745 }, + { 21028, 38075 }, + { 21029, 38346 }, + { 21031, 39303 }, + { 21033, 38808 }, + { 21034, 39304 }, + { 21038, 39305 }, + { 21040, 37790 }, + { 21043, 39306 }, + { 21046, 37031 }, + { 21047, 36348 }, + { 21048, 35988 }, + { 21049, 39307 }, + { 21050, 36456 }, + { 21051, 36239 }, + { 21059, 37604 }, + { 21060, 39309 }, + { 21063, 37285 }, + { 21066, 36333 }, + { 21067, 39310 }, + { 21068, 39311 }, + { 21069, 37199 }, + { 21071, 39308 }, + { 21076, 39313 }, + { 21078, 38485 }, + { 21083, 36228 }, + { 21086, 39312 }, + { 21091, 35989 }, + { 21092, 36316 }, + { 21093, 38029 }, + { 21097, 39316 }, + { 21098, 39314 }, + { 21103, 38299 }, + { 21104, 36840 }, + { 21105, 39323 }, + { 21106, 35460 }, + { 21107, 39317 }, + { 21108, 39315 }, + { 21109, 37230 }, + { 21117, 39319 }, + { 21119, 39318 }, + { 21123, 35427 }, + { 21127, 35968 }, + { 21128, 39324 }, + { 21129, 38827 }, + { 21133, 39320 }, + { 21137, 39325 }, + { 21138, 39322 }, + { 21140, 39321 }, + { 21147, 38861 }, + { 21148, 64133 }, + { 21151, 36087 }, + { 21152, 35265 }, + { 21155, 38898 }, + { 21158, 64134 }, + { 21161, 36757 }, + { 21162, 37751 }, + { 21163, 36229 }, + { 21164, 39328 }, + { 21165, 39329 }, + { 21167, 64375 }, + { 21169, 38883 }, + { 21172, 38986 }, + { 21173, 39331 }, + { 21177, 36088 }, + { 21180, 39330 }, + { 21182, 35406 }, + { 21184, 64135 }, + { 21185, 39332 }, + { 21187, 38517 }, + { 21189, 37562 }, + { 21191, 38725 }, + { 21193, 38359 }, + { 21197, 39333 }, + { 21202, 59603 }, + { 21205, 37806 }, + { 21207, 39334 }, + { 21208, 35496 }, + { 21209, 38577 }, + { 21211, 64136 }, + { 21213, 36767 }, + { 21214, 39335 }, + { 21215, 38373 }, + { 21216, 39339 }, + { 21218, 37032 }, + { 21219, 39336 }, + { 21220, 35790 }, + { 21222, 39337 }, + { 21223, 35497 }, + { 21234, 35917 }, + { 21235, 39340 }, + { 21237, 39341 }, + { 21240, 39342 }, + { 21241, 39343 }, + { 21242, 36569 }, + { 21246, 36089 }, + { 21247, 38620 }, + { 21248, 64137 }, + { 21249, 38630 }, + { 21250, 37877 }, + { 21253, 38383 }, + { 21254, 39344 }, + { 21255, 64138 }, + { 21256, 39345 }, + { 21261, 39347 }, + { 21263, 39349 }, + { 21264, 39348 }, + { 21269, 39350 }, + { 21270, 35259 }, + { 21271, 38507 }, + { 21273, 36346 }, + { 21274, 39351 }, + { 21277, 37240 }, + { 21280, 36768 }, + { 21281, 35751 }, + { 21283, 39352 }, + { 21284, 64139 }, + { 21290, 38105 }, + { 21295, 39353 }, + { 21297, 39354 }, + { 21299, 39355 }, + { 21304, 39356 }, + { 21305, 38211 }, + { 21306, 35814 }, + { 21307, 35043 }, + { 21311, 37821 }, + { 21312, 39357 }, + { 21313, 36700 }, + { 21315, 37095 }, + { 21317, 39359 }, + { 21318, 39358 }, + { 21319, 36769 }, + { 21320, 36063 }, + { 21321, 39361 }, + { 21322, 38076 }, + { 21325, 39362 }, + { 21329, 38106 }, + { 21330, 37298 }, + { 21331, 37356 }, + { 21332, 35750 }, + { 21335, 37868 }, + { 21336, 37456 }, + { 21338, 38030 }, + { 21340, 38509 }, + { 21342, 39364 }, + { 21344, 37096 }, + { 21350, 35924 }, + { 21353, 39365 }, + { 21358, 39366 }, + { 21359, 35147 }, + { 21360, 35059 }, + { 21361, 35563 }, + { 21362, 64140 }, + { 21363, 37286 }, + { 21364, 35696 }, + { 21365, 38801 }, + { 21367, 39369 }, + { 21368, 35253 }, + { 21371, 39368 }, + { 21375, 35752 }, + { 21378, 39370 }, + { 21380, 38639 }, + { 21395, 64141 }, + { 21398, 39371 }, + { 21400, 38864 }, + { 21402, 36090 }, + { 21407, 36020 }, + { 21408, 39372 }, + { 21413, 39374 }, + { 21414, 39373 }, + { 21416, 36990 }, + { 21417, 35160 }, + { 21421, 35197 }, + { 21422, 39375 }, + { 21424, 39376 }, + { 21426, 64142 }, + { 21427, 36021 }, + { 21430, 39377 }, + { 21435, 35726 }, + { 21442, 36433 }, + { 21443, 39378 }, + { 21448, 38548 }, + { 21449, 36275 }, + { 21450, 35705 }, + { 21451, 38726 }, + { 21452, 37231 }, + { 21453, 38077 }, + { 21454, 36603 }, + { 21460, 36710 }, + { 21462, 36582 }, + { 21463, 36595 }, + { 21465, 36758 }, + { 21467, 38078 }, + { 21469, 64143 }, + { 21471, 39381 }, + { 21473, 35170 }, + { 21474, 37232 }, + { 21475, 36091 }, + { 21476, 36035 }, + { 21477, 35813 }, + { 21480, 39385 }, + { 21481, 37440 }, + { 21482, 37372 }, + { 21483, 35753 }, + { 21484, 36770 }, + { 21485, 39386 }, + { 21486, 39384 }, + { 21487, 35266 }, + { 21488, 37348 }, + { 21489, 36534 }, + { 21490, 36458 }, + { 21491, 35141 }, + { 21494, 35472 }, + { 21495, 36230 }, + { 21496, 36457 }, + { 21498, 39387 }, + { 21505, 39388 }, + { 21507, 35688 }, + { 21508, 35429 }, + { 21512, 36231 }, + { 21513, 35687 }, + { 21514, 37597 }, + { 21515, 35140 }, + { 21516, 37807 }, + { 21517, 38588 }, + { 21518, 36160 }, + { 21519, 38809 }, + { 21520, 37734 }, + { 21521, 36092 }, + { 21531, 35918 }, + { 21533, 39397 }, + { 21535, 35809 }, + { 21536, 38505 }, + { 21542, 38107 }, + { 21545, 39396 }, + { 21547, 35548 }, + { 21548, 39391 }, + { 21549, 39392 }, + { 21550, 39394 }, + { 21558, 39395 }, + { 21560, 35706 }, + { 21561, 36993 }, + { 21563, 38315 }, + { 21564, 39393 }, + { 21565, 39389 }, + { 21566, 36065 }, + { 21568, 39390 }, + { 21570, 38979 }, + { 21574, 38384 }, + { 21576, 37606 }, + { 21577, 36064 }, + { 21578, 36240 }, + { 21582, 39398 }, + { 21585, 37851 }, + { 21599, 39402 }, + { 21608, 36604 }, + { 21610, 36596 }, + { 21616, 39405 }, + { 21617, 39403 }, + { 21619, 38561 }, + { 21621, 39400 }, + { 21622, 39409 }, + { 21623, 39404 }, + { 21627, 39407 }, + { 21628, 36036 }, + { 21629, 38589 }, + { 21632, 39408 }, + { 21636, 39410 }, + { 21638, 39412 }, + { 21642, 64146 }, + { 21643, 36334 }, + { 21644, 39009 }, + { 21646, 39401 }, + { 21647, 39399 }, + { 21648, 39411 }, + { 21650, 39406 }, + { 21660, 64145 }, + { 21666, 39414 }, + { 21668, 39490 }, + { 21669, 39416 }, + { 21672, 39420 }, + { 21673, 64147 }, + { 21675, 39488 }, + { 21676, 39417 }, + { 21679, 39517 }, + { 21682, 36327 }, + { 21683, 35408 }, + { 21688, 39415 }, + { 21692, 39492 }, + { 21693, 35060 }, + { 21694, 39491 }, + { 21696, 34979 }, + { 21697, 38249 }, + { 21698, 39489 }, + { 21700, 39418 }, + { 21703, 39413 }, + { 21704, 39419 }, + { 21705, 36294 }, + { 21720, 39493 }, + { 21729, 35061 }, + { 21730, 39502 }, + { 21733, 39494 }, + { 21734, 39495 }, + { 21736, 36771 }, + { 21737, 38537 }, + { 21741, 39500 }, + { 21742, 39499 }, + { 21746, 37710 }, + { 21754, 39501 }, + { 21757, 39498 }, + { 21759, 64148 }, + { 21764, 35155 }, + { 21766, 36276 }, + { 21767, 36943 }, + { 21775, 39496 }, + { 21776, 37762 }, + { 21780, 39497 }, + { 21782, 34976 }, + { 21806, 39507 }, + { 21807, 38722 }, + { 21809, 36773 }, + { 21811, 39513 }, + { 21816, 39512 }, + { 21817, 39503 }, + { 21822, 37313 }, + { 21824, 39504 }, + { 21828, 37357 }, + { 21829, 39509 }, + { 21830, 36772 }, + { 21836, 39506 }, + { 21839, 38626 }, + { 21843, 35931 }, + { 21846, 39510 }, + { 21847, 39511 }, + { 21852, 39508 }, + { 21853, 39514 }, + { 21859, 39505 }, + { 21883, 39520 }, + { 21884, 39525 }, + { 21886, 39521 }, + { 21888, 39516 }, + { 21891, 39526 }, + { 21892, 37200 }, + { 21894, 64149 }, + { 21895, 39528 }, + { 21897, 36161 }, + { 21898, 39518 }, + { 21899, 37533 }, + { 21912, 39522 }, + { 21913, 39515 }, + { 21914, 35499 }, + { 21916, 35564 }, + { 21917, 35461 }, + { 21918, 39523 }, + { 21919, 39519 }, + { 21927, 35990 }, + { 21928, 39529 }, + { 21929, 39527 }, + { 21930, 37234 }, + { 21931, 35689 }, + { 21932, 35754 }, + { 21934, 39524 }, + { 21936, 35826 }, + { 21942, 35171 }, + { 21956, 39533 }, + { 21957, 39531 }, + { 21959, 39589 }, + { 21972, 39536 }, + { 21978, 39530 }, + { 21980, 39534 }, + { 21983, 39532 }, + { 21987, 36459 }, + { 21988, 39535 }, + { 22007, 39538 }, + { 22009, 39543 }, + { 22013, 39541 }, + { 22014, 39540 }, + { 22022, 37457 }, + { 22025, 35267 }, + { 22036, 39537 }, + { 22038, 39539 }, + { 22039, 36774 }, + { 22040, 35154 }, + { 22043, 39542 }, + { 22057, 35292 }, + { 22063, 39554 }, + { 22065, 36858 }, + { 22066, 39549 }, + { 22068, 39547 }, + { 22070, 39548 }, + { 22072, 39550 }, + { 22082, 35164 }, + { 22092, 37208 }, + { 22094, 39544 }, + { 22096, 39545 }, + { 22107, 35482 }, + { 22116, 39553 }, + { 22120, 35565 }, + { 22122, 39556 }, + { 22123, 39552 }, + { 22124, 39555 }, + { 22132, 38316 }, + { 22136, 37843 }, + { 22138, 38070 }, + { 22144, 39558 }, + { 22150, 39557 }, + { 22151, 35428 }, + { 22154, 39559 }, + { 22159, 39562 }, + { 22164, 39561 }, + { 22176, 39560 }, + { 22178, 37976 }, + { 22181, 39563 }, + { 22190, 39564 }, + { 22196, 39566 }, + { 22198, 39565 }, + { 22204, 39568 }, + { 22208, 39571 }, + { 22209, 39569 }, + { 22210, 39567 }, + { 22211, 39570 }, + { 22216, 39572 }, + { 22222, 39573 }, + { 22225, 39574 }, + { 22227, 39575 }, + { 22231, 39576 }, + { 22232, 39268 }, + { 22234, 36602 }, + { 22235, 36460 }, + { 22238, 35313 }, + { 22240, 35062 }, + { 22243, 37475 }, + { 22254, 39577 }, + { 22256, 36258 }, + { 22258, 35021 }, + { 22259, 36989 }, + { 22265, 39578 }, + { 22266, 36037 }, + { 22269, 36241 }, + { 22271, 39580 }, + { 22272, 39579 }, + { 22275, 38366 }, + { 22276, 39581 }, + { 22280, 39583 }, + { 22281, 39582 }, + { 22283, 39584 }, + { 22285, 39585 }, + { 22287, 35991 }, + { 22290, 35200 }, + { 22291, 39586 }, + { 22294, 39588 }, + { 22296, 39587 }, + { 22300, 39590 }, + { 22303, 37753 }, + { 22310, 39591 }, + { 22311, 34995 }, + { 22312, 36317 }, + { 22317, 35932 }, + { 22320, 37486 }, + { 22327, 39592 }, + { 22328, 39593 }, + { 22331, 39595 }, + { 22336, 39596 }, + { 22338, 36322 }, + { 22343, 35791 }, + { 22346, 38486 }, + { 22350, 39594 }, + { 22351, 39597 }, + { 22352, 36287 }, + { 22353, 36162 }, + { 22361, 64150 }, + { 22369, 39601 }, + { 22372, 36259 }, + { 22373, 64151 }, + { 22374, 37458 }, + { 22377, 39598 }, + { 22378, 37592 }, + { 22399, 39602 }, + { 22402, 36994 }, + { 22408, 39600 }, + { 22409, 39603 }, + { 22411, 35934 }, + { 22419, 39604 }, + { 22432, 39605 }, + { 22434, 36163 }, + { 22435, 35423 }, + { 22436, 39607 }, + { 22442, 39608 }, + { 22444, 64152 }, + { 22448, 39609 }, + { 22451, 39606 }, + { 22464, 39599 }, + { 22467, 39610 }, + { 22470, 39611 }, + { 22471, 64154 }, + { 22472, 64153 }, + { 22475, 38532 }, + { 22478, 36841 }, + { 22482, 39613 }, + { 22483, 39614 }, + { 22484, 39612 }, + { 22486, 39616 }, + { 22492, 37975 }, + { 22495, 35046 }, + { 22496, 38261 }, + { 22499, 39617 }, + { 22516, 36859 }, + { 22519, 36535 }, + { 22521, 38012 }, + { 22522, 35566 }, + { 22524, 36329 }, + { 22528, 38520 }, + { 22530, 37808 }, + { 22533, 35992 }, + { 22534, 37325 }, + { 22538, 39615 }, + { 22539, 39618 }, + { 22549, 37314 }, + { 22553, 39619 }, + { 22557, 39620 }, + { 22561, 39622 }, + { 22564, 37607 }, + { 22570, 35500 }, + { 22575, 60063 }, + { 22576, 35201 }, + { 22577, 38385 }, + { 22580, 36842 }, + { 22581, 37735 }, + { 22586, 36324 }, + { 22589, 39628 }, + { 22592, 38331 }, + { 22593, 38875 }, + { 22602, 35314 }, + { 22603, 39624 }, + { 22609, 37209 }, + { 22610, 39627 }, + { 22612, 37763 }, + { 22615, 37736 }, + { 22616, 37764 }, + { 22617, 38071 }, + { 22618, 37579 }, + { 22622, 36295 }, + { 22626, 39623 }, + { 22633, 35222 }, + { 22635, 37717 }, + { 22640, 39625 }, + { 22642, 39621 }, + { 22645, 36975 }, + { 22649, 39629 }, + { 22654, 36717 }, + { 22659, 35755 }, + { 22661, 39630 }, + { 22675, 38374 }, + { 22679, 37277 }, + { 22684, 37572 }, + { 22686, 64157 }, + { 22687, 39632 }, + { 22696, 38510 }, + { 22699, 39633 }, + { 22702, 39638 }, + { 22706, 64158 }, + { 22707, 38317 }, + { 22712, 39637 }, + { 22713, 39631 }, + { 22714, 39634 }, + { 22715, 39636 }, + { 22718, 36260 }, + { 22721, 38343 }, + { 22725, 39639 }, + { 22727, 37476 }, + { 22730, 35315 }, + { 22732, 36843 }, + { 22737, 39641 }, + { 22739, 39640 }, + { 22741, 36232 }, + { 22743, 39642 }, + { 22744, 39644 }, + { 22745, 39643 }, + { 22748, 39646 }, + { 22750, 39635 }, + { 22751, 39648 }, + { 22756, 39647 }, + { 22757, 39645 }, + { 22763, 36461 }, + { 22764, 36976 }, + { 22766, 37235 }, + { 22767, 39649 }, + { 22768, 37050 }, + { 22769, 35051 }, + { 22770, 38020 }, + { 22775, 37593 }, + { 22777, 39651 }, + { 22778, 39650 }, + { 22779, 39652 }, + { 22780, 39653 }, + { 22781, 39654 }, + { 22786, 39655 }, + { 22793, 38351 }, + { 22794, 39656 }, + { 22795, 64159 }, + { 22799, 35268 }, + { 22800, 39657 }, + { 22805, 38747 }, + { 22806, 35407 }, + { 22808, 39367 }, + { 22809, 36711 }, + { 22810, 37309 }, + { 22811, 39658 }, + { 22812, 38633 }, + { 22818, 38578 }, + { 22821, 39660 }, + { 22823, 37349 }, + { 22825, 37718 }, + { 22826, 37310 }, + { 22827, 38262 }, + { 22828, 39661 }, + { 22829, 39662 }, + { 22830, 35227 }, + { 22833, 36536 }, + { 22834, 39663 }, + { 22839, 35022 }, + { 22840, 39664 }, + { 22846, 39665 }, + { 22852, 35202 }, + { 22855, 35567 }, + { 22856, 37854 }, + { 22857, 38386 }, + { 22862, 39669 }, + { 22863, 37236 }, + { 22864, 39668 }, + { 22865, 35935 }, + { 22867, 64160 }, + { 22868, 38522 }, + { 22869, 39667 }, + { 22871, 37765 }, + { 22872, 39671 }, + { 22874, 39670 }, + { 22875, 64161 }, + { 22877, 64162 }, + { 22880, 39673 }, + { 22882, 39672 }, + { 22883, 64163 }, + { 22885, 35228 }, + { 22887, 39674 }, + { 22888, 36775 }, + { 22889, 39676 }, + { 22890, 37444 }, + { 22892, 39675 }, + { 22894, 38321 }, + { 22899, 36759 }, + { 22900, 37754 }, + { 22904, 39744 }, + { 22909, 36164 }, + { 22913, 39745 }, + { 22914, 37952 }, + { 22915, 38108 }, + { 22916, 38607 }, + { 22922, 37956 }, + { 22925, 39754 }, + { 22931, 35671 }, + { 22934, 38756 }, + { 22937, 38573 }, + { 22939, 39850 }, + { 22941, 39746 }, + { 22947, 39749 }, + { 22948, 64164 }, + { 22949, 37315 }, + { 22952, 38487 }, + { 22956, 37737 }, + { 22962, 39750 }, + { 22969, 38533 }, + { 22970, 64165 }, + { 22971, 36296 }, + { 22974, 36776 }, + { 22982, 39751 }, + { 22985, 36463 }, + { 22987, 36462 }, + { 22992, 34999 }, + { 22993, 36038 }, + { 22995, 37033 }, + { 22996, 35023 }, + { 23001, 39755 }, + { 23002, 39756 }, + { 23004, 39753 }, + { 23013, 35159 }, + { 23014, 35501 }, + { 23016, 39752 }, + { 23018, 38595 }, + { 23019, 38224 }, + { 23030, 34982 }, + { 23035, 35063 }, + { 23039, 36464 }, + { 23041, 35024 }, + { 23043, 34977 }, + { 23049, 39761 }, + { 23057, 39759 }, + { 23064, 38586 }, + { 23066, 39762 }, + { 23068, 39760 }, + { 23071, 39758 }, + { 23072, 36944 }, + { 23077, 39757 }, + { 23081, 38360 }, + { 23087, 36066 }, + { 23093, 39766 }, + { 23094, 39767 }, + { 23100, 36777 }, + { 23104, 39763 }, + { 23105, 38987 }, + { 23110, 37995 }, + { 23113, 39765 }, + { 23130, 36261 }, + { 23138, 39768 }, + { 23142, 38263 }, + { 23146, 39769 }, + { 23148, 39764 }, + { 23167, 38585 }, + { 23186, 38013 }, + { 23194, 39770 }, + { 23195, 38225 }, + { 23228, 39771 }, + { 23229, 39775 }, + { 23230, 39772 }, + { 23233, 35269 }, + { 23234, 39774 }, + { 23241, 36537 }, + { 23243, 39773 }, + { 23244, 35993 }, + { 23248, 39787 }, + { 23254, 39780 }, + { 23255, 39777 }, + { 23265, 37508 }, + { 23267, 39776 }, + { 23270, 39778 }, + { 23273, 39779 }, + { 23290, 39781 }, + { 23291, 39782 }, + { 23305, 35568 }, + { 23307, 39784 }, + { 23308, 39783 }, + { 23318, 39785 }, + { 23330, 36844 }, + { 23338, 39788 }, + { 23340, 37594 }, + { 23344, 35172 }, + { 23346, 39786 }, + { 23350, 39789 }, + { 23358, 39790 }, + { 23360, 39793 }, + { 23363, 39791 }, + { 23365, 39792 }, + { 23376, 36465 }, + { 23377, 39794 }, + { 23380, 36165 }, + { 23381, 39795 }, + { 23382, 64166 }, + { 23383, 36506 }, + { 23384, 37302 }, + { 23386, 39796 }, + { 23387, 39797 }, + { 23388, 36473 }, + { 23389, 36166 }, + { 23391, 38608 }, + { 23395, 35655 }, + { 23396, 36039 }, + { 23397, 39798 }, + { 23398, 35447 }, + { 23401, 39799 }, + { 23403, 37303 }, + { 23408, 39800 }, + { 23409, 39841 }, + { 23411, 39801 }, + { 23413, 39802 }, + { 23416, 39803 }, + { 23418, 39805 }, + { 23424, 39806 }, + { 23427, 39808 }, + { 23429, 37358 }, + { 23431, 35142 }, + { 23432, 36583 }, + { 23433, 35008 }, + { 23435, 37238 }, + { 23436, 35502 }, + { 23437, 36531 }, + { 23439, 36167 }, + { 23445, 37766 }, + { 23447, 36672 }, + { 23448, 35503 }, + { 23449, 37512 }, + { 23450, 37608 }, + { 23451, 34998 }, + { 23452, 35672 }, + { 23453, 38387 }, + { 23455, 36544 }, + { 23458, 35697 }, + { 23459, 37097 }, + { 23460, 36538 }, + { 23461, 38727 }, + { 23462, 39809 }, + { 23470, 35707 }, + { 23472, 36297 }, + { 23475, 35409 }, + { 23476, 35203 }, + { 23477, 36778 }, + { 23478, 35270 }, + { 23480, 39810 }, + { 23481, 38757 }, + { 23487, 36712 }, + { 23488, 64167 }, + { 23490, 36578 }, + { 23491, 39811 }, + { 23492, 35569 }, + { 23493, 37840 }, + { 23494, 38567 }, + { 23495, 39812 }, + { 23497, 39813 }, + { 23500, 38264 }, + { 23504, 39815 }, + { 23506, 35494 }, + { 23507, 35829 }, + { 23508, 39814 }, + { 23512, 64169 }, + { 23515, 35504 }, + { 23517, 36945 }, + { 23518, 39819 }, + { 23519, 36416 }, + { 23521, 35271 }, + { 23522, 39818 }, + { 23524, 39816 }, + { 23525, 39820 }, + { 23526, 39817 }, + { 23527, 37962 }, + { 23528, 40651 }, + { 23529, 36946 }, + { 23531, 39821 }, + { 23532, 64170 }, + { 23534, 38846 }, + { 23536, 39822 }, + { 23539, 39824 }, + { 23541, 37534 }, + { 23542, 39823 }, + { 23544, 37025 }, + { 23546, 36507 }, + { 23550, 37326 }, + { 23551, 36597 }, + { 23553, 38293 }, + { 23554, 37098 }, + { 23556, 36555 }, + { 23557, 39825 }, + { 23558, 36779 }, + { 23559, 39826 }, + { 23560, 39827 }, + { 23561, 35025 }, + { 23562, 37304 }, + { 23563, 36977 }, + { 23565, 39828 }, + { 23566, 37809 }, + { 23567, 36780 }, + { 23569, 36781 }, + { 23571, 39829 }, + { 23574, 37099 }, + { 23578, 36782 }, + { 23582, 64171 }, + { 23584, 39830 }, + { 23586, 39831 }, + { 23588, 38622 }, + { 23592, 39832 }, + { 23597, 35780 }, + { 23601, 36673 }, + { 23608, 39833 }, + { 23609, 39834 }, + { 23610, 36570 }, + { 23611, 36939 }, + { 23612, 37874 }, + { 23613, 36979 }, + { 23614, 38134 }, + { 23615, 37953 }, + { 23616, 35783 }, + { 23617, 39835 }, + { 23621, 35727 }, + { 23622, 39836 }, + { 23624, 35836 }, + { 23626, 37837 }, + { 23627, 35246 }, + { 23629, 36466 }, + { 23630, 39837 }, + { 23631, 39840 }, + { 23632, 39839 }, + { 23633, 35835 }, + { 23635, 39838 }, + { 23637, 37719 }, + { 23646, 37294 }, + { 23648, 37738 }, + { 23649, 36550 }, + { 23652, 37239 }, + { 23653, 38810 }, + { 23660, 39842 }, + { 23662, 39843 }, + { 23663, 37844 }, + { 23665, 36434 }, + { 23670, 39845 }, + { 23673, 39846 }, + { 23692, 39847 }, + { 23696, 35570 }, + { 23697, 39848 }, + { 23700, 39849 }, + { 23713, 35242 }, + { 23718, 64172 }, + { 23720, 37210 }, + { 23721, 35554 }, + { 23723, 39851 }, + { 23724, 38566 }, + { 23729, 37328 }, + { 23731, 35448 }, + { 23734, 39853 }, + { 23735, 39855 }, + { 23736, 35549 }, + { 23738, 64173 }, + { 23739, 39852 }, + { 23740, 39854 }, + { 23742, 39857 }, + { 23749, 39856 }, + { 23751, 39858 }, + { 23769, 39859 }, + { 23776, 37819 }, + { 23777, 35756 }, + { 23784, 35299 }, + { 23785, 39860 }, + { 23786, 39865 }, + { 23789, 39863 }, + { 23791, 38389 }, + { 23792, 38388 }, + { 23797, 64174 }, + { 23798, 37767 }, + { 23802, 39862 }, + { 23803, 36723 }, + { 23805, 39861 }, + { 23815, 37010 }, + { 23819, 39866 }, + { 23822, 36328 }, + { 23825, 39872 }, + { 23828, 39873 }, + { 23829, 39867 }, + { 23830, 35410 }, + { 23831, 39868 }, + { 23832, 39877 }, + { 23833, 39876 }, + { 23834, 39875 }, + { 23835, 39871 }, + { 23839, 39870 }, + { 23842, 39874 }, + { 23847, 64175 }, + { 23849, 38390 }, + { 23874, 64178 }, + { 23883, 39881 }, + { 23884, 39878 }, + { 23886, 39880 }, + { 23888, 38802 }, + { 23890, 39879 }, + { 23891, 64176 }, + { 23900, 39869 }, + { 23913, 37011 }, + { 23916, 39882 }, + { 23917, 64179 }, + { 23919, 36277 }, + { 23923, 39883 }, + { 23926, 39884 }, + { 23938, 39887 }, + { 23940, 39886 }, + { 23943, 39885 }, + { 23947, 37768 }, + { 23948, 39864 }, + { 23952, 39893 }, + { 23965, 39889 }, + { 23970, 39888 }, + { 23980, 39890 }, + { 23982, 39891 }, + { 23991, 39894 }, + { 23992, 64180 }, + { 23993, 64181 }, + { 23994, 38884 }, + { 23996, 39895 }, + { 23997, 39892 }, + { 24009, 39896 }, + { 24012, 35550 }, + { 24013, 39897 }, + { 24016, 64182 }, + { 24018, 39899 }, + { 24019, 39898 }, + { 24022, 39900 }, + { 24027, 39901 }, + { 24029, 37100 }, + { 24030, 36674 }, + { 24033, 36740 }, + { 24035, 37251 }, + { 24037, 36168 }, + { 24038, 36278 }, + { 24039, 36169 }, + { 24040, 35728 }, + { 24043, 39902 }, + { 24046, 36279 }, + { 24049, 36040 }, + { 24050, 39903 }, + { 24051, 38564 }, + { 24052, 37986 }, + { 24053, 39904 }, + { 24055, 36170 }, + { 24059, 35498 }, + { 24061, 37446 }, + { 24062, 35792 }, + { 24066, 36467 }, + { 24067, 38266 }, + { 24070, 38079 }, + { 24075, 39905 }, + { 24076, 35571 }, + { 24081, 39908 }, + { 24086, 37535 }, + { 24089, 39907 }, + { 24090, 39906 }, + { 24091, 39909 }, + { 24093, 37609 }, + { 24101, 36995 }, + { 24107, 36468 }, + { 24109, 37064 }, + { 24111, 37329 }, + { 24112, 35649 }, + { 24115, 37536 }, + { 24118, 39910 }, + { 24119, 39911 }, + { 24120, 36845 }, + { 24125, 38488 }, + { 24128, 39914 }, + { 24131, 39913 }, + { 24132, 39912 }, + { 24133, 38301 }, + { 24135, 39921 }, + { 24140, 38521 }, + { 24142, 39915 }, + { 24148, 39917 }, + { 24149, 38539 }, + { 24151, 39916 }, + { 24159, 39918 }, + { 24161, 38054 }, + { 24162, 39919 }, + { 24163, 38332 }, + { 24164, 39920 }, + { 24178, 35505 }, + { 24179, 38333 }, + { 24180, 37966 }, + { 24181, 39922 }, + { 24182, 39923 }, + { 24184, 36171 }, + { 24185, 35506 }, + { 24186, 39924 }, + { 24187, 36022 }, + { 24188, 38755 }, + { 24189, 38728 }, + { 24190, 35572 }, + { 24191, 39926 }, + { 24193, 37537 }, + { 24195, 36172 }, + { 24196, 36783 }, + { 24199, 38109 }, + { 24202, 36784 }, + { 24207, 36760 }, + { 24213, 37610 }, + { 24214, 38391 }, + { 24215, 37720 }, + { 24218, 36173 }, + { 24220, 38267 }, + { 24224, 39927 }, + { 24230, 37752 }, + { 24231, 36288 }, + { 24235, 36041 }, + { 24237, 37611 }, + { 24245, 35009 }, + { 24246, 36750 }, + { 24247, 36174 }, + { 24248, 38758 }, + { 24257, 39928 }, + { 24258, 39929 }, + { 24259, 38000 }, + { 24264, 39930 }, + { 24265, 38901 }, + { 24266, 38988 }, + { 24271, 39932 }, + { 24272, 39931 }, + { 24275, 35430 }, + { 24278, 40000 }, + { 24282, 40003 }, + { 24283, 40004 }, + { 24285, 40002 }, + { 24287, 38239 }, + { 24288, 36785 }, + { 24289, 40006 }, + { 24290, 40005 }, + { 24291, 40001 }, + { 24296, 40007 }, + { 24297, 40008 }, + { 24300, 40009 }, + { 24304, 40012 }, + { 24305, 40010 }, + { 24307, 40011 }, + { 24308, 40013 }, + { 24310, 35204 }, + { 24311, 37612 }, + { 24312, 40014 }, + { 24314, 35994 }, + { 24315, 35316 }, + { 24316, 37973 }, + { 24318, 40015 }, + { 24319, 37881 }, + { 24321, 38361 }, + { 24323, 40016 }, + { 24324, 38989 }, + { 24329, 40017 }, + { 24330, 38334 }, + { 24331, 40020 }, + { 24332, 39071 }, + { 24333, 39087 }, + { 24335, 36526 }, + { 24336, 37875 }, + { 24337, 40021 }, + { 24339, 35708 }, + { 24340, 37538 }, + { 24341, 35064 }, + { 24342, 40022 }, + { 24343, 38308 }, + { 24344, 36175 }, + { 24347, 37487 }, + { 24351, 37613 }, + { 24353, 64183 }, + { 24357, 38637 }, + { 24358, 36023 }, + { 24359, 36042 }, + { 24361, 40023 }, + { 24365, 40024 }, + { 24367, 40030 }, + { 24369, 36579 }, + { 24372, 64184 }, + { 24373, 37539 }, + { 24375, 35757 }, + { 24376, 40025 }, + { 24380, 38218 }, + { 24382, 37477 }, + { 24385, 40026 }, + { 24389, 64103 }, + { 24392, 40027 }, + { 24394, 35758 }, + { 24396, 40028 }, + { 24398, 40029 }, + { 24401, 40031 }, + { 24403, 37782 }, + { 24406, 40032 }, + { 24407, 40033 }, + { 24409, 40034 }, + { 24412, 40019 }, + { 24413, 40018 }, + { 24417, 40035 }, + { 24418, 35936 }, + { 24422, 38214 }, + { 24423, 64185 }, + { 24425, 36298 }, + { 24426, 38230 }, + { 24427, 37540 }, + { 24428, 38250 }, + { 24429, 40036 }, + { 24432, 36786 }, + { 24433, 35173 }, + { 24435, 40037 }, + { 24439, 40038 }, + { 24441, 38640 }, + { 24444, 38110 }, + { 24447, 40041 }, + { 24448, 35229 }, + { 24449, 37034 }, + { 24450, 40040 }, + { 24451, 40039 }, + { 24452, 35937 }, + { 24453, 37330 }, + { 24455, 40045 }, + { 24456, 40043 }, + { 24458, 40042 }, + { 24459, 38821 }, + { 24460, 36067 }, + { 24464, 36761 }, + { 24465, 40044 }, + { 24466, 37739 }, + { 24467, 36701 }, + { 24471, 37822 }, + { 24472, 40048 }, + { 24473, 40047 }, + { 24478, 40046 }, + { 24480, 40049 }, + { 24481, 36068 }, + { 24488, 40050 }, + { 24489, 38300 }, + { 24490, 36730 }, + { 24493, 40051 }, + { 24494, 38135 }, + { 24499, 37823 }, + { 24500, 37541 }, + { 24503, 64186 }, + { 24505, 37711 }, + { 24508, 40052 }, + { 24509, 35658 }, + { 24515, 36947 }, + { 24517, 38219 }, + { 24524, 35573 }, + { 24525, 37957 }, + { 24534, 40053 }, + { 24535, 36469 }, + { 24536, 38489 }, + { 24537, 38490 }, + { 24540, 35230 }, + { 24541, 40058 }, + { 24542, 64187 }, + { 24544, 37513 }, + { 24548, 40055 }, + { 24555, 35317 }, + { 24560, 40107 }, + { 24561, 40057 }, + { 24565, 37967 }, + { 24568, 40056 }, + { 24571, 40054 }, + { 24573, 36250 }, + { 24575, 40060 }, + { 24590, 40067 }, + { 24591, 40073 }, + { 24592, 40065 }, + { 24594, 37755 }, + { 24597, 40070 }, + { 24598, 38268 }, + { 24601, 40064 }, + { 24603, 40069 }, + { 24604, 38885 }, + { 24605, 36470 }, + { 24608, 37331 }, + { 24609, 40061 }, + { 24613, 35709 }, + { 24614, 40072 }, + { 24615, 37035 }, + { 24616, 35205 }, + { 24617, 40066 }, + { 24618, 35318 }, + { 24619, 40071 }, + { 24623, 35759 }, + { 24625, 40068 }, + { 24634, 40074 }, + { 24641, 40076 }, + { 24642, 40086 }, + { 24643, 40084 }, + { 24646, 40081 }, + { 24650, 40080 }, + { 24651, 38902 }, + { 24653, 40082 }, + { 24656, 35760 }, + { 24658, 36176 }, + { 24661, 36762 }, + { 24665, 40089 }, + { 24666, 40075 }, + { 24669, 64188 }, + { 24671, 40079 }, + { 24672, 40062 }, + { 24674, 35320 }, + { 24675, 40083 }, + { 24676, 40085 }, + { 24677, 37488 }, + { 24680, 36262 }, + { 24681, 35254 }, + { 24682, 40077 }, + { 24683, 40088 }, + { 24684, 40087 }, + { 24685, 35761 }, + { 24687, 37287 }, + { 24688, 35462 }, + { 24693, 35938 }, + { 24695, 40078 }, + { 24705, 40090 }, + { 24707, 40093 }, + { 24708, 40095 }, + { 24709, 64189 }, + { 24713, 36539 }, + { 24714, 64190 }, + { 24715, 40101 }, + { 24716, 37614 }, + { 24717, 40091 }, + { 24722, 40099 }, + { 24724, 35319 }, + { 24726, 40097 }, + { 24727, 40098 }, + { 24730, 40094 }, + { 24731, 40096 }, + { 24735, 36069 }, + { 24736, 38729 }, + { 24739, 35507 }, + { 24742, 35192 }, + { 24743, 40100 }, + { 24745, 37977 }, + { 24746, 34987 }, + { 24754, 38111 }, + { 24755, 40059 }, + { 24756, 40106 }, + { 24757, 40110 }, + { 24758, 38627 }, + { 24760, 40103 }, + { 24764, 37769 }, + { 24765, 40108 }, + { 24773, 36846 }, + { 24774, 40109 }, + { 24775, 37845 }, + { 24785, 39014 }, + { 24787, 40105 }, + { 24789, 64192 }, + { 24792, 40111 }, + { 24794, 36251 }, + { 24796, 37065 }, + { 24798, 64191 }, + { 24799, 35026 }, + { 24800, 40104 }, + { 24801, 40102 }, + { 24803, 37241 }, + { 24807, 40092 }, + { 24808, 36435 }, + { 24816, 37316 }, + { 24817, 40123 }, + { 24818, 64194 }, + { 24819, 37242 }, + { 24820, 40118 }, + { 24822, 40115 }, + { 24823, 40116 }, + { 24825, 36580 }, + { 24826, 40119 }, + { 24827, 40122 }, + { 24832, 40117 }, + { 24833, 36676 }, + { 24835, 40120 }, + { 24838, 40114 }, + { 24840, 38650 }, + { 24841, 38649 }, + { 24845, 40124 }, + { 24846, 40125 }, + { 24847, 35027 }, + { 24849, 64195 }, + { 24853, 40113 }, + { 24858, 35824 }, + { 24859, 34980 }, + { 24863, 35508 }, + { 24864, 64193 }, + { 24865, 40121 }, + { 24871, 40129 }, + { 24872, 40128 }, + { 24876, 40133 }, + { 24880, 64197 }, + { 24884, 40134 }, + { 24887, 64196 }, + { 24892, 40132 }, + { 24893, 40135 }, + { 24894, 40127 }, + { 24895, 40131 }, + { 24898, 40136 }, + { 24900, 40137 }, + { 24903, 40126 }, + { 24904, 36508 }, + { 24906, 40130 }, + { 24907, 37332 }, + { 24908, 36177 }, + { 24909, 40112 }, + { 24910, 36948 }, + { 24915, 40150 }, + { 24917, 38375 }, + { 24920, 40140 }, + { 24921, 40141 }, + { 24922, 40142 }, + { 24925, 40149 }, + { 24927, 40148 }, + { 24930, 38557 }, + { 24931, 35509 }, + { 24933, 40146 }, + { 24935, 35940 }, + { 24936, 35411 }, + { 24939, 40143 }, + { 24942, 38838 }, + { 24943, 40145 }, + { 24944, 35028 }, + { 24945, 40147 }, + { 24947, 40138 }, + { 24948, 40144 }, + { 24949, 40151 }, + { 24950, 35939 }, + { 24951, 40139 }, + { 24958, 38780 }, + { 24962, 38730 }, + { 24967, 40154 }, + { 24970, 40158 }, + { 24974, 37278 }, + { 24976, 38903 }, + { 24977, 40159 }, + { 24980, 40156 }, + { 24982, 40153 }, + { 24984, 64198 }, + { 24985, 40152 }, + { 24986, 40157 }, + { 24996, 38318 }, + { 24999, 37810 }, + { 25001, 35941 }, + { 25003, 40160 }, + { 25004, 40155 }, + { 25006, 40161 }, + { 25010, 35995 }, + { 25014, 35247 }, + { 25018, 40169 }, + { 25022, 35510 }, + { 25027, 40167 }, + { 25030, 40168 }, + { 25031, 36263 }, + { 25032, 40166 }, + { 25033, 40164 }, + { 25034, 40163 }, + { 25035, 40170 }, + { 25036, 40162 }, + { 25037, 40172 }, + { 25040, 35321 }, + { 25059, 40174 }, + { 25062, 40173 }, + { 25074, 37542 }, + { 25076, 40177 }, + { 25078, 40175 }, + { 25079, 40165 }, + { 25080, 35996 }, + { 25082, 40176 }, + { 25084, 40180 }, + { 25085, 40179 }, + { 25086, 40181 }, + { 25087, 40178 }, + { 25088, 40182 }, + { 25096, 40183 }, + { 25097, 40184 }, + { 25098, 38376 }, + { 25100, 40186 }, + { 25101, 40185 }, + { 25102, 36702 }, + { 25104, 37036 }, + { 25105, 35300 }, + { 25106, 35322 }, + { 25107, 64199 }, + { 25108, 40187 }, + { 25110, 35005 }, + { 25114, 37066 }, + { 25115, 40188 }, + { 25117, 59073 }, + { 25118, 40256 }, + { 25119, 35969 }, + { 25121, 40257 }, + { 25126, 37101 }, + { 25130, 40258 }, + { 25134, 40259 }, + { 25135, 35673 }, + { 25136, 40260 }, + { 25138, 40261 }, + { 25139, 40262 }, + { 25140, 37333 }, + { 25144, 36043 }, + { 25147, 38623 }, + { 25151, 38491 }, + { 25152, 36746 }, + { 25153, 40263 }, + { 25159, 37102 }, + { 25160, 59323 }, + { 25161, 38112 }, + { 25163, 36584 }, + { 25165, 36299 }, + { 25166, 40264 }, + { 25171, 37317 }, + { 25173, 38309 }, + { 25176, 37359 }, + { 25179, 40267 }, + { 25182, 40265 }, + { 25184, 40268 }, + { 25187, 40266 }, + { 25192, 40269 }, + { 25198, 38319 }, + { 25201, 34997 }, + { 25206, 38269 }, + { 25209, 38113 }, + { 25212, 40270 }, + { 25214, 40273 }, + { 25215, 36787 }, + { 25216, 35674 }, + { 25218, 40271 }, + { 25219, 40278 }, + { 25220, 36788 }, + { 25225, 40272 }, + { 25226, 37987 }, + { 25233, 38781 }, + { 25234, 40274 }, + { 25235, 40275 }, + { 25236, 40279 }, + { 25237, 37770 }, + { 25238, 40276 }, + { 25239, 36178 }, + { 25240, 37084 }, + { 25243, 40293 }, + { 25244, 38066 }, + { 25246, 37360 }, + { 25254, 64200 }, + { 25259, 38114 }, + { 25260, 40363 }, + { 25265, 38392 }, + { 25269, 37615 }, + { 25273, 38549 }, + { 25275, 40282 }, + { 25276, 35231 }, + { 25277, 37514 }, + { 25282, 40291 }, + { 25285, 37459 }, + { 25286, 40285 }, + { 25287, 40292 }, + { 25288, 40287 }, + { 25289, 40294 }, + { 25290, 40290 }, + { 25292, 40289 }, + { 25293, 38031 }, + { 25295, 40283 }, + { 25296, 35323 }, + { 25297, 40281 }, + { 25298, 35729 }, + { 25299, 37361 }, + { 25300, 40277 }, + { 25303, 40280 }, + { 25304, 36179 }, + { 25305, 37081 }, + { 25307, 36789 }, + { 25308, 40288 }, + { 25309, 38001 }, + { 25312, 35730 }, + { 25313, 35431 }, + { 25324, 35463 }, + { 25325, 36928 }, + { 25326, 40296 }, + { 25327, 40301 }, + { 25329, 40297 }, + { 25331, 35997 }, + { 25333, 40302 }, + { 25334, 36417 }, + { 25335, 36233 }, + { 25342, 36677 }, + { 25343, 40284 }, + { 25345, 36509 }, + { 25346, 40299 }, + { 25351, 36471 }, + { 25352, 40300 }, + { 25353, 35010 }, + { 25356, 40295 }, + { 25361, 37543 }, + { 25369, 35731 }, + { 25375, 35762 }, + { 25383, 40298 }, + { 25384, 34981 }, + { 25387, 36289 }, + { 25391, 36949 }, + { 25402, 37616 }, + { 25405, 38098 }, + { 25406, 40304 }, + { 25407, 37245 }, + { 25417, 37288 }, + { 25420, 36426 }, + { 25421, 40305 }, + { 25423, 40307 }, + { 25424, 40303 }, + { 25429, 38367 }, + { 25431, 37563 }, + { 25436, 37243 }, + { 25447, 38393 }, + { 25448, 36556 }, + { 25449, 40320 }, + { 25451, 40318 }, + { 25454, 37016 }, + { 25458, 35998 }, + { 25462, 40312 }, + { 25463, 36791 }, + { 25466, 37862 }, + { 25467, 37968 }, + { 25472, 40310 }, + { 25475, 37244 }, + { 25480, 36598 }, + { 25481, 40315 }, + { 25484, 36790 }, + { 25486, 40309 }, + { 25487, 40314 }, + { 25490, 38002 }, + { 25494, 40308 }, + { 25496, 35904 }, + { 25499, 35452 }, + { 25503, 40316 }, + { 25504, 38825 }, + { 25505, 36300 }, + { 25506, 37460 }, + { 25507, 40313 }, + { 25509, 37082 }, + { 25511, 36180 }, + { 25512, 36996 }, + { 25513, 35206 }, + { 25514, 37211 }, + { 25515, 40311 }, + { 25516, 35684 }, + { 25522, 35942 }, + { 25524, 37581 }, + { 25525, 40317 }, + { 25531, 37246 }, + { 25534, 40321 }, + { 25536, 40323 }, + { 25539, 37301 }, + { 25540, 40329 }, + { 25542, 40324 }, + { 25545, 40326 }, + { 25551, 38240 }, + { 25552, 37617 }, + { 25554, 40327 }, + { 25558, 38731 }, + { 25562, 38759 }, + { 25563, 35511 }, + { 25569, 34988 }, + { 25571, 40325 }, + { 25577, 40322 }, + { 25582, 35574 }, + { 25588, 35207 }, + { 25589, 64201 }, + { 25590, 40328 }, + { 25594, 38760 }, + { 25606, 40332 }, + { 25613, 37305 }, + { 25615, 40339 }, + { 25619, 40333 }, + { 25622, 40330 }, + { 25623, 40337 }, + { 25628, 40306 }, + { 25638, 40334 }, + { 25640, 40338 }, + { 25644, 38080 }, + { 25645, 37771 }, + { 25652, 40331 }, + { 25654, 40335 }, + { 25658, 35943 }, + { 25662, 36335 }, + { 25666, 37083 }, + { 25678, 40343 }, + { 25688, 37701 }, + { 25696, 64202 }, + { 25703, 40340 }, + { 25705, 38528 }, + { 25711, 40341 }, + { 25718, 40342 }, + { 25720, 38604 }, + { 25722, 37024 }, + { 25731, 35970 }, + { 25736, 40349 }, + { 25746, 36436 }, + { 25747, 40346 }, + { 25749, 40345 }, + { 25754, 37969 }, + { 25757, 64203 }, + { 25758, 37811 }, + { 25764, 37712 }, + { 25765, 40347 }, + { 25769, 40348 }, + { 25771, 38287 }, + { 25773, 37988 }, + { 25774, 36418 }, + { 25776, 37103 }, + { 25778, 38511 }, + { 25785, 35432 }, + { 25787, 40355 }, + { 25788, 40350 }, + { 25793, 38761 }, + { 25794, 40357 }, + { 25797, 40353 }, + { 25799, 40354 }, + { 25805, 37248 }, + { 25806, 64204 }, + { 25810, 40352 }, + { 25812, 40286 }, + { 25816, 40356 }, + { 25818, 40351 }, + { 25824, 40361 }, + { 25825, 40362 }, + { 25826, 37702 }, + { 25827, 40364 }, + { 25830, 36419 }, + { 25831, 40359 }, + { 25836, 35675 }, + { 25839, 40365 }, + { 25841, 40358 }, + { 25842, 40369 }, + { 25844, 40368 }, + { 25846, 40367 }, + { 25850, 40370 }, + { 25853, 40372 }, + { 25854, 36847 }, + { 25856, 40371 }, + { 25861, 40375 }, + { 25880, 40373 }, + { 25884, 40374 }, + { 25885, 40336 }, + { 25891, 40377 }, + { 25892, 40376 }, + { 25898, 40344 }, + { 25899, 40378 }, + { 25900, 40366 }, + { 25903, 36472 }, + { 25908, 40379 }, + { 25909, 40380 }, + { 25910, 40382 }, + { 25911, 40381 }, + { 25912, 40383 }, + { 25913, 35324 }, + { 25915, 36181 }, + { 25918, 38394 }, + { 25919, 37037 }, + { 25925, 36044 }, + { 25928, 40385 }, + { 25933, 40388 }, + { 25934, 64205 }, + { 25935, 38257 }, + { 25937, 35710 }, + { 25941, 40387 }, + { 25942, 40386 }, + { 25943, 38003 }, + { 25944, 40389 }, + { 25945, 35763 }, + { 25949, 40391 }, + { 25950, 40390 }, + { 25954, 35512 }, + { 25955, 36437 }, + { 25958, 37846 }, + { 25964, 35944 }, + { 25968, 37012 }, + { 25970, 40392 }, + { 25972, 37038 }, + { 25973, 37703 }, + { 25975, 38270 }, + { 25976, 40393 }, + { 25986, 40394 }, + { 25987, 40395 }, + { 25991, 38326 }, + { 25992, 39804 }, + { 25993, 37060 }, + { 25996, 38251 }, + { 25998, 36310 }, + { 26000, 38115 }, + { 26001, 38081 }, + { 26007, 37740 }, + { 26009, 38847 }, + { 26011, 40397 }, + { 26012, 36558 }, + { 26015, 40398 }, + { 26017, 34996 }, + { 26020, 35794 }, + { 26021, 37067 }, + { 26023, 38272 }, + { 26027, 40399 }, + { 26028, 36449 }, + { 26029, 37478 }, + { 26031, 36474 }, + { 26032, 36950 }, + { 26039, 40400 }, + { 26041, 38395 }, + { 26044, 35223 }, + { 26045, 36475 }, + { 26049, 40403 }, + { 26051, 40401 }, + { 26052, 40404 }, + { 26053, 38839 }, + { 26054, 40402 }, + { 26059, 37113 }, + { 26060, 40405 }, + { 26063, 37296 }, + { 26066, 40406 }, + { 26071, 35576 }, + { 26073, 40408 }, + { 26075, 40407 }, + { 26080, 40409 }, + { 26081, 40410 }, + { 26082, 35577 }, + { 26085, 37882 }, + { 26086, 37461 }, + { 26087, 35724 }, + { 26088, 36476 }, + { 26089, 37249 }, + { 26092, 36731 }, + { 26093, 34990 }, + { 26097, 40411 }, + { 26106, 35232 }, + { 26107, 40415 }, + { 26112, 64206 }, + { 26114, 36182 }, + { 26115, 40414 }, + { 26118, 36265 }, + { 26119, 36792 }, + { 26121, 64209 }, + { 26122, 40413 }, + { 26124, 36793 }, + { 26126, 38590 }, + { 26127, 36264 }, + { 26131, 35029 }, + { 26132, 37068 }, + { 26133, 64207 }, + { 26140, 40420 }, + { 26142, 64211 }, + { 26143, 37039 }, + { 26144, 35174 }, + { 26148, 64212 }, + { 26149, 36724 }, + { 26151, 38534 }, + { 26152, 36336 }, + { 26157, 36794 }, + { 26158, 64210 }, + { 26159, 37029 }, + { 26161, 64099 }, + { 26164, 40419 }, + { 26165, 40417 }, + { 26166, 40418 }, + { 26171, 64208 }, + { 26172, 37515 }, + { 26175, 40517 }, + { 26177, 40424 }, + { 26178, 36510 }, + { 26179, 36183 }, + { 26180, 40422 }, + { 26185, 40423 }, + { 26187, 36951 }, + { 26191, 40421 }, + { 26194, 36430 }, + { 26199, 64214 }, + { 26201, 64215 }, + { 26205, 40426 }, + { 26206, 40425 }, + { 26207, 40430 }, + { 26210, 40431 }, + { 26212, 40427 }, + { 26213, 64213 }, + { 26214, 35393 }, + { 26215, 40428 }, + { 26216, 40429 }, + { 26217, 38099 }, + { 26222, 38273 }, + { 26223, 35945 }, + { 26224, 40432 }, + { 26227, 64217 }, + { 26228, 37040 }, + { 26230, 36795 }, + { 26234, 37489 }, + { 26241, 35781 }, + { 26243, 40433 }, + { 26244, 40437 }, + { 26247, 35273 }, + { 26248, 40434 }, + { 26249, 40436 }, + { 26254, 40435 }, + { 26257, 36747 }, + { 26262, 37479 }, + { 26263, 35011 }, + { 26264, 40438 }, + { 26265, 64218 }, + { 26269, 40439 }, + { 26272, 64219 }, + { 26274, 37544 }, + { 26278, 38895 }, + { 26283, 36450 }, + { 26286, 38377 }, + { 26290, 64220 }, + { 26292, 38492 }, + { 26296, 40513 }, + { 26297, 40441 }, + { 26300, 40444 }, + { 26302, 40443 }, + { 26303, 64221 }, + { 26305, 40440 }, + { 26308, 40512 }, + { 26311, 37852 }, + { 26313, 40442 }, + { 26326, 40514 }, + { 26329, 36748 }, + { 26330, 40515 }, + { 26332, 38762 }, + { 26333, 38040 }, + { 26336, 40516 }, + { 26342, 40518 }, + { 26345, 40519 }, + { 26352, 40520 }, + { 26354, 35784 }, + { 26355, 35175 }, + { 26356, 36184 }, + { 26357, 40521 }, + { 26359, 40522 }, + { 26360, 36753 }, + { 26361, 37250 }, + { 26362, 64222 }, + { 26363, 64102 }, + { 26364, 39382 }, + { 26365, 37213 }, + { 26366, 37212 }, + { 26367, 37334 }, + { 26368, 36293 }, + { 26371, 39152 }, + { 26376, 35982 }, + { 26377, 38732 }, + { 26379, 38396 }, + { 26381, 38302 }, + { 26382, 64223 }, + { 26383, 40523 }, + { 26388, 36337 }, + { 26389, 37565 }, + { 26390, 40524 }, + { 26391, 38990 }, + { 26395, 38493 }, + { 26397, 37545 }, + { 26398, 40525 }, + { 26399, 35578 }, + { 26406, 40526 }, + { 26407, 40527 }, + { 26408, 38616 }, + { 26410, 38562 }, + { 26411, 38550 }, + { 26412, 38523 }, + { 26413, 36420 }, + { 26414, 40529 }, + { 26417, 36585 }, + { 26420, 38512 }, + { 26422, 40531 }, + { 26423, 40534 }, + { 26424, 40533 }, + { 26426, 35575 }, + { 26429, 35712 }, + { 26431, 40530 }, + { 26433, 40532 }, + { 26438, 40535 }, + { 26441, 37017 }, + { 26446, 38811 }, + { 26447, 35015 }, + { 26448, 36318 }, + { 26449, 37306 }, + { 26451, 36571 }, + { 26454, 36849 }, + { 26457, 40538 }, + { 26460, 37741 }, + { 26462, 40536 }, + { 26463, 37289 }, + { 26464, 40537 }, + { 26465, 36848 }, + { 26466, 38619 }, + { 26467, 40539 }, + { 26468, 40540 }, + { 26469, 38792 }, + { 26470, 64225 }, + { 26474, 40545 }, + { 26477, 36185 }, + { 26479, 38004 }, + { 26480, 40542 }, + { 26481, 37772 }, + { 26482, 40412 }, + { 26483, 40416 }, + { 26485, 35694 }, + { 26487, 37990 }, + { 26492, 40544 }, + { 26494, 36796 }, + { 26495, 38082 }, + { 26501, 40550 }, + { 26503, 38136 }, + { 26505, 40541 }, + { 26507, 40547 }, + { 26508, 40546 }, + { 26512, 37069 }, + { 26517, 38541 }, + { 26519, 38865 }, + { 26522, 38535 }, + { 26524, 35274 }, + { 26525, 36477 }, + { 26528, 39015 }, + { 26529, 40549 }, + { 26530, 37013 }, + { 26534, 40548 }, + { 26537, 40543 }, + { 26543, 36045 }, + { 26547, 40555 }, + { 26548, 40553 }, + { 26550, 35275 }, + { 26551, 40551 }, + { 26552, 40557 }, + { 26553, 40563 }, + { 26555, 64226 }, + { 26560, 64228 }, + { 26561, 37318 }, + { 26564, 38335 }, + { 26566, 40565 }, + { 26570, 38209 }, + { 26574, 40564 }, + { 26575, 38032 }, + { 26576, 38494 }, + { 26577, 35513 }, + { 26579, 37109 }, + { 26580, 36703 }, + { 26584, 37585 }, + { 26586, 38733 }, + { 26589, 40560 }, + { 26590, 40559 }, + { 26594, 40561 }, + { 26596, 40558 }, + { 26599, 40566 }, + { 26601, 40556 }, + { 26604, 40554 }, + { 26606, 40562 }, + { 26607, 40552 }, + { 26609, 37516 }, + { 26611, 38646 }, + { 26612, 36548 }, + { 26613, 36338 }, + { 26619, 36280 }, + { 26622, 38543 }, + { 26623, 35424 }, + { 26625, 64229 }, + { 26626, 37580 }, + { 26627, 37832 }, + { 26628, 35176 }, + { 26643, 37104 }, + { 26646, 37042 }, + { 26647, 35913 }, + { 26654, 40568 }, + { 26657, 36186 }, + { 26658, 35484 }, + { 26665, 40570 }, + { 26666, 35476 }, + { 26667, 40577 }, + { 26674, 40573 }, + { 26676, 37105 }, + { 26680, 35434 }, + { 26681, 36266 }, + { 26684, 35433 }, + { 26685, 36301 }, + { 26688, 40571 }, + { 26689, 35973 }, + { 26690, 35946 }, + { 26691, 37773 }, + { 26692, 64230 }, + { 26694, 40569 }, + { 26696, 35012 }, + { 26701, 40572 }, + { 26702, 40574 }, + { 26704, 35787 }, + { 26705, 35915 }, + { 26706, 64227 }, + { 26707, 35514 }, + { 26708, 35690 }, + { 26713, 40578 }, + { 26716, 36343 }, + { 26717, 38545 }, + { 26719, 36438 }, + { 26723, 40579 }, + { 26727, 38223 }, + { 26740, 40591 }, + { 26742, 35249 }, + { 26743, 40580 }, + { 26750, 40597 }, + { 26751, 40581 }, + { 26753, 38848 }, + { 26755, 40588 }, + { 26757, 38014 }, + { 26765, 40596 }, + { 26767, 40583 }, + { 26771, 34994 }, + { 26772, 40585 }, + { 26775, 36187 }, + { 26779, 40587 }, + { 26781, 40586 }, + { 26783, 40582 }, + { 26784, 40593 }, + { 26786, 36797 }, + { 26790, 39659 }, + { 26791, 36070 }, + { 26792, 38812 }, + { 26797, 40584 }, + { 26799, 37618 }, + { 26800, 35394 }, + { 26801, 36267 }, + { 26803, 40576 }, + { 26805, 40592 }, + { 26806, 35457 }, + { 26809, 40590 }, + { 26810, 40594 }, + { 26812, 37774 }, + { 26820, 35580 }, + { 26822, 40624 }, + { 26824, 64100 }, + { 26825, 38599 }, + { 26826, 40599 }, + { 26827, 35579 }, + { 26829, 40606 }, + { 26831, 64231 }, + { 26834, 38495 }, + { 26836, 40607 }, + { 26837, 40609 }, + { 26839, 40613 }, + { 26840, 40601 }, + { 26842, 37449 }, + { 26847, 37775 }, + { 26848, 40617 }, + { 26849, 40604 }, + { 26851, 40614 }, + { 26855, 40608 }, + { 26862, 36952 }, + { 26863, 40618 }, + { 26866, 37041 }, + { 26873, 40616 }, + { 26874, 35515 }, + { 26880, 39023 }, + { 26881, 40598 }, + { 26884, 40612 }, + { 26885, 35030 }, + { 26888, 40600 }, + { 26891, 38584 }, + { 26892, 40605 }, + { 26893, 36929 }, + { 26894, 37573 }, + { 26895, 40595 }, + { 26898, 40611 }, + { 26905, 37018 }, + { 26906, 40621 }, + { 26907, 35473 }, + { 26908, 35999 }, + { 26913, 40623 }, + { 26914, 40602 }, + { 26915, 40622 }, + { 26917, 40615 }, + { 26918, 40603 }, + { 26920, 40619 }, + { 26922, 40620 }, + { 26928, 40637 }, + { 26932, 37836 }, + { 26934, 40610 }, + { 26937, 40633 }, + { 26941, 40635 }, + { 26943, 37590 }, + { 26954, 38763 }, + { 26963, 38294 }, + { 26964, 40630 }, + { 26965, 37320 }, + { 26969, 40636 }, + { 26970, 37214 }, + { 26972, 40627 }, + { 26973, 40640 }, + { 26974, 40639 }, + { 26976, 37869 }, + { 26977, 40638 }, + { 26978, 37864 }, + { 26984, 64233 }, + { 26986, 40642 }, + { 26987, 40629 }, + { 26989, 35782 }, + { 26990, 40632 }, + { 26991, 36732 }, + { 26995, 38016 }, + { 26996, 40634 }, + { 26997, 35785 }, + { 26999, 40626 }, + { 27000, 40628 }, + { 27001, 40625 }, + { 27004, 38991 }, + { 27005, 35449 }, + { 27006, 40631 }, + { 27009, 40641 }, + { 27010, 35412 }, + { 27018, 36325 }, + { 27022, 35196 }, + { 27025, 40658 }, + { 27028, 38992 }, + { 27029, 40661 }, + { 27032, 64235 }, + { 27035, 36953 }, + { 27036, 40660 }, + { 27040, 40659 }, + { 27047, 40656 }, + { 27054, 40644 }, + { 27057, 40673 }, + { 27058, 40643 }, + { 27060, 40662 }, + { 27067, 40654 }, + { 27070, 40649 }, + { 27071, 40646 }, + { 27073, 40647 }, + { 27075, 40655 }, + { 27079, 60064 }, + { 27082, 40652 }, + { 27083, 36188 }, + { 27084, 37574 }, + { 27085, 37252 }, + { 27086, 40650 }, + { 27088, 40645 }, + { 27091, 40648 }, + { 27096, 38764 }, + { 27097, 38538 }, + { 27101, 40653 }, + { 27102, 40663 }, + { 27106, 64236 }, + { 27111, 40671 }, + { 27112, 40664 }, + { 27115, 40677 }, + { 27117, 40675 }, + { 27122, 40670 }, + { 27129, 40669 }, + { 27131, 37582 }, + { 27133, 37253 }, + { 27135, 40667 }, + { 27138, 40665 }, + { 27141, 40672 }, + { 27146, 40678 }, + { 27147, 38131 }, + { 27148, 40684 }, + { 27154, 40679 }, + { 27155, 40682 }, + { 27156, 40676 }, + { 27159, 37524 }, + { 27161, 38231 }, + { 27163, 40666 }, + { 27166, 40674 }, + { 27167, 36798 }, + { 27169, 38605 }, + { 27170, 40694 }, + { 27171, 40681 }, + { 27177, 36000 }, + { 27178, 35233 }, + { 27179, 35454 }, + { 27182, 40657 }, + { 27184, 64237 }, + { 27189, 36799 }, + { 27190, 40686 }, + { 27192, 40693 }, + { 27193, 36599 }, + { 27194, 35474 }, + { 27197, 37453 }, + { 27204, 40683 }, + { 27206, 64239 }, + { 27207, 40688 }, + { 27208, 40692 }, + { 27211, 35764 }, + { 27224, 35691 }, + { 27225, 40690 }, + { 27231, 35648 }, + { 27233, 37833 }, + { 27234, 40689 }, + { 27238, 40691 }, + { 27243, 64238 }, + { 27250, 40685 }, + { 27251, 64240 }, + { 27256, 40687 }, + { 27262, 64241 }, + { 27263, 35456 }, + { 27264, 37480 }, + { 27268, 40698 }, + { 27277, 40696 }, + { 27278, 36071 }, + { 27280, 40695 }, + { 27287, 40768 }, + { 27292, 40567 }, + { 27296, 40697 }, + { 27298, 40699 }, + { 27299, 40700 }, + { 27306, 40779 }, + { 27308, 40775 }, + { 27310, 40589 }, + { 27315, 40774 }, + { 27320, 40773 }, + { 27323, 40770 }, + { 27329, 40680 }, + { 27330, 40772 }, + { 27331, 40771 }, + { 27345, 40777 }, + { 27347, 38981 }, + { 27354, 40780 }, + { 27355, 35833 }, + { 27358, 40776 }, + { 27359, 40778 }, + { 27362, 64242 }, + { 27364, 64243 }, + { 27368, 38053 }, + { 27370, 40781 }, + { 27386, 40785 }, + { 27387, 40782 }, + { 27396, 38803 }, + { 27397, 40783 }, + { 27402, 40668 }, + { 27410, 40786 }, + { 27414, 40787 }, + { 27421, 35156 }, + { 27423, 40789 }, + { 27424, 35975 }, + { 27425, 36511 }, + { 27427, 35795 }, + { 27431, 35234 }, + { 27442, 38782 }, + { 27447, 40791 }, + { 27448, 40790 }, + { 27449, 40793 }, + { 27450, 35676 }, + { 27453, 35796 }, + { 27454, 35516 }, + { 27459, 40796 }, + { 27463, 40795 }, + { 27465, 40797 }, + { 27468, 35276 }, + { 27470, 37462 }, + { 27472, 40798 }, + { 27475, 35517 }, + { 27476, 40800 }, + { 27481, 40799 }, + { 27483, 40801 }, + { 27487, 40802 }, + { 27489, 40803 }, + { 27490, 36478 }, + { 27491, 37043 }, + { 27492, 36255 }, + { 27494, 38288 }, + { 27497, 38368 }, + { 27498, 39011 }, + { 27503, 36501 }, + { 27507, 36302 }, + { 27508, 38896 }, + { 27512, 40804 }, + { 27513, 40805 }, + { 27515, 36480 }, + { 27519, 40806 }, + { 27520, 40807 }, + { 27523, 40809 }, + { 27524, 40808 }, + { 27526, 38519 }, + { 27529, 36733 }, + { 27530, 36586 }, + { 27531, 36451 }, + { 27533, 40810 }, + { 27541, 40812 }, + { 27542, 36930 }, + { 27544, 40811 }, + { 27550, 40813 }, + { 27556, 40814 }, + { 27562, 40815 }, + { 27563, 40816 }, + { 27567, 40817 }, + { 27569, 40819 }, + { 27570, 40818 }, + { 27571, 40820 }, + { 27572, 35235 }, + { 27573, 37481 }, + { 27575, 40821 }, + { 27578, 36421 }, + { 27579, 35435 }, + { 27580, 40822 }, + { 27583, 37729 }, + { 27584, 39626 }, + { 27589, 35650 }, + { 27590, 40823 }, + { 27595, 40824 }, + { 27597, 38378 }, + { 27598, 38536 }, + { 27602, 37829 }, + { 27603, 40825 }, + { 27604, 38116 }, + { 27606, 64244 }, + { 27608, 38137 }, + { 27611, 38609 }, + { 27615, 40826 }, + { 27627, 40828 }, + { 27628, 40827 }, + { 27631, 40830 }, + { 27635, 40829 }, + { 27656, 40833 }, + { 27663, 36481 }, + { 27665, 38575 }, + { 27667, 40834 }, + { 27668, 40835 }, + { 27671, 35651 }, + { 27675, 40836 }, + { 27683, 40838 }, + { 27684, 40837 }, + { 27700, 36997 }, + { 27703, 38232 }, + { 27704, 35177 }, + { 27710, 38083 }, + { 27711, 64245 }, + { 27712, 37619 }, + { 27713, 36704 }, + { 27714, 35713 }, + { 27726, 38084 }, + { 27728, 36524 }, + { 27733, 40840 }, + { 27735, 35518 }, + { 27738, 35224 }, + { 27740, 64246 }, + { 27741, 37872 }, + { 27742, 40839 }, + { 27743, 36189 }, + { 27744, 37490 }, + { 27746, 40841 }, + { 27752, 40849 }, + { 27754, 40842 }, + { 27759, 64248 }, + { 27760, 37311 }, + { 27762, 35714 }, + { 27763, 40850 }, + { 27770, 35976 }, + { 27773, 35652 }, + { 27774, 40848 }, + { 27777, 40846 }, + { 27778, 40843 }, + { 27779, 38784 }, + { 27782, 64247 }, + { 27784, 37566 }, + { 27788, 37847 }, + { 27789, 40844 }, + { 27792, 40852 }, + { 27794, 40851 }, + { 27795, 35906 }, + { 27798, 35243 }, + { 27801, 36281 }, + { 27802, 40845 }, + { 27803, 40847 }, + { 27809, 38518 }, + { 27810, 37362 }, + { 27819, 38551 }, + { 27822, 40860 }, + { 27825, 40861 }, + { 27827, 35277 }, + { 27832, 38310 }, + { 27833, 38651 }, + { 27834, 40863 }, + { 27835, 36513 }, + { 27836, 36800 }, + { 27837, 40856 }, + { 27838, 40862 }, + { 27839, 35208 }, + { 27841, 35765 }, + { 27844, 40853 }, + { 27845, 40858 }, + { 27849, 37106 }, + { 27850, 38033 }, + { 27852, 38117 }, + { 27859, 40855 }, + { 27861, 38464 }, + { 27863, 40857 }, + { 27865, 40866 }, + { 27866, 64249 }, + { 27867, 40864 }, + { 27869, 40859 }, + { 27873, 38465 }, + { 27874, 37991 }, + { 27875, 35715 }, + { 27877, 37700 }, + { 27880, 37517 }, + { 27882, 40867 }, + { 27887, 40865 }, + { 27888, 37335 }, + { 27889, 40854 }, + { 27891, 35178 }, + { 27908, 64250 }, + { 27915, 38765 }, + { 27916, 40878 }, + { 27922, 40877 }, + { 27927, 37108 }, + { 27929, 40874 }, + { 27931, 38796 }, + { 27934, 37812 }, + { 27935, 40868 }, + { 27941, 37571 }, + { 27945, 35179 }, + { 27946, 36190 }, + { 27947, 40871 }, + { 27954, 36678 }, + { 27955, 40876 }, + { 27957, 40875 }, + { 27958, 40870 }, + { 27960, 40873 }, + { 27963, 35464 }, + { 27965, 40872 }, + { 27966, 37992 }, + { 27969, 38828 }, + { 27972, 36850 }, + { 27973, 37107 }, + { 27993, 40884 }, + { 27994, 40882 }, + { 27996, 38252 }, + { 28003, 40879 }, + { 28004, 40881 }, + { 28006, 35161 }, + { 28009, 36191 }, + { 28010, 38993 }, + { 28012, 35420 }, + { 28014, 38274 }, + { 28015, 64252 }, + { 28020, 38785 }, + { 28023, 35395 }, + { 28024, 36954 }, + { 28025, 40883 }, + { 28037, 40888 }, + { 28039, 64251 }, + { 28040, 36801 }, + { 28044, 38735 }, + { 28046, 40885 }, + { 28051, 40880 }, + { 28053, 40886 }, + { 28054, 64320 }, + { 28057, 38876 }, + { 28059, 37779 }, + { 28060, 37824 }, + { 28076, 64321 }, + { 28079, 35413 }, + { 28082, 35188 }, + { 28085, 40892 }, + { 28088, 40895 }, + { 28092, 38849 }, + { 28096, 38788 }, + { 28101, 40902 }, + { 28102, 40896 }, + { 28103, 40893 }, + { 28107, 38866 }, + { 28108, 40899 }, + { 28111, 64322 }, + { 28113, 36713 }, + { 28114, 40901 }, + { 28117, 40906 }, + { 28120, 37777 }, + { 28121, 40904 }, + { 28126, 40898 }, + { 28129, 37463 }, + { 28132, 40905 }, + { 28134, 40894 }, + { 28136, 40900 }, + { 28138, 40907 }, + { 28139, 35066 }, + { 28140, 40897 }, + { 28142, 40908 }, + { 28145, 36955 }, + { 28146, 64324 }, + { 28147, 36734 }, + { 28149, 38307 }, + { 28151, 36268 }, + { 28152, 64323 }, + { 28153, 40889 }, + { 28154, 40903 }, + { 28155, 37721 }, + { 28156, 64325 }, + { 28165, 37044 }, + { 28167, 35465 }, + { 28168, 36303 }, + { 28169, 36802 }, + { 28170, 40891 }, + { 28171, 36705 }, + { 28179, 35947 }, + { 28181, 40890 }, + { 28185, 40912 }, + { 28186, 36749 }, + { 28187, 36024 }, + { 28189, 40927 }, + { 28191, 40921 }, + { 28192, 35732 }, + { 28193, 37742 }, + { 28195, 40916 }, + { 28196, 40925 }, + { 28197, 34989 }, + { 28198, 35153 }, + { 28199, 64328 }, + { 28201, 35255 }, + { 28203, 40918 }, + { 28204, 37290 }, + { 28205, 40909 }, + { 28206, 40911 }, + { 28207, 36192 }, + { 28216, 40928 }, + { 28217, 64326 }, + { 28218, 40923 }, + { 28220, 64329 }, + { 28222, 40915 }, + { 28227, 40922 }, + { 28234, 38569 }, + { 28237, 40920 }, + { 28238, 40924 }, + { 28246, 36046 }, + { 28248, 36803 }, + { 28251, 37464 }, + { 28252, 64327 }, + { 28255, 40914 }, + { 28263, 38734 }, + { 28267, 40917 }, + { 28270, 40910 }, + { 28271, 37778 }, + { 28274, 40913 }, + { 28278, 40919 }, + { 28286, 39024 }, + { 28287, 36540 }, + { 28288, 38558 }, + { 28290, 40929 }, + { 28300, 38060 }, + { 28303, 40941 }, + { 28304, 36025 }, + { 28310, 36736 }, + { 28312, 40931 }, + { 28316, 38829 }, + { 28317, 36193 }, + { 28319, 40944 }, + { 28322, 35052 }, + { 28325, 40942 }, + { 28330, 40930 }, + { 28335, 40936 }, + { 28338, 40938 }, + { 28342, 38766 }, + { 28343, 40933 }, + { 28346, 37709 }, + { 28349, 40935 }, + { 28351, 64330 }, + { 28354, 40943 }, + { 28356, 40937 }, + { 28357, 38597 }, + { 28361, 40932 }, + { 28363, 36512 }, + { 28364, 40956 }, + { 28369, 35466 }, + { 28371, 40934 }, + { 28372, 40939 }, + { 28373, 40940 }, + { 28381, 37354 }, + { 28382, 37336 }, + { 28396, 40948 }, + { 28399, 40954 }, + { 28402, 40952 }, + { 28404, 37704 }, + { 28407, 57410 }, + { 28408, 40949 }, + { 28414, 40950 }, + { 28415, 40926 }, + { 28417, 35737 }, + { 28418, 38233 }, + { 28422, 36541 }, + { 28425, 36247 }, + { 28431, 38994 }, + { 28433, 40946 }, + { 28435, 57409 }, + { 28436, 35209 }, + { 28437, 37254 }, + { 28448, 38041 }, + { 28450, 35519 }, + { 28451, 38904 }, + { 28459, 38559 }, + { 28460, 37584 }, + { 28465, 40953 }, + { 28466, 40955 }, + { 28472, 37201 }, + { 28478, 57408 }, + { 28479, 40951 }, + { 28481, 40945 }, + { 28485, 35521 }, + { 28500, 35977 }, + { 28504, 57422 }, + { 28507, 57417 }, + { 28508, 37110 }, + { 28511, 35459 }, + { 28516, 36737 }, + { 28518, 57426 }, + { 28525, 57419 }, + { 28526, 37546 }, + { 28527, 57416 }, + { 28528, 37591 }, + { 28532, 57451 }, + { 28536, 57413 }, + { 28538, 57412 }, + { 28540, 57421 }, + { 28544, 57415 }, + { 28545, 57414 }, + { 28546, 57420 }, + { 28548, 37023 }, + { 28550, 57411 }, + { 28552, 64331 }, + { 28558, 57423 }, + { 28561, 57424 }, + { 28567, 35520 }, + { 28577, 57429 }, + { 28579, 57428 }, + { 28580, 57430 }, + { 28586, 57433 }, + { 28593, 37730 }, + { 28595, 57427 }, + { 28597, 64332 }, + { 28601, 57431 }, + { 28608, 35971 }, + { 28609, 37367 }, + { 28610, 57425 }, + { 28611, 37978 }, + { 28614, 57432 }, + { 28628, 57437 }, + { 28629, 57435 }, + { 28632, 57438 }, + { 28635, 57441 }, + { 28639, 57434 }, + { 28640, 36234 }, + { 28641, 37959 }, + { 28644, 40887 }, + { 28651, 38804 }, + { 28652, 57436 }, + { 28654, 57440 }, + { 28655, 37363 }, + { 28657, 57439 }, + { 28659, 57418 }, + { 28661, 64333 }, + { 28662, 59529 }, + { 28666, 57444 }, + { 28670, 57448 }, + { 28673, 57446 }, + { 28677, 64334 }, + { 28679, 64335 }, + { 28681, 57442 }, + { 28683, 57443 }, + { 28687, 57447 }, + { 28689, 57445 }, + { 28693, 38253 }, + { 28696, 57453 }, + { 28698, 57450 }, + { 28699, 57449 }, + { 28701, 57452 }, + { 28702, 37842 }, + { 28703, 57454 }, + { 28710, 37525 }, + { 28711, 37355 }, + { 28712, 64336 }, + { 28716, 37027 }, + { 28720, 57455 }, + { 28722, 57457 }, + { 28734, 57456 }, + { 28748, 40947 }, + { 28753, 57458 }, + { 28760, 37861 }, + { 28771, 57459 }, + { 28779, 35278 }, + { 28783, 37780 }, + { 28784, 35396 }, + { 28792, 35716 }, + { 28796, 36572 }, + { 28797, 36304 }, + { 28805, 64337 }, + { 28809, 38982 }, + { 28810, 36998 }, + { 28814, 35210 }, + { 28818, 57461 }, + { 28825, 57460 }, + { 28843, 64338 }, + { 28844, 57464 }, + { 28845, 37465 }, + { 28846, 57467 }, + { 28847, 57462 }, + { 28851, 57466 }, + { 28856, 57465 }, + { 28857, 37727 }, + { 28858, 35031 }, + { 28859, 64098 }, + { 28872, 38899 }, + { 28875, 57469 }, + { 28879, 35143 }, + { 28889, 57472 }, + { 28893, 57470 }, + { 28895, 57468 }, + { 28913, 57463 }, + { 28921, 38466 }, + { 28925, 57474 }, + { 28932, 64340 }, + { 28937, 57473 }, + { 28943, 64339 }, + { 28948, 35211 }, + { 28953, 57476 }, + { 28954, 38320 }, + { 28956, 57475 }, + { 28961, 38579 }, + { 28966, 36805 }, + { 28982, 37202 }, + { 28988, 36804 }, + { 28998, 64342 }, + { 28999, 64343 }, + { 29001, 38905 }, + { 29004, 57482 }, + { 29006, 37111 }, + { 29013, 57478 }, + { 29014, 57483 }, + { 29017, 35212 }, + { 29020, 64341 }, + { 29026, 57481 }, + { 29028, 38017 }, + { 29029, 57477 }, + { 29030, 57480 }, + { 29031, 36806 }, + { 29033, 38095 }, + { 29036, 57484 }, + { 29038, 36559 }, + { 29053, 37112 }, + { 29060, 57487 }, + { 29064, 57479 }, + { 29066, 35910 }, + { 29071, 57485 }, + { 29076, 38767 }, + { 29077, 57488 }, + { 29081, 60068 }, + { 29087, 36718 }, + { 29096, 57489 }, + { 29100, 57490 }, + { 29105, 37965 }, + { 29113, 57492 }, + { 29118, 57493 }, + { 29121, 64345 }, + { 29123, 37970 }, + { 29128, 37781 }, + { 29129, 57495 }, + { 29134, 57497 }, + { 29136, 38867 }, + { 29138, 57494 }, + { 29140, 57496 }, + { 29141, 35213 }, + { 29143, 57491 }, + { 29151, 39546 }, + { 29152, 57498 }, + { 29157, 37255 }, + { 29158, 36439 }, + { 29159, 57500 }, + { 29164, 57499 }, + { 29165, 36931 }, + { 29166, 39383 }, + { 29173, 57501 }, + { 29177, 57503 }, + { 29179, 57486 }, + { 29180, 57502 }, + { 29182, 64346 }, + { 29183, 57504 }, + { 29190, 38042 }, + { 29197, 57505 }, + { 29200, 57506 }, + { 29211, 57507 }, + { 29224, 57508 }, + { 29226, 37596 }, + { 29228, 57510 }, + { 29229, 57509 }, + { 29232, 57511 }, + { 29234, 57512 }, + { 29237, 36573 }, + { 29238, 38275 }, + { 29242, 38634 }, + { 29243, 57513 }, + { 29244, 57514 }, + { 29245, 37237 }, + { 29246, 36514 }, + { 29247, 57515 }, + { 29248, 57516 }, + { 29254, 57517 }, + { 29255, 38352 }, + { 29256, 38085 }, + { 29259, 57518 }, + { 29260, 38006 }, + { 29266, 37547 }, + { 29272, 57519 }, + { 29273, 35301 }, + { 29275, 35725 }, + { 29277, 38596 }, + { 29279, 38580 }, + { 29281, 35250 }, + { 29282, 38995 }, + { 29287, 38513 }, + { 29289, 38312 }, + { 29298, 37045 }, + { 29300, 57520 }, + { 29305, 37825 }, + { 29309, 36001 }, + { 29310, 57521 }, + { 29312, 36306 }, + { 29313, 57523 }, + { 29314, 57522 }, + { 29319, 57524 }, + { 29330, 57525 }, + { 29334, 57526 }, + { 29344, 35677 }, + { 29346, 57527 }, + { 29351, 57528 }, + { 29356, 36002 }, + { 29359, 38086 }, + { 29361, 64347 }, + { 29362, 57530 }, + { 29366, 36851 }, + { 29369, 57529 }, + { 29374, 64348 }, + { 29378, 35766 }, + { 29379, 57531 }, + { 29380, 57533 }, + { 29382, 57532 }, + { 29390, 57534 }, + { 29392, 36047 }, + { 29394, 57535 }, + { 29399, 35815 }, + { 29401, 37215 }, + { 29403, 36253 }, + { 29408, 57537 }, + { 29409, 57538 }, + { 29410, 57536 }, + { 29417, 36587 }, + { 29420, 37830 }, + { 29421, 35767 }, + { 29431, 57540 }, + { 29432, 37451 }, + { 29433, 57539 }, + { 29436, 38996 }, + { 29437, 38018 }, + { 29450, 57543 }, + { 29462, 57545 }, + { 29463, 57542 }, + { 29467, 38610 }, + { 29468, 57544 }, + { 29469, 57546 }, + { 29471, 38850 }, + { 29476, 64349 }, + { 29477, 57550 }, + { 29481, 57549 }, + { 29482, 37526 }, + { 29483, 37964 }, + { 29486, 36003 }, + { 29487, 57548 }, + { 29492, 57547 }, + { 29494, 38736 }, + { 29495, 38737 }, + { 29502, 57551 }, + { 29503, 35214 }, + { 29508, 36246 }, + { 29509, 36482 }, + { 29518, 57552 }, + { 29519, 57553 }, + { 29527, 57555 }, + { 29539, 36706 }, + { 29544, 57557 }, + { 29546, 57556 }, + { 29552, 57558 }, + { 29554, 35436 }, + { 29557, 57560 }, + { 29559, 64351 }, + { 29560, 57559 }, + { 29562, 57562 }, + { 29563, 57561 }, + { 29572, 36026 }, + { 29575, 38822 }, + { 29577, 35786 }, + { 29579, 35236 }, + { 29590, 35816 }, + { 29609, 35551 }, + { 29618, 38886 }, + { 29619, 57564 }, + { 29627, 57566 }, + { 29629, 64352 }, + { 29632, 57567 }, + { 29634, 35279 }, + { 29640, 57563 }, + { 29641, 64353 }, + { 29642, 36440 }, + { 29645, 37567 }, + { 29646, 57565 }, + { 29650, 64356 }, + { 29654, 64354 }, + { 29662, 57570 }, + { 29664, 36588 }, + { 29667, 64355 }, + { 29669, 57568 }, + { 29674, 35933 }, + { 29677, 38087 }, + { 29678, 57569 }, + { 29681, 57596 }, + { 29685, 64358 }, + { 29688, 57575 }, + { 29694, 36027 }, + { 29699, 35717 }, + { 29701, 57572 }, + { 29702, 38813 }, + { 29703, 64357 }, + { 29705, 38830 }, + { 29730, 37364 }, + { 29733, 57574 }, + { 29734, 64359 }, + { 29737, 64361 }, + { 29738, 64360 }, + { 29742, 64362 }, + { 29746, 57576 }, + { 29747, 38868 }, + { 29748, 35797 }, + { 29749, 38138 }, + { 29750, 37993 }, + { 29754, 57577 }, + { 29759, 57579 }, + { 29761, 57582 }, + { 29781, 57578 }, + { 29785, 57581 }, + { 29786, 36072 }, + { 29787, 35180 }, + { 29788, 57583 }, + { 29790, 37008 }, + { 29791, 57580 }, + { 29792, 38874 }, + { 29794, 64363 }, + { 29795, 57586 }, + { 29796, 60066 }, + { 29801, 57584 }, + { 29802, 57587 }, + { 29807, 57573 }, + { 29808, 57585 }, + { 29811, 36282 }, + { 29814, 57588 }, + { 29822, 57589 }, + { 29827, 38814 }, + { 29833, 64364 }, + { 29835, 57590 }, + { 29854, 57591 }, + { 29855, 64365 }, + { 29858, 57571 }, + { 29863, 57592 }, + { 29872, 35522 }, + { 29885, 36515 }, + { 29898, 57593 }, + { 29903, 57594 }, + { 29908, 57595 }, + { 29916, 35162 }, + { 29920, 57664 }, + { 29922, 38234 }, + { 29923, 57665 }, + { 29926, 35490 }, + { 29927, 57666 }, + { 29929, 57667 }, + { 29934, 57668 }, + { 29936, 57670 }, + { 29937, 57671 }, + { 29938, 57669 }, + { 29942, 38258 }, + { 29943, 57673 }, + { 29944, 57672 }, + { 29953, 64366 }, + { 29955, 57675 }, + { 29956, 57674 }, + { 29957, 57676 }, + { 29964, 57677 }, + { 29965, 57679 }, + { 29966, 57678 }, + { 29969, 36249 }, + { 29971, 57681 }, + { 29973, 57680 }, + { 29976, 35523 }, + { 29978, 36978 }, + { 29980, 37723 }, + { 29982, 57682 }, + { 29983, 37046 }, + { 29987, 36441 }, + { 29989, 35225 }, + { 29990, 57683 }, + { 29992, 38768 }, + { 29995, 38369 }, + { 29996, 57684 }, + { 29999, 64168 }, + { 30000, 37731 }, + { 30001, 38738 }, + { 30002, 36194 }, + { 30003, 36956 }, + { 30007, 37482 }, + { 30008, 39346 }, + { 30010, 37548 }, + { 30011, 35302 }, + { 30012, 57685 }, + { 30020, 57686 }, + { 30022, 57691 }, + { 30025, 57689 }, + { 30026, 57688 }, + { 30027, 40384 }, + { 30028, 35397 }, + { 30029, 57687 }, + { 30031, 35032 }, + { 30033, 38056 }, + { 30036, 38088 }, + { 30041, 38831 }, + { 30042, 57692 }, + { 30043, 57690 }, + { 30044, 37499 }, + { 30045, 37028 }, + { 30048, 38057 }, + { 30050, 38220 }, + { 30052, 57694 }, + { 30053, 38826 }, + { 30054, 35948 }, + { 30055, 57695 }, + { 30057, 57693 }, + { 30058, 38100 }, + { 30059, 57696 }, + { 30061, 57697 }, + { 30063, 64367 }, + { 30064, 35033 }, + { 30067, 36852 }, + { 30068, 57702 }, + { 30070, 57699 }, + { 30071, 37867 }, + { 30072, 57698 }, + { 30079, 35653 }, + { 30082, 57705 }, + { 30086, 57700 }, + { 30087, 57701 }, + { 30089, 57704 }, + { 30090, 57703 }, + { 30091, 38212 }, + { 30094, 37217 }, + { 30095, 37216 }, + { 30097, 35678 }, + { 30100, 57706 }, + { 30106, 57707 }, + { 30109, 57708 }, + { 30115, 57710 }, + { 30117, 57709 }, + { 30123, 35189 }, + { 30129, 57718 }, + { 30130, 38118 }, + { 30131, 57712 }, + { 30133, 57714 }, + { 30136, 57716 }, + { 30137, 36957 }, + { 30140, 57717 }, + { 30141, 57715 }, + { 30142, 36542 }, + { 30146, 57711 }, + { 30147, 57713 }, + { 30149, 38241 }, + { 30151, 36807 }, + { 30154, 57720 }, + { 30157, 57719 }, + { 30162, 57721 }, + { 30164, 36516 }, + { 30165, 36269 }, + { 30168, 37783 }, + { 30169, 57722 }, + { 30171, 37577 }, + { 30174, 57724 }, + { 30178, 38815 }, + { 30179, 57723 }, + { 30185, 37257 }, + { 30192, 57730 }, + { 30194, 57732 }, + { 30195, 57733 }, + { 30196, 37491 }, + { 30202, 57731 }, + { 30204, 57728 }, + { 30206, 57725 }, + { 30207, 57726 }, + { 30209, 57729 }, + { 30217, 57736 }, + { 30219, 57734 }, + { 30221, 57735 }, + { 30239, 57737 }, + { 30240, 57739 }, + { 30241, 57740 }, + { 30242, 57741 }, + { 30244, 57742 }, + { 30247, 57738 }, + { 30256, 57744 }, + { 30260, 57743 }, + { 30267, 57745 }, + { 30274, 38851 }, + { 30278, 57748 }, + { 30279, 57746 }, + { 30280, 57747 }, + { 30284, 35552 }, + { 30290, 38652 }, + { 30294, 38344 }, + { 30296, 57750 }, + { 30300, 57749 }, + { 30305, 57751 }, + { 30306, 57752 }, + { 30311, 57756 }, + { 30312, 57753 }, + { 30313, 57754 }, + { 30314, 57755 }, + { 30316, 57757 }, + { 30320, 57758 }, + { 30322, 57759 }, + { 30326, 57760 }, + { 30328, 57761 }, + { 30330, 38061 }, + { 30331, 37743 }, + { 30332, 57762 }, + { 30333, 38034 }, + { 30334, 38227 }, + { 30336, 57763 }, + { 30338, 64368 }, + { 30339, 57764 }, + { 30340, 37705 }, + { 30342, 35398 }, + { 30343, 36195 }, + { 30344, 57765 }, + { 30347, 57766 }, + { 30350, 57767 }, + { 30352, 36424 }, + { 30355, 57769 }, + { 30358, 57768 }, + { 30361, 57770 }, + { 30362, 57771 }, + { 30363, 64371 }, + { 30364, 64369 }, + { 30366, 64370 }, + { 30374, 64372 }, + { 30382, 38119 }, + { 30384, 57772 }, + { 30388, 57773 }, + { 30391, 60041 }, + { 30392, 57774 }, + { 30393, 57775 }, + { 30394, 57776 }, + { 30399, 36429 }, + { 30402, 57777 }, + { 30403, 38005 }, + { 30406, 38526 }, + { 30408, 35181 }, + { 30410, 35190 }, + { 30413, 57778 }, + { 30418, 57780 }, + { 30422, 57779 }, + { 30423, 37776 }, + { 30427, 37047 }, + { 30428, 40792 }, + { 30430, 57781 }, + { 30431, 38591 }, + { 30433, 57782 }, + { 30435, 35524 }, + { 30436, 38101 }, + { 30437, 57783 }, + { 30439, 57784 }, + { 30442, 57785 }, + { 30446, 38618 }, + { 30450, 38611 }, + { 30452, 37564 }, + { 30456, 37258 }, + { 30459, 57787 }, + { 30462, 36738 }, + { 30465, 36808 }, + { 30468, 57790 }, + { 30471, 57789 }, + { 30472, 57788 }, + { 30473, 38139 }, + { 30475, 35525 }, + { 30476, 36007 }, + { 30491, 57796 }, + { 30494, 57793 }, + { 30495, 36958 }, + { 30496, 38576 }, + { 30500, 57792 }, + { 30501, 57794 }, + { 30502, 57795 }, + { 30505, 57791 }, + { 30519, 57797 }, + { 30520, 57798 }, + { 30522, 37549 }, + { 30524, 35553 }, + { 30528, 37509 }, + { 30534, 64374 }, + { 30535, 57799 }, + { 30554, 57800 }, + { 30555, 57803 }, + { 30561, 36999 }, + { 30563, 37826 }, + { 30565, 57804 }, + { 30566, 38514 }, + { 30568, 57801 }, + { 30571, 57802 }, + { 30585, 57807 }, + { 30590, 57806 }, + { 30591, 57805 }, + { 30603, 57809 }, + { 30606, 57808 }, + { 30609, 57810 }, + { 30622, 57812 }, + { 30624, 57811 }, + { 30629, 38347 }, + { 30636, 36725 }, + { 30637, 38852 }, + { 30640, 57813 }, + { 30643, 37813 }, + { 30646, 57814 }, + { 30649, 57815 }, + { 30651, 57819 }, + { 30652, 57817 }, + { 30653, 57818 }, + { 30655, 57816 }, + { 30663, 57820 }, + { 30669, 57821 }, + { 30679, 57822 }, + { 30682, 57823 }, + { 30683, 38581 }, + { 30684, 57824 }, + { 30690, 38638 }, + { 30691, 57825 }, + { 30693, 37485 }, + { 30695, 38026 }, + { 30697, 35817 }, + { 30701, 37466 }, + { 30702, 57826 }, + { 30703, 35768 }, + { 30707, 37070 }, + { 30716, 57827 }, + { 30722, 36283 }, + { 30732, 57828 }, + { 30738, 57829 }, + { 30740, 36004 }, + { 30741, 36307 }, + { 30752, 57831 }, + { 30753, 64376 }, + { 30757, 37749 }, + { 30758, 36308 }, + { 30759, 35693 }, + { 30770, 38467 }, + { 30772, 37994 }, + { 30778, 37750 }, + { 30783, 36219 }, + { 30789, 57833 }, + { 30798, 64377 }, + { 30813, 36809 }, + { 30820, 64378 }, + { 30827, 38832 }, + { 30828, 36196 }, + { 30831, 36005 }, + { 30834, 38049 }, + { 30836, 57835 }, + { 30842, 64379 }, + { 30844, 57837 }, + { 30849, 36073 }, + { 30854, 57836 }, + { 30855, 37620 }, + { 30860, 57839 }, + { 30861, 35414 }, + { 30862, 57834 }, + { 30865, 38120 }, + { 30867, 35151 }, + { 30869, 36330 }, + { 30871, 39025 }, + { 30874, 57838 }, + { 30883, 57840 }, + { 30887, 38345 }, + { 30889, 37079 }, + { 30890, 57842 }, + { 30895, 57843 }, + { 30901, 57841 }, + { 30906, 35437 }, + { 30908, 57849 }, + { 30910, 57848 }, + { 30913, 36517 }, + { 30917, 57850 }, + { 30918, 57845 }, + { 30922, 57851 }, + { 30923, 57846 }, + { 30928, 38102 }, + { 30929, 57844 }, + { 30932, 57847 }, + { 30938, 57921 }, + { 30951, 57920 }, + { 30952, 38529 }, + { 30956, 57852 }, + { 30959, 35049 }, + { 30964, 57923 }, + { 30973, 57922 }, + { 30977, 36810 }, + { 30983, 57924 }, + { 30990, 37218 }, + { 30993, 57926 }, + { 30994, 57925 }, + { 31001, 57927 }, + { 31014, 57830 }, + { 31018, 57832 }, + { 31019, 57929 }, + { 31020, 57928 }, + { 31024, 64380 }, + { 31034, 36518 }, + { 31036, 38887 }, + { 31038, 36560 }, + { 31040, 57930 }, + { 31041, 35926 }, + { 31047, 35679 }, + { 31048, 35654 }, + { 31049, 36483 }, + { 31056, 38739 }, + { 31059, 57936 }, + { 31061, 57935 }, + { 31062, 37219 }, + { 31063, 57932 }, + { 31066, 57934 }, + { 31069, 36714 }, + { 31070, 36959 }, + { 31071, 57933 }, + { 31072, 57931 }, + { 31074, 37961 }, + { 31077, 36811 }, + { 31080, 38235 }, + { 31085, 36309 }, + { 31095, 37784 }, + { 31098, 57937 }, + { 31103, 57938 }, + { 31104, 57960 }, + { 31105, 35798 }, + { 31108, 39004 }, + { 31109, 37204 }, + { 31114, 57939 }, + { 31117, 35280 }, + { 31118, 37621 }, + { 31119, 38303 }, + { 31124, 64385 }, + { 31131, 64387 }, + { 31133, 57940 }, + { 31142, 35738 }, + { 31143, 57941 }, + { 31146, 57943 }, + { 31150, 57944 }, + { 31152, 37960 }, + { 31155, 57945 }, + { 31161, 57946 }, + { 31162, 57947 }, + { 31165, 35799 }, + { 31166, 35281 }, + { 31167, 37827 }, + { 31168, 36679 }, + { 31169, 36484 }, + { 31177, 57948 }, + { 31179, 36680 }, + { 31185, 35272 }, + { 31186, 38242 }, + { 31189, 57949 }, + { 31192, 38121 }, + { 31199, 37220 }, + { 31201, 57952 }, + { 31203, 57953 }, + { 31204, 38025 }, + { 31206, 36960 }, + { 31207, 57950 }, + { 31209, 37505 }, + { 31212, 57951 }, + { 31216, 36812 }, + { 31227, 35034 }, + { 31232, 35656 }, + { 31240, 57954 }, + { 31243, 37622 }, + { 31245, 57955 }, + { 31246, 37061 }, + { 31252, 38571 }, + { 31255, 38210 }, + { 31256, 57956 }, + { 31257, 57957 }, + { 31258, 37492 }, + { 31260, 38853 }, + { 31263, 57959 }, + { 31264, 57958 }, + { 31278, 36589 }, + { 31281, 57961 }, + { 31282, 35054 }, + { 31287, 57964 }, + { 31291, 57962 }, + { 31292, 35282 }, + { 31293, 35949 }, + { 31294, 57963 }, + { 31295, 36197 }, + { 31296, 36242 }, + { 31298, 38372 }, + { 31299, 57965 }, + { 31302, 38515 }, + { 31305, 57967 }, + { 31309, 37071 }, + { 31310, 35182 }, + { 31311, 35256 }, + { 31312, 34986 }, + { 31319, 57966 }, + { 31329, 57968 }, + { 31330, 57969 }, + { 31331, 36853 }, + { 31337, 57970 }, + { 31339, 35438 }, + { 31344, 57972 }, + { 31348, 35978 }, + { 31350, 35718 }, + { 31353, 57973 }, + { 31354, 35827 }, + { 31357, 57974 }, + { 31359, 37114 }, + { 31361, 37835 }, + { 31363, 37086 }, + { 31364, 36339 }, + { 31368, 57975 }, + { 31378, 37506 }, + { 31379, 37259 }, + { 31381, 57977 }, + { 31382, 57979 }, + { 31383, 57976 }, + { 31384, 57978 }, + { 31391, 35905 }, + { 31401, 57980 }, + { 31402, 35909 }, + { 31406, 35719 }, + { 31407, 38769 }, + { 31408, 57982 }, + { 31414, 57984 }, + { 31418, 35149 }, + { 31423, 57987 }, + { 31427, 35478 }, + { 31428, 57986 }, + { 31429, 57985 }, + { 31431, 57989 }, + { 31432, 57981 }, + { 31434, 57990 }, + { 31435, 38823 }, + { 31437, 57991 }, + { 31439, 57992 }, + { 31441, 64388 }, + { 31442, 39666 }, + { 31443, 57994 }, + { 31445, 57993 }, + { 31449, 57995 }, + { 31450, 57996 }, + { 31452, 38835 }, + { 31453, 57997 }, + { 31455, 59629 }, + { 31456, 36813 }, + { 31457, 57998 }, + { 31458, 57999 }, + { 31459, 36726 }, + { 31461, 37814 }, + { 31462, 58000 }, + { 31463, 64389 }, + { 31466, 37447 }, + { 31467, 64391 }, + { 31469, 58001 }, + { 31471, 37467 }, + { 31472, 58002 }, + { 31478, 35747 }, + { 31480, 39262 }, + { 31481, 37500 }, + { 31482, 36529 }, + { 31487, 35526 }, + { 31490, 58003 }, + { 31492, 58016 }, + { 31494, 58006 }, + { 31496, 35720 }, + { 31498, 58005 }, + { 31499, 58018 }, + { 31503, 58004 }, + { 31505, 36814 }, + { 31512, 58008 }, + { 31513, 58009 }, + { 31515, 37706 }, + { 31518, 58010 }, + { 31520, 35453 }, + { 31525, 36985 }, + { 31526, 38276 }, + { 31528, 58012 }, + { 31532, 37350 }, + { 31539, 58007 }, + { 31541, 58011 }, + { 31542, 58013 }, + { 31545, 36345 }, + { 31557, 58020 }, + { 31558, 38221 }, + { 31560, 38052 }, + { 31561, 37785 }, + { 31563, 35800 }, + { 31564, 58019 }, + { 31565, 58017 }, + { 31567, 38067 }, + { 31568, 58014 }, + { 31569, 37501 }, + { 31570, 37787 }, + { 31572, 37786 }, + { 31574, 36340 }, + { 31581, 58038 }, + { 31589, 58022 }, + { 31591, 58024 }, + { 31596, 58027 }, + { 31598, 58028 }, + { 31600, 58025 }, + { 31601, 58026 }, + { 31604, 58023 }, + { 31605, 58021 }, + { 31610, 58015 }, + { 31622, 38349 }, + { 31623, 35283 }, + { 31627, 58035 }, + { 31629, 58032 }, + { 31631, 58037 }, + { 31634, 58036 }, + { 31636, 38035 }, + { 31637, 38565 }, + { 31639, 36442 }, + { 31640, 58030 }, + { 31641, 58039 }, + { 31642, 58034 }, + { 31644, 58033 }, + { 31645, 58029 }, + { 31646, 64392 }, + { 31647, 58031 }, + { 31649, 35527 }, + { 31658, 37468 }, + { 31661, 37115 }, + { 31665, 38048 }, + { 31668, 58044 }, + { 31672, 38050 }, + { 31680, 37087 }, + { 31681, 58041 }, + { 31684, 38093 }, + { 31686, 58045 }, + { 31687, 38353 }, + { 31689, 37498 }, + { 31691, 58040 }, + { 31692, 58042 }, + { 31695, 58043 }, + { 31709, 58046 }, + { 31712, 36546 }, + { 31716, 37828 }, + { 31717, 58051 }, + { 31718, 58050 }, + { 31721, 58047 }, + { 31725, 38997 }, + { 31731, 58056 }, + { 31734, 58060 }, + { 31735, 58057 }, + { 31744, 58053 }, + { 31751, 58054 }, + { 31757, 58059 }, + { 31761, 58048 }, + { 31762, 39379 }, + { 31763, 58055 }, + { 31764, 58049 }, + { 31767, 58058 }, + { 31775, 58064 }, + { 31777, 35528 }, + { 31779, 58061 }, + { 31783, 58062 }, + { 31786, 58063 }, + { 31787, 58066 }, + { 31799, 58065 }, + { 31800, 38132 }, + { 31805, 58067 }, + { 31806, 38906 }, + { 31807, 38379 }, + { 31808, 58072 }, + { 31811, 58069 }, + { 31820, 58068 }, + { 31821, 37072 }, + { 31823, 58071 }, + { 31824, 58073 }, + { 31828, 58070 }, + { 31830, 58077 }, + { 31832, 58074 }, + { 31839, 58075 }, + { 31840, 58052 }, + { 31844, 58076 }, + { 31845, 58078 }, + { 31852, 58079 }, + { 31859, 38340 }, + { 31861, 58080 }, + { 31870, 38624 }, + { 31873, 35788 }, + { 31874, 35912 }, + { 31875, 58081 }, + { 31881, 38322 }, + { 31883, 37000 }, + { 31885, 38574 }, + { 31888, 58082 }, + { 31890, 38833 }, + { 31893, 38036 }, + { 31895, 37221 }, + { 31896, 37971 }, + { 31899, 36716 }, + { 31903, 35006 }, + { 31905, 58087 }, + { 31906, 58085 }, + { 31908, 58083 }, + { 31909, 35487 }, + { 31911, 36815 }, + { 31912, 58088 }, + { 31915, 58086 }, + { 31917, 58084 }, + { 31918, 58092 }, + { 31921, 58091 }, + { 31922, 58090 }, + { 31923, 58089 }, + { 31929, 58093 }, + { 31933, 58094 }, + { 31934, 37048 }, + { 31936, 58095 }, + { 31938, 58097 }, + { 31941, 58096 }, + { 31946, 36048 }, + { 31950, 37207 }, + { 31954, 58099 }, + { 31958, 37788 }, + { 31960, 58098 }, + { 31964, 58100 }, + { 31966, 38323 }, + { 31967, 37260 }, + { 31968, 36198 }, + { 31970, 58101 }, + { 31975, 38854 }, + { 31983, 58103 }, + { 31986, 58104 }, + { 31988, 58105 }, + { 31990, 58106 }, + { 31992, 36485 }, + { 31994, 58107 }, + { 31995, 35950 }, + { 31998, 35722 }, + { 32000, 35657 }, + { 32002, 58176 }, + { 32004, 38641 }, + { 32005, 36199 }, + { 32006, 58108 }, + { 32010, 58179 }, + { 32011, 38628 }, + { 32013, 37979 }, + { 32016, 38226 }, + { 32020, 36739 }, + { 32021, 58178 }, + { 32023, 36561 }, + { 32024, 36200 }, + { 32025, 36486 }, + { 32026, 35721 }, + { 32027, 38324 }, + { 32028, 58177 }, + { 32032, 37222 }, + { 32033, 38497 }, + { 32034, 36341 }, + { 32043, 36487 }, + { 32044, 37595 }, + { 32046, 58182 }, + { 32047, 38877 }, + { 32048, 36311 }, + { 32050, 58183 }, + { 32051, 36961 }, + { 32053, 58185 }, + { 32057, 36816 }, + { 32058, 36270 }, + { 32063, 58184 }, + { 32066, 36681 }, + { 32067, 36028 }, + { 32068, 37223 }, + { 32069, 58180 }, + { 32070, 58186 }, + { 32072, 64394 }, + { 32075, 58181 }, + { 32076, 35951 }, + { 32078, 58189 }, + { 32079, 58193 }, + { 32080, 35979 }, + { 32086, 58188 }, + { 32091, 58197 }, + { 32092, 64395 }, + { 32094, 36201 }, + { 32097, 38797 }, + { 32098, 35002 }, + { 32099, 58194 }, + { 32102, 35723 }, + { 32104, 58191 }, + { 32110, 58192 }, + { 32113, 37789 }, + { 32114, 58190 }, + { 32115, 58187 }, + { 32117, 35399 }, + { 32118, 37090 }, + { 32121, 36006 }, + { 32125, 58199 }, + { 32137, 58196 }, + { 32143, 58198 }, + { 32147, 58195 }, + { 32153, 35952 }, + { 32154, 37297 }, + { 32155, 58200 }, + { 32156, 37262 }, + { 32159, 58213 }, + { 32160, 64397 }, + { 32162, 58209 }, + { 32163, 58203 }, + { 32171, 58207 }, + { 32172, 36600 }, + { 32173, 35035 }, + { 32174, 58202 }, + { 32175, 58210 }, + { 32176, 58214 }, + { 32177, 36202 }, + { 32178, 38612 }, + { 32180, 37588 }, + { 32181, 58204 }, + { 32183, 64396 }, + { 32184, 58212 }, + { 32186, 58201 }, + { 32187, 37469 }, + { 32189, 58206 }, + { 32190, 35003 }, + { 32191, 38600 }, + { 32199, 58205 }, + { 32202, 35801 }, + { 32203, 38122 }, + { 32207, 37261 }, + { 32209, 38862 }, + { 32210, 36751 }, + { 32213, 58254 }, + { 32214, 64398 }, + { 32216, 58215 }, + { 32218, 37116 }, + { 32220, 58211 }, + { 32221, 58216 }, + { 32222, 58218 }, + { 32224, 37623 }, + { 32225, 58221 }, + { 32228, 58217 }, + { 32232, 38354 }, + { 32233, 35529 }, + { 32236, 38601 }, + { 32239, 35036 }, + { 32242, 58220 }, + { 32244, 38907 }, + { 32251, 58219 }, + { 32257, 35215 }, + { 32260, 37866 }, + { 32261, 58222 }, + { 32265, 58229 }, + { 32266, 58223 }, + { 32267, 58230 }, + { 32274, 58226 }, + { 32283, 38043 }, + { 32286, 36552 }, + { 32287, 58228 }, + { 32289, 58225 }, + { 32290, 58231 }, + { 32291, 58224 }, + { 32294, 36707 }, + { 32299, 38468 }, + { 32302, 36715 }, + { 32305, 58227 }, + { 32306, 58240 }, + { 32309, 58235 }, + { 32311, 58238 }, + { 32313, 58236 }, + { 32314, 58241 }, + { 32315, 58234 }, + { 32317, 58208 }, + { 32318, 37073 }, + { 32321, 38089 }, + { 32323, 58237 }, + { 32326, 58232 }, + { 32330, 37184 }, + { 32331, 35953 }, + { 32333, 36682 }, + { 32338, 64399 }, + { 32340, 36932 }, + { 32341, 37205 }, + { 32342, 58244 }, + { 32345, 58246 }, + { 32346, 58247 }, + { 32349, 58243 }, + { 32350, 58245 }, + { 32358, 58233 }, + { 32359, 58242 }, + { 32361, 58250 }, + { 32362, 58249 }, + { 32365, 38554 }, + { 32368, 35914 }, + { 32377, 58248 }, + { 32379, 58252 }, + { 32380, 58251 }, + { 32381, 58255 }, + { 32383, 58257 }, + { 32386, 36443 }, + { 32387, 58253 }, + { 32392, 58258 }, + { 32393, 58259 }, + { 32394, 64092 }, + { 32396, 58260 }, + { 32398, 58266 }, + { 32399, 37722 }, + { 32400, 58262 }, + { 32402, 58261 }, + { 32403, 58263 }, + { 32404, 58264 }, + { 32406, 58265 }, + { 32411, 58267 }, + { 32412, 58268 }, + { 32566, 35530 }, + { 32568, 58269 }, + { 32570, 58270 }, + { 32581, 58271 }, + { 32583, 64400 }, + { 32588, 58272 }, + { 32589, 58273 }, + { 32590, 58274 }, + { 32592, 58275 }, + { 32593, 58276 }, + { 32596, 58278 }, + { 32597, 58277 }, + { 32600, 58279 }, + { 32607, 58280 }, + { 32608, 58281 }, + { 32615, 58284 }, + { 32616, 58282 }, + { 32617, 58283 }, + { 32618, 36319 }, + { 32619, 35954 }, + { 32622, 37493 }, + { 32624, 38065 }, + { 32626, 36752 }, + { 32629, 37996 }, + { 32631, 38123 }, + { 32632, 58285 }, + { 32633, 40171 }, + { 32642, 58286 }, + { 32643, 58288 }, + { 32645, 38789 }, + { 32646, 58287 }, + { 32647, 58290 }, + { 32648, 58289 }, + { 32650, 38770 }, + { 32652, 58291 }, + { 32654, 38140 }, + { 32660, 58292 }, + { 32666, 58295 }, + { 32669, 58294 }, + { 32670, 58293 }, + { 32673, 64401 }, + { 32675, 58296 }, + { 32676, 35921 }, + { 32680, 37185 }, + { 32681, 35680 }, + { 32686, 58300 }, + { 32687, 58297 }, + { 32690, 58298 }, + { 32694, 58301 }, + { 32696, 58302 }, + { 32697, 58299 }, + { 32701, 35144 }, + { 32705, 35237 }, + { 32709, 58304 }, + { 32710, 58305 }, + { 32714, 58306 }, + { 32716, 38786 }, + { 32722, 36683 }, + { 32724, 58308 }, + { 32725, 58307 }, + { 32736, 37001 }, + { 32737, 58309 }, + { 32742, 58310 }, + { 32745, 58311 }, + { 32747, 35555 }, + { 32752, 35531 }, + { 32755, 58312 }, + { 32761, 58313 }, + { 32763, 38524 }, + { 32764, 38787 }, + { 32768, 38771 }, + { 32769, 38998 }, + { 32771, 36204 }, + { 32772, 58316 }, + { 32773, 36562 }, + { 32774, 58315 }, + { 32779, 58317 }, + { 32780, 36519 }, + { 32784, 37327 }, + { 32786, 58318 }, + { 32789, 36203 }, + { 32791, 38613 }, + { 32792, 58319 }, + { 32793, 58320 }, + { 32796, 58321 }, + { 32801, 58322 }, + { 32808, 58323 }, + { 32819, 36520 }, + { 32822, 38635 }, + { 32827, 58325 }, + { 32829, 37470 }, + { 32831, 58324 }, + { 32838, 58327 }, + { 32842, 58326 }, + { 32850, 58328 }, + { 32854, 37049 }, + { 32856, 58329 }, + { 32858, 58330 }, + { 32862, 38327 }, + { 32863, 58331 }, + { 32865, 37263 }, + { 32866, 58332 }, + { 32872, 58333 }, + { 32879, 38908 }, + { 32880, 58336 }, + { 32882, 58335 }, + { 32883, 58334 }, + { 32884, 37550 }, + { 32886, 58337 }, + { 32887, 36933 }, + { 32889, 58338 }, + { 32893, 58339 }, + { 32894, 38999 }, + { 32895, 58340 }, + { 32900, 58341 }, + { 32901, 58343 }, + { 32902, 58342 }, + { 32903, 38051 }, + { 32905, 37879 }, + { 32907, 39005 }, + { 32908, 38055 }, + { 32915, 58345 }, + { 32918, 36817 }, + { 32920, 38217 }, + { 32922, 58346 }, + { 32923, 58344 }, + { 32925, 35532 }, + { 32929, 36050 }, + { 32930, 36488 }, + { 32933, 38124 }, + { 32937, 36008 }, + { 32938, 38498 }, + { 32940, 58349 }, + { 32941, 58347 }, + { 32943, 36205 }, + { 32945, 36206 }, + { 32946, 35047 }, + { 32948, 36326 }, + { 32954, 38008 }, + { 32963, 35037 }, + { 32964, 58354 }, + { 32966, 37471 }, + { 32972, 38007 }, + { 32974, 37337 }, + { 32982, 58356 }, + { 32985, 58352 }, + { 32986, 58355 }, + { 32987, 58350 }, + { 32989, 58353 }, + { 32990, 38469 }, + { 32993, 36051 }, + { 32996, 35067 }, + { 32997, 58351 }, + { 33007, 58358 }, + { 33009, 58359 }, + { 33012, 37815 }, + { 33016, 35769 }, + { 33020, 58437 }, + { 33021, 37980 }, + { 33026, 36489 }, + { 33029, 35770 }, + { 33030, 37062 }, + { 33031, 39013 }, + { 33032, 38572 }, + { 33033, 58357 }, + { 33034, 37074 }, + { 33050, 35698 }, + { 33051, 58360 }, + { 33059, 58362 }, + { 33065, 58361 }, + { 33071, 58363 }, + { 33073, 37445 }, + { 33075, 37981 }, + { 33081, 37551 }, + { 33086, 58434 }, + { 33094, 58433 }, + { 33099, 58364 }, + { 33102, 36980 }, + { 33104, 38277 }, + { 33105, 58436 }, + { 33107, 58435 }, + { 33108, 36207 }, + { 33109, 39026 }, + { 33119, 58452 }, + { 33125, 58440 }, + { 33126, 58441 }, + { 33131, 36590 }, + { 33134, 58439 }, + { 33136, 36248 }, + { 33137, 58438 }, + { 33140, 58442 }, + { 33144, 37552 }, + { 33145, 38304 }, + { 33146, 37186 }, + { 33151, 37338 }, + { 33152, 58446 }, + { 33154, 58447 }, + { 33155, 58443 }, + { 33160, 58444 }, + { 33162, 58445 }, + { 33167, 36208 }, + { 33171, 58453 }, + { 33173, 58449 }, + { 33178, 38278 }, + { 33180, 38540 }, + { 33181, 38215 }, + { 33184, 58448 }, + { 33187, 58451 }, + { 33188, 58450 }, + { 33192, 38499 }, + { 33193, 58454 }, + { 33200, 58455 }, + { 33203, 37206 }, + { 33205, 58456 }, + { 33208, 58458 }, + { 33210, 58462 }, + { 33213, 58459 }, + { 33214, 58457 }, + { 33215, 37982 }, + { 33216, 58460 }, + { 33218, 58461 }, + { 33222, 35248 }, + { 33224, 58468 }, + { 33225, 58463 }, + { 33229, 58464 }, + { 33233, 58465 }, + { 33235, 37279 }, + { 33240, 58467 }, + { 33241, 58466 }, + { 33242, 58469 }, + { 33247, 58470 }, + { 33248, 58471 }, + { 33251, 36962 }, + { 33253, 35303 }, + { 33255, 58472 }, + { 33256, 38869 }, + { 33258, 36521 }, + { 33261, 36684 }, + { 33267, 36490 }, + { 33268, 37494 }, + { 33274, 58473 }, + { 33275, 58474 }, + { 33276, 35152 }, + { 33278, 58475 }, + { 33281, 58476 }, + { 33282, 58477 }, + { 33285, 58478 }, + { 33287, 58479 }, + { 33288, 35771 }, + { 33289, 40360 }, + { 33290, 58480 }, + { 33292, 37091 }, + { 33293, 58481 }, + { 33294, 36553 }, + { 33296, 58482 }, + { 33298, 39086 }, + { 33302, 58483 }, + { 33303, 38364 }, + { 33304, 35546 }, + { 33307, 37187 }, + { 33308, 36727 }, + { 33310, 38289 }, + { 33311, 36685 }, + { 33321, 58484 }, + { 33322, 36209 }, + { 33323, 58485 }, + { 33324, 38090 }, + { 33326, 58500 }, + { 33331, 58487 }, + { 33333, 37319 }, + { 33334, 38037 }, + { 33335, 36029 }, + { 33336, 58486 }, + { 33337, 37188 }, + { 33344, 58488 }, + { 33351, 37624 }, + { 33368, 58490 }, + { 33369, 58489 }, + { 33370, 58492 }, + { 33373, 58491 }, + { 33375, 58493 }, + { 33378, 58496 }, + { 33380, 58494 }, + { 33382, 35533 }, + { 33384, 58497 }, + { 33386, 58498 }, + { 33387, 58499 }, + { 33390, 36271 }, + { 33391, 38855 }, + { 33393, 58501 }, + { 33394, 36934 }, + { 33398, 35216 }, + { 33399, 58502 }, + { 33400, 58503 }, + { 33406, 58504 }, + { 33419, 35056 }, + { 33421, 58505 }, + { 33426, 58506 }, + { 33433, 38279 }, + { 33437, 36549 }, + { 33439, 58508 }, + { 33445, 35400 }, + { 33446, 34992 }, + { 33451, 58507 }, + { 33452, 58510 }, + { 33453, 37997 }, + { 33455, 36963 }, + { 33457, 35284 }, + { 33459, 38470 }, + { 33464, 35964 }, + { 33465, 35802 }, + { 33467, 58509 }, + { 33469, 35304 }, + { 33477, 35489 }, + { 33489, 35217 }, + { 33490, 58514 }, + { 33491, 38888 }, + { 33492, 37339 }, + { 33495, 38243 }, + { 33497, 58526 }, + { 33499, 35285 }, + { 33500, 58524 }, + { 33502, 58522 }, + { 33503, 58513 }, + { 33505, 58511 }, + { 33507, 58512 }, + { 33509, 36577 }, + { 33510, 35818 }, + { 33511, 37527 }, + { 33515, 37839 }, + { 33521, 35184 }, + { 33523, 58516 }, + { 33524, 58515 }, + { 33529, 58521 }, + { 33530, 58517 }, + { 33531, 58520 }, + { 33537, 64403 }, + { 33538, 38606 }, + { 33539, 58519 }, + { 33540, 35286 }, + { 33541, 35485 }, + { 33542, 58523 }, + { 33545, 58525 }, + { 33550, 35955 }, + { 33558, 58529 }, + { 33559, 58538 }, + { 33560, 58539 }, + { 33564, 34985 }, + { 33571, 58546 }, + { 33576, 35055 }, + { 33579, 58537 }, + { 33583, 58536 }, + { 33585, 58531 }, + { 33586, 58530 }, + { 33588, 58528 }, + { 33589, 58527 }, + { 33590, 37507 }, + { 33592, 37369 }, + { 33593, 58533 }, + { 33600, 58532 }, + { 33605, 58535 }, + { 33609, 37264 }, + { 33610, 35956 }, + { 33615, 35168 }, + { 33616, 58534 }, + { 33618, 36210 }, + { 33624, 37265 }, + { 33634, 64404 }, + { 33651, 58552 }, + { 33653, 58553 }, + { 33655, 35287 }, + { 33659, 35244 }, + { 33660, 58550 }, + { 33663, 64405 }, + { 33669, 58540 }, + { 33671, 58548 }, + { 33673, 58555 }, + { 33674, 58549 }, + { 33678, 58547 }, + { 33683, 58518 }, + { 33686, 58545 }, + { 33690, 58541 }, + { 33694, 35534 }, + { 33695, 58543 }, + { 33696, 58554 }, + { 33698, 58544 }, + { 33704, 58556 }, + { 33706, 58542 }, + { 33707, 38044 }, + { 33713, 38793 }, + { 33717, 58551 }, + { 33725, 58573 }, + { 33729, 58565 }, + { 33733, 37019 }, + { 33735, 64406 }, + { 33738, 35685 }, + { 33740, 35803 }, + { 33742, 58560 }, + { 33747, 35289 }, + { 33750, 36818 }, + { 33752, 58563 }, + { 33756, 36312 }, + { 33759, 37744 }, + { 33760, 58568 }, + { 33769, 38380 }, + { 33771, 58559 }, + { 33775, 35288 }, + { 33776, 36052 }, + { 33777, 38216 }, + { 33778, 58569 }, + { 33780, 58557 }, + { 33782, 64407 }, + { 33783, 58566 }, + { 33787, 58576 }, + { 33789, 58561 }, + { 33795, 58562 }, + { 33796, 37816 }, + { 33799, 58567 }, + { 33803, 58564 }, + { 33804, 38471 }, + { 33805, 58570 }, + { 33806, 35038 }, + { 33811, 58558 }, + { 33824, 58572 }, + { 33826, 58571 }, + { 33833, 38027 }, + { 33834, 58578 }, + { 33836, 58589 }, + { 33841, 35486 }, + { 33845, 58592 }, + { 33848, 58574 }, + { 33852, 58579 }, + { 33853, 38798 }, + { 33862, 58588 }, + { 33864, 64408 }, + { 33865, 38772 }, + { 33870, 38824 }, + { 33879, 37528 }, + { 33883, 35467 }, + { 33889, 38290 }, + { 33890, 58594 }, + { 33891, 37791 }, + { 33894, 34991 }, + { 33897, 58587 }, + { 33899, 58583 }, + { 33900, 37266 }, + { 33901, 58577 }, + { 33902, 58585 }, + { 33903, 58590 }, + { 33905, 37963 }, + { 33909, 34984 }, + { 33911, 58582 }, + { 33913, 58591 }, + { 33914, 38296 }, + { 33922, 58586 }, + { 33924, 58581 }, + { 33931, 36819 }, + { 33936, 36686 }, + { 33940, 36522 }, + { 33945, 38614 }, + { 33948, 38246 }, + { 33951, 58597 }, + { 33953, 58606 }, + { 33965, 58584 }, + { 33970, 35479 }, + { 33972, 64409 }, + { 33976, 36854 }, + { 33977, 58595 }, + { 33979, 58600 }, + { 33980, 37267 }, + { 33983, 58596 }, + { 33985, 58603 }, + { 33988, 37502 }, + { 33990, 58604 }, + { 33993, 38773 }, + { 33994, 58593 }, + { 33995, 35415 }, + { 33997, 58599 }, + { 34000, 58602 }, + { 34001, 38570 }, + { 34006, 58605 }, + { 34009, 58598 }, + { 34010, 58601 }, + { 34012, 64096 }, + { 34028, 38472 }, + { 34030, 38976 }, + { 34036, 58609 }, + { 34044, 58616 }, + { 34047, 58608 }, + { 34048, 36545 }, + { 34054, 58575 }, + { 34065, 38348 }, + { 34067, 38560 }, + { 34068, 58615 }, + { 34069, 58614 }, + { 34071, 58610 }, + { 34072, 58611 }, + { 34074, 35157 }, + { 34079, 58613 }, + { 34081, 58607 }, + { 34086, 37587 }, + { 34092, 58612 }, + { 34093, 35068 }, + { 34101, 37280 }, + { 34109, 38337 }, + { 34112, 58617 }, + { 34113, 58688 }, + { 34115, 38103 }, + { 34120, 58620 }, + { 34121, 36820 }, + { 34122, 36551 }, + { 34123, 58690 }, + { 34126, 35772 }, + { 34131, 64410 }, + { 34133, 58691 }, + { 34135, 38297 }, + { 34136, 58619 }, + { 34137, 64411 }, + { 34138, 58580 }, + { 34147, 58618 }, + { 34152, 39022 }, + { 34153, 37792 }, + { 34154, 38291 }, + { 34155, 64412 }, + { 34157, 58698 }, + { 34167, 58704 }, + { 34174, 58705 }, + { 34176, 58692 }, + { 34180, 38038 }, + { 34183, 58702 }, + { 34184, 58694 }, + { 34186, 58696 }, + { 34192, 58706 }, + { 34193, 58695 }, + { 34196, 58699 }, + { 34199, 35218 }, + { 34201, 37859 }, + { 34203, 58700 }, + { 34204, 58703 }, + { 34212, 58693 }, + { 34214, 37189 }, + { 34216, 58697 }, + { 34217, 36422 }, + { 34218, 36964 }, + { 34219, 35919 }, + { 34220, 38642 }, + { 34222, 38647 }, + { 34223, 36754 }, + { 34224, 64414 }, + { 34233, 58710 }, + { 34234, 58708 }, + { 34241, 39021 }, + { 34249, 58707 }, + { 34253, 38805 }, + { 34255, 58709 }, + { 34256, 58711 }, + { 34261, 58712 }, + { 34268, 58715 }, + { 34269, 58713 }, + { 34276, 37793 }, + { 34277, 58714 }, + { 34281, 38091 }, + { 34282, 58701 }, + { 34295, 36755 }, + { 34297, 58716 }, + { 34298, 58721 }, + { 34299, 37268 }, + { 34302, 58720 }, + { 34306, 58689 }, + { 34310, 58722 }, + { 34311, 37224 }, + { 34314, 58717 }, + { 34315, 58719 }, + { 34323, 58718 }, + { 34326, 40784 }, + { 34327, 40769 }, + { 34330, 58724 }, + { 34338, 58723 }, + { 34349, 38806 }, + { 34351, 57786 }, + { 34352, 58725 }, + { 34367, 58726 }, + { 34381, 58727 }, + { 34382, 36053 }, + { 34384, 35699 }, + { 34388, 58729 }, + { 34389, 39292 }, + { 34394, 35733 }, + { 34396, 38840 }, + { 34398, 35825 }, + { 34399, 58730 }, + { 34407, 58731 }, + { 34411, 37518 }, + { 34417, 58732 }, + { 34425, 37880 }, + { 34427, 35000 }, + { 34442, 35297 }, + { 34443, 58737 }, + { 34444, 58738 }, + { 34451, 58733 }, + { 34453, 36444 }, + { 34467, 58734 }, + { 34468, 37985 }, + { 34473, 58735 }, + { 34474, 58736 }, + { 34475, 58746 }, + { 34479, 58740 }, + { 34480, 58743 }, + { 34486, 58739 }, + { 34500, 58741 }, + { 34502, 58742 }, + { 34503, 36566 }, + { 34505, 58744 }, + { 34507, 37472 }, + { 34509, 35957 }, + { 34510, 35425 }, + { 34516, 58747 }, + { 34521, 35422 }, + { 34523, 58753 }, + { 34526, 58748 }, + { 34527, 58752 }, + { 34532, 38072 }, + { 34537, 58749 }, + { 34540, 58750 }, + { 34541, 38247 }, + { 34542, 38104 }, + { 34543, 58754 }, + { 34552, 37371 }, + { 34553, 58764 }, + { 34555, 58760 }, + { 34558, 35305 }, + { 34560, 58758 }, + { 34562, 38473 }, + { 34563, 58759 }, + { 34566, 58756 }, + { 34568, 58757 }, + { 34569, 58762 }, + { 34570, 58765 }, + { 34573, 58763 }, + { 34577, 58761 }, + { 34578, 58755 }, + { 34584, 37495 }, + { 34586, 58772 }, + { 34588, 38568 }, + { 34597, 58770 }, + { 34601, 58771 }, + { 34612, 58766 }, + { 34615, 58768 }, + { 34619, 58769 }, + { 34623, 58767 }, + { 34633, 37092 }, + { 34635, 39000 }, + { 34636, 58776 }, + { 34638, 58777 }, + { 34643, 58783 }, + { 34645, 36937 }, + { 34647, 58779 }, + { 34649, 58782 }, + { 34655, 58774 }, + { 34656, 58773 }, + { 34659, 58784 }, + { 34662, 35290 }, + { 34664, 58780 }, + { 34666, 58785 }, + { 34670, 58781 }, + { 34676, 58778 }, + { 34678, 37553 }, + { 34680, 58775 }, + { 34687, 38024 }, + { 34690, 58789 }, + { 34701, 38746 }, + { 34719, 58788 }, + { 34722, 58787 }, + { 34731, 58796 }, + { 34735, 58790 }, + { 34739, 58798 }, + { 34746, 38790 }, + { 34747, 58801 }, + { 34749, 58792 }, + { 34752, 58793 }, + { 34756, 58797 }, + { 34758, 58800 }, + { 34759, 58799 }, + { 34763, 58791 }, + { 34768, 58794 }, + { 34770, 58811 }, + { 34784, 58804 }, + { 34799, 58802 }, + { 34802, 58803 }, + { 34806, 58808 }, + { 34807, 58809 }, + { 34809, 35401 }, + { 34811, 35681 }, + { 34814, 58807 }, + { 34821, 58786 }, + { 34823, 64417 }, + { 34829, 58806 }, + { 34830, 58810 }, + { 34831, 58805 }, + { 34833, 58812 }, + { 34837, 58814 }, + { 34838, 58813 }, + { 34849, 58816 }, + { 34850, 58815 }, + { 34851, 58745 }, + { 34855, 58820 }, + { 34865, 58817 }, + { 34870, 58818 }, + { 34873, 58819 }, + { 34875, 58821 }, + { 34880, 35980 }, + { 34882, 58823 }, + { 34884, 58822 }, + { 34886, 36687 }, + { 34892, 36211 }, + { 34893, 40869 }, + { 34898, 58824 }, + { 34899, 36720 }, + { 34903, 35416 }, + { 34905, 58825 }, + { 34907, 35185 }, + { 34909, 36821 }, + { 34910, 58826 }, + { 34913, 36212 }, + { 34914, 58827 }, + { 34915, 35039 }, + { 34920, 38236 }, + { 34923, 58828 }, + { 34928, 37002 }, + { 34930, 58835 }, + { 34933, 58832 }, + { 34935, 37519 }, + { 34941, 58833 }, + { 34942, 58830 }, + { 34943, 35804 }, + { 34945, 58829 }, + { 34946, 58836 }, + { 34952, 35925 }, + { 34955, 37340 }, + { 34957, 58842 }, + { 34962, 58838 }, + { 34966, 37299 }, + { 34967, 58837 }, + { 34969, 58840 }, + { 34974, 58831 }, + { 34978, 58841 }, + { 34980, 58843 }, + { 34987, 38125 }, + { 34990, 58839 }, + { 34992, 58844 }, + { 34993, 58846 }, + { 34996, 36049 }, + { 34997, 58834 }, + { 34999, 35007 }, + { 35007, 58845 }, + { 35009, 36313 }, + { 35010, 38900 }, + { 35011, 58847 }, + { 35012, 58848 }, + { 35013, 37269 }, + { 35023, 38816 }, + { 35028, 58849 }, + { 35029, 38740 }, + { 35032, 58850 }, + { 35033, 58851 }, + { 35036, 38370 }, + { 35037, 58852 }, + { 35039, 36286 }, + { 35041, 38817 }, + { 35048, 58857 }, + { 35058, 58858 }, + { 35059, 36822 }, + { 35060, 58856 }, + { 35061, 64418 }, + { 35064, 38791 }, + { 35065, 58853 }, + { 35068, 58855 }, + { 35069, 37051 }, + { 35070, 37022 }, + { 35074, 58854 }, + { 35076, 58859 }, + { 35079, 38305 }, + { 35082, 58861 }, + { 35084, 58860 }, + { 35088, 35468 }, + { 35090, 38474 }, + { 35091, 58862 }, + { 35100, 64093 }, + { 35101, 58874 }, + { 35102, 58864 }, + { 35109, 58865 }, + { 35114, 58866 }, + { 35115, 58867 }, + { 35126, 58871 }, + { 35128, 58872 }, + { 35131, 58870 }, + { 35137, 58868 }, + { 35139, 58863 }, + { 35140, 58869 }, + { 35148, 58873 }, + { 35149, 59573 }, + { 35158, 35238 }, + { 35166, 58876 }, + { 35167, 35805 }, + { 35168, 58875 }, + { 35172, 58945 }, + { 35174, 58944 }, + { 35178, 58947 }, + { 35181, 58946 }, + { 35183, 58948 }, + { 35186, 36688 }, + { 35188, 58949 }, + { 35191, 58950 }, + { 35198, 58951 }, + { 35199, 37052 }, + { 35201, 38774 }, + { 35203, 58952 }, + { 35206, 38306 }, + { 35207, 37989 }, + { 35208, 58953 }, + { 35210, 58954 }, + { 35211, 36009 }, + { 35215, 35659 }, + { 35219, 58955 }, + { 35222, 36491 }, + { 35223, 37984 }, + { 35224, 58956 }, + { 35226, 35439 }, + { 35233, 58957 }, + { 35238, 58959 }, + { 35239, 38807 }, + { 35241, 58958 }, + { 35242, 36965 }, + { 35244, 58960 }, + { 35247, 58961 }, + { 35250, 58962 }, + { 35251, 35535 }, + { 35258, 58963 }, + { 35261, 58964 }, + { 35263, 58965 }, + { 35264, 58966 }, + { 35282, 35440 }, + { 35290, 58967 }, + { 35292, 58968 }, + { 35293, 58969 }, + { 35299, 35312 }, + { 35302, 36935 }, + { 35303, 58970 }, + { 35316, 58971 }, + { 35320, 58972 }, + { 35328, 36030 }, + { 35330, 37625 }, + { 35331, 58973 }, + { 35336, 35958 }, + { 35338, 36981 }, + { 35340, 58976 }, + { 35342, 37794 }, + { 35344, 58975 }, + { 35346, 64419 }, + { 35347, 35920 }, + { 35350, 58974 }, + { 35351, 37365 }, + { 35352, 35660 }, + { 35355, 58977 }, + { 35357, 58978 }, + { 35359, 36823 }, + { 35363, 35981 }, + { 35365, 58979 }, + { 35370, 38475 }, + { 35373, 37085 }, + { 35377, 35734 }, + { 35379, 38643 }, + { 35380, 37225 }, + { 35382, 58980 }, + { 35383, 64420 }, + { 35386, 36966 }, + { 35387, 37520 }, + { 35388, 36824 }, + { 35393, 58981 }, + { 35398, 58984 }, + { 35400, 58985 }, + { 35408, 36284 }, + { 35409, 37312 }, + { 35410, 58983 }, + { 35412, 36825 }, + { 35413, 38237 }, + { 35419, 58982 }, + { 35422, 36492 }, + { 35424, 35186 }, + { 35426, 58989 }, + { 35427, 35959 }, + { 35430, 36494 }, + { 35433, 36493 }, + { 35435, 39020 }, + { 35436, 58988 }, + { 35437, 58987 }, + { 35438, 37190 }, + { 35440, 35692 }, + { 35441, 39010 }, + { 35442, 35417 }, + { 35443, 36826 }, + { 35449, 64421 }, + { 35452, 58986 }, + { 35458, 58991 }, + { 35460, 58992 }, + { 35461, 58990 }, + { 35463, 36054 }, + { 35465, 38751 }, + { 35468, 36495 }, + { 35469, 37958 }, + { 35473, 58995 }, + { 35475, 37054 }, + { 35477, 37473 }, + { 35480, 38741 }, + { 35482, 58998 }, + { 35486, 36074 }, + { 35488, 37053 }, + { 35489, 58994 }, + { 35491, 58999 }, + { 35492, 36075 }, + { 35493, 58996 }, + { 35494, 58997 }, + { 35495, 64422 }, + { 35496, 58993 }, + { 35500, 37088 }, + { 35501, 37831 }, + { 35504, 37454 }, + { 35506, 35291 }, + { 35513, 38126 }, + { 35516, 35682 }, + { 35518, 64423 }, + { 35519, 37554 }, + { 35522, 59002 }, + { 35524, 59000 }, + { 35527, 37483 }, + { 35531, 37055 }, + { 35532, 35536 }, + { 35533, 59001 }, + { 35535, 36986 }, + { 35538, 38856 }, + { 35542, 39007 }, + { 35546, 59003 }, + { 35547, 59015 }, + { 35548, 37555 }, + { 35550, 59014 }, + { 35551, 64424 }, + { 35552, 59011 }, + { 35553, 59019 }, + { 35554, 59012 }, + { 35556, 59008 }, + { 35558, 37626 }, + { 35559, 59006 }, + { 35563, 59004 }, + { 35565, 38720 }, + { 35566, 36496 }, + { 35569, 59009 }, + { 35571, 59005 }, + { 35574, 64426 }, + { 35575, 59013 }, + { 35576, 36756 }, + { 35578, 36031 }, + { 35582, 37368 }, + { 35584, 38500 }, + { 35585, 35193 }, + { 35586, 35040 }, + { 35588, 37795 }, + { 35591, 59017 }, + { 35596, 59016 }, + { 35598, 37860 }, + { 35600, 59021 }, + { 35604, 59010 }, + { 35606, 59020 }, + { 35607, 59022 }, + { 35609, 36010 }, + { 35610, 59018 }, + { 35611, 36213 }, + { 35613, 36563 }, + { 35616, 59023 }, + { 35617, 38775 }, + { 35622, 59026 }, + { 35624, 59029 }, + { 35627, 59027 }, + { 35628, 38228 }, + { 35635, 59024 }, + { 35641, 35806 }, + { 35646, 59028 }, + { 35649, 59030 }, + { 35657, 59034 }, + { 35660, 59031 }, + { 35662, 59033 }, + { 35663, 59032 }, + { 35667, 64427 }, + { 35670, 59035 }, + { 35672, 36527 }, + { 35674, 59037 }, + { 35675, 59036 }, + { 35676, 38280 }, + { 35679, 59039 }, + { 35686, 35960 }, + { 35691, 59038 }, + { 35692, 59040 }, + { 35695, 59041 }, + { 35696, 35683 }, + { 35697, 58303 }, + { 35698, 36855 }, + { 35700, 59042 }, + { 35703, 36076 }, + { 35709, 59043 }, + { 35711, 64428 }, + { 35712, 59044 }, + { 35715, 36445 }, + { 35722, 40396 }, + { 35724, 59045 }, + { 35726, 59046 }, + { 35728, 36689 }, + { 35730, 59047 }, + { 35731, 59048 }, + { 35734, 59049 }, + { 35737, 59050 }, + { 35738, 59051 }, + { 35895, 37450 }, + { 35898, 59052 }, + { 35903, 59054 }, + { 35905, 59053 }, + { 35910, 37796 }, + { 35912, 59055 }, + { 35914, 38476 }, + { 35916, 59056 }, + { 35918, 59057 }, + { 35920, 59058 }, + { 35925, 59059 }, + { 35930, 37848 }, + { 35937, 36827 }, + { 35938, 59060 }, + { 35946, 36235 }, + { 35947, 39084 }, + { 35948, 59061 }, + { 35960, 59062 }, + { 35961, 38238 }, + { 35962, 59063 }, + { 35964, 59071 }, + { 35970, 59064 }, + { 35973, 59066 }, + { 35977, 59065 }, + { 35978, 59067 }, + { 35980, 38501 }, + { 35981, 59068 }, + { 35982, 59069 }, + { 35988, 59070 }, + { 35992, 59072 }, + { 35997, 35404 }, + { 35998, 37605 }, + { 36000, 38281 }, + { 36001, 36320 }, + { 36002, 36214 }, + { 36007, 38254 }, + { 36008, 35293 }, + { 36009, 38092 }, + { 36010, 59075 }, + { 36011, 35537 }, + { 36012, 37075 }, + { 36013, 59074 }, + { 36014, 59079 }, + { 36015, 37529 }, + { 36016, 38625 }, + { 36018, 59077 }, + { 36019, 59078 }, + { 36020, 35661 }, + { 36022, 59080 }, + { 36023, 38019 }, + { 36024, 37341 }, + { 36027, 38127 }, + { 36028, 37724 }, + { 36029, 59076 }, + { 36031, 38502 }, + { 36032, 35306 }, + { 36033, 59082 }, + { 36034, 38983 }, + { 36035, 37568 }, + { 36036, 39012 }, + { 36039, 36497 }, + { 36040, 59081 }, + { 36042, 37295 }, + { 36045, 59098 }, + { 36046, 37191 }, + { 36049, 37878 }, + { 36051, 38255 }, + { 36058, 59085 }, + { 36059, 36446 }, + { 36060, 36498 }, + { 36062, 36828 }, + { 36064, 38021 }, + { 36066, 36011 }, + { 36067, 59084 }, + { 36068, 59083 }, + { 36070, 38282 }, + { 36074, 36543 }, + { 36077, 37745 }, + { 36080, 64429 }, + { 36084, 64430 }, + { 36090, 59087 }, + { 36091, 59088 }, + { 36092, 36215 }, + { 36093, 59086 }, + { 36100, 59089 }, + { 36101, 59090 }, + { 36103, 59092 }, + { 36104, 37281 }, + { 36106, 59091 }, + { 36107, 35556 }, + { 36109, 59094 }, + { 36111, 59093 }, + { 36112, 59095 }, + { 36114, 64431 }, + { 36115, 59097 }, + { 36116, 59099 }, + { 36118, 59100 }, + { 36196, 37076 }, + { 36198, 36557 }, + { 36199, 59101 }, + { 36203, 35441 }, + { 36205, 59102 }, + { 36208, 37270 }, + { 36209, 59103 }, + { 36211, 59104 }, + { 36212, 38283 }, + { 36214, 64432 }, + { 36215, 35662 }, + { 36225, 59105 }, + { 36229, 37556 }, + { 36234, 35194 }, + { 36249, 59106 }, + { 36259, 36591 }, + { 36264, 37014 }, + { 36275, 37291 }, + { 36282, 59109 }, + { 36286, 59108 }, + { 36290, 59107 }, + { 36299, 59115 }, + { 36300, 59113 }, + { 36303, 59110 }, + { 36310, 59112 }, + { 36314, 59111 }, + { 36315, 59114 }, + { 36317, 35735 }, + { 36319, 59118 }, + { 36321, 37077 }, + { 36323, 59119 }, + { 36328, 36055 }, + { 36330, 59116 }, + { 36331, 59117 }, + { 36335, 38984 }, + { 36339, 37557 }, + { 36341, 37192 }, + { 36348, 59120 }, + { 36351, 59123 }, + { 36360, 59121 }, + { 36361, 59122 }, + { 36362, 38776 }, + { 36367, 37797 }, + { 36368, 59126 }, + { 36381, 59124 }, + { 36382, 59125 }, + { 36383, 59127 }, + { 36394, 59208 }, + { 36400, 59130 }, + { 36404, 59131 }, + { 36405, 59129 }, + { 36418, 59128 }, + { 36420, 37627 }, + { 36423, 59200 }, + { 36424, 59204 }, + { 36425, 59201 }, + { 36426, 59132 }, + { 36428, 59202 }, + { 36432, 59203 }, + { 36437, 59210 }, + { 36441, 59205 }, + { 36447, 37078 }, + { 36448, 59207 }, + { 36451, 59209 }, + { 36452, 59206 }, + { 36466, 59212 }, + { 36468, 36690 }, + { 36470, 59211 }, + { 36476, 59213 }, + { 36481, 59214 }, + { 36484, 59217 }, + { 36485, 59216 }, + { 36487, 59215 }, + { 36490, 59219 }, + { 36491, 59218 }, + { 36493, 38644 }, + { 36497, 59221 }, + { 36499, 59220 }, + { 36500, 59222 }, + { 36505, 59223 }, + { 36513, 59225 }, + { 36522, 59224 }, + { 36523, 36967 }, + { 36524, 59226 }, + { 36527, 35819 }, + { 36528, 59227 }, + { 36529, 59229 }, + { 36542, 59230 }, + { 36549, 59231 }, + { 36550, 59228 }, + { 36552, 59232 }, + { 36554, 36564 }, + { 36555, 59233 }, + { 36556, 35663 }, + { 36557, 35922 }, + { 36559, 64434 }, + { 36562, 36012 }, + { 36571, 59234 }, + { 36575, 37870 }, + { 36578, 37725 }, + { 36579, 59235 }, + { 36587, 59238 }, + { 36600, 36530 }, + { 36603, 59237 }, + { 36604, 59236 }, + { 36605, 35961 }, + { 36606, 59239 }, + { 36611, 35442 }, + { 36613, 59241 }, + { 36617, 36314 }, + { 36618, 59240 }, + { 36620, 59249 }, + { 36626, 59243 }, + { 36627, 59245 }, + { 36628, 38371 }, + { 36629, 59242 }, + { 36633, 59244 }, + { 36635, 59248 }, + { 36636, 59246 }, + { 36637, 35664 }, + { 36639, 59247 }, + { 36646, 59250 }, + { 36649, 38009 }, + { 36650, 38870 }, + { 36655, 36691 }, + { 36659, 59251 }, + { 36664, 38721 }, + { 36665, 59253 }, + { 36667, 59252 }, + { 36670, 59256 }, + { 36671, 38752 }, + { 36674, 59255 }, + { 36676, 35469 }, + { 36677, 59254 }, + { 36678, 59259 }, + { 36681, 59258 }, + { 36684, 59257 }, + { 36685, 37713 }, + { 36686, 59260 }, + { 36695, 59261 }, + { 36700, 59262 }, + { 36703, 36236 }, + { 36705, 35908 }, + { 36706, 59264 }, + { 36707, 59265 }, + { 36708, 59266 }, + { 36763, 36968 }, + { 36764, 59267 }, + { 36766, 36523 }, + { 36767, 59268 }, + { 36771, 59269 }, + { 36775, 39327 }, + { 36776, 39326 }, + { 36781, 59270 }, + { 36782, 58256 }, + { 36783, 59271 }, + { 36784, 37443 }, + { 36785, 36938 }, + { 36786, 37983 }, + { 36791, 59272 }, + { 36794, 38355 }, + { 36795, 37586 }, + { 36796, 36254 }, + { 36799, 37448 }, + { 36802, 35145 }, + { 36804, 38552 }, + { 36805, 36982 }, + { 36814, 35965 }, + { 36817, 35807 }, + { 36820, 38356 }, + { 36826, 59273 }, + { 36834, 59275 }, + { 36837, 59274 }, + { 36838, 35294 }, + { 36841, 37876 }, + { 36842, 59276 }, + { 36843, 38039 }, + { 36845, 37714 }, + { 36847, 59277 }, + { 36848, 36721 }, + { 36852, 59279 }, + { 36855, 38592 }, + { 36856, 59294 }, + { 36857, 59281 }, + { 36858, 59282 }, + { 36861, 37575 }, + { 36864, 37342 }, + { 36865, 37271 }, + { 36867, 37798 }, + { 36869, 59280 }, + { 36870, 35700 }, + { 36875, 59289 }, + { 36877, 59286 }, + { 36878, 59299 }, + { 36879, 37799 }, + { 36880, 37504 }, + { 36881, 59283 }, + { 36883, 37628 }, + { 36884, 37746 }, + { 36885, 59284 }, + { 36886, 59288 }, + { 36887, 36992 }, + { 36889, 38023 }, + { 36890, 37578 }, + { 36893, 37056 }, + { 36894, 59287 }, + { 36895, 37292 }, + { 36896, 37282 }, + { 36897, 59285 }, + { 36898, 34983 }, + { 36899, 38977 }, + { 36903, 59290 }, + { 36910, 37343 }, + { 36913, 36692 }, + { 36914, 36969 }, + { 36917, 59292 }, + { 36918, 59291 }, + { 36920, 35053 }, + { 36921, 59293 }, + { 36924, 38222 }, + { 36926, 59301 }, + { 36929, 37849 }, + { 36930, 37003 }, + { 36933, 37496 }, + { 36935, 35830 }, + { 36937, 59300 }, + { 36938, 38742 }, + { 36939, 35166 }, + { 36941, 38357 }, + { 36942, 35295 }, + { 36943, 59295 }, + { 36944, 59296 }, + { 36945, 59297 }, + { 36946, 59298 }, + { 36947, 37817 }, + { 36948, 37442 }, + { 36949, 35041 }, + { 36950, 59302 }, + { 36952, 59303 }, + { 36953, 60065 }, + { 36956, 37307 }, + { 36958, 59304 }, + { 36960, 35219 }, + { 36961, 37227 }, + { 36963, 36013 }, + { 36965, 38777 }, + { 36967, 64437 }, + { 36968, 59305 }, + { 36969, 37707 }, + { 36973, 37272 }, + { 36974, 36565 }, + { 36975, 59306 }, + { 36978, 59309 }, + { 36981, 36741 }, + { 36982, 59307 }, + { 36983, 37194 }, + { 36984, 37193 }, + { 36986, 35042 }, + { 36988, 38857 }, + { 36989, 59311 }, + { 36991, 38128 }, + { 36992, 59313 }, + { 36993, 59312 }, + { 36994, 59310 }, + { 36995, 57988 }, + { 36996, 35538 }, + { 36999, 59278 }, + { 37001, 59315 }, + { 37002, 59314 }, + { 37007, 59316 }, + { 37009, 38743 }, + { 37027, 37855 }, + { 37030, 38477 }, + { 37032, 59317 }, + { 37034, 36567 }, + { 37039, 59318 }, + { 37041, 59319 }, + { 37045, 59320 }, + { 37048, 37696 }, + { 37057, 35048 }, + { 37066, 36216 }, + { 37070, 39001 }, + { 37083, 59324 }, + { 37086, 64438 }, + { 37089, 35923 }, + { 37090, 59321 }, + { 37092, 59322 }, + { 37096, 38292 }, + { 37101, 35443 }, + { 37109, 38744 }, + { 37111, 35773 }, + { 37117, 37747 }, + { 37122, 59325 }, + { 37138, 59326 }, + { 37141, 64440 }, + { 37145, 59327 }, + { 37159, 64441 }, + { 37165, 37697 }, + { 37168, 59329 }, + { 37170, 59328 }, + { 37193, 37841 }, + { 37194, 59330 }, + { 37195, 36693 }, + { 37196, 36574 }, + { 37197, 38010 }, + { 37198, 37521 }, + { 37202, 36592 }, + { 37204, 37004 }, + { 37206, 59331 }, + { 37208, 59332 }, + { 37218, 36988 }, + { 37219, 59333 }, + { 37221, 59334 }, + { 37225, 59335 }, + { 37226, 38799 }, + { 37228, 36694 }, + { 37234, 59337 }, + { 37235, 59336 }, + { 37237, 36217 }, + { 37239, 36243 }, + { 37240, 36447 }, + { 37250, 59340 }, + { 37255, 36742 }, + { 37257, 59339 }, + { 37259, 59338 }, + { 37261, 37351 }, + { 37264, 36077 }, + { 37266, 37057 }, + { 37271, 38062 }, + { 37276, 36696 }, + { 37282, 59341 }, + { 37284, 36829 }, + { 37290, 59344 }, + { 37291, 59342 }, + { 37295, 59343 }, + { 37300, 59346 }, + { 37301, 59345 }, + { 37304, 36856 }, + { 37306, 59347 }, + { 37312, 59348 }, + { 37313, 59349 }, + { 37318, 38094 }, + { 37319, 36305 }, + { 37320, 36575 }, + { 37321, 59350 }, + { 37323, 59351 }, + { 37324, 38818 }, + { 37325, 36708 }, + { 37326, 38636 }, + { 37327, 38858 }, + { 37328, 59352 }, + { 37329, 35808 }, + { 37334, 59353 }, + { 37335, 64443 }, + { 37336, 37698 }, + { 37338, 64442 }, + { 37339, 59356 }, + { 37340, 35480 }, + { 37341, 36970 }, + { 37342, 64444 }, + { 37343, 59354 }, + { 37345, 59355 }, + { 37347, 37598 }, + { 37348, 64447 }, + { 37349, 64448 }, + { 37350, 38516 }, + { 37351, 35834 }, + { 37357, 64445 }, + { 37358, 64446 }, + { 37365, 59358 }, + { 37366, 59359 }, + { 37372, 59357 }, + { 37375, 59361 }, + { 37382, 64449 }, + { 37386, 64451 }, + { 37389, 37853 }, + { 37390, 35426 }, + { 37392, 64450 }, + { 37393, 59365 }, + { 37396, 59362 }, + { 37397, 59364 }, + { 37406, 59360 }, + { 37417, 59502 }, + { 37420, 59363 }, + { 37428, 38889 }, + { 37431, 36056 }, + { 37433, 64458 }, + { 37434, 64452 }, + { 37436, 64454 }, + { 37439, 59373 }, + { 37440, 64453 }, + { 37444, 37715 }, + { 37445, 59368 }, + { 37448, 59371 }, + { 37449, 59369 }, + { 37451, 59374 }, + { 37454, 64455 }, + { 37456, 59375 }, + { 37457, 64457 }, + { 37463, 59367 }, + { 37465, 64456 }, + { 37466, 59380 }, + { 37467, 35220 }, + { 37470, 59366 }, + { 37474, 38059 }, + { 37476, 59370 }, + { 37478, 36830 }, + { 37479, 64459 }, + { 37489, 36218 }, + { 37495, 64461 }, + { 37496, 64462 }, + { 37502, 38503 }, + { 37504, 35810 }, + { 37507, 36709 }, + { 37509, 37818 }, + { 37512, 64095 }, + { 37521, 37196 }, + { 37523, 59378 }, + { 37525, 59372 }, + { 37526, 59377 }, + { 37528, 38593 }, + { 37530, 37558 }, + { 37531, 59379 }, + { 37532, 59376 }, + { 37543, 64460 }, + { 37549, 37195 }, + { 37559, 59383 }, + { 37561, 59382 }, + { 37583, 59381 }, + { 37584, 64466 }, + { 37586, 38478 }, + { 37587, 64470 }, + { 37589, 64468 }, + { 37591, 64464 }, + { 37593, 64465 }, + { 37600, 64469 }, + { 37604, 36763 }, + { 37607, 64463 }, + { 37609, 59384 }, + { 37610, 38365 }, + { 37613, 35187 }, + { 37618, 38245 }, + { 37619, 37522 }, + { 37624, 35736 }, + { 37625, 64101 }, + { 37626, 59386 }, + { 37627, 64473 }, + { 37628, 36220 }, + { 37631, 64476 }, + { 37634, 64478 }, + { 37638, 36427 }, + { 37647, 59385 }, + { 37648, 37005 }, + { 37656, 37006 }, + { 37657, 59456 }, + { 37658, 59458 }, + { 37661, 64477 }, + { 37662, 64475 }, + { 37664, 36857 }, + { 37665, 64472 }, + { 37666, 59457 }, + { 37667, 59459 }, + { 37669, 64471 }, + { 37670, 35793 }, + { 37672, 38244 }, + { 37675, 36576 }, + { 37676, 38978 }, + { 37678, 59388 }, + { 37679, 36342 }, + { 37682, 39006 }, + { 37685, 59461 }, + { 37690, 59460 }, + { 37691, 59462 }, + { 37700, 59387 }, + { 37704, 64094 }, + { 37707, 37863 }, + { 37709, 37748 }, + { 37716, 37589 }, + { 37718, 59467 }, + { 37719, 64480 }, + { 37723, 37474 }, + { 37724, 59463 }, + { 37728, 59464 }, + { 37740, 35916 }, + { 37742, 59466 }, + { 37744, 64479 }, + { 37749, 36014 }, + { 37756, 59465 }, + { 37758, 36831 }, + { 37772, 35481 }, + { 37780, 59471 }, + { 37782, 36285 }, + { 37783, 37273 }, + { 37786, 37576 }, + { 37796, 64481 }, + { 37799, 35418 }, + { 37804, 59469 }, + { 37805, 59470 }, + { 37806, 37569 }, + { 37808, 59468 }, + { 37817, 59472 }, + { 37827, 59478 }, + { 37830, 64482 }, + { 37832, 59481 }, + { 37840, 59480 }, + { 37841, 37708 }, + { 37846, 59473 }, + { 37847, 59474 }, + { 37848, 59477 }, + { 37853, 59479 }, + { 37854, 64483 }, + { 37857, 35774 }, + { 37860, 59482 }, + { 37861, 59476 }, + { 37864, 59475 }, + { 37880, 64484 }, + { 37891, 59486 }, + { 37895, 59487 }, + { 37904, 59488 }, + { 37907, 59485 }, + { 37908, 59484 }, + { 37912, 36832 }, + { 37913, 37800 }, + { 37914, 59483 }, + { 37921, 59492 }, + { 37931, 59490 }, + { 37937, 64485 }, + { 37941, 59491 }, + { 37942, 59489 }, + { 37944, 37366 }, + { 37946, 59493 }, + { 37953, 59494 }, + { 37956, 59496 }, + { 37957, 64486 }, + { 37960, 64487 }, + { 37969, 35539 }, + { 37970, 59495 }, + { 37971, 38648 }, + { 37978, 59507 }, + { 37979, 59497 }, + { 37982, 59500 }, + { 37984, 59498 }, + { 37986, 59499 }, + { 37994, 59501 }, + { 38000, 59503 }, + { 38005, 59504 }, + { 38007, 59505 }, + { 38012, 59508 }, + { 38013, 59506 }, + { 38014, 59509 }, + { 38015, 59511 }, + { 38017, 59510 }, + { 38263, 37559 }, + { 38272, 38629 }, + { 38274, 59512 }, + { 38275, 37197 }, + { 38279, 59513 }, + { 38281, 38338 }, + { 38282, 59514 }, + { 38283, 35402 }, + { 38287, 35163 }, + { 38289, 35541 }, + { 38290, 64488 }, + { 38291, 35540 }, + { 38292, 59515 }, + { 38294, 59516 }, + { 38296, 59517 }, + { 38297, 59518 }, + { 38304, 59520 }, + { 38306, 35542 }, + { 38307, 35444 }, + { 38308, 36221 }, + { 38309, 38068 }, + { 38311, 59522 }, + { 38312, 59521 }, + { 38317, 59523 }, + { 38322, 35195 }, + { 38329, 59526 }, + { 38331, 59525 }, + { 38332, 59524 }, + { 38334, 59527 }, + { 38339, 59530 }, + { 38343, 35013 }, + { 38346, 59528 }, + { 38348, 59532 }, + { 38349, 59531 }, + { 38356, 59534 }, + { 38357, 59533 }, + { 38358, 59535 }, + { 38360, 37804 }, + { 38364, 59536 }, + { 38369, 59537 }, + { 38370, 59539 }, + { 38373, 59538 }, + { 38428, 38284 }, + { 38433, 59540 }, + { 38440, 59541 }, + { 38442, 36323 }, + { 38446, 59542 }, + { 38447, 59543 }, + { 38450, 38504 }, + { 38459, 37226 }, + { 38463, 34978 }, + { 38464, 37321 }, + { 38466, 59544 }, + { 38468, 38285 }, + { 38475, 59547 }, + { 38476, 59545 }, + { 38477, 36222 }, + { 38479, 59546 }, + { 38480, 36032 }, + { 38491, 38339 }, + { 38492, 59549 }, + { 38493, 59551 }, + { 38494, 59550 }, + { 38495, 59552 }, + { 38498, 35136 }, + { 38499, 36983 }, + { 38500, 36764 }, + { 38501, 35543 }, + { 38502, 59553 }, + { 38506, 38022 }, + { 38508, 59555 }, + { 38512, 35137 }, + { 38514, 59554 }, + { 38515, 37570 }, + { 38517, 38859 }, + { 38518, 37801 }, + { 38519, 59548 }, + { 38520, 38820 }, + { 38522, 36015 }, + { 38525, 38778 }, + { 38533, 35831 }, + { 38534, 38834 }, + { 38536, 35911 }, + { 38538, 37344 }, + { 38539, 58432 }, + { 38541, 59556 }, + { 38542, 35403 }, + { 38543, 37007 }, + { 38548, 35445 }, + { 38549, 59558 }, + { 38551, 59559 }, + { 38552, 59557 }, + { 38553, 35972 }, + { 38555, 36315 }, + { 38556, 36833 }, + { 38557, 64491 }, + { 38560, 35138 }, + { 38563, 38871 }, + { 38567, 59561 }, + { 38568, 59308 }, + { 38570, 59560 }, + { 38575, 64492 }, + { 38576, 59564 }, + { 38577, 59562 }, + { 38578, 59563 }, + { 38580, 59565 }, + { 38582, 59566 }, + { 38583, 38890 }, + { 38584, 59567 }, + { 38585, 59568 }, + { 38587, 37063 }, + { 38588, 38073 }, + { 38592, 37021 }, + { 38593, 35557 }, + { 38596, 38745 }, + { 38597, 35307 }, + { 38598, 36695 }, + { 38599, 36057 }, + { 38601, 59571 }, + { 38603, 59570 }, + { 38604, 36499 }, + { 38605, 59572 }, + { 38606, 59569 }, + { 38609, 36423 }, + { 38613, 59576 }, + { 38614, 58795 }, + { 38617, 39380 }, + { 38619, 37015 }, + { 38620, 59574 }, + { 38626, 38819 }, + { 38627, 37871 }, + { 38632, 35146 }, + { 38634, 37089 }, + { 38635, 36532 }, + { 38640, 38325 }, + { 38642, 35167 }, + { 38646, 38891 }, + { 38647, 38795 }, + { 38649, 59577 }, + { 38651, 37732 }, + { 38656, 36601 }, + { 38660, 59578 }, + { 38662, 59579 }, + { 38663, 36971 }, + { 38664, 59580 }, + { 38666, 38892 }, + { 38669, 59575 }, + { 38670, 59582 }, + { 38671, 59584 }, + { 38673, 59583 }, + { 38675, 59581 }, + { 38678, 59585 }, + { 38681, 59586 }, + { 38684, 37274 }, + { 38686, 35296 }, + { 38692, 59587 }, + { 38695, 38582 }, + { 38698, 59588 }, + { 38704, 59589 }, + { 38706, 38985 }, + { 38707, 64493 }, + { 38712, 40528 }, + { 38713, 59590 }, + { 38715, 64494 }, + { 38717, 59591 }, + { 38718, 59592 }, + { 38722, 59596 }, + { 38723, 64495 }, + { 38724, 59593 }, + { 38726, 59594 }, + { 38728, 59595 }, + { 38729, 59597 }, + { 38733, 64496 }, + { 38735, 64497 }, + { 38737, 64498 }, + { 38738, 37058 }, + { 38741, 64499 }, + { 38742, 38645 }, + { 38745, 37059 }, + { 38748, 59598 }, + { 38750, 38129 }, + { 38752, 59599 }, + { 38753, 60018 }, + { 38754, 38602 }, + { 38756, 59600 }, + { 38758, 59601 }, + { 38760, 59602 }, + { 38761, 35446 }, + { 38763, 59604 }, + { 38765, 36984 }, + { 38769, 59605 }, + { 38772, 35907 }, + { 38777, 59606 }, + { 38778, 59610 }, + { 38780, 59608 }, + { 38785, 59609 }, + { 38788, 35475 }, + { 38789, 59607 }, + { 38790, 59611 }, + { 38795, 59612 }, + { 38797, 35014 }, + { 38799, 59613 }, + { 38800, 59614 }, + { 38808, 36834 }, + { 38812, 59615 }, + { 38816, 35686 }, + { 38819, 59618 }, + { 38822, 59617 }, + { 38824, 59616 }, + { 38827, 59025 }, + { 38829, 38362 }, + { 38835, 59619 }, + { 38836, 59620 }, + { 38851, 59621 }, + { 38854, 59622 }, + { 38856, 59623 }, + { 38859, 59624 }, + { 38867, 35544 }, + { 38876, 59625 }, + { 38893, 59626 }, + { 38894, 37954 }, + { 38898, 59628 }, + { 38899, 35257 }, + { 38901, 59631 }, + { 38902, 59630 }, + { 38907, 35139 }, + { 38911, 35775 }, + { 38913, 38341 }, + { 38914, 37560 }, + { 38915, 36256 }, + { 38917, 36224 }, + { 38918, 36743 }, + { 38920, 36987 }, + { 38924, 59633 }, + { 38927, 59632 }, + { 38928, 38753 }, + { 38929, 35558 }, + { 38930, 38096 }, + { 38931, 37850 }, + { 38935, 37020 }, + { 38936, 38860 }, + { 38938, 35962 }, + { 38945, 59636 }, + { 38948, 59635 }, + { 38956, 38506 }, + { 38957, 37802 }, + { 38964, 35183 }, + { 38967, 59637 }, + { 38968, 59634 }, + { 38971, 38256 }, + { 38972, 38794 }, + { 38973, 59638 }, + { 38982, 59639 }, + { 38987, 59641 }, + { 38988, 37352 }, + { 38989, 35450 }, + { 38990, 35451 }, + { 38991, 59640 }, + { 38996, 35559 }, + { 38997, 36016 }, + { 38999, 64500 }, + { 39000, 35560 }, + { 39003, 37726 }, + { 39006, 38878 }, + { 39013, 64501 }, + { 39015, 36058 }, + { 39019, 59642 }, + { 39023, 59643 }, + { 39024, 59644 }, + { 39025, 59712 }, + { 39027, 59714 }, + { 39028, 59713 }, + { 39080, 38295 }, + { 39082, 59715 }, + { 39087, 59716 }, + { 39089, 59717 }, + { 39094, 59718 }, + { 39107, 59720 }, + { 39108, 59719 }, + { 39110, 59721 }, + { 39131, 38130 }, + { 39132, 58314 }, + { 39135, 36936 }, + { 39138, 35665 }, + { 39145, 59722 }, + { 39147, 59723 }, + { 39149, 39338 }, + { 39150, 40794 }, + { 39151, 38097 }, + { 39154, 35065 }, + { 39156, 35001 }, + { 39164, 36500 }, + { 39165, 38479 }, + { 39166, 36860 }, + { 39171, 59724 }, + { 39173, 38621 }, + { 39177, 59725 }, + { 39178, 38779 }, + { 39180, 35169 }, + { 39184, 36448 }, + { 39186, 59726 }, + { 39187, 35308 }, + { 39188, 59727 }, + { 39192, 59728 }, + { 39197, 59730 }, + { 39198, 59731 }, + { 39200, 59733 }, + { 39201, 59729 }, + { 39204, 59732 }, + { 39207, 64504 }, + { 39208, 35545 }, + { 39212, 59734 }, + { 39214, 59735 }, + { 39229, 59736 }, + { 39230, 59737 }, + { 39234, 59738 }, + { 39237, 59740 }, + { 39241, 59739 }, + { 39243, 59742 }, + { 39244, 59745 }, + { 39248, 59741 }, + { 39249, 59743 }, + { 39250, 59744 }, + { 39253, 59746 }, + { 39255, 35776 }, + { 39318, 36593 }, + { 39319, 59747 }, + { 39320, 59748 }, + { 39321, 36225 }, + { 39326, 64506 }, + { 39333, 59749 }, + { 39336, 35421 }, + { 39340, 37998 }, + { 39341, 59750 }, + { 39342, 59751 }, + { 39347, 37497 }, + { 39348, 37865 }, + { 39356, 59752 }, + { 39361, 38045 }, + { 39364, 37322 }, + { 39365, 35191 }, + { 39366, 35820 }, + { 39368, 35821 }, + { 39376, 37523 }, + { 39377, 59757 }, + { 39378, 35822 }, + { 39381, 35309 }, + { 39384, 59756 }, + { 39387, 59754 }, + { 39389, 59755 }, + { 39391, 59753 }, + { 39394, 59767 }, + { 39405, 59758 }, + { 39406, 59759 }, + { 39409, 59760 }, + { 39410, 59761 }, + { 39416, 59763 }, + { 39419, 59762 }, + { 39423, 36728 }, + { 39425, 59764 }, + { 39429, 59766 }, + { 39438, 35666 }, + { 39439, 59765 }, + { 39442, 37275 }, + { 39443, 36017 }, + { 39449, 59768 }, + { 39464, 37323 }, + { 39467, 59769 }, + { 39472, 37803 }, + { 39479, 59770 }, + { 39486, 59776 }, + { 39488, 59773 }, + { 39490, 59772 }, + { 39491, 59774 }, + { 39493, 59771 }, + { 39501, 59778 }, + { 39502, 64507 }, + { 39509, 59777 }, + { 39511, 59780 }, + { 39514, 35777 }, + { 39515, 59779 }, + { 39519, 59781 }, + { 39522, 59782 }, + { 39524, 59784 }, + { 39525, 59783 }, + { 39529, 59785 }, + { 39530, 59787 }, + { 39531, 59786 }, + { 39592, 36252 }, + { 39597, 59788 }, + { 39600, 59789 }, + { 39608, 35419 }, + { 39612, 59790 }, + { 39616, 59791 }, + { 39620, 37009 }, + { 39631, 59792 }, + { 39633, 59793 }, + { 39635, 59794 }, + { 39636, 59795 }, + { 39640, 36226 }, + { 39641, 64508 }, + { 39644, 64576 }, + { 39646, 59796 }, + { 39647, 59797 }, + { 39650, 59798 }, + { 39651, 59799 }, + { 39654, 59800 }, + { 39658, 38063 }, + { 39659, 59802 }, + { 39661, 38213 }, + { 39662, 59803 }, + { 39663, 59801 }, + { 39665, 59805 }, + { 39668, 59804 }, + { 39671, 59806 }, + { 39675, 59807 }, + { 39686, 59808 }, + { 39704, 59809 }, + { 39706, 59810 }, + { 39711, 59811 }, + { 39714, 59812 }, + { 39715, 59813 }, + { 39717, 59814 }, + { 39719, 59815 }, + { 39720, 59816 }, + { 39721, 59817 }, + { 39722, 59818 }, + { 39726, 59819 }, + { 39727, 59820 }, + { 39729, 40788 }, + { 39730, 59821 }, + { 39739, 58102 }, + { 39740, 35667 }, + { 39745, 35392 }, + { 39746, 36272 }, + { 39747, 59823 }, + { 39748, 59822 }, + { 39749, 38563 }, + { 39757, 59825 }, + { 39758, 59826 }, + { 39759, 59824 }, + { 39761, 59827 }, + { 39764, 38530 }, + { 39768, 59828 }, + { 39770, 35739 }, + { 39791, 38980 }, + { 39794, 64578 }, + { 39796, 59829 }, + { 39797, 64577 }, + { 39811, 59831 }, + { 39822, 35004 }, + { 39823, 64579 }, + { 39825, 59832 }, + { 39826, 38313 }, + { 39827, 59830 }, + { 39830, 59833 }, + { 39831, 59834 }, + { 39839, 59835 }, + { 39840, 59836 }, + { 39848, 59837 }, + { 39850, 38542 }, + { 39851, 36428 }, + { 39853, 36344 }, + { 39854, 37198 }, + { 39857, 64580 }, + { 39860, 59838 }, + { 39865, 59841 }, + { 39867, 64581 }, + { 39872, 59839 }, + { 39878, 59842 }, + { 39881, 36079 }, + { 39882, 59840 }, + { 39887, 59843 }, + { 39889, 59844 }, + { 39890, 59845 }, + { 39892, 59849 }, + { 39894, 36425 }, + { 39899, 37346 }, + { 39905, 59850 }, + { 39906, 59847 }, + { 39907, 59846 }, + { 39908, 59848 }, + { 39912, 35966 }, + { 39920, 59854 }, + { 39921, 59853 }, + { 39922, 59852 }, + { 39925, 34993 }, + { 39936, 64582 }, + { 39940, 59864 }, + { 39942, 59860 }, + { 39944, 59861 }, + { 39945, 59857 }, + { 39946, 59863 }, + { 39948, 59859 }, + { 39949, 35458 }, + { 39952, 39019 }, + { 39954, 59862 }, + { 39955, 59858 }, + { 39956, 59856 }, + { 39957, 59855 }, + { 39963, 59866 }, + { 39969, 59869 }, + { 39972, 59868 }, + { 39973, 59867 }, + { 39981, 38248 }, + { 39982, 59865 }, + { 39983, 35057 }, + { 39984, 59870 }, + { 39986, 59872 }, + { 39993, 35471 }, + { 39994, 59851 }, + { 39995, 35158 }, + { 39998, 59874 }, + { 40006, 59873 }, + { 40007, 59871 }, + { 40008, 37452 }, + { 40018, 38544 }, + { 40023, 38872 }, + { 40026, 59875 }, + { 40032, 59876 }, + { 40039, 59877 }, + { 40054, 59878 }, + { 40056, 59879 }, + { 40165, 37561 }, + { 40167, 59880 }, + { 40169, 38069 }, + { 40171, 59885 }, + { 40172, 59881 }, + { 40176, 59882 }, + { 40179, 38480 }, + { 40180, 38594 }, + { 40182, 37838 }, + { 40195, 59886 }, + { 40198, 59887 }, + { 40199, 37820 }, + { 40200, 59884 }, + { 40201, 59883 }, + { 40206, 35240 }, + { 40210, 59895 }, + { 40213, 59894 }, + { 40219, 35221 }, + { 40223, 59892 }, + { 40227, 59891 }, + { 40230, 59889 }, + { 40232, 35483 }, + { 40234, 59888 }, + { 40235, 36528 }, + { 40236, 35239 }, + { 40251, 36227 }, + { 40254, 59898 }, + { 40255, 59897 }, + { 40257, 59896 }, + { 40260, 59893 }, + { 40262, 59899 }, + { 40264, 59900 }, + { 40272, 59972 }, + { 40273, 59971 }, + { 40281, 59973 }, + { 40284, 35148 }, + { 40285, 59968 }, + { 40286, 59969 }, + { 40288, 36244 }, + { 40289, 38583 }, + { 40292, 59970 }, + { 40299, 64584 }, + { 40300, 38481 }, + { 40303, 59978 }, + { 40304, 64583 }, + { 40306, 59974 }, + { 40314, 59979 }, + { 40327, 59976 }, + { 40329, 59975 }, + { 40335, 35963 }, + { 40346, 59980 }, + { 40356, 59981 }, + { 40361, 59982 }, + { 40363, 59977 }, + { 40367, 59890 }, + { 40370, 59983 }, + { 40372, 37599 }, + { 40376, 59987 }, + { 40378, 59988 }, + { 40379, 59986 }, + { 40385, 59985 }, + { 40386, 59991 }, + { 40388, 59984 }, + { 40390, 59989 }, + { 40399, 59990 }, + { 40403, 59993 }, + { 40409, 59992 }, + { 40422, 59995 }, + { 40429, 59996 }, + { 40431, 59997 }, + { 40434, 39016 }, + { 40440, 59994 }, + { 40441, 37353 }, + { 40442, 36331 }, + { 40445, 59998 }, + { 40473, 64586 }, + { 40474, 59999 }, + { 40475, 60000 }, + { 40478, 60001 }, + { 40565, 60002 }, + { 40568, 36018 }, + { 40569, 60003 }, + { 40573, 60004 }, + { 40575, 36525 }, + { 40577, 60005 }, + { 40584, 60006 }, + { 40587, 60007 }, + { 40588, 60008 }, + { 40593, 60011 }, + { 40594, 60009 }, + { 40595, 39003 }, + { 40597, 60010 }, + { 40599, 38893 }, + { 40605, 60012 }, + { 40607, 38873 }, + { 40613, 60013 }, + { 40614, 38046 }, + { 40617, 60014 }, + { 40618, 60016 }, + { 40621, 60017 }, + { 40632, 60015 }, + { 40633, 36237 }, + { 40634, 38603 }, + { 40635, 38531 }, + { 40636, 39925 }, + { 40638, 40832 }, + { 40639, 38555 }, + { 40644, 35241 }, + { 40652, 60019 }, + { 40653, 35695 }, + { 40654, 60020 }, + { 40655, 60021 }, + { 40656, 60022 }, + { 40657, 64587 }, + { 40658, 36245 }, + { 40660, 60023 }, + { 40664, 57554 }, + { 40665, 38617 }, + { 40667, 37345 }, + { 40668, 60024 }, + { 40669, 60026 }, + { 40670, 60025 }, + { 40672, 60027 }, + { 40677, 60028 }, + { 40680, 60029 }, + { 40687, 60030 }, + { 40692, 60032 }, + { 40694, 60033 }, + { 40695, 60034 }, + { 40697, 60035 }, + { 40699, 60036 }, + { 40700, 60037 }, + { 40701, 60038 }, + { 40711, 60039 }, + { 40712, 60040 }, + { 40718, 37699 }, + { 40723, 36059 }, + { 40725, 60042 }, + { 40736, 37228 }, + { 40737, 60043 }, + { 40748, 60044 }, + { 40763, 38208 }, + { 40766, 60045 }, + { 40778, 60046 }, + { 40779, 57942 }, + { 40782, 59096 }, + { 40783, 59627 }, + { 40786, 60047 }, + { 40788, 60048 }, + { 40799, 60050 }, + { 40800, 60051 }, + { 40801, 60052 }, + { 40802, 38894 }, + { 40803, 60049 }, + { 40806, 60053 }, + { 40807, 60054 }, + { 40810, 60056 }, + { 40812, 60055 }, + { 40818, 60058 }, + { 40822, 60059 }, + { 40823, 60057 }, + { 40845, 38836 }, + { 40853, 60060 }, + { 40860, 60061 }, + { 40861, 57971 }, + { 40864, 60062 }, + { 57344, 61504 }, + { 57345, 61505 }, + { 57346, 61506 }, + { 57347, 61507 }, + { 57348, 61508 }, + { 57349, 61509 }, + { 57350, 61510 }, + { 57351, 61511 }, + { 57352, 61512 }, + { 57353, 61513 }, + { 57354, 61514 }, + { 57355, 61515 }, + { 57356, 61516 }, + { 57357, 61517 }, + { 57358, 61518 }, + { 57359, 61519 }, + { 57360, 61520 }, + { 57361, 61521 }, + { 57362, 61522 }, + { 57363, 61523 }, + { 57364, 61524 }, + { 57365, 61525 }, + { 57366, 61526 }, + { 57367, 61527 }, + { 57368, 61528 }, + { 57369, 61529 }, + { 57370, 61530 }, + { 57371, 61531 }, + { 57372, 61532 }, + { 57373, 61533 }, + { 57374, 61534 }, + { 57375, 61535 }, + { 57376, 61536 }, + { 57377, 61537 }, + { 57378, 61538 }, + { 57379, 61539 }, + { 57380, 61540 }, + { 57381, 61541 }, + { 57382, 61542 }, + { 57383, 61543 }, + { 57384, 61544 }, + { 57385, 61545 }, + { 57386, 61546 }, + { 57387, 61547 }, + { 57388, 61548 }, + { 57389, 61549 }, + { 57390, 61550 }, + { 57391, 61551 }, + { 57392, 61552 }, + { 57393, 61553 }, + { 57394, 61554 }, + { 57395, 61555 }, + { 57396, 61556 }, + { 57397, 61557 }, + { 57398, 61558 }, + { 57399, 61559 }, + { 57400, 61560 }, + { 57401, 61561 }, + { 57402, 61562 }, + { 57403, 61563 }, + { 57404, 61564 }, + { 57405, 61565 }, + { 57406, 61566 }, + { 57407, 61568 }, + { 57408, 61569 }, + { 57409, 61570 }, + { 57410, 61571 }, + { 57411, 61572 }, + { 57412, 61573 }, + { 57413, 61574 }, + { 57414, 61575 }, + { 57415, 61576 }, + { 57416, 61577 }, + { 57417, 61578 }, + { 57418, 61579 }, + { 57419, 61580 }, + { 57420, 61581 }, + { 57421, 61582 }, + { 57422, 61583 }, + { 57423, 61584 }, + { 57424, 61585 }, + { 57425, 61586 }, + { 57426, 61587 }, + { 57427, 61588 }, + { 57428, 61589 }, + { 57429, 61590 }, + { 57430, 61591 }, + { 57431, 61592 }, + { 57432, 61593 }, + { 57433, 61594 }, + { 57434, 61595 }, + { 57435, 61596 }, + { 57436, 61597 }, + { 57437, 61598 }, + { 57438, 61599 }, + { 57439, 61600 }, + { 57440, 61601 }, + { 57441, 61602 }, + { 57442, 61603 }, + { 57443, 61604 }, + { 57444, 61605 }, + { 57445, 61606 }, + { 57446, 61607 }, + { 57447, 61608 }, + { 57448, 61609 }, + { 57449, 61610 }, + { 57450, 61611 }, + { 57451, 61612 }, + { 57452, 61613 }, + { 57453, 61614 }, + { 57454, 61615 }, + { 57455, 61616 }, + { 57456, 61617 }, + { 57457, 61618 }, + { 57458, 61619 }, + { 57459, 61620 }, + { 57460, 61621 }, + { 57461, 61622 }, + { 57462, 61623 }, + { 57463, 61624 }, + { 57464, 61625 }, + { 57465, 61626 }, + { 57466, 61627 }, + { 57467, 61628 }, + { 57468, 61629 }, + { 57469, 61630 }, + { 57470, 61631 }, + { 57471, 61632 }, + { 57472, 61633 }, + { 57473, 61634 }, + { 57474, 61635 }, + { 57475, 61636 }, + { 57476, 61637 }, + { 57477, 61638 }, + { 57478, 61639 }, + { 57479, 61640 }, + { 57480, 61641 }, + { 57481, 61642 }, + { 57482, 61643 }, + { 57483, 61644 }, + { 57484, 61645 }, + { 57485, 61646 }, + { 57486, 61647 }, + { 57487, 61648 }, + { 57488, 61649 }, + { 57489, 61650 }, + { 57490, 61651 }, + { 57491, 61652 }, + { 57492, 61653 }, + { 57493, 61654 }, + { 57494, 61655 }, + { 57495, 61656 }, + { 57496, 61657 }, + { 57497, 61658 }, + { 57498, 61659 }, + { 57499, 61660 }, + { 57500, 61661 }, + { 57501, 61662 }, + { 57502, 61663 }, + { 57503, 61664 }, + { 57504, 61665 }, + { 57505, 61666 }, + { 57506, 61667 }, + { 57507, 61668 }, + { 57508, 61669 }, + { 57509, 61670 }, + { 57510, 61671 }, + { 57511, 61672 }, + { 57512, 61673 }, + { 57513, 61674 }, + { 57514, 61675 }, + { 57515, 61676 }, + { 57516, 61677 }, + { 57517, 61678 }, + { 57518, 61679 }, + { 57519, 61680 }, + { 57520, 61681 }, + { 57521, 61682 }, + { 57522, 61683 }, + { 57523, 61684 }, + { 57524, 61685 }, + { 57525, 61686 }, + { 57526, 61687 }, + { 57527, 61688 }, + { 57528, 61689 }, + { 57529, 61690 }, + { 57530, 61691 }, + { 57531, 61692 }, + { 57532, 61760 }, + { 57533, 61761 }, + { 57534, 61762 }, + { 57535, 61763 }, + { 57536, 61764 }, + { 57537, 61765 }, + { 57538, 61766 }, + { 57539, 61767 }, + { 57540, 61768 }, + { 57541, 61769 }, + { 57542, 61770 }, + { 57543, 61771 }, + { 57544, 61772 }, + { 57545, 61773 }, + { 57546, 61774 }, + { 57547, 61775 }, + { 57548, 61776 }, + { 57549, 61777 }, + { 57550, 61778 }, + { 57551, 61779 }, + { 57552, 61780 }, + { 57553, 61781 }, + { 57554, 61782 }, + { 57555, 61783 }, + { 57556, 61784 }, + { 57557, 61785 }, + { 57558, 61786 }, + { 57559, 61787 }, + { 57560, 61788 }, + { 57561, 61789 }, + { 57562, 61790 }, + { 57563, 61791 }, + { 57564, 61792 }, + { 57565, 61793 }, + { 57566, 61794 }, + { 57567, 61795 }, + { 57568, 61796 }, + { 57569, 61797 }, + { 57570, 61798 }, + { 57571, 61799 }, + { 57572, 61800 }, + { 57573, 61801 }, + { 57574, 61802 }, + { 57575, 61803 }, + { 57576, 61804 }, + { 57577, 61805 }, + { 57578, 61806 }, + { 57579, 61807 }, + { 57580, 61808 }, + { 57581, 61809 }, + { 57582, 61810 }, + { 57583, 61811 }, + { 57584, 61812 }, + { 57585, 61813 }, + { 57586, 61814 }, + { 57587, 61815 }, + { 57588, 61816 }, + { 57589, 61817 }, + { 57590, 61818 }, + { 57591, 61819 }, + { 57592, 61820 }, + { 57593, 61821 }, + { 57594, 61822 }, + { 57595, 61824 }, + { 57596, 61825 }, + { 57597, 61826 }, + { 57598, 61827 }, + { 57599, 61828 }, + { 57600, 61829 }, + { 57601, 61830 }, + { 57602, 61831 }, + { 57603, 61832 }, + { 57604, 61833 }, + { 57605, 61834 }, + { 57606, 61835 }, + { 57607, 61836 }, + { 57608, 61837 }, + { 57609, 61838 }, + { 57610, 61839 }, + { 57611, 61840 }, + { 57612, 61841 }, + { 57613, 61842 }, + { 57614, 61843 }, + { 57615, 61844 }, + { 57616, 61845 }, + { 57617, 61846 }, + { 57618, 61847 }, + { 57619, 61848 }, + { 57620, 61849 }, + { 57621, 61850 }, + { 57622, 61851 }, + { 57623, 61852 }, + { 57624, 61853 }, + { 57625, 61854 }, + { 57626, 61855 }, + { 57627, 61856 }, + { 57628, 61857 }, + { 57629, 61858 }, + { 57630, 61859 }, + { 57631, 61860 }, + { 57632, 61861 }, + { 57633, 61862 }, + { 57634, 61863 }, + { 57635, 61864 }, + { 57636, 61865 }, + { 57637, 61866 }, + { 57638, 61867 }, + { 57639, 61868 }, + { 57640, 61869 }, + { 57641, 61870 }, + { 57642, 61871 }, + { 57643, 61872 }, + { 57644, 61873 }, + { 57645, 61874 }, + { 57646, 61875 }, + { 57647, 61876 }, + { 57648, 61877 }, + { 57649, 61878 }, + { 57650, 61879 }, + { 57651, 61880 }, + { 57652, 61881 }, + { 57653, 61882 }, + { 57654, 61883 }, + { 57655, 61884 }, + { 57656, 61885 }, + { 57657, 61886 }, + { 57658, 61887 }, + { 57659, 61888 }, + { 57660, 61889 }, + { 57661, 61890 }, + { 57662, 61891 }, + { 57663, 61892 }, + { 57664, 61893 }, + { 57665, 61894 }, + { 57666, 61895 }, + { 57667, 61896 }, + { 57668, 61897 }, + { 57669, 61898 }, + { 57670, 61899 }, + { 57671, 61900 }, + { 57672, 61901 }, + { 57673, 61902 }, + { 57674, 61903 }, + { 57675, 61904 }, + { 57676, 61905 }, + { 57677, 61906 }, + { 57678, 61907 }, + { 57679, 61908 }, + { 57680, 61909 }, + { 57681, 61910 }, + { 57682, 61911 }, + { 57683, 61912 }, + { 57684, 61913 }, + { 57685, 61914 }, + { 57686, 61915 }, + { 57687, 61916 }, + { 57688, 61917 }, + { 57689, 61918 }, + { 57690, 61919 }, + { 57691, 61920 }, + { 57692, 61921 }, + { 57693, 61922 }, + { 57694, 61923 }, + { 57695, 61924 }, + { 57696, 61925 }, + { 57697, 61926 }, + { 57698, 61927 }, + { 57699, 61928 }, + { 57700, 61929 }, + { 57701, 61930 }, + { 57702, 61931 }, + { 57703, 61932 }, + { 57704, 61933 }, + { 57705, 61934 }, + { 57706, 61935 }, + { 57707, 61936 }, + { 57708, 61937 }, + { 57709, 61938 }, + { 57710, 61939 }, + { 57711, 61940 }, + { 57712, 61941 }, + { 57713, 61942 }, + { 57714, 61943 }, + { 57715, 61944 }, + { 57716, 61945 }, + { 57717, 61946 }, + { 57718, 61947 }, + { 57719, 61948 }, + { 57720, 62016 }, + { 57721, 62017 }, + { 57722, 62018 }, + { 57723, 62019 }, + { 57724, 62020 }, + { 57725, 62021 }, + { 57726, 62022 }, + { 57727, 62023 }, + { 57728, 62024 }, + { 57729, 62025 }, + { 57730, 62026 }, + { 57731, 62027 }, + { 57732, 62028 }, + { 57733, 62029 }, + { 57734, 62030 }, + { 57735, 62031 }, + { 57736, 62032 }, + { 57737, 62033 }, + { 57738, 62034 }, + { 57739, 62035 }, + { 57740, 62036 }, + { 57741, 62037 }, + { 57742, 62038 }, + { 57743, 62039 }, + { 57744, 62040 }, + { 57745, 62041 }, + { 57746, 62042 }, + { 57747, 62043 }, + { 57748, 62044 }, + { 57749, 62045 }, + { 57750, 62046 }, + { 57751, 62047 }, + { 57752, 62048 }, + { 57753, 62049 }, + { 57754, 62050 }, + { 57755, 62051 }, + { 57756, 62052 }, + { 57757, 62053 }, + { 57758, 62054 }, + { 57759, 62055 }, + { 57760, 62056 }, + { 57761, 62057 }, + { 57762, 62058 }, + { 57763, 62059 }, + { 57764, 62060 }, + { 57765, 62061 }, + { 57766, 62062 }, + { 57767, 62063 }, + { 57768, 62064 }, + { 57769, 62065 }, + { 57770, 62066 }, + { 57771, 62067 }, + { 57772, 62068 }, + { 57773, 62069 }, + { 57774, 62070 }, + { 57775, 62071 }, + { 57776, 62072 }, + { 57777, 62073 }, + { 57778, 62074 }, + { 57779, 62075 }, + { 57780, 62076 }, + { 57781, 62077 }, + { 57782, 62078 }, + { 57783, 62080 }, + { 57784, 62081 }, + { 57785, 62082 }, + { 57786, 62083 }, + { 57787, 62084 }, + { 57788, 62085 }, + { 57789, 62086 }, + { 57790, 62087 }, + { 57791, 62088 }, + { 57792, 62089 }, + { 57793, 62090 }, + { 57794, 62091 }, + { 57795, 62092 }, + { 57796, 62093 }, + { 57797, 62094 }, + { 57798, 62095 }, + { 57799, 62096 }, + { 57800, 62097 }, + { 57801, 62098 }, + { 57802, 62099 }, + { 57803, 62100 }, + { 57804, 62101 }, + { 57805, 62102 }, + { 57806, 62103 }, + { 57807, 62104 }, + { 57808, 62105 }, + { 57809, 62106 }, + { 57810, 62107 }, + { 57811, 62108 }, + { 57812, 62109 }, + { 57813, 62110 }, + { 57814, 62111 }, + { 57815, 62112 }, + { 57816, 62113 }, + { 57817, 62114 }, + { 57818, 62115 }, + { 57819, 62116 }, + { 57820, 62117 }, + { 57821, 62118 }, + { 57822, 62119 }, + { 57823, 62120 }, + { 57824, 62121 }, + { 57825, 62122 }, + { 57826, 62123 }, + { 57827, 62124 }, + { 57828, 62125 }, + { 57829, 62126 }, + { 57830, 62127 }, + { 57831, 62128 }, + { 57832, 62129 }, + { 57833, 62130 }, + { 57834, 62131 }, + { 57835, 62132 }, + { 57836, 62133 }, + { 57837, 62134 }, + { 57838, 62135 }, + { 57839, 62136 }, + { 57840, 62137 }, + { 57841, 62138 }, + { 57842, 62139 }, + { 57843, 62140 }, + { 57844, 62141 }, + { 57845, 62142 }, + { 57846, 62143 }, + { 57847, 62144 }, + { 57848, 62145 }, + { 57849, 62146 }, + { 57850, 62147 }, + { 57851, 62148 }, + { 57852, 62149 }, + { 57853, 62150 }, + { 57854, 62151 }, + { 57855, 62152 }, + { 57856, 62153 }, + { 57857, 62154 }, + { 57858, 62155 }, + { 57859, 62156 }, + { 57860, 62157 }, + { 57861, 62158 }, + { 57862, 62159 }, + { 57863, 62160 }, + { 57864, 62161 }, + { 57865, 62162 }, + { 57866, 62163 }, + { 57867, 62164 }, + { 57868, 62165 }, + { 57869, 62166 }, + { 57870, 62167 }, + { 57871, 62168 }, + { 57872, 62169 }, + { 57873, 62170 }, + { 57874, 62171 }, + { 57875, 62172 }, + { 57876, 62173 }, + { 57877, 62174 }, + { 57878, 62175 }, + { 57879, 62176 }, + { 57880, 62177 }, + { 57881, 62178 }, + { 57882, 62179 }, + { 57883, 62180 }, + { 57884, 62181 }, + { 57885, 62182 }, + { 57886, 62183 }, + { 57887, 62184 }, + { 57888, 62185 }, + { 57889, 62186 }, + { 57890, 62187 }, + { 57891, 62188 }, + { 57892, 62189 }, + { 57893, 62190 }, + { 57894, 62191 }, + { 57895, 62192 }, + { 57896, 62193 }, + { 57897, 62194 }, + { 57898, 62195 }, + { 57899, 62196 }, + { 57900, 62197 }, + { 57901, 62198 }, + { 57902, 62199 }, + { 57903, 62200 }, + { 57904, 62201 }, + { 57905, 62202 }, + { 57906, 62203 }, + { 57907, 62204 }, + { 57908, 62272 }, + { 57909, 62273 }, + { 57910, 62274 }, + { 57911, 62275 }, + { 57912, 62276 }, + { 57913, 62277 }, + { 57914, 62278 }, + { 57915, 62279 }, + { 57916, 62280 }, + { 57917, 62281 }, + { 57918, 62282 }, + { 57919, 62283 }, + { 57920, 62284 }, + { 57921, 62285 }, + { 57922, 62286 }, + { 57923, 62287 }, + { 57924, 62288 }, + { 57925, 62289 }, + { 57926, 62290 }, + { 57927, 62291 }, + { 57928, 62292 }, + { 57929, 62293 }, + { 57930, 62294 }, + { 57931, 62295 }, + { 57932, 62296 }, + { 57933, 62297 }, + { 57934, 62298 }, + { 57935, 62299 }, + { 57936, 62300 }, + { 57937, 62301 }, + { 57938, 62302 }, + { 57939, 62303 }, + { 57940, 62304 }, + { 57941, 62305 }, + { 57942, 62306 }, + { 57943, 62307 }, + { 57944, 62308 }, + { 57945, 62309 }, + { 57946, 62310 }, + { 57947, 62311 }, + { 57948, 62312 }, + { 57949, 62313 }, + { 57950, 62314 }, + { 57951, 62315 }, + { 57952, 62316 }, + { 57953, 62317 }, + { 57954, 62318 }, + { 57955, 62319 }, + { 57956, 62320 }, + { 57957, 62321 }, + { 57958, 62322 }, + { 57959, 62323 }, + { 57960, 62324 }, + { 57961, 62325 }, + { 57962, 62326 }, + { 57963, 62327 }, + { 57964, 62328 }, + { 57965, 62329 }, + { 57966, 62330 }, + { 57967, 62331 }, + { 57968, 62332 }, + { 57969, 62333 }, + { 57970, 62334 }, + { 57971, 62336 }, + { 57972, 62337 }, + { 57973, 62338 }, + { 57974, 62339 }, + { 57975, 62340 }, + { 57976, 62341 }, + { 57977, 62342 }, + { 57978, 62343 }, + { 57979, 62344 }, + { 57980, 62345 }, + { 57981, 62346 }, + { 57982, 62347 }, + { 57983, 62348 }, + { 57984, 62349 }, + { 57985, 62350 }, + { 57986, 62351 }, + { 57987, 62352 }, + { 57988, 62353 }, + { 57989, 62354 }, + { 57990, 62355 }, + { 57991, 62356 }, + { 57992, 62357 }, + { 57993, 62358 }, + { 57994, 62359 }, + { 57995, 62360 }, + { 57996, 62361 }, + { 57997, 62362 }, + { 57998, 62363 }, + { 57999, 62364 }, + { 58000, 62365 }, + { 58001, 62366 }, + { 58002, 62367 }, + { 58003, 62368 }, + { 58004, 62369 }, + { 58005, 62370 }, + { 58006, 62371 }, + { 58007, 62372 }, + { 58008, 62373 }, + { 58009, 62374 }, + { 58010, 62375 }, + { 58011, 62376 }, + { 58012, 62377 }, + { 58013, 62378 }, + { 58014, 62379 }, + { 58015, 62380 }, + { 58016, 62381 }, + { 58017, 62382 }, + { 58018, 62383 }, + { 58019, 62384 }, + { 58020, 62385 }, + { 58021, 62386 }, + { 58022, 62387 }, + { 58023, 62388 }, + { 58024, 62389 }, + { 58025, 62390 }, + { 58026, 62391 }, + { 58027, 62392 }, + { 58028, 62393 }, + { 58029, 62394 }, + { 58030, 62395 }, + { 58031, 62396 }, + { 58032, 62397 }, + { 58033, 62398 }, + { 58034, 62399 }, + { 58035, 62400 }, + { 58036, 62401 }, + { 58037, 62402 }, + { 58038, 62403 }, + { 58039, 62404 }, + { 58040, 62405 }, + { 58041, 62406 }, + { 58042, 62407 }, + { 58043, 62408 }, + { 58044, 62409 }, + { 58045, 62410 }, + { 58046, 62411 }, + { 58047, 62412 }, + { 58048, 62413 }, + { 58049, 62414 }, + { 58050, 62415 }, + { 58051, 62416 }, + { 58052, 62417 }, + { 58053, 62418 }, + { 58054, 62419 }, + { 58055, 62420 }, + { 58056, 62421 }, + { 58057, 62422 }, + { 58058, 62423 }, + { 58059, 62424 }, + { 58060, 62425 }, + { 58061, 62426 }, + { 58062, 62427 }, + { 58063, 62428 }, + { 58064, 62429 }, + { 58065, 62430 }, + { 58066, 62431 }, + { 58067, 62432 }, + { 58068, 62433 }, + { 58069, 62434 }, + { 58070, 62435 }, + { 58071, 62436 }, + { 58072, 62437 }, + { 58073, 62438 }, + { 58074, 62439 }, + { 58075, 62440 }, + { 58076, 62441 }, + { 58077, 62442 }, + { 58078, 62443 }, + { 58079, 62444 }, + { 58080, 62445 }, + { 58081, 62446 }, + { 58082, 62447 }, + { 58083, 62448 }, + { 58084, 62449 }, + { 58085, 62450 }, + { 58086, 62451 }, + { 58087, 62452 }, + { 58088, 62453 }, + { 58089, 62454 }, + { 58090, 62455 }, + { 58091, 62456 }, + { 58092, 62457 }, + { 58093, 62458 }, + { 58094, 62459 }, + { 58095, 62460 }, + { 58096, 62528 }, + { 58097, 62529 }, + { 58098, 62530 }, + { 58099, 62531 }, + { 58100, 62532 }, + { 58101, 62533 }, + { 58102, 62534 }, + { 58103, 62535 }, + { 58104, 62536 }, + { 58105, 62537 }, + { 58106, 62538 }, + { 58107, 62539 }, + { 58108, 62540 }, + { 58109, 62541 }, + { 58110, 62542 }, + { 58111, 62543 }, + { 58112, 62544 }, + { 58113, 62545 }, + { 58114, 62546 }, + { 58115, 62547 }, + { 58116, 62548 }, + { 58117, 62549 }, + { 58118, 62550 }, + { 58119, 62551 }, + { 58120, 62552 }, + { 58121, 62553 }, + { 58122, 62554 }, + { 58123, 62555 }, + { 58124, 62556 }, + { 58125, 62557 }, + { 58126, 62558 }, + { 58127, 62559 }, + { 58128, 62560 }, + { 58129, 62561 }, + { 58130, 62562 }, + { 58131, 62563 }, + { 58132, 62564 }, + { 58133, 62565 }, + { 58134, 62566 }, + { 58135, 62567 }, + { 58136, 62568 }, + { 58137, 62569 }, + { 58138, 62570 }, + { 58139, 62571 }, + { 58140, 62572 }, + { 58141, 62573 }, + { 58142, 62574 }, + { 58143, 62575 }, + { 58144, 62576 }, + { 58145, 62577 }, + { 58146, 62578 }, + { 58147, 62579 }, + { 58148, 62580 }, + { 58149, 62581 }, + { 58150, 62582 }, + { 58151, 62583 }, + { 58152, 62584 }, + { 58153, 62585 }, + { 58154, 62586 }, + { 58155, 62587 }, + { 58156, 62588 }, + { 58157, 62589 }, + { 58158, 62590 }, + { 58159, 62592 }, + { 58160, 62593 }, + { 58161, 62594 }, + { 58162, 62595 }, + { 58163, 62596 }, + { 58164, 62597 }, + { 58165, 62598 }, + { 58166, 62599 }, + { 58167, 62600 }, + { 58168, 62601 }, + { 58169, 62602 }, + { 58170, 62603 }, + { 58171, 62604 }, + { 58172, 62605 }, + { 58173, 62606 }, + { 58174, 62607 }, + { 58175, 62608 }, + { 58176, 62609 }, + { 58177, 62610 }, + { 58178, 62611 }, + { 58179, 62612 }, + { 58180, 62613 }, + { 58181, 62614 }, + { 58182, 62615 }, + { 58183, 62616 }, + { 58184, 62617 }, + { 58185, 62618 }, + { 58186, 62619 }, + { 58187, 62620 }, + { 58188, 62621 }, + { 58189, 62622 }, + { 58190, 62623 }, + { 58191, 62624 }, + { 58192, 62625 }, + { 58193, 62626 }, + { 58194, 62627 }, + { 58195, 62628 }, + { 58196, 62629 }, + { 58197, 62630 }, + { 58198, 62631 }, + { 58199, 62632 }, + { 58200, 62633 }, + { 58201, 62634 }, + { 58202, 62635 }, + { 58203, 62636 }, + { 58204, 62637 }, + { 58205, 62638 }, + { 58206, 62639 }, + { 58207, 62640 }, + { 58208, 62641 }, + { 58209, 62642 }, + { 58210, 62643 }, + { 58211, 62644 }, + { 58212, 62645 }, + { 58213, 62646 }, + { 58214, 62647 }, + { 58215, 62648 }, + { 58216, 62649 }, + { 58217, 62650 }, + { 58218, 62651 }, + { 58219, 62652 }, + { 58220, 62653 }, + { 58221, 62654 }, + { 58222, 62655 }, + { 58223, 62656 }, + { 58224, 62657 }, + { 58225, 62658 }, + { 58226, 62659 }, + { 58227, 62660 }, + { 58228, 62661 }, + { 58229, 62662 }, + { 58230, 62663 }, + { 58231, 62664 }, + { 58232, 62665 }, + { 58233, 62666 }, + { 58234, 62667 }, + { 58235, 62668 }, + { 58236, 62669 }, + { 58237, 62670 }, + { 58238, 62671 }, + { 58239, 62672 }, + { 58240, 62673 }, + { 58241, 62674 }, + { 58242, 62675 }, + { 58243, 62676 }, + { 58244, 62677 }, + { 58245, 62678 }, + { 58246, 62679 }, + { 58247, 62680 }, + { 58248, 62681 }, + { 58249, 62682 }, + { 58250, 62683 }, + { 58251, 62684 }, + { 58252, 62685 }, + { 58253, 62686 }, + { 58254, 62687 }, + { 58255, 62688 }, + { 58256, 62689 }, + { 58257, 62690 }, + { 58258, 62691 }, + { 58259, 62692 }, + { 58260, 62693 }, + { 58261, 62694 }, + { 58262, 62695 }, + { 58263, 62696 }, + { 58264, 62697 }, + { 58265, 62698 }, + { 58266, 62699 }, + { 58267, 62700 }, + { 58268, 62701 }, + { 58269, 62702 }, + { 58270, 62703 }, + { 58271, 62704 }, + { 58272, 62705 }, + { 58273, 62706 }, + { 58274, 62707 }, + { 58275, 62708 }, + { 58276, 62709 }, + { 58277, 62710 }, + { 58278, 62711 }, + { 58279, 62712 }, + { 58280, 62713 }, + { 58281, 62714 }, + { 58282, 62715 }, + { 58283, 62716 }, + { 58284, 62784 }, + { 58285, 62785 }, + { 58286, 62786 }, + { 58287, 62787 }, + { 58288, 62788 }, + { 58289, 62789 }, + { 58290, 62790 }, + { 58291, 62791 }, + { 58292, 62792 }, + { 58293, 62793 }, + { 58294, 62794 }, + { 58295, 62795 }, + { 58296, 62796 }, + { 58297, 62797 }, + { 58298, 62798 }, + { 58299, 62799 }, + { 58300, 62800 }, + { 58301, 62801 }, + { 58302, 62802 }, + { 58303, 62803 }, + { 58304, 62804 }, + { 58305, 62805 }, + { 58306, 62806 }, + { 58307, 62807 }, + { 58308, 62808 }, + { 58309, 62809 }, + { 58310, 62810 }, + { 58311, 62811 }, + { 58312, 62812 }, + { 58313, 62813 }, + { 58314, 62814 }, + { 58315, 62815 }, + { 58316, 62816 }, + { 58317, 62817 }, + { 58318, 62818 }, + { 58319, 62819 }, + { 58320, 62820 }, + { 58321, 62821 }, + { 58322, 62822 }, + { 58323, 62823 }, + { 58324, 62824 }, + { 58325, 62825 }, + { 58326, 62826 }, + { 58327, 62827 }, + { 58328, 62828 }, + { 58329, 62829 }, + { 58330, 62830 }, + { 58331, 62831 }, + { 58332, 62832 }, + { 58333, 62833 }, + { 58334, 62834 }, + { 58335, 62835 }, + { 58336, 62836 }, + { 58337, 62837 }, + { 58338, 62838 }, + { 58339, 62839 }, + { 58340, 62840 }, + { 58341, 62841 }, + { 58342, 62842 }, + { 58343, 62843 }, + { 58344, 62844 }, + { 58345, 62845 }, + { 58346, 62846 }, + { 58347, 62848 }, + { 58348, 62849 }, + { 58349, 62850 }, + { 58350, 62851 }, + { 58351, 62852 }, + { 58352, 62853 }, + { 58353, 62854 }, + { 58354, 62855 }, + { 58355, 62856 }, + { 58356, 62857 }, + { 58357, 62858 }, + { 58358, 62859 }, + { 58359, 62860 }, + { 58360, 62861 }, + { 58361, 62862 }, + { 58362, 62863 }, + { 58363, 62864 }, + { 58364, 62865 }, + { 58365, 62866 }, + { 58366, 62867 }, + { 58367, 62868 }, + { 58368, 62869 }, + { 58369, 62870 }, + { 58370, 62871 }, + { 58371, 62872 }, + { 58372, 62873 }, + { 58373, 62874 }, + { 58374, 62875 }, + { 58375, 62876 }, + { 58376, 62877 }, + { 58377, 62878 }, + { 58378, 62879 }, + { 58379, 62880 }, + { 58380, 62881 }, + { 58381, 62882 }, + { 58382, 62883 }, + { 58383, 62884 }, + { 58384, 62885 }, + { 58385, 62886 }, + { 58386, 62887 }, + { 58387, 62888 }, + { 58388, 62889 }, + { 58389, 62890 }, + { 58390, 62891 }, + { 58391, 62892 }, + { 58392, 62893 }, + { 58393, 62894 }, + { 58394, 62895 }, + { 58395, 62896 }, + { 58396, 62897 }, + { 58397, 62898 }, + { 58398, 62899 }, + { 58399, 62900 }, + { 58400, 62901 }, + { 58401, 62902 }, + { 58402, 62903 }, + { 58403, 62904 }, + { 58404, 62905 }, + { 58405, 62906 }, + { 58406, 62907 }, + { 58407, 62908 }, + { 58408, 62909 }, + { 58409, 62910 }, + { 58410, 62911 }, + { 58411, 62912 }, + { 58412, 62913 }, + { 58413, 62914 }, + { 58414, 62915 }, + { 58415, 62916 }, + { 58416, 62917 }, + { 58417, 62918 }, + { 58418, 62919 }, + { 58419, 62920 }, + { 58420, 62921 }, + { 58421, 62922 }, + { 58422, 62923 }, + { 58423, 62924 }, + { 58424, 62925 }, + { 58425, 62926 }, + { 58426, 62927 }, + { 58427, 62928 }, + { 58428, 62929 }, + { 58429, 62930 }, + { 58430, 62931 }, + { 58431, 62932 }, + { 58432, 62933 }, + { 58433, 62934 }, + { 58434, 62935 }, + { 58435, 62936 }, + { 58436, 62937 }, + { 58437, 62938 }, + { 58438, 62939 }, + { 58439, 62940 }, + { 58440, 62941 }, + { 58441, 62942 }, + { 58442, 62943 }, + { 58443, 62944 }, + { 58444, 62945 }, + { 58445, 62946 }, + { 58446, 62947 }, + { 58447, 62948 }, + { 58448, 62949 }, + { 58449, 62950 }, + { 58450, 62951 }, + { 58451, 62952 }, + { 58452, 62953 }, + { 58453, 62954 }, + { 58454, 62955 }, + { 58455, 62956 }, + { 58456, 62957 }, + { 58457, 62958 }, + { 58458, 62959 }, + { 58459, 62960 }, + { 58460, 62961 }, + { 58461, 62962 }, + { 58462, 62963 }, + { 58463, 62964 }, + { 58464, 62965 }, + { 58465, 62966 }, + { 58466, 62967 }, + { 58467, 62968 }, + { 58468, 62969 }, + { 58469, 62970 }, + { 58470, 62971 }, + { 58471, 62972 }, + { 58472, 63040 }, + { 58473, 63041 }, + { 58474, 63042 }, + { 58475, 63043 }, + { 58476, 63044 }, + { 58477, 63045 }, + { 58478, 63046 }, + { 58479, 63047 }, + { 58480, 63048 }, + { 58481, 63049 }, + { 58482, 63050 }, + { 58483, 63051 }, + { 58484, 63052 }, + { 58485, 63053 }, + { 58486, 63054 }, + { 58487, 63055 }, + { 58488, 63056 }, + { 58489, 63057 }, + { 58490, 63058 }, + { 58491, 63059 }, + { 58492, 63060 }, + { 58493, 63061 }, + { 58494, 63062 }, + { 58495, 63063 }, + { 58496, 63064 }, + { 58497, 63065 }, + { 58498, 63066 }, + { 58499, 63067 }, + { 58500, 63068 }, + { 58501, 63069 }, + { 58502, 63070 }, + { 58503, 63071 }, + { 58504, 63072 }, + { 58505, 63073 }, + { 58506, 63074 }, + { 58507, 63075 }, + { 58508, 63076 }, + { 58509, 63077 }, + { 58510, 63078 }, + { 58511, 63079 }, + { 58512, 63080 }, + { 58513, 63081 }, + { 58514, 63082 }, + { 58515, 63083 }, + { 58516, 63084 }, + { 58517, 63085 }, + { 58518, 63086 }, + { 58519, 63087 }, + { 58520, 63088 }, + { 58521, 63089 }, + { 58522, 63090 }, + { 58523, 63091 }, + { 58524, 63092 }, + { 58525, 63093 }, + { 58526, 63094 }, + { 58527, 63095 }, + { 58528, 63096 }, + { 58529, 63097 }, + { 58530, 63098 }, + { 58531, 63099 }, + { 58532, 63100 }, + { 58533, 63101 }, + { 58534, 63102 }, + { 58535, 63104 }, + { 58536, 63105 }, + { 58537, 63106 }, + { 58538, 63107 }, + { 58539, 63108 }, + { 58540, 63109 }, + { 58541, 63110 }, + { 58542, 63111 }, + { 58543, 63112 }, + { 58544, 63113 }, + { 58545, 63114 }, + { 58546, 63115 }, + { 58547, 63116 }, + { 58548, 63117 }, + { 58549, 63118 }, + { 58550, 63119 }, + { 58551, 63120 }, + { 58552, 63121 }, + { 58553, 63122 }, + { 58554, 63123 }, + { 58555, 63124 }, + { 58556, 63125 }, + { 58557, 63126 }, + { 58558, 63127 }, + { 58559, 63128 }, + { 58560, 63129 }, + { 58561, 63130 }, + { 58562, 63131 }, + { 58563, 63132 }, + { 58564, 63133 }, + { 58565, 63134 }, + { 58566, 63135 }, + { 58567, 63136 }, + { 58568, 63137 }, + { 58569, 63138 }, + { 58570, 63139 }, + { 58571, 63140 }, + { 58572, 63141 }, + { 58573, 63142 }, + { 58574, 63143 }, + { 58575, 63144 }, + { 58576, 63145 }, + { 58577, 63146 }, + { 58578, 63147 }, + { 58579, 63148 }, + { 58580, 63149 }, + { 58581, 63150 }, + { 58582, 63151 }, + { 58583, 63152 }, + { 58584, 63153 }, + { 58585, 63154 }, + { 58586, 63155 }, + { 58587, 63156 }, + { 58588, 63157 }, + { 58589, 63158 }, + { 58590, 63159 }, + { 58591, 63160 }, + { 58592, 63161 }, + { 58593, 63162 }, + { 58594, 63163 }, + { 58595, 63164 }, + { 58596, 63165 }, + { 58597, 63166 }, + { 58598, 63167 }, + { 58599, 63168 }, + { 58600, 63169 }, + { 58601, 63170 }, + { 58602, 63171 }, + { 58603, 63172 }, + { 58604, 63173 }, + { 58605, 63174 }, + { 58606, 63175 }, + { 58607, 63176 }, + { 58608, 63177 }, + { 58609, 63178 }, + { 58610, 63179 }, + { 58611, 63180 }, + { 58612, 63181 }, + { 58613, 63182 }, + { 58614, 63183 }, + { 58615, 63184 }, + { 58616, 63185 }, + { 58617, 63186 }, + { 58618, 63187 }, + { 58619, 63188 }, + { 58620, 63189 }, + { 58621, 63190 }, + { 58622, 63191 }, + { 58623, 63192 }, + { 58624, 63193 }, + { 58625, 63194 }, + { 58626, 63195 }, + { 58627, 63196 }, + { 58628, 63197 }, + { 58629, 63198 }, + { 58630, 63199 }, + { 58631, 63200 }, + { 58632, 63201 }, + { 58633, 63202 }, + { 58634, 63203 }, + { 58635, 63204 }, + { 58636, 63205 }, + { 58637, 63206 }, + { 58638, 63207 }, + { 58639, 63208 }, + { 58640, 63209 }, + { 58641, 63210 }, + { 58642, 63211 }, + { 58643, 63212 }, + { 58644, 63213 }, + { 58645, 63214 }, + { 58646, 63215 }, + { 58647, 63216 }, + { 58648, 63217 }, + { 58649, 63218 }, + { 58650, 63219 }, + { 58651, 63220 }, + { 58652, 63221 }, + { 58653, 63222 }, + { 58654, 63223 }, + { 58655, 63224 }, + { 58656, 63225 }, + { 58657, 63226 }, + { 58658, 63227 }, + { 58659, 63228 }, + { 58660, 63296 }, + { 58661, 63297 }, + { 58662, 63298 }, + { 58663, 63299 }, + { 58664, 63300 }, + { 58665, 63301 }, + { 58666, 63302 }, + { 58667, 63303 }, + { 58668, 63304 }, + { 58669, 63305 }, + { 58670, 63306 }, + { 58671, 63307 }, + { 58672, 63308 }, + { 58673, 63309 }, + { 58674, 63310 }, + { 58675, 63311 }, + { 58676, 63312 }, + { 58677, 63313 }, + { 58678, 63314 }, + { 58679, 63315 }, + { 58680, 63316 }, + { 58681, 63317 }, + { 58682, 63318 }, + { 58683, 63319 }, + { 58684, 63320 }, + { 58685, 63321 }, + { 58686, 63322 }, + { 58687, 63323 }, + { 58688, 63324 }, + { 58689, 63325 }, + { 58690, 63326 }, + { 58691, 63327 }, + { 58692, 63328 }, + { 58693, 63329 }, + { 58694, 63330 }, + { 58695, 63331 }, + { 58696, 63332 }, + { 58697, 63333 }, + { 58698, 63334 }, + { 58699, 63335 }, + { 58700, 63336 }, + { 58701, 63337 }, + { 58702, 63338 }, + { 58703, 63339 }, + { 58704, 63340 }, + { 58705, 63341 }, + { 58706, 63342 }, + { 58707, 63343 }, + { 58708, 63344 }, + { 58709, 63345 }, + { 58710, 63346 }, + { 58711, 63347 }, + { 58712, 63348 }, + { 58713, 63349 }, + { 58714, 63350 }, + { 58715, 63351 }, + { 58716, 63352 }, + { 58717, 63353 }, + { 58718, 63354 }, + { 58719, 63355 }, + { 58720, 63356 }, + { 58721, 63357 }, + { 58722, 63358 }, + { 58723, 63360 }, + { 58724, 63361 }, + { 58725, 63362 }, + { 58726, 63363 }, + { 58727, 63364 }, + { 58728, 63365 }, + { 58729, 63366 }, + { 58730, 63367 }, + { 58731, 63368 }, + { 58732, 63369 }, + { 58733, 63370 }, + { 58734, 63371 }, + { 58735, 63372 }, + { 58736, 63373 }, + { 58737, 63374 }, + { 58738, 63375 }, + { 58739, 63376 }, + { 58740, 63377 }, + { 58741, 63378 }, + { 58742, 63379 }, + { 58743, 63380 }, + { 58744, 63381 }, + { 58745, 63382 }, + { 58746, 63383 }, + { 58747, 63384 }, + { 58748, 63385 }, + { 58749, 63386 }, + { 58750, 63387 }, + { 58751, 63388 }, + { 58752, 63389 }, + { 58753, 63390 }, + { 58754, 63391 }, + { 58755, 63392 }, + { 58756, 63393 }, + { 58757, 63394 }, + { 58758, 63395 }, + { 58759, 63396 }, + { 58760, 63397 }, + { 58761, 63398 }, + { 58762, 63399 }, + { 58763, 63400 }, + { 58764, 63401 }, + { 58765, 63402 }, + { 58766, 63403 }, + { 58767, 63404 }, + { 58768, 63405 }, + { 58769, 63406 }, + { 58770, 63407 }, + { 58771, 63408 }, + { 58772, 63409 }, + { 58773, 63410 }, + { 58774, 63411 }, + { 58775, 63412 }, + { 58776, 63413 }, + { 58777, 63414 }, + { 58778, 63415 }, + { 58779, 63416 }, + { 58780, 63417 }, + { 58781, 63418 }, + { 58782, 63419 }, + { 58783, 63420 }, + { 58784, 63421 }, + { 58785, 63422 }, + { 58786, 63423 }, + { 58787, 63424 }, + { 58788, 63425 }, + { 58789, 63426 }, + { 58790, 63427 }, + { 58791, 63428 }, + { 58792, 63429 }, + { 58793, 63430 }, + { 58794, 63431 }, + { 58795, 63432 }, + { 58796, 63433 }, + { 58797, 63434 }, + { 58798, 63435 }, + { 58799, 63436 }, + { 58800, 63437 }, + { 58801, 63438 }, + { 58802, 63439 }, + { 58803, 63440 }, + { 58804, 63441 }, + { 58805, 63442 }, + { 58806, 63443 }, + { 58807, 63444 }, + { 58808, 63445 }, + { 58809, 63446 }, + { 58810, 63447 }, + { 58811, 63448 }, + { 58812, 63449 }, + { 58813, 63450 }, + { 58814, 63451 }, + { 58815, 63452 }, + { 58816, 63453 }, + { 58817, 63454 }, + { 58818, 63455 }, + { 58819, 63456 }, + { 58820, 63457 }, + { 58821, 63458 }, + { 58822, 63459 }, + { 58823, 63460 }, + { 58824, 63461 }, + { 58825, 63462 }, + { 58826, 63463 }, + { 58827, 63464 }, + { 58828, 63465 }, + { 58829, 63466 }, + { 58830, 63467 }, + { 58831, 63468 }, + { 58832, 63469 }, + { 58833, 63470 }, + { 58834, 63471 }, + { 58835, 63472 }, + { 58836, 63473 }, + { 58837, 63474 }, + { 58838, 63475 }, + { 58839, 63476 }, + { 58840, 63477 }, + { 58841, 63478 }, + { 58842, 63479 }, + { 58843, 63480 }, + { 58844, 63481 }, + { 58845, 63482 }, + { 58846, 63483 }, + { 58847, 63484 }, + { 58848, 63552 }, + { 58849, 63553 }, + { 58850, 63554 }, + { 58851, 63555 }, + { 58852, 63556 }, + { 58853, 63557 }, + { 58854, 63558 }, + { 58855, 63559 }, + { 58856, 63560 }, + { 58857, 63561 }, + { 58858, 63562 }, + { 58859, 63563 }, + { 58860, 63564 }, + { 58861, 63565 }, + { 58862, 63566 }, + { 58863, 63567 }, + { 58864, 63568 }, + { 58865, 63569 }, + { 58866, 63570 }, + { 58867, 63571 }, + { 58868, 63572 }, + { 58869, 63573 }, + { 58870, 63574 }, + { 58871, 63575 }, + { 58872, 63576 }, + { 58873, 63577 }, + { 58874, 63578 }, + { 58875, 63579 }, + { 58876, 63580 }, + { 58877, 63581 }, + { 58878, 63582 }, + { 58879, 63583 }, + { 58880, 63584 }, + { 58881, 63585 }, + { 58882, 63586 }, + { 58883, 63587 }, + { 58884, 63588 }, + { 58885, 63589 }, + { 58886, 63590 }, + { 58887, 63591 }, + { 58888, 63592 }, + { 58889, 63593 }, + { 58890, 63594 }, + { 58891, 63595 }, + { 58892, 63596 }, + { 58893, 63597 }, + { 58894, 63598 }, + { 58895, 63599 }, + { 58896, 63600 }, + { 58897, 63601 }, + { 58898, 63602 }, + { 58899, 63603 }, + { 58900, 63604 }, + { 58901, 63605 }, + { 58902, 63606 }, + { 58903, 63607 }, + { 58904, 63608 }, + { 58905, 63609 }, + { 58906, 63610 }, + { 58907, 63611 }, + { 58908, 63612 }, + { 58909, 63613 }, + { 58910, 63614 }, + { 58911, 63616 }, + { 58912, 63617 }, + { 58913, 63618 }, + { 58914, 63619 }, + { 58915, 63620 }, + { 58916, 63621 }, + { 58917, 63622 }, + { 58918, 63623 }, + { 58919, 63624 }, + { 58920, 63625 }, + { 58921, 63626 }, + { 58922, 63627 }, + { 58923, 63628 }, + { 58924, 63629 }, + { 58925, 63630 }, + { 58926, 63631 }, + { 58927, 63632 }, + { 58928, 63633 }, + { 58929, 63634 }, + { 58930, 63635 }, + { 58931, 63636 }, + { 58932, 63637 }, + { 58933, 63638 }, + { 58934, 63639 }, + { 58935, 63640 }, + { 58936, 63641 }, + { 58937, 63642 }, + { 58938, 63643 }, + { 58939, 63644 }, + { 58940, 63645 }, + { 58941, 63646 }, + { 58942, 63647 }, + { 58943, 63648 }, + { 58944, 63649 }, + { 58945, 63650 }, + { 58946, 63651 }, + { 58947, 63652 }, + { 58948, 63653 }, + { 58949, 63654 }, + { 58950, 63655 }, + { 58951, 63656 }, + { 58952, 63657 }, + { 58953, 63658 }, + { 58954, 63659 }, + { 58955, 63660 }, + { 58956, 63661 }, + { 58957, 63662 }, + { 58958, 63663 }, + { 58959, 63664 }, + { 58960, 63665 }, + { 58961, 63666 }, + { 58962, 63667 }, + { 58963, 63668 }, + { 58964, 63669 }, + { 58965, 63670 }, + { 58966, 63671 }, + { 58967, 63672 }, + { 58968, 63673 }, + { 58969, 63674 }, + { 58970, 63675 }, + { 58971, 63676 }, + { 58972, 63677 }, + { 58973, 63678 }, + { 58974, 63679 }, + { 58975, 63680 }, + { 58976, 63681 }, + { 58977, 63682 }, + { 58978, 63683 }, + { 58979, 63684 }, + { 58980, 63685 }, + { 58981, 63686 }, + { 58982, 63687 }, + { 58983, 63688 }, + { 58984, 63689 }, + { 58985, 63690 }, + { 58986, 63691 }, + { 58987, 63692 }, + { 58988, 63693 }, + { 58989, 63694 }, + { 58990, 63695 }, + { 58991, 63696 }, + { 58992, 63697 }, + { 58993, 63698 }, + { 58994, 63699 }, + { 58995, 63700 }, + { 58996, 63701 }, + { 58997, 63702 }, + { 58998, 63703 }, + { 58999, 63704 }, + { 59000, 63705 }, + { 59001, 63706 }, + { 59002, 63707 }, + { 59003, 63708 }, + { 59004, 63709 }, + { 59005, 63710 }, + { 59006, 63711 }, + { 59007, 63712 }, + { 59008, 63713 }, + { 59009, 63714 }, + { 59010, 63715 }, + { 59011, 63716 }, + { 59012, 63717 }, + { 59013, 63718 }, + { 59014, 63719 }, + { 59015, 63720 }, + { 59016, 63721 }, + { 59017, 63722 }, + { 59018, 63723 }, + { 59019, 63724 }, + { 59020, 63725 }, + { 59021, 63726 }, + { 59022, 63727 }, + { 59023, 63728 }, + { 59024, 63729 }, + { 59025, 63730 }, + { 59026, 63731 }, + { 59027, 63732 }, + { 59028, 63733 }, + { 59029, 63734 }, + { 59030, 63735 }, + { 59031, 63736 }, + { 59032, 63737 }, + { 59033, 63738 }, + { 59034, 63739 }, + { 59035, 63740 }, + { 59036, 63808 }, + { 59037, 63809 }, + { 59038, 63810 }, + { 59039, 63811 }, + { 59040, 63812 }, + { 59041, 63813 }, + { 59042, 63814 }, + { 59043, 63815 }, + { 59044, 63816 }, + { 59045, 63817 }, + { 59046, 63818 }, + { 59047, 63819 }, + { 59048, 63820 }, + { 59049, 63821 }, + { 59050, 63822 }, + { 59051, 63823 }, + { 59052, 63824 }, + { 59053, 63825 }, + { 59054, 63826 }, + { 59055, 63827 }, + { 59056, 63828 }, + { 59057, 63829 }, + { 59058, 63830 }, + { 59059, 63831 }, + { 59060, 63832 }, + { 59061, 63833 }, + { 59062, 63834 }, + { 59063, 63835 }, + { 59064, 63836 }, + { 59065, 63837 }, + { 59066, 63838 }, + { 59067, 63839 }, + { 59068, 63840 }, + { 59069, 63841 }, + { 59070, 63842 }, + { 59071, 63843 }, + { 59072, 63844 }, + { 59073, 63845 }, + { 59074, 63846 }, + { 59075, 63847 }, + { 59076, 63848 }, + { 59077, 63849 }, + { 59078, 63850 }, + { 59079, 63851 }, + { 59080, 63852 }, + { 59081, 63853 }, + { 59082, 63854 }, + { 59083, 63855 }, + { 59084, 63856 }, + { 59085, 63857 }, + { 59086, 63858 }, + { 59087, 63859 }, + { 59088, 63860 }, + { 59089, 63861 }, + { 59090, 63862 }, + { 59091, 63863 }, + { 59092, 63864 }, + { 59093, 63865 }, + { 59094, 63866 }, + { 59095, 63867 }, + { 59096, 63868 }, + { 59097, 63869 }, + { 59098, 63870 }, + { 59099, 63872 }, + { 59100, 63873 }, + { 59101, 63874 }, + { 59102, 63875 }, + { 59103, 63876 }, + { 59104, 63877 }, + { 59105, 63878 }, + { 59106, 63879 }, + { 59107, 63880 }, + { 59108, 63881 }, + { 59109, 63882 }, + { 59110, 63883 }, + { 59111, 63884 }, + { 59112, 63885 }, + { 59113, 63886 }, + { 59114, 63887 }, + { 59115, 63888 }, + { 59116, 63889 }, + { 59117, 63890 }, + { 59118, 63891 }, + { 59119, 63892 }, + { 59120, 63893 }, + { 59121, 63894 }, + { 59122, 63895 }, + { 59123, 63896 }, + { 59124, 63897 }, + { 59125, 63898 }, + { 59126, 63899 }, + { 59127, 63900 }, + { 59128, 63901 }, + { 59129, 63902 }, + { 59130, 63903 }, + { 59131, 63904 }, + { 59132, 63905 }, + { 59133, 63906 }, + { 59134, 63907 }, + { 59135, 63908 }, + { 59136, 63909 }, + { 59137, 63910 }, + { 59138, 63911 }, + { 59139, 63912 }, + { 59140, 63913 }, + { 59141, 63914 }, + { 59142, 63915 }, + { 59143, 63916 }, + { 59144, 63917 }, + { 59145, 63918 }, + { 59146, 63919 }, + { 59147, 63920 }, + { 59148, 63921 }, + { 59149, 63922 }, + { 59150, 63923 }, + { 59151, 63924 }, + { 59152, 63925 }, + { 59153, 63926 }, + { 59154, 63927 }, + { 59155, 63928 }, + { 59156, 63929 }, + { 59157, 63930 }, + { 59158, 63931 }, + { 59159, 63932 }, + { 59160, 63933 }, + { 59161, 63934 }, + { 59162, 63935 }, + { 59163, 63936 }, + { 59164, 63937 }, + { 59165, 63938 }, + { 59166, 63939 }, + { 59167, 63940 }, + { 59168, 63941 }, + { 59169, 63942 }, + { 59170, 63943 }, + { 59171, 63944 }, + { 59172, 63945 }, + { 59173, 63946 }, + { 59174, 63947 }, + { 59175, 63948 }, + { 59176, 63949 }, + { 59177, 63950 }, + { 59178, 63951 }, + { 59179, 63952 }, + { 59180, 63953 }, + { 59181, 63954 }, + { 59182, 63955 }, + { 59183, 63956 }, + { 59184, 63957 }, + { 59185, 63958 }, + { 59186, 63959 }, + { 59187, 63960 }, + { 59188, 63961 }, + { 59189, 63962 }, + { 59190, 63963 }, + { 59191, 63964 }, + { 59192, 63965 }, + { 59193, 63966 }, + { 59194, 63967 }, + { 59195, 63968 }, + { 59196, 63969 }, + { 59197, 63970 }, + { 59198, 63971 }, + { 59199, 63972 }, + { 59200, 63973 }, + { 59201, 63974 }, + { 59202, 63975 }, + { 59203, 63976 }, + { 59204, 63977 }, + { 59205, 63978 }, + { 59206, 63979 }, + { 59207, 63980 }, + { 59208, 63981 }, + { 59209, 63982 }, + { 59210, 63983 }, + { 59211, 63984 }, + { 59212, 63985 }, + { 59213, 63986 }, + { 59214, 63987 }, + { 59215, 63988 }, + { 59216, 63989 }, + { 59217, 63990 }, + { 59218, 63991 }, + { 59219, 63992 }, + { 59220, 63993 }, + { 59221, 63994 }, + { 59222, 63995 }, + { 59223, 63996 }, + { 63728, 160 }, + { 63729, 253 }, + { 63730, 254 }, + { 63731, 255 }, + { 63785, 64224 }, + { 63964, 64489 }, + { 64014, 64144 }, + { 64015, 64155 }, + { 64016, 64156 }, + { 64017, 64177 }, + { 64018, 64216 }, + { 64019, 64232 }, + { 64020, 64234 }, + { 64021, 64344 }, + { 64022, 64350 }, + { 64023, 64373 }, + { 64024, 64381 }, + { 64025, 64382 }, + { 64026, 64384 }, + { 64027, 64386 }, + { 64028, 64390 }, + { 64029, 64393 }, + { 64030, 64402 }, + { 64031, 64413 }, + { 64032, 64415 }, + { 64033, 64416 }, + { 64034, 64425 }, + { 64035, 64433 }, + { 64036, 64435 }, + { 64037, 64436 }, + { 64038, 64439 }, + { 64039, 64467 }, + { 64040, 64474 }, + { 64041, 64490 }, + { 64042, 64502 }, + { 64043, 64503 }, + { 64044, 64505 }, + { 64045, 64585 }, + { 65281, 33097 }, + { 65282, 64087 }, + { 65283, 33172 }, + { 65284, 33168 }, + { 65285, 33171 }, + { 65286, 33173 }, + { 65287, 64086 }, + { 65288, 33129 }, + { 65289, 33130 }, + { 65290, 33174 }, + { 65291, 33147 }, + { 65292, 33091 }, + { 65293, 33148 }, + { 65294, 33092 }, + { 65295, 33118 }, + { 65296, 33359 }, + { 65297, 33360 }, + { 65298, 33361 }, + { 65299, 33362 }, + { 65300, 33363 }, + { 65301, 33364 }, + { 65302, 33365 }, + { 65303, 33366 }, + { 65304, 33367 }, + { 65305, 33368 }, + { 65306, 33094 }, + { 65307, 33095 }, + { 65308, 33155 }, + { 65309, 33153 }, + { 65310, 33156 }, + { 65311, 33096 }, + { 65312, 33175 }, + { 65313, 33376 }, + { 65314, 33377 }, + { 65315, 33378 }, + { 65316, 33379 }, + { 65317, 33380 }, + { 65318, 33381 }, + { 65319, 33382 }, + { 65320, 33383 }, + { 65321, 33384 }, + { 65322, 33385 }, + { 65323, 33386 }, + { 65324, 33387 }, + { 65325, 33388 }, + { 65326, 33389 }, + { 65327, 33390 }, + { 65328, 33391 }, + { 65329, 33392 }, + { 65330, 33393 }, + { 65331, 33394 }, + { 65332, 33395 }, + { 65333, 33396 }, + { 65334, 33397 }, + { 65335, 33398 }, + { 65336, 33399 }, + { 65337, 33400 }, + { 65338, 33401 }, + { 65339, 33133 }, + { 65340, 33119 }, + { 65341, 33134 }, + { 65342, 33103 }, + { 65343, 33105 }, + { 65344, 33101 }, + { 65345, 33409 }, + { 65346, 33410 }, + { 65347, 33411 }, + { 65348, 33412 }, + { 65349, 33413 }, + { 65350, 33414 }, + { 65351, 33415 }, + { 65352, 33416 }, + { 65353, 33417 }, + { 65354, 33418 }, + { 65355, 33419 }, + { 65356, 33420 }, + { 65357, 33421 }, + { 65358, 33422 }, + { 65359, 33423 }, + { 65360, 33424 }, + { 65361, 33425 }, + { 65362, 33426 }, + { 65363, 33427 }, + { 65364, 33428 }, + { 65365, 33429 }, + { 65366, 33430 }, + { 65367, 33431 }, + { 65368, 33432 }, + { 65369, 33433 }, + { 65370, 33434 }, + { 65371, 33135 }, + { 65372, 33122 }, + { 65373, 33136 }, + { 65374, 33120 }, + { 65377, 161 }, + { 65378, 162 }, + { 65379, 163 }, + { 65380, 164 }, + { 65381, 165 }, + { 65382, 166 }, + { 65383, 167 }, + { 65384, 168 }, + { 65385, 169 }, + { 65386, 170 }, + { 65387, 171 }, + { 65388, 172 }, + { 65389, 173 }, + { 65390, 174 }, + { 65391, 175 }, + { 65392, 176 }, + { 65393, 177 }, + { 65394, 178 }, + { 65395, 179 }, + { 65396, 180 }, + { 65397, 181 }, + { 65398, 182 }, + { 65399, 183 }, + { 65400, 184 }, + { 65401, 185 }, + { 65402, 186 }, + { 65403, 187 }, + { 65404, 188 }, + { 65405, 189 }, + { 65406, 190 }, + { 65407, 191 }, + { 65408, 192 }, + { 65409, 193 }, + { 65410, 194 }, + { 65411, 195 }, + { 65412, 196 }, + { 65413, 197 }, + { 65414, 198 }, + { 65415, 199 }, + { 65416, 200 }, + { 65417, 201 }, + { 65418, 202 }, + { 65419, 203 }, + { 65420, 204 }, + { 65421, 205 }, + { 65422, 206 }, + { 65423, 207 }, + { 65424, 208 }, + { 65425, 209 }, + { 65426, 210 }, + { 65427, 211 }, + { 65428, 212 }, + { 65429, 213 }, + { 65430, 214 }, + { 65431, 215 }, + { 65432, 216 }, + { 65433, 217 }, + { 65434, 218 }, + { 65435, 219 }, + { 65436, 220 }, + { 65437, 221 }, + { 65438, 222 }, + { 65439, 223 }, + { 65504, 33169 }, + { 65505, 33170 }, + { 65506, 33226 }, + { 65507, 33104 }, + { 65508, 64085 }, + { 65509, 33167 } + }; +#if __cplusplus + for( int i = 0; i < _LEN_DICT; i++ ){ + _DICT_SRC[i][0] = n[i][0]; + _DICT_SRC[i][1] = n[i][1]; + } + } +#endif + +#if __cplusplus + static bool m_initialized; + static std::map _DICT; +#else + static bool m_initialized = false; + static bool m_cp932_available = false; + static Encoding m_cp932 = null; +#endif + + static void init() { +#if __cplusplus + init_cor(); + for( int i = 0; i < _LEN_DICT; i++ ){ + _DICT.insert( map::value_type( _DICT_SRC[i][0], _DICT_SRC[i][1] ) ); + } +#else + try { + m_cp932 = Encoding.GetEncoding( 932 ); + m_cp932_available = true; + } catch { + m_cp932_available = false; + } +#endif +#if DEBUG + m_cp932_available = false; +#endif + m_initialized = true; + } + +#if __cplusplus + public: + static vector convert( std::string str ){ +#else + public static byte[] convert( string str ) { +#endif +#if !__cplusplus + if ( !m_initialized ) { + init(); + } + if ( m_cp932_available ) { + return m_cp932.GetBytes( str ); + } else { +#endif +#if __cplusplus + int len = str.size(); + wchar_t *arr = new wchar_t[len]; + vector list( 0 ); + for( int i = 0; i < len; i++ ){ +#else + char[] arr = str.ToCharArray(); + List list = new List(); + for ( int i = 0; i < arr.Length; i++ ) { +#endif +#if DEBUG + System.Diagnostics.Debug.WriteLine( "arr[i]=" + arr[i] ); +#endif +#if __cplusplus + map::const_iterator finder = _DICT.find( (int)arr[i] ); + if( finder != _DICT.end() ){ +#else + if ( _DICT.ContainsKey( (int)arr[i] ) ) { +#endif + int t = _DICT[(int)arr[i]]; + if ( t > 0xff ) { + byte b1 = (byte)(t >> 8); + byte b2 = (byte)(t - (b1 << 8)); +#if __cplusplus + list.push_back( b1 ); + list.push_back( b2 ); +#else + list.Add( b1 ); + list.Add( b2 ); +#endif + } else { +#if __cplusplus + list.push_back( (byte)t ); +#else + list.Add( (byte)t ); +#endif + } + } else { +#if __cplusplus + list.push_back( 0x63 ); +#else + list.Add( 0x63 ); +#endif + } + } +#if __cplusplus + return list; +#else + return list.ToArray(); + } +#endif + } + + +#if __cplusplus + public: + static string convert( vector dat ){ +#else + public static string convert( byte[] dat ) { +#endif + if ( !m_initialized ) { + init(); + } +#if !__cplusplus + if ( m_cp932_available ) { + char[] res = m_cp932.GetChars( dat ); + return new string( res ); + } else { +#endif +#if __cplusplus + string sb( "" ); +#else + StringBuilder sb = new StringBuilder(); +#endif + int i = 0; +#if __cplusplus + while( i < dat.size() ){ +#else + while ( i < dat.Length ) { +#endif + int b1 = dat[i]; + bool found = false; +#if __cplusplus + for( int j = 0; j < _LEN_DICT; j++ ){ + int key = _DICT_SRC[j][0]; + int test = _DICT_SRC[j][1]; +#else + foreach ( int key in _DICT.Keys ) { + int test = _DICT[key]; +#endif + if ( b1 == test ) { + found = true; +#if __cplusplus + sb = sb + (char)key; +#else + sb.Append( ((char)key).ToString() ); +#endif + break; + } + } + i++; +#if __cplusplus + if( !found && i < dat.size() ){ +#else + if ( !found && i < dat.Length ) { +#endif + int b2 = (dat[i - 1] << 8) + dat[i]; +#if __cplusplus + for( int j = 0; j < _LEN_DICT; j++ ){ + int key = _DICT_SRC[j][0]; + int test = _DICT_SRC[j][1]; +#else + foreach ( int key in _DICT.Keys ) { + int test = _DICT[key]; +#endif + if ( test == b2 ) { +#if __cplusplus + sb = sb + (char)key; +#else + sb.Append( ((char)key).ToString() ); +#endif + break; + } + } + i++; + } + } +#if __cplusplus + return sb; +#else + return sb.ToString(); + } +#endif + } + }; + +} + +#endif //__cp932__ diff --git a/trunk/bocoree/cp932reader.cs b/trunk/bocoree/cp932reader.cs new file mode 100644 index 0000000..31dfe5a --- /dev/null +++ b/trunk/bocoree/cp932reader.cs @@ -0,0 +1,110 @@ +/* + * cp932reader.cs + * Copyright (c) 2009 kbinani + * + * This file is part of bocoree + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace bocoree { + + public class cp932reader : IDisposable { + private Stream m_stream; + + + private cp932reader() { + } + + public cp932reader( Stream stream ) + : this() { + m_stream = stream; + } + + public cp932reader( string path ) + : this() { + m_stream = new FileStream( path, FileMode.Open, FileAccess.Read ); + } + + public string ReadLine() { + byte[] line; + if ( get_line( out line ) ) { + return cp932.convert( line ); + } else { + return null; + } + } + + public void Close() { + if ( m_stream != null ) { + m_stream.Close(); + } + } + + public void Dispose() { + Close(); + } + + public int Peek() { + int ch = m_stream.ReadByte(); + if ( ch < 0 ) { + return ch; + } else { + m_stream.Seek( -1, SeekOrigin.Current ); + return ch; + } + } + + public string ReadToEnd() { + StringBuilder sb = new StringBuilder(); + while ( Peek() >= 0 ) { + sb.Append( ReadLine() + Environment.NewLine ); + } + return sb.ToString(); + } + + private bool get_line( out byte[] line ) { + List ret = new List(); + if ( !m_stream.CanRead ) { + line = ret.ToArray(); + return false; + } + if ( !m_stream.CanSeek ) { + line = ret.ToArray(); + return false; + } + int ch = m_stream.ReadByte(); + if ( ch < 0 ) { + line = ret.ToArray(); + return false; + } + while ( ch >= 0 ) { + if ( ch == 0x0d ) { + ch = m_stream.ReadByte(); + if ( ch < 0 ) { + break; + } else if ( ch != 0x0a ) { + m_stream.Seek( -1, SeekOrigin.Current ); + } + break; + } else if ( ch == 0x0a ) { + break; + } + ret.Add( (byte)ch ); + ch = m_stream.ReadByte(); + } + line = ret.ToArray(); + return true; + } + } + +} diff --git a/trunk/bocoree/cp932writer.cs b/trunk/bocoree/cp932writer.cs new file mode 100644 index 0000000..2963fff --- /dev/null +++ b/trunk/bocoree/cp932writer.cs @@ -0,0 +1,60 @@ +/* + * cp932writer.cs + * Copyright (c) 2009 kbinani + * + * This file is part of bocoree + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Text; + +namespace bocoree { + + public class cp932writer : IDisposable { + Stream m_stream; + byte[] m_newline; + + private cp932writer() { + m_newline = Encoding.ASCII.GetBytes( Environment.NewLine ); + } + + public cp932writer( Stream stream ) + : this() { + m_stream = stream; + } + + public cp932writer( string file ) + : this() { + m_stream = new FileStream( file, FileMode.Create ); + } + + public void WriteLine( string line ) { + byte[] bytes = cp932.convert( line ); + m_stream.Write( bytes, 0, bytes.Length ); + m_stream.Write( m_newline, 0, m_newline.Length ); + } + + public void Write( string line ) { + byte[] bytes = cp932.convert( line ); + m_stream.Write( bytes, 0, bytes.Length ); + } + + public void Close() { + if ( m_stream != null ) { + m_stream.Close(); + } + } + + public void Dispose() { + Close(); + } + } + +} diff --git a/trunk/bocoree/fft.cs b/trunk/bocoree/fft.cs new file mode 100644 index 0000000..425c821 --- /dev/null +++ b/trunk/bocoree/fft.cs @@ -0,0 +1,3255 @@ +/* + * fft.cs + * Copyright (c) 2008-2009 kbinani + * + * Part of this is derived from + * General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package + * Copyright(C) 1996-2001 Takuya OOURA + * (http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html) + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; + +namespace bocoree { + + public static unsafe class fft_test { + const int NMAXSQRT = 64; + const int NMAX = 8192; + + static double RND( ref int seed ) { + seed = (seed * 7141 + 54773) % 259200; + return seed * (1.0 / 259200.0); + } + + + public static int test() { + int n; + int[] ip_ = new int[NMAXSQRT + 2]; + double[] a_ = new double[NMAX + 1]; + double[] w_ = new double[NMAX * 5 / 4]; + double[] t_ = new double[NMAX / 2 + 1]; + double err; + fixed ( int* ip = &ip_[0] ) + fixed ( double* a = &a_[0] ) + fixed ( double* w = &w_[0] ) + fixed ( double* t = &t_[0] ) { + + Console.WriteLine( "data length n=? (must be 2^m)" ); + string ret = Console.ReadLine(); + n = int.Parse( ret ); + ip[0] = 0; + + int np = 100; + + using ( System.IO.StreamWriter sw = new System.IO.StreamWriter( @"c:\rdft_data.txt" ) ) { + for ( int i = 0; i < n; i++ ) { + double x = (double)i / (double)n; + a_[i] = Math.Sin( x * np * Math.PI ) + Math.Sin( x * np * 2 * Math.PI ) + Math.Sin( x * np * 3 * Math.PI ); + sw.WriteLine( a_[i] ); + } + } + + /* check of CDFT + putdata( 0, n - 1, a ); + fft.cdft( n, 1, a, ip, w ); + fft.cdft( n, -1, a, ip, w ); + err = errorcheck( 0, n - 1, 2.0 / n, a ); + Console.WriteLine( "cdft err= {0}", err );*/ + + /* check of RDFT */ + //putdata( 0, n - 1, a ); + fft.rdft( n, 1, a, ip, w ); + using ( System.IO.StreamWriter sw_a = new System.IO.StreamWriter( @"c:\rdft_a.txt" ) ) { + for ( int i = 0; i < n; i++ ) { + sw_a.WriteLine( a[i] ); + } + } + err = errorcheck( 0, n - 1, 2.0 / n, a ); + Console.WriteLine( "rdft err= {0}", err ); + + /* check of DDCT + putdata( 0, n - 1, a ); + fft.ddct( n, 1, a, ip, w ); + fft.ddct( n, -1, a, ip, w ); + a[0] *= 0.5; + err = errorcheck( 0, n - 1, 2.0 / n, a ); + Console.WriteLine( "ddct err= {0}", err );*/ + + /* check of DDST + putdata( 0, n - 1, a ); + fft.ddst( n, 1, a, ip, w ); + fft.ddst( n, -1, a, ip, w ); + a[0] *= 0.5; + err = errorcheck( 0, n - 1, 2.0 / n, a ); + Console.WriteLine( "ddst err= {0} \n", err );*/ + + /* check of DFCT + putdata( 0, n, a ); + a[0] *= 0.5; + a[n] *= 0.5; + fft.dfct( n, a, t, ip, w ); + a[0] *= 0.5; + a[n] *= 0.5; + fft.dfct( n, a, t, ip, w ); + err = errorcheck( 0, n, 2.0 / n, a ); + Console.WriteLine( "dfct err= {0}", err );*/ + + /* check of DFST + putdata( 1, n - 1, a ); + fft.dfst( n, a, t, ip, w ); + fft.dfst( n, a, t, ip, w ); + err = errorcheck( 1, n - 1, 2.0 / n, a ); + Console.WriteLine( "dfst err= {0}", err );*/ + } + + return 0; + } + + + static void putdata( int nini, int nend, double* a ) { + int j, seed = 0; + + for ( j = nini; j <= nend; j++ ) { + a[j] = RND( ref seed ); + } + } + + + static double errorcheck( int nini, int nend, double scale, double* a ) { + int j, seed = 0; + double err = 0, e; + + for ( j = nini; j <= nend; j++ ) { + e = RND( ref seed ) - a[j] * scale; + err = Math.Max( err, Math.Abs( e ) ); + } + return err; + } + } + + + public static unsafe class fft { + /* + Fast Fourier/Cosine/Sine Transform + dimension :one + data length :power of 2 + decimation :frequency + radix :split-radix + data :inplace + table :use + functions + cdft: Complex Discrete Fourier Transform + rdft: Real Discrete Fourier Transform + ddct: Discrete Cosine Transform + ddst: Discrete Sine Transform + dfct: Cosine Transform of RDFT (Real Symmetric DFT) + dfst: Sine Transform of RDFT (Real Anti-symmetric DFT) + function prototypes + void cdft(int, int, double *, int *, double *); + void rdft(int, int, double *, int *, double *); + void ddct(int, int, double *, int *, double *); + void ddst(int, int, double *, int *, double *); + void dfct(int, double *, double *, int *, double *); + void dfst(int, double *, double *, int *, double *); + macro definitions + USE_CDFT_PTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=8192 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536 + USE_CDFT_WINTHREADS : default=not defined + CDFT_THREADS_BEGIN_N : must be >= 512, default=32768 + CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288 + + + -------- Complex DFT (Discrete Fourier Transform) -------- + [definition] + + X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k + X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k + ip[0] = 0; // first time only + cdft(2*n, 1, a, ip, w); + + ip[0] = 0; // first time only + cdft(2*n, -1, a, ip, w); + [parameters] + 2*n :data length (int) + n >= 1, n = power of 2 + a[0...2*n-1] :input/output data (double *) + input data + a[2*j] = Re(x[j]), + a[2*j+1] = Im(x[j]), 0<=j= 2+sqrt(n) + strictly, + length of ip >= + 2+(1<<(int)(log(n+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + cdft(2*n, -1, a, ip, w); + is + cdft(2*n, 1, a, ip, w); + for (j = 0; j <= 2 * n - 1; j++) { + a[j] *= 1.0 / n; + } + . + + + -------- Real DFT / Inverse of Real DFT -------- + [definition] + RDFT + R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2 + I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0 IRDFT (excluding scale) + a[k] = (R[0] + R[n/2]*cos(pi*k))/2 + + sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) + + sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k + ip[0] = 0; // first time only + rdft(n, 1, a, ip, w); + + ip[0] = 0; // first time only + rdft(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + + output data + a[2*k] = R[k], 0<=k + input data + a[2*j] = R[j], 0<=j= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n/2-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + rdft(n, 1, a, ip, w); + is + rdft(n, -1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + + -------- DCT (Discrete Cosine Transform) / Inverse of DCT -------- + [definition] + IDCT (excluding scale) + C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k DCT + C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k + ip[0] = 0; // first time only + ddct(n, 1, a, ip, w); + + ip[0] = 0; // first time only + ddct(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = C[k], 0<=k= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddct(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddct(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + + -------- DST (Discrete Sine Transform) / Inverse of DST -------- + [definition] + IDST (excluding scale) + S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k DST + S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0 + ip[0] = 0; // first time only + ddst(n, 1, a, ip, w); + + ip[0] = 0; // first time only + ddst(n, -1, a, ip, w); + [parameters] + n :data length (int) + n >= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + + input data + a[j] = A[j], 0 + output data + a[k] = S[k], 0= 2+sqrt(n/2) + strictly, + length of ip >= + 2+(1<<(int)(log(n/2+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/4-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + ddst(n, -1, a, ip, w); + is + a[0] *= 0.5; + ddst(n, 1, a, ip, w); + for (j = 0; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + + -------- Cosine Transform of RDFT (Real Symmetric DFT) -------- + [definition] + C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n + [usage] + ip[0] = 0; // first time only + dfct(n, a, t, ip, w); + [parameters] + n :data length - 1 (int) + n >= 2, n = power of 2 + a[0...n] :input/output data (double *) + output data + a[k] = C[k], 0<=k<=n + t[0...n/2] :work area (double *) + ip[0...*] :work area for bit reversal (int *) + length of ip >= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + is + a[0] *= 0.5; + a[n] *= 0.5; + dfct(n, a, t, ip, w); + for (j = 0; j <= n; j++) { + a[j] *= 2.0 / n; + } + . + + + -------- Sine Transform of RDFT (Real Anti-symmetric DFT) -------- + [definition] + S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0= 2, n = power of 2 + a[0...n-1] :input/output data (double *) + output data + a[k] = S[k], 0= 2+sqrt(n/4) + strictly, + length of ip >= + 2+(1<<(int)(log(n/4+0.5)/log(2))/2). + ip[0],ip[1] are pointers of the cos/sin table. + w[0...n*5/8-1] :cos/sin table (double *) + w[],ip[] are initialized if ip[0] == 0. + [remark] + Inverse of + dfst(n, a, t, ip, w); + is + dfst(n, a, t, ip, w); + for (j = 1; j <= n - 1; j++) { + a[j] *= 2.0 / n; + } + . + + + Appendix : + The cos/sin table is recalculated when the larger table required. + w[] and ip[] are compatible with all routines. + */ + + static double cos( double x ) { + return Math.Cos( x ); + } + + + static double sin( double x ) { + return Math.Sin( x ); + } + + + static double atan( double x ) { + return Math.Atan( x ); + } + + + public static void cdft( int n, int isgn, double* a, int* ip, double* w ) { + //void makewt(int nw, int *ip, double *w); + //void cftfsub(int n, double *a, int *ip, int nw, double *w); + //void cftbsub(int n, double *a, int *ip, int nw, double *w); + int nw; + + nw = ip[0]; + if ( n > (nw << 2) ) { + nw = n >> 2; + makewt( nw, ip, w ); + } + if ( isgn >= 0 ) { + cftfsub( n, a, ip, nw, w ); + } else { + cftbsub( n, a, ip, nw, w ); + } + } + + + public static void rdft( int n, int isgn, double* a, int* ip, double* w ) { + int nw, nc; + double xi; + + nw = ip[0]; + if ( n > (nw << 2) ) { + nw = n >> 2; + makewt( nw, ip, w ); + } + nc = ip[1]; + if ( n > (nc << 2) ) { + nc = n >> 2; + makect( nc, ip, w + nw ); + } + if ( isgn >= 0 ) { + if ( n > 4 ) { + cftfsub( n, a, ip, nw, w ); + rftfsub( n, a, nc, w + nw ); + } else if ( n == 4 ) { + cftfsub( n, a, ip, nw, w ); + } + xi = a[0] - a[1]; + a[0] += a[1]; + a[1] = xi; + } else { + a[1] = 0.5 * (a[0] - a[1]); + a[0] -= a[1]; + if ( n > 4 ) { + rftbsub( n, a, nc, w + nw ); + cftbsub( n, a, ip, nw, w ); + } else if ( n == 4 ) { + cftbsub( n, a, ip, nw, w ); + } + } + } + + + public static void ddct( int n, int isgn, double* a, int* ip, double* w ) { + //void makewt(int nw, int *ip, double *w); + //void makect(int nc, int *ip, double *c); + //void cftfsub(int n, double *a, int *ip, int nw, double *w); + //void cftbsub(int n, double *a, int *ip, int nw, double *w); + //void rftfsub(int n, double *a, int nc, double *c); + //void rftbsub(int n, double *a, int nc, double *c); + //void dctsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if ( n > (nw << 2) ) { + nw = n >> 2; + makewt( nw, ip, w ); + } + nc = ip[1]; + if ( n > nc ) { + nc = n; + makect( nc, ip, w + nw ); + } + if ( isgn < 0 ) { + xr = a[n - 1]; + for ( j = n - 2; j >= 2; j -= 2 ) { + a[j + 1] = a[j] - a[j - 1]; + a[j] += a[j - 1]; + } + a[1] = a[0] - xr; + a[0] += xr; + if ( n > 4 ) { + rftbsub( n, a, nc, w + nw ); + cftbsub( n, a, ip, nw, w ); + } else if ( n == 4 ) { + cftbsub( n, a, ip, nw, w ); + } + } + dctsub( n, a, nc, w + nw ); + if ( isgn >= 0 ) { + if ( n > 4 ) { + cftfsub( n, a, ip, nw, w ); + rftfsub( n, a, nc, w + nw ); + } else if ( n == 4 ) { + cftfsub( n, a, ip, nw, w ); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for ( j = 2; j < n; j += 2 ) { + a[j - 1] = a[j] - a[j + 1]; + a[j] += a[j + 1]; + } + a[n - 1] = xr; + } + } + + + public static void ddst( int n, int isgn, double* a, int* ip, double* w ) { + //void makewt(int nw, int *ip, double *w); + //void makect(int nc, int *ip, double *c); + //void cftfsub(int n, double *a, int *ip, int nw, double *w); + //void cftbsub(int n, double *a, int *ip, int nw, double *w); + //void rftfsub(int n, double *a, int nc, double *c); + //void rftbsub(int n, double *a, int nc, double *c); + //void dstsub(int n, double *a, int nc, double *c); + int j, nw, nc; + double xr; + + nw = ip[0]; + if ( n > (nw << 2) ) { + nw = n >> 2; + makewt( nw, ip, w ); + } + nc = ip[1]; + if ( n > nc ) { + nc = n; + makect( nc, ip, w + nw ); + } + if ( isgn < 0 ) { + xr = a[n - 1]; + for ( j = n - 2; j >= 2; j -= 2 ) { + a[j + 1] = -a[j] - a[j - 1]; + a[j] -= a[j - 1]; + } + a[1] = a[0] + xr; + a[0] -= xr; + if ( n > 4 ) { + rftbsub( n, a, nc, w + nw ); + cftbsub( n, a, ip, nw, w ); + } else if ( n == 4 ) { + cftbsub( n, a, ip, nw, w ); + } + } + dstsub( n, a, nc, w + nw ); + if ( isgn >= 0 ) { + if ( n > 4 ) { + cftfsub( n, a, ip, nw, w ); + rftfsub( n, a, nc, w + nw ); + } else if ( n == 4 ) { + cftfsub( n, a, ip, nw, w ); + } + xr = a[0] - a[1]; + a[0] += a[1]; + for ( j = 2; j < n; j += 2 ) { + a[j - 1] = -a[j] - a[j + 1]; + a[j] -= a[j + 1]; + } + a[n - 1] = -xr; + } + } + + + public static void dfct( int n, double* a, double* t, int* ip, double* w ) { + //void makewt(int nw, int *ip, double *w); + //void makect(int nc, int *ip, double *c); + //void cftfsub(int n, double *a, int *ip, int nw, double *w); + //void rftfsub(int n, double *a, int nc, double *c); + //void dctsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if ( n > (nw << 3) ) { + nw = n >> 3; + makewt( nw, ip, w ); + } + nc = ip[1]; + if ( n > (nc << 1) ) { + nc = n >> 1; + makect( nc, ip, w + nw ); + } + m = n >> 1; + yi = a[m]; + xi = a[0] + a[n]; + a[0] -= a[n]; + t[0] = xi - yi; + t[m] = xi + yi; + if ( n > 2 ) { + mh = m >> 1; + for ( j = 1; j < mh; j++ ) { + k = m - j; + xr = a[j] - a[n - j]; + xi = a[j] + a[n - j]; + yr = a[k] - a[n - k]; + yi = a[k] + a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi - yi; + t[k] = xi + yi; + } + t[mh] = a[mh] + a[n - mh]; + a[mh] -= a[n - mh]; + dctsub( m, a, nc, w + nw ); + if ( m > 4 ) { + cftfsub( m, a, ip, nw, w ); + rftfsub( m, a, nc, w + nw ); + } else if ( m == 4 ) { + cftfsub( m, a, ip, nw, w ); + } + a[n - 1] = a[0] - a[1]; + a[1] = a[0] + a[1]; + for ( j = m - 2; j >= 2; j -= 2 ) { + a[2 * j + 1] = a[j] + a[j + 1]; + a[2 * j - 1] = a[j] - a[j + 1]; + } + l = 2; + m = mh; + while ( m >= 2 ) { + dctsub( m, t, nc, w + nw ); + if ( m > 4 ) { + cftfsub( m, t, ip, nw, w ); + rftfsub( m, t, nc, w + nw ); + } else if ( m == 4 ) { + cftfsub( m, t, ip, nw, w ); + } + a[n - l] = t[0] - t[1]; + a[l] = t[0] + t[1]; + k = 0; + for ( j = 2; j < m; j += 2 ) { + k += l << 2; + a[k - l] = t[j] - t[j + 1]; + a[k + l] = t[j] + t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for ( j = 0; j < mh; j++ ) { + k = m - j; + t[j] = t[m + k] - t[m + j]; + t[k] = t[m + k] + t[m + j]; + } + t[mh] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + a[n] = t[2] - t[1]; + a[0] = t[2] + t[1]; + } else { + a[1] = a[0]; + a[2] = t[0]; + a[0] = t[1]; + } + } + + + public static void dfst( int n, double* a, double* t, int* ip, double* w ) { + //void makewt(int nw, int *ip, double *w); + //void makect(int nc, int *ip, double *c); + //void cftfsub(int n, double *a, int *ip, int nw, double *w); + //void rftfsub(int n, double *a, int nc, double *c); + //void dstsub(int n, double *a, int nc, double *c); + int j, k, l, m, mh, nw, nc; + double xr, xi, yr, yi; + + nw = ip[0]; + if ( n > (nw << 3) ) { + nw = n >> 3; + makewt( nw, ip, w ); + } + nc = ip[1]; + if ( n > (nc << 1) ) { + nc = n >> 1; + makect( nc, ip, w + nw ); + } + if ( n > 2 ) { + m = n >> 1; + mh = m >> 1; + for ( j = 1; j < mh; j++ ) { + k = m - j; + xr = a[j] + a[n - j]; + xi = a[j] - a[n - j]; + yr = a[k] + a[n - k]; + yi = a[k] - a[n - k]; + a[j] = xr; + a[k] = yr; + t[j] = xi + yi; + t[k] = xi - yi; + } + t[0] = a[mh] - a[n - mh]; + a[mh] += a[n - mh]; + a[0] = a[m]; + dstsub( m, a, nc, w + nw ); + if ( m > 4 ) { + cftfsub( m, a, ip, nw, w ); + rftfsub( m, a, nc, w + nw ); + } else if ( m == 4 ) { + cftfsub( m, a, ip, nw, w ); + } + a[n - 1] = a[1] - a[0]; + a[1] = a[0] + a[1]; + for ( j = m - 2; j >= 2; j -= 2 ) { + a[2 * j + 1] = a[j] - a[j + 1]; + a[2 * j - 1] = -a[j] - a[j + 1]; + } + l = 2; + m = mh; + while ( m >= 2 ) { + dstsub( m, t, nc, w + nw ); + if ( m > 4 ) { + cftfsub( m, t, ip, nw, w ); + rftfsub( m, t, nc, w + nw ); + } else if ( m == 4 ) { + cftfsub( m, t, ip, nw, w ); + } + a[n - l] = t[1] - t[0]; + a[l] = t[0] + t[1]; + k = 0; + for ( j = 2; j < m; j += 2 ) { + k += l << 2; + a[k - l] = -t[j] - t[j + 1]; + a[k + l] = t[j] - t[j + 1]; + } + l <<= 1; + mh = m >> 1; + for ( j = 1; j < mh; j++ ) { + k = m - j; + t[j] = t[m + k] + t[m + j]; + t[k] = t[m + k] - t[m + j]; + } + t[0] = t[m + mh]; + m = mh; + } + a[l] = t[0]; + } + a[0] = 0; + } + + + /* -------- initializing routines -------- */ + + + //#include + + static void makewt( int nw, int* ip, double* w ) { + //void makeipt(int nw, int *ip); + int j, nwh, nw0, nw1; + double delta, wn4r, wk1r, wk1i, wk3r, wk3i; + + ip[0] = nw; + ip[1] = 1; + if ( nw > 2 ) { + nwh = nw >> 1; + delta = atan( 1.0 ) / nwh; + wn4r = cos( delta * nwh ); + w[0] = 1; + w[1] = wn4r; + if ( nwh == 4 ) { + w[2] = cos( delta * 2 ); + w[3] = sin( delta * 2 ); + } else if ( nwh > 4 ) { + makeipt( nw, ip ); + w[2] = 0.5 / cos( delta * 2 ); + w[3] = 0.5 / cos( delta * 6 ); + for ( j = 4; j < nwh; j += 4 ) { + w[j] = cos( delta * j ); + w[j + 1] = sin( delta * j ); + w[j + 2] = cos( 3 * delta * j ); + w[j + 3] = -sin( 3 * delta * j ); + } + } + nw0 = 0; + while ( nwh > 2 ) { + nw1 = nw0 + nwh; + nwh >>= 1; + w[nw1] = 1; + w[nw1 + 1] = wn4r; + if ( nwh == 4 ) { + wk1r = w[nw0 + 4]; + wk1i = w[nw0 + 5]; + w[nw1 + 2] = wk1r; + w[nw1 + 3] = wk1i; + } else if ( nwh > 4 ) { + wk1r = w[nw0 + 4]; + wk3r = w[nw0 + 6]; + w[nw1 + 2] = 0.5 / wk1r; + w[nw1 + 3] = 0.5 / wk3r; + for ( j = 4; j < nwh; j += 4 ) { + wk1r = w[nw0 + 2 * j]; + wk1i = w[nw0 + 2 * j + 1]; + wk3r = w[nw0 + 2 * j + 2]; + wk3i = w[nw0 + 2 * j + 3]; + w[nw1 + j] = wk1r; + w[nw1 + j + 1] = wk1i; + w[nw1 + j + 2] = wk3r; + w[nw1 + j + 3] = wk3i; + } + } + nw0 = nw1; + } + } + } + + + static void makeipt( int nw, int* ip ) { + int j, l, m, m2, p, q; + + ip[2] = 0; + ip[3] = 16; + m = 2; + for ( l = nw; l > 32; l >>= 2 ) { + m2 = m << 1; + q = m2 << 3; + for ( j = m; j < m2; j++ ) { + p = ip[j] << 2; + ip[m + j] = p; + ip[m2 + j] = p + q; + } + m = m2; + } + } + + + static void makect( int nc, int* ip, double* c ) { + int j, nch; + double delta; + + ip[1] = nc; + if ( nc > 1 ) { + nch = nc >> 1; + delta = atan( 1.0 ) / nch; + c[0] = cos( delta * nch ); + c[nch] = 0.5 * c[0]; + for ( j = 1; j < nch; j++ ) { + c[j] = 0.5 * cos( delta * j ); + c[nc - j] = 0.5 * sin( delta * j ); + } + } + } + + + /* -------- child routines -------- */ + + + + + + static void cftfsub( int n, double* a, int* ip, int nw, double* w ) { + //void bitrv2(int n, int *ip, double *a); + //void bitrv216(double *a); + //void bitrv208(double *a); + //void cftf1st(int n, double *a, double *w); + //void cftrec4(int n, double *a, int nw, double *w); + //void cftleaf(int n, int isplt, double *a, int nw, double *w); + //void cftfx41(int n, double *a, int nw, double *w); + //void cftf161(double *a, double *w); + //void cftf081(double *a, double *w); + //void cftf040(double *a); + //void cftx020(double *a); + + if ( n > 8 ) { + if ( n > 32 ) { + cftf1st( n, a, &w[nw - (n >> 2)] ); + if ( n > 512 ) { + cftrec4( n, a, nw, w ); + } else if ( n > 128 ) { + cftleaf( n, 1, a, nw, w ); + } else { + cftfx41( n, a, nw, w ); + } + bitrv2( n, ip, a ); + } else if ( n == 32 ) { + cftf161( a, &w[nw - 8] ); + bitrv216( a ); + } else { + cftf081( a, w ); + bitrv208( a ); + } + } else if ( n == 8 ) { + cftf040( a ); + } else if ( n == 4 ) { + cftx020( a ); + } + } + + + static void cftbsub( int n, double* a, int* ip, int nw, double* w ) { + //void bitrv2conj(int n, int *ip, double *a); + //void bitrv216neg(double *a); + //void bitrv208neg(double *a); + //void cftb1st(int n, double *a, double *w); + //void cftrec4(int n, double *a, int nw, double *w); + //void cftleaf(int n, int isplt, double *a, int nw, double *w); + //void cftfx41(int n, double *a, int nw, double *w); + //void cftf161(double *a, double *w); + //void cftf081(double *a, double *w); + //void cftb040(double *a); + //void cftx020(double *a); + + if ( n > 8 ) { + if ( n > 32 ) { + cftb1st( n, a, &w[nw - (n >> 2)] ); + if ( n > 512 ) { + cftrec4( n, a, nw, w ); + } else if ( n > 128 ) { + cftleaf( n, 1, a, nw, w ); + } else { + cftfx41( n, a, nw, w ); + } + bitrv2conj( n, ip, a ); + } else if ( n == 32 ) { + cftf161( a, &w[nw - 8] ); + bitrv216neg( a ); + } else { + cftf081( a, w ); + bitrv208neg( a ); + } + } else if ( n == 8 ) { + cftb040( a ); + } else if ( n == 4 ) { + cftx020( a ); + } + } + + + static void bitrv2( int n, int* ip, double* a ) { + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for ( l = n >> 2; l > 8; l >>= 2 ) { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if ( l == 8 ) { + for ( k = 0; k < m; k++ ) { + for ( j = 0; j < k; j++ ) { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } else { + for ( k = 0; k < m; k++ ) { + for ( j = 0; j < k; j++ ) { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = a[j1 + 1]; + yr = a[k1]; + yi = a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } + + + static void bitrv2conj( int n, int* ip, double* a ) { + int j, j1, k, k1, l, m, nh, nm; + double xr, xi, yr, yi; + + m = 1; + for ( l = n >> 2; l > 8; l >>= 2 ) { + m <<= 1; + } + nh = n >> 1; + nm = 4 * m; + if ( l == 8 ) { + for ( k = 0; k < m; k++ ) { + for ( j = 0; j < k; j++ ) { + j1 = 4 * j + 2 * ip[m + k]; + k1 = 4 * k + 2 * ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + 2 * ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += 2 * nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= 2; + k1 -= nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh + 2; + k1 += nh + 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh - nm; + k1 += 2 * nm - 2; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } else { + for ( k = 0; k < m; k++ ) { + for ( j = 0; j < k; j++ ) { + j1 = 4 * j + ip[m + k]; + k1 = 4 * k + ip[m + j]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nh; + k1 += 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += 2; + k1 += nh; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += nm; + k1 += nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nh; + k1 -= 2; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + j1 -= nm; + k1 -= nm; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + } + k1 = 4 * k + ip[m + k]; + j1 = k1 + 2; + k1 += nh; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + j1 += nm; + k1 += nm; + a[j1 - 1] = -a[j1 - 1]; + xr = a[j1]; + xi = -a[j1 + 1]; + yr = a[k1]; + yi = -a[k1 + 1]; + a[j1] = yr; + a[j1 + 1] = yi; + a[k1] = xr; + a[k1 + 1] = xi; + a[k1 + 3] = -a[k1 + 3]; + } + } + } + + + static void bitrv216( double* a ) { + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, + x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + a[2] = x8r; + a[3] = x8i; + a[4] = x4r; + a[5] = x4i; + a[6] = x12r; + a[7] = x12i; + a[8] = x2r; + a[9] = x2i; + a[10] = x10r; + a[11] = x10i; + a[14] = x14r; + a[15] = x14i; + a[16] = x1r; + a[17] = x1i; + a[20] = x5r; + a[21] = x5i; + a[22] = x13r; + a[23] = x13i; + a[24] = x3r; + a[25] = x3i; + a[26] = x11r; + a[27] = x11i; + a[28] = x7r; + a[29] = x7i; + } + + + static void bitrv216neg( double* a ) { + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, + x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, + x13r, x13i, x14r, x14i, x15r, x15i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + x8r = a[16]; + x8i = a[17]; + x9r = a[18]; + x9i = a[19]; + x10r = a[20]; + x10i = a[21]; + x11r = a[22]; + x11i = a[23]; + x12r = a[24]; + x12i = a[25]; + x13r = a[26]; + x13i = a[27]; + x14r = a[28]; + x14i = a[29]; + x15r = a[30]; + x15i = a[31]; + a[2] = x15r; + a[3] = x15i; + a[4] = x7r; + a[5] = x7i; + a[6] = x11r; + a[7] = x11i; + a[8] = x3r; + a[9] = x3i; + a[10] = x13r; + a[11] = x13i; + a[12] = x5r; + a[13] = x5i; + a[14] = x9r; + a[15] = x9i; + a[16] = x1r; + a[17] = x1i; + a[18] = x14r; + a[19] = x14i; + a[20] = x6r; + a[21] = x6i; + a[22] = x10r; + a[23] = x10i; + a[24] = x2r; + a[25] = x2i; + a[26] = x12r; + a[27] = x12i; + a[28] = x4r; + a[29] = x4i; + a[30] = x8r; + a[31] = x8i; + } + + + static void bitrv208( double* a ) { + double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i; + + x1r = a[2]; + x1i = a[3]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x6r = a[12]; + x6i = a[13]; + a[2] = x4r; + a[3] = x4i; + a[6] = x6r; + a[7] = x6i; + a[8] = x1r; + a[9] = x1i; + a[12] = x3r; + a[13] = x3i; + } + + + static void bitrv208neg( double* a ) { + double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, + x5r, x5i, x6r, x6i, x7r, x7i; + + x1r = a[2]; + x1i = a[3]; + x2r = a[4]; + x2i = a[5]; + x3r = a[6]; + x3i = a[7]; + x4r = a[8]; + x4i = a[9]; + x5r = a[10]; + x5i = a[11]; + x6r = a[12]; + x6i = a[13]; + x7r = a[14]; + x7i = a[15]; + a[2] = x7r; + a[3] = x7i; + a[4] = x3r; + a[5] = x3i; + a[6] = x5r; + a[7] = x5i; + a[8] = x1r; + a[9] = x1i; + a[10] = x6r; + a[11] = x6i; + a[12] = x2r; + a[13] = x2i; + a[14] = x4r; + a[15] = x4i; + } + + + static void cftf1st( int n, double* a, double* w ) { + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for ( j = 2; j < mh - 2; j += 4 ) { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = a[j + 3] + a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = a[j + 3] - a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = a[j0 - 1] + a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i + y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i - y2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r - y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r + y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = a[j0 - 1] + a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = a[j0 - 1] - a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i + x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = a[j0 + 3] + a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = a[j0 + 3] - a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i + x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; + } + + + static void cftb1st( int n, double* a, double* w ) { + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, csc1, csc3, wk1r, wk1i, wk3r, wk3i, + wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = -a[1] - a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = -a[1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j2] = x1r + x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r - x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + csc1 = w[2]; + csc3 = w[3]; + wd1r = 1; + wd1i = 0; + wd3r = 1; + wd3i = 0; + k = 0; + for ( j = 2; j < mh - 2; j += 4 ) { + k += 4; + wk1r = csc1 * (wd1r + w[k]); + wk1i = csc1 * (wd1i + w[k + 1]); + wk3r = csc3 * (wd3r + w[k + 2]); + wk3i = csc3 * (wd3i + w[k + 3]); + wd1r = w[k]; + wd1i = w[k + 1]; + wd3r = w[k + 2]; + wd3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = -a[j + 1] - a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = -a[j + 1] + a[j2 + 1]; + y0r = a[j + 2] + a[j2 + 2]; + y0i = -a[j + 3] - a[j2 + 3]; + y1r = a[j + 2] - a[j2 + 2]; + y1i = -a[j + 3] + a[j2 + 3]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 + 2] + a[j3 + 2]; + y2i = a[j1 + 3] + a[j3 + 3]; + y3r = a[j1 + 2] - a[j3 + 2]; + y3i = a[j1 + 3] - a[j3 + 3]; + a[j] = x0r + x2r; + a[j + 1] = x0i - x2i; + a[j + 2] = y0r + y2r; + a[j + 3] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 + 2] = y0r - y2r; + a[j1 + 3] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 + 2] = wd1r * x0r - wd1i * x0i; + a[j2 + 3] = wd1r * x0i + wd1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 + 2] = wd3r * x0r + wd3i * x0i; + a[j3 + 3] = wd3r * x0i - wd3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + y0r = a[j0 - 2] + a[j2 - 2]; + y0i = -a[j0 - 1] - a[j2 - 1]; + y1r = a[j0 - 2] - a[j2 - 2]; + y1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + y2r = a[j1 - 2] + a[j3 - 2]; + y2i = a[j1 - 1] + a[j3 - 1]; + y3r = a[j1 - 2] - a[j3 - 2]; + y3i = a[j1 - 1] - a[j3 - 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j0 - 2] = y0r + y2r; + a[j0 - 1] = y0i - y2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + a[j1 - 2] = y0r - y2r; + a[j1 - 1] = y0i + y2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = y1r + y3i; + x0i = y1i + y3r; + a[j2 - 2] = wd1i * x0r - wd1r * x0i; + a[j2 - 1] = wd1i * x0i + wd1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + x0r = y1r - y3i; + x0i = y1i - y3r; + a[j3 - 2] = wd3i * x0r + wd3r * x0i; + a[j3 - 1] = wd3i * x0i - wd3r * x0r; + } + wk1r = csc1 * (wd1r + wn4r); + wk1i = csc1 * (wd1i + wn4r); + wk3r = csc3 * (wd3r - wn4r); + wk3i = csc3 * (wd3i - wn4r); + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0 - 2] + a[j2 - 2]; + x0i = -a[j0 - 1] - a[j2 - 1]; + x1r = a[j0 - 2] - a[j2 - 2]; + x1i = -a[j0 - 1] + a[j2 - 1]; + x2r = a[j1 - 2] + a[j3 - 2]; + x2i = a[j1 - 1] + a[j3 - 1]; + x3r = a[j1 - 2] - a[j3 - 2]; + x3i = a[j1 - 1] - a[j3 - 1]; + a[j0 - 2] = x0r + x2r; + a[j0 - 1] = x0i - x2i; + a[j1 - 2] = x0r - x2r; + a[j1 - 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 - 2] = wk1r * x0r - wk1i * x0i; + a[j2 - 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 - 2] = wk3r * x0r + wk3i * x0i; + a[j3 - 1] = wk3r * x0i - wk3i * x0r; + x0r = a[j0] + a[j2]; + x0i = -a[j0 + 1] - a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = -a[j0 + 1] + a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i - x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + x0r = a[j0 + 2] + a[j2 + 2]; + x0i = -a[j0 + 3] - a[j2 + 3]; + x1r = a[j0 + 2] - a[j2 + 2]; + x1i = -a[j0 + 3] + a[j2 + 3]; + x2r = a[j1 + 2] + a[j3 + 2]; + x2i = a[j1 + 3] + a[j3 + 3]; + x3r = a[j1 + 2] - a[j3 + 2]; + x3i = a[j1 + 3] - a[j3 + 3]; + a[j0 + 2] = x0r + x2r; + a[j0 + 3] = x0i - x2i; + a[j1 + 2] = x0r - x2r; + a[j1 + 3] = x0i + x2i; + x0r = x1r + x3i; + x0i = x1i + x3r; + a[j2 + 2] = wk1i * x0r - wk1r * x0i; + a[j2 + 3] = wk1i * x0i + wk1r * x0r; + x0r = x1r - x3i; + x0i = x1i - x3r; + a[j3 + 2] = wk3i * x0r + wk3r * x0i; + a[j3 + 3] = wk3i * x0i - wk3r * x0r; + } + + + static void cftrec4( int n, double* a, int nw, double* w ) { + //int cfttree(int n, int j, int k, double *a, int nw, double *w); + //void cftleaf(int n, int isplt, double *a, int nw, double *w); + //void cftmdl1(int n, double *a, double *w); + int isplt, j, k, m; + + m = n; + while ( m > 512 ) { + m >>= 2; + cftmdl1( m, &a[n - m], &w[nw - (m >> 1)] ); + } + cftleaf( m, 1, &a[n - m], nw, w ); + k = 0; + for ( j = n - m; j > 0; j -= m ) { + k++; + isplt = cfttree( m, j, k, a, nw, w ); + cftleaf( m, isplt, &a[j - m], nw, w ); + } + } + + + static int cfttree( int n, int j, int k, double* a, int nw, double* w ) { + //void cftmdl1(int n, double *a, double *w); + //void cftmdl2(int n, double *a, double *w); + int i, isplt, m; + + if ( (k & 3) != 0 ) { + isplt = k & 1; + if ( isplt != 0 ) { + cftmdl1( n, &a[j - n], &w[nw - (n >> 1)] ); + } else { + cftmdl2( n, &a[j - n], &w[nw - n] ); + } + } else { + m = n; + for ( i = k; (i & 3) == 0; i >>= 2 ) { + m <<= 2; + } + isplt = i & 1; + if ( isplt != 0 ) { + while ( m > 128 ) { + cftmdl1( m, &a[j - m], &w[nw - (m >> 1)] ); + m >>= 2; + } + } else { + while ( m > 128 ) { + cftmdl2( m, &a[j - m], &w[nw - m] ); + m >>= 2; + } + } + } + return isplt; + } + + + static void cftleaf( int n, int isplt, double* a, int nw, double* w ) { + //void cftmdl1(int n, double *a, double *w); + //void cftmdl2(int n, double *a, double *w); + //void cftf161(double *a, double *w); + //void cftf162(double *a, double *w); + //void cftf081(double *a, double *w); + //void cftf082(double *a, double *w); + + if ( n == 512 ) { + cftmdl1( 128, a, &w[nw - 64] ); + cftf161( a, &w[nw - 8] ); + cftf162( &a[32], &w[nw - 32] ); + cftf161( &a[64], &w[nw - 8] ); + cftf161( &a[96], &w[nw - 8] ); + cftmdl2( 128, &a[128], &w[nw - 128] ); + cftf161( &a[128], &w[nw - 8] ); + cftf162( &a[160], &w[nw - 32] ); + cftf161( &a[192], &w[nw - 8] ); + cftf162( &a[224], &w[nw - 32] ); + cftmdl1( 128, &a[256], &w[nw - 64] ); + cftf161( &a[256], &w[nw - 8] ); + cftf162( &a[288], &w[nw - 32] ); + cftf161( &a[320], &w[nw - 8] ); + cftf161( &a[352], &w[nw - 8] ); + if ( isplt != 0 ) { + cftmdl1( 128, &a[384], &w[nw - 64] ); + cftf161( &a[480], &w[nw - 8] ); + } else { + cftmdl2( 128, &a[384], &w[nw - 128] ); + cftf162( &a[480], &w[nw - 32] ); + } + cftf161( &a[384], &w[nw - 8] ); + cftf162( &a[416], &w[nw - 32] ); + cftf161( &a[448], &w[nw - 8] ); + } else { + cftmdl1( 64, a, &w[nw - 32] ); + cftf081( a, &w[nw - 8] ); + cftf082( &a[16], &w[nw - 8] ); + cftf081( &a[32], &w[nw - 8] ); + cftf081( &a[48], &w[nw - 8] ); + cftmdl2( 64, &a[64], &w[nw - 64] ); + cftf081( &a[64], &w[nw - 8] ); + cftf082( &a[80], &w[nw - 8] ); + cftf081( &a[96], &w[nw - 8] ); + cftf082( &a[112], &w[nw - 8] ); + cftmdl1( 64, &a[128], &w[nw - 32] ); + cftf081( &a[128], &w[nw - 8] ); + cftf082( &a[144], &w[nw - 8] ); + cftf081( &a[160], &w[nw - 8] ); + cftf081( &a[176], &w[nw - 8] ); + if ( isplt != 0 ) { + cftmdl1( 64, &a[192], &w[nw - 32] ); + cftf081( &a[240], &w[nw - 8] ); + } else { + cftmdl2( 64, &a[192], &w[nw - 64] ); + cftf082( &a[240], &w[nw - 8] ); + } + cftf081( &a[192], &w[nw - 8] ); + cftf082( &a[208], &w[nw - 8] ); + cftf081( &a[224], &w[nw - 8] ); + } + } + + + static void cftmdl1( int n, double* a, double* w ) { + int j, j0, j1, j2, j3, k, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + mh = n >> 3; + m = 2 * mh; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] + a[j2]; + x0i = a[1] + a[j2 + 1]; + x1r = a[0] - a[j2]; + x1i = a[1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + a[j2] = x1r - x3i; + a[j2 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + wn4r = w[1]; + k = 0; + for ( j = 2; j < mh; j += 2 ) { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] + a[j2]; + x0i = a[j + 1] + a[j2 + 1]; + x1r = a[j] - a[j2]; + x1i = a[j + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1r * x0r - wk1i * x0i; + a[j2 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r + wk3i * x0i; + a[j3 + 1] = wk3r * x0i - wk3i * x0r; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wk1i * x0r - wk1r * x0i; + a[j2 + 1] = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3i * x0r + wk3r * x0i; + a[j3 + 1] = wk3i * x0i - wk3r * x0r; + } + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] + a[j2]; + x0i = a[j0 + 1] + a[j2 + 1]; + x1r = a[j0] - a[j2]; + x1i = a[j0 + 1] - a[j2 + 1]; + x2r = a[j1] + a[j3]; + x2i = a[j1 + 1] + a[j3 + 1]; + x3r = a[j1] - a[j3]; + x3i = a[j1 + 1] - a[j3 + 1]; + a[j0] = x0r + x2r; + a[j0 + 1] = x0i + x2i; + a[j1] = x0r - x2r; + a[j1 + 1] = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j2] = wn4r * (x0r - x0i); + a[j2 + 1] = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = -wn4r * (x0r + x0i); + a[j3 + 1] = -wn4r * (x0i - x0r); + } + + + static void cftmdl2( int n, double* a, double* w ) { + int j, j0, j1, j2, j3, k, kr, m, mh; + double wn4r, wk1r, wk1i, wk3r, wk3i, wd1r, wd1i, wd3r, wd3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y2r, y2i; + + mh = n >> 3; + m = 2 * mh; + wn4r = w[1]; + j1 = m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[0] - a[j2 + 1]; + x0i = a[1] + a[j2]; + x1r = a[0] + a[j2 + 1]; + x1i = a[1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wn4r * (x2r - x2i); + y0i = wn4r * (x2i + x2r); + a[0] = x0r + y0r; + a[1] = x0i + y0i; + a[j1] = x0r - y0r; + a[j1 + 1] = x0i - y0i; + y0r = wn4r * (x3r - x3i); + y0i = wn4r * (x3i + x3r); + a[j2] = x1r - y0i; + a[j2 + 1] = x1i + y0r; + a[j3] = x1r + y0i; + a[j3 + 1] = x1i - y0r; + k = 0; + kr = 2 * m; + for ( j = 2; j < mh; j += 2 ) { + k += 4; + wk1r = w[k]; + wk1i = w[k + 1]; + wk3r = w[k + 2]; + wk3i = w[k + 3]; + kr -= 4; + wd1i = w[kr]; + wd1r = w[kr + 1]; + wd3i = w[kr + 2]; + wd3r = w[kr + 3]; + j1 = j + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j] - a[j2 + 1]; + x0i = a[j + 1] + a[j2]; + x1r = a[j] + a[j2 + 1]; + x1i = a[j + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wd1r * x2r - wd1i * x2i; + y2i = wd1r * x2i + wd1i * x2r; + a[j] = y0r + y2r; + a[j + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk3r * x1r + wk3i * x1i; + y0i = wk3r * x1i - wk3i * x1r; + y2r = wd3r * x3r + wd3i * x3i; + y2i = wd3r * x3i - wd3i * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + j0 = m - j; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wd1i * x0r - wd1r * x0i; + y0i = wd1i * x0i + wd1r * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wd3i * x1r + wd3r * x1i; + y0i = wd3i * x1i - wd3r * x1r; + y2r = wk3i * x3r + wk3r * x3i; + y2i = wk3i * x3i - wk3r * x3r; + a[j2] = y0r + y2r; + a[j2 + 1] = y0i + y2i; + a[j3] = y0r - y2r; + a[j3 + 1] = y0i - y2i; + } + wk1r = w[m]; + wk1i = w[m + 1]; + j0 = mh; + j1 = j0 + m; + j2 = j1 + m; + j3 = j2 + m; + x0r = a[j0] - a[j2 + 1]; + x0i = a[j0 + 1] + a[j2]; + x1r = a[j0] + a[j2 + 1]; + x1i = a[j0 + 1] - a[j2]; + x2r = a[j1] - a[j3 + 1]; + x2i = a[j1 + 1] + a[j3]; + x3r = a[j1] + a[j3 + 1]; + x3i = a[j1 + 1] - a[j3]; + y0r = wk1r * x0r - wk1i * x0i; + y0i = wk1r * x0i + wk1i * x0r; + y2r = wk1i * x2r - wk1r * x2i; + y2i = wk1i * x2i + wk1r * x2r; + a[j0] = y0r + y2r; + a[j0 + 1] = y0i + y2i; + a[j1] = y0r - y2r; + a[j1 + 1] = y0i - y2i; + y0r = wk1i * x1r - wk1r * x1i; + y0i = wk1i * x1i + wk1r * x1r; + y2r = wk1r * x3r - wk1i * x3i; + y2i = wk1r * x3i + wk1i * x3r; + a[j2] = y0r - y2r; + a[j2 + 1] = y0i - y2i; + a[j3] = y0r + y2r; + a[j3 + 1] = y0i + y2i; + } + + + static void cftfx41( int n, double* a, int nw, double* w ) { + //void cftf161(double *a, double *w); + //void cftf162(double *a, double *w); + //void cftf081(double *a, double *w); + //void cftf082(double *a, double *w); + + if ( n == 128 ) { + cftf161( a, &w[nw - 8] ); + cftf162( &a[32], &w[nw - 32] ); + cftf161( &a[64], &w[nw - 8] ); + cftf161( &a[96], &w[nw - 8] ); + } else { + cftf081( a, &w[nw - 8] ); + cftf082( &a[16], &w[nw - 8] ); + cftf081( &a[32], &w[nw - 8] ); + cftf081( &a[48], &w[nw - 8] ); + } + } + + + static void cftf161( double* a, double* w ) { + double wn4r, wk1r, wk1i, + x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + x0r = a[0] + a[16]; + x0i = a[1] + a[17]; + x1r = a[0] - a[16]; + x1i = a[1] - a[17]; + x2r = a[8] + a[24]; + x2i = a[9] + a[25]; + x3r = a[8] - a[24]; + x3i = a[9] - a[25]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y4r = x0r - x2r; + y4i = x0i - x2i; + y8r = x1r - x3i; + y8i = x1i + x3r; + y12r = x1r + x3i; + y12i = x1i - x3r; + x0r = a[2] + a[18]; + x0i = a[3] + a[19]; + x1r = a[2] - a[18]; + x1i = a[3] - a[19]; + x2r = a[10] + a[26]; + x2i = a[11] + a[27]; + x3r = a[10] - a[26]; + x3i = a[11] - a[27]; + y1r = x0r + x2r; + y1i = x0i + x2i; + y5r = x0r - x2r; + y5i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y9r = wk1r * x0r - wk1i * x0i; + y9i = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y13r = wk1i * x0r - wk1r * x0i; + y13i = wk1i * x0i + wk1r * x0r; + x0r = a[4] + a[20]; + x0i = a[5] + a[21]; + x1r = a[4] - a[20]; + x1i = a[5] - a[21]; + x2r = a[12] + a[28]; + x2i = a[13] + a[29]; + x3r = a[12] - a[28]; + x3i = a[13] - a[29]; + y2r = x0r + x2r; + y2i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y10r = wn4r * (x0r - x0i); + y10i = wn4r * (x0i + x0r); + x0r = x1r + x3i; + x0i = x1i - x3r; + y14r = wn4r * (x0r + x0i); + y14i = wn4r * (x0i - x0r); + x0r = a[6] + a[22]; + x0i = a[7] + a[23]; + x1r = a[6] - a[22]; + x1i = a[7] - a[23]; + x2r = a[14] + a[30]; + x2i = a[15] + a[31]; + x3r = a[14] - a[30]; + x3i = a[15] - a[31]; + y3r = x0r + x2r; + y3i = x0i + x2i; + y7r = x0r - x2r; + y7i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + y11r = wk1i * x0r - wk1r * x0i; + y11i = wk1i * x0i + wk1r * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + y15r = wk1r * x0r - wk1i * x0i; + y15i = wk1r * x0i + wk1i * x0r; + x0r = y12r - y14r; + x0i = y12i - y14i; + x1r = y12r + y14r; + x1i = y12i + y14i; + x2r = y13r - y15r; + x2i = y13i - y15i; + x3r = y13r + y15r; + x3i = y13i + y15i; + a[24] = x0r + x2r; + a[25] = x0i + x2i; + a[26] = x0r - x2r; + a[27] = x0i - x2i; + a[28] = x1r - x3i; + a[29] = x1i + x3r; + a[30] = x1r + x3i; + a[31] = x1i - x3r; + x0r = y8r + y10r; + x0i = y8i + y10i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + x3r = y9r - y11r; + x3i = y9i - y11i; + a[16] = x0r + x2r; + a[17] = x0i + x2i; + a[18] = x0r - x2r; + a[19] = x0i - x2i; + a[20] = x1r - x3i; + a[21] = x1i + x3r; + a[22] = x1r + x3i; + a[23] = x1i - x3r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + x0r = y5r + y7i; + x0i = y5i - y7r; + x3r = wn4r * (x0r - x0i); + x3i = wn4r * (x0i + x0r); + x0r = y4r - y6i; + x0i = y4i + y6r; + x1r = y4r + y6i; + x1i = y4i - y6r; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[10] = x0r - x2r; + a[11] = x0i - x2i; + a[12] = x1r - x3i; + a[13] = x1i + x3r; + a[14] = x1r + x3i; + a[15] = x1i - x3r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + x3r = y1r - y3r; + x3i = y1i - y3i; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x0r - x2r; + a[3] = x0i - x2i; + a[4] = x1r - x3i; + a[5] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + } + + + static void cftf162( double* a, double* w ) { + double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, + x0r, x0i, x1r, x1i, x2r, x2i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, + y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, + y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i; + + wn4r = w[1]; + wk1r = w[4]; + wk1i = w[5]; + wk3r = w[6]; + wk3i = -w[7]; + wk2r = w[8]; + wk2i = w[9]; + x1r = a[0] - a[17]; + x1i = a[1] + a[16]; + x0r = a[8] - a[25]; + x0i = a[9] + a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y0r = x1r + x2r; + y0i = x1i + x2i; + y4r = x1r - x2r; + y4i = x1i - x2i; + x1r = a[0] + a[17]; + x1i = a[1] - a[16]; + x0r = a[8] + a[25]; + x0i = a[9] - a[24]; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + y8r = x1r - x2i; + y8i = x1i + x2r; + y12r = x1r + x2i; + y12i = x1i - x2r; + x0r = a[2] - a[19]; + x0i = a[3] + a[18]; + x1r = wk1r * x0r - wk1i * x0i; + x1i = wk1r * x0i + wk1i * x0r; + x0r = a[10] - a[27]; + x0i = a[11] + a[26]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y1r = x1r + x2r; + y1i = x1i + x2i; + y5r = x1r - x2r; + y5i = x1i - x2i; + x0r = a[2] + a[19]; + x0i = a[3] - a[18]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[10] + a[27]; + x0i = a[11] - a[26]; + x2r = wk1r * x0r + wk1i * x0i; + x2i = wk1r * x0i - wk1i * x0r; + y9r = x1r - x2r; + y9i = x1i - x2i; + y13r = x1r + x2r; + y13i = x1i + x2i; + x0r = a[4] - a[21]; + x0i = a[5] + a[20]; + x1r = wk2r * x0r - wk2i * x0i; + x1i = wk2r * x0i + wk2i * x0r; + x0r = a[12] - a[29]; + x0i = a[13] + a[28]; + x2r = wk2i * x0r - wk2r * x0i; + x2i = wk2i * x0i + wk2r * x0r; + y2r = x1r + x2r; + y2i = x1i + x2i; + y6r = x1r - x2r; + y6i = x1i - x2i; + x0r = a[4] + a[21]; + x0i = a[5] - a[20]; + x1r = wk2i * x0r - wk2r * x0i; + x1i = wk2i * x0i + wk2r * x0r; + x0r = a[12] + a[29]; + x0i = a[13] - a[28]; + x2r = wk2r * x0r - wk2i * x0i; + x2i = wk2r * x0i + wk2i * x0r; + y10r = x1r - x2r; + y10i = x1i - x2i; + y14r = x1r + x2r; + y14i = x1i + x2i; + x0r = a[6] - a[23]; + x0i = a[7] + a[22]; + x1r = wk3r * x0r - wk3i * x0i; + x1i = wk3r * x0i + wk3i * x0r; + x0r = a[14] - a[31]; + x0i = a[15] + a[30]; + x2r = wk1i * x0r - wk1r * x0i; + x2i = wk1i * x0i + wk1r * x0r; + y3r = x1r + x2r; + y3i = x1i + x2i; + y7r = x1r - x2r; + y7i = x1i - x2i; + x0r = a[6] + a[23]; + x0i = a[7] - a[22]; + x1r = wk1i * x0r + wk1r * x0i; + x1i = wk1i * x0i - wk1r * x0r; + x0r = a[14] + a[31]; + x0i = a[15] - a[30]; + x2r = wk3i * x0r - wk3r * x0i; + x2i = wk3i * x0i + wk3r * x0r; + y11r = x1r + x2r; + y11i = x1i + x2i; + y15r = x1r - x2r; + y15i = x1i - x2i; + x1r = y0r + y2r; + x1i = y0i + y2i; + x2r = y1r + y3r; + x2i = y1i + y3i; + a[0] = x1r + x2r; + a[1] = x1i + x2i; + a[2] = x1r - x2r; + a[3] = x1i - x2i; + x1r = y0r - y2r; + x1i = y0i - y2i; + x2r = y1r - y3r; + x2i = y1i - y3i; + a[4] = x1r - x2i; + a[5] = x1i + x2r; + a[6] = x1r + x2i; + a[7] = x1i - x2r; + x1r = y4r - y6i; + x1i = y4i + y6r; + x0r = y5r - y7i; + x0i = y5i + y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[8] = x1r + x2r; + a[9] = x1i + x2i; + a[10] = x1r - x2r; + a[11] = x1i - x2i; + x1r = y4r + y6i; + x1i = y4i - y6r; + x0r = y5r + y7i; + x0i = y5i - y7r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[12] = x1r - x2i; + a[13] = x1i + x2r; + a[14] = x1r + x2i; + a[15] = x1i - x2r; + x1r = y8r + y10r; + x1i = y8i + y10i; + x2r = y9r - y11r; + x2i = y9i - y11i; + a[16] = x1r + x2r; + a[17] = x1i + x2i; + a[18] = x1r - x2r; + a[19] = x1i - x2i; + x1r = y8r - y10r; + x1i = y8i - y10i; + x2r = y9r + y11r; + x2i = y9i + y11i; + a[20] = x1r - x2i; + a[21] = x1i + x2r; + a[22] = x1r + x2i; + a[23] = x1i - x2r; + x1r = y12r - y14i; + x1i = y12i + y14r; + x0r = y13r + y15i; + x0i = y13i - y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[24] = x1r + x2r; + a[25] = x1i + x2i; + a[26] = x1r - x2r; + a[27] = x1i - x2i; + x1r = y12r + y14i; + x1i = y12i - y14r; + x0r = y13r - y15i; + x0i = y13i + y15r; + x2r = wn4r * (x0r - x0i); + x2i = wn4r * (x0i + x0r); + a[28] = x1r - x2i; + a[29] = x1i + x2r; + a[30] = x1r + x2i; + a[31] = x1i - x2r; + } + + + static void cftf081( double* a, double* w ) { + double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + x0r = a[0] + a[8]; + x0i = a[1] + a[9]; + x1r = a[0] - a[8]; + x1i = a[1] - a[9]; + x2r = a[4] + a[12]; + x2i = a[5] + a[13]; + x3r = a[4] - a[12]; + x3i = a[5] - a[13]; + y0r = x0r + x2r; + y0i = x0i + x2i; + y2r = x0r - x2r; + y2i = x0i - x2i; + y1r = x1r - x3i; + y1i = x1i + x3r; + y3r = x1r + x3i; + y3i = x1i - x3r; + x0r = a[2] + a[10]; + x0i = a[3] + a[11]; + x1r = a[2] - a[10]; + x1i = a[3] - a[11]; + x2r = a[6] + a[14]; + x2i = a[7] + a[15]; + x3r = a[6] - a[14]; + x3i = a[7] - a[15]; + y4r = x0r + x2r; + y4i = x0i + x2i; + y6r = x0r - x2r; + y6i = x0i - x2i; + x0r = x1r - x3i; + x0i = x1i + x3r; + x2r = x1r + x3i; + x2i = x1i - x3r; + y5r = wn4r * (x0r - x0i); + y5i = wn4r * (x0r + x0i); + y7r = wn4r * (x2r - x2i); + y7i = wn4r * (x2r + x2i); + a[8] = y1r + y5r; + a[9] = y1i + y5i; + a[10] = y1r - y5r; + a[11] = y1i - y5i; + a[12] = y3r - y7i; + a[13] = y3i + y7r; + a[14] = y3r + y7i; + a[15] = y3i - y7r; + a[0] = y0r + y4r; + a[1] = y0i + y4i; + a[2] = y0r - y4r; + a[3] = y0i - y4i; + a[4] = y2r - y6i; + a[5] = y2i + y6r; + a[6] = y2r + y6i; + a[7] = y2i - y6r; + } + + + static void cftf082( double* a, double* w ) { + double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, + y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, + y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i; + + wn4r = w[1]; + wk1r = w[2]; + wk1i = w[3]; + y0r = a[0] - a[9]; + y0i = a[1] + a[8]; + y1r = a[0] + a[9]; + y1i = a[1] - a[8]; + x0r = a[4] - a[13]; + x0i = a[5] + a[12]; + y2r = wn4r * (x0r - x0i); + y2i = wn4r * (x0i + x0r); + x0r = a[4] + a[13]; + x0i = a[5] - a[12]; + y3r = wn4r * (x0r - x0i); + y3i = wn4r * (x0i + x0r); + x0r = a[2] - a[11]; + x0i = a[3] + a[10]; + y4r = wk1r * x0r - wk1i * x0i; + y4i = wk1r * x0i + wk1i * x0r; + x0r = a[2] + a[11]; + x0i = a[3] - a[10]; + y5r = wk1i * x0r - wk1r * x0i; + y5i = wk1i * x0i + wk1r * x0r; + x0r = a[6] - a[15]; + x0i = a[7] + a[14]; + y6r = wk1i * x0r - wk1r * x0i; + y6i = wk1i * x0i + wk1r * x0r; + x0r = a[6] + a[15]; + x0i = a[7] - a[14]; + y7r = wk1r * x0r - wk1i * x0i; + y7i = wk1r * x0i + wk1i * x0r; + x0r = y0r + y2r; + x0i = y0i + y2i; + x1r = y4r + y6r; + x1i = y4i + y6i; + a[0] = x0r + x1r; + a[1] = x0i + x1i; + a[2] = x0r - x1r; + a[3] = x0i - x1i; + x0r = y0r - y2r; + x0i = y0i - y2i; + x1r = y4r - y6r; + x1i = y4i - y6i; + a[4] = x0r - x1i; + a[5] = x0i + x1r; + a[6] = x0r + x1i; + a[7] = x0i - x1r; + x0r = y1r - y3i; + x0i = y1i + y3r; + x1r = y5r - y7r; + x1i = y5i - y7i; + a[8] = x0r + x1r; + a[9] = x0i + x1i; + a[10] = x0r - x1r; + a[11] = x0i - x1i; + x0r = y1r + y3i; + x0i = y1i - y3r; + x1r = y5r + y7r; + x1i = y5i + y7i; + a[12] = x0r - x1i; + a[13] = x0i + x1r; + a[14] = x0r + x1i; + a[15] = x0i - x1r; + } + + + static void cftf040( double* a ) { + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + } + + + static void cftb040( double* a ) { + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[4]; + x0i = a[1] + a[5]; + x1r = a[0] - a[4]; + x1i = a[1] - a[5]; + x2r = a[2] + a[6]; + x2i = a[3] + a[7]; + x3r = a[2] - a[6]; + x3i = a[3] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[2] = x1r + x3i; + a[3] = x1i - x3r; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[6] = x1r - x3i; + a[7] = x1i + x3r; + } + + + static void cftx020( double* a ) { + double x0r, x0i; + + x0r = a[0] - a[2]; + x0i = a[1] - a[3]; + a[0] += a[2]; + a[1] += a[3]; + a[2] = x0r; + a[3] = x0i; + } + + + static void rftfsub( int n, double* a, int nc, double* c ) { + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for ( j = 2; j < m; j += 2 ) { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } + } + + + static void rftbsub( int n, double* a, int nc, double* c ) { + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; + + m = n >> 1; + ks = 2 * nc / m; + kk = 0; + for ( j = 2; j < m; j += 2 ) { + k = n - j; + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[j] - a[k]; + xi = a[j + 1] + a[k + 1]; + yr = wkr * xr + wki * xi; + yi = wkr * xi - wki * xr; + a[j] -= yr; + a[j + 1] -= yi; + a[k] += yr; + a[k + 1] -= yi; + } + } + + + static void dctsub( int n, double* a, int nc, double* c ) { + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for ( j = 1; j < m; j++ ) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[j] - wkr * a[k]; + a[j] = wkr * a[j] + wki * a[k]; + a[k] = xr; + } + a[m] *= c[0]; + } + + + static void dstsub( int n, double* a, int nc, double* c ) { + int j, k, kk, ks, m; + double wkr, wki, xr; + + m = n >> 1; + ks = nc / n; + kk = 0; + for ( j = 1; j < m; j++ ) { + k = n - j; + kk += ks; + wkr = c[kk] - c[nc - kk]; + wki = c[kk] + c[nc - kk]; + xr = wki * a[k] - wkr * a[j]; + a[k] = wkr * a[k] + wki * a[j]; + a[j] = xr; + } + a[m] *= c[0]; + } + + } + +} \ No newline at end of file diff --git a/trunk/bocoree/makefile b/trunk/bocoree/makefile new file mode 100644 index 0000000..ade002c --- /dev/null +++ b/trunk/bocoree/makefile @@ -0,0 +1,8 @@ +CP=cp +RM=rm +SRC=cp932.cs fft.cs math.cs windows.cs wingdi.cs +bocoree.dll: *.cs + gmcs -recurse:*.cs -unsafe+ -target:library -out:bocoree.dll -r:System,System.Drawing,System.Windows.Forms + +clean: + $(RM) bocoree.dll diff --git a/trunk/bocoree/math.cs b/trunk/bocoree/math.cs new file mode 100644 index 0000000..5de68b7 --- /dev/null +++ b/trunk/bocoree/math.cs @@ -0,0 +1,273 @@ +/* + * math.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Collections.Generic; + +namespace bocoree { + + public partial class math { + private const double _PI2 = 2.0 * Math.PI; + private const double _PI4 = 4.0 * Math.PI; + private const double _PI6 = 6.0 * Math.PI; + private const double _PI8 = 8.0 * Math.PI; + + public enum WindowFunctionType { + Hamming, + rectangular, + Gauss, + Hann, + Blackman, + Bartlett, + Nuttall, + Blackman_Harris, + Blackman_Nattall, + flap_top, + Parzen, + Akaike, + Welch, + Kaiser, + } + + public static double window_func( WindowFunctionType type, double x ) { + switch ( type ) { + case WindowFunctionType.Akaike: + return wnd_akaike( x ); + case WindowFunctionType.Bartlett: + return wnd_bartlett( x ); + case WindowFunctionType.Blackman: + return wnd_blackman( x ); + case WindowFunctionType.Blackman_Harris: + return wnd_blackman_harris( x ); + case WindowFunctionType.Blackman_Nattall: + return wnd_blackman_nattall( x ); + case WindowFunctionType.flap_top: + return wnd_flap_top( x ); + case WindowFunctionType.Gauss: + throw new ApplicationException( "too few argument for Gauss window function" ); + case WindowFunctionType.Hamming: + return wnd_hamming( x ); + case WindowFunctionType.Hann: + return wnd_hann( x ); + case WindowFunctionType.Kaiser: + throw new ApplicationException( "too few argument for Kaiser window function" ); + case WindowFunctionType.Nuttall: + return wnd_nuttall( x ); + case WindowFunctionType.Parzen: + return wnd_parzen( x ); + case WindowFunctionType.rectangular: + return wnd_rectangular( x ); + case WindowFunctionType.Welch: + return wnd_welch( x ); + } + return 0.0; + } + + public static double window_func( WindowFunctionType type, double x, params double[] param ) { + switch ( type ) { + case WindowFunctionType.Akaike: + return wnd_akaike( x ); + case WindowFunctionType.Bartlett: + return wnd_bartlett( x ); + case WindowFunctionType.Blackman: + return wnd_blackman( x ); + case WindowFunctionType.Blackman_Harris: + return wnd_blackman_harris( x ); + case WindowFunctionType.Blackman_Nattall: + return wnd_blackman_nattall( x ); + case WindowFunctionType.flap_top: + return wnd_flap_top( x ); + case WindowFunctionType.Gauss: + return wnd_gauss( x, param[0] ); + case WindowFunctionType.Hamming: + return wnd_hamming( x ); + case WindowFunctionType.Hann: + return wnd_hann( x ); + case WindowFunctionType.Kaiser: + return wnd_kaiser( x, param[0] ); + case WindowFunctionType.Nuttall: + return wnd_nuttall( x ); + case WindowFunctionType.Parzen: + return wnd_parzen( x ); + case WindowFunctionType.rectangular: + return wnd_rectangular( x ); + case WindowFunctionType.Welch: + return wnd_welch( x ); + } + return 0.0; + } + + public static double wnd_kaiser( double x, double alpha ) { + if ( 0.0 <= x && x <= 1.0 ) { + double t = 2.0 * x - 1.0; + return besi0( Math.PI * alpha * Math.Sqrt( 1.0 - t * t ) ) / besi0( Math.PI * alpha ); + } else { + return 0.0; + } + } + + public static double wnd_welch( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 4.0 * x * (1.0 - x); + } else { + return 0.0; + } + } + + public static double wnd_akaike( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.625 - 0.5 * Math.Cos( _PI2 * x ) + - 0.125 * Math.Cos( _PI4 * x ); + } else { + return 0.0; + } + } + + public static double wnd_parzen( double x ) { + double x0 = Math.Abs( x ); + if ( x0 <= 1.0 ) { + return (0.75 * x0 - 1.5) * x0 * x0 + 1.0; + } else { + x0 = 2.0 - x0; + return 0.25 * x0 * x0 * x0; + } + } + + public static double wnd_flap_top( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0 - 1.93 * Math.Cos( _PI2 * x ) + + 1.29 * Math.Cos( _PI4 * x ) + - 0.388 * Math.Cos( _PI6 * x ) + + 0.032 * Math.Cos( _PI8 * x ); + } else { + return 0.0; + } + } + + public static double wnd_blackman_nattall( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.3635819 - 0.4891775 * Math.Cos( _PI2 * x ) + + 0.1365995 * Math.Cos( _PI4 * x ) + - 0.0106411 * Math.Cos( _PI6 * x ); + } else { + return 0.0; + } + } + + public static double wnd_blackman_harris( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.35875 - 0.48829 * Math.Cos( _PI2 * x ) + + 0.14128 * Math.Cos( _PI4 * x ) + - 0.01168 * Math.Cos( _PI6 * x ); + } else { + return 0.0; + } + } + + public static double wnd_nuttall( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.355768 - 0.487396 * Math.Cos( _PI2 * x ) + + 0.144232 * Math.Cos( _PI4 * x ) + - 0.012604 * Math.Cos( _PI6 * x ); + } else { + return 0.0; + } + } + + public static double wnd_bartlett( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0 - 2.0 * Math.Abs( x - 0.5 ); + } else { + return 0.0; + } + } + + public static double wnd_blackman( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.42 - 0.5 * Math.Cos( _PI2 * x ) + 0.08 * Math.Cos( _PI4 * x ); + } else { + return 0.0; + } + } + + public static double wnd_hann( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.5 - 0.5 * Math.Cos( _PI2 * x ); + } else { + return 0.0; + } + } + + public static double wnd_gauss( double x, double sigma ) { + return Math.Exp( -x * x / (sigma * sigma) ); + } + + public static double wnd_rectangular( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 1.0; + } else { + return 0.0; + } + } + + public static double wnd_hamming( double x ) { + if ( 0.0 <= x && x <= 1.0 ) { + return 0.54 - 0.46 * Math.Cos( _PI2 * x ); + } else { + return 0.0; + } + } + + public static double besi0( double x ) { + int i; + double w, wx375; + double[] a = { 1.0, 3.5156229, 3.0899424, + 1.2067492, 0.2659732, 0.0360768}; + double[] b = { 0.39894228, 0.013285917, 0.002253187, + -0.001575649, 0.009162808, -0.020577063, + 0.026355372, -0.016476329}; + if ( x < 0.0 ) { + return 0.0; + } + if ( x <= 3.75 ) { + wx375 = x * x / 14.0625; + w = 0.0045813; + for ( i = 5; i >= 0; i-- ) { + w = w * wx375 + a[i]; + } + return w; + } + wx375 = 3.75 / x; + w = 0.003923767; + for ( i = 7; i >= 0; i-- ) { + w = w * wx375 + b[i]; + } + return w / Math.Sqrt( x ) * Math.Exp( x ); + } + + public static double erfcc( double x ) { + double t, z, res; + z = Math.Abs( x ); + t = 1.0 / (1.0 + 0.5 * z); + res = t * Math.Exp( -z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196 + + t * (0.09678418 + t * (-0.18628806 + t * (0.27886807 + + t * (-1.13520398 + t * (1.48851587 + t * (-0.82215223 + + t * 0.17087277)))))))) ); + if ( x < 0.0 ) { + res = 2.0 - res; + } + return res; + } + } + +} diff --git a/trunk/bocoree/misc.cs b/trunk/bocoree/misc.cs new file mode 100644 index 0000000..a9edd59 --- /dev/null +++ b/trunk/bocoree/misc.cs @@ -0,0 +1,145 @@ +/* + * misc.cs + * Copyright (c) 2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using System.Collections.Generic; + +namespace bocoree { + + public static class misc { + /// + /// Reflectionを利用して、インスタンスのディープなクローニングを行います。 + /// クローン操作の対象はインスタンスのフィールドであり、値型のものは単なる代入を、 + /// 参照型の物であってかつClone(void)メソッドが実装されているものはCloneしたものを、 + /// それ以外は単に参照が代入されます + /// + /// + /// + public static object obj_clone( object obj ) { + Type t = obj.GetType(); + object ret; + if ( t.IsValueType ) { + return obj; //値型の場合 + } else { + System.Reflection.MethodInfo mi = t.GetMethod( "Clone", new Type[] { } ); + if ( mi != null && (mi.ReturnType == typeof( object ) || mi.ReturnType == t) ) { + // return値がobject型またはt型のCloneメソッドを持っている場合 + ret = mi.Invoke( obj, new object[] { } ); + } else { + // Cloneメソッドが無い場合。型のフィールドを列挙してobj_cloneをRecursiveに呼び出す + // 最初にコンストラクタを取得 + System.Reflection.ConstructorInfo ctor = t.GetConstructor( new Type[] { } ); + if ( ctor == null ) { + // 引数無しのコンストラクタが必要。無い場合はどうしようもないので例外を投げる + throw new ApplicationException( "obj_clone requires zero-argument constructor" ); + } + // インスタンスを作成 + ret = ctor.Invoke( new object[] { } ); + // 全てのフィールドに対してobj_cloneを呼び、値をセットする + foreach ( System.Reflection.FieldInfo fi in t.GetFields() ) { + Type fieldtype = fi.FieldType; + fi.SetValue( ret, obj_clone( obj ) ); + } + } + return ret; + } + } + + public static string getmd5( string s ) { + MD5 md5 = MD5.Create(); + byte[] data = Encoding.Unicode.GetBytes( s ); + byte[] hash = md5.ComputeHash( data ); + return BitConverter.ToString( hash ).ToLower().Replace( "-", "" ); + } + + /// + /// 現在の実行アセンブリで使用されている型のリストを取得します + /// + /// + public static Type[] get_executing_types() { + System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly(); + List types = new List( asm.GetTypes() ); + foreach ( System.Reflection.AssemblyName asmname in asm.GetReferencedAssemblies() ) { + System.Reflection.Assembly asmref = System.Reflection.Assembly.Load( asmname ); + types.AddRange( asmref.GetTypes() ); + } + + asm = System.Reflection.Assembly.GetCallingAssembly(); + types.AddRange( asm.GetTypes() ); + foreach ( System.Reflection.AssemblyName asmname in asm.GetReferencedAssemblies() ) { + System.Reflection.Assembly asmref = System.Reflection.Assembly.Load( asmname ); + types.AddRange( asmref.GetTypes() ); + } + + asm = System.Reflection.Assembly.GetEntryAssembly(); + types.AddRange( asm.GetTypes() ); + foreach ( System.Reflection.AssemblyName asmname in asm.GetReferencedAssemblies() ) { + System.Reflection.Assembly asmref = System.Reflection.Assembly.Load( asmname ); + types.AddRange( asmref.GetTypes() ); + } + + List ret = new List(); + foreach ( Type t in types ) { + if ( t.IsPublic && !ret.Contains( t ) ) { + ret.Add( t ); + } + } + return ret.ToArray(); + } + + /// + /// 現在の実行アセンブリで使用されている名前空間のリストを取得します + /// + /// + public static string[] get_executing_namespaces() { + Type[] types = get_executing_types(); + List list = new List(); + foreach ( Type t in types ) { + if ( !list.Contains( t.Namespace ) ) { + list.Add( t.Namespace ); + } + } + list.Sort(); + return list.ToArray(); + } + } + + public static class debug { + private static StreamWriter s_debug_out = null; + private static string s_path = ""; + + public static void force_logfile_path( string path ) { + s_path = path; + } + + public static void push_log( string s ) { + if ( s_debug_out == null ) { + if ( s_path == "" ) { + s_debug_out = new StreamWriter( Path.Combine( System.Windows.Forms.Application.StartupPath, "run.log" ) ); + } else { + s_debug_out = new StreamWriter( s_path ); + } + s_debug_out.AutoFlush = true; + s_debug_out.WriteLine( "************************************************************************" ); + s_debug_out.WriteLine( " Date: " + DateTime.Now.ToString() ); + s_debug_out.WriteLine( "------------------------------------------------------------------------" ); + } + s_debug_out.WriteLine( s ); + Console.WriteLine( s ); + } + } + +} diff --git a/trunk/bocoree/windows.cs b/trunk/bocoree/windows.cs new file mode 100644 index 0000000..fe0e9ec --- /dev/null +++ b/trunk/bocoree/windows.cs @@ -0,0 +1,171 @@ +/* + * windows.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Runtime.InteropServices; + +namespace bocoree { + + public static partial class windows { + #region winbase.h + public const int OF_READ = 0; + public const int OF_READWRITE = 2; + public const int OF_WRITE = 1; + public const int OF_SHARE_COMPAT = 0; + public const int OF_SHARE_DENY_NONE = 64; + public const int OF_SHARE_DENY_READ = 48; + public const int OF_SHARE_DENY_WRITE = 32; + public const int OF_SHARE_EXCLUSIVE = 16; + public const int OF_CREATE = 4096; + + public const int DONT_RESOLVE_DLL_REFERENCES = 0x00000001; + public const int LOAD_LIBRARY_AS_DATAFILE = 0x00000002; + public const int LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008; + public const int LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010; + public const int LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020; + public const int LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040; + + [DllImport( "kernel32.dll" )] + public static extern IntPtr LoadLibraryExW( [MarshalAs( UnmanagedType.LPWStr)]string lpFileName, IntPtr hFile, uint dwFlags ); + + [DllImport( "kernel32.dll", CharSet = CharSet.Ansi, EntryPoint = "GetProcAddress", ExactSpelling = true )] + public static extern IntPtr GetProcAddress( IntPtr hModule, string lpProcName ); + + [DllImport( "kernel32.dll" )] + public static extern bool FreeLibrary( IntPtr hModule ); + #endregion + + #region winerror.h + public const uint ERROR_SUCCESS = 0; + #endregion + + #region winreg.h + public const uint HKEY_CLASSES_ROOT = 0x80000000; + public const uint HKEY_CURRENT_USER = 0x80000001; + public const uint HKEY_LOCAL_MACHINE = 0x80000002; + public const uint HKEY_USERS = 0x80000003; + public const uint HKEY_PERFORMANCE_DATA = 0x80000004; + public const uint HKEY_CURRENT_CONFIG = 0x80000005; + public const uint HKEY_DYN_DATA = 0x80000006; + + /// + /// + /// + /// キーのハンドル + /// オープンするサブキーの名前 + /// 予約(0を指定) + /// セキュリティアクセスマスク + /// ハンドルを格納する変数のアドレス + /// + [DllImport( "Advapi32.dll" )] + public static unsafe extern int RegOpenKeyExW( + uint hKey, + [MarshalAs( UnmanagedType.LPWStr )] string pSubKey, + uint ulOptions, + uint samDesired, + uint* phkResult ); + + /// + /// + /// + /// キーのハンドル + /// サブキーのインデックス + /// サブキー名を格納するバッファ + /// pName のサイズを入れた変数 + /// 予約(NULLを指定) + /// クラス名を格納するバッファ + /// pClass のサイズを入れた変数 + /// 最終書き込み時間 + /// + [DllImport( "Advapi32.dll" )] + public static unsafe extern int RegEnumKeyExW( + uint hKey, + uint dwIndex, + [MarshalAs( UnmanagedType.LPWStr )] string pName, + uint* pcbName, + uint* pReserved, + [MarshalAs( UnmanagedType.LPWStr )] string pClass, + uint* pcbClass, + FILETIME* pftLastWrite ); + + /// + /// + /// + /// キーのハンドル + /// 値の名前 + /// 予約(NULLを指定) + /// データタイプを格納する変数 + /// データを格納するバッファ + /// バッファサイズを入れた変数 + /// + [DllImport( "Advapi32.dll" )] + public static unsafe extern int RegQueryValueExW( + uint hKey, + [MarshalAs( UnmanagedType.LPWStr )] string pValueName, + uint* pReserved, + uint* pType, + byte* pData, + uint* pcbData ); + + + /// + /// + /// + /// キーのハンドル + /// + [DllImport( "Advapi32.dll" )] + public static extern int RegCloseKey( uint hKey ); + #endregion + + #region winnt.h + public const uint KEY_QUERY_VALUE = 1; + public const uint KEY_SET_VALUE = 2; + public const uint KEY_CREATE_SUB_KEY = 4; + public const uint KEY_ENUMERATE_SUB_KEYS = 8; + public const uint KEY_NOTIFY = 16; + public const uint KEY_CREATE_LINK = 32; + public const uint KEY_WRITE = 0x20006; + public const uint KEY_EXECUTE = 0x20019; + public const uint KEY_READ = 0x20019; + public const uint KEY_ALL_ACCESS = 0xf003f; + + public const int REG_NONE = 0; + public const int REG_SZ = 1; + public const int REG_EXPAND_SZ = 2; + public const int REG_BINARY = 3; + public const int REG_DWORD = 4; + public const int REG_DWORD_LITTLE_ENDIAN = 4; + public const int REG_DWORD_BIG_ENDIAN = 5; + public const int REG_LINK = 6; + public const int REG_MULTI_SZ = 7; + public const int REG_RESOURCE_LIST = 8; + public const int REG_FULL_RESOURCE_DESCRIPTOR = 9; + public const int REG_RESOURCE_REQUIREMENTS_LIST = 10; + public const int REG_QWORD = 11; + public const int REG_QWORD_LITTLE_ENDIAN = 11; + #endregion + + #region windef.h + public const int MAX_PATH = 260; + #endregion + } + + + #region windef.h + public struct FILETIME { + public uint dwLowDateTime; + public uint dwHighDateTime; + } + #endregion + +} \ No newline at end of file diff --git a/trunk/bocoree/wingdi.cs b/trunk/bocoree/wingdi.cs new file mode 100644 index 0000000..829d674 --- /dev/null +++ b/trunk/bocoree/wingdi.cs @@ -0,0 +1,118 @@ +/* + * wingdi.cs + * Copyright (c) 2008-2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Runtime.InteropServices; +using System.IO; + +namespace bocoree { + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct BITMAPINFOHEADER { + public UInt32 biSize; + public Int32 biWidth; + public Int32 biHeight; + public Int16 biPlanes; + public Int16 biBitCount; + public UInt32 biCompression; + public UInt32 biSizeImage; + public Int32 biXPelsPerMeter; + public Int32 biYPelsPerMeter; + public UInt32 biClrUsed; + public UInt32 biClrImportant; + public void Write( BinaryWriter bw ) { + bw.Write( biSize ); + bw.Write( (uint)biWidth ); + bw.Write( (uint)biHeight ); + bw.Write( (ushort)biPlanes ); + bw.Write( (ushort)biBitCount ); + bw.Write( (uint)biCompression ); + bw.Write( (uint)biSizeImage ); + bw.Write( (uint)biXPelsPerMeter ); + bw.Write( (uint)biYPelsPerMeter ); + bw.Write( (uint)biClrUsed ); + bw.Write( (uint)biClrImportant ); + } + public void Write( Stream s ) { + byte[] b; + bool bigendian = !BitConverter.IsLittleEndian; + + b = BitConverter.GetBytes( biSize ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biWidth ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biHeight ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biPlanes ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 2 ); + + b = BitConverter.GetBytes( biBitCount ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 2 ); + + b = BitConverter.GetBytes( biCompression ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biSizeImage ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biXPelsPerMeter ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biYPelsPerMeter ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biClrUsed ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + + b = BitConverter.GetBytes( biClrImportant ); + if ( bigendian ) { + Array.Reverse( b ); + } + s.Write( b, 0, 4 ); + } + } + +} \ No newline at end of file diff --git a/trunk/bocoree/winmm.cs b/trunk/bocoree/winmm.cs new file mode 100644 index 0000000..39036de --- /dev/null +++ b/trunk/bocoree/winmm.cs @@ -0,0 +1,405 @@ +/* + * windows.cs + * Copyright (c) 2009 kbinani + * + * This file is part of bocoree. + * + * bocoree is free software; you can redistribute it and/or + * modify it under the terms of the BSD License. + * + * bocoree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ +using System; +using System.Runtime.InteropServices; + +namespace bocoree { + + using MMRESULT = System.UInt32; + using HMIDIIN = System.Int32; + using DWORD = System.UInt32; + using UINT = System.UInt32; + using WORD = System.UInt16; + using BYTE = System.Byte; + + public delegate void delegateWaveOutProc( IntPtr hwo, uint uMsg, uint dwInstance, uint dwParam1, uint dwParam2 ); + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct JOYINFO { + [MarshalAs( UnmanagedType.U4 )] + public uint wXpos; + [MarshalAs( UnmanagedType.U4 )] + public uint wYpos; + [MarshalAs( UnmanagedType.U4 )] + public uint wZpos; + [MarshalAs( UnmanagedType.U4 )] + public uint wButtons; + } + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Unicode, Pack = 1 )] + public struct JOYCAPSW { + const int MAXPNAMELEN = 32; + const int MAX_JOYSTICKOEMVXDNAME = 260; + [MarshalAs( UnmanagedType.U2 )] + public ushort wMid; + [MarshalAs( UnmanagedType.U2 )] + public ushort wPid; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN )] + public string szPname; + [MarshalAs( UnmanagedType.U4 )] + public uint wXmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wXmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wYmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wYmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wZmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wZmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wNumButtons; + [MarshalAs( UnmanagedType.U4 )] + public uint wPeriodMin; + [MarshalAs( UnmanagedType.U4 )] + public uint wPeriodMax; + [MarshalAs( UnmanagedType.U4 )] + public uint wRmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wRmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wUmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wUmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wVmin; + [MarshalAs( UnmanagedType.U4 )] + public uint wVmax; + [MarshalAs( UnmanagedType.U4 )] + public uint wCaps; + [MarshalAs( UnmanagedType.U4 )] + public uint wMaxAxes; + [MarshalAs( UnmanagedType.U4 )] + public uint wNumAxes; + [MarshalAs( UnmanagedType.U4 )] + public uint wMaxButtons; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = MAXPNAMELEN )] + public string szRegKey; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = MAX_JOYSTICKOEMVXDNAME )] + public string szOEMVxD; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct JOYINFOEX { + public uint dwSize; + public uint dwFlags; + public uint dwXpos; + public uint dwYpos; + public uint dwZpos; + public uint dwRpos; + public uint dwUpos; + public uint dwVpos; + public uint dwButtons; + public uint dwButtonNumber; + public uint dwPOV; + public uint dwReserved1; + public uint dwReserved2; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct WAVEFORMATEX { + public ushort wFormatTag; + public ushort nChannels; + public uint nSamplesPerSec; + public uint nAvgBytesPerSec; + public ushort nBlockAlign; + public ushort wBitsPerSample; + public ushort cbSize; + } + + [StructLayout( LayoutKind.Sequential, Pack = 1 )] + public struct WAVEHDR { + public IntPtr lpData; // pointer to locked data buffer + public uint dwBufferLength; // length of data buffer + public uint dwBytesRecorded; // used for input only + public IntPtr dwUser; // for client's use + public uint dwFlags; // assorted flags (see defines) + public uint dwLoops; // loop control counter + public IntPtr lpNext; // PWaveHdr, reserved for driver + public uint reserved; // reserved for driver + } + + /*typedef struct mmtime_tag +{ + UINT wType; // indicates the contents of the union + union + { + DWORD ms; // milliseconds + DWORD sample; // samples + DWORD cb; // byte count + DWORD ticks; // ticks in MIDI stream + + // SMPTE + struct + { + BYTE hour; // hours + BYTE min; // minutes + BYTE sec; // seconds + BYTE frame; // frames + BYTE fps; // frames per second + BYTE dummy; // pad +#ifdef _WIN32 + BYTE pad[2]; +#endif + } smpte; + + // MIDI + struct + { + DWORD songptrpos; // song pointer position + } midi; + } u; +}*/ + [StructLayout( LayoutKind.Explicit )] + public struct MMTIME { + [FieldOffset( 0 )] + public UInt32 wType; + [FieldOffset( 4 )] + public UInt32 ms; + [FieldOffset( 4 )] + public UInt32 sample; + [FieldOffset( 4 )] + public UInt32 cb; + [FieldOffset( 4 )] + public UInt32 ticks; + [FieldOffset( 4 )] + public Byte smpteHour; + [FieldOffset( 5 )] + public Byte smpteMin; + [FieldOffset( 6 )] + public Byte smpteSec; + [FieldOffset( 7 )] + public Byte smpteFrame; + [FieldOffset( 8 )] + public Byte smpteFps; + [FieldOffset( 9 )] + public Byte smpteDummy; + [FieldOffset( 10 )] + public Byte smptePad0; + [FieldOffset( 11 )] + public Byte smptePad1; + [FieldOffset( 4 )] + public UInt32 midiSongPtrPos; + } + + [StructLayout(LayoutKind.Sequential, Pack = 1 )] + public unsafe struct _MMTIME { + public UINT wType; + byte b1; + byte b2; + byte b3; + byte b4; + byte b5; + byte b6; + byte b7; + byte b8; + + public struct SMPTE { + public BYTE hour; // hours + public BYTE min; // minutes + public BYTE sec; // seconds + public BYTE frame; // frames + public BYTE fps; // frames per second + public BYTE dummy; // pad + public fixed BYTE pad[2]; + } + + public SMPTE smpte { + get { + SMPTE ret = new SMPTE(); + ret.hour = b1; + ret.min = b2; + ret.sec = b3; + ret.frame = b4; + ret.fps = b5; + ret.dummy = b6; + ret.pad[0] = b7; + ret.pad[1] = b8; + return ret; + } + } + + public struct MIDI { + public DWORD songptrpos; // song pointer position + } + + public MIDI midi { + get { + MIDI ret = new MIDI(); + ret.songptrpos = ms; + return ret; + } + } + + public uint ms { + get { + return (uint)b1 | (uint)(b2 << 8) | (uint)(b3 << 16) | (uint)(b4 << 32); + } + } + public uint sample { + get { + return ms; + } + } + public uint cb { + get { + return ms; + } + } + public uint ticks { + get { + return ms; + } + } + } + + [StructLayout( LayoutKind.Sequential, CharSet = CharSet.Ansi )] + public struct MIDIINCAPS { + public ushort wMid; + public ushort wPid; + public uint vDriverVersion; + [MarshalAs( UnmanagedType.ByValTStr, SizeConst = windows.MAXPNAMELEN )] + public string szPname; + public uint dwSupport; + + public override string ToString() { + return szPname; + } + } + + public static partial class windows { + public const uint JOYERR_NOERROR = 0; + public const ushort JOY_RETURNX = 0x00000001; + public const ushort JOY_RETURNY = 0x00000002; + public const ushort JOY_RETURNZ = 0x00000004; + public const ushort JOY_RETURNR = 0x00000008; + public const ushort JOY_RETURNU = 0x00000010; + public const ushort JOY_RETURNV = 0x00000020; + public const ushort JOY_RETURNPOV = 0x00000040; + public const ushort JOY_RETURNBUTTONS = 0x00000080; + public const ushort JOY_RETURNRAWDATA = 0x00000100; + public const ushort JOY_RETURNPOVCTS = 0x00000200; + public const ushort JOY_RETURNCENTERED = 0x00000400; + public const ushort JOY_USEDEADZONE = 0x00000800; + public const ushort JOY_RETURNALL = (JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | + JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | + JOY_RETURNPOV | JOY_RETURNBUTTONS); + + public const ushort MM_MCINOTIFY = 0x3B9; /* MCI */ + + public const ushort MM_WOM_OPEN = 0x3BB; /* waveform output */ + public const ushort MM_WOM_CLOSE = 0x3BC; + public const ushort MM_WOM_DONE = 0x3BD; + + public const ushort MM_WIM_OPEN = 0x3BE; /* waveform input */ + public const ushort MM_WIM_CLOSE = 0x3BF; + public const ushort MM_WIM_DATA = 0x3C0; + + public const ushort MM_MIM_OPEN = 0x3C1; /* MIDI input */ + public const ushort MM_MIM_CLOSE = 0x3C2; + public const ushort MM_MIM_DATA = 0x3C3; + public const ushort MM_MIM_LONGDATA = 0x3C4; + public const ushort MM_MIM_ERROR = 0x3C5; + public const ushort MM_MIM_LONGERROR = 0x3C6; + + public const ushort MM_MOM_OPEN = 0x3C7; /* MIDI output */ + public const ushort MM_MOM_CLOSE = 0x3C8; + public const ushort MM_MOM_DONE = 0x3C9; + + public const int WAVE_MAPPER = -1; + + public const int WAVE_FORMAT_PCM = 1; + + public const int CALLBACK_TYPEMASK = 0x00070000; /* callback type mask */ + public const int CALLBACK_NULL = 0x00000000; /* no callback */ + public const int CALLBACK_WINDOW = 0x00010000; /* dwCallback is a HWND */ + public const int CALLBACK_TASK = 0x00020000; /* dwCallback is a HTASK */ + public const int CALLBACK_FUNCTION = 0x00030000; /* dwCallback is a FARPROC */ + public const int CALLBACK_THREAD = (CALLBACK_TASK);/* thread ID replaces 16 bit task */ + public const int CALLBACK_EVENT = 0x00050000; /* dwCallback is an EVENT Handle */ + + public const int WHDR_DONE = 0x00000001; /* done bit */ + public const int WHDR_PREPARED = 0x00000002; /* set if this header has been prepared */ + public const int WHDR_BEGINLOOP = 0x00000004; /* loop start block */ + public const int WHDR_ENDLOOP = 0x00000008; /* loop end block */ + public const int WHDR_INQUEUE = 0x00000010; /* reserved for driver */ + + public const int TIME_MS = 0x0001; /* time in milliseconds */ + public const int TIME_SAMPLES= 0x0002; /* number of wave samples */ + public const int TIME_BYTES= 0x0004; /* current byte offset */ + public const int TIME_SMPTE = 0x0008; /* SMPTE time */ + public const int TIME_MIDI = 0x0010; /* MIDI time */ + public const int TIME_TICKS = 0x0020; /* Ticks within MIDI stream */ + + public const int MAXPNAMELEN = 32; + public const int MAX_JOYSTICKOEMVXDNAME = 260; + + #region midi + [DllImport( "winmm.dll" )] + public static extern UINT midiInGetNumDevs(); + [DllImport( "winmm.dll" )] + public static unsafe extern MMRESULT midiInOpen( HMIDIIN* lphMidiIn, + UINT uDeviceID, + DWORD dwCallback, + DWORD dwCallbackInstance, + DWORD dwFlags ); + #endregion + + #region joy + [DllImport( "winmm.dll" )] + [return: MarshalAs( UnmanagedType.U4 )] + public static extern uint joyGetNumDevs(); + + [DllImport( "winmm.dll" )] + public static extern uint joyGetPos( uint uJoyID, ref JOYINFO pji ); + + [DllImport( "winmm.dll" )] + public static extern uint joyGetDevCapsW( uint uJoyID, ref JOYCAPSW pjc, uint cbjc ); + + [DllImport( "winmm.dll" )] + public static extern uint joyGetPosEx( uint uJoyID, ref JOYINFOEX pji ); + #endregion + + #region wave + [DllImport( "winmm.dll" )] + public static extern uint waveOutWrite( IntPtr hwo, ref WAVEHDR pwh, uint cbwh ); + [DllImport( "winmm.dll" )] + //[return: MarshalAs(UnmanagedType.U4)] + public static extern uint waveOutOpen( ref IntPtr hWaveOut, + int uDeviceID, + ref WAVEFORMATEX lpFormat, + delegateWaveOutProc dwCallback, + IntPtr dwInstance, + uint dwFlags ); + //public static extern uint waveOutOpen( ref IntPtr phwo, UINT uDeviceID, ref WAVEFORMATEX pwfx, delegateWaveOutProc dwCallback, IntPtr dwInstance, uint fdwOpen ); + [DllImport("winmm.dll")] + public static extern uint waveOutPrepareHeader( IntPtr hwo, ref WAVEHDR pwh, UINT cbwh); + [DllImport( "winmm.dll")] + public static extern uint waveOutGetPosition( IntPtr hwo, ref MMTIME pmmt, UINT cbmmt); + [DllImport("winmm.dll")] + public static extern uint waveOutReset( IntPtr hwo); + [DllImport("winmm.dll")] + public static extern uint waveOutUnprepareHeader( IntPtr hwo, ref WAVEHDR pwh, UINT cbwh); + [DllImport("winmm.dll")] + public static extern uint waveOutClose( IntPtr hwo); + #endregion + + #region mci + [DllImport( "winmm.dll", CharSet = CharSet.Ansi )] + public static extern bool mciGetErrorStringA( uint mcierr, [MarshalAs( UnmanagedType.LPStr )] string pszText, UINT cchText ); + #endregion + } + +}