diff --git a/.MDT b/.MDT new file mode 100644 index 0000000..e8d15f3 Binary files /dev/null and b/.MDT differ diff --git a/ARRL.DX b/ARRL.DX new file mode 100644 index 0000000..05faa26 --- /dev/null +++ b/ARRL.DX @@ -0,0 +1,423 @@ +! ARRL DXCC COUNTRIES LIST For MMLOG +! +AP ;AP-AS,6P-6S ;PAKISTAN ;AS ;E +!A1 ;A1 ;ABU AIL ;AS +A2 ;A2,8O ;BOTSWANA ;AF ;B +A3 ;A3 ;TONGA ;OC ;N +A4 ;A4 ;OMAN ;AS ;D +A5 ;A5 ;BHUTAN ;AS ;F +A6 ;A6 ;UNITED ARAB ;AS ;D +A7 ;A7 ;QATAR ;AS ;C +A9 ;A9 ;BAHRAIN ;AS ;C +BV9P ;BV9P\,BQ9P\ ;PRATAS IS. ;AS ;H +BV ;BV ;TAIWAN ;AS ;H +BS7 ;BS7H\ ;SCARBOROUGH REEF ;AS ;H +BY ;BA-BZ,3H-3U,B1-B9 ;CHINA ;AS ;H +CE0X ;CE0X,XQ0X-XR0X,CE0AA ;SAN FELIX IS. ;SA ;R +CE0Z ;CE0Z,CE0I,CE0OGZ,XQ0Z-XR0Z,XQ0I-XR0I,CE0/JA7XYE; FERNANDEZ ;SA ;R +CE0 ;CE0,XQ0-XR0 ;EASTER IS. ;SA ;T +CE ;CA-CE,XQ-XR,3G ;CHILE ;SA ;Q +CM ;CL-CM,CO,T4 ;CUBA ;NA ;R +CN ;CN,5C-5G ;MOROCCO ;AF ;Z +CP ;CP ;BOLIVIA ;SA ;Q +CT3 ;CS3,CT3,CR9 ;MADEIRAI IS.(PORTUGAL) ;AF ;Z +CU ;CU ;AZORES IS.(PORTUGAL) ;EU ;Z +CT ;CQ-CU ;PORTUGAL ;EU ;Z +CY9 ;CY9,CY0SPI ;ST PAUL IS. ;NA ;Q +CY0 ;CY0 ;SABLE IS. ;NA ;Q +CX ;CV-CX ;URUGUAY ;SA ;P +C2 ;C2 ;NAURU ;OC ;M +C3 ;C3 ;ANDORRA ;EU ;A +C5 ;C5 ;THE GAMBIA ;AF ;Z +C6 ;C6 ;BAHAMA IS. ;NA ;R +C8 ;C8-C9 ;MOZAMBIQUE ;AF ;B +DL ;DA-DR,Y2-Y9 ;GERMANY ;EU ;A +DU ;DU-DZ,4D-4I ;PHILIPPINES ;OC ;H +D2 ;D2-D3 ;ANGOLA ;AF ;A +D4 ;D4 ;CAPE VERDE ;AF ;A +D6 ;D6 ;COMOROS ;AF ;C +EA6 ;EA6-EH6,AM6-AO6 ;BALEARIC ;EU ;A +EA8 ;EA8-EH8,AM8-AO8 ;CANARY ;AF ;A +EA9 ;EA9-EH9,AM9-AO9 ;CEUTA & MELILLA(SPAIN) ;AF ;A +EA ;EA-EH,AM-AO ;SPAIN ;EU ;A +EI ;EI-EJ ;IRELAND ;EU ;Z +EK ;EK ;ARMENIA (ex UG) ;AS ;D +EL ;EL,5L-5M,A8,D5,6Z ;LIBERIA ;AF ;Z +EP ;EP-EQ,HN,9B-9D ;IRAN ;AS ;c +ER ;ER ;MOLDOVA (ex UO) ;EU ;C +ES ;ES ;ESTONIA ;EU ;C +ET ;ET,9E-9F ;ETHIOPIA ;AF ;C +EU ;EU-EW ;BELARUS (ex UC) ;EU ;C +EX ;EX ;KYRGYZSTAN (ex UM) ;AS ;F +EY ;EY ;TAJIKISTAN (ex UJ) ;AS ;F +EZ ;EZ ;TURKMENISTAN (ex UH) ;AS ;F +E4 ;E4 ;PALESTINE ;AS ;B +E3 ;E3 ;ERITREA ;AF ;C +FG ;FG ;GUADELOUPE ;NA ;Q +FH ;FH ;MAYOTTE ;AF ;C +FJ ;FJ,FS ;SAINT MARTIN ;NA ;Q +FK ;FK,TX8 ;NEW CALEDONIA ;OC ;L +FM ;FM ;MARTINIQUE ;NA ;Q +FO/C ;FO0X,FO0AAA ;CLIPPERTON IS. ;NA ;T +FO ;FO ;FRENCH POLYNESIA ;OC ;W +FO/A ;FO ;AUSTRAL IS ;OC ;W +FO/M ;FO ;MARQUESAS IS ;OC ;W +FP ;FP ;ST.PIERRE & MIQUELON IS. ;NA ;Q +FR/J ;FR*/J,FR*/E ;JUAN DE NOVA & EUROPA IS. ;AF ;C +FR/G ;FR*/G ;GLORIOSO IS. ;AF ;C +FR/T ;FR*/T ;TROMELIN ;AF ;C +FR ; ;REUNION IS. ;AF ;C +FR/? ;FR ;REUNION IS. /GLORIOSO IS. /JUAN DE NOVA & EUROPA ;AF ;C +FT5W ;FT8W,FT2W,FT4W,FT5W,FT0W ;CROZET IS. ;AF ;C +FT5X ;FT8X,FT2X,FT4X,FT5X,FT0X ;KERGUELEN IS. ;AF ;E +FT5Z ;FT8Z,FT2Z,FT4Z,FT5Z,FT0Z ;AMSTERDAM & ST PAUL IS. ;AF ;E +FW ;FW ;WALLIS & FUTUNA IS. ;OC ;M +FY ;FY ;FRENCH GUIANA ;SA ;P +F ;F,HW-HY,TM,TO-TQ ;FRANCE ;EU ;A +GD ;GD,GT,MA6-MB6,2A6,MD ;ISLE OF MAN ;EU ;Z +GI ;GI,GN,MA5-MB5,2A5,MI ;NORTHERN IRELAND ;EU ;Z +GJ ;GH,GJ,MA7-MB7,2A7,MJ ;JERSEY ;EU ;Z +GM ;GM,GS,MA3-MB3,2A3,MM ;SCOTLAND ;EU ;Z +GU ;GU,GP,MA8-MB8,2A8,MG ;GUERNSEY ;EU ;Z +GW ;GW,GC,MA4-MB4,2A4,MW ;WALES,U.K ;EU ;Z +G ;G,2,M ;ENGLAND(U.K) ;EU ;Z +HA ;HA,HG ;HUNGARY ;EU ;A +HB0 ;HB0,HE0 ;LIECHTENSTEIN ;EU ;A +HB ;HB,HE,4U1VIC ;SWITZERLAND ;EU ;A +HC8 ;HC8-HD8 ;GALAPAGOS IS.(ECUADOR) ;SA ;R +HC ;HC,HD ;ECUADOR ;SA ;R +HH ;HH,4V ;HAITI ;NA ;R +HI ;HI ;DOMINICAN REPUBLIC ;NA ;R +HK0/M ;HK0M,5J0M,HK0TU ;MALPELO IS. ;NA ;R +HK0/A ;HK0,5J0 ;SAN ANDRES ;NA ;R +HK ;HJ-HK,5J-5K ;COLOMBIA ;SA ;R +HL ;HL,DS-DT,6K-6N,D7-D9,KL9 ;REPUBLIC OF KOREA (SOUTH KOREA) ;AS ;I +HP ;HO-HP,3E-3F,H3,H8-H9 ;PANAMA ;NA ;R +HR ;HQ-HR ;HONDURAS ;NA ;S +HS ;HS,E2 ;THAILAND ;AS ;G +HV ;HV ;VATICAN ;EU ;A +HZ ;HZ,7Z-8Z ;SAUDI ARABIA ;AS ;C +H40 ;H40 ;TEMOTU IS ;OC ;L +H4 ;H4 ;SOLOMON IS. ;OC ;L +IS ;IS,IM0,IU0 ;SARDINIA ;EU ;A +I ;I ;ITALY ;EU ;A +JD1/M ;JD1YAA,JD1BIY ;MINAMI TORISHIMA ;OC ;I +JD1 ;JD1BIC ;OGASAWARA ;AS ;I +JD1/? ;JD1 ;OGASAWARA, /MINAMI TORISHIMA ;I +JA ;JA-JS,7J-7N,8J-8N ;JAPAN ;AS ;I +JT ;JT-JV ;MONGOLIA ;AS ;H +JW ;JW ;SVALBARD IS. ;EU ;A +JX ;JX ;JA MAYEN IS. ;EU ;Z +JY ;JY ;JORDAN ;AS ;B +J2 ;J2 ;DJIBOUTI ;AF ;C +J3 ;J3 ;GRENADA ;NA ;Q +J5 ;J5 ;GUINEA-BISSAU ;AF ;Z +J6 ;J6 ;ST LUCIA ;NA ;Q +J7 ;J7 ;DOMINICA ;NA ;Q +J8 ;J8 ;ST VINCENT & DEPENDENCIES ;NA ;Q +KC4 ;8J1R?\,R1A,FB8Y,CE9A,ZL5,Y88,Y90ANT,ZS8BBB,ZS8AAA,KC4AAC,KC4USV,Y73SOP,KC4AAA,KC4USB,KC4USX,3G9A,3Y9WT,8J1RY,AT0A,IA0PS,OR4,XS7ANT,Y83ANT,ZL0AIC,ZS7ANT,VK0DS,KC4AAE ;ANTARCTICA ;AN +KC6 ;T8,KC6??\ ;(WESTERN CAROLINE IS.) BELAU ;OC ;I +KG4 ;KG4??\ ;GUANTANAMO BAY ;NA ;R +KH0 ;AH0,KH0,NH0,WH0 ;MARIANA IS. ;OC ;K +KH1 ;AH1,KH1,NH1,WH1 ;BAKER & HOWLAND IS. ;OC ;X +KH2 ;AH2,KH2,NH2,WH2 ;GUAM ;OC ;K +KH3 ;AH3,KH3,NH3,WH3 ;JOHNSTON IS. ;OC ;X +KH4 ;AH4,KH4,NH4,WH4 ;MIDWAY IS. ;OC ;M +KH5K ;AH5K,KH5K,NH5K,WH5K ;KINGMAN REEF ;OC ;W +KH5 ;AH5,KH5,NH5,WH5 ;PALMYRA & JARVIS ;OC ;W +KH7K ;AH7K,KH7K,NH7K,WH7K ;KURE IS. ;OC ;M +KH6 ;AH6-AH7,KH6-KH7,NH6-NH7,WH6-WH7 ;HAWAIIAN IS. ;OC ;W +KH8 ;AH8,KH8,NH8,WH8 ;AMERICAN SAMOA ;OC ;W +KH9 ;AH9,KH9,NH9,WH9 ;WAKE IS. ;OC ;L +KL7 ;AL,KL0-KL8,NL,WL ;ALASKA ;NA ;W +KP1 ;KP1,NP1,WP1 ;NAVASSA IS. ;NA ;Q +KP2 ;KP2,NP2,WP2 ;AM.VIRGIN IS. ;NA ;Q +KP4 ;KP3-KP4,NP3-NP4,WP3-WP4 ;PUERTO RICO ;NA ;Q +KP5 ;KP5,NP5,WP5 ;DESECHEO IS. ;NA ;Q +W ;AA6-AK6,K6,N6,W6,K?6,N?6,W?6 ;U.S.A. ;NA ;U +W ;AA7-AK7,K7,N7,W7,K?7,N?7,W?7 ;U.S.A. ;NA ;T +W ;AA0-AK0,K0,N0,W0,K?0,N?0,W?0,AA5-AK5,K5,N5,W5,K?5,N?5,W?5,AA9-AK9,K9,N9,W9,K?9,N?9,W?9 ;U.S.A. ;NA ;S +W ;AA-AL,K,N,W,4U1WB ;U.S.A. ;NA ;R +LA ;LA-LN ;NORWAY ;EU ;A +LU ;LO-LW,AY-AZ,L2-L9 ;ARGENTINA ;SA ;P +LX ;LX ;LUXEMBOURG ;EU ;A +LY ;LY ;LITHUANIA ;EU ;C +LZ ;LZ ;BULGARIA ;EU ;B +OA ;OA-OC,4T ;PERU ;SA ;R +OD ;OD ;LEBANON ;AS ;B +OE ;OE ;AUSTRIA ;EU ;A +OH0 ;OH0,OF0 ;ALAND IS. ;EU ;B +OJ0 ;OJ0 ;MARKET REEF ;EU ;B +OH ;OF-OJ ;FINLAND ;EU ;B +OK ;OK-OL ;CZECH REPUBLIC ;EU ;A +OM ;OM ;SLOVAK REPUBLIC ;EU ;A +ON ;ON-OT ;BELGIUM ;EU ;A +OX ;OX ;GREENLAND ;NA ;Q +OY ;OY ;FAROES ;EU ;Z +OZ ;OU-OZ,XP,5P-5Q ;DENMARK ;EU ;A +PJ8 ;PJ5-PJ8,PJ0J,PJ1F ;SINT MAARTEN ;NA ;Q +PJ9 ;PJ ;NETHERLANDS ANTILLES ;SA ;Q +PA ;PA-PI ;NETHERLANDS ;EU ;A +PY0/S ;PP0S-PY0S,ZV0S-ZZ0S,PY0DX,PT0MI,PS0WH-PT0WH,PY0RO,PW0PP,PP0ZS-PY0ZS ;ST PETER ;SA ;P +PY0/T ;PP0T-PY0T,ZV0T-ZZ0T ;TRINDADE ;SA ;P +PY0 ;PP0-PY0,ZV0-ZZ0 ;FERNANDO DE NORONHA ;SA ;P +PY ;PP-PY,ZV-ZZ ;BRAZIL ;SA ;P +PZ ;PZ ;SURINAM ;SA ;Q +P2 ;P2 ;PAPUA NEW GUINEA ;OC ;K +P4 ;P4 ;ARUBA ;SA ;Q +P5 ;P5-P9,HM ;NORTH KOREA (DPRK) ;AS ;I +R1/MVI ;4J1FS,R1M,*/MVI,MVI/* ;MALYJ VYSOTSKIJ IS. (ex 4J1) ;EU ;C +R1/FJL ;R1F,*/FJL,FJL/* ;FRANZ JOSEPH LAND (ex UA1/4K2) ;EU ;C +SM ;SA-SM,7S-8S ;SWEDEN ;EU ;A +SP ;SN-SR,HF,3Z ;POLAND ;EU ;A +!ST0 ;ST0,6T0-6U0 ;SOUTHEN SUDAN ;AF ;B +ST ;ST,6T-6U ;SUDAN ;AF ;B +SU ;SU,6A-6B ;EGYPT ;AF ;B +SV/A ;SY1MA,SV*/A,*/SV/A ;MT ATHOS ;EU ;B +SV5 ;SV5-SZ5,J45 ;DODECANESE IS. ;EU ;B +SV9 ;SV9-SZ9,J49 ;CRETE ;EU ;B +SV ;SV-SZ,J4 ;GREECE ;EU ;B +S2 ;S2-S3 ;BANGLADESH ;AS ;F +S5 ;S5 ;SLOVENIA (ex YU3) ;EU ;A +S7 ;S7 ;SEYCHELLES ;AF ;C +S9 ;S9 ;SAO TOME & PRINCIPE ;AF ;B +S0 ;S0 ;WESTERN SAHARA ;AF ;Z +TA ;TA1-TC1,YM1 ;TURKEY (EU) ;EU ;C +TA ;TA2-TA9,TB2-TB9,TC2-TC9,YM2-YM9;TURKEY (AS) ;AS ;C +TF ;TF ;ICELAND ;EU ;Z +TG ;TG,TD ;GUATEMALA ;NA ;S +TI9 ;TI9,TE9 ;COCOS IS. ;NA ;S +TI ;TI,TE ;COSTA RICA ;NA ;S +TJ ;TJ ;CAMEROON ;AF ;A +TK ;TK ;CORSICA ;EU ;A +TL ;TL ;CENTRAL AFRICAN REP ;AF ;A +TN ;TN ;CONGO ;AF ;A +TR ;TR ;GABON ;AF ;A +TT ;TT ;CHAD ;AF ;A +TU ;TU ;IVORY COAST ;AF ;Z +TY ;TY ;BENIN ;AF ;Z +TX0 ;TX0 ;CHESTERFIELD IS. ;OC ;L +TZ ;TZ ;MALI ;AF ;Z +T2 ;T2 ;TUVALU ;OC ;M +T30 ;T30 ;WEST KIRIBATI(GILBERT IS.) ;OC ;X +T31 ;T31 ;CENTRAL KIRIBATI(BRITISH PHOENIX IS.) ;OC ;X +T32 ;T32 ;EAST KIRIBATI(LINE IS.) ;OC ;W +T33 ;T33 ;BANABA IS(OCEAN IS.) ;OC ;M +T5 ;T5,6O ;SOMALIA ;AF ;C +T7 ;T7 ;SAN MARINO ;EU ;A +T9 ;T9 ;BOSNIA-HERZEGOVINA (ex YU4,4N4) ;EU ;A +UJ ;UJ-UM ;UZBEKISTAN (ex UI) ;AS ;E +UN ;UN-UQ ;KAZAKHSTAN (ex UL) ;AS ;E +UR ;UR-UZ,EM-EO ;UKRAINE (ex UB) ;EU ;B +UA2 ;U?2,R?2 ;KALININGRAD ;EU ;C +UA/EU ;U?1-U?6,R?1-R?6,U1-U6,R1-R6 ;EUROPEAN RUSSIA ;EU ;C +UA/AS ;U?9,R?9,U9,R9 ;ASIATIC RUSSIA ;AS ;E +UA/AS ;U?8,U?0,R?8,R?0,U8,U0,R8,R0 ;ASIATIC RUSSIA ;AS ;I +VE ;VA7-VG7,VX7,CF7-CK7,XJ7-XO7,VY1 ;CANADA ;NA ;U +VE ;VA6-VG6,VX6,CF6-CK6,XJ6-XO6,VA5-VG5,VX5,CF5-CK5,XJ5-XO5 ;CANADA ;NA ;T +VE ;VA4-VG4,VX4,CF4-CK4,XJ4-XO4 ;CANADA ;NA ;S +VE ;VA3-VG3,VX3,CF3-CK3,XJ3-XO3,VA2-VG2,VX2,CF2-CK2,XJ2-XO2 ;CANADA ;NA ;R +VE ;VA-VG,VO,VX-VY,CF-CK,CY-CZ,XJ-XO ;CANADA ;NA ;Q +VK9L ;VK9L,AX9L ;LORD HOWE IS. ;OC ;L +VK9M ;VK9JW,VK9ZR,VK9MR,VK9ZM ;MELLISH REEF ;OC ;K +VK9N ;VK9N,AX9N ;NORFOLK IS. ;OC ;L +VK9W ;VK9Z,AX9Z,VK9TR ;WILLIS IS. ;OC ;K +VK9X ;VK9X,AX9X ;CHRISTMAS IS. ;OC ;H +VK9C ;VK9Y,AX9Y,VK9WB,VK9EW ;COCOS-KEELING IS. ;OC ;H +VK9? ;VK9 ;COCOS-KEELING IS., /LORD HOWE IS., /MELLISH IS., /NORFOLK IS., /WILLIS IS., /CHRISTMAS IS. ;OC ;K +VK0/M ;VK0AE,VK0GC,VK0WH ;MACQUARIE ;OC ;K +VK0/H ;VK0HM,VK0HI,VK0CW,VK0DA,VK0IR ;HEARD IS. ;AF ;E +VK0/? ;VK0 ;HEARD IS., /MACQUARIE IS. +VK ;VH-VN,VZ,AX ;AUSTRALIA ;OC ;K +VP2E ;VP2E,VP25E ;ANGUILLA ;NA ;Q +VP2M ;VP2M ;MONTSERRAT ;NA ;Q +VP2V ;VP2V ;BRITISH VIRGIN IS. ;NA ;Q +VP5 ;VP5 ;TURKS & CAICOS IS. ;NA ;R +VP8/G ;VP8BUB,VP8CDJ,VP8SGP ;SOUTH GEORGIA ;SA ;P +VP8/O ;LU1Z,VP8BXK ;SOUTH ORKNEY ;SA ;P +VP8/S ;LU2Z,4K1F,CX0XY,HF0POL,LU5ZI,ZX0ECF,VP8CQS,VP8CQR,LZ0A ;SOUTH SHETLAND ;SA ;P +VP8/SW ;VP8SSI ;SOUTH SANDWICH IS. ;SA ;P +VP8 ;VP8CSA ;FALKLAND IS. ;SA ;Q +VP8/? ;VP8,LU?Z ;FALKLAND IS., /SOUTH GEORGIA IS., /SOUTH ORKNEY IS., /SOUTH SANDWICH IS., /SOUTH SHETLAND IS. ;SA ;P +VP9 ;VP9 ;BERMUDA IS. ;NA +VQ9 ;VQ9 ;CHAGOS IS. ;AF ;E +VR6 ;VR6,VP6 ;PITCAIRN IS. ;OC ;U +VR2 ;VS6,VS96,VS97,VR97,VR98,VR2 ;HONG KONG ;AS ;H +VU/A ;VU2JPS ;ANDAMAN & NICOBAR IS. ;AS ;e +VU/L ; ;LACCADIVE IS. ;AS ;e +VU ; ;INDIA ;AS ;e +VU/? ;VT-VW,AT-AW,8T-8Y ;INDIA, /ANDAMAN & NICOBAR IS., /LACCADIVE IS. ;AS ;e +V2 ;V2 ;ANTIGUA & BARBUDA ;NA ;Q +V3 ;V3 ;BELIZE ;NA ;S +V4 ;V4 ;ST KITTS & NEVIS ;NA ;Q +V5 ;V5 ;NAMIBIA ;AF ;B +V6 ;V6 ;MICRONESIA(E CAROLINE IS.) ;OC ;L +V7 ;V7 ;MARSHALL IS. ;OC ;M +V8 ;V8 ;BRUNEI ;OC ;H +XF4 ;XA4-XI4,4A4-4C4,6D4-6J4 ;REVILLA GIGEDO ;NA ;T +XE ;XA-XI,4A-4C,6D-6J ;MEXICO ;NA ;S +XT ;XT ;BURKINA-FASO ;AF ;Z +XU ;XU ;CAMBODIA ;AS ;G +XV ;XV,3W ;VIETNAM ;AS ;G +XW ;XW ;LAOS ;AS ;G +XX9 ;XX9 ;MACAO ;AS ;H +XZ ;XY-XZ,1Z ;MYANMAR ;AS ;f +YA ;YA,T6 ;AFGHANISTAN ;AS ;d +YB ;YB-YH,JZ,PK-PO,7A-7I,8A-8I ;INDONESIA ;OC ;H +YI ;YI ;IRAQ ;AS ;C +YJ ;YJ ;VANUATU ;OC ;L +YK ;YK,6C ;SYRIA ;AS ;B +YL ;YL,UQ ;LATVIA ;EU ;C +YN ;YN,HT,H6-H7 ;NICARAGUA ;NA ;S +YO ;YO-YR ;ROMANIA ;EU ;B +YS ;YS,HU ;EL SALVADOR ;NA ;S +YU ;YT,YU,YZ,4N-4O ;YUGOSLAVIA ;EU ;A +YV0 ;YV0-YY0,4M0 ;AVES IS. ;NA ;Q +YV ;YV-YY,4M ;VENEZUELA ;SA ;Q +ZA ;ZA ;ALBANIA ;EU ;A +ZB ;ZB ;GIBRALTAR ;EU ;A +ZC ;ZC ;UK SOVEREIGN BASES ON CYPRUS ;AS ;B +ZD7 ;ZD7 ;ST HELENA ;AF ;Z +ZD8 ;ZD8 ;ASCENSION IS. ;AF ;Z +ZD9 ;ZD9 ;TRISTAN DE CUNHA & GOUGH IS. ;AF ;Z +ZF ;ZF ;CAYMAN IS. ;NA ;R +ZK1/N ;ZK1CQ,ZK1RS,ZK1BY,ZK1WL,ZK1XP,ZK1XY ;NORTH COOK IS. ;OC ;W +ZK1/S ; ;SOUTH COOK IS ;OC ;W +ZK1/? ;ZK1 ;NORTH COOK IS., /SOUTH COOK IS. ;OC ;W +ZK2 ;ZK2 ;NIUE ;OC ;X +ZK3 ;ZK3 ;TOKELAU IS. ;OC ;X +ZL7 ;ZL7-ZM7 ;CHATHAM IS. ;OC ;M +ZL8 ;ZL8-ZM8 ;KERMADEC IS. ;OC ;M +ZL9 ;ZL9-ZM9 ;AUKLAND & CAMPBELL IS. ;OC ;M +ZL ;ZL-ZM ;NEW ZEALAND ;OC ;M +ZP ;ZP ;PARAGUAY ;SA ;Q +ZS8 ;ZS8MI,ZT8M-ZU8M,ZR8M,ZS8IR ;PRINCE EDWARD & MARION IS. ;AF ;B +!ZS9 ;ZS9 ;WALVIS BAY ;AF +ZS ;ZR-ZU ;REP OF SOUTH AFRICA ;AF ;B +Z2 ;Z2 ;ZIMBABWE ;AF ;B +Z3 ;Z3 ;MACEDONIA (ex YU5,4N5) ;EU ;A +1A0 ;1A0 ;SOVEREIGN MILLITARY ORDER OF MALTA ;EU ;A +1S ;1S,9M0,9M6OO ;SPRATLY IS. ;AS ;H +3A ;3A ;MONACO ;EU ;A +3B6 ;3B6-3B7 ;AGALEGA & ST BRANDON IS. ;AF ;C +3B8 ;3B8 ;MAURITIUS IS. ;AF ;C +3B9 ;3B9 ;RODRIGUEZ IS. ;AF ;C +3C0 ;3C0 ;ANNOBON IS. ;AF ;A +3C ;3C ;EQUATORIAL GUINEA ;AF ;A +3D2/C ;3D2CR,3D2WV,3D2HL,3D2VT,3D2AM,3D2CU,3D2CT ;CONWAY REEF ;OC ;M +3D2/R ;3D2XX,3D2RJ,3D2XV,3D2XR,3D2AP,3D2RO,3D2OQ,3D2RW ;ROTUMA IS ;OC ;M +3D2 ;3D2 ;FIJI IS. ;OC ;M +3DA ;3DA ;SWAZILAND ;AF ;B +3V ;3V,TS ;TUNISIA ;AF ;A +3X ;3X ;GUINEA ;AF ;Z +3Y ;3Y1VC,3Y5X ;BOUVET ;AF ;Z +3Y/P ;3Y1EE,3Y2GV ;PETER 1 IS. ;AN ;S +3Y/? ;3Y ;BOUVET, /PETER 1 IS. ;AF,AN +4J ;4J-4K ;AZERBAIJAN (ex UD) ;AS ;F +4L ;4L ;GEORGIA (ex UF) ;AS ;F +4S ;4P-4S ;SRI LANKA ;AS ;e +4U1/U ;4U1U,4U43-4U44,4U45UN ;UN HEADQUATERS NEW YORK ;NA ;R +4U1/I ;4U?ITU ;ITU GENEVA ;EU ;A +4U1/? ;4U ;UN HEADQUATERS NEW YORK, /ITU GENEVA, etc +!4W ;4W ;YEMEN :AS +4W ;4W ;EAST TIMOR ;OC ;H +4X ;4X,4Z ;ISRAEL ;AS ;B +5A ;5A ;LIBYA ;AF ;B +5B ;5B,C4,H2,P3 ;CYPRUS ;AS ;B +5H ;5H-5I ;TANZANIA ;AF ;C +5N ;5N-5O ;NIGERIA ;AF ;A +5R ;5R-5S,6X ;MADAGASCAR ;AF ;C +5T ;5T ;MAURITANIA ;AF ;Z +5U ;5U ;NIGER ;AF ;A +5V ;5V ;TOGO ;AF ;Z +5W ;5W ;WESTERN SAMOA ;OC ;X +5X ;5X ;UGANDA ;AF ;C +5Y ;5Y-5Z ;KENYA ;AF ;C +6W ;6V-6W ;SENEGAL ;AF ;Z +6Y ;6Y ;JAMAICA ;NA ;R +7O ;7O ;REP OF YEMEN ;AS ;C +7P ;7P ;LESOTHO ;AF ;B +7Q ;7Q ;MALAWI ;AF ;B +7X ;7T-7Y ;ALGERIA ;AF ;Z +8P ;8P ;BARBADOS ;NA ;Q +8Q ;8Q ;MALDIVES ;AS,AF ;E +8R ;8R ;GUYANA ;SA ;P +9A ;9A ;CROATIA (ex YU2) ;EU ;A +9G ;9G ;GHANA ;AF ;Z +9H ;9H ;MALTA ;EU ;A +9J ;9I-9J ;ZAMBIA ;AF ;B +9K ;9K ;KUWAIT ;AS ;C +9L ;9L ;SIERRA LEONE ;AF ;Z +9M2 ;9M2,9M4,9W2,9W4 ;WEST MALAYSIA ;AS ;H +9M6 ;9M6,9M8,9W6,9W8 ;EAST MALAYSIA ;OC ;H +9N ;9N ;NEPAL ;AS ;e +9Q ;9O-9T ;ZAIRE ;AF ;B +9U ;9U ;BURUNDI ;AF ;B +9V ;9V,S6 ;SINGAPORE ;AS ;H +9X ;9X ;RWANDA ;AF ;B +9Y ;9Y-9Z ;TRINIDAD & TOBAGO ;SA ;Q +$END +!---------------------------------------------------------------------------- +!ファイルの形式 +! カントリ名 ; カントリ識別子 ; QTH ; 大陸名 ; タイムゾーン +! +!● 行の先頭のはコメントコード,<$>は終了コード +!● カントリ名は8文字以内。 +!● カントリ識別子は<,>で区切って複数個記述可。 +!● QTHは任意の文字列 +!● 大陸名は NA, SA, EU, OC, AF, AS, AN +!● タイムゾーンはA〜Z(Jを除く)で記述する。小文字は+30分 +!● コードは任意の位置にあっても良い +!● 1行255文字以内。 +!● 定義する行(コメント行を除く)は最大512行まで +!● このファイルをネット等で流通させる場合は、最後の変更履歴に追加記載する +! ことをお勧めします。 +! +!カントリ識別子 +! 1.プリフィックス(コールサイン)の羅列 +! 9M2,9M4,9W2,9W4 +! JD1YAA,JD1BIY +! ※ コールサインが短い場合は終端記号(\)を付加したほうが良い +! BV9P → BV9PAも含まれる +! BV9P\ → BV9Pのみ +! +! 2.範囲の指定 +! DA-DR,Y2-Y9 +! EA6-EH6,AM6-AO6 +! 範囲は同じ位置の1ヶ所のみを昇順で記述 +! JA-JS EA6-EH6 OK +! JS-JA(降順) EA6-EH7(2ヶ所) NG +! +! 3.ワイルドカード(範囲の複合可) +! U?1-U?6,R?1-R?6 +! SV*/A,*/SV/A +! =すべての文字, <*>=すべての文字列 +! +! 4.最初に定義したほうが優先される +! JD1/M ;JD1YAA ; MINAMI TORISHIMA ;OC +! JA ;JA-JS ; JAPAN ;AS +! 上記の例ではJD1YAAはJA-JSにも含まれるが、その前にJD1/Mの定義 +! があるのでそちらが優先される +! +!<<<変更履歴>>> +! Jan 15, 1996 - BV9P追加 JE3HHT +! Feb 15, 1996 - BS7H追加 JE3HHT +! Aug. 4, 1998 - VR98追加 JQ3UDL +! Aug. 4, 1998 - TA(AS)変更 JQ3UDL +! Nov. 15, 1998 - BQ9P追加 JQ3UDL +! Feb. 7, 1999 - FO0/M追加 JQ3UDL +! Feb. 7, 1999 - FO0/A追加 JQ3UDL +! Feb. 7, 1999 - H40追加 JQ3UDL +! Jul. 10, 1999 - E4追加  JQ3UDL +! Nov. 15. 1999 - 9M6OO追加 JQ3UDL +! Nov. 20. 1999 - B1-B9追加 JQ3UDL +! Jan. 06. 2000 - ST0削除 JE3HHT +! Feb. 15. 2000 - VR6にVP6追加 JE3HHT +! Mar. 03. 2000 - FO0XにFO0AAA追加 JE3HHT +! Mar. 20. 2000 - FO0X=>FO/C,FO0/M=>FO/M,FO0/A=>FO/Aに変更 JQ3UDL +! Mar. 20. 2000 - 4W追加 JQ3UDL +! Mar. 21. 2000 - TX0追加 JE3HHT +! Jan. 07. 2001 - P2の範囲変更 JQ3UDL +! Jan. 08. 2001 - KG4範囲変更 JQ3UDL +! Jan. 08. 2001 - LZ0A追加 JQ3UDL + \ No newline at end of file diff --git a/CLX.cpp b/CLX.cpp new file mode 100644 index 0000000..6a50d85 --- /dev/null +++ b/CLX.cpp @@ -0,0 +1,82 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "math.h" +#include "CLX.h" + +///---------------------------------------------------------------- +/// 複素数演算クラス +void CLX::Div(const CLX &ref) +{ + double R, J, D; + R = r * ref.r + j * ref.j; + J = j * ref.r - r * ref.j; + D = ref.r * ref.r + ref.j * ref.j; + if( D ){ + r = R/D; + j = J/D; + } + else { + r = R >= 0 ? 1e100 : -1e100; + j = J >= 0 ? 1e100 : -1e100; + } +} + +CLX CLX::Sqrt(void) +{ + CLX a; + + double R, ST; + R = sqrt(sqrt(r*r + j*j)); + ST = 0; + if( r ) ST = atan2(j, r)/2.0; + a.r = R*cos(ST); + a.j = R*sin(ST); + return a; +} + +CLX operator+(const double R, const CLX &ref) +{ + CLX a(R); + a+=ref; + return a; +} +CLX operator-(const double R, const CLX &ref) +{ + CLX a(R); + a-=ref; + return a; +} +CLX operator*(const double R, const CLX &ref) +{ + CLX a(R); + a*=ref; + return a; +} +CLX operator/(const double R, const CLX &ref) +{ + CLX a(R); + a/=ref; + return a; +} +#pragma package(smart_init) diff --git a/CLX.h b/CLX.h new file mode 100644 index 0000000..ec48b4e --- /dev/null +++ b/CLX.h @@ -0,0 +1,188 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef CLXH +#define CLXH +//--------------------------------------------------------------------------- +///---------------------------------------------------------------- +/// 複素数演算クラス +class CLX { +public: + double r; + double j; + inline CLX(void){}; + inline CLX(const double R){ + r = R; + j = 0; + }; + inline CLX(const double R, const double J){ + r = R; + j = J; + }; + inline CLX(CLX &ref){ + r = ref.r; + j = ref.j; + }; + inline void Add(const CLX &ref){ + r += ref.r; + j += ref.j; + }; + inline void Add(const double &R){ + r += R; + }; + inline void Sub(const CLX &ref){ + r -= ref.r; + j -= ref.j; + }; + inline void Sub(const double &R){ + r -= R; + }; + inline double Abs(void){ + return sqrt(r * r + j * j); + }; + inline double vAbs(void){ + return r * r + j * j; + }; + inline void Mul(CLX &z, const CLX &ref){ + z.r = r * ref.r - j * ref.j; + z.j = r * ref.j + j * ref.r; + } + inline void Mul(const CLX &ref){ + CLX z; + z.r = r * ref.r - j * ref.j; + z.j = r * ref.j + j * ref.r; + r = z.r; j = z.j; + }; + void Div(const CLX &ref); + inline void Mul(const double &R){ + r *= R; j *= R; + } + inline void Div(const double &R){ + r /= R; j /= R; + } + CLX Sqrt(void); + inline void PhDiff(CLX &z, const CLX &ref){ + z.r = r * ref.r + j * ref.j; + z.j = j * ref.r - r * ref.j; + + }; + inline double Phase(void){ + if( r && j ){ + return atan2(j, r); + } + else { + return 0; + } + }; + inline CLX Ccor(CLX x, CLX y){ + CLX z; + + z.r = x.r * y.r + x.j * y.j; + z.j = x.r * y.j - x.j * y.r; + return z; + } + inline BOOL IsSame(const CLX &ref){ + return ((r == ref.r) && (j == ref.j)); + }; + inline CLX& operator=(const CLX &ref){ + if( this != &ref ){ + r = ref.r; + j = ref.j; + } + return *this; + }; + inline CLX& operator+=(const CLX &ref){ + Add(ref); + return *this; + }; + inline CLX& operator+=(const double R){ + Add(R); + return *this; + }; + inline CLX& operator-=(const CLX &ref){ + Sub(ref); + return *this; + }; + inline CLX& operator-=(const double R){ + Sub(R); + return *this; + }; + inline CLX& operator*=(const CLX &ref){ + Mul(ref); + return *this; + }; + inline CLX& operator*=(const double R){ + Mul(R); + return *this; + }; + inline CLX& operator/=(const CLX &ref){ + Div(ref); + return *this; + }; + inline CLX& operator/=(const double R){ + Div(R); + return *this; + }; + inline CLX operator+(const CLX &ref) const { + CLX a(r, j); + a+=ref; + return a; + }; + inline CLX operator+(const double R) const { + CLX a(r, j); + a+=R; + return a; + }; + inline CLX operator-(const CLX &ref) const { + CLX a(r, j); + a-=ref; + return a; + }; + inline CLX operator-(const double R) const { + CLX a(r, j); + a-=R; + return a; + }; + inline CLX operator*(const CLX &ref) const { + CLX a(r, j); + a*=ref; + return a; + }; + inline CLX operator*(const double R) const { + CLX a(r, j); + a*=R; + return a; + }; + inline CLX operator/(const CLX &ref) const { + CLX a(r, j); + a/=ref; + return a; + }; + inline CLX operator/(const double R) const { + CLX a(r, j); + a/=R; + return a; + }; + friend CLX operator+(const double R, const CLX &ref); + friend CLX operator-(const double R, const CLX &ref); + friend CLX operator*(const double R, const CLX &ref); + friend CLX operator/(const double R, const CLX &ref); +}; +#endif diff --git a/COPYING.LESSER.txt b/COPYING.LESSER.txt new file mode 100644 index 0000000..02bbb60 --- /dev/null +++ b/COPYING.LESSER.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..20d40b6 --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/Clock.txt b/Clock.txt new file mode 100644 index 0000000..e4d7d93 --- /dev/null +++ b/Clock.txt @@ -0,0 +1,23 @@ +◎再生同期パルス + 実はPCのサウンドカードはサンプリング周波数が相当ズレている場合があります。例えばサウンドカードのサンプリング周波数に標準の11025Hzを指定した場合、実際の物理サンプリング周波数は11100Hz近辺になっている場合があります(送信時と受信時で異なる場合が多い)。この場合のズレ量は約6800ppmにもなり、すべてのDSP処理はこのサンプリング周波数を基準に行われるために、取り扱うすべての周波数やタイミングにこのズレ量が同じ比率で影響し、主として次の問題点が発生します。 + + ・キャリア周波数のズレ + ・伝送速度(符号タイミング/周波数偏移)のズレ + + キャリア周波数に関しては、例えば2000Hzが2014Hzになる程度で、運用上少し不便ですが、大きな問題ではありません。GMSKの場合の周波数偏移も変化しますが、伝送速度(=位相変化速度)が同じ比率で変化するため送信側では必ずGMSKになります。 + しかし問題となるのは伝送速度のズレのほうです。VARICODEは文字と文字の間に必ずGAPが存在しますので、ここで同期パルスの位相を調整すればRTTYのような調歩同期式符号として扱うことができます。しかし最大で21Bitsもの符号を伝送するような符号方式では、大きなクロックずれは符号の後半部で同期が外れてしまいS/Nに関係なく誤りが発生してしまいます。 + つまり再生同期パルスは位相の調整だけでは不十分で、その周波数(周期)も調整する必要があります。しかし受信信号のタイミングがすぐに再生同期パルスの周波数に影響を与えるような方式ではQSBなどの外乱で簡単に乱れてしまい良くありません。そこで高速に応答できる範囲を1000ppm程度とし、ある程度の時間をかければ25000ppm程度のズレでも補正できるような同期パルスの再生方法が必要になります。 + + 以下に今回採用した再生同期パルスの生成回路を示します。 + + 受信パルス --> 位相比較 --> LPF1 -------------------> SYNC status + | | + | -----> LPF2------- + | | | + -------------- 移相器 <----- VCO <-- + | + --------- π/4 shift --------------> 再生同期パルス + + この方式では2つのループがあるので、少し複雑な動作になりますが、動作としては小さなズレは移相器で(高速で)補正し、大きなズレはVCO周波数を可変して(低速で)補正するようなイメージになります。この回路はあきらかにPLLですからその応答特性は(LPF1,LPF2,VCOゲインからなる)ダンピングファクタによって決定され、十分な時間が経過した後の再生同期パルスは、送信側の同期パルスの周期とほぼ一致し、位相がπ/4ずれている状態になると考えられます。この回路をMMVARIではATC(Automatic Timing Control)と呼びます。 + + 「SYNC status」は、PLLがロックしているかどうかを表し、MMVARIではスペクトラムまたはウォータフォール画面の左上に「SYNC」として表示されます。PLLがロックしていない場合は、受信パルスで強制的に周期調整した別系統の再生同期パルスをデコードパルスにします。この別系統のパルスは、若干外乱に弱いですが、PLLがロックするまでの期間のタイミングズレによる文字化けを防止することができます。 diff --git a/ClockAdj.cpp b/ClockAdj.cpp new file mode 100644 index 0000000..047a641 --- /dev/null +++ b/ClockAdj.cpp @@ -0,0 +1,581 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ClockAdj.h" +#include "Main.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//TClockAdjDlg *ClockAdjDlg; +//--------------------------------------------------------------------------- +__fastcall TClockAdjDlg::TClockAdjDlg(TComponent* Owner) + : TForm(Owner) +{ + m_fDisEvent = TRUE; + Font->Name = ((TForm *)Owner)->Font->Name; + Font->Charset = ((TForm *)Owner)->Font->Charset; + if( sys.m_MsgEng ){ + Caption = "Calibrating the SoundCard (Clock-RX) with a Time Standard Broadcast Station"; + SBClose->Caption = "Cancel"; + } + else { + char bf[256]; + sprintf(bf, "サウンドカード(%uHz系)の受信クロック値の較正", SAMPBASE); + Caption = bf; + } + m_SampFreq = SAMPFREQ; + m_ToneFreq = 1000.0; + m_Clock.Create(PBoxT->Width); + m_Clock.SetSampleFreq(m_SampFreq); + m_Clock.SetToneFreq(m_ToneFreq); + m_pBitmapFFT = new Graphics::TBitmap; + m_pBitmapFFT->Width = PBoxFFT->Width; + m_pBitmapFFT->Height = PBoxFFT->Height; + m_pBitmapT = new Graphics::TBitmap; +// m_pBitmapT->Width = PBoxT->Width; +// m_pBitmapT->Height = PBoxT->Height; + + m_FFTWindow = (3000-1) * FFT_SIZE / MainVARI->m_FFTSampFreq; + + m_StgT.Sum = 0; + m_StgT.Max = 16384; + m_StgT.VW = 16384; + + m_MouseDown = 0; + m_Point = 0; + m_PointRX = 0; + m_CursorX = 640; + CreateWaterColors(); + CBTone->Text = m_ToneFreq; + + m_fDisEvent = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::FormDestroy(TObject *Sender) +{ + if( m_pBitmapFFT ) delete m_pBitmapFFT; + if( m_pBitmapT ) delete m_pBitmapT; +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + CanClose = TRUE; + double d = SAMPFREQ - m_SampFreq; + d = fabs(d); + if( d >= 0.005 ){ + if( YesNoMB(sys.m_MsgEng ? "The clock value (%.2lfHz) is not applied, are you sure?":"クロック値(%.2lfHz)は適用されません. よろしいですか?", m_SampFreq) == IDNO ){ + CanClose = FALSE; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::SBCloseClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::FormClose(TObject *Sender, + TCloseAction &Action) +{ + if( Action == caHide ){ + ::PostMessage(MainVARI->Handle, WM_WAVE, waveClockAdj, DWORD(this)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::Execute(void) +{ + char bf[256]; + sprintf(bf, "%.2lf", m_SampFreq); + EditClock->Text = bf; + UdClock->Position = 0; + UpdatePPM(); + Visible = TRUE; +} +//--------------------------------------------------------------------- +void __fastcall TClockAdjDlg::UpdatePPM(void) +{ + double dd = ((m_SampFreq - SAMPBASE) * 1000000.0 / SAMPBASE); + + char bf[64]; + sprintf(bf, "(%+dppm)", int(dd+0.5)); + LPPM->Caption = bf; +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::DrawMsg(void) +{ + TCanvas *cp = m_pBitmapT->Canvas; + + cp->Font->Name = Font->Name; + cp->Font->Charset = Font->Charset; + cp->Font->Color = clWhite; + cp->Font->Size = 10; + int FH = cp->TextHeight("A"); + int Y = 5; + if( sys.m_MsgEng ){ + cp->TextOut(10, Y, "1) Receive standard radio wave (e.g. BPM on 5MHz, 10MHz, 15MHz, 20MHz)."); Y+=FH; + cp->TextOut(10, Y, "2) Tune into the tick sound."); Y+=FH; + cp->TextOut(10, Y, "3) Continue listening to the sound for a while. You have a vertical line."); Y+=FH; + cp->TextOut(10, Y, "4) Click the lower point of the line."); Y+=FH; + cp->TextOut(10, Y, "5) Click the upper point of the line."); Y+=FH; + Y+=FH; + cp->TextOut(10, Y, "You could use FAX broadcasting instead of WWV, but be sure it has"); Y+=FH; + cp->TextOut(10, Y, "exact timing."); + } + else { + cp->TextOut(10, Y, "1.BPM(WWV)をAMまたはSSBで受信し、この画面の下にあるToneに1000Hz"); Y+=FH; + cp->TextOut(10, Y, " または1800Hzを設定します. (放送周波数 = 5MHz, 10MHz, 15MHz, 20MHz)"); Y+=FH; + cp->TextOut(10, Y, "2.SSBの場合は1秒チック音がToneに重なるように受信周波数を調整します."); Y+=FH; + cp->TextOut(10, Y, "3.しばらく受信して縦または斜めの帯線が表示されるのを待ちます(数分)."); Y+=FH; + cp->TextOut(10, Y, "4.表示された帯線の下の端点をクリックします."); Y+=FH; + cp->TextOut(10, Y, "5.更に同じ帯線の上の端点をクリックするとクロック値が自動的に"); Y+=FH; + cp->TextOut(10, Y, " 設定されます.(2点間の距離が長いほうが正確です)"); Y+=FH; + cp->TextOut(10, Y, "6.最終的に帯線が垂直にまっすぐ表示されるようになればOKです."); Y+=FH+FH; + cp->TextOut(10, Y, "- BPM(WWV)の代わりに、精度は劣りますが、JMH,JMGなどのFAX放送の0.5秒毎の"); Y+=FH; + cp->TextOut(10, Y, " デッドセクタを利用してもOKのようです."); Y+=FH; + cp->TextOut(10, Y, "- NTTの時報サービスを利用することもできます."); Y+=FH+FH; + cp->TextOut(10, Y, "左クリック - 調整の開始"); Y+=FH; + cp->TextOut(10, Y, "右クリック - 垂直カーソル移動"); + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::FormResize(TObject *Sender) +{ + SBClose->Left = PCC->ClientWidth - SBClose->Width - 2; + SBSet->Left = SBClose->Left - SBSet->Width - 2; +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::Do(short ds) +{ + if( m_Clock.Do(ds) ){ + TCanvas *pCanvas = m_pBitmapT->Canvas; + TRect src; + src.Left = 0; src.Right = m_pBitmapT->Width; + src.Top = 0; src.Bottom = m_pBitmapT->Height; + TRect trc = src; + src.Bottom--; + trc.Top++; + pCanvas->CopyRect(trc, pCanvas, src); + + int sum = 0; + int max = 0; + int mp; + int d; + for( int i = 0; i < src.Right; i++ ){ + d = m_Clock.GetData(i); + if( max < d ){ + max = d; + mp = i; + } + sum += d; + + d = (d - m_StgT.Sum) * 256 / m_StgT.VW; + if( d >= 256 ) d = 255; + if( d < 0 ) d = 0; + pCanvas->Pixels[i][0] = m_tWaterColors[d]; + } + pCanvas->Pixels[mp][0] = clRed; + + sum /= src.Right; + m_StgT.Sum = (m_StgT.Sum + sum) / 2; + m_StgT.Max = (m_StgT.Max + max) / 2; + m_StgT.VW = m_StgT.Max - m_StgT.Sum; + if( m_StgT.VW < 128 ) m_StgT.VW = 128; + m_PointY++; + m_PointRX++; + if( m_PointRX >= PBoxT->Height ) m_PointRX = PBoxT->Height; + PBoxTPaint(NULL); + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::DrawFFT(BOOL fClear) +{ + if( !m_pBitmapFFT ) return; + + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_fftXW; rc.Bottom = m_fftYW; + pCanvas->Brush->Color = MainVARI->m_tFFTColset[0].c; + pCanvas->Pen->Color = MainVARI->m_tFFTColset[0].c; + pCanvas->FillRect(rc); + + pCanvas->Pen->Style = psDot; + int xx, y; + int fh = pCanvas->TextHeight("A"); + + switch(MainVARI->m_FFTVType){ + case 0: + pCanvas->Pen->Color = MainVARI->m_tFFTColset[3].c; + for( y = 6; y <= 86; y += 20 ){ + xx = y * m_fftYW / 100; + pCanvas->MoveTo(0, xx); pCanvas->LineTo(m_fftXW, xx); + } + break; + case 1: + pCanvas->Pen->Color = MainVARI->m_tFFTColset[3].c; + for( y = 6; y <= 66; y += 20 ){ + xx = y * m_fftYW / 60; + pCanvas->MoveTo(0, xx); pCanvas->LineTo(m_fftXW, xx); + } + break; + } + +#if 1 + pCanvas->Font->Height = -12; + pCanvas->Font->Color = MainVARI->m_tFFTColset[2].c; + pCanvas->Pen->Color = MainVARI->m_tFFTColset[3].c; + MainVARI->DrawFreqScale(pCanvas, m_fftXW, m_fftYW, 0, 3000, fh, FALSE); +#else + int A, L; + A = 500; L = 500; + f = 0; + int f, fw; + char bf[128]; + pCanvas->Font->Height = -12; + pCanvas->Font->Color = MainVARI->m_tFFTColset[2].c; + pCanvas->Pen->Color = MainVARI->m_tFFTColset[3].c; + y = 0; + for( ; f < 3000; f += A ){ + xx = f * m_fftXW / 3000; + if( xx >= m_fftXW ) break; + if( !(f % 1000) || !(f % L) ){ + sprintf(bf, "%u", f); + fw = pCanvas->TextWidth(bf)/2; + if( (xx - fw) > 0 ) pCanvas->TextOut(xx - fw, y, bf); +// pCanvas->MoveTo(xx, y ? 0 : fh); pCanvas->LineTo(xx, y ? m_fftYW-fh : m_fftYW); + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + } + else { + pCanvas->MoveTo(xx, 0); pCanvas->LineTo(xx, m_fftYW); + } + } +#endif + pCanvas->Pen->Color = clGreen; + xx = (DEMSAMPFREQ*0.5) * m_fftXW / 3000; + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + int rfo = m_ToneFreq; + pCanvas->Pen->Style = psSolid; + pCanvas->Pen->Color = MainVARI->m_tFFTColset[4].c; + xx = 0.5 + rfo * m_fftXW / 3000; + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + POINT pt[4]; + pt[0].x = xx; pt[0].y = fh; + pt[1].x = xx - 3; pt[1].y = fh+3; + pt[2].x = xx; pt[2].y = fh + 6; + pt[3].x = xx + 3; pt[3].y = fh+3; + pCanvas->Brush->Color = MainVARI->m_tFFTColset[4].c; + pCanvas->Polygon(pt, 3); + + if( !fClear ){ + pCanvas->Pen->Style = psSolid; + pCanvas->Pen->Color = MainVARI->m_tFFTColset[1].c; + + double k = double(PBoxFFT->Height)/double(MainVARI->PBoxFFT->Height); + int *pFFT = MainVARI->m_fftout; + int xo = 0; + int x, y; + if( MainVARI->m_FFTVType == 1 ){ + int yo = m_fftYW * 40; + for( x = 0; x < m_fftXW; x++ ){ + xx = xo + (x * m_FFTWindow / m_fftXW); + y = pFFT[xx] * k; + y = m_fftYW - ((y-yo)/60); + if( x ){ + pCanvas->LineTo(x, y); + } + else { + pCanvas->MoveTo(x, y); + } + } + } + else { + for( x = 0; x < m_fftXW; x++ ){ + xx = xo + (x * m_FFTWindow / m_fftXW); + y = pFFT[xx] * k; + y = m_fftYW - (y/100); + if( x ){ + pCanvas->LineTo(x, y); + } + else { + pCanvas->MoveTo(x, y); + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::UpdateFFT(void) +{ + DrawFFT(FALSE); + PBoxFFTPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PBoxTPaint(TObject *Sender) +{ + PBoxT->Canvas->Draw(0, 0, m_pBitmapT); + DrawCursor(); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PBoxFFTPaint(TObject *Sender) +{ + PBoxFFT->Canvas->Draw(0, 0, m_pBitmapFFT); + MainVARI->DrawErrorMsg(PBoxFFT->Canvas, m_fftXW, m_fftYW, FALSE); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PCFFTResize(TObject *Sender) +{ + m_pBitmapFFT->Width = PBoxFFT->Width; + m_pBitmapFFT->Height = PBoxFFT->Height; + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + pCanvas->Brush->Color = MainVARI->m_tFFTColset[0].c; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_pBitmapFFT->Width; + rc.Bottom = m_pBitmapFFT->Height; + pCanvas->FillRect(rc); + m_fftXW = m_pBitmapFFT->Width; + m_fftYW = m_pBitmapFFT->Height; + DrawFFT(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PCTResize(TObject *Sender) +{ + BOOL f = m_pBitmapT->Width != PBoxT->Width; + + m_pBitmapT->Width = PBoxT->Width; + m_pBitmapT->Height = PBoxT->Height; + if( f ){ + TCanvas *pCanvas = m_pBitmapT->Canvas; + pCanvas->Brush->Color = clBlack; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_pBitmapT->Width; + rc.Bottom = m_pBitmapT->Height; + pCanvas->FillRect(rc); + + m_Clock.Create(PBoxT->Width); + DrawMsg(); + m_PointRX = 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::SBSetClick(TObject *Sender) +{ + MainVARI->SetSampleFreq(m_SampFreq, FALSE); + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::UdClockClick(TObject *Sender, + TUDBtnType Button) +{ + double f; + sscanf(AnsiString(EditClock->Text).c_str(), "%lf", &f); //JA7UDE 0428 + if( Button == Comctrls::btNext ){ + f += 0.01; + } + else { + f -= 0.01; + } + char bf[128]; + sprintf(bf, "%.2lf", f); + EditClock->Text = bf; + m_SampFreq = f; + m_Clock.SetSampleFreq(f); + UpdatePPM(); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::DrawMessage(LPCSTR p) +{ + TCanvas *pCanvas = PBoxT->Canvas; + int xr = pCanvas->TextWidth(p); + int xl = (PBoxT->Width - xr)/2; + xr += xl; + int FH = pCanvas->TextHeight(p); + int VC = PBoxT->Height - FH; + pCanvas->Pen->Color = clWhite; + pCanvas->Brush->Color = clBlack; + pCanvas->RoundRect(xl-10, VC-FH, xr+10, VC+FH, 10, 10); + pCanvas->Font->Color = clWhite; + pCanvas->TextOut(xl, VC-FH/2, p); +} +//--------------------------------------------------------------------------- +double __fastcall TClockAdjDlg::GetPointSamp(void) +{ + if( m_PointY == m_PointY2 ) return m_SampFreq; + double d = (m_PointX2 - m_PointX); + d = d * m_SampFreq / PBoxT->Width; + d /= (m_PointY - m_PointY2); + d += m_SampFreq; + d = int(d * 100 + 0.5) * 0.01; + return d; +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::DrawCursor(void) +{ + TCanvas *pCanvas = PBoxT->Canvas; + pCanvas->Pen->Color = clLime; + pCanvas->Pen->Style = psDot; + pCanvas->MoveTo(m_CursorX, 0); + int rop = ::SetROP2(pCanvas->Handle, R2_MASKPENNOT); + pCanvas->LineTo(m_CursorX, PBoxT->Height - 1); + ::SetROP2(pCanvas->Handle, rop); + if( m_Point ){ + pCanvas->Pen->Color = clYellow; + pCanvas->Pen->Style = psSolid; + pCanvas->MoveTo(m_PointX, m_PointY); + ::SetROP2(pCanvas->Handle, R2_MASKPENNOT); + pCanvas->LineTo(m_PointX2, m_PointY2); + ::SetROP2(pCanvas->Handle, rop); + char bf[256]; + if( sys.m_MsgEng ){ + sprintf( bf, "OK : Left button, Cancel : Right button Clock=%.2lf", GetPointSamp()); + } + else { + sprintf( bf, "決定 : 左ボタン, 中止 : 右ボタン Clock=%.2lf", GetPointSamp()); + } + DrawMessage(bf); + if( PBoxT->Cursor != crCross ) PBoxT->Cursor = crCross; + } + else { + if( PBoxT->Cursor != crDefault ) PBoxT->Cursor = crDefault; + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PBoxTMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbLeft ){ + if( m_Point ){ + m_Point = 0; + if( m_PointY2 != m_PointY ){ + m_SampFreq = GetPointSamp(); + char bf[256]; + sprintf(bf, "%.2lf", m_SampFreq); + EditClock->Text = bf; + m_Clock.SetSampleFreq(m_SampFreq); + UpdatePPM(); + + TRect rc; + rc.Left = 0; rc.Right = m_pBitmapT->Width; + rc.Top = 0; + rc.Bottom = m_PointRX; + TCanvas *pCanvas = m_pBitmapT->Canvas; + pCanvas->Brush->Color = clBlack; + pCanvas->FillRect(rc); + m_PointRX = 0; + } + } + else { + m_PointX2 = m_PointX = X; + m_PointY2 = m_PointY = Y; + m_Point = 1; + } + } + else if( m_Point ){ + m_Point = 0; + } + else { + m_CursorX = X; + } + PBoxTPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::PBoxTMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_Point ){ + m_PointX2 = X; + m_PointY2 = Y; + PBoxTPaint(NULL); + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::CreateWaterColors(void) +{ + UCOL col[3]; + col[0].c = clBlack; + col[1].c = clWhite; + col[2].c = clYellow; + int i; + UCOL c; + for( i = 0; i < 160; i++ ){ + c = GetGrade2(col, i, 160); + m_tWaterColors[i] = c.c; + } + for( i = 0; i < 96; i++ ){ + c = GetGrade2(&col[1], i, 96); + m_tWaterColors[i+160] = c.c; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TClockAdjDlg::CBToneChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + int f; + sscanf(AnsiString(CBTone->Text).c_str(), "%d", &f); //JA7UDE 0428 + if( (f >= 250) && (f <= 2700) ){ + SetToneFreq(f); + } +} +//--------------------------------------------------------------------------- +void __fastcall TClockAdjDlg::SetToneFreq(int f) +{ + if( f < 250 ) f = 250; + if( f > 2700 ) f = 2700; + m_ToneFreq = f; + m_Clock.SetToneFreq(m_ToneFreq); + m_fDisEvent++; + CBTone->Text = m_ToneFreq; + m_fDisEvent--; +} +//--------------------------------------------------------------------------- + +void __fastcall TClockAdjDlg::PBoxFFTMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button != mbLeft ) return; + + SetToneFreq((X * 3000) / PBoxFFT->Width); + m_MouseDown = 1; +} +//--------------------------------------------------------------------------- + +void __fastcall TClockAdjDlg::PBoxFFTMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_MouseDown ){ + SetToneFreq((X * 3000) / PBoxFFT->Width); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TClockAdjDlg::PBoxFFTMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + m_MouseDown = FALSE; +} +//--------------------------------------------------------------------------- + diff --git a/ClockAdj.dfm b/ClockAdj.dfm new file mode 100644 index 0000000..b73cfd8 Binary files /dev/null and b/ClockAdj.dfm differ diff --git a/ClockAdj.h b/ClockAdj.h new file mode 100644 index 0000000..24b2c44 --- /dev/null +++ b/ClockAdj.h @@ -0,0 +1,123 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef ClockAdjH +#define ClockAdjH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include + +//--------------------------------------------------------------------------- +#include "ComLib.h" +#include "dsp.h" +//--------------------------------------------------------------------------- +class TClockAdjDlg : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *PCFFT; + TPanel *PCT; + TLabel *L1; + TEdit *EditClock; + TLabel *L2; + TUpDown *UdClock; + TSpeedButton *SBClose; + TPaintBox *PBoxFFT; + TPaintBox *PBoxT; + TPanel *PCC; + TSplitter *Splitter; + TSpeedButton *SBSet; + TComboBox *CBTone; + TLabel *L3; + TLabel *L4; + TLabel *LPPM; + void __fastcall SBCloseClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormResize(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall PBoxTPaint(TObject *Sender); + void __fastcall PBoxFFTPaint(TObject *Sender); + void __fastcall PCFFTResize(TObject *Sender); + void __fastcall PCTResize(TObject *Sender); + void __fastcall SBSetClick(TObject *Sender); + void __fastcall UdClockClick(TObject *Sender, TUDBtnType Button); + void __fastcall PBoxTMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall PBoxTMouseMove(TObject *Sender, TShiftState Shift, int X, + int Y); + void __fastcall CBToneChange(TObject *Sender); + void __fastcall PBoxFFTMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall PBoxFFTMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall PBoxFFTMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); +private: // ユーザー宣言 + int m_fDisEvent; + + double m_SampFreq; + double m_ToneFreq; + CClock m_Clock; + + TColor m_tWaterColors[256]; + Graphics::TBitmap *m_pBitmapT; + FFTSTG m_StgT; + + int m_CursorX; + int m_Point; + int m_PointX, m_PointY; + int m_PointX2, m_PointY2; + int m_PointRX; + + int m_fftXW, m_fftYW; + Graphics::TBitmap *m_pBitmapFFT; + int m_FFTWindow; + + int m_MouseDown; +private: + void __fastcall UpdatePPM(void); + void __fastcall CreateWaterColors(void); + void __fastcall DrawMsg(void); + void __fastcall InitWater(void); + void __fastcall DrawFFT(BOOL fClear); + + double __fastcall GetPointSamp(void); + void __fastcall DrawMessage(LPCSTR p); + void __fastcall DrawCursor(void); + void __fastcall SetToneFreq(int f); + + +public: // ユーザー宣言 + __fastcall TClockAdjDlg(TComponent* Owner); + + void __fastcall Execute(void); + void __fastcall Do(short ds); + void __fastcall UpdateFFT(void); +}; +//--------------------------------------------------------------------------- +//extern PACKAGE TClockAdjDlg *ClockAdjDlg; +//--------------------------------------------------------------------------- +#endif + diff --git a/CodeVw.cpp b/CodeVw.cpp new file mode 100644 index 0000000..f73aab4 --- /dev/null +++ b/CodeVw.cpp @@ -0,0 +1,409 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "CodeVw.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//TCodeView *CodeView; +//--------------------------------------------------------------------------- +__fastcall TCodeView::TCodeView(TComponent* Owner) + : TForm(Owner) +{ + if( sys.m_MsgEng ){ + Font->Name = "Arial"; + Font->Charset = ANSI_CHARSET; + SBClose->Caption = "Close"; + } + SBUS->Hint = "English(ANSI)"; + SBJA->Hint = sys.m_MsgEng ? "Japanese(Shift-JIS)" : "日本語(シフトJIS)"; + SBHL->Hint = sys.m_MsgEng ? "Korean(Hangul)" : "韓国語(ハングル)"; + SBBY->Hint = sys.m_MsgEng ? "Chinese(GB2312)" : "中国語(簡体)"; + SBBV->Hint = sys.m_MsgEng ? "Chinese(BIG5)" : "中国語(繁体)"; + m_hWnd = NULL; + m_pFont = NULL; + m_Base = 0; + m_MouseDown = 0; + CheckFontCharset(); + SBJA->Enabled = sys.m_tFontFam[fmJA]; + SBHL->Enabled = sys.m_tFontFam[fmHL] || sys.m_tFontFam[fmJOHAB]; + SBBV->Enabled = sys.m_tFontFam[fmBV]; + SBBY->Enabled = sys.m_tFontFam[fmBY]; + + UpdateXW(); +#if 0 + int YW = GetSystemMetrics(SM_CYFULLSCREEN); + Left = sys.m_CodeLeft; + Top = sys.m_CodeTop; + if( Left < 0 ) Left = 0; + if( Top + Height > YW ) Top = YW - Height; +#endif + ShowHint = sys.m_WinNT; + FormCenter(this); +} +//--------------------------------------------------------------------------- +WORD __fastcall TCodeView::GetEUDC(int y, int x) +{ +const WORD _tOut[]={0xf040, 0xf050, 0xf060, 0xf070, + 0xf080, 0xf090, 0xf0a0, 0xf0b0, + 0xf0c0, 0xf0d0, 0xf0e0, 0xf0f0, + 0xf140, 0xf150, 0xf160, 0xf170, +}; +const WORD _tOutHL[]={0xc9a0, 0xc9b0, 0xc9c0, 0xc9d0, + 0xc9e0, 0xc9f0, 0xfea0, 0xfeb0, + 0xfec0, 0xfed0, 0xfee0, 0xfef0, + 0, 0, 0, 0, +}; +const WORD _tOutBV[]={0xfa40, 0xfa50, 0xfa60, 0xfa70, + 0xfaa0, 0xfab0, 0xfac0, 0xfad0, + 0xfae0, 0xfaf0, 0xfb40, 0xfb50, + 0xfb60, 0xfb70, 0xfba0, 0xfbb0, +}; +const WORD _tOutBY[]={0xaaa0, 0xaab0, 0xaac0, 0xaad0, + 0xaae0, 0xaaf0, 0xaba0, 0xabb0, + 0xabc0, 0xabd0, 0xabe0, 0xabf0, + 0xaca0, 0xacb0, 0xacc0, 0xacd0, +}; + int c; + switch(m_pFont->Charset){ + case SHIFTJIS_CHARSET: + c = _tOut[y] + x; + if( (c==0xf07f)||(c==0xf0fd)||(c==0xf0fe)||(c==0xf0ff)||(c==0xf17f) ) c = 0; + break; + case HANGEUL_CHARSET: + c = _tOutHL[y]; + if( c ){ + c += x; + if( (c==0xc9a0)||(c==0xfea0)||(c==0xc9ff)||(c==0xfeff) ) c = 0; + } + break; + case CHINESEBIG5_CHARSET: // 台湾 + c = _tOutBV[y] + x; + if( (c==0xfa7f)||(c==0xfaa0)||(c==0xfaff)||(c==0xfb7f)||(c==0xfba0) ) c = 0; + break; + case 134: // 中国語簡略 + c = _tOutBY[y] + x; + if( (c==0xaaa0)||(c==0xaaff)||(c==0xaba0)||(c==0xabff)||(c==0xaca0) ) c = 0; + break; + default: + c = 0; + break; + } + return WORD(c); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::UpdateTitle(void) +{ + AnsiString as = sys.m_MsgEng ? "Character code list" : "Character Code list"; //AA6YQ 2013-05-25 removed JA characters + as += " ["; + as += m_pFont->Name; + AddStyle(as, m_pFont->Charset, 0); + as += "]"; + Caption = as; +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::UpdateXW(void) +{ + if( m_Base ){ + m_XW = PBox->Width / 17; + m_XW--; + m_YW1 = m_YW = PBox->Height / 17; + m_XW1 = PBox->Width - (m_XW * 16); + UDMB->Visible = m_Base ? TRUE : FALSE; + } + else { + m_XW1 = m_XW = PBox->Width / 17; + m_YW1 = m_YW = PBox->Height / 17; + UDMB->Visible = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::SetPBoxFont(TCanvas *pCanvas) +{ + pCanvas->Font = m_pFont; + pCanvas->Font->Height = -(m_YW-5); + TFontStyles fs; + fs = Code2FontStyle(0); + pCanvas->Font->Style = fs; +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::DrawChar(TCanvas *pCanvas, int c, BOOL f) +{ + + int x = c % 16; + int y = c / 16; + char bf[32]; + LPSTR t = bf; + if( c ){ + c += m_Base; + } + if( !c ) return; + if( c & 0x00ff00 ) *t++ = BYTE(c>>8); + *t++ = BYTE(c); + *t = 0; + pCanvas->Font->Color = f ? clWhite : clBlack; + int fw = pCanvas->TextWidth(bf); + int fh = pCanvas->TextHeight(bf); + int xx = m_XW1 + x * m_XW + (m_XW-fw)/2; + int yy = m_YW1 + y * m_YW + (m_YW-fh)/2; + ::SetBkMode(pCanvas->Handle, TRANSPARENT); + pCanvas->TextOut(xx, yy, bf); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::DrawCursor(TCanvas *pCanvas, int c, BOOL f) +{ + TRect rc; + + int x = c % 16; + int y = c / 16; + rc.Left = 1 + m_XW1 + x * m_XW; + rc.Top = 1 + m_YW1 + y * m_YW; + rc.Right = rc.Left + m_XW - 1; + rc.Bottom = rc.Top + m_YW - 1; + TColor col; + if( f ){ + col = clBlue; + } + else if( (!m_Base) && m_tPfx[c] ){ + col = clGray; + } + else { + col = clWhite; + } + pCanvas->Pen->Color = col; + pCanvas->Brush->Color = col; + pCanvas->FillRect(rc); + DrawChar(pCanvas, c, f); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::PBoxPaint(TObject *Sender) +{ + if( !m_pFont ) return; + + CWaitCursor w; + Graphics::TBitmap *pBmp = new Graphics::TBitmap; + pBmp->Width = PBox->Width; + pBmp->Height = PBox->Height; + TCanvas *pCanvas = pBmp->Canvas; + if( !m_Base ) memset(m_tPfx, 0, sizeof(m_tPfx)); + SetPBoxFont(pCanvas); + OnWave(); + SetMBCP(m_pFont->Charset); + int x, y, xx, yy, fw, fh; + char bf[16]; + int c = 0; + for( y = 0; y < 16; y++ ){ + OnWave(); + for( x = 0; x < 16; x++ ){ + if( !m_Base && (_mbsbtype((const unsigned char *)&c, 0) == _MBC_LEAD) ){ + m_tPfx[c] = TRUE; + DrawCursor(pCanvas, c, FALSE); + } + else { + DrawChar(pCanvas, c, FALSE); + } + c++; + } + } + pCanvas->Font = Font; + pCanvas->Pen->Color = clBlack; + ::SetBkMode(pCanvas->Handle, TRANSPARENT); + for( y = 0; y < 16; y++ ){ + wsprintf(bf, "%X", y); + fw = pCanvas->TextWidth(bf); + fh = pCanvas->TextHeight(bf); + xx = m_XW1 + y*m_XW + (m_XW-fw)/2; + yy = (m_YW1-fh)/2; + pCanvas->TextOut(xx, yy, bf); + + if( m_Base ){ + wsprintf(bf, "%04x", y*16 + m_Base); + } + else { + wsprintf(bf, "%02X", y*16); + } + fw = pCanvas->TextWidth(bf); + fh = pCanvas->TextHeight(bf); + xx = (m_XW1-fw)/2; + yy = m_YW1 + y*m_YW + (m_YW-fh)/2; + pCanvas->TextOut(xx, yy, bf); + + pCanvas->Pen->Width = y ? 1 : 2; + pCanvas->MoveTo(0, m_YW1 + y*m_YW); + pCanvas->LineTo(PBox->Width, m_YW1 + y*m_YW); + pCanvas->MoveTo(m_XW1 + y*m_XW, 0); + pCanvas->LineTo(m_XW1 + y*m_XW, PBox->Height); + } + PBox->Canvas->Draw(0, 0, pBmp); + delete pBmp; + m_pfxCount = 0; + for( x = 0; x < 256; x++ ){ + if( m_tPfx[x] ){ + m_tPfxIdx[m_pfxCount] = x; + m_pfxCount++; + } + } + if( m_pfxCount != UDMB->Max ) UDMB->Max = short(m_pfxCount - 1); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::UpdatePfx(void) +{ + memset(m_tPfx, 0, sizeof(m_tPfx)); + int c; + for( c = 0; c < 256; c++ ){ + if( _mbsbtype((const unsigned char *)&c, 0) == _MBC_LEAD ){ + m_tPfx[c] = TRUE; + } + } + m_pfxCount = 0; + for( c = 0; c < 256; c++ ){ + if( m_tPfx[c] ){ + m_tPfxIdx[m_pfxCount] = c; + m_pfxCount++; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::Execute(HWND hWnd, UINT uMsg, int wParam, TFont *pFont) +{ + m_hWnd = hWnd; + m_uMsg = uMsg; + m_wParam = wParam; + m_pFont = pFont; + m_Base = 0; + UpdateXW(); + UpdateTitle(); + ShowModal(); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::SBCloseClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::PBoxMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( (Button == mbRight) && (m_Base) ){ + if( m_Base ){ + m_Base = 0; + } + UpdateXW(); PBoxPaint(NULL); + return; + } + if( Button != mbLeft ) return; + + X -= m_XW1; + Y -= m_YW1; + if( X < 0 ) return; + if( Y < 0 ) return; + X /= m_XW; + Y /= m_YW; + if( X >= 16 ) X = 15; + if( Y >= 16 ) Y = 15; + int code = (Y * 16) + X; + m_MouseDown = code + 1; + TCanvas *pCanvas = PBox->Canvas; + SetPBoxFont(pCanvas); + DrawCursor(pCanvas, code, TRUE); + + if( m_Base ){ + code |= m_Base | 0x00010000; + } + else if( m_tPfx[code] ){ + for( int i = 0; i < m_pfxCount; i++ ){ + if( m_tPfxIdx[i] == code ){ + UDMB->Position = short(i); + break; + } + } + m_Base = (code << 8); + UpdateXW(); PBoxPaint(NULL); + m_MouseDown = FALSE; + return; + } + + if( m_hWnd ){ + m_Code = code & 0x0000ffff; + ::PostMessage(m_hWnd, m_uMsg, m_wParam, m_Code); + Timer->Interval = 500; + Timer->Enabled = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::PBoxMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( !m_MouseDown ) return; + + m_MouseDown--; + TCanvas *pCanvas = PBox->Canvas; + SetPBoxFont(pCanvas); + DrawCursor(pCanvas, m_MouseDown, FALSE); + m_MouseDown = 0; + Timer->Enabled = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::TimerTimer(TObject *Sender) +{ + if( m_MouseDown ){ + ::PostMessage(m_hWnd, m_uMsg, m_wParam, m_Code); + Timer->Interval = 100; + } +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::SBUSClick(TObject *Sender) +{ + WORD wLang; + if( Sender == SBJA ){ + wLang = 0x0411; + } + else if( Sender == SBHL ){ + wLang = 0x0412; + } + else if( Sender == SBBY ){ + wLang = 0x0804; + } + else if( Sender == SBBV ){ + wLang = 0x0404; + } + else { + wLang = 0; + } + SetLangFont(m_pFont, wLang); + PBox->Invalidate(); + UpdateTitle(); + if( m_hWnd ){ + ::PostMessage(m_hWnd, m_uMsg, m_wParam, 0x10000000); + } + SetMBCP(m_pFont->Charset); + UpdatePfx(); +} +//--------------------------------------------------------------------------- +void __fastcall TCodeView::UDMBClick(TObject *Sender, TUDBtnType Button) +{ + m_Base = m_tPfxIdx[UDMB->Position] << 8; + UpdateXW(); PBoxPaint(NULL); +} +//--------------------------------------------------------------------------- + diff --git a/CodeVw.dfm b/CodeVw.dfm new file mode 100644 index 0000000..b3656ef Binary files /dev/null and b/CodeVw.dfm differ diff --git a/CodeVw.h b/CodeVw.h new file mode 100644 index 0000000..da909ce --- /dev/null +++ b/CodeVw.h @@ -0,0 +1,91 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef CodeVwH +#define CodeVwH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include + +#include "ComLib.h" +#include +#define WM_FORMCLOSE (WM_USER+410) +#define WM_CODEINSERT (WM_USER+411) +//--------------------------------------------------------------------------- +class TCodeView : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *Panel; + TPaintBox *PBox; + TSpeedButton *SBClose; + TSpeedButton *SBUS; + TSpeedButton *SBJA; + TSpeedButton *SBHL; + TSpeedButton *SBBY; + TSpeedButton *SBBV; + TUpDown *UDMB; + TTimer *Timer; + void __fastcall PBoxPaint(TObject *Sender); + void __fastcall SBCloseClick(TObject *Sender); + void __fastcall PBoxMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall SBUSClick(TObject *Sender); + void __fastcall UDMBClick(TObject *Sender, TUDBtnType Button); + void __fastcall PBoxMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + void __fastcall TimerTimer(TObject *Sender); +private: // ユーザー宣言 + HWND m_hWnd; + UINT m_uMsg; + int m_wParam; + + TFont *m_pFont; + int m_Code; + int m_XW1; + int m_YW1; + int m_XW; + int m_YW; + int m_MouseDown; + int m_Base; + BOOL m_tPfx[256]; + int m_pfxCount; + int m_tPfxIdx[256]; + void __fastcall UpdateTitle(void); + void __fastcall UpdatePfx(void); + void __fastcall UpdateXW(void); + void __fastcall SetPBoxFont(TCanvas *pCanvas); + void __fastcall DrawChar(TCanvas *pCanvas, int c, BOOL f); + void __fastcall DrawCursor(TCanvas *pCanvas, int c, BOOL f); + WORD __fastcall GetEUDC(int y, int x); + +public: // ユーザー宣言 + __fastcall TCodeView(TComponent* Owner); + + void __fastcall Execute(HWND hWnd, UINT uMsg, int wParam, TFont *pFont); +}; +//--------------------------------------------------------------------------- +//extern PACKAGE TCodeView *CodeView; +//--------------------------------------------------------------------------- +#endif diff --git a/ComFSK.fsk b/ComFSK.fsk new file mode 100644 index 0000000..088e734 Binary files /dev/null and b/ComFSK.fsk differ diff --git a/ComLib.cpp b/ComLib.cpp new file mode 100644 index 0000000..f27a4c9 --- /dev/null +++ b/ComLib.cpp @@ -0,0 +1,3702 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ComLib.h" +#include "LogFile.h" +#include "main.h" +//--------------------------------------------------------------------------- +//char g_MMLogDir[256]; + +SYSSET sys; // システム共通データ + +//LPCSTR g_tLogModeTable[]={"GMSK", "FSK", "FSK", "PSK", "PSK", "PSK", "PSK", "RTTY", "RTTY", "MFSK", "MFSK", NULL}; +//LPCSTR g_tDispModeTable[]={"GMSK", "FSK", "FSK-W", "BPSK", "2PSK-L", "2PSK-U", "bpsk", "rtty-L", "rtty-U", "mfsk-L", "mfsk-U", NULL}; +const LPCSTR g_tLogModeTable[]={"GMSK", "FSK", "FSK", "PSK", "PSK", "RTTY", "RTTY", "MFSK", "MFSK", "QPSK", "QPSK", NULL}; +const LPCSTR g_tDispModeTable[]={"GMSK", "FSK", "FSK-W", "BPSK", "bpsk", "rtty-L", "rtty-U", "mfsk-L", "mfsk-U", "qpsk-L", "qpsk-U", NULL}; +const LPCSTR g_tMacEvent[]={"OnTimer","OnPTT","OnQSO","OnFind", "OnBand", "OnStart", "OnExit", "OnMode", "OnSpeed", "OnClick", "OnFFTScale"}; +const LPCSTR g_tSoundCH[]={"MONO","LEFT","RIGHT"}; +const LPCSTR g_tOnOff[]={"OFF", "ON", "ONOFF"}; +//--------------------------------------------------------------------------- +void __fastcall OnWave(void) +{ + MainVARI->OnWave(); +} +//--------------------------------------------------------------------------- +int __fastcall FindStringTableStrictly(const LPCSTR _tt[], LPCSTR pName, int max) +{ + int n; + for( n = 0; (n < max) && (_tt[n]!=NULL); n++ ){ + if( !strcmp(_tt[n], pName) ) return n; + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall FindStringTable(const LPCSTR _tt[], LPCSTR pName, int max) +{ + int n; + for( n = 0; (n < max) && (_tt[n]!=NULL); n++ ){ + if( !strcmpi(_tt[n], pName) ) return n; + } + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall GetModeIndex(LPCSTR pName) +{ + int m; + for( m = 0; g_tDispModeTable[m] && (m < MODE_END); m++ ){ + if( !strcmp(g_tDispModeTable[m], pName) ) return m; + } + if( sscanf(pName, "%d", &m) == 1 ){ + if( m < 0 ) m = 0; + if( m >= MODE_END ) m = MODE_END - 1; + } + else { + m = 0; + } + return m; +} + +const DEFKEYTBL KEYTBL[]={ + { VK_F1, "F1" }, + { VK_F2, "F2" }, + { VK_F3, "F3" }, + { VK_F4, "F4" }, + { VK_F5, "F5" }, + { VK_F6, "F6" }, + { VK_F7, "F7" }, + { VK_F8, "F8" }, + { VK_F9, "F9" }, + { VK_F10, "F10" }, + { VK_F11, "F11" }, + { VK_F12, "F12" }, + + { VK_LEFT, "←"}, + { VK_RIGHT, "→"}, + { VK_UP, "↑"}, + { VK_DOWN, "↓"}, + { VK_PRIOR, "PageUp"}, + { VK_NEXT, "PageDown"}, + { VK_HOME, "Home" }, + { VK_END, "End" }, + { VK_INSERT, "Insert" }, + { VK_DELETE, "Delete" }, + { VK_HELP, "Help" }, + { VK_ESCAPE, "ESC" }, + { VK_PAUSE, "PAUSE" }, + + + { VK_F1 | 0x400, "Shift+F1" }, + { VK_F2 | 0x400, "Shift+F2" }, + { VK_F3 | 0x400, "Shift+F3" }, + { VK_F4 | 0x400, "Shift+F4" }, + { VK_F5 | 0x400, "Shift+F5" }, + { VK_F6 | 0x400, "Shift+F6" }, + { VK_F7 | 0x400, "Shift+F7" }, + { VK_F8 | 0x400, "Shift+F8" }, + { VK_F9 | 0x400, "Shift+F9" }, + { VK_F10 | 0x400, "Shift+F10" }, + { VK_F11 | 0x400, "Shift+F11" }, + { VK_F12 | 0x400, "Shift+F12" }, + + { VK_LEFT | 0x400, "Shift+←"}, + { VK_RIGHT | 0x400, "Shift+→"}, + { VK_UP | 0x400, "Shift+↑"}, + { VK_DOWN | 0x400, "Shift+↓"}, + { VK_PRIOR | 0x400, "Shift+PageUp"}, + { VK_NEXT | 0x400, "Shift+PageDown"}, + { VK_HOME | 0x400, "Shift+Home" }, + { VK_END | 0x400, "Shift+End" }, + { VK_INSERT | 0x400, "Shift+Insert" }, + { VK_DELETE | 0x400, "Shift+Delete" }, + { VK_HELP | 0x400, "Shift+Help" }, + { VK_ESCAPE | 0x400, "Shift+ESC" }, + { VK_PAUSE | 0x400, "Shift+PAUSE" }, + + { VK_F1 | 0x100, "Ctrl+F1" }, + { VK_F2 | 0x100, "Ctrl+F2" }, + { VK_F3 | 0x100, "Ctrl+F3" }, + { VK_F4 | 0x100, "Ctrl+F4" }, + { VK_F5 | 0x100, "Ctrl+F5" }, + { VK_F6 | 0x100, "Ctrl+F6" }, + { VK_F7 | 0x100, "Ctrl+F7" }, + { VK_F8 | 0x100, "Ctrl+F8" }, + { VK_F9 | 0x100, "Ctrl+F9" }, + { VK_F10 | 0x100, "Ctrl+F10" }, + { VK_F11 | 0x100, "Ctrl+F11" }, + { VK_F12 | 0x100, "Ctrl+F12" }, + { '1' | 0x100, "Ctrl+1" }, + { '2' | 0x100, "Ctrl+2" }, + { '3' | 0x100, "Ctrl+3" }, + { '4' | 0x100, "Ctrl+4" }, + { '5' | 0x100, "Ctrl+5" }, + { '6' | 0x100, "Ctrl+6" }, + { '7' | 0x100, "Ctrl+7" }, + { '8' | 0x100, "Ctrl+8" }, + { '9' | 0x100, "Ctrl+9" }, + { '0' | 0x100, "Ctrl+0" }, + { 'A' | 0x100, "Ctrl+A" }, + { 'B' | 0x100, "Ctrl+B" }, + { 'C' | 0x100, "Ctrl+C" }, + { 'D' | 0x100, "Ctrl+D" }, + { 'E' | 0x100, "Ctrl+E" }, + { 'F' | 0x100, "Ctrl+F" }, + { 'G' | 0x100, "Ctrl+G" }, +// { 'H' | 0x100, "Ctrl+H" }, +// { 'I' | 0x100, "Ctrl+I" }, + { 'K' | 0x100, "Ctrl+K" }, + { 'L' | 0x100, "Ctrl+L" }, +// { 'M' | 0x100, "Ctrl+M" }, + { 'N' | 0x100, "Ctrl+N" }, + { 'O' | 0x100, "Ctrl+O" }, + { 'P' | 0x100, "Ctrl+P" }, + { 'Q' | 0x100, "Ctrl+Q" }, + { 'R' | 0x100, "Ctrl+R" }, + { 'S' | 0x100, "Ctrl+S" }, + { 'T' | 0x100, "Ctrl+T" }, + { 'U' | 0x100, "Ctrl+U" }, + { 'V' | 0x100, "Ctrl+V" }, + { 'W' | 0x100, "Ctrl+W" }, + { 'X' | 0x100, "Ctrl+X" }, + { 'Y' | 0x100, "Ctrl+Y" }, + { 'Z' | 0x100, "Ctrl+Z" }, + + { VK_LEFT | 0x100, "Ctrl+←"}, + { VK_RIGHT | 0x100, "Ctrl+→"}, + { VK_UP | 0x100, "Ctrl+↑"}, + { VK_DOWN | 0x100, "Ctrl+↓"}, + { VK_PRIOR | 0x100, "Ctrl+PageUp"}, + { VK_NEXT | 0x100, "Ctrl+PageDown"}, + { VK_HOME | 0x100, "Ctrl+Home" }, + { VK_END | 0x100, "Ctrl+End" }, + { VK_INSERT | 0x100, "Ctrl+Insert" }, + { VK_DELETE | 0x100, "Ctrl+Delete" }, + { VK_HELP | 0x100, "Ctrl+Help" }, + { VK_ESCAPE | 0x100, "Ctrl+ESC" }, + + { VK_F1 | 0x200, "Alt+F1" }, + { VK_F2 | 0x200, "Alt+F2" }, + { VK_F3 | 0x200, "Alt+F3" }, + { VK_F4 | 0x200, "Alt+F4" }, + { VK_F5 | 0x200, "Alt+F5" }, + { VK_F6 | 0x200, "Alt+F6" }, + { VK_F7 | 0x200, "Alt+F7" }, + { VK_F8 | 0x200, "Alt+F8" }, + { VK_F9 | 0x200, "Alt+F9" }, + { VK_F10 | 0x200, "Alt+F10" }, + { VK_F11 | 0x200, "Alt+F11" }, + { VK_F12 | 0x200, "Alt+F12" }, + { '1' | 0x200, "Alt+1" }, + { '2' | 0x200, "Alt+2" }, + { '3' | 0x200, "Alt+3" }, + { '4' | 0x200, "Alt+4" }, + { '5' | 0x200, "Alt+5" }, + { '6' | 0x200, "Alt+6" }, + { '7' | 0x200, "Alt+7" }, + { '8' | 0x200, "Alt+8" }, + { '9' | 0x200, "Alt+9" }, + { '0' | 0x200, "Alt+0" }, + { 'A' | 0x200, "Alt+A" }, + { 'B' | 0x200, "Alt+B" }, + { 'C' | 0x200, "Alt+C" }, + { 'D' | 0x200, "Alt+D" }, + { 'E' | 0x200, "Alt+E" }, + { 'F' | 0x200, "Alt+F" }, + { 'G' | 0x200, "Alt+G" }, + { 'H' | 0x200, "Alt+H" }, + { 'I' | 0x200, "Alt+I" }, + { 'K' | 0x200, "Alt+K" }, + { 'L' | 0x200, "Alt+L" }, + { 'M' | 0x200, "Alt+M" }, + { 'N' | 0x200, "Alt+N" }, + { 'O' | 0x200, "Alt+O" }, + { 'P' | 0x200, "Alt+P" }, + { 'Q' | 0x200, "Alt+Q" }, + { 'R' | 0x200, "Alt+R" }, + { 'S' | 0x200, "Alt+S" }, + { 'T' | 0x200, "Alt+T" }, + { 'U' | 0x200, "Alt+U" }, + { 'V' | 0x200, "Alt+V" }, + { 'W' | 0x200, "Alt+W" }, + { 'X' | 0x200, "Alt+X" }, + { 'Y' | 0x200, "Alt+Y" }, + { 'Z' | 0x200, "Alt+Z" }, + + { VK_LEFT | 0x200, "Alt+←"}, + { VK_RIGHT | 0x200, "Alt+→"}, + { VK_UP | 0x200, "Alt+↑"}, + { VK_DOWN | 0x200, "Alt+↓"}, + { VK_PRIOR | 0x200, "Alt+PageUp"}, + { VK_NEXT | 0x200, "Alt+PageDown"}, + { VK_HOME | 0x200, "Alt+Home" }, + { VK_END | 0x200, "Alt+End" }, + { VK_INSERT | 0x200, "Alt+Insert" }, + { VK_DELETE | 0x200, "Alt+Delete" }, + { VK_HELP | 0x200, "Alt+Help" }, + { VK_ESCAPE | 0x200, "Alt+ESC" }, + { VK_PAUSE | 0x200, "Alt+PAUSE" }, + { 0, "" }, +}; +//--------------------------------------------------------------------------- +LPCSTR __fastcall ToDXKey(LPCSTR s) +{ + if( sys.m_MsgEng && *s ){ + LPSTR p; + static char bf[32]; + strcpy(bf, s); + if( (p = strstr(bf, "←"))!=NULL ){ + strcpy(p, "ArrowLeft"); + return bf; + } + else if( (p = strstr(bf, "→"))!=NULL ){ + strcpy(p, "ArrowRight"); + return bf; + } + else if( (p = strstr(bf, "↓"))!=NULL ){ + strcpy(p, "ArrowDown"); + return bf; + } + else if( (p = strstr(bf, "↑"))!=NULL ){ + strcpy(p, "ArrowUp"); + return bf; + } + } + return s; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall ToJAKey(LPCSTR s) +{ + if( sys.m_MsgEng && *s ){ + LPSTR p; + static char bf[32]; + strcpy(bf, s); + if( (p = strstr(bf, "ArrowLeft"))!=NULL ){ + strcpy(p, "←"); + return bf; + } + else if( (p = strstr(bf, "ArrowRight"))!=NULL ){ + strcpy(p, "→"); + return bf; + } + else if( (p = strstr(bf, "ArrowDown"))!=NULL ){ + strcpy(p, "↓"); + return bf; + } + else if( (p = strstr(bf, "ArrowUp"))!=NULL ){ + strcpy(p, "↑"); + return bf; + } + } + return s; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall GetKeyName(WORD Key) +{ + int i; + for( i = 0; KEYTBL[i].Key; i++ ){ + if( Key == KEYTBL[i].Key ){ + break; + } + } + return ToDXKey(KEYTBL[i].pName); +} +//--------------------------------------------------------------------------- +WORD __fastcall GetKeyCode(LPCSTR pName) +{ + LPCSTR p = ToJAKey(pName); + int i; + for( i = 0; KEYTBL[i].Key; i++ ){ + if( !strcmp(p, KEYTBL[i].pName) ) break; + } + return KEYTBL[i].Key; +} + +//--------------------------------------------------------------------------- +int __fastcall IsFile(LPCSTR pName) +{ + if( !pName || !*pName ) return 0; + FILE *fp; + fp = fopen(pName, "rb"); + if( fp != NULL ){ + fclose(fp); + return 1; + } + else { + return 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall SetTimeOffsetInfo(int &Hour, int &Min) +{ + TIME_ZONE_INFORMATION tz; + + int off; + switch(GetTimeZoneInformation(&tz)){ + case TIME_ZONE_ID_STANDARD: + off = tz.StandardBias; + break; + case TIME_ZONE_ID_DAYLIGHT: + off = tz.DaylightBias; + break; + default: + return FALSE; + } + if( off >= 0 ){ + Hour = -(off / 60); + Min = (off % 60); + } + else { + off = -off; + Hour = off / 60; + Min = off % 60; + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall AddjustOffset(SYSTEMTIME *tp) +{ + if( sys.m_TimeOffset || sys.m_TimeOffsetMin ){ +//typedef struct _SYSTEMTIME { /* st */ +// WORD wYear; +// WORD wMonth; +// WORD wDayOfWeek; +// WORD wDay; +// WORD wHour; +// WORD wMinute; +// WORD wSecond; +// WORD wMilliseconds; +//} SYSTEMTIME; + + + LPCSTR mt; + int Hour = tp->wHour; + int Min = tp->wMinute; + Min += sys.m_TimeOffsetMin; + if( Min >= 60 ){ + Hour++; + Min -= 60; + } + else if( Min < 0 ){ + Hour--; + Min += 60; + } + tp->wMinute = WORD(Min); + Hour += sys.m_TimeOffset; + if( Hour >= 24 ){ + tp->wHour = WORD(Hour - 24); + tp->wDay++; + if( tp->wYear % 4 ){ + mt = MONN; + } + else { + mt = MONU; + } + if( tp->wDay > mt[tp->wMonth] ){ + tp->wDay = 1; + tp->wMonth++; + if( tp->wMonth > 12 ){ + tp->wMonth = 1; + tp->wYear++; + } + } + } + else if( Hour < 0 ){ + tp->wHour = WORD(Hour + 24); + tp->wDay--; + if( tp->wDay < 1 ){ + tp->wMonth--; + if( tp->wMonth < 1 ){ + tp->wMonth = 12; + tp->wYear--; + } + if( tp->wYear % 4 ){ + tp->wDay = MONN[tp->wMonth]; + } + else { + tp->wDay = MONU[tp->wMonth]; + } + } + } + else { + tp->wHour = WORD(Hour); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall GetUTC(SYSTEMTIME *tp) +{ + ::GetSystemTime(tp); + AddjustOffset(tp); +} +//--------------------------------------------------------------------------- +void __fastcall GetLocal(SYSTEMTIME *tp) +{ + ::GetLocalTime(tp); + AddjustOffset(tp); +} +//--------------------------------------------------------------------------- +void __fastcall LimitInt(int *pInt, int min, int max) +{ + if( *pInt < min ) *pInt = min; + if( *pInt > max ) *pInt = max; +} +//--------------------------------------------------------------------------- +void __fastcall LimitDbl(double *pInt, double min, double max) +{ + if( *pInt < min ) *pInt = min; + if( *pInt > max ) *pInt = max; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall StrDbl(LPSTR bf, double d) +{ + LPSTR p; + + sprintf(bf, "%lf", d); + for( p = &bf[strlen(bf)-1]; p >= bf; p-- ){ + if( (*p == '0')&&(*(p-1)!='.') ){ + *p = 0; + } + else { + break; + } + } + return bf; +} +//--------------------------------------------------------------------------- +void __fastcall AdjustAS(AnsiString *pAS) +{ + LPCSTR p; + BOOL f = TRUE; + for( p = pAS->c_str(); *p; p++ ){ + if( (*p != '\r') && (*p != '\n') ) f = FALSE; + } + if( f ) *pAS = ""; +} +//--------------------------------------------------------------------------- +// ビットマップへのメッセージの描画 +void __fastcall DrawMessage(TCanvas *pCanvas, int XW, int YW, LPCSTR p, int Pos) +{ + if( !*p ) return; + + int xr, xl, vc; + int fh = pCanvas->TextHeight(p); + int fw = pCanvas->TextWidth(p); + switch(Pos){ + case 0: // 中央 + xr = fw; + xl = (XW - xr)/2; + xr += xl; + vc = YW / 2; + break; + case 1: // 左上 + xl = 5; + xr = xl + fw; + vc = fh*2/3; + break; + case 2: // 右上 + xr = XW - 8; + xl = xr - fw; + vc = fh*2/3; + break; + case 3: // 右下 + xr = XW - 8; + xl = xr - fw; + vc = YW - fh; + break; + case 4: // 左下 + xl = 5; + xr = xl + fw; + vc = YW - fh; + break; + default: + xl = Pos - fw/2; + xr = xl + fw; + vc = fh*2/3; + break; + } + pCanvas->Pen->Style = psSolid; + pCanvas->Pen->Color = clBlack; + pCanvas->Brush->Color = clWhite; + int yo = fh * 2/3; + pCanvas->RoundRect(xl-5, vc-yo, xr+5, vc+yo, 10, 10); + pCanvas->Font->Color = clBlack; + pCanvas->TextOut(xl, vc-fh/2, p); +} +//--------------------------------------------------------------------------- +LPSTR __fastcall StrDupe(LPCSTR s) +{ + LPSTR p = new char[strlen(s)+1]; + strcpy(p, s); + return p; +} + + +LPUSTR __fastcall jstrupr(LPUSTR s) +{ + LPUSTR p = s; + int kf; + + for( kf = 0; *p; p++ ){ + if( kf ){ + kf = 0; + } + else if( _mbsbtype((unsigned char *)p, 0) == _MBC_LEAD ){ + kf = 1; + } + else { + *p = (unsigned char)toupper(*p); + } + } + return s; +} +LPUSTR __fastcall jstrlwr(LPUSTR s) +{ + LPUSTR p = s; + int kf; + + for( kf = 0; *p; p++ ){ + if( kf ){ + kf = 0; + } + else if( _mbsbtype((unsigned char *)p, 0) == _MBC_LEAD ){ + kf = 1; + } + else { + *p = (unsigned char)tolower(*p); + } + } + return s; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall ConvAndChar(LPSTR t, LPCSTR p) +{ + LPSTR s = t; + + while(*p){ + if( *p == '&' ){ + *t++ = *p; + } + *t++ = *p++; + } + *t = 0; + return s; +} +/*#$% +=============================================================== + 時刻を調整する +--------------------------------------------------------------- + t : 時刻(UTC) + c : 時差コード +--------------------------------------------------------------- + ローカルタイム +--------------------------------------------------------------- + A-Z + a-z +30min +=============================================================== +*/ +WORD __fastcall AdjustRolTimeUTC(WORD tim, char c) +{ + const char tdf[]={ +/* A B C D E F G H I J K L M N O P Q R S T U V W X Y Z */ + 1,2,3,4,5,6,7,8,9,9,10,11,12,23,22,21,20,19,18,17,16,15,14,13,12,0 + }; + int cc; + + cc = toupper(c); + if( (cc >= 'A')&&(cc <= 'Z') ){ + // JST to UTC +#if 0 + if( tim >= (9*60*30) ){ + tim -= WORD(9 * 60 * 30); + } + else { + tim += WORD(15 * 60 * 30); + } +#endif + tim /= WORD(30); + tim += WORD(tdf[cc-'A'] * 60); + if( c >= 'a' ) tim += WORD(30); + while( tim >= (24 * 60) ){ + tim -= WORD(24 * 60); + } + tim *= WORD(30); + if( !tim ) tim++; + } + else { + tim = 0; + } + return tim; +} +///---------------------------------------------------------------- +/// ウィンドウをクライアントセンターにする +void __fastcall FormCenter(TForm *tp, int XW, int YW) +{ + int top = (YW - tp->Height)/2; + int left = (XW - tp->Width)/2; + if( top < 0 ) top = 0; + if( left < 0 ) left = 0; + tp->Position = poDesigned; + tp->SetBounds(left, top, tp->Width, tp->Height); +} +///---------------------------------------------------------------- +/// ウィンドウをクライアントセンターにする +void __fastcall FormCenter(TForm *tp, TForm *pOwner) +{ + int top = (pOwner->Height - tp->Height)/2; + int left = (pOwner->Width - tp->Width)/2; + if( top < 0 ) top = 0; + if( left < 0 ) left = 0; + tp->Position = poDesigned; + tp->SetBounds(pOwner->Left + left, pOwner->Top + top, tp->Width, tp->Height); +} +///---------------------------------------------------------------- +/// ウィンドウをクライアントセンターにする +void __fastcall FormCenter(TForm *tp) +{ + FormCenter(tp, MainVARI); +} +/*#$% +======================================================== + 最後の文字コードを返す +-------------------------------------------------------- + p : 文字列のポインタ +-------------------------------------------------------- + 文字コード +-------------------------------------------------------- +======================================================== +*/ +char *__fastcall lastp(char *p) +{ + if( *p ){ + for( ; *p; p++ ); + p--; + return(p); + } + else { + return(p); + } +} +/*#$% +======================================================== + 末尾のスペースとTABを取る +-------------------------------------------------------- + s : 文字列のポインタ +-------------------------------------------------------- + 文字列のポインタ +-------------------------------------------------------- +======================================================== +*/ +char *__fastcall clipsp(char *s) +{ + char *p; + + if( *s ){ + for( p = lastp(s); p >= s; p-- ){ + if( (*p == ' ')||(*p == 0x09) ){ + *p = 0; + } + else { + break; + } + } + } + return(s); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall _strdmcpy(LPSTR t, LPCSTR p, char c) +{ + for( ; *p && (*p != c); p++, t++ ) *t = *p; + *t = 0; + if( *p == c ) p++; + return(p); +} +const char *__fastcall StrDlmCpy(char *t, const char *p, char Dlm, int len) +{ + const char _tt1[]="[{(「<"; + const char _tt2[]="]})」>"; + const char *pp; + int r = FALSE; + + char Key; + if( (pp = strchr(_tt2, Dlm))!=NULL ){ + Key = _tt1[pp - _tt2]; + } + else { + Key = 0; + } + int f, k; + for( f = k = 0; *p; p++ ){ + if( k ){ // 漢字2バイト目 + k = 0; + } + else if( _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){ // 漢字1バイト目 + k = 1; + } + else if( *p == Key ){ + f++; + } + else if( *p == Dlm ){ + if( f ){ + f--; + } + else { + r = TRUE; + p++; + break; + } + } + if( len ){ + *t++ = *p; + len--; + } + } + *t = 0; + return (r == TRUE) ? p : NULL; +} + +const char *__fastcall StrDlmCpyK(char *t, const char *p, char Dlm, int len) +{ + const char _tt1[]="[{(「<"; + const char _tt2[]="]})」>"; + const char *pp; + int r = FALSE; + + char Key; + if( (pp = strchr(_tt2, Dlm))!=NULL ){ + Key = _tt1[pp - _tt2]; + } + else { + Key = 0; + } + int f, k; + for( f = k = 0; *p; p++ ){ + if( k ){ // 漢字2バイト目 + k = 0; + } + else if( _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){ // 漢字1バイト目 + k = 1; + } + else if( (pp = strchr(_tt1, *p))!=NULL ){ + Key = _tt2[pp - _tt1]; + f++; + } + else if( f && (*p == Key) ){ + f--; + Key = 0; + } + else if( *p == Dlm ){ + if( !f ){ + r = TRUE; + p++; + break; + } + } + if( len ){ + *t++ = *p; + len--; + } + } + *t = 0; + return (r == TRUE) ? p : NULL; +} +//--------------------------------------------------------------------------- +void __fastcall StrCopy(LPSTR t, LPCSTR s, int n) +{ + for( ; *s && n; n--, s++, t++){ + *t = *s; + } + *t = 0; +} +//--------------------------------------------------------------------------- +char __fastcall LastC(LPCSTR p) +{ + char c = 0; + + if( *p ){ + c = *(p + strlen(p) - 1); + } + return c; +} + +/*#$% +======================================================== + 拡張子を得る +-------------------------------------------------------- + p : 文字列のポインタ +-------------------------------------------------------- + 文字コード +-------------------------------------------------------- +======================================================== +*/ +LPCSTR __fastcall GetEXT(LPCSTR Fname) +{ + if( *Fname ){ + LPCSTR p = Fname + (strlen(Fname) - 1); + for( ; p > Fname; p-- ){ + if( *p == '.' ) return p+1; + } + } + return ""; +} + +void __fastcall SetEXT(LPSTR pName, LPSTR pExt) +{ + if( *pName ){ + LPSTR p; + + for( p = &pName[strlen(pName)-1]; p >= pName; p-- ){ + if( *p == '.' ){ + strcpy(p, pExt); + return; + } + } + strcat(pName, pExt); + } +} + +BOOL __fastcall CheckEXT(LPCSTR pName, LPCSTR pExt) +{ + return !strcmpi(GetEXT(pName), pExt); +} + +void __fastcall SetCurDir(LPSTR t, int size) +{ + if( !::GetCurrentDirectory(size-1, t) ){ + *t = 0; + } + else { + if( LastC(t) != '\\' ){ + strcat(t, "\\"); + } + } +} + +void __fastcall SetDirName(LPSTR t, LPCSTR pName) +{ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + AnsiString Dir; + + ::_splitpath( pName, drive, dir, name, ext ); + Dir = drive; + Dir += dir; + strncpy(t, Dir.c_str(), 128); +} + +///---------------------------------------------------------------- +void __fastcall GetFileName(AnsiString &Name, LPCSTR pName) +{ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + ::_splitpath( pName, drive, dir, name, ext ); + Name = name; + Name += ext; +} +//--------------------------------------------------------------------------- +void __fastcall GetFullPathName(AnsiString &as, LPCSTR pName) +{ + GetFullPathName(as, pName, sys.m_BgnDir); +} +//--------------------------------------------------------------------------- +void __fastcall GetFullPathName(AnsiString &as, LPCSTR pName, LPCSTR pFolder) +{ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + + ::_splitpath( pName, drive, dir, name, ext ); + if( !drive[0] || !dir[0] ){ + char fname[512]; + sprintf(fname, "%s%s", pFolder, pName); + as = fname; + } + else { + as = pName; + } +} +///---------------------------------------------------------------- +/// CR/LFを削除 +/// +void __fastcall ClipLF(LPSTR sp) +{ + for( ; *sp; sp++ ){ + if( (*sp == LF)||(*sp == CR) ){ + *sp = 0; + break; + } + } +} +///---------------------------------------------------------------- +/// CRを削除 +/// +void __fastcall DelCR(AnsiString &ws, LPCSTR s) +{ + ws = ""; + for( ; *s; s++ ){ + if( *s != CR ){ + ws += *s; + } + } +} +///---------------------------------------------------------------- +/// コメントを削除(スペースおよびTABも削除) +/// +void __fastcall DeleteComment(LPSTR bf) +{ + LPSTR sp, tp; + + for( sp = tp = bf; *sp; sp++ ){ + if( (*sp == ';')||(*sp == CR)||(*sp == LF) ){ + break; + } + else if( (*sp!=' ')&&(*sp!=TAB) ){ + *tp++ = *sp; + } + } + *tp = 0; +} + +LPSTR __fastcall FillSpace(LPSTR s, int n) +{ + LPSTR p = s; + int i = 0; + for( ; *p && (i < n); i++, p++ ); + for( ; i < n; i++, p++ ){ + *p = ' '; + } + *p = 0; + return s; +} +///---------------------------------------------------------------- +LPCSTR __fastcall SkipToValue(LPCSTR sp) +{ + while(*sp){ + if( isdigit(*sp) ) break; + if( (*sp == '+') || (*sp == '-') || (*sp == '.') ) break; + sp++; + } + return sp; +} +///---------------------------------------------------------------- +/// ホワイトスペースのスキップ +/// +LPSTR __fastcall SkipSpace(LPSTR sp) +{ + for( ; *sp; sp++ ){ + if( (*sp != ' ')&&(*sp != TAB) ) break; + } + return sp; +} + +LPCSTR __fastcall SkipSpace(LPCSTR sp) +{ + for( ; *sp; sp++ ){ + if( (*sp != ' ')&&(*sp != TAB) ) break; + } + return sp; +} +///---------------------------------------------------------------- +LPSTR __fastcall DelLastSpace(LPSTR t) +{ + int l = strlen(t); + if( l ){ + LPSTR p; + for( p = t + l - 1; p >= t; p-- ){ + if( (*p == ' ') || (*p == TAB) ){ + *p = 0; + } + else { + break; + } + } + } + return t; +} +///---------------------------------------------------------------- +/// デリミッタ分解を行う +/// +LPSTR __fastcall StrDlm(LPSTR &t, LPSTR p) +{ + return StrDlm(t, p, ','); +} + +///---------------------------------------------------------------- +/// デリミッタ分解を行う +/// +LPSTR __fastcall StrDlm(LPSTR &t, LPSTR p, char c) +{ + int f, k; + LPSTR d1=NULL; + LPSTR d2=NULL; + + t = p; + f = k = 0; + while(*p){ + if( k ){ // 漢字2バイト目 + if( (c == -1) && !sys.m_MsgEng ){ + k |= *p & 0x00ff; + if( k == 0x8140 ){ + p--; + *p = 0; + p+=2; + break; + } + } + k = 0; + } + else if( _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){ // 漢字1バイト目 + k = *p & 0x00ff; + k = k << 8; + } + else if( *p == 0x22 ){ + if( !f ){ + if( d1 == NULL ) d1 = p+1; + f++; + } + else { + d2 = p; + f--; + } + } + else if( !f && ((*p == c) || ((c == -1) && strchr(" /,;;.", *p))) ){ + *p = 0; + p++; + break; + } + p++; + } + if( (d1!=NULL)&&(d2!=NULL) ){ + if( ((t+1)==d1) && ( ((p-2)==d2)||((p-1)==d2) ) ){ + t = d1; + *d2 = 0; + } + } + return(p); +} + +///---------------------------------------------------------------- +/// +void __fastcall ChgString(LPSTR t, char a, char b) +{ + for( ; *t; t++ ){ + if( *t == a ) *t = b; + } +} + +///---------------------------------------------------------------- +/// +void __fastcall DelChar(LPSTR t, char a) +{ + for( ; *t; t++ ){ + if( *t == a ){ + strcpy(t, t+1); + t--; + } + } +} + +/*#$% +======================================================== + デシマルアスキーを数値に変換する +-------------------------------------------------------- + p : 文字列のポインタ + n : 変換桁数 +-------------------------------------------------------- + 数値 +-------------------------------------------------------- +======================================================== +*/ +int __fastcall atoin(const char *p, int n) +{ + int d; + + for( d = 0; *p && n; p++, n-- ){ + d *= 10; + d += (*p & 0x0f); + } + return(d); +} +/*#$% +======================================================== + 16進アスキーを数値に変換する +-------------------------------------------------------- + p : 文字列のポインタ + n : 変換桁数 +-------------------------------------------------------- + 数値 +-------------------------------------------------------- +======================================================== +*/ +int __fastcall htoin(const char *p, int n) +{ + if( *p == 'x' ) return 0; + int d; + + for( d = 0; *p && n; p++, n-- ){ + d = d << 4; + d += (*p & 0x0f); + if( *p >= 'A' ) d += 9; + } + return(d); +} +//--------------------------------------------------------------------------- +int __fastcall FontStyle2Code(TFontStyles style) +{ + int code = 0; + + TFontStyles fa; + TFontStyles fb; + + fa << fsBold; + fb << fsBold; + fa *= style; + if( fa == fb ) code |= FSBOLD; + + fa >> fsBold; + fb >> fsBold; + fa << fsItalic; + fb << fsItalic; + fa *= style; + if( fa == fb ) code |= FSITALIC; + + fa >> fsItalic; + fb >> fsItalic; + fa << fsUnderline; + fb << fsUnderline; + fa *= style; + if( fa == fb ) code |= FSUNDERLINE; + + fa >> fsUnderline; + fb >> fsUnderline; + fa << fsStrikeOut; + fb << fsStrikeOut; + fa *= style; + if( fa == fb ) code |= FSSTRIKEOUT; + + return code; +} + +TFontStyles __fastcall Code2FontStyle(int code) +{ + TFontStyles fs; + + if( code & FSBOLD ) fs << fsBold; + if( code & FSITALIC ) fs << fsItalic; + if( code & FSUNDERLINE ) fs << fsUnderline; + if( code & FSSTRIKEOUT ) fs << fsStrikeOut; + return fs; +} +//--------------------------------------------------------------------------- +void __fastcall Font2FontData(FONTDATA *pData, TFont *pFont) +{ + pData->m_Name = pFont->Name; + pData->m_Charset = pFont->Charset; + pData->m_Height = pFont->Height; + TFontStyles ts = pFont->Style; + pData->m_Style = FontStyle2Code(ts); +} +//--------------------------------------------------------------------------- +void __fastcall FontData2Font(TFont *pFont, FONTDATA *pData) +{ + pFont->Name = pData->m_Name; + pFont->Charset = pData->m_Charset; + pFont->Height = pData->m_Height; + TFontStyles ts; + ts = Code2FontStyle(pData->m_Style); + pFont->Style = ts; +} +//--------------------------------------------------------------------------- +void __fastcall LoadFontFromInifile(FONTDATA *pData, LPCSTR pSect, TMemIniFile *pIniFile) +{ + if( pData == NULL ) return; + + pData->m_Name = pIniFile->ReadString(pSect, "FontName", pData->m_Name); + pData->m_Charset = (BYTE)pIniFile->ReadInteger(pSect, "FontSet", pData->m_Charset); + pData->m_Height = pIniFile->ReadInteger(pSect, "FontSize", pData->m_Height); + pData->m_Style = pIniFile->ReadInteger(pSect, "FontStyle", pData->m_Style); +} +//--------------------------------------------------------------------------- +void __fastcall SaveFontToInifile(FONTDATA *pData, LPCSTR pSect, TMemIniFile *pIniFile) +{ + if( pData == NULL ) return; + + pIniFile->WriteString(pSect, "FontName", pData->m_Name); + pIniFile->WriteInteger(pSect, "FontSet", pData->m_Charset); + pIniFile->WriteInteger(pSect, "FontSize", pData->m_Height); + pIniFile->WriteInteger(pSect, "FontStyle", pData->m_Style); +} +//--------------------------------------------------------------------------- +void __fastcall LoadFontFromInifile(TFont *pFont, LPCSTR pSect, TMemIniFile *pIniFile) +{ + if( pFont == NULL ) return; + + pFont->Name = pIniFile->ReadString(pSect, "FontName", pFont->Name); + pFont->Charset = (BYTE)pIniFile->ReadInteger(pSect, "FontSet", pFont->Charset); + pFont->Height = pIniFile->ReadInteger(pSect, "FontSize", pFont->Height); + TFontStyles ts = pFont->Style; + DWORD d = FontStyle2Code(ts); + d = pIniFile->ReadInteger(pSect, "FontStyle", d); + ts = Code2FontStyle(d); + pFont->Style = ts; +} +//--------------------------------------------------------------------------- +void __fastcall SaveFontToInifile(TFont *pFont, LPCSTR pSect, TMemIniFile *pIniFile) +{ + if( pFont == NULL ) return; + + pIniFile->WriteString(pSect, "FontName", pFont->Name); + pIniFile->WriteInteger(pSect, "FontSet", pFont->Charset); + pIniFile->WriteInteger(pSect, "FontSize", pFont->Height); + TFontStyles ts = pFont->Style; + DWORD d = FontStyle2Code(ts); + pIniFile->WriteInteger(pSect, "FontStyle", d); +} +//--------------------------------------------------------------------------- +void __fastcall SetMBCP(BYTE charset) +{ + sys.m_Charset = charset; + UINT cp; + switch(charset){ + case SHIFTJIS_CHARSET: + cp = 932; + break; + case HANGEUL_CHARSET: + cp = 949; + break; + case JOHAB_CHARSET: + cp = 1361; + break; + case CHINESEBIG5_CHARSET: // + cp = 950; + break; + case 134: // 簡略 + cp = 936; + break; + case ANSI_CHARSET: + case SYMBOL_CHARSET: + cp = 1252; + break; + default: + cp = _MB_CP_ANSI; + break; + } + if( cp != _MB_CP_ANSI ){ + CPINFO info; + if( GetCPInfo(cp, &info) != TRUE ){ + cp = _MB_CP_ANSI; + } + } + _setmbcp(cp); +} + +//--------------------------------------------------------------------------- +BOOL __fastcall SetLangFont(TFont *pFont, WORD wLang) +{ + BOOL r = TRUE; + switch(wLang){ + case 0x0411: // JA + if( pFont ){ + pFont->Name = sys.m_MsgEng ? "MS UI Gothic" : "MS Pゴシック"; + pFont->Charset = SHIFTJIS_CHARSET; + } + break; + case 0x0412: // HL + if( pFont ){ + pFont->Name = "DotumChe"; + pFont->Charset = HANGEUL_CHARSET; + if( sys.m_fFontFam && (!sys.m_tFontFam[fmHL] && sys.m_tFontFam[fmJOHAB]) ){ + pFont->Charset = JOHAB_CHARSET; + } + } + break; + case 0x0404: // BV + if( pFont ){ + pFont->Name = "PMingLiU"; + pFont->Charset = CHINESEBIG5_CHARSET; + } + break; + case 0x0804: // BY + if( pFont ){ + pFont->Name = "SimHei"; + pFont->Charset = 134; + } + break; + default: + if( pFont ){ + pFont->Name = "Arial"; + pFont->Charset = ANSI_CHARSET; + } + r = FALSE; + break; + } + return r; +} +//--------------------------------------------------------------------------- +void __fastcall GetLogFont(LOGFONT *pLogfont, TFont *pFont) +{ + memset(pLogfont, 0, sizeof(LOGFONT)); + pLogfont->lfHeight = pFont->Height; + pLogfont->lfWidth = 0; + pLogfont->lfEscapement = 0; + pLogfont->lfOrientation = 0; + TFontStyles ts = pFont->Style; + int fsw = FontStyle2Code(ts); + pLogfont->lfWeight = fsw & FSBOLD ? 700 : 400; + pLogfont->lfItalic = BYTE(fsw & FSITALIC ? TRUE : FALSE); + pLogfont->lfUnderline = BYTE(fsw & FSUNDERLINE ? TRUE : FALSE); + pLogfont->lfStrikeOut = BYTE(fsw & FSSTRIKEOUT ? TRUE : FALSE); + pLogfont->lfCharSet = pFont->Charset; + pLogfont->lfOutPrecision = OUT_CHARACTER_PRECIS; + pLogfont->lfClipPrecision = CLIP_DEFAULT_PRECIS; + pLogfont->lfQuality = NONANTIALIASED_QUALITY; + pLogfont->lfPitchAndFamily = DEFAULT_PITCH; + strcpy(pLogfont->lfFaceName, AnsiString(pFont->Name).c_str()); //JA7UDE 0428 +} +//--------------------------------------------------------------------------- +void __fastcall AddStyle(AnsiString &as, BYTE charset, DWORD style) +{ + switch(charset){ + case ANSI_CHARSET: + as += sys.m_MsgEng ? "/ANSI" : "/欧文"; + break; + case SHIFTJIS_CHARSET: + as += sys.m_MsgEng ? "/Japanese" : "/日本語"; + break; + case HANGEUL_CHARSET: + as += sys.m_MsgEng ? "/Korean(Hangul)" : "/ハングル"; + break; + case JOHAB_CHARSET: + as += sys.m_MsgEng ? "/Korean(Johab)" : "/ハングル(Johab)"; + break; + case CHINESEBIG5_CHARSET: // 台湾 + as += sys.m_MsgEng ? "/Chinese(BIG5)" : "/中国語(繁体)"; + break; + case 134: // 中国語簡略 + as += sys.m_MsgEng ? "/Chinese(GB2312)" : "/中国語(簡体)"; + break; + case SYMBOL_CHARSET: + as += sys.m_MsgEng ? "/Symbol" : "/シンボル"; + break; + default: + break; + } + if( style & FSBOLD ) as += sys.m_MsgEng ? "/Bold" : "/太字"; + if( style & FSITALIC ) as += sys.m_MsgEng ? "/Italic" : "/斜体"; + if( style & FSUNDERLINE ) as += sys.m_MsgEng ? "/UnderLine" : "/下線"; + if( style & FSSTRIKEOUT ) as += sys.m_MsgEng ? "/StrikeOut" : "/取消し線"; +} +//--------------------------------------------------------------------------- +//static int CALLBACK EnumFontFamExProc( ENUMLOGFONT FAR* lpelf, NEWTEXTMETRIC FAR* lpntm, DWORD FontType, LPARAM lParam) //ja7ude 0522 +static int CALLBACK EnumFontFamExProc( const tagLOGFONTA FAR* lpelf, const tagTEXTMETRICA FAR* lpntm, DWORD FontType, LPARAM lParam) +{ + OnWave(); + //switch(lpelf->elfLogFont.lfCharSet){ + switch(lpelf->lfCharSet){ + case SHIFTJIS_CHARSET: + sys.m_tFontFam[fmJA] = TRUE; + break; + case HANGEUL_CHARSET: + sys.m_tFontFam[fmHL] = TRUE; + break; + case JOHAB_CHARSET: + sys.m_tFontFam[fmJOHAB] = TRUE; + break; + case CHINESEBIG5_CHARSET: // 台湾 + sys.m_tFontFam[fmBV] = TRUE; + break; + case 134: // 中国語簡略 + sys.m_tFontFam[fmBY] = TRUE; + break; + default: + break; + } + int r = FALSE; + for( int i = 0; i < fmEND; i++ ){ + if( !sys.m_tFontFam[i] ) r = TRUE; + } + return r; +} +//--------------------------------------------------------------------------- +void __fastcall CheckFontCharset(void) +{ + if( sys.m_fFontFam ) return; + + sys.m_fFontFam = TRUE; + memset(sys.m_tFontFam, 0, sizeof(sys.m_tFontFam)); + LOGFONT logfont; + memset(&logfont, 0, sizeof(logfont)); + logfont.lfCharSet = DEFAULT_CHARSET; + HDC hDC = ::CreateDC("DISPLAY", NULL, NULL, NULL); + //::EnumFontFamiliesEx(hDC, &logfont, (int (_stdcall *)())EnumFontFamExProc, 0, 0); //ja7ude 0522 + ::EnumFontFamiliesEx(hDC, &logfont, EnumFontFamExProc, 0, 0); + ::DeleteDC(hDC); +} +//--------------------------------------------------------------------------- +UCOL __fastcall GetGrade2(UCOL s[2], int x, int xw) +{ + if( x < 0 ) x = 0; + if( x > xw ) x = xw; + UCOL r; + int c = s[0].b.b + ((int(s[1].b.b) - int(s[0].b.b)) * x / xw); + if( c < 0 ) c = 0; + if( c > 255 ) c = 255; + r.b.b = BYTE(c); + c = s[0].b.g + ((int(s[1].b.g) - int(s[0].b.g)) * x / xw); + if( c < 0 ) c = 0; + if( c > 255 ) c = 255; + r.b.g = BYTE(c); + c = s[0].b.r + ((int(s[1].b.r) - int(s[0].b.r)) * x / xw); + if( c < 0 ) c = 0; + if( c > 255 ) c = 255; + r.b.r = BYTE(c); + return r; +} +//--------------------------------------------------------------------------- +int __fastcall GetActiveIndex(TPageControl *pp) +{ + int i; + for( i = 0; i < pp->PageCount; i++ ){ + if( pp->ActivePage == pp->Pages[i] ) return i; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall SetActiveIndex(TPageControl *pp, int page) +{ + if( (page >= 0) && (page < pp->PageCount) ){ + pp->ActivePage = pp->Pages[page]; + } +} +//--------------------------------------------------------------------------- +int __fastcall InvMenu(TMenuItem *pItem) +{ + pItem->Checked = pItem->Checked ? FALSE : TRUE; + return pItem->Checked; +} +///---------------------------------------------------------------- +HWND __fastcall GetMBHandle(int &flag) +{ + HWND hd; + if( Screen->ActiveForm != NULL ){ + hd = Screen->ActiveForm->Handle; + } + else { + hd = NULL; + } + flag = MB_SETFOREGROUND; + flag |= MB_TOPMOST; + flag |= (hd == NULL) ? MB_TASKMODAL : MB_APPLMODAL; + return hd; +} +static int MsgBoxFlag = 0; +///---------------------------------------------------------------- +/// メッセージの表示 +/// +void InfoMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); + flag |= (MB_OK | MB_ICONINFORMATION); +// Application->NormalizeTopMosts(); + ::MessageBox(hd, bf, "MMVARI", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; +} +///---------------------------------------------------------------- +/// エラーメッセージの表示 +/// +void ErrorMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); + flag |= (MB_OK | MB_ICONEXCLAMATION); +// Application->NormalizeTopMosts(); + ::MessageBox(hd, bf, sys.m_MsgEng ? "Error":"エラー", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; +} + +///---------------------------------------------------------------- +/// 警告メッセージの表示 +/// +void WarningMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); + flag |= (MB_OK | MB_ICONEXCLAMATION); +// Application->NormalizeTopMosts(); + ::MessageBox(hd, bf, sys.m_MsgEng?"Warning":"警告", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; +} + +///---------------------------------------------------------------- +/// 実行選択メッセージの表示 +/// +int YesNoMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return IDNO; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); +// if( Screen->ActiveForm != NULL ) NormalWindow(Screen->ActiveForm); + flag |= (MB_YESNO | MB_ICONQUESTION); +// Application->NormalizeTopMosts(); + int r = ::MessageBox(hd, bf, "MMVARI", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; + return r; +} + +///---------------------------------------------------------------- +/// 実行選択メッセージの表示 +/// +int YesNoCancelMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return IDCANCEL; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); + flag |= (MB_YESNOCANCEL | MB_ICONQUESTION); +// Application->NormalizeTopMosts(); + int r = ::MessageBox(hd, bf, "MMVARI", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; + return r; +} +///---------------------------------------------------------------- +/// 実行選択メッセージの表示 +/// +int OkCancelMB(LPCSTR fmt, ...) +{ + if( MsgBoxFlag ) return IDCANCEL; + MsgBoxFlag++; + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + + int flag; + HWND hd = GetMBHandle(flag); + flag |= (MB_OKCANCEL | MB_ICONQUESTION); +// Application->NormalizeTopMosts(); + int r = ::MessageBox(hd, bf, "MMVARI", flag); +// Application->RestoreTopMosts(); + MsgBoxFlag--; + return r; +} +///---------------------------------------------------------------- +/// +void __fastcall ErrorFWrite(LPCSTR pName) +{ + if( GetFileAttributes(pName) & FILE_ATTRIBUTE_READONLY ){ + ErrorMB(sys.m_MsgEng ? "'%s' is read-only (fail to update)." : "'%s'が 読み取り専用 に設定されているため更新に失敗しました.", pName); + } + else { + ErrorMB( "Could not update '%s'", pName ); + } +} +///---------------------------------------------------------------- +/// +int __fastcall RemoveL2(LPSTR t, LPSTR ss, LPCSTR pKey, int size) +{ + char c; + int k; + LPCSTR pp; + LPSTR s; + const char _tt1[]="[{(「<"; + const char _tt2[]="]})」>"; + + int len = strlen(pKey); + char ac = ';'; + for( k = 0, s = ss; *s; s++ ){ + if( k ){ // 漢字2バイト目 + k = 0; + ac = 0x1e; + } + else if( _mbsbtype((const unsigned char *)s, 0) == _MBC_LEAD ){ // 漢字1バイト目 + k = 1; + if( (len >= 2) && (strchr(" ,./;:*\t[{(「<]})」>", ac)!=NULL) && (!strnicmp(s, pKey, len)) ){ + pp = s + len; + if( (pp = strchr(_tt1, *pp))!=NULL ){ + c = _tt2[pp - _tt1]; + if( *(s+len+1) ){ + StrDlmCpy(t, s+len+1, c, size); + if( *t ){ + strcpy((ac == ' ')?(s-1):s, s+len+2+strlen(t)); + return TRUE; + } + } + } + } + } + else if( (strchr(" ,./;:*\t\x1e[{(「<]})」>", ac)!=NULL) && (!strnicmp(s, pKey, len)) ){ + pp = s + len; + if( (pp = strchr(_tt1, *pp))!=NULL ){ + c = _tt2[pp - _tt1]; + if( *(s+len+1) ){ + StrDlmCpy(t, s+len+1, c, size); + if( *t ){ + strcpy((ac == ' ')?(s-1):s, s+len+2+strlen(t)); + return TRUE; + } + } + } + ac = *s; + } + else { + ac = *s; + } + } + return FALSE; +} + +void __fastcall AddL2(LPSTR t, LPCSTR pKey, LPCSTR s, UCHAR c1, UCHAR c2, int size) +{ + if( *s ){ + int len = strlen(t); + int lenkey = strlen(pKey); + int lenData = strlen(s); + if( (len + lenkey + lenData + 2) < size ){ + t += len; + if( len ) *t++ = ' '; + if( *pKey ){ + strcpy(t, pKey); + t += lenkey; + } + *t++ = c1; + strcpy(t, s); + t += lenData; + *t++ = c2; + *t = 0; + } + } +} +///---------------------------------------------------------------- +void __fastcall NumCopy(LPSTR t, LPCSTR p) +{ + p = SkipSpace(p); + for( ; *p; p++ ){ + if( isdigit(*p) ){ + *t++ = *p; + } + else { + break; + } + } + *t = 0; +} +///---------------------------------------------------------------- +/// 数字が含まれるかどうか調べる +/// +int __fastcall IsNumbs(LPCSTR p) +{ + for( ; *p; p++ ){ + if( isdigit(*p) ) return 1; + } + return 0; +} +///---------------------------------------------------------------- +/// 数字が含まれるかどうか調べる +/// +int __fastcall IsNumbAll(LPCSTR p) +{ + for( ; *p; p++ ){ + if( !isdigit(*p) ) return 0; + } + return 1; +} +///---------------------------------------------------------------- +/// 数字が含まれるかどうか調べる +/// +int __fastcall IsAlphas(LPCSTR p) +{ + for( ; *p; p++ ){ + if( isalpha(*p) ) return 1; + } + return 0; +} +///---------------------------------------------------------------- +int __fastcall IsAlphaAll(LPCSTR p) +{ + for( ; *p; p++ ){ + if( !isalpha(*p) ) return FALSE; + } + return TRUE; +} +///---------------------------------------------------------------- +/// RSTかどうか調べる +/// +int __fastcall IsRST(LPCSTR p) +{ + if( strlen(p) < 3 ) return 0; + if( (*p < '1') || (*p > '5') ) return 0; + p++; + if( (*p < '1') || (*p > '9') ) return 0; + p++; + if( (*p < '1') || (*p > '9') ) return 0; + return 1; +} +///---------------------------------------------------------------- +int __fastcall IsCallChar(char c) +{ + if( !isalpha(c) && !isdigit(c) && (c != '/') ) return 0; + if( islower(c) ) return 0; + return 1; +} +///---------------------------------------------------------------- +/// コールサインかどうか調べる +/// +int __fastcall IsCall(LPCSTR p) +{ + int l = strlen(p); + if( l > 16 ) return 0; + if( l < 3 ) return 0; + if( isdigit(*p) ){ // 先頭が数字 + if( l <= 3 ) return 0; // 3文字以下の時NG + if( isdigit(*(p+1)) ) return 0; // 2文字目が数字の時NG + } + if( isdigit(LastC(p)) ){ // 最後が数字 + if( l <= 4 ) return 0; // 4文字以下の時NG +// if( !strchr(p, '/')==NULL ) return 0; // /が含まれていない時NG +// if( p[l-2] != '/' ) return 0; // 最後の1つ前が/以外の時NG + } + int i; + for( i = 0; i < l-1; i++, p++ ){ + if( isdigit(*p) ) return 1; // 数字が含まれていればOK + } + return 0; +} +/*#$% +====================================================== + JAとDXの区別をする +------------------------------------------------------ + s : コールサイン文字列のポインタ +------------------------------------------------------ + 1 : JA + 0 : DX (JD1 INCLUDEED) +------------------------------------------------------ +====================================================== +*/ +int __fastcall IsJA(const char *s) +{ + if( (!memcmp(s, "8J1R", 4) && (strlen(s) == 5))||(strstr(s, "/JD1")!=NULL) ){ + return(0); + } + else if( strchr(s, '/') ){ + char bf[MLCALL+1]; + StrCopy(bf, s, MLCALL); + char *p; + char *t; + for( p = bf; *p; ){ + p = StrDlm(t, p, '/'); + if( *t ){ + if( (strlen(t) >= 2) && isdigit((unsigned char)LastC(t)) ){ + if( *t == 'J' ){ + t++; + if( *t == 'D' ) return(0); + if( (*t >= 'A')&&(*t <= 'S' ) ) return(1); + } + else if( *t == '7' ){ + t++; + if( (*t >= 'J')&&(*t <= 'N' ) ) return(1); + } + else if( *t == '8' ){ + t++; + if( (*t >= 'J')&&(*t <= 'N' ) ) return(1); + } + else { + return 0; + } + } + } + } + } + if( *s == 'J' ){ + s++; + if( *s == 'D' ) return(0); + if( (*s >= 'A')&&(*s <= 'S' ) ) return(1); + } + else if( *s == '7' ){ + s++; + if( (*s >= 'J')&&(*s <= 'N' ) ) return(1); + } + else if( *s == '8' ){ + s++; + if( (*s >= 'J')&&(*s <= 'N' ) ) return(1); + } + return(0); +} +/*#$% +====================================================== + コールサインをクリップする +------------------------------------------------------ + s : コールサイン文字列のポインタ +------------------------------------------------------ + クリップコールのポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall ClipCall(LPCSTR s) +{ + static char bf[MLCALL+1]; + LPCSTR p1, p2; + + if( (p1=strchr(s, '/'))!=NULL ){ + if( (p2=strchr(p1+1, '/'))!=NULL ){ /* 3分割 */ + if( (int(strlen(p2+1)) < int((p2 - p1)+1)) || (!IsCall(p2+1)) ){ /* 最後より途中が長い */ + if( ((p2-p1) < (p1-s))||(!IsCall(p1+1)) ){ /* 途中より最初が長い */ + StrCopy(bf, s, MLCALL); + *strchr(bf, '/') = 0; + return(bf); + } + else { + strcpy(bf, p1+1); + *strchr(bf, '/') = 0; + return(bf); + } + } + else if( int(strlen(p2+1)) < int((p1 - s)+1) ){ /* 最後より最初が長い */ + StrCopy(bf, s, MLCALL); + *strchr(bf, '/') = 0; + return(bf); + } + else { + return(p2+1); + } + } + else { /* 2分割 */ + if( (int(strlen(p1+1)) < int((p1 - s)+1)) || (!IsCall(p1+1)) ){ + StrCopy(bf, s, MLCALL); + *strchr(bf, '/') = 0; + return(bf); + } + else { + return(p1+1); + } + } + } + else { + return(s); + } +} + +/*#$% +====================================================== + ポータブル表記を調べる +------------------------------------------------------ + p : コールサイン文字列のポインタ +------------------------------------------------------ + 数値のポインタ +------------------------------------------------------ +====================================================== +*/ +static LPSTR __fastcall chkptb(LPSTR p) +{ + if( *p ){ + p = lastp(p); + if( isdigit(*p) && ((*(p-1))=='/') ){ + return(p); + } + } + return(NULL); +} + +/*#$% +====================================================== + ポータブル表記の入れ替え +------------------------------------------------------ + s : コールサイン文字列のポインタ +------------------------------------------------------ +------------------------------------------------------ + 元の文字列を破壊する +====================================================== +*/ +void __fastcall chgptb(LPSTR s) +{ + LPSTR p, t; + + if( (p = chkptb(s))!=NULL ){ + t = p; + for( p--; p > s; p-- ){ + if( isdigit(*p) ){ + *p = *t; + t--; + *t = 0; + break; + } + } + } +} + +/*#$% +====================================================== + コールサインからカントリの元をクリップする +------------------------------------------------------ + s : コールサイン文字列のポインタ +------------------------------------------------------ + カントリのポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall ClipCC(LPCSTR s) +{ + static char bf[MLCALL+1]; + LPSTR p, t; + + StrCopy(bf, s, MLCALL); + chgptb(bf); /* ポータブル表記の入れ替え */ + for( p = bf; *p; ){ + if( *p ){ + p = StrDlm(t, p, '/'); + if( (strlen(t) > 1) && (isdigit(*t) || isdigit(LastC(t))) ) return(t); + } + } + for( p = bf; *p; ){ + if( *p ){ + p = StrDlm(t, p, '/'); + if( (strlen(t) > 1) && (*t!='Q') && strcmp(t, "MM") ) return(t); + } + } + return ClipCall(s); +} +//--------------------------------------------------------------------------- +// コンボBOXに文字列を設定する +void __fastcall SetComboBox(TComboBox *pCombo, LPCSTR pList) +{ + pCombo->Items->Clear(); + LPSTR s = strdup(pList); + LPSTR p = s; + LPSTR t; + while(*p){ + p = StrDlm(t, p); + clipsp(t); + t = SkipSpace(t); + if( *t ) pCombo->Items->Add(t); + } + free(s); + pCombo->DropDownCount = pCombo->Items->Count; +} +//--------------------------------------------------------------------------- +void __fastcall GetComboBox(AnsiString &as, TComboBox *pCombo) +{ + as = ""; + int i; + for( i = 0; i < pCombo->Items->Count; i++ ){ + if( i ) as += ','; + as += pCombo->Items->Strings[i]; + } +} +///---------------------------------------------------------------- +/// 文字列変換 +/// +void __fastcall Yen2CrLf(AnsiString &ws, AnsiString &cs) +{ + ws = ""; + LPCSTR p; + int f; + int dlm = 0; + + p = cs.c_str(); + if( *p == 0x22 ){ + p++; + dlm++; + } + for( f = 0; *p; p++ ){ + if( f ){ + f = 0; + ws += *p; + } + else if( _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){ + f = 1; + ws += *p; + } + else if( *p == '\\' ){ + switch(*(p+1)){ + case 'r': + ws += "\r"; + p++; + break; + case 'n': + ws += "\n"; + p++; + break; + case 't': + ws += "\t"; + p++; + break; + case '\\': + ws += "\\"; + p++; + break; + default: + p++; + ws += *p; + break; + } + } + else if( !dlm || (*p!=0x22) || *(p+1) ){ + ws += *p; + } + } +} + +void __fastcall CrLf2Yen(AnsiString &ws, AnsiString &cs) +{ + ws = "\x22"; + LPCSTR p; + int f = 0; + + for( p = cs.c_str(); *p; p++ ){ + if( f ){ + f = 0; + ws += *p; + } + else if( _mbsbtype((const unsigned char *)p, 0) == _MBC_LEAD ){ + f = 1; + ws += *p; + } + else if( *p == 0x0d ){ + ws += "\\r"; + } + else if( *p == 0x0a ){ + ws += "\\n"; + } + else if( *p == TAB ){ + ws += "\\t"; + } + else if( *p == '\\' ){ + ws += "\\\\"; + } + else { + ws += *p; + } + } + ws += "\x22"; +} + + +///--------------------------------------------------------- +/// テキスト文字列ストリーマー +int __fastcall CTextString::LoadText(LPSTR tp, int len) +{ + char c; + int n = 0; + if( !(*rp) ) return FALSE; + while(*rp){ + c = *rp++; + if( c == LF ){ + *tp = 0; + return TRUE; + } + else if( (c != CR)&&(c != 0x1a) ){ + if( n < (len-1) ){ + *tp++ = c; + n++; + } + } + } + *tp = 0; + return TRUE; +} +///------------------------------------------------------ +/// +///CWebRef クラス +/// +void __fastcall MakeCommand(LPSTR t, LPCSTR s, LPCSTR p) +{ + for( ;*s; s++ ){ + if( *s == '%' ){ + s++; + if( *s == '%' ){ + *t++ = '%'; + } + else if( (p != NULL) && (*s == '1') ){ + strcpy(t, p); + t += strlen(t); + p = NULL; + } + } + else { + *t++ = *s; + } + } + *t = 0; + if( p != NULL ){ + *t++ = ' '; + strcpy(t, p); + } +} + +__fastcall CWebRef::CWebRef() +{ + HTML = ""; + + HKEY hkey=NULL; /* オープン キーのハンドル */ + + char bf[512], name[512]; + ULONG namelen, len; + if( !RegOpenKeyEx(HKEY_CLASSES_ROOT, "http", 0, KEY_READ, &hkey) ){ + if( !RegOpenKeyEx(hkey, "shell", 0, KEY_READ, &hkey) ){ + if( !RegOpenKeyEx(hkey, "open", 0, KEY_READ, &hkey) ){ + if( !RegOpenKeyEx(hkey, "command", 0, KEY_READ, &hkey) ){ + namelen = sizeof(name); + len = sizeof(bf); + if( !::RegEnumValue(hkey, 0, name, &namelen, NULL, + NULL, (LPBYTE)bf, &len) ){ + HTML = bf; + } + } + } + } + } + ::RegCloseKey(hkey); +} + +void __fastcall CWebRef::ShowHTML(LPCSTR url) +{ + char cmd[1024]; + MakeCommand(cmd, HTML.c_str(), url); + ::WinExec(cmd, SW_SHOWDEFAULT); +} + + +///------------------------------------------------------ +/// +///CWaitCursor クラス +/// +__fastcall CWaitCursor::CWaitCursor() +{ + sv = Screen->Cursor; + Screen->Cursor = crHourGlass; +} + +__fastcall CWaitCursor::~CWaitCursor() +{ + Screen->Cursor = sv; +} + +void __fastcall CWaitCursor::Delete(void) +{ + Screen->Cursor = sv; +} + +void __fastcall CWaitCursor::Wait(void) +{ + Screen->Cursor = crHourGlass; +} + +///---------------------------------------------------------------- +/// CAlignクラス +void __fastcall CAlign::InitControl(TControl *p, TControl *pB, TFont *pF /*= NULL*/) +{ + tp = p; + OTop = p->Top; + OLeft = p->Left; + OWidth = p->Width; + OHeight = p->Height; + if( pF != NULL ){ + fp = pF; + OFontHeight = pF->Height; + } + + BTop = pB->Top; + BLeft = pB->Left; + BWidth = pB->ClientWidth; + BHeight = pB->ClientHeight; +} + +void __fastcall CAlign::InitControl(TControl *p, RECT *rp, TFont *pF /*= NULL*/) +{ + tp = p; + OTop = p->Top; + OLeft = p->Left; + OWidth = p->Width; + OHeight = p->Height; + if( pF != NULL ){ + fp = pF; + OFontHeight = pF->Height; + } + + BTop = rp->top; + BLeft = rp->left; + BWidth = rp->right - rp->left + 1; + BHeight = rp->bottom - rp->top + 1; +} + +void __fastcall CAlign::NewAlign(TControl *pB) +{ + double Sx = double(pB->ClientWidth)/double(BWidth); + double Sy = double(pB->ClientHeight)/double(BHeight); + tp->SetBounds(int(OLeft * Sx), int(OTop * Sy), int(OWidth * Sx), int(OHeight * Sy)); + if( fp != NULL ){ + if( Sx > Sy ) Sx = Sy; + fp->Height = int(OFontHeight * Sx); + m_FontAdj = Sx; + } + if( tp->ClassNameIs("TComboBox") ){ + ((TComboBox *)tp)->SelLength = 0; + } + else if( tp->ClassNameIs("TLabel") ){ + TLabel *lp = ((TLabel *)tp); + if( lp->Alignment == taRightJustify ){ + lp->AutoSize = FALSE; + lp->AutoSize = TRUE; + } + } +} + +void __fastcall CAlign::NewAlign(TControl *pB, double hx) +{ + double Sx = double(pB->ClientWidth)/double(BWidth); + double Sy = double(pB->ClientHeight)/double(BHeight); + Sy *= hx; + tp->SetBounds(int(OLeft * Sx), int(OTop * Sy), int(OWidth * Sx), int(OHeight * Sy)); + if( fp != NULL ){ + if( Sx > Sy ) Sx = Sy; + fp->Height = int(OFontHeight * Sx); + m_FontAdj = Sx; + } + if( tp->ClassNameIs("TComboBox") ){ + ((TComboBox *)tp)->SelLength = 0; + } +} + +void __fastcall CAlign::NewFont(AnsiString &FontName, BYTE Charset, TFontStyles fs) +{ + if( fp != NULL ){ + fp->Name = FontName; + fp->Charset = Charset; + fp->Style = fs; + if( tp->ClassNameIs("TComboBox") ){ + ((TComboBox *)tp)->SelLength = 0; + } + } +} + +void __fastcall CAlign::NewFixAlign(TControl *pB, int XR) +{ + double Sx = double(pB->ClientWidth - XR) / double(BWidth - XR); + + tp->SetBounds(XR + (OLeft - XR) * Sx, OTop, OWidth * Sx, OHeight); + if( fp != NULL ){ + fp->Height = int(OFontHeight * (Sx < 1.0 ? Sx : 1.0)); + m_FontAdj = Sx; + } + if( tp->ClassNameIs("TComboBox") ){ + ((TComboBox *)tp)->SelLength = 0; + } +} + +void __fastcall CAlign::Resume(void) +{ + if( tp != NULL ){ + tp->Top = OTop; + tp->Left = OLeft; + tp->Width = OWidth; + tp->Height = OHeight; + if( fp != NULL ){ + fp->Height = OFontHeight; + } + } +} +///---------------------------------------------------------------- +/// CAlignListクラス +__fastcall CAlignList::CAlignList(void) +{ + Max = 0; + Cnt = 0; + AlignList = NULL; +} + +__fastcall CAlignList::~CAlignList(){ + if( AlignList != NULL ){ + for( int i = 0; i < Cnt; i++ ){ + delete AlignList[i]; + } + delete AlignList; + AlignList = NULL; + } +} + +void __fastcall CAlignList::Alloc(void) +{ + if( Cnt >= Max ){ + Max = Max ? Max * 2 : 16; + CAlign **np = (CAlign **)new BYTE[sizeof(CAlign*) * Max]; + if( AlignList != NULL ){ + for( int i = 0; i < Cnt; i++ ){ + np[i] = AlignList[i]; + } + delete AlignList; + } + AlignList = np; + } + AlignList[Cnt] = new CAlign; +} +void __fastcall CAlignList::EntryControl(TControl *tp, TControl *pB, TFont *pF /*= NULL*/) +{ + Alloc(); + AlignList[Cnt]->InitControl(tp, pB, pF); + Cnt++; +} + +void __fastcall CAlignList::EntryControl(TControl *tp, RECT *rp, TFont *pF /*= NULL*/){ + Alloc(); + AlignList[Cnt]->InitControl(tp, rp, pF); + Cnt++; +} + +void __fastcall CAlignList::EntryControl(TControl *tp, int XW, int YW, TFont *pF /*= NULL*/){ + RECT rc; + rc.left = rc.top = 0; + rc.right = XW; rc.bottom = YW; + Alloc(); + AlignList[Cnt]->InitControl(tp, &rc, pF); + Cnt++; +} + +void __fastcall CAlignList::NewAlign(TControl *pB) +{ + if( AlignList == NULL ) return; + for( int i = 0; i < Cnt; i++ ){ + AlignList[i]->NewAlign(pB); + } +} + +double __fastcall CAlignList::GetFontAdj(TControl *pB) +{ + for( int i = 0; i < Cnt; i++ ){ + if( AlignList[i]->GetControl() == pB ){ + return AlignList[i]->GetFontAdj(); + } + } + return 1.0; +} + +void __fastcall CAlignList::NewAlign(TControl *pB, TControl *pS, double hx) +{ + for( int i = 0; i < Cnt; i++ ){ + if( AlignList[i]->GetControl() == pS ){ + AlignList[i]->NewAlign(pB, hx); + break; + } + } +} +void __fastcall CAlignList::NewFont(AnsiString &FontName, BYTE Charset, TFontStyles fs) +{ + if( AlignList == NULL ) return; + for( int i = 0; i < Cnt; i++ ){ + AlignList[i]->NewFont(FontName, Charset, fs); + } +} + +void __fastcall CAlignList::NewFixAlign(TControl *pB, int XR) +{ + if( AlignList == NULL ) return; + for( int i = 0; i < Cnt; i++ ){ + AlignList[i]->NewFixAlign(pB, XR); + } +} + +void __fastcall CAlignList::Resume(TControl *pB) +{ + if( AlignList == NULL ) return; + for( int i = 0; i < Cnt; i++ ){ + if( pB == NULL ){ + AlignList[i]->Resume(); + } + else if( pB == AlignList[i]->GetControl() ){ + AlignList[i]->Resume(); + break; + } + } +} + +//--------------------------------------------------------------------------- +void __fastcall SetGroupEnabled(TGroupBox *gp) +{ + int enb = gp->Enabled; + TControl *tp; + int i; + for( i = 0; i < gp->ControlCount; i++ ){ + tp = gp->Controls[i]; + if( tp != NULL ){ + tp->Enabled = enb; + if( tp->ClassNameIs("TGroupBox") ){ + SetGroupEnabled((TGroupBox *)tp); + } + } + } + gp->Font->Color = gp->Enabled ? clBlack : clGrayText; + for( i = 0; i < gp->ControlCount; i++ ){ + tp = gp->Controls[i]; + if( tp != NULL ){ + if( tp->ClassNameIs("TComboBox") ){ + ((TComboBox *)tp)->SelLength = 0; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall KeyEvent(const short *p) +{ + for( ; *p; p++ ){ + keybd_event(BYTE(*p), 0, *p&0x8000 ? KEYEVENTF_KEYUP : 0, 0); + } +} +//--------------------------------------------------------------------------- +// CMULTクラス +__fastcall CMULT::CMULT() +{ + m_pBase = NULL; + m_CNT = m_MAX = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CMULT::Clear(void) +{ + for( int i = 0; i < m_CNT; i++ ){ + delete m_pBase[i].pStr; + } + delete m_pBase; + m_pBase = NULL; + m_CNT = m_MAX = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CMULT::Alloc(void) +{ + int max = m_MAX ? (m_MAX * 2) : 256; + MULTSET *pBase = new MULTSET[max]; + if( m_pBase != NULL ){ + memcpy(pBase, m_pBase, sizeof(MULTSET) * m_CNT); + delete m_pBase; + } + m_pBase = pBase; + m_MAX = max; +} +//--------------------------------------------------------------------------- +int __fastcall CMULT::Add(LPCSTR pKey) +{ + for( int i = 0; i < m_CNT; i++ ){ + if( !strcmp(m_pBase[i].pStr, pKey) ){ + m_pBase[i].Count++; + return 0; + } + } + if( m_CNT >= m_MAX ) Alloc(); + m_pBase[m_CNT].pStr = StrDupe(pKey); + m_pBase[m_CNT].Count = 1; + m_CNT++; + return 1; +} +//--------------------------------------------------------------------------- +int __fastcall CMULT::Set(LPCSTR pKey, int n) +{ + for( int i = 0; i < m_CNT; i++ ){ + if( !strcmp(m_pBase[i].pStr, pKey) ){ + m_pBase[i].Count = n; + return 0; + } + } + if( m_CNT >= m_MAX ) Alloc(); + m_pBase[m_CNT].pStr = StrDupe(pKey); + m_pBase[m_CNT].Count = n; + m_CNT++; + return 1; +} +//--------------------------------------------------------------------------- +static int CMULTcmpCall(const void *s, const void *t) +{ + MULTSET *sp = (MULTSET *)s; + MULTSET *tp = (MULTSET *)t; + return strcmp(sp->pStr, tp->pStr); +} +static int CMULTcmpCount(const void *s, const void *t) +{ + MULTSET *sp = (MULTSET *)s; + MULTSET *tp = (MULTSET *)t; + if( sp->Count == tp->Count ){ + return strcmp(sp->pStr, tp->pStr); + } + else { + return tp->Count - sp->Count; + } +} +void __fastcall CMULT::Sort(void) +{ + if( m_CNT < 2 ) return; + qsort(m_pBase, m_CNT, sizeof(MULTSET), CMULTcmpCall); +} +void __fastcall CMULT::SortCount(void) +{ + if( m_CNT < 2 ) return; + qsort(m_pBase, m_CNT, sizeof(MULTSET), CMULTcmpCount); +} +//--------------------------------------------------------------------------- +int __fastcall CMULT::GetCount(LPCSTR pKey) +{ + for( int i = 0; i < m_CNT; i++ ){ + if( !strcmp(m_pBase[i].pStr, pKey) ) return m_pBase[i].Count; + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall CMULT::GetTotal(void) +{ + int sum = 0; + for( int i = 0; i < m_CNT; i++ ){ + sum += m_pBase[i].Count; + } + return sum; +} +//--------------------------------------------------------------------------- +BOOL __fastcall StrWindowsVer(LPSTR t) +{ + *t = 0; + OSVERSIONINFO osvi; + + memset(&osvi, 0, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + if( !GetVersionEx(&osvi) ) return FALSE; + + switch (osvi.dwPlatformId){ + case VER_PLATFORM_WIN32_NT: // NT, 2000, XP + if( osvi.dwMajorVersion <= 4 ){ + strcat(t, "NT"); + } + else if( osvi.dwMajorVersion == 5 ){ + if( osvi.dwMinorVersion == 0 ){ + strcat(t, "2000"); + } + else if( osvi.dwMinorVersion == 1 ){ + strcat(t, "XP"); + } + } + break; + case VER_PLATFORM_WIN32_WINDOWS: // 95, 98, 98SE, ME + if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0){ + strcat(t, "95"); + if( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ){ + strcat(t, " OSR2" ); + } + } + else if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10){ + strcat(t, "98"); + if( osvi.szCSDVersion[1] == 'A' ){ + strcat(t, "SE" ); + } + } + else if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90){ + strcat(t, "ME"); + } + break; + default: + break; + } + return TRUE; +} +///------------------------------------------------------ +/// +///CCond クラス +/// +int __fastcall GetDataConds(const char *p, int err, TSpeedButton *pButton) +{ + return MainVARI->GetDataConds(p, err, pButton); +} +///------------------------------------------------------ +__fastcall CCond::CCond(int max) +{ + m_CIFMAX = max; + m_f = m_fc = 0; + m_err = 1; + m_pE = new int[max]; + m_pAF = new int[max]; + memset(m_pE, 0, sizeof(int)*max); + memset(m_pAF, 0, sizeof(int)*max); + m_fCond = FALSE; +} +__fastcall CCond::~CCond(void) +{ + delete m_pE; + delete m_pAF; +} +/* +================================================================ + 条件擬似命令の開始のチェック +---------------------------------------------------------------- +---------------------------------------------------------------- +---------------------------------------------------------------- + 0 : 開始できない +================================================================ +*/ +int __fastcall CCond::BgnCond(void) +{ + if( m_f && (!m_pE[m_f-1]) ){ + m_fc++; + return(0); + } + else if( m_f >= m_CIFMAX ){ + if( m_err ){ + m_err = 0; + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + ErrorMB(sys.m_MsgEng ? "Over the nest of condition blocks":"#if〜#endifブロックのネストが制限を超えました."); + } + } + return(0); + } + else { + return(1); + } +} + +/*#$% +================================================================ + 条件ブロックの処理を行う +---------------------------------------------------------------- + p : 文字列のポインタ +---------------------------------------------------------------- + 0 : 条件が偽である + 1 : 条件が真である(行は有効) +---------------------------------------------------------------- +================================================================ +*/ +int __fastcall CCond::CondJob(const char *p, TSpeedButton *pButton) +{ + int d; + + p = SkipSpace(p); + if( !strncmp(p, "#if", 3) ){ + m_fCond = TRUE; + if( BgnCond() ){ + m_pAF[m_f] = m_pE[m_f] = GetDataConds(p+3, m_err, pButton) ? 1 : 0; + m_f++; + } + return(0); + } + else if( !strncmp(p, "#elseif", 7) ){ + if( !m_fc ){ + if( m_f ){ + if( m_pAF[m_f-1] ){ /* 過去に真の時は偽 */ + m_pE[m_f-1] = 0; + } + else { + d = GetDataConds(p+7, m_err, pButton) ? 1 : 0; + m_pE[m_f-1] = d; + m_pAF[m_f-1] |= d; + } + } + else if( m_err ){ + m_err = 0; + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + ErrorMB(sys.m_MsgEng ? "We need <#if> first":"#ifブロックが始まっていません"); + } + } + } + return(0); + } + else if( (!strcmp(p, "#else")) || (!strncmp(p, "#else ", 6)) ){ + if( !m_fc ){ + if( m_f ){ + if( m_pAF[m_f-1] ){ /* 過去に真の時は偽 */ + m_pE[m_f-1] = 0; + } + else { + m_pE[m_f-1] = m_pE[m_f-1] ? 0 : 1; /* 条件の反転 */ + m_pAF[m_f-1] |= m_pE[m_f-1]; + } + } + else if( m_err ){ + m_err = 0; + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + ErrorMB(sys.m_MsgEng ? "We need <#if> first":"#ifブロックが始まっていません"); + } + } + } + return(0); + } + else if( (!strcmp(p, "#endif")) || (!strncmp(p, "#endif ", 7)) ){ + if( m_fc ){ + m_fc--; + } + else if( m_f ){ + m_f--; + } + else if( m_err ){ + m_err = 0; + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + ErrorMB(sys.m_MsgEng ? "We need <#if> first":"#ifブロックが始まっていません"); + } + } + return(0); + } + + if( m_f && (!m_pE[m_f-1]) ){ + return(0); + } + return(1); +} + +/*#$% +================================================================ + 条件ブロックの処理を行う +---------------------------------------------------------------- + p : 文字列のポインタ +---------------------------------------------------------------- + 0 : 条件が偽である + 1 : 条件が真である(行は有効) +---------------------------------------------------------------- +================================================================ +*/ +int __fastcall CCond::CondStr(AnsiString &Cond, const char *p) +{ + p = SkipSpace(p); + if( !strncmp(p, "#if", 3) ){ + Cond = SkipSpace(p+3); + m_f++; + return m_f - 1; + } + else if( !strncmp(p, "#elseif", 7) ){ + Cond = SkipSpace(p+7); + return m_f - 1; + } + else if( (!strcmp(p, "#else")) || (!strncmp(p, "#else ", 6)) ){ + if( m_f == 1 ){ + Cond = "TRUE"; + } + return m_f - 1; + } + else if( (!strcmp(p, "#endif")) || (!strncmp(p, "#endif ", 7)) ){ + m_f--; + if( !m_f ) Cond = "$End"; + return m_f; + } + return 1; +} + +//--------------------------------------------------------------------------- +#define DUMMYMAX 64 +typedef struct { + LPCSTR pName; + int Len; + int Order; +}_DMY_PARA; +static int _CmpDummyOrder(const void *s, const void *t) +{ + _DMY_PARA *pSrc = (_DMY_PARA*)s; + _DMY_PARA *pDis = (_DMY_PARA*)t; + + if( pDis->Len != pSrc->Len ){ + return pDis->Len - pSrc->Len; + } + else { + return pSrc->Order - pDis->Order; + } +} +void __fastcall ConvDummy(AnsiString &ws, LPCSTR p, LPCSTR pNames, LPCSTR pValues) +{ + if( pNames && *pNames ){ + _DMY_PARA *pListNames = new _DMY_PARA[DUMMYMAX]; + LPCSTR *pListValues = new LPCSTR[DUMMYMAX]; + + LPSTR pp, tt; + LPSTR pbNames = StrDupe(SkipSpace(pNames)); + pp = pbNames; + int ncount = 0; + _DMY_PARA *dp = pListNames; + while(*pp && (ncount < DUMMYMAX) ){ + pp = StrDlm(tt, SkipSpace(pp)); + dp->pName = SkipSpace(tt); + dp->Len = strlen(dp->pName); + dp->Order = ncount++; + dp++; + } + LPSTR pbValues = StrDupe(SkipSpace(pValues)); + pp = pbValues; + int vcount = 0; + while(*pp && (vcount < ncount) ){ + pp = StrDlm(tt, SkipSpace(pp)); + pListValues[vcount++] = SkipSpace(tt); + } + if( ncount >= 2 ){ + qsort(pListNames, ncount, sizeof(_DMY_PARA), _CmpDummyOrder); + } + int i, f; + ws = ""; + int fAdd = 0; + int cProc = 0; + while(*p){ + f = FALSE; + if( (*p == '\n')||(*p == '\r')|| !fAdd ){ + LPCSTR pp = SkipSpace(p+fAdd); + fAdd = 1; + if( !strncmp(pp, "#proc", 5) || !strncmp(pp, "#repeat", 7) ){ + cProc++; + } + else if( !strncmp(pp, "#endp", 5) ){ + if( cProc ) cProc--; + } + } + if( !cProc ){ + dp = pListNames; + for( i = 0; i < ncount; i++, dp++ ){ + if( !strncmp(p, dp->pName, dp->Len) ){ + if( dp->Order < vcount ){ + ws += pListValues[dp->Order]; + } + p += dp->Len; + f = TRUE; + break; + } + } + } + if( !f ){ + ws += *p; + p++; + } + } + delete pbValues; + delete pbNames; + delete pListValues; + delete pListNames; + } + else { + ws = p; + } +} +//--------------------------------------------------------------------------- +static WORD GetHash(LPCSTR p) +{ + WORD d = 0; + for( ; *p; p++ ){ + d = WORD(d << 1); + d += *p; + } + return d; +} +//--------------------------------------------------------------------------- +__fastcall CVal::CVal() +{ + m_Max = m_Count = 0; + m_pBase = NULL; + m_fHandleProc = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall CVal::Delete(void) +{ + if( m_pBase ){ + VALDATA *pData = m_pBase; + for( int i = 0; i < m_Count; i++, pData++ ){ + if( pData->pName ) delete pData->pName; + if( pData->pString ) delete pData->pString; + if( pData->pPara ) delete pData->pPara; + } + delete m_pBase; + m_pBase = NULL; + m_Count = m_Max = 0; + } + m_fHandleProc = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall CVal::Alloc(void) +{ + if( m_Count >= m_Max ){ + int max = m_Max ? m_Max * 2 : 16; + VALDATA *pNew = new VALDATA[max]; + memset(pNew, 0, sizeof(VALDATA)*max); + if( m_pBase ) memcpy(pNew, m_pBase, sizeof(VALDATA) * m_Count); + delete m_pBase; + m_pBase = pNew; + m_Max = max; + } +} +//--------------------------------------------------------------------------- +int __fastcall CVal::FindName(LPCSTR pName, BYTE mtype) +{ + if( mtype & (_VAL_NORMAL|_VAL_INIFILE) ) mtype |= _VAL_NORMAL|_VAL_INIFILE; + int i; + WORD h = GetHash(pName); + VALDATA *pData = m_pBase; + for( i = 0; i < m_Count; i++, pData++ ){ + if( (pData->hash == h) && (pData->mtype & mtype) ){ + if( !strcmp(pData->pName, pName) ) return i; + } + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall CVal::Delete(BYTE mtype) +{ + int i; + VALDATA *pData = m_pBase; + for( i = 0; i < m_Count; i++, pData++ ){ + if( pData->mtype & mtype ){ + if( Delete(pData->pName, pData->mtype) ){ + pData--; i--; + } + } + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CVal::Delete(LPCSTR pName, BYTE mtype) +{ + if( !m_Count ) return FALSE; + + int r = FindName(pName, mtype); + VALDATA *pData; + if( r >= 0 ){ + pData = &m_pBase[r]; + delete pData->pName; + delete pData->pString; + if( pData->pPara ) delete pData->pPara; + r = m_Count - r - 1; + if( r > 0 ) memcpy(pData, &pData[1], r*sizeof(VALDATA)); + m_Count--; +#if 0 + FILE *fp = fopen("test.txt", "wt"); + for( int i = 0; i < m_Count; i++ ){ + fprintf(fp, "[%d] [%s]=[%s]\n", m_pBase[i].mtype, m_pBase[i].pName, m_pBase[i].pString); + } + fclose(fp); +#endif + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall CVal::RegisterString(LPCSTR pName, LPCSTR pString, LPCSTR pPara, BYTE mtype) +{ + int r = FindName(pName, mtype); + VALDATA *pData; + if( r >= 0 ){ + pData = &m_pBase[r]; + if( pData->pString ) delete pData->pString; + if( pData->pPara ) delete pData->pPara; + } + else { + Alloc(); + pData = &m_pBase[m_Count++]; + pData->pName = StrDupe(pName); + pData->hash = GetHash(pName); + } + pData->pString = StrDupe(pString); + pData->pPara = (pPara && *pPara) ? StrDupe(pPara) : NULL; + pData->mtype = BYTE(mtype); + if( (mtype == _VAL_PROC) && !strncmp(pName, "On$", 3) ){ + m_fHandleProc = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall CVal::WriteInifile(TMemIniFile *pIniFile, LPCSTR pSect) +{ + pIniFile->EraseSection(pSect); + char bf1[64]; + char bf2[4096]; + AnsiString as, rs; + VALDATA *pData = m_pBase; + int n = 0; + for( int i = 0; i < m_Count; i++, pData++ ){ + if( pData->mtype == _VAL_INIFILE ){ + sprintf(bf1, "V%d", n+1); + rs = pData->pString; + CrLf2Yen(as, rs); + sprintf(bf2, "%s,%s", pData->pName, as.c_str()); + pIniFile->WriteString(pSect, bf1, bf2); + n++; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CVal::ReadInifile(TMemIniFile *pIniFile, LPCSTR pSect) +{ + char bf1[64]; + char bf[4096]; + LPSTR p, t; + AnsiString as, rs; + int n = 1; + while(1){ + sprintf(bf1, "V%d", n++); + as = pIniFile->ReadString(pSect, bf1, ""); + if( as.IsEmpty() ) break; + StrCopy(bf, as.c_str(), sizeof(bf)-1); + p = StrDlm(t, bf); + rs = SkipSpace(p); + Yen2CrLf(as, rs); + RegisterString(t, as.c_str(), NULL, _VAL_INIFILE); + } +} +//--------------------------------------------------------------------------- +__fastcall CMBCS::CMBCS() +{ + m_pLead = NULL; + m_Charset = ANSI_CHARSET; +} +//--------------------------------------------------------------------------- +__fastcall CMBCS::~CMBCS() +{ + if( m_pLead ) delete m_pLead; +} +//--------------------------------------------------------------------------- +void __fastcall CMBCS::Create(void) +{ +// FILE *fp = fopen("DbgLog.txt", "wt"); + if( !m_pLead ) m_pLead = new BYTE[256]; + for( int i = 0; i < 256; i++ ){ + m_pLead[i] = (_mbsbtype((unsigned char *)&i, 0) == _MBC_LEAD); +// fprintf(fp, "%02X:%d\n", i, m_pLead[i]); + } +// fclose(fp); +} +//--------------------------------------------------------------------------- +void __fastcall CMBCS::Create(BYTE charset) +{ + BYTE bak_charset = sys.m_Charset; + m_Charset = charset; + SetMBCP(charset); + Create(); + SetMBCP(bak_charset); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CMBCS::IsLead(BYTE c) +{ + if( !m_pLead ) return FALSE; + return m_pLead[c]; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CMBCS::IsLead(const unsigned char *p) +{ + return IsLead(*p); +} +//--------------------------------------------------------------------------- +#define _SWAP(c) WORD((c<<8)|(c>>8)) +const CONVALPHA _tConvAlphaJA[]={ + {_SWAP(' '), ' '}, +// {_SWAP('!'), '!'}, +// {_SWAP('”'), '"'}, +// {_SWAP('#'), '#'}, +// {_SWAP('$'), '$'}, +// {_SWAP('%'), '%'}, +// {_SWAP('&'), '&'}, +// {_SWAP('’'), 0x27}, +// {_SWAP('('), '('}, +// {_SWAP(')'), ')'}, +// {_SWAP('='), '='}, +// {_SWAP('−'), '-'}, +// {_SWAP('@'), '@'}, +// {_SWAP('+'), '+'}, +// {_SWAP('*'), '*'}, +// {_SWAP(';'), ';'}, +// {_SWAP(':'), ':'}, +// {_SWAP('<'), '<'}, +// {_SWAP('>'), '>'}, + {_SWAP(','), ','}, + {_SWAP('.'), '.'}, +// {_SWAP('?'), '?'}, + {_SWAP('/'), '/'}, + {0, 0}, +}; +const CONVALPHA _tConvAlphaBV[]={ + {0xa140, ' '}, + {0xa14d, ','}, + {0xa14f, '.'}, +// {0xa151, ';'}, +// {0xa152, ':'}, +// {0xa153, '?'}, +// {0xa248, '%'}, +// {0xa249, '@'}, + {0, 0}, +}; +const char _tInhibit[]="!\x22#$%&'()=-^~|\@`[{;+*:}]<>?_"; +//--------------------------------------------------------------------------- +static int __fastcall ConvChar(const CONVALPHA *pAlpha, int code) +{ + for( ; pAlpha->cMBCS; pAlpha++ ){ + if( pAlpha->cMBCS == code ) return pAlpha->cASCII; + } + return code; +} +//--------------------------------------------------------------------------- +int __fastcall CMBCS::ConvAlpha(int code) +{ + switch(m_Charset){ + case SHIFTJIS_CHARSET: // JA + if( (code >= 0x8140) && (code <= 0x81ff) ){ + code = ConvChar(_tConvAlphaJA, code); + } + else if( (code >= 0x824f) && (code <= 0x8258) ){ + code -= (0x824f - 0x30); + } + else if( (code >= 0x8260) && (code <= 0x8279) ){ + code -= (0x8260 - 0x41); + } + else if( (code >= 0x8281) && (code <= 0x829a) ){ + code -= (0x8281 - 0x61); + } + break; + case HANGEUL_CHARSET: // HL + case 134: // BY + if( code == 0xa1a1 ){ + code = 0x20; + } + else if( (code >= 0xa3a1) && (code <= 0xa3ff) ){ + int c = code - (0xa3a1 - 0x21); + if( !strchr(_tInhibit, c) ) code = c; + } + break; + case CHINESEBIG5_CHARSET: // BV + if( (code >= 0xa140) && (code <= 0xa249) ){ + code = ConvChar(_tConvAlphaBV, code); + } + else if( (code >= 0xa2af) && (code <= 0xa2b9) ){ + code -= (0xa2af - 0x30); + } + else if( (code >= 0xa2cf) && (code <= 0xa2e8) ){ + code -= (0xa2cf - 0x41); + } + else if( (code >= 0xa2e9) && (code <= 0xa2fe) ){ + code -= (0xa2cf - 0x61); + } + else if( (code >= 0xa340) && (code <= 0xa343) ){ + code -= (0xa340 - 'w'); + } + break; + default: + break; + } + return code; +} +///---------------------------------------------------------------- +/// 式の計算 +typedef struct { + int pr; /* 優先順位 */ + char cd; /* 演算コード */ + double d; +}VSS; +static int _err; + +/*#$% +======================================================== + 演算子の優先順位を返す +-------------------------------------------------------- + c : 演算子 +-------------------------------------------------------- +-------------------------------------------------------- +======================================================== +*/ +static int __fastcall _cpr(char c) +{ + switch(c){ + case 0: + return(0); + case '+': + return(1); + case '-': + return(1); + case '*': + return(2); + case '/': + return(2); + case '%': + return(2); + case '&': + case '|': + return(3); + default: + return(-1); + } +} + +/*#$% +======================================================== + 演算子かどうかを返す +-------------------------------------------------------- + c : 演算子 +-------------------------------------------------------- +-------------------------------------------------------- +======================================================== +*/ +static int __fastcall _iscd(char c) +{ + if( c == 0 ) return(0); + return( (_cpr(c) == -1) ? 0 : 1 ); +} + +static BOOL __fastcall IsValExp(LPCSTR p, LPCSTR v) +{ + if( (*(p-1) != 'E') && (*(p-1) != 'e') ) return FALSE; + return isdigit(*v); +} +/*#$% +======================================================== + 演算子と値を式管理データに格納する +-------------------------------------------------------- + vs : 式管理データのポインタ + p : 文字列のポインタ +-------------------------------------------------------- + 文字列のポインタ +-------------------------------------------------------- +======================================================== +*/ +static LPCSTR __fastcall _val(VSS *vs, LPCSTR p) +{ + char *t, bf[80]; + + BOOL f = FALSE; + vs->cd = 0; + vs->pr = 0; + for( t = bf; *p; p++ ){ + if( *p == '<' ){ + *t++ = *p; + f++; + } + else if( *p == '>' ){ + *t++ = *p; + if( f ) f--; + } + else if( !f && _iscd(*p) && (t!=bf) && ((t==bf)||!IsValExp(p, bf) ) ){ + vs->cd = *p; + vs->pr = _cpr(*p); + p++; + break; + } + else if( *p == ')' ){ + p++; + break; + } + else if( (*p != ' ')&&(*p != TAB) ){ + *t++ = *p; + } + } + *t = 0; + if( bf[0] == 0 ){ + vs->d = 0.0; + } + else if( (bf[0] == '0') && (bf[1] == 'x') ){ + vs->d = htoin(&bf[2], -1); + } + else { + vs->d = MainVARI->GetMacroDouble(bf); + } + return(p); +} + +/*#$% +======================================================== + 演算子に従って計算を行う +-------------------------------------------------------- + vp : 式管理データのポインタ + vw : 式管理データのポインタ +-------------------------------------------------------- +-------------------------------------------------------- +======================================================== +*/ +static void __fastcall _cop(VSS *vs, VSS *vw) +{ + switch(vs->cd){ + case '+': + vs->d += vw->d; + break; + case '-': + vs->d -= vw->d; + break; + case '*': + vs->d *= vw->d; + break; + case '/': + if( vw->d ){ + vs->d /= vw->d; + } + else { + vs->d = MAXDOUBLE; + } + break; + case '%': + if( vw->d ){ + vs->d = fmod(vs->d, vw->d); + } + else { + vs->d = 0; + } + break; + case '&': + vs->d = UINT(vs->d) & UINT(vw->d); + break; + case '|': + vs->d = UINT(vs->d) | UINT(vw->d); + break; + } +} + +/*#$% +======================================================== + 式計算処理 +-------------------------------------------------------- + vp : 式管理データのポインタ + p : 文字列のポインタ +-------------------------------------------------------- + 文字列のポインタ +-------------------------------------------------------- +======================================================== +*/ +static LPCSTR __fastcall _calc(VSS *vs, LPCSTR p) +{ + VSS vw; + + p = SkipSpace(p); + if( *p ){ + if( *p == '(' ){ + p++; + vw.d = 0; + vw.pr = 0; + vw.cd = '+'; + p = _calc(&vw, p); + if( *p && _iscd(*p) ){ + vw.cd = *p; + vw.pr = _cpr(*p); + p++; + } + } + else { + p = _val(&vw, p); + } + if( vw.pr == 0 ){ + _cop(vs, &vw); + p = SkipSpace(p); + if( _iscd(*p) ){ + vs->cd = *p; + vs->pr = _cpr(*p); + p++; + } + } + else if( vs->pr >= vw.pr ){ + _cop(vs, &vw); + vs->pr = vw.pr; + vs->cd = vw.cd; + p = _calc(vs, p); + } + else { + p = _calc(&vw, p); + _cop(vs, &vw); + vs->pr = vw.pr; + vs->cd = vw.cd; + } + } + return(p); +} + +/*#$% +======================================================== + 式計算処理 +-------------------------------------------------------- + d : 計算結果格納位置のポインタ + p : 文字列のポインタ +-------------------------------------------------------- + ERR +-------------------------------------------------------- +======================================================== +*/ +int __fastcall Calc(double &d, LPCSTR p) +{ + VSS vs; + + p = SkipSpace(p); + LPSTR pBF = new char[strlen(p)+2]; + d = 0; + LPSTR t = pBF; + if( (*p == '-')||(*p == '+') ){ + *t++ = '0'; + } + strcpy(t, p); + _err = TRUE; + vs.d = 0; + vs.pr = 0; + vs.cd = '+'; + _calc(&vs, pBF); + delete pBF; + d = vs.d; + return(_err); +} +/*#$% +======================================================== + 式計算処理 +-------------------------------------------------------- + d : 計算結果格納位置のポインタ + p : 文字列のポインタ +-------------------------------------------------------- + ERR +-------------------------------------------------------- +======================================================== +*/ +int __fastcall CalcI(int &d, LPCSTR p) +{ + double dd; + int r = Calc(dd, p); + if( dd >= 0 ){ + d = int(dd + 0.5); + } + else { + d = int(dd - 0.5); + } + return r; +} +/*#$% +======================================================== + 式計算処理 +-------------------------------------------------------- + d : 計算結果格納位置のポインタ + p : 文字列のポインタ +-------------------------------------------------------- + ERR +-------------------------------------------------------- +======================================================== +*/ +int __fastcall CalcU(int &d, LPCSTR p) +{ + double dd; + int r = Calc(dd, p); + d = int(ABS(dd)+0.5); + return r; +} +short mend[14] = {31,31,28,31,30,31,30,31,31,30,31,30,31,31} ; +short summ[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334}; + +static __fastcall int cleap(int yy) +{ + if ((yy % 4) != 0) + return 0; + else if (((yy % 100) == 0) && ((yy % 400) != 0)) + return 0; + else + return 1; +} + +static __fastcall int mcleap(int y, int m) +{ + if (m == 2) + return cleap(y) ; + else + return 0 ; +} + +void __fastcall GPS2SystemTime(ULONG gps, SYSTEMTIME *sp) +{ + int s,yr,m; + long d; + + d = (gps / 86400) + 6 ; + yr = 1980 ; + while ((d > 0) && (yr <= 2060)) + { + s = cleap(yr) + 365; + d -= s; + yr++ ; + } + if (yr >= 2060) + { + memset(sp, 0, sizeof(SYSTEMTIME)); + return; + } + else + { + d += s ; + yr-- ; + } + m = 1 ; + while(d > 0) + { + d = d - (mend[m] + mcleap(yr,m)); + m++ ; + } + m-- ; + d = d + (mend[m] + mcleap(yr,m)); + +/* + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; +*/ + sp->wYear = WORD(yr); + sp->wMonth = WORD(m); + sp->wDay = WORD(d); + sp->wHour = WORD((gps % 86400) / 3600); + sp->wMinute = WORD((gps % 3600) / 60); + sp->wSecond = WORD(gps % 60); +} + +ULONG __fastcall SystemTime2GPS(SYSTEMTIME *sp) +{ + int dd; + ULONG gps; +/* + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; +*/ + + if (sp->wYear < 1980){ + return 0; + } + if ((sp->wYear == 1980) && (sp->wMonth == 1) && (sp->wDay < 6)){ + return 0; + } + + dd = (sp->wYear - 1980) * 365 + (sp->wYear - 1977) / 4 + summ[sp->wMonth] + + (sp->wMonth + 9) /12 * cleap(sp->wYear) + sp->wDay - 6; + gps = dd * 86400 + (ULONG)sp->wHour * 3600 + sp->wMinute * 60 + sp->wSecond; + + return gps; +} +//*************************************************************************** +//CLIBLクラス +//*************************************************************************** +// +// +//--------------------------------------------------------------------------- +void __fastcall CLIBL::Alloc(void) +{ + int am = m_AMax ? (m_AMax * 2) : 16; + LIBD *pN = new LIBD[am]; + if( m_pBase != NULL ){ + memcpy(pN, m_pBase, sizeof(LIBD)*m_Count); + delete m_pBase; + } + m_pBase = pN; + m_AMax = am; +} +//--------------------------------------------------------------------------- +void __fastcall CLIBL::Delete(void) +{ + if( m_pBase != NULL ){ + LIBD *cp = m_pBase; + for( int i = 0; i < m_Count; i++, cp++ ){ + delete cp->pName; + ::FreeLibrary(cp->hLib); + } + delete m_pBase; + } + m_pBase = NULL; + m_AMax = 0; + m_Count = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CLIBL::Add(LPCSTR pName, HANDLE hLib) +{ + if( m_Count >= m_AMax ) Alloc(); + LIBD *cp = &m_pBase[m_Count]; + cp->pName = StrDupe(pName); + cp->hLib = (HINSTANCE)hLib; + m_Count++; +} +//--------------------------------------------------------------------------- +HANDLE __fastcall CLIBL::LoadLibrary(LPCSTR pName) +{ + LIBD *cp = m_pBase; + for( int i = 0; i < m_Count; i++, cp++ ){ + if( !strcmpi(cp->pName, pName) ){ + if( cp->hLib == NULL ){ + ::SetCurrentDirectory(sys.m_BgnDir); + cp->hLib = ::LoadLibrary(pName); + } + return cp->hLib; + } + } + HANDLE hLib = ::LoadLibrary(pName); + if( hLib != NULL ) Add(pName, hLib); + return hLib; +} +//--------------------------------------------------------------------------- +void __fastcall CLIBL::DeleteLibrary(HANDLE hLib) +{ + if( hLib == NULL ) return; + + LIBD *cp = m_pBase; + for( int i = 0; i < m_Count; i++, cp++ ){ + if( cp->hLib == hLib ){ + ::FreeLibrary((HINSTANCE)hLib); //ja7ude 0522 + cp->hLib = NULL; + break; + } + } +} +//--------------------------------------------------------------------------- diff --git a/ComLib.h b/ComLib.h new file mode 100644 index 0000000..b923290 --- /dev/null +++ b/ComLib.h @@ -0,0 +1,733 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef ComLibH +#define ComLibH +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //ja7ude 0522 + +#define VERBETA "" +#define VERNO "0.45" +#define INI_SCHEMA 3 + +#define DEBUG TRUE +#define MEASIMD FALSE +#define LOGFFT FALSE +#define SHOWERRCOUNT FALSE +#define FORCELANG 0 +#if DEBUG +#include +#define ASSERT(c) assert(c) +#else +#define ASSERT(c) +#endif + +#if SHOWERRCOUNT +#define EPHASE(c) sys.m_ErrPhase = c +enum { + P_NULL, + P_DEMBPF, + P_DEMAGC, + P_DEMLPF, + P_DEMAFC, + P_DEMLOCK, + P_DEMVCO, + P_DEMOUT, + P_SUBCREATE, + P_SUBVIEW, +}; +#else +#define EPHASE(c) +#endif + +#define VERID "beta ver "VERNO +#define VERTTL2 "MMVARI "VERID VERBETA +#define VERTTL VERTTL2" (C) JE3HHT 2004-2010." + +#define WM_WAVE WM_USER+400 +#define CM_CRADIO WM_USER+400 +#define CM_CMML WM_USER+401 +#define CM_CMMR WM_USER+402 + +enum { + waveIN, + waveOUT, + waveCloseFileEdit, + waveCodeView, + wavePlayDlg, + waveCloseRxView, + waveSwapRxView, + waveClockAdj, + waveSeekMacro, + waveDoMacro, + waveLoadMacro, +#if DEBUG + waveRepeatMacro = 1024, +#endif +}; + +enum { + macOnTimer, + macOnPTT, + macOnQSO, + macOnFind, + macOnBand, + macOnStart, + macOnExit, + macOnMode, + macOnSpeed, + macOnClick, + macOnFFTScale, + macOnEnd, +}; +//extern char g_MMLogDir[256]; + +extern const char MONN[]; +extern const char MONU[]; +extern const LPCSTR g_tLogModeTable[]; +extern const LPCSTR g_tDispModeTable[]; +extern const LPCSTR g_tMacEvent[]; +extern const LPCSTR g_tSoundCH[]; +extern const LPCSTR g_tOnOff[]; + +#ifndef LPCUSTR +typedef const unsigned char * LPCUSTR; +typedef unsigned char * LPUSTR; +#endif + +#define ABS(c) (((c)<0)?(-(c)):(c)) +#define AN(p) (sizeof(p)/sizeof(*(p))) +#define CR 0x0d +#define LF 0x0a +#define TAB '\t' + +#define FSBOLD 1 +#define FSITALIC 2 +#define FSUNDERLINE 4 +#define FSSTRIKEOUT 8 + +typedef struct { + AnsiString m_Name; + BYTE m_Charset; + int m_Height; + DWORD m_Style; +}FONTDATA; + +enum { + kkTX, + kkTXOFF, + kkEOF, +}; +typedef struct { + WORD Key; + LPCSTR pName; +}DEFKEYTBL; +extern const DEFKEYTBL KEYTBL[]; +LPCSTR __fastcall ToDXKey(LPCSTR s); +LPCSTR __fastcall ToJAKey(LPCSTR s); +LPCSTR __fastcall GetKeyName(WORD Key); +WORD __fastcall GetKeyCode(LPCSTR pName); + +enum { + fmJA, + fmHL, + fmJOHAB, + fmBV, + fmBY, + fmEND, +}; + +typedef struct { + AnsiString m_CallSign; + + WORD m_DefKey[kkEOF]; + + BOOL m_PTTLock; + + int m_bFSKOUT; + int m_bINVFSK; + AnsiString m_PTTCOM; + + int m_DefaultMode; + int m_LoopBack; + int m_MsgEng; + + LCID m_LCID; + WORD m_wLang; + BOOL m_fShowLangMsg; + BOOL m_fBaseMBCS; + DWORD m_dwVersion; + BOOL m_WinNT; + BOOL m_WinVista; + + AnsiString m_FontName; + BYTE m_FontCharset; + + BYTE m_Charset; + BOOL m_fFontFam; + BOOL m_tFontFam[fmEND]; + + int m_OptionPage; + int m_EventIndex; + + char m_BgnDir[256]; + char m_SoundDir[256]; + char m_ExtLogDir[256]; + char m_LogDir[256]; + char m_TextDir[256]; + char m_MacroDir[256]; + + int m_AutoTimeOffset; + int m_TimeOffset; + int m_TimeOffsetMin; + int m_LogLink; + AnsiString m_LogName; + + BOOL m_fRestoreSubChannel; + BOOL m_fFixWindow; + RECT m_rcWindow; // ウインドウの配置 + int m_WindowState; // ウインドウの状態 + + BOOL m_fAutoTS; + + BOOL m_fSendSingleTone; + + BOOL m_EnableMouseWheel; + AnsiString m_SoundIDRX; + AnsiString m_SoundIDTX; + AnsiString m_SoundMMW; // MMW名 + + AnsiString m_AS; + AnsiString m_MacEvent[macOnEnd]; + + BOOL m_fPlayBack; + int m_PlayBackSpeed; + BOOL m_fShowCtrlCode; + + BOOL m_MFSK_Center; + BOOL m_MFSK_SQ_Metric; + + BOOL m_MacroError; + int m_MaxCarrier; + int m_DecCutOff; + int m_MacBuffSize; + int m_OnTimerInterval; + RECT m_PosMacEdit; + +#if DEBUG + BOOL m_test; + int m_testSN; + AnsiString m_testName; + double m_testGain; + double m_testNoiseGain; + int m_testCarrier1; + int m_testCarrier2; + int m_testDB2; + double m_testGain2; + int m_testQSBTime; + int m_testQSBDB; + BOOL m_test500; + BOOL m_testPhase; + int m_testClockErr; +#endif +#if SHOWERRCOUNT + int m_ErrPhase; +#endif +}SYSSET; +extern SYSSET sys; + +typedef struct { + int WMax; + int Max; + int Sum; + int dBSum; + int dBMax; + int dBWMax; + + int Timer; + int VW; + int LimitL, LimitH; + int Sig; + int DispSig; +}FFTSTG; + +///--------------------------------------------------------- +typedef union { + struct { + BYTE r; + BYTE g; + BYTE b; + BYTE s; + }b; + DWORD d; + TColor c; +}UCOL; +///--------------------------------------------------------- +/// テキスト文字列ストリーマー +class CTextString +{ +private: + LPCSTR rp; +public: + inline __fastcall CTextString(LPCSTR p){ + rp = p; + }; + inline __fastcall CTextString(AnsiString &As){ + rp = As.c_str(); + }; + int __fastcall LoadText(LPSTR tp, int len); +}; + +class CWebRef +{ +private: + AnsiString HTML; +public: + __fastcall CWebRef(); + inline bool __fastcall IsHTML(void){ + return !HTML.IsEmpty(); + }; + void __fastcall ShowHTML(LPCSTR url); +}; + +///--------------------------------------------------------- +/// テキストバッファストリーマー +class StrText{ +public: + char *Bp; + char *Wp; + inline __fastcall StrText(int max){ + Bp = new char[max]; + Clear(); + }; + inline __fastcall ~StrText(){ + delete Bp; + }; + inline char *Printf(char *ct, ...){ + va_list pp; + + va_start(pp, ct); + vsprintf(Wp, ct, pp ); + va_end(pp); + ct = Wp; + Wp += strlen(Wp); + return(ct); + }; + inline void __fastcall Add(LPCSTR sp){ + strcpy(Wp, sp); + Wp += strlen(Wp); + }; + inline void __fastcall Write(void *p, int n){ + memcpy(Wp, p, n); + Wp += n; + *Wp = 0; + }; + inline int __fastcall GetCnt(void){ + return Wp - Bp; + }; + inline void __fastcall Clear(void){ + Wp = Bp; + *Wp = 0; + }; + inline char *__fastcall GetText(void){ + return Bp; + }; +}; + +class CWaitCursor +{ +private: + TCursor sv; +public: + __fastcall CWaitCursor(); + __fastcall ~CWaitCursor(); + void __fastcall Delete(void); + void __fastcall Wait(void); +}; + +///--------------------------------------------------------- +/// コントロールのアラインの管理クラス +class CAlign +{ +private: + int BTop, BLeft; + int BWidth, BHeight; + int OTop, OLeft; + int OWidth, OHeight; + int OFontHeight; + double m_FontAdj; + + TControl *tp; + TFont *fp; +public: + inline __fastcall CAlign(void){ + tp = NULL; + fp = NULL; + m_FontAdj = 1.0; + }; + inline __fastcall ~CAlign(){ + }; + void __fastcall InitControl(TControl *p, TControl *pB, TFont *pF = NULL); + void __fastcall InitControl(TControl *p, RECT *rp, TFont *pF = NULL); + void __fastcall NewAlign(TControl *pB); + inline double __fastcall GetFontAdj(void){return fabs(m_FontAdj);}; + inline TControl *__fastcall GetControl(void){return tp;}; + void __fastcall NewAlign(TControl *pB, double hx); + void __fastcall NewFont(AnsiString &FontName, BYTE Charset, TFontStyles fs); + void __fastcall NewFixAlign(TControl *pB, int XR); + void __fastcall Resume(void); +}; + +///--------------------------------------------------------- +/// コントロールのアラインの管理クラス +class CAlignList +{ +private: + int Max; + int Cnt; + CAlign **AlignList; + void __fastcall Alloc(void); +public: + __fastcall CAlignList(void); + __fastcall ~CAlignList(); + void __fastcall EntryControl(TControl *tp, TControl *pB, TFont *pF = NULL); + void __fastcall EntryControl(TControl *tp, RECT *rp, TFont *pF = NULL); + void __fastcall EntryControl(TControl *tp, int XW, int YW, TFont *pF = NULL); + void __fastcall NewAlign(TControl *pB); + double __fastcall GetFontAdj(TControl *pB); + void __fastcall NewAlign(TControl *pB, TControl *pS, double hx); + void __fastcall NewFont(AnsiString &FontName, BYTE Charset, TFontStyles fs); + void __fastcall NewFixAlign(TControl *pB, int XR); + void __fastcall Resume(TControl *pB); +}; + +int __fastcall FindStringTableStrictly(const LPCSTR _tt[], LPCSTR pName, int max); +int __fastcall FindStringTable(const LPCSTR _tt[], LPCSTR pName, int max); +int __fastcall GetModeIndex(LPCSTR pName); +int __fastcall IsFile(LPCSTR pName); +BOOL __fastcall StrWindowsVer(LPSTR t); + +//--------------------------------------------------------------------------- +int __fastcall SetTimeOffsetInfo(int &Hour, int &Min); +void __fastcall AddjustOffset(SYSTEMTIME *tp); +void __fastcall GetUTC(SYSTEMTIME *tp); +void __fastcall GetLocal(SYSTEMTIME *tp); +LPSTR __fastcall StrDupe(LPCSTR s); + +LPUSTR __fastcall jstrupr(LPUSTR s); +LPUSTR __fastcall jstrlwr(LPUSTR s); +inline LPSTR __fastcall jstrupr(LPSTR s){return (LPSTR)jstrupr(LPUSTR(s));}; +inline LPSTR __fastcall jstrlwr(LPSTR s){return (LPSTR)jstrlwr(LPUSTR(s));}; +LPCSTR __fastcall ConvAndChar(LPSTR t, LPCSTR p); + +void __fastcall OnWave(void); +int __fastcall SetTimeOffsetInfo(int &Hour, int &Min); +WORD __fastcall AdjustRolTimeUTC(WORD tim, char c); +void __fastcall DrawMessage(TCanvas *pCanvas, int XW, int YW, LPCSTR p, int Pos); +void __fastcall FormCenter(TForm *tp, int XW, int YW); +void __fastcall FormCenter(TForm *tp, TForm *pOwner); +void __fastcall FormCenter(TForm *tp); +char *__fastcall lastp(char *p); +char *__fastcall clipsp(char *s); +LPCSTR __fastcall _strdmcpy(LPSTR t, LPCSTR p, char c); +const char *__fastcall StrDlmCpy(char *t, const char *p, char Dlm, int len); +const char *__fastcall StrDlmCpyK(char *t, const char *p, char Dlm, int len); +void __fastcall StrCopy(LPSTR t, LPCSTR s, int n); +char __fastcall LastC(LPCSTR p); +LPCSTR __fastcall GetEXT(LPCSTR Fname); +void __fastcall SetEXT(LPSTR pName, LPSTR pExt); +BOOL __fastcall CheckEXT(LPCSTR pName, LPCSTR pExt); +void __fastcall SetCurDir(LPSTR t, int size); +void __fastcall SetDirName(LPSTR t, LPCSTR pName); +void __fastcall GetFileName(AnsiString &Name, LPCSTR pName); +void __fastcall GetFullPathName(AnsiString &as, LPCSTR pName); +void __fastcall GetFullPathName(AnsiString &as, LPCSTR pName, LPCSTR pFolder); +void __fastcall LimitInt(int *pInt, int min, int max); +void __fastcall LimitDbl(double *pInt, double min, double max); +LPCSTR __fastcall StrDbl(LPSTR bf, double d); +void __fastcall AdjustAS(AnsiString *pAS); +void __fastcall ClipLF(LPSTR sp); +void __fastcall DelCR(AnsiString &ws, LPCSTR s); +void __fastcall DeleteComment(LPSTR bf); +LPSTR __fastcall FillSpace(LPSTR s, int n); +LPCSTR __fastcall SkipToValue(LPCSTR sp); +LPSTR __fastcall SkipSpace(LPSTR sp); +LPCSTR __fastcall SkipSpace(LPCSTR sp); +LPSTR __fastcall DelLastSpace(LPSTR t); +LPSTR __fastcall StrDlm(LPSTR &t, LPSTR p); +LPSTR __fastcall StrDlm(LPSTR &t, LPSTR p, char c); +void __fastcall ChgString(LPSTR t, char a, char b); +void __fastcall DelChar(LPSTR t, char a); +int __fastcall atoin(const char *p, int n); +int __fastcall htoin(const char *p, int n); + +int __fastcall GetActiveIndex(TPageControl *pp); +void __fastcall SetActiveIndex(TPageControl *pp, int page); +int __fastcall InvMenu(TMenuItem *pItem); + +void InfoMB(LPCSTR fmt, ...); +void ErrorMB(LPCSTR fmt, ...); +void WarningMB(LPCSTR fmt, ...); +int YesNoMB(LPCSTR fmt, ...); +int YesNoCancelMB(LPCSTR fmt, ...); +int OkCancelMB(LPCSTR fmt, ...); +void __fastcall ErrorFWrite(LPCSTR pName); + +int __fastcall RemoveL2(LPSTR t, LPSTR ss, LPCSTR pKey, int size); +void __fastcall AddL2(LPSTR t, LPCSTR pKey, LPCSTR s, UCHAR c1, UCHAR c2, int size); +int __fastcall IsJA(const char *s); +LPCSTR __fastcall ClipCall(LPCSTR s); +void __fastcall chgptb(LPSTR s); +LPCSTR __fastcall ClipCC(LPCSTR s); +void __fastcall Yen2CrLf(AnsiString &ws, AnsiString &cs); +void __fastcall CrLf2Yen(AnsiString &ws, AnsiString &cs); + +void __fastcall GetLogFont(LOGFONT *pLogfont, TFont *pFont); +void __fastcall AddStyle(AnsiString &as, BYTE charset, DWORD style); +TFontStyles __fastcall Code2FontStyle(int code); +int __fastcall FontStyle2Code(TFontStyles style); +void __fastcall LoadFontFromInifile(TFont *pFont, LPCSTR pSect, TMemIniFile *pIniFile); +void __fastcall SaveFontToInifile(TFont *pFont, LPCSTR pSect, TMemIniFile *pIniFile); +UCOL __fastcall GetGrade2(UCOL s[2], int x, int xw); +void __fastcall CheckFontCharset(void); +BOOL __fastcall SetLangFont(TFont *pFont, WORD wLang); +void __fastcall SetMBCP(BYTE charset); + +void __fastcall Font2FontData(FONTDATA *pData, TFont *pFont); +void __fastcall FontData2Font(TFont *pFont, FONTDATA *pData); +void __fastcall LoadFontFromInifile(FONTDATA *pData, LPCSTR pSect, TMemIniFile *pIniFile); +void __fastcall SaveFontToInifile(FONTDATA *pData, LPCSTR pSect, TMemIniFile *pIniFile); + +void __fastcall NumCopy(LPSTR t, LPCSTR p); +int __fastcall IsNumbs(LPCSTR p); +int __fastcall IsNumbAll(LPCSTR p); +int __fastcall IsAlphas(LPCSTR p); +int __fastcall IsAlphaAll(LPCSTR p); +int __fastcall IsRST(LPCSTR p); +int __fastcall IsCallChar(char c); +int __fastcall IsCall(LPCSTR p); +int __fastcall IsJA(const char *s); +LPCSTR __fastcall ClipCall(LPCSTR s); +LPCSTR __fastcall ClipCC(LPCSTR s); +/* +inline LPUSTR __fastcall StrDlm(LPUSTR &t, LPUSTR p, char c){return (LPUSTR)StrDlm(LPSTR(t), LPSTR(p), c);}; +inline LPUSTR __fastcall StrDlm(LPUSTR &t, LPUSTR p){return (LPUSTR)StrDlm(LPSTR(t), LPSTR(p));}; +inline LPUSTR __fastcall StrDlm(LPUSTR &t, LPSTR p, char c){return (LPUSTR)StrDlm(LPSTR(t), p, c);}; +inline LPUSTR __fastcall StrDlm(LPUSTR &t, LPSTR p){return (LPUSTR)StrDlm(LPSTR(t), p);}; +*/ +void __fastcall SetGroupEnabled(TGroupBox *gp); +void __fastcall KeyEvent(const short *p); + +int __fastcall Calc(double &d, LPCSTR p); +int __fastcall CalcI(int &d, LPCSTR p); +int __fastcall CalcU(int &d, LPCSTR p); + +void __fastcall GPS2SystemTime(ULONG gps, SYSTEMTIME *sp); +ULONG __fastcall SystemTime2GPS(SYSTEMTIME *sp); + +void __fastcall SetComboBox(TComboBox *pCombo, LPCSTR pList); +void __fastcall GetComboBox(AnsiString &as, TComboBox *pCombo); + +void __fastcall ConvDummy(AnsiString &ws, LPCSTR p, LPCSTR pNames, LPCSTR pValues); + +typedef struct { + LPSTR pStr; + int Count; +}MULTSET; + +class CMULT +{ +private: + int m_CNT; + int m_MAX; + MULTSET *m_pBase; +// LPSTR *m_pStr; +// LPSTR m_pStr[MULTMAX]; +private: + void __fastcall Alloc(void); + +public: + __fastcall CMULT(); + __fastcall ~CMULT(){ + Clear(); + }; + void __fastcall Clear(void); + int __fastcall Add(LPCSTR pKey); + int __fastcall Set(LPCSTR pKey, int n); + int __fastcall GetCount(void){ + return m_CNT; + }; + void __fastcall Sort(void); + void __fastcall SortCount(void); + LPCSTR __fastcall GetText(int n){ + if( (n >= 0) && (n < m_CNT) ){ + return m_pBase[n].pStr; + } + else { + return NULL; + } + }; + int __fastcall GetCount(int n){ + if( (n >= 0) && (n < m_CNT) ){ + return m_pBase[n].Count; + } + else { + return 0; + } + }; + int __fastcall GetCount(LPCSTR pKey); + int __fastcall GetTotal(void); +}; + +//--------------------------------------------------------------------------- +class CCond +{ +private: + int m_CIFMAX; + int m_f; /* 条件のカウンタ */ + int m_fc; /* 偽の場合のレベルカウンタ */ + int *m_pE; /* 状態のネスト配列 */ + int *m_pAF; /* 展開フラグのネスト配列 */ + int m_err; /* エラーチェック */ + BOOL m_fCond; + + int __fastcall BgnCond(void); +public: + int __fastcall CondJob(const char *p, TSpeedButton *pButton); + int __fastcall CondStr(AnsiString &Cond, const char *p); + inline void __fastcall SetCond(void){m_fCond=TRUE;}; + inline BOOL __fastcall IsCond(void){return m_fCond;}; + inline int __fastcall GetLevel(void){return m_f;}; + inline void __fastcall ClearLevel(void){m_f = 0;}; + + __fastcall CCond(int max); + __fastcall ~CCond(void); +}; +//--------------------------------------------------------------------------- +#pragma option -a- // パックの指示 +typedef struct { + WORD hash; + BYTE mtype; + BYTE dummy; + LPCSTR pName; + LPCSTR pString; + LPCSTR pPara; +}VALDATA; +#pragma option -a. // パック解除の指示 + +#define _VAL_NORMAL 1 +#define _VAL_INIFILE 2 +#define _VAL_PROC 4 + +class CVal +{ +private: + VALDATA *m_pBase; + int m_Max; + int m_Count; + BOOL m_fHandleProc; +private: + void __fastcall Alloc(void); + +public: + __fastcall CVal(); + __fastcall ~CVal(){Delete();}; + + inline int __fastcall GetCount(void){return m_Count;}; + inline BOOL __fastcall IsHandleProc(void){return m_fHandleProc;}; + + void __fastcall Delete(void); + void __fastcall Delete(BYTE mtype); + BOOL __fastcall Delete(LPCSTR pName, BYTE mtype); + + int __fastcall FindName(LPCSTR pName, BYTE mtype); + void __fastcall RegisterString(LPCSTR pName, LPCSTR pString, LPCSTR pPara, BYTE mtype); + + void __fastcall WriteInifile(TMemIniFile *pIniFile, LPCSTR pSect); + void __fastcall ReadInifile(TMemIniFile *pIniFile, LPCSTR pSect); + + inline LPCSTR __fastcall GetString(int n){ return m_pBase[n].pString; }; + inline LPCSTR __fastcall GetPara(int n){ return m_pBase[n].pPara; }; +}; +//--------------------------------------------------------------------------- +#pragma option -a- // パックの指示 +typedef struct { + WORD cMBCS; + WORD cASCII; +}CONVALPHA; +#pragma option -a. // パック解除の指示 + +class CMBCS +{ +private: + BYTE *m_pLead; + int m_Charset; +public: + __fastcall CMBCS(); + __fastcall ~CMBCS(); + void __fastcall Create(BYTE charset); + void __fastcall Create(void); + BOOL __fastcall IsLead(BYTE c); + BOOL __fastcall IsLead(const unsigned char *p); + int __fastcall ConvAlpha(int code); + + inline BOOL __fastcall IsCreate(void){return m_pLead != NULL;}; + inline void __fastcall SetCharset(BYTE charset){m_Charset = charset;}; +}; + +//--------------------------------------------------------------------------- +// CLIBLクラス +typedef struct { + LPCSTR pName; + //HANDLE hLib; //ja7ude 0522 + HINSTANCE hLib; +}LIBD; + +typedef void (__stdcall *tmmMacro)(HWND hWnd, LPSTR t, LPCSTR p); +class CLIBL { +public: + int m_AMax; + int m_Count; + LIBD *m_pBase; +private: + void __fastcall Alloc(void); + void __fastcall Add(LPCSTR pName, HANDLE hLib); +public: + CLIBL(){ + m_pBase = NULL; + Delete(); + }; + ~CLIBL(){ + Delete(); + }; + void __fastcall Delete(void); + HANDLE __fastcall LoadLibrary(LPCSTR pName); + void __fastcall DeleteLibrary(HANDLE hLib); +}; +#endif + diff --git a/Comm.cpp b/Comm.cpp new file mode 100644 index 0000000..286affc --- /dev/null +++ b/Comm.cpp @@ -0,0 +1,576 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Comm.h" +#include "ComLib.h" +#include "Dsp.h" + +#define WAITSTAT 0 + +#define DEFFSOUND 3 + +COMMPARA COMM; +void __fastcall InitCOMMPara(void) +{ + COMM.change = 1; +} + +//--------------------------------------------------------------------------- +void CALLBACK MMTimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) +{ + CComm *pComm = (CComm *)dwUser; + if( uID != pComm->m_uMMTimerID ) return; + + pComm->m_FSK.Timer(); +} + +//*************************************************************************** +// CFSK class +__fastcall CFSK::CFSK(void) +{ + m_bPortD = 0; + + m_BLen = 5; + Init(); +#if MeasureAccuracy + QueryPerformanceFrequency(&m_liFreq); + m_liPOld.u.HighPart = -1; +#endif +} +//--------------------------------------------------------------------------- +void __fastcall CFSK::Init(void) +{ + m_hPort = INVALID_HANDLE_VALUE; + m_StgD = -1; + m_Sequence = 0; + m_Count = 0; + m_oFSK = 1; + m_aFSK = -1; +} +//--------------------------------------------------------------------------- +void __fastcall CFSK::SetHandle(HANDLE hPort) +{ + m_hPort = hPort; + m_StgD = -1; + m_Sequence = 0; + m_Count = 0; + m_oFSK = 1; // mark signal + m_aFSK = -1; +} +//--------------------------------------------------------------------------- +// para: Upper16bits Speed(eg. 45) +// Lower16bits b1-b0 Stop (0-1, 1-1.5, 2-2) +// b5-b2 Length +void __fastcall CFSK::SetPara(LONG para) +{ + m_BLen = (para >> 2) & 0x000f; +} +//--------------------------------------------------------------------------- +// This function is called from the TimeProc(). and according to +//MSDN, it may be an illegal operation. MSDN said, Applications +//should not call any system-defined functions from inside a +//callback function, except for several functions. +// However, the EscapeCommFunction() seems to be no problem on my +//PCs with Windows 2000 and Windows XP, but I am not sure if it +//works on every PC. +// BTW, EnterCriticalSection() and LeaveCriticalSection() had problem +//on this, and I gave up to use them.... +// +void __fastcall CFSK::SetPort(int sw) +{ + ::EscapeCommFunction(m_hPort, sw ? SETBREAK : CLRBREAK); +} +//--------------------------------------------------------------------------- +// 11ms interval +void __fastcall CFSK::Timer(void) +{ + if( m_Count <= 0 ){ + switch(m_Sequence){ + case 1: // output data + m_oFSK = (m_NowD & 1) ? 1 : 0; + m_NowD = m_NowD >> 1; + m_BCount--; + if( !m_BCount ){ + m_Sequence++; + } + m_Count = 1; + break; + case 2: // output stop-bit + m_oFSK = 1; + m_Count = 2; + m_Sequence = 0; + break; + default: + if( m_StgD != -1 ){ + m_NowD = m_StgD; + m_StgD = -1; + m_BCount = m_BLen; + m_oFSK = 0; // output start-bit + m_Sequence = 1; + m_Count = 1; + m_Idle = 0; +#if MeasureAccuracy + if( QueryPerformanceCounter(&m_liPCur) ){ + if( m_liPOld.u.HighPart != -1 ){ + m_dlDiff = m_liPCur.QuadPart - m_liPOld.QuadPart; + } + m_liPOld = m_liPCur; + } +#endif + } + else { + m_oFSK = 1; // output mark signal. + m_Idle = 1; +#if MeasureAccuracy + m_liPOld.u.HighPart = -1; +#endif + } + break; + } + } + else { + m_Count--; + } + + if( !IsOpen() ) return; + + if( m_oFSK != m_aFSK ){ + m_aFSK = m_oFSK; + SetPort(m_invFSK ? m_oFSK : !m_oFSK); + } +} + +//--------------------------------------------------------------------------- +__fastcall CComm::CComm(void) +{ + m_CreateON = FALSE; // クリエイトフラグ + m_Command = 0; + m_fHnd = INVALID_HANDLE_VALUE; // ファイルハンドル + m_ptt = m_scan = 0; + m_pEXT = NULL; + + m_Baud = 45; + m_bFSKOUT = FALSE; + m_bINVFSK = FALSE; + + m_pReadTimerExtfsk = NULL; + m_fSendChar = 0; + m_Diddle = diddleLTR; + m_Fig = FALSE; + m_FigOut = FALSE; + m_bDiddleEnabled = TRUE; + m_cGuard = 0; + + m_uMMTimerID = 0; +} + +//----------------------------------------------------------------- +int __fastcall CComm::GetPutChar(void) +{ + int c; + + if( m_QueueExtfsk.IsEmpty() ){ + if( !m_bDiddleEnabled ) return -1; + switch(m_Diddle){ + case diddleLTR: + c = 0x1f; + if( m_Fig ) m_FigOut = TRUE; + break; + default: + c = 0x00; + break; + } + } + else if( m_FigOut ){ + c = 0x1b; + m_FigOut = FALSE; + } + else { + c = m_QueueExtfsk.Pop(); + switch(c){ + case 0x1f: // 11111 LTR + m_Fig = FALSE; + break; + case 0x1b: // 11011 FIG + m_Fig = TRUE; + break; + } + } + return c; +} +//----------------------------------------------------------------- +void __fastcall CComm::PutCharExtfsk( TObject *Sender ) +{ + if( m_cGuard > 0 ){ + m_cGuard--; + return; + } + if( m_pEXT != NULL ){ + if( !m_pEXT->IsTxBusy() ){ + int c = GetPutChar(); + if( c != -1 ) m_pEXT->PutChar(BYTE(c)); + } + } + else if( m_FSK.IsOpen() ){ + if( !m_FSK.IsBusy() ){ + int c = GetPutChar(); + if( c != -1 ) m_FSK.PutByte(BYTE(c)); + } + } +} + +//----------------------------------------------------------------- +void __fastcall CComm::CreateTimer(void) +{ + if( !m_bFSKOUT ) return; + if( !m_fSendChar ) return; + if( !m_pEXT && (m_fHnd == INVALID_HANDLE_VALUE) ) return; + + m_Fig = FALSE; + m_FigOut = FALSE; + + m_QueueExtfsk.Clear(); + if( !m_pReadTimerExtfsk ) m_pReadTimerExtfsk = new TTimer(NULL); + int interval = (1000.0 / m_Baud); + if( interval < 10 ) interval = 10; + m_pReadTimerExtfsk->Interval = interval; + m_pReadTimerExtfsk->Enabled = true; + m_pReadTimerExtfsk->OnTimer = PutCharExtfsk; + m_bDiddleEnabled = TRUE; + m_cGuard = 8; + + if( !m_pEXT && (m_fHnd != INVALID_HANDLE_VALUE) ){ + m_FSK.SetHandle(m_fHnd); + m_FSK.ClearPort(); + + m_uMMTimerID = 0; + if( ::timeGetDevCaps(&m_TimeCaps, sizeof(m_TimeCaps)) == TIMERR_NOERROR ){ + ::timeBeginPeriod(m_TimeCaps.wPeriodMin); + m_uMMTimerID = ::timeSetEvent(11, 0, MMTimeProc, DWORD(this), TIME_PERIODIC); + } + } +} +//----------------------------------------------------------------- +void __fastcall CComm::DeleteTimer(void) +{ + if( m_pReadTimerExtfsk ){ + delete m_pReadTimerExtfsk; + m_pReadTimerExtfsk = NULL; + } + if( m_uMMTimerID ){ + m_FSK.Disable(); + + ::timeKillEvent(m_uMMTimerID); + m_uMMTimerID = 0; + ::timeEndPeriod(m_TimeCaps.wPeriodMin); + } +} + +void __fastcall CComm::SetFSK(int bFSK, int bINV) +{ + m_bFSKOUT = bFSK; + m_bINVFSK = bINV; + m_FSK.SetInvFSK(m_bINVFSK); + if( m_ptt && !m_pReadTimerExtfsk ) CreateTimer(); +} + +/*#$% +============================================================== + 通信回線をクローズする +-------------------------------------------------------------- +-------------------------------------------------------------- +-------------------------------------------------------------- +============================================================== +*/ +void __fastcall CComm::Close(void) +{ + if( m_CreateON ){ + DeleteTimer(); + if( m_pEXT != NULL ){ + delete m_pEXT; + m_pEXT = NULL; + } + else if( m_fHnd != INVALID_HANDLE_VALUE ){ + ::CloseHandle(m_fHnd); + m_fHnd = INVALID_HANDLE_VALUE; + } + m_CreateON = FALSE; + } +} + +/*#$% +============================================================== + 通信回線をオープンする +-------------------------------------------------------------- +PortName : 回線の名前 +pCP : COMMPARAのポインタ(ヌルの時はデフォルトで初期化) +RBufSize : 受信バッファのサイズ(default=2048) +TBufSize : 送信バッファのサイズ(default=2048) +-------------------------------------------------------------- +TRUE/FALSE +-------------------------------------------------------------- +============================================================== +*/ +BOOL __fastcall CComm::Open(LPCTSTR PortName) +{ + if( m_CreateON ) Close(); + m_fHnd = ::CreateFile( PortName, GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if( m_fHnd == INVALID_HANDLE_VALUE ){ + AnsiString as = "\\\\.\\"; + as += PortName; + m_fHnd = ::CreateFile( as.c_str(), GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + } + if( m_fHnd == INVALID_HANDLE_VALUE ){ + m_pEXT = new CEXTFSK(PortName); + if( m_pEXT->IsLib() ){ + LONG para; + para = (m_Baud << 16) | (5 << 2); + m_pEXT->Open(para); + m_CreateON = TRUE; + return TRUE; + } + else { + delete m_pEXT; + m_pEXT = NULL; + } + return FALSE; + } + // setup device buffers + if( ::SetupComm( m_fHnd, DWORD(1024), DWORD(2) ) == FALSE ){ + ::CloseHandle(m_fHnd); + m_fHnd = INVALID_HANDLE_VALUE; + return FALSE; + } + + // purge any information in the buffer + ::PurgeComm( m_fHnd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); + + // set up for overlapped I/O + COMMTIMEOUTS TimeOut; + + TimeOut.ReadIntervalTimeout = 0xffffffff; + TimeOut.ReadTotalTimeoutMultiplier = 0; + TimeOut.ReadTotalTimeoutConstant = 0; + TimeOut.WriteTotalTimeoutMultiplier = 0; + TimeOut.WriteTotalTimeoutConstant = 20000; +// TimeOut.WriteTotalTimeoutConstant = 1; + if( !::SetCommTimeouts( m_fHnd, &TimeOut ) ){ + ::CloseHandle( m_fHnd ); + m_fHnd = INVALID_HANDLE_VALUE; + return FALSE; + } + ::GetCommState( m_fHnd, &m_dcb ); + m_dcb.BaudRate = 9600; + m_dcb.fBinary = TRUE; + m_dcb.ByteSize = 8; + m_dcb.Parity = NOPARITY; + m_dcb.StopBits = ONESTOPBIT; + m_dcb.XonChar = 0x11; // XON + m_dcb.XoffChar = 0x13; // XOFF + m_dcb.fParity = 0; + m_dcb.fOutxCtsFlow = FALSE; + m_dcb.fInX = m_dcb.fOutX = FALSE; + m_dcb.fOutxDsrFlow = FALSE; + m_dcb.EvtChar = 0x0d; + + m_dcb.fRtsControl = RTS_CONTROL_DISABLE; // 送信禁止 + m_dcb.fDtrControl = DTR_CONTROL_DISABLE; // 送信禁止 + +// m_dcb.fTXContinueOnXoff = TRUE; + m_dcb.XonLim = USHORT(1024/4); // 1/4 of RBufSize + m_dcb.XoffLim = USHORT(1024*3/4); // 3/4 of RBufSize + m_dcb.DCBlength = sizeof( DCB ); + + if( !::SetCommState( m_fHnd, &m_dcb ) ){ + ::CloseHandle( m_fHnd ); + m_fHnd = INVALID_HANDLE_VALUE; + return FALSE; + } + + // get any early notifications + if( !::SetCommMask( m_fHnd, EV_RXFLAG ) ){ + ::CloseHandle(m_fHnd); + m_fHnd = INVALID_HANDLE_VALUE; + return FALSE; + } + m_CreateON = TRUE; + return TRUE; +} +//----------------------------------------------------------------- +// PTT切り替え用 +int __fastcall CComm::PTTOpen(void) +{ + if( !m_CreateON ){ + if( !strcmpi(sys.m_PTTCOM.c_str(), "NONE") ) return FALSE; + Open(sys.m_PTTCOM.c_str()); + if( !m_CreateON ) return FALSE; + } + return TRUE; +} +//----------------------------------------------------------------- +// PTT切り替え用 +int __fastcall CComm::SetPTT(void) +{ + if( m_pEXT != NULL ){ + m_pEXT->SetPTT(m_ptt); + } + else if( m_fHnd != INVALID_HANDLE_VALUE ){ + ::EscapeCommFunction(m_fHnd, m_ptt ? SETRTS : CLRRTS); + ::EscapeCommFunction(m_fHnd, m_ptt ? SETDTR : CLRDTR); + } + if( m_ptt ){ + CreateTimer(); + } + else { + DeleteTimer(); + } + return m_ptt; +} +//----------------------------------------------------------------- +// PTT切り替え用 +void __fastcall CComm::SetPTT(int sw) +{ + m_ptt = sw; + + if( !PTTOpen() ) return; + if( !SetPTT() && (!sys.m_PTTLock) ) Close(); +} + +/******************************************************************* + EXTFSK.DLL +*******************************************************************/ +__fastcall CEXTFSK::CEXTFSK(LPCSTR pName) +{ + char Name[128]; + sprintf(Name, "%s.%s", pName, strcmpi(pName, "EXTFSK") ? "fsk" : "dll"); + + fextfskOpen = NULL; + fextfskClose = NULL; + fextfskIsTxBusy = NULL; + fextfskPutChar = NULL; + fextfskSetPTT = NULL; + + m_hLib = ::LoadLibrary(Name); + if( m_hLib != NULL ){ + fextfskOpen = (extfskOpen)GetProc("_extfskOpen"); + fextfskClose = (extfskClose)GetProc("_extfskClose"); + fextfskIsTxBusy = (extfskIsTxBusy)GetProc("_extfskIsTxBusy"); + fextfskPutChar = (extfskPutChar)GetProc("_extfskPutChar"); + fextfskSetPTT = (extfskSetPTT)GetProc("_extfskSetPTT"); + } +} + +//--------------------------------------------------------------------- +__fastcall CEXTFSK::~CEXTFSK() +{ + if( m_hLib != NULL ){ + Close(); + ::FreeLibrary(m_hLib); + m_hLib = NULL; + } +} + +//--------------------------------------------------------------------- +FARPROC CEXTFSK::GetProc(LPCSTR pName) +{ + FARPROC fn = ::GetProcAddress(m_hLib, pName+1); + if( fn == NULL ){ + fn = ::GetProcAddress(m_hLib, pName); + } + return fn; +} + +long __fastcall CEXTFSK::Open(long para) +{ + if( !m_hLib || !fextfskOpen ) return FALSE; + return fextfskOpen(para); +} + +void __fastcall CEXTFSK::Close(void) +{ + if( !m_hLib || !fextfskClose ) return; + fextfskClose(); +} + +long __fastcall CEXTFSK::IsTxBusy(void) +{ + if( !m_hLib || !fextfskIsTxBusy ) return FALSE; + return fextfskIsTxBusy(); +} + +void __fastcall CEXTFSK::PutChar(BYTE c) +{ + if( !m_hLib || !fextfskPutChar ) return; + fextfskPutChar(c); +} + +void __fastcall CEXTFSK::SetPTT(long tx) +{ + if( !m_hLib || !fextfskSetPTT ) return; + fextfskSetPTT(tx); +} + +//-------------------------------------------------------------------------------------------------- +CQUE::CQUE(void) +{ + Clear(); +} + +//-------------------------------------------------------------------------------------------------- +void __fastcall CQUE::Clear(void) +{ + m_R = 0; + m_W = 0; + m_C = 0; +} +//-------------------------------------------------------------------------------------------------- +void __fastcall CQUE::Push(BYTE c) +{ + if( m_C < QUEMAX ){ + m_tFifo[m_W++] = c; + if( m_W >= QUEMAX ) m_W = 0; + m_C++; + } +} + +//-------------------------------------------------------------------------------------------------- +BYTE __fastcall CQUE::Pop(void) +{ + if( !m_C ) return 0; + + BYTE c = m_tFifo[m_R++]; + if( m_R >= QUEMAX ) m_R = 0; + m_C--; + return c; +} + diff --git a/Comm.h b/Comm.h new file mode 100644 index 0000000..d97297f --- /dev/null +++ b/Comm.h @@ -0,0 +1,217 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +///---------------------------------------------------------- +/// RS232C通信クラス +/// +/// (C) JE3HHT Makoto.Mori +/// +//--------------------------------------------------------------------------- +#ifndef CommH +#define CommH +//--------------------------------------------------------------------------- +#include +#include +//--------------------------------------------------------------------------- +#define CR 0x0d +#define LF 0x0a +#define COMM_CLOSE 1 +//--------------------------------------------------------------------------- + +#define MeasureAccuracy FALSE +//--------------------------------------------------------------------------- +class CFSK { +private: + volatile HANDLE m_hPort; + + volatile BYTE m_bPortD; + + volatile int m_BLen; + + volatile int m_Sequence; + volatile int m_Count; + volatile int m_BCount; + volatile int m_NowD; + volatile int m_StgD; + + volatile int m_Idle; + + volatile int m_invFSK; + volatile int m_oFSK; + volatile int m_aFSK; + +#if MeasureAccuracy + LARGE_INTEGER m_liFreq; + LARGE_INTEGER m_liPCur, m_liPOld; + DWORDLONG m_dlDiff; +#endif +public: + inline int __fastcall IsOpen(void){ return m_hPort != INVALID_HANDLE_VALUE;}; + +public: + __fastcall CFSK(void); + void __fastcall Init(void); + void __fastcall Timer(void); + void __fastcall SetPara(LONG para); + inline void __fastcall Disable(void){m_hPort = INVALID_HANDLE_VALUE;}; + void __fastcall SetHandle(HANDLE hPort); + void __fastcall PutByte(BYTE c){m_StgD = c;}; + void __fastcall SetPort(int sw); + void __fastcall ClearPort(void){ + SetPort(m_invFSK ? m_oFSK : !m_oFSK); + } + inline int __fastcall IsBusy(void){ + return (m_StgD != -1) ? TRUE : FALSE; + }; + inline void __fastcall SetInvFSK(int inv){ + m_invFSK = inv; + m_aFSK = -1; + }; + inline void __fastcall SetDelay(int n){m_Count = n;}; +#if MeasureAccuracy + inline DWORDLONG __fastcall GetPDiff(void){return m_dlDiff;}; + inline DWORDLONG __fastcall GetPFreq(void){return m_liFreq.QuadPart;}; +#endif +}; + +//Added by JA7UDE (April 17, 2010) +#define EXTFSK_CHECK_INTERVAL 22 +//Till here + +#define QUEMAX 1024 +class CQUE { +private: + int m_R; + int m_W; + int m_C; + BYTE m_tFifo[QUEMAX]; +public: + CQUE(void); + void __fastcall Clear(void); + void __fastcall Push(BYTE c); + BYTE __fastcall Pop(void); + + inline BOOL IsEmpty(void){return m_C == 0;}; +}; + +typedef struct { + int change; + + int Baud; + int BitLen; + int Stop; + int Parity; +}COMMPARA; +extern COMMPARA COMM; + +typedef long (__stdcall *extfskOpen)(long para); +typedef void (__stdcall *extfskClose)(void); +typedef long (__stdcall *extfskIsTxBusy)(void); +typedef void (__stdcall *extfskPutChar)(BYTE c); +typedef void (__stdcall *extfskSetPTT)(long tx); + +class CEXTFSK +{ +private: + //HANDLE m_hLib; //ja7ude 0522 + HINSTANCE m_hLib; + extfskOpen fextfskOpen; + extfskClose fextfskClose; + extfskIsTxBusy fextfskIsTxBusy; + extfskPutChar fextfskPutChar; + extfskSetPTT fextfskSetPTT; +private: + FARPROC GetProc(LPCSTR pName); + +public: + __fastcall CEXTFSK(LPCSTR pName); + __fastcall ~CEXTFSK(); + long __fastcall IsLib(void){return m_hLib != NULL;}; + long __fastcall Open(long para); + void __fastcall Close(void); + long __fastcall IsTxBusy(void); + void __fastcall PutChar(BYTE c); + void __fastcall SetPTT(long tx); +}; + +#define COMM_TXBUFSIZE MODBUFMAX +class CComm +{ +public: + BOOL m_CreateON; // クリエイトフラグ + volatile int m_Command; + DCB m_dcb; // DCB + HANDLE m_fHnd; // ファイルハンドル + + int m_ptt; + int m_scan; + CEXTFSK *m_pEXT; + + int m_Baud; + int m_bFSKOUT; + int m_bINVFSK; + + int m_cGuard; + int m_Fig; + int m_FigOut; + int m_Diddle; + int m_fSendChar; + int m_bDiddleEnabled; + CQUE m_QueueExtfsk; + TTimer *m_pReadTimerExtfsk; + + TIMECAPS m_TimeCaps; + UINT m_uMMTimerID; + CFSK m_FSK; +protected: +private: + int __fastcall PTTOpen(void); + void __fastcall CreateTimer(void); + void __fastcall DeleteTimer(void); + +public: + __fastcall CComm(void); + __fastcall ~CComm(){ + Close(); + }; + inline BOOL __fastcall IsOpen(void){ + return m_CreateON; + }; + BOOL __fastcall Open(LPCTSTR PortName); + void __fastcall Close(void); + int __fastcall SetPTT(void); + void __fastcall SetPTT(int sw); + + void __fastcall SetFSK(int bFSK, int bINV); + int __fastcall GetPutChar(void); + void __fastcall PutCharExtfsk( TObject *Sender ); //Added by JA7UDE on April 5, 2010 + void __fastcall SetSendChar(BOOL f){m_fSendChar = f;}; // Added by JE3HHT on Sep.1010 + void __fastcall SetDiddle(int d){m_Diddle = d;}; // Added by JE3HHT on Sep.1010 + BOOL __fastcall IsBaudChange(double speed){return int(speed) != m_Baud;}; + void __fastcall SetMark(void){m_bDiddleEnabled = FALSE;}; +}; + +void __fastcall InitCOMMPara(void); +#endif + + + + + + diff --git a/DSP.cpp b/DSP.cpp new file mode 100644 index 0000000..ae746ee --- /dev/null +++ b/DSP.cpp @@ -0,0 +1,6640 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +#include + +#include "DSP.h" +#include "ComLib.h" +#include "Main.h" +double SAMPFREQ=11025; +int SAMPBASE=11025; +double SAMPTXOFFSET=0; +int SAMPTYPE=0; +double DEMSAMPFREQ=11025*0.5; + +CVARICODE g_VariCode; +CSinTable g_SinTable; +int g_tBpfTaps[]={64, 80, 128, 256}; +//--------------------------------------------------------------------------- +#pragma package(smart_init) + +const DWORD _tBitData[]={ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x00000100, 0x00000200, 0x00000400, 0x00000800, + 0x00001000, 0x00002000, 0x00004000, 0x00008000, + 0x00010000, 0x00020000, 0x00040000, 0x00080000, + 0x00100000, 0x00200000, 0x00400000, 0x00800000, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, +}; + +const BYTE tQPSK_Viterbi[32]={ + 2, 1, 3, 0, 3, 0, 2, 1, 0, 3, 1, 2, 1, 2, 0, 3, + 1, 2, 0, 3, 0, 3, 1, 2, 3, 0, 2, 1, 2, 1, 3, 0, +}; + +//--------------------------------------------------------------------------- +BOOL __fastcall IsRTTY(int m) +{ + return (m==MODE_RTTY)||(m==MODE_U_RTTY); +} +//--------------------------------------------------------------------------- +BOOL __fastcall Is170(int m) +{ + return (m==MODE_FSKW)||IsRTTY(m); +} +//--------------------------------------------------------------------------- +BOOL __fastcall IsBPSK(int m) +{ + return (m==MODE_BPSK)||(m==MODE_N_BPSK); +} +//--------------------------------------------------------------------------- +BOOL __fastcall IsQPSK(int m) +{ + return (m==MODE_qpsk_L)||(m==MODE_qpsk_U); +} +//--------------------------------------------------------------------------- +BOOL __fastcall IsPSK(int m) +{ + return IsBPSK(m)||IsQPSK(m); +} +//--------------------------------------------------------------------------- +BOOL __fastcall IsFSK(int m) +{ + return (m==MODE_GMSK)||(m==MODE_FSK); +} +//--------------------------------------------------------------------------- +BOOL __fastcall IsMFSK(int m) +{ + return (m==MODE_mfsk_L)||(m==MODE_mfsk_U); +} +//--------------------------------------------------------------------------- +// FIRフィルタのたたき込み演算 +double __fastcall DoFIR(double *hp, double *zp, double d, int tap) +{ + memcpy(zp, &zp[1], sizeof(double)*tap); + zp[tap] = d; + d = 0.0; + for( int i = 0; i <= tap; i++, hp++, zp++ ){ + d += (*zp) * (*hp); + } + return d; +} +//--------------------------------------------------------------------------- +//ベッセル関数 +static double __fastcall I0(double x) +{ + double sum, xj; + int j; + + sum = 1.0; + xj = 1.0; + j = 1; + while(1){ + xj *= ((0.5 * x) / (double)j); + sum += (xj*xj); + j++; + if( ((0.00000001 * sum) - (xj*xj)) > 0 ) break; + } + return(sum); +} +//--------------------------------------------------------------------------- +//FIRフィルタの設計 +void __fastcall MakeFilter(double *HP, FIR *fp) +{ + if( fp->n <= 1 ){ + HP[0] = 1.0; + return; + } + if( fp->typ == ffGAUSSIAN ){ + MakeGaussian(HP, fp->n, fp->fcl, fp->fs, fp->gain); + return; + } + int j, m; + double alpha, win, fm, w0, sum; + double *hp; + + if( fp->typ == ffHPF ){ + fp->fc = 0.5*fp->fs - fp->fcl; + } + else if( fp->typ != ffLPF ){ + fp->fc = (fp->fch - fp->fcl)/2.0; + } + else { + fp->fc = fp->fcl; + } + if( fp->att >= 50.0 ){ + alpha = 0.1102 * (fp->att - 8.7); + } + else if( fp->att >= 21 ){ + alpha = (0.5842 * pow(fp->att - 21.0, 0.4)) + (0.07886 * (fp->att - 21.0)); + } + else { + alpha = 0.0; + } + + hp = fp->hp; + sum = PI*2.0*fp->fc/fp->fs; + if( fp->att >= 21 ){ // インパルス応答と窓関数を計算 + for( j = 0; j <= (fp->n/2); j++, hp++ ){ + fm = (double)(2 * j)/(double)fp->n; + win = I0(alpha * sqrt(1.0-(fm*fm)))/I0(alpha); + if( !j ){ + *hp = fp->fc * 2.0/fp->fs; + } + else { + *hp = (1.0/(PI*(double)j))*sin((double)j*sum)*win; + } + } + } + else { // インパルス応答のみ計算 + for( j = 0; j <= (fp->n/2); j++, hp++ ){ + if( !j ){ + *hp = fp->fc * 2.0/fp->fs; + } + else { + *hp = (1.0/(PI*(double)j))*sin((double)j*sum); + } + } + } + hp = fp->hp; + sum = *hp++; + for( j = 1; j <= (fp->n/2); j++, hp++ ) sum += 2.0 * (*hp); + hp = fp->hp; + if( sum > 0.0 ){ + for( j = 0; j <= (fp->n/2); j++, hp++ ) (*hp) /= sum; + } + + // 周波数変換 + + if( fp->typ == ffHPF ){ + hp = fp->hp; + for( j = 0; j <= (fp->n/2); j++, hp++ ) (*hp) *= cos((double)j*PI); + } + else if( fp->typ != ffLPF ){ + w0 = PI * (fp->fcl + fp->fch) / fp->fs; + if( fp->typ == ffBPF ){ + hp = fp->hp; + for( j = 0; j <= (fp->n/2); j++, hp++ ) (*hp) *= 2.0*cos((double)j*w0); + } + else { + hp = fp->hp; + *hp = 1.0 - (2.0 * (*hp)); + for( hp++, j = 1; j <= (fp->n/2); j++, hp++ ) (*hp) *= -2.0*cos((double)j*w0); + } + } + for( m = fp->n/2, hp = &fp->hp[m], j = m; j >= 0; j--, hp-- ){ + *HP++ = (*hp) * fp->gain; + } + for( hp = &fp->hp[1], j = 1; j <= (fp->n/2); j++, hp++ ){ + *HP++ = (*hp) * fp->gain; + } +} +//--------------------------------------------------------------------------- +//FIRフィルタの設計 +void __fastcall MakeFilter(double *HP, int tap, int type, double fs, double fcl, double fch, double att, double gain) +{ + FIR fir; + + fir.typ = type; + fir.n = tap; + fir.fs = fs; + fir.fcl = fcl; + fir.fch = fch; + fir.att = att; + fir.gain = gain; + MakeFilter(HP, &fir); +} +//--------------------------------------------------------------------------- +//FIRフィルタ(ヒルベルト変換フィルタ)の設計 +// +void __fastcall MakeHilbert(double *H, int N, double fs, double fc1, double fc2) +{ + int L = N / 2; + double T = 1.0 / fs; + + double W1 = 2 * PI * fc1; + double W2 = 2 * PI * fc2; + + // 2*fc2*T*SA((n-L)*W2*T) - 2*fc1*T*SA((n-L)*W1*T) + + double w; + int n; + double x1, x2; + for( n = 0; n <= N; n++ ){ + if( n == L ){ + x1 = x2 = 0.0; + } + else if( (n - L) ){ + x1 = ((n - L) * W1 * T); + x1 = cos(x1) / x1; + x2 = ((n - L) * W2 * T); + x2 = cos(x2) / x2; + } + else { + x1 = x2 = 1.0; + } + w = 0.54 - 0.46 * cos(2*PI*n/(N)); + H[n] = -(2 * fc2 * T * x2 - 2 * fc1 * T * x1) * w; + } + + if( N < 8 ){ + w = 0; + for( n = 0; n <= N; n++ ){ + w += fabs(H[n]); + } + if( w ){ + w = 1.0 / w; + for( n = 0; n <= N; n++ ){ + H[n] *= w; + } + } + } +} +//--------------------------------------------------------------------- +void __fastcall MakeGaussian(double *H, int N, double fc, double fs, double B) +{ + double W = fc; + double T = 1.0 / fs; + double k = B * T * W; + + double LN = 2.0/log(2.0); + int L = N / 2; + int i, n; + double sum = 0; + for( i = 0; i <= N; i++ ){ + n = i - L; + if( n < 0 ) n = -n; + double d = -sqrt(LN) * PI * k * n; + H[i] = sqrt(LN*PI) * k * exp(d); + sum += H[i]; + } + if( sum ){ + sum = 1.0 / sum; + for( i = 0; i <= N; i++ ){ + H[i] *= sum; + } + } +} +//--------------------------------------------------------------------- +// 周波数特性グラフ(フィルタスレッド内でコールしてはいけない) +// +// H(ejωT) = [Σ0]Hm cos(mωT) - j[Σ1]Hm sin(mωT) +// +void __fastcall DrawGraph(Graphics::TBitmap *pBitmap, const double *H, int Tap, int &nmax, int init, TColor col, double SampFreq) +{ + int k, x, y; + double f, gdb, g, pi2t, fs; + double max; + char bf[80]; + + TCanvas *tp = pBitmap->Canvas; + TRect rc; + rc.Left = 0; + rc.Right = pBitmap->Width; + rc.Top = 0; + rc.Bottom = pBitmap->Height; + if( init ){ + tp->Brush->Color = clWhite; + tp->FillRect(rc); + } + int LM; // 周波数表示のあるライン数 + int DM; // 内部線の数 + int MM; // 実線の間隔 + max = 3000; + fs = SampFreq; + if( nmax ){ + max = nmax; + } + else { + nmax = max; + } +#if 0 + LM = 4; + DM = 19; + MM = 5; +#else + switch(nmax){ + case 3000: + LM = 3; + DM = 14; + MM = 5; + break; + case 100: + case 200: + case 2000: + LM = 4; + DM = 19; + MM = 5; + break; + case 400: + case 800: + case 4000: + LM = 4; + DM = 19; + MM = 5; + break; + default: // 6000 + LM = 3; + DM = 11; + MM = 4; + break; + } +#endif + int XL = 32; + int XR = pBitmap->Width - 16; + int YT = 16; + int YB = pBitmap->Height - 24; + + int i; + if( init ){ + tp->Pen->Color = clBlack; + tp->Font->Size = 8; + tp->MoveTo(XL, YT); tp->LineTo(XR, YT); tp->LineTo(XR, YB); tp->LineTo(XL, YB); tp->LineTo(XL, YT); + tp->Pen->Color = clGray; + for( i = 0; i < 7; i++ ){ + tp->Pen->Style = (i & 1) ? psSolid : psDot; + y = (int)(double(i + 1) * double(YB - YT)/8.0 + YT); + tp->MoveTo(XL, y); tp->LineTo(XR, y); + } + for( i = 1; i < 5; i++ ){ + y = (int)(double(i) * double(YB - YT)/4.0 + YT); + sprintf( bf, "-%2u", (80 / 4)*i ); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(XL - 6 - tp->TextWidth(bf), y - (tp->TextHeight(bf)/2), bf); + } + strcpy(bf, "dB"); + tp->TextOut(XL - 6 - tp->TextWidth(bf), YT-(tp->TextHeight(bf)/2), bf); + for( i = 1; i <= DM; i++ ){ + tp->Pen->Style = (i % MM) ? psDot : psSolid; + x = (int)(double(i) * double(XR - XL)/double(DM+1) + XL); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + } + for( i = 0; i <= LM; i++ ){ + x = (int)(double(i) * double(XR - XL)/double(LM) + XL); + sprintf(bf, "%4.0lf", (max*i)/LM); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(x - (tp->TextWidth(bf)/2), YB + 6, bf); + } + tp->Pen->Color = clRed; + tp->Pen->Style = psDot; + x = (int)(XL + (fs/2) * (double(XR-XL)/max)); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + + tp->Pen->Color = clBlue; + tp->Pen->Style = psSolid; + } + int ay = 0; + int apy = 0; + double ra, im; + pi2t = 2.0 * PI / fs; + tp->Pen->Color = col; + for( x = XL, f = 0.0; x < XR; x++, f += (max/double(XR-XL)) ){ + if( Tap ){ + ra = im = 0.0; + for( k = 0; k <= Tap; k++ ){ + ra += H[k] * cos(pi2t*f*k); + if( k ) im -= H[k] * sin(pi2t*f*k); + } + if( ra * im ){ + g = sqrt(ra * ra + im * im); + } + else { + g = 0.0; + } + } + else { + g = 1.0; + } + if( g == 0 ) g = 1.0e-38; + gdb = 20*0.4342944*log(fabs(g)) + 80.0; + if( gdb < 0.0 ) gdb = 0.0; + gdb = (gdb * double(YB-YT))/80.0; + y = YB - (int)gdb; + if( x == XL ){ + tp->MoveTo(x, y); + tp->LineTo(x, y); + } + else { + tp->MoveTo(x-1, ay); + tp->LineTo(x, y); + } + ay = y; + + double ph = 0; + if( ra ){ + ph = atan2(im, ra); + } + int yc = (YB + YT) / 2; + y = yc + (ph * (YB - YT) / (4*PI)); + if( x != XL ){ + tp->Pen->Color = clRed; + tp->MoveTo(x-1, apy); + tp->LineTo(x, y); + tp->Pen->Color = clBlue; + } + apy = y; + } +} + + +//--------------------------------------------------------------------- +// 周波数特性グラフ(フィルタスレッド内でコールしてはいけない) +// +// +void __fastcall DrawGraphIIR(Graphics::TBitmap *pBitmap, double a0, double a1, double a2, double b1, double b2, int &nmax, int init, TColor col, double SampFreq) +{ + int x, y; + double f, gdb, g, pi2t, pi4t, fs; + double max; + char bf[80]; + + TCanvas *tp = pBitmap->Canvas; + TRect rc; + rc.Left = 0; + rc.Right = pBitmap->Width; + rc.Top = 0; + rc.Bottom = pBitmap->Height; + if( init ){ + tp->Brush->Color = clWhite; + tp->FillRect(rc); + } + int LM; // 周波数表示のあるライン数 + int DM; // 内部線の数 + int MM; // 実線の間隔 + max = 4000; + fs = SampFreq; + if( nmax ){ + max = nmax; + } + else { + nmax = max; + } + switch(nmax){ + case 3000: + LM = 3; + DM = 14; + MM = 5; + break; + case 100: + case 200: + case 2000: + LM = 4; + DM = 19; + MM = 5; + break; + case 400: + case 800: + case 4000: + LM = 4; + DM = 19; + MM = 5; + break; + default: // 6000 + LM = 3; + DM = 11; + MM = 4; + break; + } + int XL = 32; + int XR = pBitmap->Width - 16; + int YT = 16; + int YB = pBitmap->Height - 24; + + int i; + if( init ){ + tp->Pen->Color = clBlack; + tp->Font->Size = 8; + tp->MoveTo(XL, YT); tp->LineTo(XR, YT); tp->LineTo(XR, YB); tp->LineTo(XL, YB); tp->LineTo(XL, YT); + tp->Pen->Color = clGray; + for( i = 0; i < 5; i++ ){ + tp->Pen->Style = (i & 1) ? psSolid : psDot; + y = (int)(double(i + 1) * double(YB - YT)/6.0 + YT); + tp->MoveTo(XL, y); tp->LineTo(XR, y); + } + for( i = 1; i < 4; i++ ){ + y = (int)(double(i) * double(YB - YT)/3.0 + YT); + sprintf( bf, "-%2u", (60 / 3)*i ); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(XL - 6 - tp->TextWidth(bf), y - (tp->TextHeight(bf)/2), bf); + } + strcpy(bf, "dB"); + tp->TextOut(XL - 6 - tp->TextWidth(bf), YT-(tp->TextHeight(bf)/2), bf); + for( i = 1; i <= DM; i++ ){ + tp->Pen->Style = (i % MM) ? psDot : psSolid; + x = (int)(double(i) * double(XR - XL)/double(DM+1) + XL); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + } + for( i = 0; i <= LM; i++ ){ + x = (int)(double(i) * double(XR - XL)/double(LM) + XL); + sprintf(bf, "%4.0lf", (max*i)/LM); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(x - (tp->TextWidth(bf)/2), YB + 6, bf); + } + tp->Pen->Color = clRed; + tp->Pen->Style = psDot; + x = (int)(XL + (fs/2) * (double(XR-XL)/max)); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + + tp->Pen->Color = clBlue; + tp->Pen->Style = psSolid; + } + int ay = 0; + pi2t = 2.0 * PI / fs; + pi4t = 2.0 * pi2t; + tp->Pen->Color = col; + double A, B, C, D, P, R; + double cosw, sinw, cos2w, sin2w; + for( x = XL, f = 0.0; x < XR; x++, f += (max/double(XR-XL)) ){ + cosw = cos(pi2t*f); + sinw = sin(pi2t*f); + cos2w = cos(pi4t*f); + sin2w = sin(pi4t*f); + A = a0 + a1 * cosw + a2 * cos2w; + B = 1 + b1 * cosw + b2 * cos2w; + C = a1 * sinw + a2 * sin2w; + D = b1 * sinw + b2 * sin2w; + P = A*A + C*C; + R = B*B + D*D; + g = sqrt(P/R); + if( g == 0 ) g = 1.0e-38; + gdb = 20*0.4342944*log(fabs(g)) + 60.0; + if( gdb < 0.0 ) gdb = 0.0; + gdb = (gdb * double(YB-YT))/60.0; + y = YB - (int)gdb; + if( x == XL ){ + tp->MoveTo(x, y); + tp->LineTo(x, y); + } + else { + tp->MoveTo(x-1, ay); + tp->LineTo(x, y); + } + ay = y; + } +} + +//--------------------------------------------------------------------- +// 周波数特性グラフ(フィルタスレッド内でコールしてはいけない) +// +// +void __fastcall DrawGraphIIR(Graphics::TBitmap *pBitmap, CIIR *ip, int &nmax, int init, TColor col, double SampFreq) +{ + int x, y; + double f, gdb, g, pi2t, pi4t, fs; + double max; + char bf[80]; + + TCanvas *tp = pBitmap->Canvas; + TRect rc; + rc.Left = 0; + rc.Right = pBitmap->Width; + rc.Top = 0; + rc.Bottom = pBitmap->Height; + if( init ){ + tp->Brush->Color = clWhite; + tp->FillRect(rc); + } + int LM; // 周波数表示のあるライン数 + int DM; // 内部線の数 + int MM; // 実線の間隔 + max = 4000; + fs = SampFreq; + if( nmax ){ + max = nmax; + } + else { + nmax = max; + } + switch(nmax){ + case 3000: + LM = 3; + DM = 14; + MM = 5; + break; + case 100: + case 200: + case 2000: + LM = 4; + DM = 19; + MM = 5; + break; + case 400: + case 800: + case 4000: + LM = 4; + DM = 19; + MM = 5; + break; + default: // 6000 + LM = 3; + DM = 11; + MM = 4; + break; + } + int XL = 32; + int XR = pBitmap->Width - 16; + int YT = 16; + int YB = pBitmap->Height - 24; + + int i; + if( init ){ + tp->Pen->Color = clBlack; + tp->Font->Size = 8; + tp->MoveTo(XL, YT); tp->LineTo(XR, YT); tp->LineTo(XR, YB); tp->LineTo(XL, YB); tp->LineTo(XL, YT); + tp->Pen->Color = clGray; + for( i = 0; i < 5; i++ ){ + tp->Pen->Style = (i & 1) ? psSolid : psDot; + y = (int)(double(i + 1) * double(YB - YT)/6.0 + YT); + tp->MoveTo(XL, y); tp->LineTo(XR, y); + } + for( i = 1; i < 4; i++ ){ + y = (int)(double(i) * double(YB - YT)/3.0 + YT); + sprintf( bf, "-%2u", (60 / 3)*i ); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(XL - 6 - tp->TextWidth(bf), y - (tp->TextHeight(bf)/2), bf); + } + strcpy(bf, "dB"); + tp->TextOut(XL - 6 - tp->TextWidth(bf), YT-(tp->TextHeight(bf)/2), bf); + for( i = 1; i <= DM; i++ ){ + tp->Pen->Style = (i % MM) ? psDot : psSolid; + x = (int)(double(i) * double(XR - XL)/double(DM+1) + XL); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + } + for( i = 0; i <= LM; i++ ){ + x = (int)(double(i) * double(XR - XL)/double(LM) + XL); + sprintf(bf, "%4.0lf", (max*i)/LM); + ::SetBkMode(tp->Handle, TRANSPARENT); + tp->TextOut(x - (tp->TextWidth(bf)/2), YB + 6, bf); + } + tp->Pen->Color = clRed; + tp->Pen->Style = psDot; + x = (int)(XL + (fs/2) * (double(XR-XL)/max)); + tp->MoveTo(x, YT); tp->LineTo(x, YB); + + tp->Pen->Color = clBlue; + tp->Pen->Style = psSolid; + } + int ay = 0; + pi2t = 2.0 * PI / fs; + pi4t = 2.0 * pi2t; + tp->Pen->Color = col; + double A, B, C, D, P, R; + double cosw, sinw, cos2w, sin2w; + for( x = XL, f = 0.0; x < XR; x++, f += (max/double(XR-XL)) ){ + cosw = cos(pi2t*f); + sinw = sin(pi2t*f); + cos2w = cos(pi4t*f); + sin2w = sin(pi4t*f); + g = 1.0; + double *ap = ip->m_A; + double *bp = ip->m_B; + for( i = 0; i < ip->m_order/2; i++, ap += 2, bp += 3 ){ +/* + A = a0 + a1 * cosw + a2 * cos2w; + B = 1 + b1 * cosw + b2 * cos2w; + C = a1 * sinw + a2 * sin2w; + D = b1 * sinw + b2 * sin2w; +*/ + A = bp[0] + bp[1] * cosw + bp[2] * cos2w; + B = 1 + -ap[0] * cosw + -ap[1] * cos2w; + C = bp[1] * sinw + bp[2] * sin2w; + D = -ap[0] * sinw + -ap[1] * sin2w; + P = A*A + C*C; + R = B*B + D*D; + g *= sqrt(P/R); + } + if( ip->m_order & 1 ){ + A = bp[0] + bp[1] * cosw; + B = 1 + -ap[0] * cosw; + C = bp[1] * sinw; + D = -ap[0] * sinw; + P = A*A + C*C; + R = B*B + D*D; + g *= sqrt(P/R); + } + if( g == 0 ) g = 1.0e-38; + gdb = 20*0.4342944*log(fabs(g)) + 60.0; + if( gdb < 0.0 ) gdb = 0.0; + gdb = (gdb * double(YB-YT))/60.0; + y = YB - (int)gdb; + if( x == XL ){ + tp->MoveTo(x, y); + tp->LineTo(x, y); + } + else { + tp->MoveTo(x-1, ay); + tp->LineTo(x, y); + } + ay = y; + } +} + +//--------------------------------------------------------------------------- +// CSinTableクラス +__fastcall CSinTable::CSinTable() +{ + m_Size = 48000; + m_tSin = new double[m_Size]; + double pi2t = 2 * PI / double(m_Size); + for( int i = 0; i < m_Size; i++ ){ + m_tSin[i] = sin(double(i) * pi2t); + } +} +//--------------------------------------------------------------------------- +__fastcall CSinTable::~CSinTable() +{ + delete m_tSin; +} +//--------------------------------------------------------------------------- +// VCOクラス +__fastcall CVCO::CVCO() +{ + m_SampleFreq = SAMPFREQ; + m_FreeFreq = 2000.0; + m_TableSize = g_SinTable.m_Size; + m_TableCOS = m_TableSize / 4; + m_c1 = 0.0; + m_c2 = double(m_TableSize) * m_FreeFreq / m_SampleFreq; + m_z = 0.0; +} + +__fastcall CVCO::~CVCO() +{ +} + +void __fastcall CVCO::SetGain(double gain) +{ + m_c1 = double(m_TableSize) * gain / m_SampleFreq; +} + +void __fastcall CVCO::SetSampleFreq(double f) +{ + m_SampleFreq = f; + SetFreeFreq(m_FreeFreq); +} + +void __fastcall CVCO::SetFreeFreq(double f) +{ + m_FreeFreq = f; + m_c2 = double(m_TableSize) * m_FreeFreq / m_SampleFreq; + if( f < 1.0 ) m_z = 0; +} + +void __fastcall CVCO::InitPhase(void) +{ + m_z = 0.0; +} +//------------------------------------------------------------------ +double __fastcall CVCO::Do(void) +{ + m_z += m_c2; + if( m_z >= m_TableSize ){ + m_z -= m_TableSize; + } + if( m_z < 0 ){ + m_z += m_TableSize; + } + return g_SinTable.m_tSin[int(m_z)]; +} +//------------------------------------------------------------------ +double __fastcall CVCO::Do(double d) +{ +#if DEBUG + if( ABS(d) >= 2.0 ) Application->MainForm->Caption = "VCO over range"; +#endif + // -1 to 1 + m_z += (d * m_c1 + m_c2); + while( m_z >= m_TableSize ){ + m_z -= m_TableSize; + } + while( m_z < 0 ){ + m_z += m_TableSize; + } + return g_SinTable.m_tSin[int(m_z)]; +} +//------------------------------------------------------------------ +double __fastcall CVCO::DoCos(void) +{ + double z = m_z + m_TableCOS; + if(z >= m_TableSize ) z -= m_TableSize; + return g_SinTable.m_tSin[int(z)]; +} + +//------------------------------------------------------------------ +static double __fastcall asinh(double x) +{ + return log(x + sqrt(x*x+1.0)); +} +//------------------------------------------------------------------ +// bc : 0-バターワース, 1-チェビシフ +// rp : 通過域のリップル +void __fastcall MakeIIR(int type, double *A, double *B, double fc, double fs, int order, int bc, double rp) +{ + double w0, wa, u, zt, x; + int j, n; + + if( bc ){ // チェビシフ + u = 1.0/double(order) * asinh(1.0/sqrt(pow(10.0,0.1*rp)-1.0)); + } + wa = tan(PI*fc/fs); + w0 = 1.0; + n = (order & 1) + 1; + double *pA = A; + double *pB = B; + double s, d, d1, d2; + for( j = 1; j <= order/2; j++, pA+=2, pB+=3 ){ + if( bc ){ // チェビシフ + d1 = sinh(u)*cos(n*PI/(2*order)); + d2 = cosh(u)*sin(n*PI/(2*order)); + w0 = sqrt(d1 * d1 + d2 * d2); + zt = sinh(u)*cos(n*PI/(2*order))/w0; + } + else { // バターワース + w0 = 1.0; + zt = cos(n*PI/(2*order)); + } + switch(type){ + case ffLPF: + s = wa * w0; + d = 1 + s*2*zt + s*s; + pA[0] = -2 * (s*s - 1)/d; + pA[1] = -(1.0 - s*2*zt + s*s)/d; + pB[0] = s*s / d; + pB[1] = 2*pB[0]; + pB[2] = pB[0]; + break; + case ffHPF: + s = wa / w0; + d = 1 + s*2*zt + s*s; + pA[0] = -2 * (s*s - 1)/d; + pA[1] = -(1.0 - s*2*zt + s*s)/d; + pB[0] = 1.0 / d; + pB[1] = -2*pB[0]; + pB[2] = pB[0]; + break; + } + n += 2; + } + if( bc && !(order & 1) ){ + x = pow( 1.0/pow(10.0,rp/20.0), 1.0/double(order/2) ); + pB = B; + for( j = 1; j <= order/2; j++, pB+=3 ){ + pB[0] *= x; + pB[1] *= x; + pB[2] *= x; + } + } + if( order & 1 ){ + if( bc ) w0 = sinh(u); + j = (order / 2); + pA = A + (j*2); + pB = B + (j*3); + switch(type){ + case ffLPF: + s = wa * w0; + d = 1 + s; + pA[0] = -(s - 1)/d; + pB[0] = wa*w0/d; + pB[1] = pB[0]; + break; + case ffHPF: + s = wa / w0; + d = 1 + s; + pA[0] = -(s - 1)/d; + pB[0] = 1.0/d; + pB[1] = -pB[0]; + break; + } + } +} + +//--------------------------------------------------------------------------- +__fastcall CIIR::CIIR() +{ + m_order = 0; + memset(m_A, 0, sizeof(m_A)); + memset(m_B, 0, sizeof(m_B)); + memset(m_Z, 0, sizeof(m_Z)); +} + +__fastcall CIIR::~CIIR() +{ +} + +void __fastcall CIIR::Clear(void) +{ + memset(m_Z, 0, sizeof(m_Z)); +} + +void __fastcall CIIR::Create(int type, double fc, double fs, int order, int bc, double rp) +{ +#if DEBUG + if( order > IIRMAX ){ + Application->MainForm->Caption = "Over tap in CIIR"; + order = IIRMAX; + } +#endif + m_bc = bc; + m_rp = rp; + m_order = order; + m_orderH = order/2; + ::MakeIIR(type, m_A, m_B, fc, fs, order, bc, rp); +} + +double __fastcall CIIR::Do(double d) +{ + double *pA = m_A; + double *pB = m_B; + double *pZ = m_Z; + double o; + for( int i = 0; i < m_orderH; i++, pA+=2, pB+=3, pZ+=2 ){ + d += pZ[0] * pA[0] + pZ[1] * pA[1]; + o = d * pB[0] + pZ[0] * pB[1] + pZ[1] * pB[2]; + pZ[1] = pZ[0]; + if( d < 0 ){ + if( d > -IIRVLIMIT ) d = 0.0; + } + else if( d < IIRVLIMIT ){ + d = 0.0; + } + pZ[0] = d; + d = o; + } + if( m_order & 1 ){ + d += pZ[0] * pA[0]; + o = d * pB[0] + pZ[0] * pB[1]; + if( d < 0 ){ + if( d > -IIRVLIMIT ) d = 0.0; + } + else if( d < IIRVLIMIT ){ + d = 0.0; + } + pZ[0] = d; + d = o; + } + return d; +} + + +//--------------------------------------------------------------------------- +__fastcall CIIRTANK::CIIRTANK() +{ + b1 = b2 = a0 = z1 = z2 = 0; + m_SampleFreq = SAMPFREQ; + m_Freq = CARRIERFREQ; + m_BW = 100; + Create(); +} +//--------------------------------------------------------------------------- +void __fastcall CIIRTANK::Create(void) +{ + SetFreq(m_Freq, m_SampleFreq, m_BW); +} +//--------------------------------------------------------------------------- +void __fastcall CIIRTANK::SetFreq(double f, double smp, double bw) +{ + double lb1, lb2, la0; + lb1 = 2 * exp(-PI * bw/smp) * cos(2 * PI * f / smp); + lb2 = -exp(-2*PI*bw/smp); + if( bw ){ + la0 = sin(2 * PI * f/smp) / ((smp/(PI*2.0)) / bw); + } + else { + la0 = sin(2 * PI * f/smp); + } + b1 = lb1; b2 = lb2; a0 = la0; +} +//--------------------------------------------------------------------------- +double __fastcall CIIRTANK::Do(double d) +{ + d *= a0; + d += (z1 * b1); + d += (z2 * b2); + z2 = z1; + if( d < 0 ){ + if( d > -IIRVLIMIT ) d = 0.0; + } + else if( d < IIRVLIMIT ){ + d = 0.0; + } + z1 = d; + return d; +} + +//--------------------------------------------------------------------------- +__fastcall CIIRTANK2::CIIRTANK2() +{ + m_SampleFreq = SAMPFREQ; + m_Freq = CARRIERFREQ; + m_BW = 100; + Create(); +} +//--------------------------------------------------------------------------- +void __fastcall CIIRTANK2::SetSampleFreq(double f) +{ + m_SampleFreq = f; + Create(); +} +//--------------------------------------------------------------------------- +void __fastcall CIIRTANK2::Create(void) +{ + m_Tank1.m_SampleFreq = m_SampleFreq; + m_Tank1.m_Freq = m_Freq; + m_Tank1.m_BW = m_BW; + m_Tank2.m_SampleFreq = m_SampleFreq; + m_Tank2.m_Freq = m_Freq; + m_Tank2.m_BW = m_BW; + m_Tank1.Create(); + m_Tank2.Create(); +} +//--------------------------------------------------------------------------- +double __fastcall CIIRTANK2::Do(double d) +{ + return m_Tank1.Do(m_Tank2.Do(d)); +} + +//--------------------------------------------------------------------------- +// CFIRクラス +__fastcall CFIR::CFIR() +{ + m_pZ = NULL; + m_pH = NULL; + m_Tap = 0; +} + +//--------------------------------------------------------------------------- +__fastcall CFIR::~CFIR() +{ + if( m_pZ ) delete m_pZ; + if( m_pH ) delete m_pH; +} +//--------------------------------------------------------------------------- +void __fastcall CFIR::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain) +{ + m_Tap = tap; + if( m_pZ ) delete m_pZ; + if( m_pH ) delete m_pH; + m_pZ = new double[tap+1]; + m_pH = new double[tap+1]; + memset(m_pZ, 0, sizeof(double)*(tap+1)); + ::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain); +} +//--------------------------------------------------------------------------- +double __fastcall CFIR::Do(double d) +{ + return DoFIR(m_pH, m_pZ, d, m_Tap); +} +//--------------------------------------------------------------------------- +void __fastcall CFIR::SaveCoef(LPCSTR pName) +{ + FILE *fp; + if( (fp = fopen(pName, "wt")) != NULL ){ + int i; + for( i = 0; i <= m_Tap; i++ ){ + fprintf(fp, "H[%u]=%lf\n", i, m_pH[i]); + } + fclose(fp); + } +} + +//--------------------------------------------------------------------------- +// CFIR2クラス +__fastcall CFIR2::CFIR2() +{ + m_pZ = NULL; + m_pH = NULL; + m_pZP = NULL; + m_W = 0; + m_Tap = 0; + m_fs = 0; +} + +//--------------------------------------------------------------------------- +__fastcall CFIR2::~CFIR2() +{ + if( m_pZ ) delete m_pZ; + if( m_pH ) delete m_pH; +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::Delete(void) +{ + if( m_pZ ) delete m_pZ; + if( m_pH ) delete m_pH; + m_pZ = NULL; + m_pH = NULL; + m_pZP = NULL; + m_W = 0; + m_Tap = 0; + m_fs = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain) +{ + if( (m_Tap != tap) || !m_pZ || !m_pH ){ + if( m_pZ ) delete m_pZ; + m_pZ = new double[(tap+1)*2]; + memset(m_pZ, 0, sizeof(double)*(tap+1)*2); + if( m_pH ) delete m_pH; + m_pH = new double[tap+1]; + m_W = 0; + } + m_Tap = tap; + m_TapHalf = tap/2; + m_fs = fs; + ::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain); +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::Create(int tap, double fs, double fcl, double fch) +{ + if( (m_Tap != tap) || !m_pZ || !m_pH ){ + if( m_pZ ) delete m_pZ; + m_pZ = new double[(tap+1)*2]; + memset(m_pZ, 0, sizeof(double)*(tap+1)*2); + if( m_pH ) delete m_pH; + m_pH = new double[tap+1]; + m_W = 0; + } + m_Tap = tap; + m_TapHalf = tap/2; + m_fs = fs; + ::MakeHilbert(m_pH, tap, fs, fcl, fch); +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::CreateSamp(int tap, double fs, const double *pSmpFQ) +{ + if( (m_Tap != tap) || !m_pZ || !m_pH ){ + if( m_pZ ) delete m_pZ; + m_pZ = new double[(tap+1)*2]; + memset(m_pZ, 0, sizeof(double)*(tap+1)*2); + if( m_pH ) delete m_pH; + m_pH = new double[tap+1]; + m_W = 0; + } + + int htap = tap/2; + int i, j; + double *pSamp = new double[tap+1]; + memcpy(pSamp, pSmpFQ, sizeof(double)*(tap/2)); + for( i = 0; i < tap/2; i++ ){ + pSamp[tap-i] = pSamp[i]; + } + pSamp[tap/2] = pSamp[tap/2 - 1]; + double *pH = new double[tap+1]; + double re, fm; + + for( i = 0; i <= htap; i++ ){ + re = 0.0; + for( j = 0; j < tap; j++ ){ + fm = 2.0 * PI * double((i*j)%tap)/double(tap); + re += pSamp[j] * cos(fm); + } + pH[i] = re / tap; + } +#if 0 + fm = 0; + for( i = 0; i <= htap; i++ ){ + fm += pH[i]; + } + fm = 0.5 / fm; + for( i = 0; i <= htap; i++ ){ + pH[i] *= fm; + } +#endif + for( i = 0; i <= htap; i++ ) m_pH[htap-i] = pH[i]; + for( i = 0; i < htap; i++ ) m_pH[tap-i] = m_pH[i]; + delete pH; + delete pSamp; + + m_Tap = tap; + m_TapHalf = htap; + m_fs = fs; +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::Clear(void) +{ + if( m_pZ ) memset(m_pZ, 0, sizeof(double)*(m_Tap+1)*2); + m_W = 0; +} +//--------------------------------------------------------------------------- +double __fastcall CFIR2::Do(double d) +{ + double *dp1 = &m_pZ[m_W+m_Tap+1]; + m_pZP = dp1; + *dp1 = d; + m_pZ[m_W] = d; + d = 0; + double *hp = m_pH; + for( int i = 0; i <= m_Tap; i++ ){ + d += (*dp1--) * (*hp++); + } + m_W++; + if( m_W > m_Tap ) m_W = 0; + return d; +} +//--------------------------------------------------------------------------- +double __fastcall CFIR2::Do(double *hp) +{ + double d = 0; + double *dp = m_pZP; + for( int i = 0; i <= m_Tap; i++ ){ + d += (*dp--) * (*hp++); + } + return d; +} +//--------------------------------------------------------------------------- +void __fastcall CFIR2::Do(CLX &z, double d) +{ + double *dp1 = &m_pZ[m_W+m_Tap+1]; + m_pZP = dp1; + *dp1 = d; + m_pZ[m_W] = d; + d = 0; + double *hp = m_pH; + for( int i = 0; i <= m_Tap; i++ ){ + d += (*dp1--) * (*hp++); + } + z.j = d; + z.r = m_pZ[m_W+m_TapHalf+1]; + m_W++; + if( m_W > m_Tap ) m_W = 0; +} + + +//--------------------------------------------------------------------------- +// CFIRXクラス +__fastcall CFIRX::CFIRX() +{ + m_pZ = NULL; + m_pH = NULL; + m_pZP = NULL; + m_W = 0; + m_Tap = 0; + m_fs = 0; +} + +//--------------------------------------------------------------------------- +__fastcall CFIRX::~CFIRX() +{ + if( m_pZ ) delete m_pZ; + if( m_pH ) delete m_pH; +} +//--------------------------------------------------------------------------- +void __fastcall CFIRX::Create(int tap, int type, double fs, double fcl, double fch, double att, double gain) +{ + if( (m_Tap != tap) || !m_pZ || !m_pH ){ + if( m_pZ ) delete m_pZ; + m_pZ = new CLX[(tap+1)*2]; + memset(m_pZ, 0, sizeof(CLX)*(tap+1)*2); + if( m_pH ) delete m_pH; + m_pH = new double[tap+1]; + m_W = 0; + } + m_Tap = tap; + m_TapHalf = tap/2; + m_fs = fs; + ::MakeFilter(m_pH, tap, type, fs, fcl, fch, att, gain); +} +//--------------------------------------------------------------------------- +void __fastcall CFIRX::CreateSamp(int tap, double fs, const double *pSmpFQ, int wDB) +{ + if( (m_Tap != tap) || !m_pZ || !m_pH ){ + if( m_pZ ) delete m_pZ; + m_pZ = new CLX[(tap+1)*2]; + memset(m_pZ, 0, sizeof(CLX)*(tap+1)*2); + if( m_pH ) delete m_pH; + m_pH = new double[tap+1]; + m_W = 0; + } + + int htap = tap/2; + int i, j; + double *pSamp = new double[tap+1]; + memcpy(pSamp, pSmpFQ, sizeof(double)*(tap/2)); + double maxAmp = 0; + double *dp = pSamp; + for( i = 0; i < tap/2; i++, dp++ ){ + pSamp[tap-i] = *dp; + if( maxAmp < *dp ) maxAmp = *dp; + } + pSamp[tap/2] = pSamp[tap/2 - 1]; + double *pH = new double[tap+1]; + double re, fm; + + for( i = 0; i <= htap; i++ ){ + re = 0.0; + dp = pSamp; + for( j = 0; j < tap; j++ ){ + fm = 2.0 * PI * double((i*j)%tap)/double(tap); + re += (*dp++) * cos(fm); + } + pH[i] = re / tap; + } + if( wDB >= 21 ){ + double alpha, att; + att = double(wDB); + if( att >= 50.0 ){ + alpha = 0.1102 * (att - 8.7); + } + else { + alpha = (0.5842*pow(att - 21.0, 0.4)) + (0.07886 * (att - 21.0)); + } + dp = pH; + for( i = 0; i <= htap; i++, dp++ ){ + double fm = double(2 * i)/double(tap); + double win = I0(alpha * sqrt(1.0-(fm*fm)))/I0(alpha); + *dp *= win; + } + fm = 0.000001; + double f = 0.0; + double g; + double pi2t = 2.0 * PI / fs; + int i, k; + double fk = fs * 0.5 / tap; + for( i = 0; i < tap; i++, f += fk ){ + g = pH[0]; + for( k = 1; k <= htap; k++ ){ + g += 2.0 * pH[k] * cos(pi2t*f*double(k)); + } + if( fm < g ) fm = g; + } + fm = maxAmp / fm; + dp = pH; + for( i = 0; i <= htap; i++, dp++ ){ + *dp *= fm; + } + } + for( i = 0; i <= htap; i++ ) m_pH[htap-i] = pH[i]; + for( i = 0; i < htap; i++ ) m_pH[tap-i] = m_pH[i]; + delete pH; + delete pSamp; + + m_Tap = tap; + m_TapHalf = htap; + m_fs = fs; +} +//--------------------------------------------------------------------------- +void __fastcall CFIRX::Clear(void) +{ + if( m_pZ ) memset(m_pZ, 0, sizeof(CLX)*(m_Tap+1)*2); + m_W = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CFIRX::Do(CLX &d) +{ + CLX *dp1 = &m_pZ[m_W+m_Tap+1]; + m_pZP = dp1; + *dp1 = d; + m_pZ[m_W] = d; + CLX z = 0; + double *hp = m_pH; + for( int i = 0; i <= m_Tap; i++, dp1-- ){ + z.r += dp1->r * (*hp); + z.j += dp1->j * (*hp++); + } + m_W++; + if( m_W > m_Tap ) m_W = 0; + d = z; +} + + +/*============================================================================= + CSlideFFTクラス スライディング FFT +=============================================================================*/ +#define SLIDE_WINDOW_COEFF 0.9999 +__fastcall CSlideFFT::CSlideFFT(void) +{ + m_Length = 0; + m_Base = 0; + m_Tones = 0; + m_kWindow = 0; + m_pBase = NULL; + m_pCur = m_pEnd = NULL; +} + +//-------------------------------------------------------------------------- +__fastcall CSlideFFT::~CSlideFFT() +{ + if( m_pBase ) delete m_pBase; +} + +//-------------------------------------------------------------------------- +void __fastcall CSlideFFT::Create(int len, int base, int tones) +{ + if( !m_pBase || (len != m_Length) ){ + if( m_pBase ) delete m_pBase; + m_pBase = new CLX[len]; + } + +#if DEBUG + if( tones > MFSK_MAXTONES ){ + Application->MainForm->Caption = "Tones overflow in CSlideFFT"; + tones = MFSK_MAXTONES; + } +#endif + + memset(m_pBase, 0, sizeof(CLX)*len); + memset(m_tWindow, 0, sizeof(m_tWindow)); + memset(m_tData, 0, sizeof(m_tData)); + + m_Length = len; + m_Base = base; + m_Tones = tones; + + double k = 2.0 * PI / double(len); + for(int i = 0; i < tones; i++){ + m_tWindow[i].r = cos((i+base) * k) * SLIDE_WINDOW_COEFF; + m_tWindow[i].j = sin((i+base) * k) * SLIDE_WINDOW_COEFF; + } + m_kWindow = pow(SLIDE_WINDOW_COEFF, len); + m_pCur = m_pBase; + m_pEnd = &m_pBase[m_Length]; +} + +//-------------------------------------------------------------------------- +CLX* __fastcall CSlideFFT::Do(const CLX &zIn) +{ + CLX z; + + if( m_pCur >= m_pEnd ) m_pCur = m_pBase; + z = *m_pCur; + *m_pCur = zIn; + m_pCur++; + z *= m_kWindow; + + CLX *pData = m_tData; + CLX *pWindow = m_tWindow; + for( int i = 0; i < m_Tones; i++, pData++ ){ + *pData -= z; + *pData += zIn; + *pData *= *pWindow++; + } + return m_tData; +} + +#if DEBUG +//-------------------------------------------------------- +// CQSBクラス +__fastcall CQSB::CQSB() +{ + m_vMin = 16384/32; + m_vMax = 16384/4; + m_fPhaseError = FALSE; +} + +__fastcall CQSB::~CQSB() +{ +} + +void __fastcall CQSB::Create(int min, int max, int msec, BOOL perr) +{ + m_vMin = min; + m_vMax = max; + + m_VCO.SetSampleFreq(SAMPFREQ); + m_VCO.SetFreeFreq(1000.0 / double(msec)); + m_VCOP.SetSampleFreq(SAMPFREQ); + m_VCOP.SetFreeFreq(1000.0 / 10000.0); + m_tap = 200; + memset(m_Z, 0, sizeof(m_Z)); + + m_fPhaseError = perr; +} + +int __fastcall CQSB::Do(void) +{ + int d = m_VCO.Do() * 16384.0; + BOOL fm = d < 0; + d = ABS(d); + d = m_vMin + ((m_vMax - m_vMin) * d / 16384); + if( d > 16384 ) d = 16384; + if( fm && m_fPhaseError ) d *= -1.0; + return d; +} + +double __fastcall CQSB::Do(double d) +{ + double ds = m_VCO.Do(); + if( m_fPhaseError ){ + double dc = m_VCO.DoCos(); + m_Z[m_tap] = d; + memcpy(m_Z, &m_Z[1], m_tap*sizeof(double)); + int n = m_tap * (0.6 + m_VCOP.Do(0.0)*0.4); + if( n < 0 ) n = 0; + if( n > m_tap ) n = m_tap; + d = m_Z[0] * ds + m_Z[n] * dc; + } + if( m_vMin != m_vMax ){ + ds = m_vMin + ((m_vMax - m_vMin) * ABS(ds)); + if( d > 16384 ) d = 16384; + } + else { + ds = m_vMax; + } + return d * ds; +} +//-------------------------------------------------------- +// CNoiseクラス +__fastcall CNoise::CNoise() +{ + m_SampleFreq = SAMPFREQ; +// m_reg = 0x12345; + m_reg = 0x11111; + Create(600, 2700); +}; + +void __fastcall CNoise::SetSampleFreq(double f) +{ + m_SampleFreq = f; + Create(100, 2700); +} + +void __fastcall CNoise::Create(double f1, double f2) +{ + m_HPF.Create(ffHPF, f1, m_SampleFreq, 3, 1, 0.3); + m_LPF.Create(ffLPF, f2, m_SampleFreq, 7, 1, 0.3); +} + +DWORD __fastcall CNoise::Do(void) +{ + DWORD r = m_reg >> 1; + if( (m_reg ^ r) & 1 ){ + r |= 0xffe00000; + } + else { + r &= 0x001fffff; + } + m_reg = r; + return r >> 19; +} + +double __fastcall CNoise::DoLPF(void) +{ + return m_LPF.Do(Do()); +} + +double __fastcall CNoise::DoHPF(void) +{ + return m_LPF.Do(m_HPF.Do(Do())); +} + + +void __fastcall AddGaussian(short *pData, int n, double gain) +{ + int i = 0; + double rad; + double r; + double u1; + double u2; + while( i < n ){ + do { + u1 = 1.0 - 2.0 * (double)rand()/(double)RAND_MAX ; + u2 = 1.0 - 2.0 * (double)rand()/(double)RAND_MAX ; + r = u1*u1 + u2*u2; + } while(r >= 1.0 || r == 0.0); + rad = sqrt(-2.0*log(r)/r); + pData[i++] += (gain*u1*rad); + pData[i++] += (gain*u2*rad); + } +} +#endif + +//********************************************************************* +// CDECM2 1/Nデシメータ処理クラス +// +/* + Clock 復調器 FFT + 6000Hz 6000Hz 6000Hz 1024 + 8000Hz 8000Hz 8000Hz 2048 + 11025Hz 5513Hz 11025Hz 2048 + 12000Hz 6000Hz 6000Hz 1024 + 16000Hz 5333Hz 10667Hz 2048 + 18000Hz 6000Hz 6000Hz 1024 + 22050Hz 5513Hz 11025Hz 2048 + 24000Hz 6000Hz 6000Hz 1024 + 44100Hz 6300Hz 6300Hz 1024 + 48000Hz 6000Hz 6000Hz 1024 + 50000Hz 6250Hz 6250Hz 1024 +*/ +__fastcall CDECM2::CDECM2() +{ + m_Type = 1; + m_Count = 0; + SetSampleFreq(m_Type, SAMPFREQ); +} + +void __fastcall CDECM2::SetSampleFreq(int type, double f) +{ + m_Type = type; + m_SampleFreq = f; +#if DECFIR + switch(m_Type){ + case 2: // 16000, 18000 + case 3: // 22050, 24000 + case 4: + case 5: + m_FIR.Create(40, ffLPF, m_SampleFreq, 2900, 2900, 40, 1.0); + break; + case 6: // 44100, + case 7: // 48000, 50000 + m_FIR.Create(44, ffLPF, m_SampleFreq, 3000, 3000, 40, 1.0); + break; + default: // 11025, 12000 + m_FIR.Create(36, ffLPF, m_SampleFreq, 2700, 2700, 40, 1.0); + break; + } +#else + m_IIR.Create(ffLPF, sys.m_DecCutOff, m_SampleFreq, 10, 1, 0.1); +#endif +} + +BOOL __fastcall CDECM2::Do(double d) +{ +#if DECFIR + m_O = m_FIR.Do(d); +#else + m_O = m_IIR.Do(d); +#endif + if( !m_Count ){ + m_Count = m_Type; + return TRUE; + } + else { + m_Count--; + return FALSE; + } +} + +//-------------------------------------------------------- +// CAGCクラス +__fastcall CAGC::CAGC() +{ + m_fc = 1000.0; + m_MonitorFreq = SAMPFREQ/2048; + m_SampleFreq = SAMPFREQ; + m_CarrierFreq = CARRIERFREQ; + m_LimitGain = 0.005; + m_AvgOver.Create(4); + Create(); +} +//-------------------------------------------------------- +void __fastcall CAGC::Create(void) +{ + m_Count = 0; + m_Max = -1.0; + m_Min = 1.0; + m_d = 0; + m_agc = 1.0; +// m_Level.Create(ffLPF, 0.3, m_MonitorFreq, 3, 0, 0); + SetCarrierFreq(m_CarrierFreq); +} +//-------------------------------------------------------- +void __fastcall CAGC::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + if( m_CarrierFreq >= 1000.0 ){ + m_Gain = (m_CarrierFreq / 1000.0); + +/* +500 0.003 333 +1000 0.0035 285 1.0 1.0 +1500 0.005 200 1.4 1.5 +1800 0.006 166 1.71 +2000 0.008 125 2.3 2.0 +2100 0.01 100 2.85 2.1 +2200 0.012 83 3.4 2.2 +2300 0.015 66 4.3 2.3 +2400 0.025 40 7.1 2.4 +2500 0.028 36 7.9 2.5 +2600 0.030 33 8.6 2.6 +*/ + if( m_Gain >= 2.35 ){ + m_Gain *= 7.1 / 2.4; + } + else if( m_Gain >= 2.25 ){ + m_Gain *= 4.3 / 2.3; + } + else if( m_Gain >= 2.15 ){ + m_Gain *= 3.4 / 2.2; + } + else if( m_Gain >= 2.05 ){ + m_Gain *= 2.9 / 2.1; + } + else if( m_Gain >= 1.8 ){ + m_Gain *= 2.3 / 2.2; + } + } + else { + m_Gain = 1.0; + } + SetFC(m_fc); +} +//-------------------------------------------------------- +void __fastcall CAGC::SetFC(double fc) +{ + m_fc = fc; + if( fc > m_CarrierFreq*0.45 ) fc = m_CarrierFreq*0.45; + m_LPF.Create(ffLPF, fc, m_CarrierFreq, 1, 0, 0); + m_d = 0; + m_TLimit = m_SampleFreq*0.8/m_CarrierFreq; + m_AvgOver.Reset(1.0); +} +//-------------------------------------------------------- +void __fastcall CAGC::Reset(void) +{ + m_Max = -1.0; + m_Min = 1.0; + m_agc = 1.0; + m_d = 0; + m_Count = 0; + for( int i = 0; i < 12; i++ ){ + m_LPF.Do(1.0); +// m_Level.Do(0); + } + m_AvgOver.Reset(1.0); +} +//-------------------------------------------------------- +double __fastcall CAGC::Do(double d) +{ + if( m_Max < d ) m_Max = d; + if( m_Min > d ) m_Min = d; + if( (d >= 0) && (m_d < 0) && (m_Count >= m_TLimit) ){ + double amp = m_Max - m_Min; + if( amp > 0.1 ){ + m_agc = m_LPF.Do(5.0/amp); + if( m_agc >= 1.0 ) m_agc = 1.0; + m_Max = -32768.0; + m_Min = 32768.0; + } + m_Count = 0; + } + m_Count++; + m_d = d; + d *= m_agc; + if( d > 2.5 ){ d = 2.5; } else if( d < -2.5 ){ d = -2.5; } + return d; +} +//-------------------------------------------------------- +BOOL __fastcall CAGC::GetOver(void) +{ +// 5.0 / (65536 * 0.666) + return (m_AvgOver.Do(m_agc) < 0.0001146); +// return (m_agc < 0.0001146); +} + +//-------------------------------------------------------- +__fastcall CAFC::CAFC() +{ + m_Speed = SPEED; + m_SampleFreq = SAMPFREQ; + m_A = m_SampleFreq / (2 * PI); + m_B = 0.0; + SetTap(32); + SetTone(CARRIERFREQ); + m_LPF.Create(ffLPF, SPEED, m_SampleFreq, 1, 0, 0); + m_d = 0; + m_min = 65536.0; + m_max = -65536.0; + m_Max = m_Min = 0.0; + m_Count = 0; + m_LCount1 = m_SampleFreq * 1.8 / m_Speed; + m_LCount2 = m_SampleFreq * 31.8 / m_Speed; +} + +void __fastcall CAFC::SetPara(double a, double b) +{ + m_A = a; + m_B = b; +} + +void __fastcall CAFC::SetTap(int tap) +{ + m_Avg.Create(tap); +} + +void __fastcall CAFC::SetTone(double fq) +{ + m_fq = fq; + m_Avg.Reset(fq); + m_fChange = FALSE; +} + +BOOL __fastcall CAFC::Do(double d) +{ + BOOL f = FALSE; + d = m_LPF.Do(d); + if( m_min > d ) m_min = d; + if( m_max < d ) m_max = d; + if( ((m_d < 0.0) && (d >= 0.0) && (m_Count > m_LCount1)) || + (m_Count > m_LCount2) + ){ + m_Max = m_max; m_Min = m_min; + double dd = (m_max + m_min) * 0.5; + m_min = m_max = d; + dd = dd * m_A + m_B; + + dd = m_Avg.Do(dd); + if( (dd >= m_B-100) && (dd <= m_B+100) ){ + m_fq = dd; + f = TRUE; + } + m_Count = 0; + } + m_d = d; + m_Count++; + return f; +} + + +//--------------------------------------------------------------------------- +// CLMSクラス +__fastcall CLMS::CLMS() +{ + m_Tap = 48; + m_lmsDelay = 32; + + memset(Z, 0, sizeof(Z)); + memset(H, 0, sizeof(H)); + memset(D, 0, sizeof(D)); + + m_lmsADJSC = 1.0 / double(32768 * 32768); // スケール調整値 + + m_lmsMU2 = 0.003; // LMS 2μ + m_lmsGM = 0.9999; // LMS γ +} + +//------------------------------------------------- +// 適応フィルタの演算 +double __fastcall CLMS::Do(double d) +{ + double a = 0.0; + int i; + double *zp = Z; + double *hp = H; + + // トランスバーサルフィルタ + memcpy(Z, &Z[1], sizeof(double)*m_Tap); + Z[m_Tap] = D[0]; + for( i = 0; i <= m_Tap; i++, zp++, hp++ ){ + a += (*zp) * (*hp); + } + // 誤差計算 + double err = d - a; + double merr = err * m_lmsMU2 * m_lmsADJSC; // lmsADJSC = 1/(32768 * 32768) スケーリング調整値 + + // 遅延器の移動 + if( m_lmsDelay ) memcpy(D, &D[1], sizeof(double)*m_lmsDelay); + D[m_lmsDelay] = d; + // 係数更新 + zp = Z; + hp = H; + double sum = 0; + for( i = 0; i <= m_Tap; i++, zp++, hp++ ){ + *hp = (merr * (*zp)) + (*hp * m_lmsGM); + sum += ABS(*hp); + } + if( sum ){ + sum = 1.0 / sum; + hp = H; + for( i = 0; i <= m_Tap; i++, hp++ ){ + *hp *= sum; + } + } + return a; +} + +//--------------------------------------------------------------------------- +// CDEMFSKクラス +__fastcall CDEMFSK::CDEMFSK() +{ +#if MEASIMD + m_imd = 0.0; + m_max = 0.0; + m_min = 0.0; + m_amax = 0.0; + m_amin = 0.0; +#endif + + m_MFSK_TYPE = typMFSK16; + m_MFSK_TONES = 16; + m_MFSK_SPEED = 15.625; + m_MFSK_BW = (m_MFSK_SPEED * (m_MFSK_TONES-1)); + m_MFSK_BITS = 4; + + m_Type = MODE_GMSK; + m_pBPF = NULL; + m_Speed = SPEED; + m_SampleFreq = DEMSAMPFREQ; +// m_LoopFc = SPEED*6; +// m_Gain = 1.0; + m_Gain = 0.8; + m_CarrierFreq = CARRIERFREQ; + m_PreBPFTaps = 64; + m_fAFC = TRUE; + m_fEnableAFC = FALSE; + m_out = m_err = 0.0; + m_RTTYShift = 170.0; + m_fRTTYTANK = TRUE; + m_fRTTYFFT = FALSE; + m_DemLevel = 1.0; + m_SW = m_Speed * 0.5; + m_pMFSK = NULL; + m_fMFSK = FALSE; + m_fQPSK = FALSE; + m_BPFLimit = 4.0; + Create(); +} +//--------------------------------------------------------------------------- +__fastcall CDEMFSK::~CDEMFSK() +{ + if( m_pMFSK ) delete m_pMFSK; +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::SetMFSKType(int type) +{ + MFSK_SetPara(type, &m_MFSK_TONES, &m_MFSK_SPEED, &m_MFSK_BITS); + m_MFSK_BW = (m_MFSK_SPEED * (m_MFSK_TONES-1)); + if( type == m_MFSK_TYPE ) return; + m_MFSK_TYPE = type; + if( m_pMFSK ) Create(); +} + +//--------------------------------------------------------------------------- +#define AFC_LPFORDER 3 +#define OUT_LPFORDER 3 +void __fastcall CDEMFSK::Create(void) +{ + m_fMFSK = IsMFSK(m_Type); + m_fQPSK = IsQPSK(m_Type); + m_fRTTYTANK = (m_Speed < m_RTTYShift); + m_LPF1.Create(ffLPF, m_Speed, m_SampleFreq, AFC_LPFORDER, 0, 0); +// m_LPF2.Create(ffLPF, m_Speed, m_SampleFreq, AFC_LPFORDER, 0, 0); + m_LPF1.Clear(); +// m_LPF2.Clear(); + double fc = m_Speed * 6.0; + if( fc > m_SampleFreq * 0.45 ) fc = m_SampleFreq * 0.45; + m_LoopLPF.Create(ffLPF, fc, m_SampleFreq, 1, 0, 0); + if( Is170(m_Type) ){ + m_FAVG.Create(128*45.45/m_Speed); + } + else if( IsFSK(m_Type) ){ + m_FAVG.Create(16); + } + else { + m_FAVG.Create(8192*31.25/m_Speed); + } + + int nSmooz = int((m_SampleFreq * 45.45 / (m_Speed * 70.0)) + 0.5); + m_SmoozM.SetCount(nSmooz); + m_SmoozS.SetCount(nSmooz); + +// m_CIC.Create(4, m_SampleFreq*0.5/m_Speed); + m_OutLPF.Create(ffLPF, m_Speed*0.5, m_SampleFreq, OUT_LPFORDER, 0, 0); + m_VCO.SetSampleFreq(m_SampleFreq); + + m_AFC.m_Speed = m_Speed; + m_AFC.SetTap(16*m_SampleFreq/11025); + + m_Decode.SetSampleFreq(m_SampleFreq); + m_Decode.SetType(m_Type); + m_Decode.SetSpeed(m_Speed); + m_Decode.Reset(); + + m_AGC.SetSampleFreq(m_SampleFreq); + m_TankL.m_BW = m_TankH.m_BW = 60.0; + m_TankL.SetSampleFreq(m_SampleFreq); + m_TankH.SetSampleFreq(m_SampleFreq); + m_PhaseX.SetSampleFreq(m_SampleFreq); + + SetCarrierFreq(m_CarrierFreq); + + m_fEnableAFC = FALSE; + m_DemLevel = 1.0; +/* + 31.25 88 + 45.45 66 + 62.5 53 + 93.75 37 + 125 30 +*/ + if( m_fMFSK ){ + if( !m_pMFSK ) m_pMFSK = new CDecMFSK; + m_pMFSK->SetMFSKType(m_MFSK_TYPE); + m_pMFSK->SetSampleFreq(m_SampleFreq); + } + else { + delete m_pMFSK; + m_pMFSK = NULL; + } + m_DecPSK.m_fLSB = (m_Type == MODE_qpsk_L); + m_DecPSK.SetSampleFreq(m_SampleFreq); + m_DecPSK.SetCarrierFreq(m_CarrierFreq); + m_DecPSK.SetSpeed(m_Speed); + double spd = m_Speed; + if( spd < 30 ) spd = 30.0; + switch(m_Type){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + m_LockTh = (2750*2/3)/spd; + m_AGC.SetFC(500); + break; + case MODE_GMSK: + m_LockTh = (2750*1/2)/spd; + m_AGC.SetFC(500); + break; + case MODE_FSKW: + case MODE_FSK: + m_LockTh = (2750*1/3)/spd; + m_AGC.SetFC(500); + break; + case MODE_RTTY: + case MODE_U_RTTY: + m_LockTh = (2750*1/3)/spd; + m_AGC.SetFC(500); + break; + case MODE_mfsk_L: + m_pMFSK->m_fLSB = TRUE; + m_pMFSK->SetCarrierFreq(m_CarrierFreq); + m_Lock = TRUE; + break; + case MODE_mfsk_U: + m_pMFSK->m_fLSB = FALSE; + m_pMFSK->SetCarrierFreq(m_CarrierFreq); + m_Lock = TRUE; + break; + } + m_out = m_err = 0.0; +} + +//--------------------------------------------------------------------------- +double __fastcall GetRTTYBW(int taps) +{ + int bw = 180.0; + if( taps == g_tBpfTaps[1] ){ + bw = 120.0; + } + else if( taps == g_tBpfTaps[2] ){ + bw = 70.0; + } + else if( taps == g_tBpfTaps[3] ){ + bw = 30.0; + } + return bw; +} + +//--------------------------------------------------------------------------- +double __fastcall GetMFSKBW(int taps) +{ + int bw = 200.0; + if( taps == g_tBpfTaps[1] ){ + bw = 150.0; + } + else if( taps == g_tBpfTaps[2] ){ + bw = 100.0; + } + else if( taps == g_tBpfTaps[3] ){ + bw = 50.0; + } + return bw; +} + +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::MakeBPF(int taps) +{ + int bw; + m_PreBPFTaps = taps; + m_PreBPFFC = m_CarrierFreq; + switch(m_Type){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + case MODE_GMSK: + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_Speed, m_PreBPFFC + m_Speed, 60, 1.0); + m_BPFLimit = m_Speed * 0.125; + break; + case MODE_FSK: + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_Speed*2, m_PreBPFFC + m_Speed*2, 60, 1.0); + m_BPFLimit = m_Speed * 0.125; + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + bw = GetRTTYBW(taps); + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_RTTYShift*0.5 - bw, m_PreBPFFC + m_RTTYShift*0.5 + bw, 60, 1.0); + m_BPFLimit = 5.0; + break; + case MODE_mfsk_L: + bw = GetMFSKBW(taps); + if( sys.m_MFSK_Center ){ + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_MFSK_BW*0.5 - bw, m_PreBPFFC + m_MFSK_BW*0.5 + bw, 60, 1.0); + } + else { + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_MFSK_BW - bw, m_PreBPFFC + bw, 60, 1.0); + } + m_BPFLimit = 2.0; + break; + case MODE_mfsk_U: + bw = GetMFSKBW(taps); + if( sys.m_MFSK_Center ){ + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - m_MFSK_BW*0.5 - bw, m_PreBPFFC + m_MFSK_BW*0.5 + bw, 60, 1.0); + } + else { + m_inBPF.Create(m_PreBPFTaps, ffBPF, m_SampleFreq, m_PreBPFFC - bw, m_PreBPFFC + m_MFSK_BW + bw, 60, 1.0); + } + m_BPFLimit = 2.0; + break; + } +} + +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + m_RxFreq = f; + m_CarrierQPSK = f; + m_RxFreqQPSK = f; + + MakeBPF(m_PreBPFTaps); + m_VCO.SetFreeFreq(m_CarrierFreq); + switch(m_Type){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_GMSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + m_VCO.SetGain(m_Speed * 0.5 * m_Gain); + m_AFC.SetPara(m_Speed * 0.5 * m_Gain, m_CarrierFreq); + m_SW = m_Speed*0.5; + m_DecPSK.SetCarrierFreq(m_CarrierFreq); + break; + case MODE_FSK: + m_VCO.SetGain(m_Speed * 1.0 * m_Gain); + m_AFC.SetPara(m_Speed * 1.0 * m_Gain, m_CarrierFreq); + m_SW = m_Speed; + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + m_TankL.SetFreq(m_CarrierFreq - (m_RTTYShift * 0.5)); + m_TankH.SetFreq(m_CarrierFreq + (m_RTTYShift * 0.5)); + m_VCO.SetGain(m_RTTYShift * 1.0 * m_Gain); + m_AFC.SetPara(m_RTTYShift * 1.0 * m_Gain, m_CarrierFreq); + m_PhaseX.SetCarrierFreq(m_CarrierFreq - (m_RTTYShift * 0.5)); + m_PhaseX.SetShift(m_RTTYShift); + m_SW = m_RTTYShift; + break; + case MODE_mfsk_L: + case MODE_mfsk_U: + if( m_pMFSK ){ + m_pMFSK->SetCarrierFreq(m_CarrierFreq); + } + break; + } + m_AFC.SetTone(m_CarrierFreq); + m_AGC.SetCarrierFreq(m_CarrierFreq); + if( IsFSK(m_Type) ) m_FAVG.Reset(m_CarrierFreq); + m_fEnableAFC = FALSE; + m_AFCCount = 0; +} +//--------------------------------------------------------------------------- +#define countBPFUPDATE (3*11025/2048) +void __fastcall CDEMFSK::UpdateBPF(void) +{ + double a = fabs(m_PreBPFFC - m_CarrierFreq); + if( a >= m_BPFLimit ){ + m_AGC.SetCarrierFreq(m_CarrierFreq); + MakeBPF(m_PreBPFTaps); + } + m_AFCCount++; +// Application->MainForm->Caption = m_AFCCount; +} +//--------------------------------------------------------------------------- +double __fastcall CDEMFSK::GetFreqErr(void) +{ + if( IsBPSK(m_Type) ){ + return m_FAVG.GetAvg(); + } + else if( m_fMFSK ){ + return (m_RxFreq - m_CarrierFreq) / m_MFSK_SPEED; + } + else { + return (m_RxFreq - m_CarrierFreq) / m_SW; + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::DoAFC(double d) +{ + if( m_AFC.Do(d) ){ + if( !m_fEnableAFC ) return; + if( m_AFCCount < DEMAFCLIMIT ){ + m_RxFreq = m_AFC.GetFreq(); + } + else { + m_RxFreq = m_FAVG.Do(m_AFC.GetFreq()); + } + if( !m_fAFC ) return; + + double a = fabs(m_CarrierFreq - m_RxFreq); + if( (a >= 0.1) && ( a <= (m_Speed*1.5)) ){ + m_CarrierFreq = m_RxFreq; + if( m_AFCCount < DEMAFCLIMIT ) m_FAVG.Reset(m_RxFreq); + m_VCO.SetFreeFreq(m_CarrierFreq); + switch(m_Type){ + case MODE_GMSK: + m_VCO.SetGain(m_Speed * 0.5 * m_Gain); + m_AFC.SetPara(m_Speed * 0.5 * m_Gain, m_CarrierFreq); + break; + case MODE_FSK: + m_VCO.SetGain(m_Speed * 1.0 * m_Gain); + m_AFC.SetPara(m_Speed * 1.0 * m_Gain, m_CarrierFreq); + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: +// m_TankL.SetFreq(m_CarrierFreq - (m_RTTYShift * 0.5)); +// m_TankH.SetFreq(m_CarrierFreq + (m_RTTYShift * 0.5)); + m_VCO.SetGain(m_RTTYShift * 1.0 * m_Gain); + m_AFC.SetPara(m_RTTYShift * 1.0 * m_Gain, m_CarrierFreq); + break; + } + m_AFC.SetTone(m_CarrierFreq); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::DoAFCPSK(double d) +{ + d = m_FAVG.DoZ(d); + if( !m_fEnableAFC ) return; + m_RxFreq = m_CarrierFreq + d * m_Speed * 0.5; + if( !m_fAFC ) return; + + double a = fabs(m_CarrierFreq - m_RxFreq); + if( (a >= 0.1) && ( a <= (m_Speed*1.5)) ){ + m_CarrierFreq = m_RxFreq; + m_VCO.SetFreeFreq(m_CarrierFreq); + switch(m_Type){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_GMSK: + m_VCO.SetGain(m_Speed * 0.5 * m_Gain); + m_AFC.SetPara(m_Speed * 0.5 * m_Gain, m_CarrierFreq); + break; + case MODE_FSK: + m_VCO.SetGain(m_Speed * 1.0 * m_Gain); + m_AFC.SetPara(m_Speed * 1.0 * m_Gain, m_CarrierFreq); + break; + } + m_AFC.SetTone(m_CarrierFreq); + m_out = 0; + m_FAVG.Reset(); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::DoAFCQPSK(double d) +{ + d = m_FAVG.DoZ(d); + if( !m_fEnableAFC ) return; + m_RxFreqQPSK = m_CarrierQPSK + d * m_Speed * 0.5; + if( !m_fAFC ) return; + + double a = fabs(m_CarrierQPSK - m_RxFreqQPSK); + if( (a >= 0.1) && ( a <= (m_Speed*1.5)) ){ + m_CarrierQPSK = m_RxFreqQPSK; + m_VCO.SetFreeFreq(m_CarrierQPSK); + m_VCO.SetGain(m_Speed * 0.5 * m_Gain); + m_AFC.SetPara(m_Speed * 0.5 * m_Gain, m_CarrierQPSK); + m_AFC.SetTone(m_CarrierFreq); + m_out = 0; + m_FAVG.Reset(); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::DoAFCRTTY(double d) +{ + if( m_AFC.Do(d) ){ + if( !m_fEnableAFC ) return; + m_RxFreq = m_AFC.GetFreq(); + if( !m_fAFC ) return; + + double a = fabs(m_CarrierFreq - m_RxFreq); + if( (a >= 1.0) && ( a <= (150.0)) ){ + a *= 0.5; + if( m_CarrierFreq < m_RxFreq ){ + m_CarrierFreq += a; + } + else { + m_CarrierFreq -= a; + } + m_VCO.SetFreeFreq(m_CarrierFreq); + m_TankL.SetFreq(m_CarrierFreq - (m_RTTYShift * 0.5)); + m_TankH.SetFreq(m_CarrierFreq + (m_RTTYShift * 0.5)); + m_VCO.SetGain(m_RTTYShift * 1.0 * m_Gain); + m_AFC.SetPara(m_RTTYShift * 1.0 * m_Gain, m_CarrierFreq); + m_AFC.SetTone(m_CarrierFreq); + m_PhaseX.SetCarrierFreq(m_CarrierFreq - (m_RTTYShift * 0.5)); + } + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::Do(double d) +{ + EPHASE(P_DEMBPF); + if( m_pBPF ){ + d = m_pBPF->Do(m_inBPF.GetHP()); + } + else { + d = m_inBPF.Do(d); + } + m_d = d; + EPHASE(P_DEMAGC); + d = m_AGC.Do(d); + switch(m_Type){ + case MODE_GMSK: // 同期検波 + case MODE_FSK: + EPHASE(P_DEMLPF); + // Loop Filter + m_out = m_LoopLPF.Do(m_err); + EPHASE(P_DEMAFC); + DoAFC(m_out); + if( m_out > 1.5 ){ m_out = 1.5; } else if( m_out < -1.5 ){ m_out = -1.5;} + EPHASE(P_DEMLOCK); + m_Lock = (m_AFC.m_Max - m_AFC.m_Min) * 100; + m_Lock = (m_Lock > m_LockTh); +// m_FreqErr = (m_AFC.m_Max + m_AFC.m_Min) * 0.5; + // VCO + // 位相比較 + EPHASE(P_DEMVCO); + m_err = m_VCO.Do(m_out) * d; + EPHASE(P_DEMOUT); + d = m_OutLPF.Do(m_out); + EPHASE(P_NULL); + return d * 32768.0; + case MODE_BPSK: + case MODE_N_BPSK: // 同期検波 + { + EPHASE(P_NULL); + m_Lock = TRUE; + double ds = d * m_VCO.Do(m_out); + double dc = d * m_VCO.DoCos(); +// double dc = -ds; +#if 0 + m_out = m_LPF1.Do(ABS(ds)) - m_LPF2.Do(ABS(dc)); +#else + m_out = m_LPF1.Do(ABS(ds)-ABS(dc)); +#endif + DoAFCPSK(m_out); +#if MEASIMD + double amp = ds * ds + dc * dc; + if( m_min > amp ) m_min = amp; + if( m_max < amp ) m_max = amp; +#endif + return m_OutLPF.Do(ds - dc) * 32768.0; + } + case MODE_qpsk_L: + case MODE_qpsk_U: // 同期検波 + { + EPHASE(P_NULL); + m_Lock = TRUE; + double ds = d * m_VCO.Do(m_out); + double dc = d * m_VCO.DoCos(); + m_out = m_LPF1.Do(ABS(ds)-ABS(dc)); + DoAFCQPSK(m_out); + return 0; + } + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + if( m_fRTTYTANK ){ // クオドラチャ検波 + EPHASE(P_DEMLPF); + // Loop Filter + m_out = m_LoopLPF.Do(m_err); + EPHASE(P_DEMAFC); + DoAFCRTTY(m_out); + if( m_out > 1.5 ){ m_out = 1.5; } else if( m_out < -1.5 ){ m_out = -1.5;} + EPHASE(P_DEMLOCK); + m_Lock = (m_AFC.m_Max - m_AFC.m_Min) * 100; + m_Lock = (m_Lock > m_LockTh) && (m_DemLevel >= 0.5); +// m_FreqErr = (m_AFC.m_Max + m_AFC.m_Min) * 0.5; + // VCO + // 位相比較 + EPHASE(P_DEMVCO); + m_err = m_VCO.Do(m_out) * d; + EPHASE(P_NULL); + + if( m_fRTTYFFT ){ + m_PhaseX.DoFSK(d); + double ds = m_PhaseX.m_ds; + double dm = m_PhaseX.m_dm; +#if 1 + ds = m_SmoozM.Avg(ds); + dm = m_SmoozS.Avg(dm); + d = ds - dm; +#else + d = m_OutLPF.Do(m_LPF1.Do(ds-dm)); +#endif + m_DemLevel = m_FAVG.Do(ABS(d)) * 4.0; + if( m_DemLevel >= 1.0 ) m_DemLevel = 1.0; + if( m_Type == MODE_RTTY ) d = -d; + return d * 32768.0; + } + else { + d *= 32.0; + if( d > 1.0 ) d = 1.0; + if( d < -1.0 ) d = -1.0; + double ds = m_TankH.Do(d); + double dm = m_TankL.Do(d); + d = m_OutLPF.Do(m_LPF1.Do(ABS(ds)-ABS(dm))); + m_DemLevel = m_FAVG.Do(ABS(d)) * 4.0; + if( m_DemLevel >= 1.0 ) m_DemLevel = 1.0; + if( m_Type == MODE_RTTY ) d = -d; + return d * 32768.0; + } + } + else { // 同期検波 + EPHASE(P_DEMLPF); + // Loop Filter + m_out = m_LoopLPF.Do(m_err); + EPHASE(P_DEMAFC); + DoAFC(m_out); + if( m_out > 1.5 ){ m_out = 1.5; } else if( m_out < -1.5 ){ m_out = -1.5;} + EPHASE(P_DEMLOCK); + m_Lock = (m_AFC.m_Max - m_AFC.m_Min) * 100; + m_Lock = (m_Lock > m_LockTh); + // VCO + // 位相比較 + EPHASE(P_DEMVCO); + m_err = m_VCO.Do(m_out) * d; + EPHASE(P_DEMOUT); + d = m_OutLPF.Do(m_out); + EPHASE(P_NULL); + if( m_Type == MODE_RTTY ) d = -d; + return d * 32768.0; + } + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::Do(double d, BOOL fSQ, BOOL fATC) +{ + if( m_fMFSK ){ + if( m_pBPF ){ + d = m_pBPF->Do(m_inBPF.GetHP()); + } + else { + d = m_inBPF.Do(d); + } + m_d = d; + m_AGC.Do(d); + return m_pMFSK->Do(m_pMFSK->m_Phase.Do(d), fSQ); + } + else if( m_fQPSK ){ + Do(d); + int r = m_DecPSK.Do(m_d, fSQ, fATC); + if( r ){ + m_Decode.m_dTmg2 = m_DecPSK.GetClockError(); + if( m_fEnableAFC ){ + d = m_CarrierQPSK - m_DecPSK.m_NextCarrierFreq; + if( fabs(d) >= (m_Speed / (3.0 * PI)) ){ + m_RxFreq = m_CarrierQPSK; + } + else { + m_RxFreq = m_DecPSK.m_NextCarrierFreq; + } + if( m_fAFC ){ + m_CarrierFreq = m_RxFreq; + m_DecPSK.SetCarrierFreq(m_CarrierFreq); + m_AFC.SetTone(m_CarrierFreq); + } + } + } + return r; + } + else { + return m_Decode.Do(Do(d), fSQ && m_Lock, fATC ); + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::GetData(void) +{ + if( m_fMFSK ){ + if( !m_pMFSK ) return 0; + return m_pMFSK->GetData(); + } + else if( m_fQPSK ){ + return m_DecPSK.GetData(); + } + else { + return m_Decode.GetData(); + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::GetTmg(void) +{ + if( m_fMFSK ){ + return m_pMFSK->GetTmg() ? 1 : -1; + } + else if( m_fQPSK ){ + return m_DecPSK.GetTmg() ? 1 : -1; + } + else { + return m_Decode.GetTmg(); + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::GetTmgLock(void) +{ + if( m_fMFSK ){ + return m_pMFSK->GetTmgLock(); + } + else if( m_fQPSK ){ + return m_DecPSK.GetTmgLock(); + } + else { + return m_Decode.m_Lock; + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::GetS(void) +{ + if( m_fMFSK ){ + return (m_pMFSK->GetS() - (m_MFSK_TONES/2)) * 32768/m_MFSK_TONES; + } + else if( m_fQPSK ){ + return m_DecPSK.GetS(); + } + else { + return m_Decode.m_s ? 16384.0 : -16384.0; + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::ResetMFSK(void) +{ + if( m_pMFSK ){ + m_pMFSK->Reset(); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::ResetMeasMFSK(void) +{ + if( m_pMFSK ){ + m_pMFSK->ResetMeas(); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDEMFSK::GetSyncState(void) +{ + if( m_fMFSK ){ + if( !m_pMFSK ) return FALSE; + return m_pMFSK->GetSyncState(); + } + else if( m_fQPSK ){ + return m_DecPSK.GetSyncState(); + } + else { + return m_Decode.GetSyncState(); + } +} +//--------------------------------------------------------------------------- +int __fastcall CDEMFSK::GetClockError(void) +{ + if( m_fMFSK ){ + if( !m_pMFSK ) return 0; + return m_pMFSK->GetClockError(); + } + else if( m_fQPSK ){ + return m_DecPSK.GetClockError(); + } + else { + double d = m_Decode.m_dTmg2; + if( d >= 0 ){d += 0.5;} else { d -= 0.5; } + return d; + } +} +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::SetTmg(int ppm) +{ + if( m_fMFSK ){ + m_pMFSK->SetTmg(ppm); + } + else if( m_fQPSK ){ + m_DecPSK.SetTmg(ppm); + } + else if( !IsRTTY(m_Type) ){ + m_Decode.SetTmg(ppm); + } +} +#if MEASIMD +//--------------------------------------------------------------------------- +void __fastcall CDEMFSK::CalcIMD(void) +{ + if( m_max > m_min ){ + m_amax = m_max > 0.0 ? sqrt(m_max) : 0.1; + m_amin = m_min > 0.0 ? sqrt(m_min) : 0.1; + DoAvg(m_imd, 20.0*log10(m_amax / m_amin), 0.25); + Application->MainForm->Caption = m_imd; + } + m_max = 0.0; + m_min = 65536.0; +} +#endif + +//--------------------------------------------------------------------------- +__fastcall CMODFSK::CMODFSK() +{ + m_MFSK_TYPE = typMFSK16; + m_MFSK_TONES = 16; + m_MFSK_SPEED = 15.625; + m_MFSK_BW = (m_MFSK_SPEED * (m_MFSK_TONES-1)); + + m_MFSK_K = 1.0 / double(m_MFSK_TONES); + m_fMFSK = FALSE; + + m_fQPSK = FALSE; + m_fLSB = FALSE; + m_Type = 0; + m_Speed = SPEED; + m_CWSpeed = 20; + m_SampleFreq = SAMPFREQ; + m_CarrierFreq = CARRIERFREQ; + m_Encode.SetVCO(&m_Carrier); + m_OutVol = 1; + m_RTTYShift = 170.0; + Create(); +} +//--------------------------------------------------------------------------- +__fastcall CMODFSK::~CMODFSK() +{ +} +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::SetMFSKType(int type) +{ + m_MFSK_TYPE = type; + MFSK_SetPara(type, &m_MFSK_TONES, &m_MFSK_SPEED, NULL); + m_MFSK_BW = (m_MFSK_SPEED * (m_MFSK_TONES-1)); + m_MFSK_K = 1.0 / double(m_MFSK_TONES); + m_Encode.SetMFSKType(type); + SetCarrierFreq(m_CarrierFreq); +} +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::Reset(void) +{ + SetCWSpeed(m_CWSpeed); + m_OutVol = 1; + m_AMPCW.Reset(); + m_AMPSIG.Reset(); + m_BPF.Clear(); + + m_Sym.r = 1; + m_Sym.j = 0; + m_PrevSym = m_Sym; + m_SHDATA = 0; +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::CreateGMSK(void) +{ + // Gaussian特性のテーブルを作成する (1.0 to -1.0) + int i; + double w = m_SampleFreq/m_Speed; + double BT = 1.0; + double LN2 = sqrt(2.0/log(2.0)); + double LN2P = sqrt(2.0*PI/log(2.0)); + double cd = 0; + for( i = 0; i < MODTABLEMAX; i++ ){ +// double d = LN2 * PI * BT * double(i)/w; +// d = BT * exp(-(d * d)); +// d = 1.0 - d; + double d = LN2 * PI * BT * double(i-w*0.5)/w; + d = LN2P * BT * exp(-(d * d)); + cd += (d / w); + // d = 0 to 1 + m_Tbl[MOD_Z2P][i] = cd; // 0 to 1 + m_Tbl[MOD_Z2M][i] = -cd; // 0 to -1 + m_Tbl[MOD_P2M][i] = 1.0 - cd * 2; // 1 to -1 + m_Tbl[MOD_M2P][i] = cd * 2 - 1.0; // -1 to 1 + } +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::CreatePSK(void) +{ + // Cos特性のテーブルを作成する (1.0 to -1.0) + int i; + if( m_fQPSK ){ + double k = PI * m_Speed / m_SampleFreq; + for( i = 0; i < MODTABLEMAX; i++ ){ + double cd = cos(double(i)*k) * 0.5 + 0.5; + m_Tbl[MOD_Z2P][i] = -cd; // 0 to 1 + m_Tbl[MOD_Z2M][i] = cd; // 0 to -1 + m_Tbl[MOD_P2M][i] = cd; // 1 to -1 + m_Tbl[MOD_M2P][i] = -cd; // -1 to 1 + } + } + else { + double k = PI * m_Speed / m_SampleFreq; + for( i = 0; i < MODTABLEMAX; i++ ){ + double cd = cos(double(i)*k); + if( i >= (m_SampleFreq / m_Speed) ) cd = -1.0; + m_Tbl[MOD_Z2P][i] = -cd; // 0 to 1 + m_Tbl[MOD_Z2M][i] = cd; // 0 to -1 + m_Tbl[MOD_P2M][i] = cd; // 1 to -1 + m_Tbl[MOD_M2P][i] = -cd; // -1 to 1 + } + } +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::CreateRTTY(void) +{ +#if 0 + // Gaussian特性のテーブルを作成する (1.0 to -1.0) + int i; + double w = m_SampleFreq/m_Speed; + double BT = 0.5; + double LN2 = sqrt(2.0/log(2.0)); + double LN2P = sqrt(2.0*PI/log(2.0)); + double cd = 0; + for( i = 0; i < MODTABLEMAX; i++ ){ +// double d = LN2 * PI * BT * double(i)/w; +// d = BT * exp(-(d * d)); +// d = 1.0 - d; + double d = LN2 * PI * BT * double(i-w*0.5)/w; + d = LN2P * BT * exp(-(d * d)); + cd += (d / w); + // d = 0 to 1 + m_Tbl[MOD_Z2P][i] = cd; // 0 to 1 + m_Tbl[MOD_Z2M][i] = -cd; // 0 to -1 + m_Tbl[MOD_P2M][i] = 1.0 - cd * 2; // 1 to -1 + m_Tbl[MOD_M2P][i] = cd * 2 - 1.0; // -1 to 1 + } +#else + int i; + for( i = 0; i < MODTABLEMAX; i++ ){ + m_Tbl[MOD_Z2P][i] = 1; // 0 to 1 + m_Tbl[MOD_Z2M][i] = -1; // 0 to -1 + m_Tbl[MOD_P2M][i] = -1; // 1 to -1 + m_Tbl[MOD_M2P][i] = 1; // -1 to 1 + } +#endif +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::Create(void) +{ + m_fMFSK = IsMFSK(m_Type); + m_fQPSK = IsQPSK(m_Type); + m_Encode.SetType(m_Type); + if( m_fMFSK ){ + m_Encode.SetMFSKType(m_MFSK_TYPE); + } + m_Sym.r = 1; + m_Sym.j = 0; + m_PrevSym = m_Sym; + m_s = 0; + m_Carrier.SetSampleFreq(m_SampleFreq); + + SetCarrierFreq(m_CarrierFreq); + m_Encode.SetSampleFreq(m_SampleFreq); + m_Encode.SetSpeed(m_Speed); + SetCWSpeed(m_CWSpeed); + m_AMPSIG.SetMax(m_SampleFreq/m_Speed); + + switch(m_Type){ + case MODE_GMSK: + case MODE_FSK: + case MODE_FSKW: + m_Encode.m_fTWO = FALSE; + CreateGMSK(); + break; + case MODE_BPSK: + m_Encode.m_fTWO = FALSE; + CreatePSK(); + break; + case MODE_N_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + m_Encode.m_fTWO = TRUE; + CreatePSK(); + m_fLSB = (m_Type == MODE_qpsk_L); + break; + case MODE_RTTY: + case MODE_U_RTTY: + m_Encode.m_fTWO = FALSE; + if( m_Speed >= m_RTTYShift ){ + CreateGMSK(); + } + else { + CreateRTTY(); + } + break; + case MODE_mfsk_L: + case MODE_mfsk_U: + m_Encode.m_fTWO = TRUE; + CreateRTTY(); // dummy + break; + } + m_pTbl = NULL; + m_d = 0.0; +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::SetCWSpeed(int d) +{ + m_CWSpeed = d; + int dCW = m_SampleFreq/m_CWSpeed; + if( dCW < 2 ) dCW = 2; + m_AMPCW.SetMax(dCW*0.25); + m_Encode.SetCW(d); +} + +//--------------------------------------------------------------------------- +void __fastcall CMODFSK::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + m_Carrier.SetFreeFreq(m_CarrierFreq); + switch(m_Type){ + case MODE_qpsk_L: + case MODE_qpsk_U: + case MODE_BPSK: + case MODE_N_BPSK: + case MODE_GMSK: + m_Carrier.SetGain((m_Speed * 0.5) * 0.5); // fm = 0.5 + break; + case MODE_FSK: + m_Carrier.SetGain((m_Speed * 0.5) * 1.0); // fm = 1.0 + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + m_Carrier.SetGain(m_RTTYShift * 0.5); + break; + case MODE_mfsk_L: +// m_Carrier.SetGain(-250); + m_Carrier.SetGain(-m_MFSK_SPEED * m_MFSK_TONES); + if( sys.m_MFSK_Center ){ + m_Carrier.SetFreeFreq(m_CarrierFreq+m_MFSK_BW*0.5); + } + break; + case MODE_mfsk_U: +// m_Carrier.SetGain(250); + m_Carrier.SetGain(m_MFSK_SPEED * m_MFSK_TONES); + if( sys.m_MFSK_Center ){ + m_Carrier.SetFreeFreq(m_CarrierFreq-m_MFSK_BW*0.5); + } + break; + } + double fl, fh; + int fHigh = (m_SampleFreq >= 15000.0); + int type = ffBPF; + double dATT = 60; + if( fHigh ) dATT -= ((m_SampleFreq - 15000.0)/1750); + if( Is170(m_Type) ){ + double hw = m_RTTYShift * 0.5; + fl = m_CarrierFreq - hw - (fHigh ? (m_SampleFreq*0.1) : 200); + fh = m_CarrierFreq + hw + (fHigh ? (m_SampleFreq*0.1) : 200); + } + else if( m_fMFSK ){ + double hw = m_MFSK_SPEED; + if( m_Type == MODE_mfsk_U ){ + fl = m_CarrierFreq - hw - (fHigh ? (m_SampleFreq*0.1) : 200); + fh = m_CarrierFreq + m_MFSK_BW + hw + (fHigh ? (m_SampleFreq*0.1) : 200); + } + else { + fl = m_CarrierFreq - m_MFSK_BW - hw - (fHigh ? (m_SampleFreq*0.1) : 200); + fh = m_CarrierFreq + hw + (fHigh ? (m_SampleFreq*0.1) : 200); + } + } + else { + fl = m_CarrierFreq-m_Speed - (fHigh ? (m_SampleFreq*0.1) : 200); + fh = m_CarrierFreq+m_Speed + (fHigh ? (m_SampleFreq*0.1) : 200); + } + if( fl < (fHigh ? 800 : 200) ){ + type = ffLPF; + fl = fh; + } + m_BPF.Create(24, type, m_SampleFreq, fl, fh, dATT, 1.0); +} + +//-------------------------------------------------------- +double __fastcall CMODFSK::Do(void) +{ + int s = m_Encode.Do(); + if( (s == 128)||(s == 129) ){ + s -= 128; // s = 0 or 1 + return m_BPF.Do(m_Carrier.Do() * m_AMPCW.Do(s)); + } + else if( m_fMFSK ){ + return m_BPF.Do(m_Carrier.Do(double(s)*m_MFSK_K)*m_AMPSIG.Do(m_OutVol)); + } + else if( m_fQPSK ){ + if( !m_Encode.m_Cnt ){ + s = m_Encode.m_outbit; + m_PrevSym = m_Sym; + if( s == -1 ){ + s = 0; + } + else { + m_SHDATA = m_SHDATA << 1; + if( s > 0 ) m_SHDATA |= 1; + + s = tQPSK_Viterbi[m_SHDATA & 0x1f]; + if(m_fLSB){ + switch(s){ // 回転方向を逆転 + case 1: + s = 3; + break; + case 3: + s = 1; + break; + } + } + } + switch(s){ // 左回転 + case 0: // 0 + m_Sym.r = 1.0; + m_Sym.j = 0.0; + break; + case 1: // 270 + m_Sym.r = 0.0; + m_Sym.j = -1.0; + break; + case 2: // 180 + m_Sym.r = -1.0; + m_Sym.j = 0.0; + break; + case 3: // 90 + m_Sym.r = 0.0; + m_Sym.j = 1.0; + break; + } + m_Sym *= m_PrevSym; + } + double sh = m_Tbl[MOD_Z2M][m_Encode.m_Cnt]; + double iv = sh * m_PrevSym.r + (1.0 - sh) * m_Sym.r; + double qv = sh * m_PrevSym.j + (1.0 - sh) * m_Sym.j; + + double d = (m_Carrier.Do() * qv + m_Carrier.DoCos() * iv); + return m_BPF.Do(d*m_AMPSIG.Do(m_OutVol)); + } + int cnt = m_Encode.m_Cnt; + if( !cnt ){ + if( s > 0 ){ + if( m_s > 0 ){ // 1 to 1 + m_d = 1.0; m_pTbl = NULL; + } + else if( m_s < 0 ){ // -1 to 1 + m_pTbl = m_Tbl[MOD_M2P]; + } + else { // 0 to 1 + m_pTbl = m_Tbl[MOD_Z2P]; + } + } + else if( s < 0 ){ + if( m_s > 0 ){ // 1 to -1 + m_pTbl = m_Tbl[MOD_P2M]; + } + else if( m_s < 0 ){ // -1 to -1 + m_d = -1; m_pTbl = NULL; + } + else { // 0 to -1 + m_pTbl = m_Tbl[MOD_Z2M]; + } + } + else { // 0 + m_d = 0; m_pTbl = NULL; + } + m_s = s; + } + if( cnt > MODTABLEMAX ) cnt = MODTABLEMAX - 1; + if( m_pTbl ){ + m_d = m_pTbl[cnt]; + } + double d; + switch(m_Type){ + case MODE_GMSK: // 周波数変調 + case MODE_FSK: + case MODE_FSKW: + case MODE_RTTY: + d = m_Carrier.Do(m_d); + break; + case MODE_BPSK: + case MODE_N_BPSK: // 直交変調 + d = -m_d; + d = (m_Carrier.Do() * m_d + m_Carrier.DoCos() * d) * PSK_OUTFAC; + break; + case MODE_U_RTTY: + d = m_Carrier.Do(-m_d); + break; + default: + d = 0.0; + break; + } + return m_BPF.Do(d*m_AMPSIG.Do(m_OutVol)); +} + +double __fastcall CMODFSK::DoCarrier(void) +{ + return m_BPF.Do(m_Carrier.Do()*m_AMPSIG.Do(m_OutVol)); +} + +//-------------------------------------------------------- +__fastcall CDECFSK::CDECFSK() +{ + m_Tmg = 0; + m_cMode = 0; + m_SampleFreq = SAMPFREQ; +// m_SampleFreq = 11100; + m_Speed = SPEED; + m_Lock = 0; + m_dAdj = 0; + m_dTmg3 = 0; + m_dTmg2 = 0; + m_dTmg = 0; + m_fATC = TRUE; + Create(); + m_T = 0; + m_T2 = 0; + m_T3 = 0; + m_cBWave = 15; + m_ATCSpeed = 0; + m_ATCLimit = 25000; + + m_ATCCounter = 0; + m_Type = MODE_GMSK; + m_AvgRTTY.Create(48); +} + +#define INI_T2 64 +#define LPFA 20 +#define LPFB 16 +void __fastcall CDECFSK::Create(void) +{ + m_dBTW = m_dTW = m_SampleFreq / m_Speed; + SetATCLimit(m_ATCLimit); + SetTmg(m_dAdj); + m_LPF.Create(LPFA*m_SampleFreq/11025); + m_LPFI.Create(LPFB*m_SampleFreq/11025); + m_cMode = 0; + for( int i = 0; i < 16; i++ ){ + m_LPF.Do(0); + m_LPFI.Do(0); + } + m_GainA = 60.0 / m_Speed; + SetATCSpeed(m_ATCSpeed); + m_dNow = 0; + m_dNext = m_dTW; + m_dFree = m_dTW; + m_T = 0; + m_T2 = INI_T2; + m_T3 = 0; + m_Threshold = 128.0; + m_A = 0; + if( m_Speed >= 70.0 ) m_Threshold *= 0.7; + m_a = 0; + + m_ATCCounter = 0; + m_ATCLimitH = 32 * m_SampleFreq / m_Speed; + m_ATCLimitL = 0.5 * m_SampleFreq / m_Speed; +} + +void __fastcall CDECFSK::SetATCSpeed(int atcspeed) +{ + m_ATCSpeed = atcspeed; +// m_GainB = 0.002 * 60.0 / m_Speed; + m_GainB = 0.002 * 60.0 / 31.25; + if( m_ATCSpeed ){ + m_GainB *= ((m_ATCSpeed * 0.5) + 1.0); + } +} + +void __fastcall CDECFSK::SetATCLimit(int atclimit) +{ + m_ATCLimit = atclimit; + double d = double(atclimit) * 1.0e-6; + m_dBTWL = m_dBTW * (1.0-d); + m_dBTWH = m_dBTW * (1.0+d); +} + +void __fastcall CDECFSK::ClearLPF(void) +{ + for( int i = 0; i < 16; i++ ){ + m_LPF.Do(0); + m_LPFI.Do(0); + } +} + +void __fastcall CDECFSK::Reset(void) +{ + m_dTW = m_SampleFreq / m_Speed; + m_dTWH = m_dTW * 0.5; + m_dNow = 0; + m_dNext = m_dTW; + m_dFree = m_dTW; + m_T = 0; + ClearLPF(); + m_T2 = INI_T2; + m_T3 = 0; + + m_dTmg3 = 0; + m_dTmg2 = 0; + m_dTmg = 0; + + m_ATCCounter = 0; + m_ATCLimitH = 32 * m_SampleFreq / m_Speed; + m_ATCLimitL = 0.5 * m_SampleFreq / m_Speed; + + m_fSync = FALSE; + m_BAUDOT.ClearRX(); + + m_fMeasClock = FALSE; + m_MeasError = m_MeasClock = m_MeasCounter = 0; + m_Meas1st = TRUE; + m_AvgRTTY.Reset(); +} + +void __fastcall CDECFSK::SetTmg(int ppm) +{ + if( (ppm < -50000) || (ppm > 50000) ) return; + + m_dAdj = ppm; + m_dTW = m_SampleFreq / m_Speed; + m_dTW += m_dTW * m_dAdj * 1.0e-6; +// m_dBTW = m_dTW; + m_dTWH = m_dTW * 0.5; + m_T2 = INI_T2; +} + +void __fastcall CDECFSK::SetMeasClock(BOOL f) +{ + if( IsRTTY(m_Type) ) return; + + m_fMeasClock = f; + if( !f ) m_MeasClock = m_MeasCounter = 0; +} + +BOOL __fastcall CDECFSK::GetSyncState(void) +{ + if( IsRTTY(m_Type) ){ + return m_fSync; + } + else if( m_T && (m_T3 > 16) ){ + return (fabs(m_dTmg) >= (0.2*60.0/m_Speed)) ? FALSE : TRUE; + } + else { + return FALSE; + } +} + +BOOL __fastcall CDECFSK::Do(double d, BOOL sq, BOOL fATC) +{ + BOOL r = FALSE; + int s = m_s; + if( ABS(d) > m_Threshold ){ + s = (d > 0) ? 1 : 0; + } + if( IsRTTY(m_Type) ){ + return DoBAUDOT(s, sq); + } + int u; + m_ATCCounter++; + m_dNow += 1.0; + if( m_dNow >= m_dFree ) m_dFree += m_dTW; + if( s != m_s ){ + m_s = s; + if( (m_ATCCounter >= m_ATCLimitL) && (m_ATCCounter < m_ATCLimitH) ){ + BOOL f1st = sq && !m_T; + d = m_dFree - m_dNow; + if( d >= m_dTWH ) d -= m_dTW; + d /= m_dBTW; + if( (m_dTmg >= 0.3) && (d < -0.1) ) d += 1.0; + if( (m_dTmg < -0.3) && (d > 0.1) ) d -= 1.0; + if( !sq ) d *= 0.1; + if( sq && !m_T ){ // 最初の1回目 + m_dFree -= d * m_dBTW; + } + d = m_LPF.Do(d * m_GainA); + m_dTmg3 = d - m_A; + m_A = d; + m_dTmg = d; + if( m_T ){ + if( m_T3 < 256 ){ + d *= 2.0; + } + else if( !fATC ){ + d *= 0.5; + } +// if( !fATC ) d *= (m_T3 > 256) ? 0.25 : 2.0; + m_dFree -= d; + } + + if( sq ){ + m_T = m_Speed; + m_T3++; + } + else if( !m_T ){ + d = (m_dTW - m_dBTW) * 20.0; + m_T2 = INI_T2; + m_T3 = 0; + m_MeasClock = m_MeasCounter = 0; + } + else { + m_T--; + m_MeasClock = m_MeasCounter = 0; + } + d = m_LPFI.Do(d); + if( (!m_T2 && fATC) || !m_T ){ + if( m_fATC ){ + m_dTW -= d * m_GainB; + if( m_dTW < m_dBTWL ){ m_dTW = m_dBTWL; } + if( m_dTW > m_dBTWH ){ m_dTW = m_dBTWH; } + m_dTWH = m_dTW * 0.5; + } + } + else if( m_T2 ){ + m_T2--; + } + m_dTmg2 = ((m_dTW / m_dBTW) - 1.0) * 1e6; + if( GetSyncState() ){ + m_dNext = m_dFree - m_dTW*0.5; + if( m_dNext > (m_dNow + m_dTW) ){ + m_dNext -= m_dTW; + } + if( m_dNext < m_dNow ) m_dNext += m_dTW; + } + else if( f1st ){ + m_dNext = m_dNow + m_dTWH; + m_MeasClock = m_MeasCounter = 0; + } + else { + d = m_dNext - m_dNow; + m_dNext = m_dNow + (d + m_dTWH) * 0.5; +// m_dNext = m_dNow + (d * 0.25 + m_dTWH * 0.75); + } + } + m_ATCCounter = 0; + } + if( m_MeasClock ) m_MeasCounter++; + switch(m_cMode){ + case 0: + if( m_dNext <= m_dNow ){ + m_MeasClock++; + if( m_MeasClock >= 256 ){ + if( sq && fATC && !GetSyncState() && m_fMeasClock ){ + d = double(m_MeasCounter) / double(m_MeasClock-1); + m_dTW += (d - m_dTW) * 0.5; + if( m_dTW < m_dBTWL ){ m_dTW = m_dBTWL; } + if( m_dTW > m_dBTWH ){ m_dTW = m_dBTWH; } + m_dTWH = m_dTW * 0.5; + } + m_MeasClock = 1; + m_MeasCounter = 0; + } + m_Tmg = !m_Tmg; + m_dNext += m_dTW; + u = (s != m_a) ? 0 : 1; + m_a = s; + m_cData = m_cData << 1; + if( u && sq ){ + if( !m_Lock ) m_Tmg = 1; + m_cData = 1; + m_cBCount = 1; + m_cMode++; + m_Lock = TRUE; + } + else { + if( !m_cBCount ){ + m_Lock = TRUE; + } + else if( m_cBCount >= m_cBWave ){ + m_cBCount = -1; + m_Lock = FALSE; + } + m_cBCount++; + } + } + break; + case 1: + if( m_dNext <= m_dNow ){ + m_MeasClock++; + m_Tmg = !m_Tmg; + m_dNext += m_dTW; + u = (s != m_a) ? 0 : 1; + m_a = s; + m_cData = m_cData << 1; + m_cBCount++; + if( u ){ + m_cData |= 1; + } + else if( m_cBCount >= 3){ + if( !(m_cData & 3) ){ + m_Data = g_VariCode.Decode(m_cData >> 2); + r = TRUE; + m_cMode--; + m_Lock = FALSE; + } + } + } + break; + default: + m_cMode = 0; + break; + } + if( m_dNow >= 1000.0 ){ + m_dNow -= 1000.0; + m_dNext -= 1000.0; + m_dFree -= 1000.0; + } + return r; +} + +//--------------------------------------------------------------------------- +BOOL __fastcall CDECFSK::DoBAUDOT(int s, BOOL sq) +{ + if( s != m_s ){ + m_s = s; + if( sq ){ + if( !m_cMode && !s ){ + if( m_MeasClock ){ + int tw = m_MeasCounter - m_MeasClock; + int stw = m_SampleFreq * 6.5 / m_Speed; + if( tw < stw ){ + m_MeasError++; + if( m_MeasError >= 3 ){ + m_MeasError = m_MeasCounter = m_MeasClock = 0; + m_AvgRTTY.Reset(); + } + } + else if( m_AvgRTTY.IsHalf() ){ + int atw = m_AvgRTTY.GetAvg(); + if( ABS(atw-tw) >= (m_dTW*0.2) ){ + m_MeasError++; + if( m_MeasError >= 3 ){ + m_MeasError = m_MeasCounter = m_MeasClock = 0; + m_AvgRTTY.Reset(); + } + } + else { + m_AvgRTTY.Do(tw); + m_MeasError = 0; + } + } + else { + m_AvgRTTY.Do(tw); + } + } + if( m_Meas1st ){ + m_AvgRTTY.Reset(); + } + else { + m_MeasClock = m_MeasCounter = 1; + } + } + } + else { + m_MeasError = m_MeasCounter = m_MeasClock = 0; + m_Meas1st = TRUE; + } + } + BOOL r = FALSE; + m_MeasCounter++; + m_dNow += 1.0; + switch(m_cMode){ + case 0: // Start bits? + if( !s && sq ){ + m_Lock = TRUE; + m_Tmg = 0; + m_dNext = m_dNow + m_dTW*0.5; + m_cData = 0; + m_cBCount = 0; + m_cMode++; + } + break; + case 1: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_Tmg = !m_Tmg; + m_cMode++; + } + break; + case 2: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_Tmg = !m_Tmg; + m_cData = m_cData << 1; + if( s ) m_cData |= 0x01; + m_cBCount++; + if( m_cBCount >= 5 ){ + m_cMode++; + } + } + break; + case 3: // Stop bits + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_Tmg = !m_Tmg; + m_fSync = s; + if( s ){ + m_Meas1st = FALSE; + r = TRUE; + m_cMode = 0; + m_Data = m_BAUDOT.ConvAscii(m_cData); + } + else { // フレーミングエラー + m_cMode++; + m_MeasClock = 0; + m_Data = m_BAUDOT.ConvAscii(m_cData); // added by JE3HHT on Sep.2010 + } + m_Lock = FALSE; + } + break; + case 4: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + } + if( s ){ + m_cMode = 0; + } + break; + default: + m_cMode = 0; + break; + } + if( m_dNow >= 1000.0 ){ + m_dNow -= 1000.0; + m_dNext -= 1000.0; + } + return r; +} +//-------------------------------------------------------------------------- +void __fastcall DoAvg(float &av, float in, float factor) +{ + av = av * (1.0 - factor) + (in * factor); +} +//-------------------------------------------------------------------------- +void __fastcall DoAvg(double &av, double in, double factor) +{ + av = av * (1.0 - factor) + (in * factor); +} +//--------------------------------------------------------------------------- +__fastcall CFAVG::CFAVG() +{ + Create(16); +} +//--------------------------------------------------------------------------- +void __fastcall CFAVG::Reset(void) +{ + m_Cnt = 0; + m_Sum = 0; + m_Avg = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CFAVG::Reset(double d) +{ + m_Cnt = m_Max; + m_Sum = d * m_Max; + m_Avg = d; +} +//--------------------------------------------------------------------------- +void __fastcall CFAVG::Create(int max) +{ + m_Max = max; + m_Mul = 1.0 / m_Max; + Reset(); +} +//--------------------------------------------------------------------------- +double __fastcall CFAVG::DoZ(double d) +{ + m_Sum += d; + if( m_Cnt < m_Max ){ + m_Cnt++; + } + else { + m_Sum -= m_Avg; + } + m_Avg = m_Sum * m_Mul; + return m_Avg; +} +//--------------------------------------------------------------------------- +double __fastcall CFAVG::Do(double d) +{ + m_Sum += d; + if( m_Cnt < m_Max ){ + m_Cnt++; + m_Avg = m_Sum / m_Cnt; + } + else { + m_Sum -= m_Avg; + m_Avg = m_Sum * m_Mul; + } + return m_Avg; +} +//--------------------------------------------------------------------------- +__fastcall CAVG::CAVG() +{ + m_Max = 0; + m_pZ = NULL; + m_Sum = 0.0; + m_Avg = 0; + m_Cnt = m_W = 0; +} + +__fastcall CAVG::~CAVG() +{ + if( m_pZ ) delete m_pZ; +} + +void __fastcall CAVG::Create(int max) +{ + if( max == m_Max ) return; + + m_Max = max; + if( m_pZ ) delete m_pZ; + m_pZ = new double[max]; + Reset(); +} + +void __fastcall CAVG::Reset(void) +{ + m_Cnt = m_W = 0; + m_Sum = 0.0; + m_Avg = 0.0; +} + +void __fastcall CAVG::Reset(double d) +{ + if( !m_pZ ) return; + + double *dp = m_pZ; + for( int i = 0; i < m_Max; i++ ){ + *dp++ = d; + } + m_Avg = d; + m_Sum = d * m_Max; + m_W = 0; + m_Cnt = m_Max; +} + +double __fastcall CAVG::Do(double d) +{ + if( !m_Max ) return d; + + double *dp = &m_pZ[m_W]; + if( m_Cnt >= m_Max ){ + m_Sum -= *dp; + } + else { + m_Cnt++; + } + m_W++; + if( m_W >= m_Max ) m_W = 0; + *dp = d; + m_Sum += d; + m_Avg = m_Sum / m_Cnt; + return m_Avg; +} + +//-------------------------------------------------------- +__fastcall CENCODE::CENCODE() +{ + m_MFSK_TYPE = typMFSK16; + m_MFSK_TONES = 16; + m_MFSK_SPEED = 15.625; + m_MFSK_BITS = 4; + m_MFSK_MASK = m_MFSK_TONES - 1; + + m_pFunc = NULL; + m_Speed = SPEED; + m_SampleFreq = SAMPFREQ; + m_Code = 0; + Create(); + m_RP = m_WP = m_CC = 0; + m_Idle = FALSE; + m_pVCO = NULL; + m_fJA = TRUE; + m_fTWO = FALSE; + m_fCW = FALSE; + m_Type = MODE_GMSK; + m_BAUDOT.Reset(); + m_rttyDiddle = diddleLTR; + m_rttyCWait = m_rttyDWait = 0; + m_Mark = FALSE; + + m_Viterbi.Init(MFSK_VITERBI_K, MFSK_VITERBI_POLY1, MFSK_VITERBI_POLY2); + m_MFSK_SHDATA = 0; + m_MFSK_SHCount = 0; +} +//-------------------------------------------------------- +void __fastcall CENCODE::SetMFSKType(int type) +{ + m_MFSK_TYPE = type; + MFSK_SetPara(type, &m_MFSK_TONES, &m_MFSK_SPEED, &m_MFSK_BITS); + m_MFSK_MASK = m_MFSK_TONES - 1; + Create(); +} +//-------------------------------------------------------- +void __fastcall CENCODE::Create(void) +{ + m_Mode = 0; + m_dCW = m_SampleFreq / 20.0; + if( IsMFSK(m_Type) ){ + m_dTW = m_SampleFreq / m_MFSK_SPEED; + } + else { + m_dTW = m_SampleFreq / m_Speed; + } + m_out = 0; + m_sync = 0; + m_Idle = FALSE; + m_fCW = FALSE; + memset(m_Z, 0, sizeof(m_Z)); +} +void __fastcall CENCODE::SetTmg(double d) +{ + if( IsMFSK(m_Type) ){ + m_dTW = m_SampleFreq / m_MFSK_SPEED; + } + else { + m_dTW = m_SampleFreq / m_Speed; + } + m_dTW += m_dTW * d / 1e6; +} +void __fastcall CENCODE::Reset(BOOL fCW) +{ + m_fCW = fCW; + m_Code = 0; + m_Mode = 0; + m_RP = m_WP = m_CC = 0; + m_Idle = FALSE; + m_Mark = FALSE; +} +void __fastcall CENCODE::SetCW(int f) +{ + m_dCW = m_SampleFreq / f; +} +//-------------------------------------------------------- +static int __fastcall GetCWCode(int &count, int code) +{ + const USHORT _tbl[]={ + // 0 1 2 3 4 5 6 7 + 0x0005, 0x8005, 0xc005, 0xe005, 0xf005, 0xf805, 0x7805, 0x3805, // 0-7 + // 8 9 : ; < = > ? + 0x1805, 0x0805, 0xe806, 0xA805, 0x0000, 0x7005, 0x0000, 0xcc06, // 8 + // @ A B C D E F G + 0xb805, 0x8002, 0x7004, 0x5004, 0x6003, 0x8001, 0xd004, 0x2003, // @-G + // H I J K L M N O + 0xf004, 0xc002, 0x8004, 0x4003, 0xb004, 0x0002, 0x4002, 0x0003, // H-O + // P Q R S T U V W + 0x9004, 0x2004, 0xa003, 0xe003, 0x0001, 0xc003, 0xe004, 0x8003, // P-W + // X Y Z [ \ ] + 0x6004, 0x4004, 0x3004, 0x0000, 0x0000, 0x4805, 0x0000, 0x0000, // X-Z + }; + if( code == '/' ){ + code = 0x6805; + count = 5; + } + else if( (code >= 0x30) && (code <= 0x7f) ){ + if( code >= 0x60 ) code -= 0x20; + code -= 0x30; + code = _tbl[code]; + count = code & 0x000f; + } + else { + code = 0; + count = 0; + } + return code; +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendBit(BOOL bit) +{ + MFSKSendPair(m_Viterbi.Do(bit)); +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendPair(BYTE pair) +{ + MFSKSendSymBit(pair & 2); + MFSKSendSymBit(pair & 1); +} +//-------------------------------------------------------------------------- +// +void __fastcall CENCODE::MFSKSendSymBit(BOOL bit) +{ + const BYTE _tGray2Bin[]={ //Encode + 0x00,0x01,0x03,0x02,0x07,0x06,0x04,0x05, + 0x0F,0x0E,0x0C,0x0D,0x08,0x09,0x0B,0x0A, + 0x1F,0x1E,0x1C,0x1D,0x18,0x19,0x1B,0x1A, + 0x10,0x11,0x13,0x12,0x17,0x16,0x14,0x15, + }; + + m_MFSK_SHDATA = m_MFSK_SHDATA << 1; + if( bit ) m_MFSK_SHDATA |= 1; + + m_MFSK_SHCount++; + if( m_MFSK_SHCount >= m_MFSK_BITS ){ + m_Fifo.PutData(_tGray2Bin[m_InterLeaver.EncodeBits(m_MFSK_SHDATA) & m_MFSK_MASK]); + m_MFSK_SHDATA = 0; + m_MFSK_SHCount = 0; + } +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendChar(int c) +{ + int code = g_VariCode.EncodeMFSK(BYTE(c)); + int n = (code & 0x0f000) >> 12; + for( n--; n >= 0; n-- ){ + MFSKSendBit(_tBitData[n] & code); + } +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendIdle(void) +{ + MFSKSendIdle(m_MFSK_TONES); +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendIdle(int n) +{ + for(int i = 0; i < n; i++){ + MFSKSendBit(0); + } +} +//-------------------------------------------------------------------------- +void __fastcall CENCODE::MFSKSendIdleChar(void) +{ + MFSKSendChar(0); + MFSKSendIdle(); + m_fChar = FALSE; +} +//-------------------------------------------------------------------------- +int __fastcall MFSK_GetIdleCount(int type) +{ + switch(type){ + case typMFSK4: + return (rand() % 2) + 2; + case typMFSK8: + return (rand() % 2) + 3; + case typMFSK31: + case typMFSK32: + return (rand() % 4) + 16; + case typMFSK64: + return (rand() % 8) + 24; + default: + return (rand() % 4) + 8; + } +} +//-------------------------------------------------------- +int __fastcall CENCODE::Do(void) +{ + m_Cnt++; + m_dNow += 1.0; + switch(m_Mode){ + case 0: // エンコードの開始 + m_fReqRX = FALSE; + m_fChar = FALSE; + if( m_pVCO ) m_pVCO->InitPhase(); + if( IsMFSK(m_Type) ){ + m_Fifo.Clear(); + m_InterLeaver.Init(m_MFSK_BITS); + m_Viterbi.Reset(); + m_MFSK_SHDATA = 0; + m_MFSK_SHCount = 0; + } + + if( m_fCW ){ + m_out = 128; + m_Mode = IsMFSK(m_Type) ? 130 : 2; + } + else if( IsRTTY(m_Type) ){ + m_Mark = FALSE; + m_BAUDOT.Reset(); + m_out = -1; + m_Mode = 64; + } + else if( IsMFSK(m_Type) ){ + m_out = 0; + m_Mode = 128; + } + else { + m_out = IsPSK(m_Type) ? 1 : 0; + m_Mode++; + } + m_outbit = m_out; + m_Cnt = 0; + m_dNext = m_dTW * 2; + m_dNow = 0.0; + m_cBCount = 0; + m_Idle = FALSE; + break; + case 1: + if( m_dNext <= m_dNow ){ + m_outbit = 0; + m_out = (m_out >= 0) ? -1 : 1; + m_dNext += m_dTW; + m_cBCount++; + if( IsQPSK(m_Type) ){ + if( m_cBCount >= (1.0 * m_Speed) ){ + m_cBCount = 0; + m_Mode++; + } + } + else { + if( m_cBCount >= (0.64 * m_Speed) ){ + m_cBCount = 0; + m_Mode++; + } + } + m_Cnt = 0; + } + break; + case 2: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + if( !m_cBCount ){ + if( m_CC ){ + m_cData = GetChar(); + } + else if( m_pFunc ){ + m_cData = m_pFunc(); + } + else { + m_cData = GetChar(); + } + if( (m_cData >= 0x100) && (m_cData < 0x0200) ){ + m_Idle = FALSE; + m_cData -= 0x0100; + m_cData = GetCWCode(m_cBCount, m_cData); + m_dNext -= m_dTW; + m_dNext += m_fCW ? m_dCW : m_dCW*3; + m_out = 128; + m_Mode = 16; + m_fCW = TRUE; + break; + } + else if( m_cData == 0x200 ){ // Idle + m_fCW = FALSE; + m_Idle = FALSE; + m_cData = 0; + m_cBCount = 20; + } + else if( m_cData >= 0 ){ + m_fCW = FALSE; + m_Idle = FALSE; + if( m_fTWO && (m_cData >= 0x8140) && (m_cData <= 0xfeff) ){ + int c1 = (m_cData >> 8) & 0x00ff; + int c2 = m_cData & 0x00ff; + c1 = g_VariCode.Mbcs2Index(c1, FALSE); + c2 = g_VariCode.Mbcs2Index(c2, FALSE); + int b1, b2; + int d1 = g_VariCode.Encode(b1, c1) << 2; + int d2 = g_VariCode.Encode(b2, c2) << 2; + m_cData = (d1 << (b2+2)) | d2; + m_cBCount = b1 + b2 + 4; + } + else { + m_cData = g_VariCode.Mbcs2Index(m_cData, m_fTWO ? FALSE : m_fJA); + if( m_cData >= 0 ){ + m_cData = g_VariCode.Encode(m_cBCount, m_cData) << 2; + m_cBCount += 2; + } + else { + m_cData = 0; + m_cBCount = 1; + } + } + } + else if( m_fCW ){ + m_out = 128; + m_Idle = TRUE; + break; + } + else if( (m_Mark || m_fReqRX) && sys.m_fSendSingleTone && IsPSK(m_Type) ){ + m_outbit = -1; + m_cBCount = 32; + m_Idle = FALSE; + m_Mode++; + m_Cnt = 0; + break; + } + else { + m_Idle = TRUE; + m_cData = 0; + m_cBCount = 1; + } + } + m_cBCount--; + m_outbit = (m_cData & _tBitData[m_cBCount]); + if( !(m_cData & _tBitData[m_cBCount]) ){ + m_out = (m_out > 0) ? -1 : 1; + } + m_Cnt = 0; + } + break; + case 3: // output single tone for the ending transmission + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_cBCount--; + if( m_cBCount <= 0 ){ + m_Idle = TRUE; + m_cData = 0; + m_cBCount = 1; + } + m_outbit = -1; + m_Cnt = 0; + } + break; + // CW output + case 16: + if( m_dNext <= m_dNow ){ + if( m_cBCount ){ + m_dNext += m_cData & 0x8000 ? m_dCW : m_dCW*3; + m_out = 129; + m_Mode++; + } + else { + m_out = 128; + m_dNext += m_dCW*6; + m_Mode = IsMFSK(m_Type) ? 130 : 2; + } + } + break; + case 17: // スペース + if( m_dNext <= m_dNow ){ + m_dNext += m_dCW; + m_out = 128; + m_cData = m_cData << 1; + m_cBCount--; + if( !m_cBCount ){ + m_dNext += m_dCW; + m_Mode = IsMFSK(m_Type) ? 130 : 2; + } + else { + m_Mode--; + } + } + break; + case 64: // BAUDOT + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_cBCount++; + if( m_cBCount >= (0.25 * m_Speed) ){ + m_cBCount = 0; + m_Mode++; + } + m_Cnt = 0; + } + break; + case 65: // BAUDOT + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW*0.5; + if( !m_cBCount ){ + if( m_CC ){ + m_cData = GetChar(); + } + else if( m_pFunc ){ + m_cData = m_pFunc(); + } + else { + m_cData = GetChar(); + } + if( (m_cData >= 0x100) && (m_cData < 0x0200) ){ + m_Idle = FALSE; + m_cData -= 0x0100; + m_cData = GetCWCode(m_cBCount, m_cData); + m_dNext -= m_dTW*0.5; + m_dNext += m_fCW ? m_dCW : m_dCW*3; + m_out = 128; + m_Mode = 16; + m_fCW = TRUE; + break; + } + else if( m_cData == 0x200 ){ // Idle + m_BAUDOT.Reset(); + m_fCW = FALSE; + m_Idle = FALSE; + if( m_fChar ){ + m_cData = (m_rttyDiddle == diddleLTR) ? 0x7ffc : 0x7000; + } + else { + m_cData = 0xffff; + } + m_cBCount = 15; + } + else if( m_cData >= 0 ){ + m_fChar = TRUE; + m_fCW = FALSE; + m_Idle = FALSE; + m_cData = m_BAUDOT.GetCode(m_cBCount, m_cData); + if( m_cData < 0 ){ + m_cData = 0x7000; // BLK + m_cBCount = 15; + } + } + else if( m_fCW ){ + m_BAUDOT.Reset(); + m_out = 128; + m_Idle = TRUE; + break; + } + else if( m_Mark || m_fReqRX ){ + m_fChar = FALSE; + m_out = -1; + m_Idle = TRUE; + break; + } + else { // Diddle + m_BAUDOT.Reset(); + m_Idle = TRUE; + m_cData = (m_rttyDiddle == diddleLTR) ? 0x7ffc : 0x7000; + m_cBCount = 15; + } + } + m_cBCount--; + if( !(m_cData & 0x0001) ){ + m_out = 1; + } + else { + m_out = -1; + } + m_cData = m_cData >> 1; + m_Cnt = 0; + if( !m_cBCount || (m_cBCount == 15) ){ + if( m_Idle ){ + if( m_rttyDWait ) m_Mode++; + } + else { + if( m_rttyCWait ) m_Mode++; + } + } + } + break; + case 66: // BAUDOT-wait + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW * 0.1 * (m_Idle ? m_rttyDWait : m_rttyCWait); + m_Mode = 65; + } + m_Cnt = 0; + break; + + // MFSK + case 128: + switch(m_MFSK_TYPE){ + case typMFSK4: + m_cBCount = 8; + break; + case typMFSK31: + case typMFSK32: + m_cBCount = 32; + break; + case typMFSK64: + m_cBCount = 64; + break; + case typMFSK22: + m_cBCount = 22; + break; + default: + m_cBCount = 16; + break; + } + m_dNext = m_dNow + m_dTW; + m_Mode++; + case 129: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + m_cBCount--; + if( !m_cBCount ){ + if( (m_MFSK_TONES == 8)||(m_MFSK_TONES == 32) ){ // 2ビタビのメトリックス初期化のため + MFSKSendChar(0); + MFSKSendChar(0); + } + m_Mode++; + } + } + break; + case 130: + case 131: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + if( !m_Fifo.GetCount() ){ +_try:; + if( m_CC ){ + m_cData = GetChar(); + } + else if( m_pFunc ){ + m_cData = m_pFunc(); + } + else { + m_cData = GetChar(); + } + if( (m_cData >= 0x100) && (m_cData < 0x0200) ){ + m_Idle = FALSE; + m_cData -= 0x0100; + m_cData = GetCWCode(m_cBCount, m_cData); + if( m_fCW ){ + m_dNext -= m_dTW; + m_dNext += m_fCW ? m_dCW : m_dCW*3; + m_out = 128; + m_Mode = 16; + m_fCW = TRUE; + } + else { + MFSKSendIdleChar(); + MFSKSendIdleChar(); + MFSKSendIdleChar(); + m_Mode = 132; + if( m_Fifo.GetCount() ) m_out = m_Fifo.GetData(); + } + break; + } + else if( m_cData == 0x200 ){ // Idle + m_Mode = 130; + m_fCW = FALSE; + m_Idle = FALSE; +// MFSKSendIdleChar(); + if( m_fChar ){ + MFSKSendIdleChar(); + } + else { + MFSKSendIdle(); + } + MFSKSendIdle(); + } + else if( m_cData >= 0 ){ + m_fChar = TRUE; + m_Mode = 130; + m_fCW = FALSE; + m_Idle = FALSE; + if( m_fTWO && (m_cData >= 0x8140) && (m_cData <= 0xfeff) ){ + MFSKSendChar((m_cData >> 8) & 0x00ff); + MFSKSendChar(m_cData & 0x00ff); + } + else { + MFSKSendChar(m_cData & 0x00ff); + } + } + else if( m_fCW ){ + m_out = 128; + m_Idle = TRUE; + break; + } + else if( m_Mode == 130 ){ + m_Idle = FALSE; + MFSKSendIdleChar(); + m_cBCount = 3; + m_Mode++; + } + else if( m_Idle ){ + m_cBCount--; + if( m_cBCount <= 0 ){ + m_cBCount = MFSK_GetIdleCount(m_MFSK_TYPE); + MFSKSendIdleChar(); + } + else { + MFSKSendIdle(); + } + } + else if( m_fReqRX ){ + if( m_MFSK_TONES == 32 ){ + MFSKSendIdle(26); + } + else if( m_MFSK_TONES == 16 ){ + MFSKSendIdle(32); + } + else { + MFSKSendIdle(20); + } + m_cBCount--; + if( m_cBCount <= 0 ){ + m_Idle = TRUE; + m_cBCount = MFSK_GetIdleCount(m_MFSK_TYPE); + } + } + else { + m_cBCount--; + if( m_cBCount <= 0 ){ + m_Idle = TRUE; + m_cBCount = MFSK_GetIdleCount(m_MFSK_TYPE); + if( m_MFSK_TONES == 32 ){ + MFSKSendIdleChar(); + } + else { + MFSKSendIdle(); + } + } + else { + MFSKSendIdle(); + } + } + } + if( m_Fifo.GetCount() ){ + m_out = m_Fifo.GetData(); + } + else { + goto _try; + } + } + break; + case 132: + if( m_dNext <= m_dNow ){ + m_dNext += m_dTW; + if( m_Fifo.GetCount() ){ + m_out = m_Fifo.GetData(); + } + else { + m_dNext += m_fCW ? m_dCW : m_dCW*3; + m_out = 128; + m_Mode = 16; + m_fCW = TRUE; + } + } + break; + } + if( m_dNow >= 8192.0 ){ + m_dNow -= 8192.0; + m_dNext -= 8192.0; + } + return m_out; +} + +//-------------------------------------------------------- +BOOL __fastcall CENCODE::IsBuffFull(void) +{ + return m_CC >= AN(m_Buff); +} + +//-------------------------------------------------------- +void __fastcall CENCODE::PutChar(int c) +{ + if( !IsBuffFull() ){ + m_Buff[m_WP] = c; + m_WP++; + if( m_WP >= AN(m_Buff) ){ + m_WP = 0; + } + m_CC++; + } +} + +//-------------------------------------------------------- +int __fastcall CENCODE::GetChar(void) +{ + if( !m_CC ) return -1; + int c = m_Buff[m_RP]; + m_RP++; + if( m_RP >= AN(m_Buff) ){ + m_RP = 0; + } + m_CC--; + return c; +} + +//-------------------------------------------------------- +__fastcall CCOLLECT::CCOLLECT() +{ + m_Max = 0; + m_Cnt = 0; + m_pZ = NULL; +} + +__fastcall CCOLLECT::~CCOLLECT() +{ + if( m_pZ ) delete m_pZ; +} + +void __fastcall CCOLLECT::Create(int max) +{ + if( m_Max == max ) return; + + m_Max = max; + m_Cnt = 0; + if( m_pZ ) delete m_pZ; + m_pZ = new double[m_Max]; + memset(m_pZ, 0, sizeof(m_pZ)); +} + +void __fastcall CCOLLECT::Do(double d) +{ + if( m_Cnt >= m_Max ) return; + + m_pZ[m_Cnt] = d; + m_Cnt++; +} + + +//--------------------------------------------------------------------------- +const BYTE _tMbcs2Index[]={ // PSK31 index converter + 0x58,0x62,0x66,0x76,0x65,0x71,0x67,0x6B, /*00*/ + 0x6C,0x30,0x0A,0x74,0x63,0x0B,0x75,0x7A, /*08*/ + 0x69,0x68,0x7B,0x7C,0x6F,0x72,0x73,0x6E, /*10*/ + 0x77,0x78,0x7E,0x6D,0x70,0x7F,0x6A,0x79, /*18*/ + 0x00,0x57,0x3A,0x53,0x4D,0x60,0x5D,0x42, /*20*/ + 0x33,0x32,0x3D,0x4F,0x1C,0x0F,0x15,0x45, /*28*/ + 0x25,0x27,0x2F,0x35,0x3F,0x38,0x3B,0x44, /*30*/ + 0x43,0x47,0x31,0x49,0x51,0x14,0x4C,0x5A, /*38*/ + 0x5E,0x1F,0x2E,0x22,0x24,0x1D,0x2B,0x34, /*40*/ + 0x36,0x20,0x56,0x41,0x2A,0x26,0x2C,0x21, /*48*/ + 0x29,0x4E,0x23,0x1B,0x1A,0x37,0x46,0x39, /*50*/ + 0x3E,0x40,0x59,0x54,0x52,0x55,0x5F,0x3C, /*58*/ + 0x64,0x04,0x18,0x0E,0x0D,0x01,0x12,0x16, /*60*/ + 0x0C,0x05,0x50,0x28,0x09,0x11,0x06,0x03, /*68*/ + 0x13,0x4A,0x07,0x08,0x02,0x10,0x1E,0x19, /*70*/ + 0x2D,0x17,0x4B,0x5C,0x48,0x5B,0x61,0x7D, +}; + +//--------------------------------------------------------------------------- +__fastcall CVARICODE::CVARICODE() +{ + m_tEncode = NULL; + m_Max = m_TMax = 0; +} + +__fastcall CVARICODE::~CVARICODE() +{ + if( m_tEncode ) delete m_tEncode; +} + +void __fastcall CVARICODE::Init(void) +{ + if( !LoadBin("VariCode.tbl") ){ + Create(256+(192*126)); + } + for( int i = 0; i < 128; i++ ){ + m_tIndex2Mbcs[_tMbcs2Index[i]] = BYTE(i); + } +} + +void __fastcall CVARICODE::Create(int max) +{ + if( m_tEncode ) delete m_tEncode; + m_TMax = max; + DWORD *tEncode = new DWORD[m_TMax]; + m_Max = 0; + int i; + int b, db; + tEncode[m_Max++] = 0x01000001; + tEncode[m_Max++] = 0x02000003; + int bmax = 3; + int bm = 2; + int bl = 0; + while(m_Max < m_TMax){ + for( b = bl; b < bm; b++ ){ + BOOL f = TRUE; + db = b; + for( i = 3; i < bmax; i++ ){ + if( !(db & 1) && !(db & 2) ){ + f = FALSE; + break; + } + db = db >> 1; + } + if( f ){ + db = b << 1; + db |= (1 | (bm<<1)); + db = db | (bmax << 24); + tEncode[m_Max++] = db; + if( m_Max >= m_TMax ) break; + } + } + bl = bl << 1; + if( !(bl & 2) ) bl |= 1; + bm = bm << 1; + bmax++; + if( bmax >= 24 ) break; + } + m_tEncode = tEncode; + SaveBin("VariCode.tbl"); +} + +static int __fastcall SwapIndex(int index) +{ + if( index <= 0x00d3 ){ // $80-$D3 + index += 0x21f - 0x0080; // $80-$D3 to Hiragana + } + else if( index <= 0x12a ){ // $D4-$12A + index += 0x280 - 0x00d4; // $D4-$12A to Katakana + } + else if( (index >= 0x021f) && (index <= 0x0272) ){ // Hiragana + index -= 0x21f - 0x0080; // Hiragana to $80-$D3 + } + else if( (index >= 0x0280) && (index <= 0x02d6) ){ // Katakana + index -= 0x280 - 0x00d4; // Katakana to $D4-$12A + } + else if( (index >= 0x1840) && (index <= 0x2f7f) ){ + index += 0x4840 - 0x1840; + } + else if( (index >= 0x4840) && (index <= 0x5f7f) ){ + index -= 0x4840 - 0x1840; + } + + return index; +} + +UINT __fastcall CVARICODE::Index2Mbcs(int index, BOOL fJA) +{ + if( fJA && (index >= 0x4840) ){ // 古いバージョンとの互換性用 + index -= 0x4840 - 0x1840; + } + if( index <= 0x007f ){ + index = m_tIndex2Mbcs[index]; + } + else if( index >= m_Max ){ + return 0; + } + else if( fJA ){ + index = SwapIndex(index); + } + + UINT mbcs; + int m, b; + if( index >= 0x0100 ){ + index -= 0x0100; + m = index % 192; + b = index / 192; + mbcs = 0x8140 + m + b * 256; + } + else { + mbcs = index; + } + return mbcs; +} + +int __fastcall CVARICODE::Mbcs2Index(UINT mbcs, BOOL fJA) +{ + int index, m, b; + if( mbcs >= 0x8100 ){ + if( (mbcs & 0x00ff) >= 0x0040 ){ + mbcs -= 0x8100; + m = mbcs % 256; + b = mbcs / 256; + index = 0x100 - 0x40 + m + b * 192; + } + else { + return -1; + } + } + else { + index = mbcs; + } + if( index >= m_Max ){ + index = 0; + } + else if( index <= 0x007f ){ + index = _tMbcs2Index[index]; + } + else if( fJA ){ + index = SwapIndex(index); + } + return index; +} + +void __fastcall CVARICODE::SaveTable(LPCSTR pName) +{ + CWaitCursor w; + FILE *fp; + if( (fp = fopen(pName, "wt")) != NULL ){ + OnWave(); + fprintf(fp, "Index ANSI JA HL/BV/BY Bits\tVaricode\n"); + int i, j; + for( i = 0; i < m_Max; i++ ){ + DWORD b = m_tEncode[i]; + int n = b >> 24; + b &= 0x00ffffff; + int m = Index2Mbcs(i, FALSE); + j = Index2Mbcs(i, TRUE); + if( i >= 0x2f80 ){ + fprintf(fp, "%04X %04X %-4u\t", i, m, n); + } + else if( i < 0x100 ){ + fprintf(fp, "%04X %04X %04X %04X %-4u\t", i, m, j, m, n); + } + else { + fprintf(fp, "%04X %04X %04X %-4u\t", i, j, m, n); + } + DWORD bm = _tBitData[n-1]; + for( j = 0; j < n; j++, bm = bm >> 1){ + fprintf(fp, "%c", (b & bm) ? '1' : '0'); + } + fprintf(fp, "\n"); + if( !(i & 0xff) ) OnWave(); + } + fclose(fp); + OnWave(); + } +} + +void __fastcall CVARICODE::SaveSource(LPCSTR pName) +{ + FILE *fp; + if( (fp = fopen(pName, "wt")) != NULL ){ + fprintf(fp, "const DWORD g_tVariCode[%u]={\n", m_TMax); + int i; + for( i = 0; i < m_Max; i++ ){ + DWORD b = m_tEncode[i]; + if( !(i % 8) ) fprintf(fp, "\n\t"); + fprintf(fp, "0x%X,", b); + } + fprintf(fp, "};\n"); + fclose(fp); + } +} + +void __fastcall CVARICODE::SaveBin(LPCSTR pName) +{ + CWaitCursor w; + char name[256]; + sprintf(name, "%s%s", sys.m_BgnDir, pName); + FILE *fp; + if( (fp = fopen(name, "wb")) != NULL ){ + fwrite(m_tEncode, sizeof(DWORD), m_Max, fp); + fclose(fp); + } +} + +BOOL __fastcall CVARICODE::LoadBin(LPCSTR pName) +{ + BOOL r = FALSE; + char name[256]; + sprintf(name, "%s%s", sys.m_BgnDir, pName); + FILE *fp; + if( (fp = fopen(name, "rb")) != NULL ){ + int len = 256 + (126*192); + if( m_tEncode ) delete m_tEncode; + m_tEncode = new DWORD[len]; + fread(m_tEncode, sizeof(DWORD), len, fp); + fclose(fp); + m_TMax = m_Max = len; + r = TRUE; + } + return r; +} + +DWORD __fastcall CVARICODE::Encode(int &n, DWORD d) +{ + if( d < DWORD(m_Max) ){ + d = m_tEncode[d]; + n = d >> 24; + } + else { + d = 0; + n = 1; + } + return d; +} + +int __fastcall CVARICODE::Decode(DWORD d) +{ + // VARICODEを二分探査サーチでインデックスに変換 + int l, h, m; + l = 0; + h = m_Max - 1; + while(l <= h){ + m = (l + h)/2; + DWORD b = m_tEncode[m] & 0x00ffffff; + if( d < b ){ + h = m - 1; + } + else if( d > b ){ + l = m + 1; + } + else { + return m; + } + } + return -1; +} +//--------------------------------------------------------------------------- +const WORD g_tMFSKVariCode[]={ // MFSK VARICODE インデックス順 + 0x3004,0x4008,0x400C,0x5010,0x5014,0x5018,0x501C,0x6020,0x6028,0x602C,0x6030,0x6034,0x6038,0x603C,0x7040,0x7050, //00 + 0x7054,0x7058,0x705C,0x7060,0x7068,0x706C,0x7070,0x7074,0x7078,0x707C,0x8080,0x80A0,0x80A8,0x80AC,0x80B0,0x80B4, //10 + 0x80B8,0x80BC,0x80C0,0x80D0,0x80D4,0x80D8,0x80DC,0x80E0,0x80E8,0x80EC,0x80F0,0x80F4,0x80F8,0x80FC,0x9100,0x9140, //20 + 0x9150,0x9154,0x9158,0x915C,0x9160,0x9168,0x916C,0x9170,0x9174,0x9178,0x917C,0x9180,0x91A0,0x91A8,0x91AC,0x91B0, //30 + 0x91B4,0x91B8,0x91BC,0x91C0,0x91D0,0x91D4,0x91D8,0x91DC,0x91E0,0x91E8,0x91EC,0x91F0,0x91F4,0x91F8,0x91FC,0xA200, //40 + 0xA280,0xA2A0,0xA2A8,0xA2AC,0xA2B0,0xA2B4,0xA2B8,0xA2BC,0xA2C0,0xA2D0,0xA2D4,0xA2D8,0xA2DC,0xA2E0,0xA2E8,0xA2EC, //50 + 0xA2F0,0xA2F4,0xA2F8,0xA2FC,0xA300,0xA340,0xA350,0xA354,0xA358,0xA35C,0xA360,0xA368,0xA36C,0xA370,0xA374,0xA378, //60 + 0xA37C,0xA380,0xA3A0,0xA3A8,0xA3AC,0xA3B0,0xA3B4,0xA3B8,0xA3BC,0xA3C0,0xA3D0,0xA3D4,0xA3D8,0xA3DC,0xA3E0,0xA3E8, //70 + 0xA3EC,0xA3F0,0xA3F4,0xA3F8,0xA3FC,0xB400,0xB500,0xB540,0xB550,0xB554,0xB558,0xB55C,0xB560,0xB568,0xB56C,0xB570, //80 + 0xB574,0xB578,0xB57C,0xB580,0xB5A0,0xB5A8,0xB5AC,0xB5B0,0xB5B4,0xB5B8,0xB5BC,0xB5C0,0xB5D0,0xB5D4,0xB5D8,0xB5DC, //90 + 0xB5E0,0xB5E8,0xB5EC,0xB5F0,0xB5F4,0xB5F8,0xB5FC,0xB600,0xB680,0xB6A0,0xB6A8,0xB6AC,0xB6B0,0xB6B4,0xB6B8,0xB6BC, //A0 + 0xB6C0,0xB6D0,0xB6D4,0xB6D8,0xB6DC,0xB6E0,0xB6E8,0xB6EC,0xB6F0,0xB6F4,0xB6F8,0xB6FC,0xB700,0xB740,0xB750,0xB754, //B0 + 0xB758,0xB75C,0xB760,0xB768,0xB76C,0xB770,0xB774,0xB778,0xB77C,0xB780,0xB7A0,0xB7A8,0xB7AC,0xB7B0,0xB7B4,0xB7B8, //C0 + 0xB7BC,0xB7C0,0xB7D0,0xB7D4,0xB7D8,0xB7DC,0xB7E0,0xB7E8,0xB7EC,0xB7F0,0xB7F4,0xB7F8,0xB7FC,0xC800,0xCA00,0xCA80, //D0 + 0xCAA0,0xCAA8,0xCAAC,0xCAB0,0xCAB4,0xCAB8,0xCABC,0xCAC0,0xCAD0,0xCAD4,0xCAD8,0xCADC,0xCAE0,0xCAE8,0xCAEC,0xCAF0, //E0 + 0xCAF4,0xCAF8,0xCAFC,0xCB00,0xCB40,0xCB50,0xCB54,0xCB58,0xCB5C,0xCB60,0xCB68,0xCB6C,0xCB70,0xCB74,0xCB78,0xCB7C, +}; +const BYTE g_tMFSKIndex2Ascii[]={ // MFSK Index -> Ascii + 0x20,0x65,0x74,0x6F,0x61,0x69,0x6E,0x72,0x73,0x6C,0x68,0x64,0x63,0x75,0x6D,0x66, //00 + 0x70,0x67,0x79,0x62,0x77,0x76,0x6B,0x78,0x71,0x7A,0x6A,0x2C,0x08,0x0D,0x54,0x53, //10 + 0x45,0x41,0x49,0x4F,0x43,0x52,0x44,0x30,0x4D,0x50,0x31,0x4C,0x46,0x4E,0x42,0x32, //20 + 0x47,0x33,0x48,0x55,0x35,0x57,0x36,0x58,0x34,0x59,0x4B,0x38,0x37,0x56,0x39,0x51, //30 + 0x4A,0x5A,0x27,0x21,0x3F,0x2E,0x2D,0x3D,0x2B,0x2F,0x3A,0x29,0x28,0x3B,0x22,0x26, //40 + 0x40,0x25,0x24,0x60,0x5F,0x2A,0x7C,0x3E,0x3C,0x5C,0x5E,0x23,0x7B,0x7D,0x5B,0x5D, //50 + 0x7E,0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE, //60 + 0xAF,0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE, //70 + 0xBF,0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE, //80 + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE, //90 + 0xDF,0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE, //A0 + 0xEF,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE, //B0 + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,0x0E,0x0F,0x10, //C0 + 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x7F, //D0 + 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F, //E0 + 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F, +}; +const BYTE g_tMFSKAscii2Index[]={ // MFSK Ascii -> Index + 0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0x1C,0xC9,0xCA,0xCB,0xCC,0x1D,0xCD,0xCE, //00 + 0xCF,0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE, //10 + 0x00,0x43,0x4E,0x5B,0x52,0x51,0x4F,0x42,0x4C,0x4B,0x55,0x48,0x1B,0x46,0x45,0x49, //20 + 0x27,0x2A,0x2F,0x31,0x38,0x34,0x36,0x3C,0x3B,0x3E,0x4A,0x4D,0x58,0x47,0x57,0x44, //30 + 0x50,0x21,0x2E,0x24,0x26,0x20,0x2C,0x30,0x32,0x22,0x40,0x3A,0x2B,0x28,0x2D,0x23, //40 + 0x29,0x3F,0x25,0x1F,0x1E,0x33,0x3D,0x35,0x37,0x39,0x41,0x5E,0x59,0x5F,0x5A,0x54, //50 + 0x53,0x04,0x13,0x0C,0x0B,0x01,0x0F,0x11,0x0A,0x05,0x1A,0x16,0x09,0x0E,0x06,0x03, //60 + 0x10,0x18,0x07,0x08,0x02,0x0D,0x15,0x14,0x17,0x12,0x19,0x5C,0x56,0x5D,0x60,0xDF, //70 + 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF, //80 + 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF, //90 + 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,0x70, //A0 + 0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,0x80, //B0 + 0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x90, //C0 + 0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,0xA0, //D0 + 0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,0xB0, //E0 + 0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,0xC0, +}; +//--------------------------------------------------------------------------- +int __fastcall CVARICODE::DecodeMFSK(DWORD d) +{ + // VARICODEを二分探査サーチでインデックスに変換 + int l, h, m; + l = 0; + h = 256 - 1; + while(l <= h){ + m = (l + h)/2; + DWORD b = g_tMFSKVariCode[m] & 0x00fff; + if( d < b ){ + h = m - 1; + } + else if( d > b ){ + l = m + 1; + } + else { + return g_tMFSKIndex2Ascii[m]; + } + } + return -1; +} + +//--------------------------------------------------------------------------- +int __fastcall CVARICODE::EncodeMFSK(BYTE c) +{ + return g_tMFSKVariCode[g_tMFSKAscii2Index[c]]; +} + +//--------------------------------------------------------------------------- +BCODETBL _TTY[]={ // S-BELL + // 0x20 - 0x7f + {0x04, 2}, {0x16, 1}, {0x11, 1}, {0x00, 2}, // !"# + {0x12, 1}, {0x00, 2}, {0x0b, 1}, {0x1a, 1}, // $%&' + {0x1e, 1}, {0x09, 1}, {0x00, 2}, {0x00, 2}, // ()*+ + {0x06, 1}, {0x18, 1}, {0x07, 1}, {0x17, 1}, // ,-./ + {0x0d, 1}, {0x1d, 1}, {0x19, 1}, {0x10, 1}, // 0123 30-33 + {0x0a, 1}, {0x01, 1}, {0x15, 1}, {0x1c, 1}, // 4567 34-37 + {0x0c, 1}, {0x03, 1}, {0x0e, 1}, {0x0f, 1}, // 89 38-3b + {0x00, 2}, {0x00, 2}, {0x00, 2}, {0x13, 1}, // <=>? 3c-3f + {0x00, 2}, {0x18, 0}, {0x13, 0}, {0x0e, 0}, // @ABC 40-43 + {0x12, 0}, {0x10, 0}, {0x16, 0}, {0x0b, 0}, // DEFG + {0x05, 0}, {0x0c, 0}, {0x1a, 0}, {0x1e, 0}, // HIJK + {0x09, 0}, {0x07, 0}, {0x06, 0}, {0x03, 0}, // LMNO + {0x0d, 0}, {0x1d, 0}, {0x0a, 0}, {0x14, 0}, // PQRS + {0x01, 0}, {0x1c, 0}, {0x0f, 0}, {0x19, 0}, // TUVW + {0x17, 0}, {0x15, 0}, {0x11, 0}, {0x00, 2}, // XYZ[ 58-5b + {0x00, 2}, {0x00, 2}, {0x00, 2}, {0x00, 2}, // \]^_ + {0x00, 2}, {0x18, 0}, {0x13, 0}, {0x0e, 0}, // @ABC 60-63 + {0x12, 0}, {0x10, 0}, {0x16, 0}, {0x0b, 0}, // DEFG + {0x05, 0}, {0x0c, 0}, {0x1a, 0}, {0x1e, 0}, // HIJK + {0x09, 0}, {0x07, 0}, {0x06, 0}, {0x03, 0}, // LMNO + {0x0d, 0}, {0x1d, 0}, {0x0a, 0}, {0x14, 0}, // PQRS + {0x01, 0}, {0x1c, 0}, {0x0f, 0}, {0x19, 0}, // TUVW + {0x17, 0}, {0x15, 0}, {0x11, 0}, {0x00, 2}, // XYZ[ 78-7b + {0x00, 2}, {0x00, 2}, {0x00, 2}, {0x00, 2}, // |{~ +}; + +//--------------------------------------------------------------------------- +__fastcall CBAUDOT::CBAUDOT() +{ + Reset(); +} +//--------------------------------------------------------------------------- +__fastcall CBAUDOT::~CBAUDOT() +{ +} +//--------------------------------------------------------------------------- +int __fastcall CBAUDOT::GetOneCode(int &fig, int code) +{ + int r; + switch(code){ + case '\n': + r = 0x08; + fig = 2; + break; + case '\r': + r = 0x02; + fig = 2; + break; + default: + if( (code >= 0x20) && (code <= 0x7f) ){ + code -= 0x20; + r = _TTY[code].Code; + fig = _TTY[code].Fig; + } + else { + r = -1; + } + break; + } + return r; +} +//--------------------------------------------------------------------------- +// 15bitsデータを作成する +int __fastcall CBAUDOT::DblCode(int code) +{ + int d = 7; // Stop bits + int i; + for( i = 0; i < 5; i++, code = code >> 1 ){ + d = d << 1; + if( code & 0x0001 ) d |= 1; + d = d << 1; + if( code & 0x0001 ) d |= 1; + } + d = d << 2; // Start bits + return d; +} +//--------------------------------------------------------------------------- +int __fastcall CBAUDOT::GetCode(int &count, int code) +{ + int fig; + int r = GetOneCode(fig, code); + if( r < 0 ) return r; +//Added by JA7UDE (April 17, 2010) + int ext_r = r; + int ext_f = 0; +//Till here + r = DblCode(r); + if( (m_OutFig < 0) || ((fig != 2)&&(m_OutFig != fig)) || ((m_CodeB4 == ' ')&&(fig==1)) ){ + switch(fig){ + case 1: // FIG + m_OutFig = 1; + r = r << 15; + r |= DblCode(0x1b); +//Added by JA7UDE (April 17, 2010) + ext_f = 0x1b; +//Till here + break; + default: // LTR + m_OutFig = 0; + r = r << 15; + r |= DblCode(0x1f); +//Added by JA7UDE (April 17, 2010) + ext_f = 0x1f; +//Till here + break; + } + count = 30; + } + else { + count = 15; + } + m_CodeB4 = code; +//Added by JA7UDE on April 5, 2010 + if( ext_f ) MainVARI->ExtFskIt(ext_f); + MainVARI->ExtFskIt(ext_r); +//Till here + return r; +} +//--------------------------------------------------------------------------- +const char _LTR[32]={ + 0x00, 'T', 0x0d, 'O', ' ', 'H', 'N', 'M', + 0x0a, 'L', 'R', 'G', 'I', 'P', 'C', 'V', + 'E', 'Z', 'D', 'B', 'S', 'Y', 'F', 'X', + 'A', 'W', 'J', 0x00, 'U', 'Q', 'K', 0x00, +}; +const char _FIG[32]={ + 0x00, '5', 0x0d, '9', ' ', 'h', ',', '.', + 0x0a, ')', '4', '&', '8', '0', ':', ';', + '3', '"', '$', '?', 's', '6', '!', '/', + '-', '2', 0x27, 0x00, '7', '1', '(', 0x00, +}; + +CRTTY::CRTTY() +{ + m_outfig = 3; + + m_fig = 0; + m_uos = TRUE; + + m_txuos = 1; + m_CodeSet = 0; // 0:S-BELL, 1:J-BELL + SetCodeSet(); +} + +void CRTTY::SetCodeSet(void) +{ + memcpy(m_TBL, _TTY, sizeof(m_TBL)); + if( m_CodeSet ){ // J-BELL + m_TBL[7].Code = 0x14; + } +} + +// 11011 FIG +// 11111 LTR +char CRTTY::ConvAscii(int d) +{ + char c = 0; + d &= 0x1f; + if( d == 0x1b ){ // FIG + m_fig = 1; + } + else if( d == 0x1f ){ // LTR + m_fig = 0; + } + else if( m_fig ){ + c = _FIG[d]; + if( m_CodeSet ){ + switch(c){ + case 's': + c = 0x27; + break; + case 0x27: + c = 'j'; + break; + } + } + if( m_uos ){ + switch(c){ + case ' ': +// case 0x0d: +// case 0x0a: + m_fig = 0; + break; + default: + break; + } + } + } + else { + c = _LTR[d]; + } + return c; +} + +int CRTTY::ConvRTTY(char d) +{ + int fig = 2; + int r = 0; + switch(d){ + case '_': + r = 0x00ff; + break; + case '~': + r = 0x00fe; + break; + case '[': + r = 0x00fd; + break; + case ']': + r = 0x00fc; + break; + case 0x0a: + r = 0x08; + break; + case 0x0d: + r = 0x02; + break; + case 0x1b: + r = 0x1b; + fig = 1; + break; + case 0x1f: + r = 0x1f; + fig = 0; + break; + default: + if( d >= 0x20 ){ + d -= char(0x20); + r = m_TBL[d].Code; + fig = m_TBL[d].Fig; + } + break; + } + if( fig != 2 ){ + if( fig != m_outfig ){ + r |= (fig ? 0x1b00 : 0x1f00); + m_outfig = fig; + } + } + else if( r == 0x04 ){ // スペースの時 + if( m_outfig == 1 ) m_outfig = 2; + } + return r; +} + +int CRTTY::ConvRTTY(BYTE *t, LPCSTR p) +{ + int n; + int d; + for( n = 0;*p; p++ ){ + d = ConvRTTY(*p); + if( d & 0x0000ff00 ){ + *t++ = BYTE(d >> 8); + n++; + } + *t++ = BYTE(d); + n++; + } + return n; +} + +int CRTTY::GetShift(char d) +{ + int fig = 2; + switch(d){ + default: + if( d >= 0x20 ){ + d -= char(0x20); + fig = m_TBL[d].Fig; + if( !m_TBL[d].Code ){ + fig = 2; + } + } + break; + } + return fig; +} + +char CRTTY::InvShift(char c) +{ + int fs = GetShift(c); + if( (c == 'h') || (c == 's') || (c == 'j') ) fs = 1; + int d = ConvRTTY(c) & 0x001f; + switch(fs){ + case 0: + if( _FIG[d] ){ + c = _FIG[d]; + if( m_CodeSet ){ + switch(c){ + case 's': + c = 0x27; + break; + case 0x27: + c = 'j'; + break; + } + } + } + return c; + case 1: + return _LTR[d] ? _LTR[d] : c; + default: + return c; + } +} + +//--------------------------------------------------------------------------- +__fastcall CClock::CClock() +{ + m_pData = NULL; + m_SampleFreq = SAMPFREQ; + m_ToneFreq = 1000.0; +} + +//--------------------------------------------------------------------------- +__fastcall CClock::~CClock() +{ + if( m_pData ) delete m_pData; +} + +//--------------------------------------------------------------------------- +void __fastcall CClock::Create(int max) +{ + m_Width = max; + if( m_pData ) delete m_pData; + m_pData = new int[m_Width]; + memset(m_pData, 0, sizeof(int)*m_Width); + m_dNow = 0; + m_BPF.m_Freq = m_ToneFreq; + m_BPF.m_BW = 100.0; + SetSampleFreq(m_SampleFreq); + m_LPF.Create(ffLPF, 100, m_SampleFreq, 3, 0, 0); + +} + +//--------------------------------------------------------------------------- +void __fastcall CClock::SetSampleFreq(double f) +{ + m_SampleFreq = f; + m_dAdd = m_Width / m_SampleFreq; + m_BPF.SetSampleFreq(m_SampleFreq); +} + +//--------------------------------------------------------------------------- +void __fastcall CClock::SetToneFreq(double f) +{ + m_ToneFreq = f; + m_BPF.m_Freq = m_ToneFreq; + m_BPF.SetSampleFreq(m_SampleFreq); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CClock::Do(short ds) +{ + BOOL f = FALSE; + double d = m_BPF.Do(ds); + d = m_LPF.Do(ABS(d)); + int i = m_dNow; + if( i < 0 ) i = 0; + if( i > m_Width ) i = m_Width; + m_pData[i] = d; + m_dNow += m_dAdd; + if( m_dNow >= m_Width ){ + f = TRUE; + m_dNow -= m_Width; + } + if( m_dNow < 0 ) m_dNow += m_Width; + return f; +} +//--------------------------------------------------------------------------- +__fastcall CAMPCONT::CAMPCONT() +{ + m_Max = g_SinTable.m_Size / 4; + m_iMax = g_SinTable.m_Size / 4; + m_Cnt = m_Max; + m_S = 0; + SetMax(16); +} +//--------------------------------------------------------------------------- +void __fastcall CAMPCONT::SetMax(int max) +{ + m_ADD = m_Max / double(max); +} +//--------------------------------------------------------------------------- +void __fastcall CAMPCONT::Reset(void) +{ + m_Cnt = m_Max; + m_S = 0; +} +//--------------------------------------------------------------------------- +double __fastcall CAMPCONT::Do(int s) +{ + if( s != m_S ){ + m_Cnt = 0.0; + m_S = s; + } + int r = m_Cnt; + if( r >= m_Max ) return s; + m_Cnt += m_ADD; + if( s ){ + return g_SinTable.m_tSin[r]; + } + else { + return g_SinTable.m_tSin[r+m_iMax]; + } +} + + +//--------------------------------------------------------------------------- +__fastcall CBFifo::CBFifo() +{ + m_WP = m_RP = m_CNT = m_MAX = 0; + m_pBase = NULL; + m_D = FALSE; +} +//--------------------------------------------------------------------------- +__fastcall CBFifo::~CBFifo() +{ + if( m_pBase ){ + delete m_pBase; + m_pBase = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall CBFifo::Create(int max) +{ + if( m_pBase ) delete m_pBase; + m_pBase = new BOOL[max]; + m_WP = m_RP = m_CNT = 0; + m_MAX = max; +} +//--------------------------------------------------------------------------- +void __fastcall CBFifo::PutFlag(BOOL f) +{ + if( m_CNT < m_MAX ){ + m_pBase[m_WP] = f; + m_WP++; + if( m_WP >= m_MAX ) m_WP = 0; + m_CNT++; + if( m_CNT >= m_MAX ) m_CNT = m_MAX; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CBFifo::GetFlag(void) +{ + if( m_CNT ){ + m_D = m_pBase[m_RP]; + m_RP++; + if( m_RP >= m_MAX ) m_RP = 0; + m_CNT--; + } + return m_D; +} +/*============================================================================= + CPHASEクラス +=============================================================================*/ +__fastcall CPHASE::CPHASE() +{ + m_MFSK_TONES = 16; + m_MFSK_SPEED = 15.625; + m_MFSK_BASEPOINT = int(MFSK_BASEFREQ/15.625); + + m_SampleFreq = 11025.0*0.5; + m_CarrierFreq = 1750; + m_MixerFreq = 0; + SetSampleFreq(m_SampleFreq); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASE::SetMFSKType(int type) +{ + MFSK_SetPara(type, &m_MFSK_TONES, &m_MFSK_SPEED, NULL); + m_MFSK_BASEPOINT = int(MFSK_BASEFREQ/m_MFSK_SPEED); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASE::SetSampleFreq(double f) +{ + m_SampleFreq = f; + Create(); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASE::Create(void) +{ + m_SymbolLen = m_SampleFreq/m_MFSK_SPEED; + m_MixerFreq = double(m_MFSK_BASEPOINT) * m_SampleFreq / m_SymbolLen; + m_VCO.SetSampleFreq(m_SampleFreq); + m_Hilbert.Create(20, m_SampleFreq, 25.0, m_SampleFreq*0.5 - 25.0); + m_Hilbert.Clear(); + SetCarrierFreq(m_CarrierFreq); + m_SlideFFT.Create(int(m_SymbolLen + 0.5), m_MFSK_BASEPOINT, m_MFSK_TONES); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASE::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + m_VCO.SetFreeFreq(m_CarrierFreq - m_MixerFreq); +} +//-------------------------------------------------------------------------- +CLX* __fastcall CPHASE::Do(double d) +{ + m_Hilbert.Do(m_sig, d); // 複素数化 + + CLX z; + z.r = m_VCO.Do(); + z.j = m_VCO.DoCos(); + z *= m_sig; // 周波数変換 + + return m_SlideFFT.Do(z); +} +/*============================================================================= + CDecMFSKクラス +=============================================================================*/ +__fastcall CDecMFSK::CDecMFSK() +{ + m_MFSK_TYPE = typMFSK16; + m_MFSK_TONES = 16; + m_MFSK_SPEED = 15.625; + m_MFSK_BITS = 4; + m_MFSK_BW = m_MFSK_SPEED * (m_MFSK_TONES - 1); + + m_InterLeaver.Init(m_MFSK_BITS); + m_AmpStgPtr = 0; + m_SHDATA = 0; + + m_Metric1 = m_Metric2 = 0; + m_ViterbiPair[0] = m_ViterbiPair[1] = 0; + m_ViterbiPhase = 0; + m_Viterbi1.Init(MFSK_VITERBI_K, MFSK_VITERBI_POLY1, MFSK_VITERBI_POLY2); + m_Viterbi2.Init(MFSK_VITERBI_K, MFSK_VITERBI_POLY1, MFSK_VITERBI_POLY2); + + memset(m_SymStg, 0, sizeof(m_SymStg)); + + m_AvgMetric = 0; + + m_dNow = 0; + + m_Tmg = m_SyncState = 0; + + m_fLSB = FALSE; + m_RxData.Clear(); + + m_fSQ = FALSE; + m_fDelaySQ = FALSE; + m_SQDelayCount = 0; + + m_AvgClock.Create(8); + m_AvgAFC.Create(8); + m_PrevZ = 0; + m_kAFC = 0; + m_AFCWidth = 0; + SetSampleFreq(11025*0.5); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::SetMFSKType(int type) +{ + m_MFSK_TYPE = type; + MFSK_SetPara(type, &m_MFSK_TONES, &m_MFSK_SPEED, &m_MFSK_BITS); + m_MFSK_BW = m_MFSK_SPEED * (m_MFSK_TONES - 1); + m_InterLeaver.Init(m_MFSK_BITS); + SetSampleFreq(m_SampleFreq); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::SetCarrierFreq(double f) +{ + if( sys.m_MFSK_Center ){ + f -= m_MFSK_BW*0.5; + } + else { + if( m_fLSB ) f -= m_MFSK_BW; + } + m_Phase.SetCarrierFreq(f); + m_AvgAFC.Reset(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::Reset(void) +{ + m_SHDATA = 0; + + m_dNow = 0; + m_dTW = m_dBTW = m_SampleFreq / m_MFSK_SPEED; + m_dBTWL = m_dBTW * (1.0-(15000.0 * 1.0e-6)); + m_dBTWH = m_dBTW * (1.0+(15000.0 * 1.0e-6)); + + m_AvgMetric = 0; + memset(m_SymStg, 0, sizeof(m_SymStg)); + + m_AmpStgPtr = 0; + memset(m_AmpStg, 0, sizeof(m_AmpStg)); + + m_Metric1 = m_Metric2 = 0; + m_ViterbiPair[0] = m_ViterbiPair[1] = 0; + m_ViterbiPhase = 0; + + m_Viterbi1.Reset(); + m_Viterbi2.Reset(); + + m_RxData.Clear(); + m_InterLeaver.Reset(); + + m_SyncState = FALSE; + + m_fSQ = FALSE; + m_fDelaySQ = FALSE; + m_SQDelayCount = 0; + ResetMeas(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::SetSampleFreq(double f) +{ + m_SampleFreq = f; + m_dTW = m_dBTW = m_SampleFreq / m_MFSK_SPEED; + m_kAFC = m_MFSK_SPEED / (2.0*PI); + m_AFCWidth = m_MFSK_SPEED * 0.48; + m_AmpStgMax = int(m_dBTW * 2); +#if DEBUG + if( m_AmpStgMax > AMPSTGMAX ) Application->MainForm->Caption = "Over AmpStgSize of MFSK"; +#endif + memset(m_AmpStg, 0, sizeof(m_AmpStg)); +// Application->MainForm->Caption = m_MFSK_TONES; + m_Phase.SetMFSKType(m_MFSK_TYPE); + m_Phase.SetSampleFreq(m_SampleFreq); + Reset(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::ResetMeas(void) +{ + m_AvgClock.Reset(); + m_MeasClock = m_MeasCounter = m_MeasStage = 0; + m_dTW = m_dBTW; +}; +//-------------------------------------------------------------------------- +double __fastcall CDecMFSK::GetFactor(void) +{ +// Application->MainForm->Caption = m_ViterbiPhase; + if( m_ViterbiPhase < 256 ){ + return 0.001; + } + else if( m_MFSK_TONES == 8 ){ + return 0.01625; + } + else { + return 0.03125; + } +} +//-------------------------------------------------------------------------- +// - MFSK8,MFSK31の場合は奇数フェーズと偶数フェーズがあるため、 +// 2つのViterbiのええほうを取る +// - MFSK16は2回に1回Viterbi2を実行する +void __fastcall CDecMFSK::StreamSym(BYTE sym) +{ + int c, metric; + + m_ViterbiPair[0] = m_ViterbiPair[1]; m_ViterbiPair[1] = sym; + m_ViterbiPhase++; + if( m_ViterbiPhase & 1 ){ // MFSK8, MFSK31 + if( m_MFSK_TONES == 16 ) return; + if( (c = m_Viterbi1.Decode(&metric, m_ViterbiPair)) == -1 ) return; + DoAvg(m_Metric1, metric, GetFactor()); + if( m_Metric1 < m_Metric2 ) return; + m_AvgMetric = m_Metric1; +// Application->MainForm->Caption = "Phase odd"; + } + else { // MFSK8, MFSK16, MFSK31 + if( (c = m_Viterbi2.Decode(&metric, m_ViterbiPair)) == -1 ) return; + DoAvg(m_Metric2, metric, GetFactor()); + if( (m_MFSK_TONES != 16) && (m_Metric2 < m_Metric1) ) return; + m_AvgMetric = m_Metric2; +// Application->MainForm->Caption = "Phase even"; + } +// char bf[256]; +// sprintf(bf, "%d", m_ViterbiPhase); +// Application->MainForm->Caption = bf; +// +// S/N Metric +// 30dB 240 +// 20dB 220 +// 10dB 110 +// Application->MainForm->Caption = int(m_AvgMetric); +// + m_SHDATA = m_SHDATA << 1; + if( c ) m_SHDATA |= 1; + + if( (m_SHDATA & 7) == 1 ){ // 001を探す + c = g_VariCode.DecodeMFSK(m_SHDATA >> 1); + if( (c != -1) && (m_fSQ || m_fDelaySQ) ) m_RxData.PutData(c); + m_SHDATA = 1; // 次の文字(1xxx)の先頭 + } +} +//-------------------------------------------------------------------------- +BYTE __fastcall Limit256(double x) +{ + if( x < 0 ) return 0; + if( x > 255 ) return 255; + return BYTE(x); +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::RecSym(const double *pAmp) +{ + int i, n; + BYTE tSym[MFSK_MAXBITS]; + double tVal[MFSK_MAXBITS]; + double *dp; + + memset(tVal, 0, sizeof(tVal)); + double sum = 1e-10; + for(i = 0; i < m_MFSK_TONES; i++){ + if( m_fLSB ){ + n = m_MFSK_TONES - i - 1; + } + else { + n = i; + } + + double v = pAmp[n]; // 二乗振幅 + int gray = (i >> 1) ^ i; // グレーコードに変換 + int mask = m_MFSK_TONES >> 1; + dp = tVal; + for( n = 0; n < m_MFSK_BITS; n++, mask = mask >> 1, dp++ ){ + if( gray & mask ){ + *dp += v; + } + else { + *dp -= v; + } + } + sum += v; + } + sum = 128.0 / sum; + dp = tVal; + BYTE *bp = tSym; + for(i = 0; i < m_MFSK_BITS; i++){ + *bp++ = Limit256(128.0 + (sum * *dp++)); + } + m_InterLeaver.DecodeSyms(tSym); + bp = tSym; + for(i = 0; i < m_MFSK_BITS; i++) StreamSym(*bp++); +} + +//-------------------------------------------------------------------------- +BYTE __fastcall CDecMFSK::DecodeSym(CLX *pFFT, double *pAmp) +{ + int sym = 0; + double d; + double max = 0.0; + + for( int i = 0; i < m_MFSK_TONES; i++ ){ + *pAmp++ = d = pFFT[i].vAbs(); + if( d > max ){ + max = d; + sym = i; + } + } + return BYTE(sym); +} + +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::DoSync(void) +{ +/* + 1つ前のシンボルの最大振幅位置を得る + + m_dBTW = 7, m_AmpStgMax = 14 + v = m_AmpStgPtr + 22220001111111 = m_AmpStg[] + <--i<--------- i = 0 to 13 + 3210dcba987654 + N +*/ + int N = 0; + double max = 0.0; + double *pAmp = &m_AmpStg[m_AmpStgPtr][m_SymStg[1]]; + for(int i = 0; i < m_AmpStgMax; i++){ + if( pAmp < m_AmpStg[0] ){ + pAmp = &m_AmpStg[m_AmpStgMax-1][m_SymStg[1]]; + } + if( *pAmp > max){ + N = i; + max = *pAmp; + } + pAmp -= MFSK_MAXTONES; + } + // カウンタを補正する + m_dNow += (N - m_dTW) * 0.125; + + // タイミング計測の開始 + if( m_MeasStage < 16 ){ + m_MeasStage++; + m_MeasClock = m_MeasCounter = 0; + m_SyncState = FALSE; + } + else { + m_SyncState = (fabs(m_dNow) < (m_dTW * 0.05)); + } +// char bf[256]; +// sprintf(bf, "%.1lf", m_dNow); +// Application->MainForm->Caption = bf; +} + +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::DoMeas(void) +{ + if( m_MeasStage ){ + m_MeasClock++; + if( m_MeasClock >= 128 ){ + m_AvgClock.Do(double(m_MeasCounter)/double(m_MeasClock)); + m_MeasClock = m_MeasCounter = 0; + + // ATC処理 + if( IsMetSQ() ){ + DoAvg(m_dTW, m_AvgClock.GetAvg(), (m_AvgMetric >= 200) ? 0.8 : 0.4); + if( m_dTW < m_dBTWL ){ m_dTW = m_dBTWL; } + if( m_dTW > m_dBTWH ){ m_dTW = m_dBTWH; } + } + else { + DoAvg(m_dTW, m_dBTW, 0.25); + } + } + } +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::DoAFC(CLX *pFFT) +{ + // 3シンボル連続で同じ周波数 + if( (m_SymStg[2] != m_SymStg[1]) || (m_SymStg[2] != m_SymStg[0]) ) return; + // ベーストーンのみを検出する + if( m_fLSB ){ + if( m_SymStg[2] != (m_MFSK_TONES - 1) ) return; + } + else { + if( m_SymStg[2] != 0 ) return; + } + + int err = GetClockError(); + if( ABS(err) >= 2000 ) return; // ATC補正が大きい時は誤差も大きい + + CLX z; + pFFT += m_SymStg[2]; + pFFT->PhDiff(z, m_PrevZ); // 位相差のみ必要なので分母の計算は不要 + double ferr = z.Phase() * m_kAFC; // 位相差を周波数偏差に変換 + if( (ferr > -m_AFCWidth) && (ferr < m_AFCWidth) ){ + m_AvgAFC.DoZ(ferr); + } + +#if 0 + double d = pFFT->Phase() - m_PrevZ.Phase(); + d += fmod(2*PI*(m_dBTW-m_dTW), 2*PI); + if( d >= PI ){d = d - PI*2;} else if( d <= -PI ){d = d + PI*2;} + d *= m_kAFC; + char bf[256]; + sprintf(bf, "%.2lf %.2lf %.2lf", d, ferr, m_dBTW-m_dTW); + Application->MainForm->Caption = bf; +#endif +} +//-------------------------------------------------------------------------- +BOOL __fastcall CDecMFSK::GetAFCShift(double &fq) +{ + if( m_AvgAFC.IsFull() ){ + fq = m_AvgAFC.GetAvg(); + m_AvgAFC.Reset(); + return TRUE; + } + else { + return FALSE; + } +} +//-------------------------------------------------------------------------- +#define DEBUG_MFSK FALSE +#if DEBUG_MFSK +FILE *pMFSKFP = fopen("test.txt", "wt"); +#endif +//-------------------------------------------------------------------------- +int __fastcall CDecMFSK::Do(CLX *pFFT, BOOL fSQ) +{ + BOOL f = FALSE; + + if( m_AmpStgPtr >= m_AmpStgMax ) m_AmpStgPtr = 0; + m_SymStg[2] = DecodeSym(pFFT, m_AmpStg[m_AmpStgPtr]); + + m_MeasCounter++; + m_dNow += 1.0; + if( m_dNow >= m_dTW ){ + m_dNow -= m_dTW; + m_Tmg = !m_Tmg; + if( fSQ ) DoMeas(); + +#if DEBUG_MFSK + if( fSQ ) fprintf(pMFSKFP, "%02X\n", m_SymStg[2]); +#endif + + // 遅延スケルチ処理 + if( m_fSQ != fSQ ){ + m_fSQ = fSQ; + if( !sys.m_MFSK_SQ_Metric ){ + m_SQDelayCount = 32; + } + ResetMeas(); + } + else if( m_SQDelayCount ){ + m_SQDelayCount--; + if( !m_SQDelayCount ){ + m_fDelaySQ = m_fSQ; + } + } + RecSym(m_AmpStg[m_AmpStgPtr]); + // シンボルが2回連続で変化した場合のみ同期位置を計算 + if( (m_SymStg[2] != m_SymStg[1]) && (m_SymStg[0] != m_SymStg[1]) ){ + DoSync(); + } + if( fSQ ) DoAFC(pFFT); + m_PrevZ = pFFT[m_SymStg[2]]; + memcpy(m_SymStg, &m_SymStg[1], 2 * sizeof(m_SymStg[0])); + f = TRUE; + } + m_AmpStgPtr++; + return f; +} + +//-------------------------------------------------------------------------- +int __fastcall CDecMFSK::GetData(void) +{ + if( m_RxData.GetCount() ){ + return m_RxData.GetData(); + } + else { + return -1; + } +} +//-------------------------------------------------------------------------- +int __fastcall CDecMFSK::GetClockError(void) +{ + if( m_AvgClock.GetCount() ){ +// double tw = (m_MeasStage >= 2) ? m_dTW : m_AvgClock.GetAvg(); + return ((m_dTW / m_dBTW) - 1.0) * 1e6; + } + else { + return 0; + } +} +//-------------------------------------------------------------------------- +void __fastcall CDecMFSK::SetTmg(int ppm) +{ + if( ppm < -15000 ) ppm = -15000; + if( ppm > 15000 ) ppm = 15000; + + m_dBTW = m_SampleFreq / m_MFSK_SPEED; + m_dTW = m_dBTW = m_dBTW + (m_dBTW * ppm * 1.0e-6); +} +//-------------------------------------------------------------------------- +// 0 to 2048 +int __fastcall CDecMFSK::GetMetric(int sw) +{ + double d; + switch(sw){ + case 1: + d = m_Metric2; + break; + case 2: + d = m_Metric1; + break; + default: + d = m_AvgMetric; + break; + } + if( d < 80.0 ){ + d = (d - 80.0) * 2.0 + 80.0; + if( d < 0.0 ) d = 0.0; + } + else if( d >= 200.0 ){ + d = 200.0 + (d - 200.0) * ((512.0-200.0) / (256.0-200.0)); + } + return int(d*4.0); +} +/*============================================================================= + CPlayBackクラス +=============================================================================*/ +__fastcall CPlayBack::CPlayBack() +{ + m_StgWidth = 0; + m_StgMax = 0; + m_pStg = NULL; + Clear(); +} +//-------------------------------------------------------------------------- +__fastcall CPlayBack::~CPlayBack() +{ + if( m_pStg ) delete m_pStg; +} +//-------------------------------------------------------------------------- +void __fastcall CPlayBack::Delete(void) +{ + m_StgMax = 0; + m_StgWidth = 0; + if( m_pStg ){ + delete m_pStg; + m_pStg = NULL; + } +} +//-------------------------------------------------------------------------- +void __fastcall CPlayBack::Init(int wSize, int SampBase) +{ + m_StgWidth = wSize; + m_StgMax = (SampBase * 60.0 / wSize) + 0.5; + int wmax = m_StgMax * wSize; + if( m_pStg ) delete m_pStg; + m_pStg = new short[wmax]; + Clear(); +} +//-------------------------------------------------------------------------- +void __fastcall CPlayBack::Clear(void) +{ + m_StgCnt = m_StgRCnt = 0; + m_StgW = m_StgR = 0; + m_WTimer = 0; +} +//-------------------------------------------------------------------------- +void __fastcall CPlayBack::Write(const short *p) +{ + if( m_StgRCnt ) return; + if( m_WTimer ){ + m_WTimer--; + return; + } + memcpy(&m_pStg[m_StgW*m_StgWidth], p, sizeof(short)*m_StgWidth); + m_StgW++; + if( m_StgW >= m_StgMax ) m_StgW = 0; + if( m_StgCnt < m_StgMax ) m_StgCnt++; +} +//-------------------------------------------------------------------------- +BOOL __fastcall CPlayBack::Read(short *p) +{ + if( !m_StgRCnt ) return FALSE; + + memcpy(p, &m_pStg[m_StgR*m_StgWidth], sizeof(WORD)*m_StgWidth); + m_StgR++; + if( m_StgR >= m_StgMax ) m_StgR = 0; + m_StgRCnt--; + return TRUE; +} +//-------------------------------------------------------------------------- +void __fastcall CPlayBack::StopPlaying(void) +{ + m_StgRCnt = 0; +} +//-------------------------------------------------------------------------- +BOOL __fastcall CPlayBack::StartPlaying(int s) +{ + if( !m_StgCnt ) return FALSE; + + m_WTimer = m_StgMax * 3 / 60; + m_StgRCnt = m_StgMax * s / 60; + if( m_StgRCnt > m_StgCnt ) m_StgRCnt = m_StgCnt; + m_StgR = m_StgW - m_StgRCnt; + if(m_StgR < 0) m_StgR += m_StgMax; + return m_StgRCnt; +} + +/*============================================================================= + CDelayクラス +=============================================================================*/ +//--------------------------------------------------------------------------- +__fastcall CDelay::CDelay(void) +{ + m_pStg = NULL; + m_Delay = 0; + m_CurPnt = 0; + m_Count = 0; +} +//--------------------------------------------------------------------------- +__fastcall CDelay::~CDelay() +{ + if( m_pStg ) delete m_pStg; +} +//--------------------------------------------------------------------------- +void __fastcall CDelay::Create(int delay) +{ + if( !m_pStg || (m_Delay != delay) ){ + if( m_pStg ) delete m_pStg; + m_pStg = new double[delay]; + } + m_Delay = delay; + Reset(); +} +//--------------------------------------------------------------------------- +void __fastcall CDelay::Reset(void) +{ + memset(m_pStg, 0, sizeof(double)*m_Delay); + m_CurPnt = 0; + m_Count = 0; +} +//--------------------------------------------------------------------------- +double __fastcall CDelay::Do(const double &d) +{ + double *cp = &m_pStg[m_CurPnt]; + double r = *cp; + *cp = d; + m_CurPnt = CIRCULATE(m_CurPnt+1, m_Delay); + if( m_Count < m_Delay ) m_Count++; + return r; +} +//--------------------------------------------------------------------------- +double __fastcall CDelay::GetData(void) +{ + return m_pStg[m_CurPnt]; +} +/*============================================================================= + CCICクラス +=============================================================================*/ +//--------------------------------------------------------------------------- +__fastcall CCIC::CCIC(void) +{ + m_N = 0; + m_K = 0; +} + +//--------------------------------------------------------------------------- +void __fastcall CCIC::Create(int n) +{ + m_N = n; + m_K = 1.0 / double(n); + + m_Com.Create(n); + m_Z = 0; +} + +//--------------------------------------------------------------------------- +double __fastcall CCIC::Do(double d) +{ + d -= m_Com.Do(d); + d += m_Z; + m_Z = d; + return d * m_K; +} +/*============================================================================= + CCICMクラス +=============================================================================*/ +//--------------------------------------------------------------------------- +__fastcall CCICM::CCICM(void) +{ + m_N = 0; +} +//--------------------------------------------------------------------------- +__fastcall CCICM::~CCICM(void) +{ +} +//--------------------------------------------------------------------------- +void __fastcall CCICM::Create(int stages, int N) +{ + m_N = stages; + for( int i = 0; i < stages; i++ ){ + m_tCIC[i].Create(N); + } + +} +//--------------------------------------------------------------------------- +double __fastcall CCICM::Do(double d) +{ + CCIC *cp = m_tCIC; + for( int i = 0; i < m_N; i++, cp++ ){ + d = cp->Do(d); + } + return d; +} +/*============================================================================= + CNotchesクラス +=============================================================================*/ +//--------------------------------------------------------------------------- +__fastcall CNotches::CNotches(void) +{ + m_nBaseTaps = 128; + m_NotchWidth = 1; + m_Count = m_Max = 0; + m_pBase = NULL; + m_SampleFreq = SAMPFREQ; +} +//--------------------------------------------------------------------------- +__fastcall CNotches::~CNotches() +{ + Delete(); +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::Delete(void) +{ + if( m_pBase ){ + delete m_pBase; + m_pBase = NULL; + } + m_Count = m_Max = 0; + m_FIR.Delete(); +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::Create(void) +{ + if( m_Count ){ + if( m_Count == 1 ){ // シングルノッチ + m_nTaps = m_nBaseTaps * m_SampleFreq / 11025; + m_nTaps = (m_nTaps + 1) & 0x0ffe; + if( m_nTaps < 4 ) m_nTaps = 4; + double fl = m_pBase[0].Freq - m_NotchWidth; + double fh = m_pBase[0].Freq + m_NotchWidth; + int att = m_NotchWidth > 50 ? 60 : 10; + if( fl < 100.0 ){ + m_FIR.Create(m_nTaps, ffHPF, m_SampleFreq, fh, fh, 60, 1.0); + } + else if( (fh > sys.m_MaxCarrier) && (m_NotchWidth >= 10) ){ + m_FIR.Create(m_nTaps, ffLPF, m_SampleFreq, fl, fl, 60, 1.0); + } + else { + m_FIR.Create(m_nTaps, ffBEF, m_SampleFreq, fl, fh, att, 1.0); + } + } + else { // マルチノッチ + m_nTaps = m_nBaseTaps * 1.5 * m_SampleFreq / 11025; + m_nTaps = (m_nTaps + 1) & 0x0ffe; + if( m_nTaps < 4 ) m_nTaps = 4; + int e = m_nTaps / 2; + double *pSamp = new double[e]; + double w = m_SampleFreq / m_nTaps; + if( w > 30.0 ) w = 30.0; + double bw = m_NotchWidth; + if( bw < w ) bw = w; + for( int i = 0; i < e; i++ ){ + double fq = i * m_SampleFreq / m_nTaps; + double gm = 1.0; + for( int j = 0; j < m_Count; j++ ){ + double g = fq - m_pBase[j].Freq; + g = fabs(g); + g = g * 0.5 / bw; + g *= g; + if( g < gm ) gm = g; + } + pSamp[i] = gm; + } + m_FIR.CreateSamp(m_nTaps, m_SampleFreq, pSamp); + delete pSamp; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::Alloc(int nIndex) +{ + if( nIndex >= m_Max ){ + int max = m_Max ? m_Max * 2 : 32; + NOTCHCTR *pNew = new NOTCHCTR[max]; + if( m_Count ) memcpy(pNew, m_pBase, m_Count * sizeof(NOTCHCTR)); + if( m_pBase ) delete m_pBase; + m_pBase = pNew; + m_Max = max; + } +} +//--------------------------------------------------------------------------- +int __fastcall CNotches::Find(int Freq) +{ + for( int i = 0; i < m_Count; i++ ){ + if( m_pBase[i].Freq == Freq ) return i; + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::Add(int Freq) +{ + if( Find(Freq) >= 0 ) return; + + Alloc(m_Count); + m_pBase[m_Count].Freq = short(Freq); + m_pBase[m_Count].m_MX = 0; + m_pBase[m_Count].m_MY = 0; + m_Count++; + Create(); +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::SetFreq(int nIndex, int Freq) +{ + if( nIndex < m_Count ){ + if( m_pBase[nIndex].Freq != Freq ){ + m_pBase[nIndex].Freq = Freq; + Create(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CNotches::Delete(int nIndex) +{ + if( (nIndex < 0) || (nIndex >= m_Count) ) return; + + NOTCHCTR *np = &m_pBase[nIndex]; + int size = sizeof(NOTCHCTR)*(m_Count-nIndex-1); + if( size > 0 ) memcpy(np, np+1, size); + m_Count--; + if( m_Count ){ + Create(); + } + else { + Delete(); + } +} +/*============================================================================= + CPHASEXクラス Added by JE3HHT on Sep.2010 for FFT RTTY demodulator +=============================================================================*/ +__fastcall CPHASEX::CPHASEX() +{ + m_TONES = 4; + m_SHIFT = 170.0; + m_SampleFreq = 11025.0*0.5; + m_CarrierFreq = 1750; + SetSampleFreq(m_SampleFreq); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::ShowPara(void) +{ +/* + if( Application->MainForm ){ + char bf[256]; + sprintf(bf, "Car=%.lf, Shift=%.lf, Syms=%.lf, Tones=%d", m_CarrierFreq, m_SHIFT, m_SymbolLen, m_TONES); + Application->MainForm->Caption = bf; + } +*/ +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::SetSampleFreq(double f) +{ + m_SampleFreq = f; + Create(); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::Create(void) +{ +// m_fftSHIFT = m_SHIFT * (m_TONES + 1) / m_TONES; + m_fftSHIFT = m_SHIFT * m_TONES / (m_TONES - 1); + m_SymbolLen = m_TONES * m_SampleFreq / m_fftSHIFT; + m_BASEPOINT = int(CPHASEX_BASEFREQ * m_TONES / m_fftSHIFT); + + m_MixerFreq = double(m_BASEPOINT) * m_SampleFreq / m_SymbolLen; + m_VCO.SetSampleFreq(m_SampleFreq); + m_Hilbert.Create(20, m_SampleFreq, 25.0, m_SampleFreq*0.5 - 25.0); + m_Hilbert.Clear(); + SetCarrierFreq(m_CarrierFreq); + m_SlideFFT.Create(int(m_SymbolLen + 0.5), m_BASEPOINT, m_TONES); + m_AGC.SetSampleFreq(m_SampleFreq); + m_AGC.SetCarrierFreq(m_CarrierFreq); +// CreateFilter(); +#if LOGFFT + m_fp = fopen("FFT.txt", "wt"); +#endif +// ShowPara(); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::SetShift(double f) +{ + m_SHIFT = f; + Create(); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + m_VCO.SetFreeFreq(m_CarrierFreq - m_MixerFreq); + m_AGC.SetCarrierFreq(m_CarrierFreq); +// ShowPara(); +} +//-------------------------------------------------------------------------- +CLX* __fastcall CPHASEX::Do(double d) +{ + m_Hilbert.Do(m_sig, d); // 複素数化 + + CLX z; + z.r = m_VCO.Do(); + z.j = m_VCO.DoCos(); + z *= m_sig; // 周波数変換 + +// m_LPF.Do(z); + return m_SlideFFT.Do(z); +} +//-------------------------------------------------------------------------- +void __fastcall CPHASEX::DoFSK(double d) +{ +// d = m_AGC.Do(d); + CLX *pFFT = Do(d); + m_dm = pFFT[0].vAbs() * (1.0 / 32768.0); + m_ds = pFFT[m_TONES-1].vAbs() * (1.0 / 32768.0); + +#if LOGFFT + for( int i = 0; i < m_TONES; i++ ){ + if( i ) fprintf(m_fp, ","); + fprintf(m_fp, "%.0lf", pFFT[i].vAbs()); + } + fprintf(m_fp, "\n"); +#endif +} +/*============================================================================= + CViterbiQPSKクラス Added by JE3HHT on Sep.2010 for QPSK demodulator +=============================================================================*/ +CViterbiQPSK::CViterbiQPSK(void) +{ + Reset(); +} +//--------------------------------------------------------------------------- +void __fastcall CViterbiQPSK::Reset(void) +{ + memset(m_tPath, 0, sizeof(m_tPath)); + memset(m_tBit, 0, sizeof(m_tBit)); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CViterbiQPSK::Do(double angle, double *pMetric) +{ + double dist[32]; + int bits[32]; + double min = MAXDOUBLE; + + int i; + if( pMetric ){ + for(i = 0; i < 32; i++){ + dist[i] = m_tPath[i/2] + pMetric[tQPSK_Viterbi[i]]; + if(dist[i] < min) min = dist[i]; + bits[i] = ((m_tBit[i/2]) << 1) + (i & 1); + } + } + else { + const double tt1[4] = {3.0*PI/2.0, 0.0, PI/2.0, PI}; + const double tt2[4] = {3.0*PI/2.0, PI*2.0, PI/2.0, PI}; + const double* pTbl = (angle >= PI) ? tt2 : tt1; + for(i = 0; i < 32; i++){ + dist[i] = m_tPath[i/2] + fabs(angle - pTbl[tQPSK_Viterbi[i]]); + if( dist[i] < min ) min = dist[i]; + bits[i] = ((m_tBit[i/2]) << 1) + (i & 1); + } + } + for(i = 0; i < 16; i++){ + if( dist[i] < dist[i + 16]){ + m_tPath[i] = dist[i] - min; + m_tBit[i] = bits[i]; + } + else { + m_tPath[i] = dist[i + 16] - min; + m_tBit[i] = bits[i + 16]; + } + } + int ones = 0; + for(i = 0; i < 16; i++){ + ones += (m_tBit[i] & (1L << 20)); + } + if( ones == (8 << 20 ) ){ + return rand() & 1; + } + else { + return ones > (8L << 20); + } +} +/*============================================================================= + CDecPSKクラス Added by JE3HHT on Sep.2010 for QPSK demodulator +=============================================================================*/ +__fastcall CDecPSK::CDecPSK(void) +{ + m_fLSB = FALSE; + m_bQPSK = TRUE; + m_bATC = TRUE; + + m_CarrierFreq = 1750.0; + m_Angle = 0.0; + m_Speed = 31.25; + m_SHDATA = 0; + + m_SN = 0; + m_dNow = 0; + + m_Tmg = m_SyncState = 0; + + m_RxData.Clear(); + + m_fSQ = FALSE; + + m_AvgClock.Create(8); + SetSampleFreq(11025*0.5); +} +//--------------------------------------------------------------------------- +__fastcall CDecPSK::~CDecPSK(void) +{ +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::SetCarrierFreq(double f) +{ + m_CarrierFreq = f; + m_NextCarrierFreq = f; + m_VCO.SetFreeFreq(f); + m_dblAvgAFC = 0.0; +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::Reset(void) +{ + m_SHDATA = 0; + m_SN = 0; + + m_dNow = 0; + m_dTW = m_dBTW = m_SampleFreq / m_Speed; + m_dBTWL = m_dBTW * (1.0-(15000.0 * 1.0e-6)); + m_dBTWH = m_dBTW * (1.0+(15000.0 * 1.0e-6)); + m_iW = int(m_dTW / QPSK_SUBFACTOR); + m_iWM = m_iW/2; + + memset(m_AmpStg, 0, sizeof(m_AmpStg)); + + memset(m_StgZ, 0, sizeof(m_StgZ)); + m_Viterbi.Reset(); + + m_RxData.Clear(); + + m_SyncState = FALSE; + + m_fSQ = FALSE; + + int taps = int(m_SampleFreq * 64.0 * 2.0 / 11025.0 + 0.5) & 0x7ffe; + m_LPF1.Create(taps, ffLPF, m_SampleFreq, m_Speed*2.0, m_Speed*2.0, 60.0, 1.0); + taps = int(m_SampleFreq * 8 * 160 / (QPSK_SUBFACTOR * 11025) + 0.5) & 0x7ffe; + m_LPF2.Create(taps, ffLPF, m_SampleFreq/double(QPSK_SUBFACTOR), m_Speed*QPSK_LPF2K, m_Speed*QPSK_LPF2K, 60.0, 1.0); + + m_dblAvgAFC = 0.0; + m_vAvg = 32768.0; + ResetATC(); +} +//-------------------------------------------------------------------------- +// 送信に切り替える際に呼ばれる +void __fastcall CDecPSK::ResetRX(void) +{ + m_dNow = 0; + memset(m_AmpStg, 0, sizeof(m_AmpStg)); + memset(m_StgZ, 0, sizeof(m_StgZ)); + m_dblAvgAFC = 0.0; + m_vAvg = 32768.0; + m_SHDATA = 0; + m_Viterbi.Reset(); + m_RxData.Clear(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::SetSpeed(double d) +{ + m_Speed = d; + Reset(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::SetSampleFreq(double f) +{ + m_SampleFreq = f; + m_dTW = m_dBTW = m_SampleFreq / m_Speed; + m_iW = int(m_dTW / QPSK_SUBFACTOR); + m_iWM = m_iW/2; + memset(m_AmpStg, 0, sizeof(m_AmpStg)); + + m_VCO.SetSampleFreq(m_SampleFreq); + m_Hilbert.Create(20, m_SampleFreq, 25.0, m_SampleFreq*0.5 - 25.0); + m_Hilbert.Clear(); + SetCarrierFreq(m_CarrierFreq); + Reset(); +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::ResetATC(void) +{ + m_AvgClock.Reset(); + m_MeasClock = m_MeasCounter = m_MeasStage = 0; + m_dTW = m_dBTW; + m_iW = int(m_dTW / QPSK_SUBFACTOR); + m_iWM = m_iW/2; + m_SN = 0; +}; +//--------------------------------------------------------------------------- +void __fastcall CDecPSK::RxBit(int bit) +{ + m_SHDATA = m_SHDATA << 1; + if( bit ) m_SHDATA |= 1; + + if( !(m_SHDATA & 3) ){ + if( m_fSQ ) m_RxData.PutData(g_VariCode.Decode(m_SHDATA >> 2)); + m_SHDATA = 0; + } +} +//--------------------------------------------------------------------------- +double __fastcall vPWR(const double &c){ + return c * c; +} +void __fastcall CDecPSK::DoSym(const CLX &z) +{ + m_StgZ[3] = m_StgZ[2]; + m_StgZ[2] = m_StgZ[1]; + m_StgZ[1] = m_StgZ[0]; + m_StgZ[0] = z; + + double max, v; + max = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].j); + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + m_Metric[QPSK_ROT_0] = max; + + max = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].j); + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].r); + if( v > max ) max = v; + m_Metric[QPSK_ROT_180] = max; + + max = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].j); + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + m_Metric[QPSK_ROT_270] = max; + + max = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].j); + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].r) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].j); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r - m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j + m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j - m_StgZ[1].r - m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r + m_StgZ[1].j - m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].r + m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].j - m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j - m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r - m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + v = vPWR(m_StgZ[3].j + m_StgZ[2].j + m_StgZ[1].r + m_StgZ[0].j) + vPWR(m_StgZ[3].r + m_StgZ[2].r - m_StgZ[1].j + m_StgZ[0].r); + if( v > max ) max = v; + m_Metric[QPSK_ROT_90] = max; + + int i; + max = m_Metric[0]; + for( i = 0; i < 4; i++ ){ + if(m_Metric[i] > max) max = m_Metric[i]; + } + if( max > 0.0 ){ + for( i = 0; i < 4; i++ ){ + m_Metric[i] = -log10(m_Metric[i]/max + 1.0E-100); + } + } + + if( m_bQPSK && m_fLSB ){ // 回転方向を逆転 + double d = m_Metric[QPSK_ROT_90]; + m_Metric[QPSK_ROT_90] = m_Metric[QPSK_ROT_270]; + m_Metric[QPSK_ROT_270] = d; + } + + if( m_bQPSK && m_fLSB ){ + m_Angle = PI + ATAN2( (m_StgZ[1].j*m_StgZ[0].j + m_StgZ[1].r*m_StgZ[0].r), (m_StgZ[0].j*m_StgZ[1].r - m_StgZ[1].j*m_StgZ[0].r)); + } + else { + m_Angle = PI + ATAN2( (m_StgZ[1].j*m_StgZ[0].j + m_StgZ[1].r*m_StgZ[0].r), (m_StgZ[1].j*m_StgZ[0].r - m_StgZ[0].j*m_StgZ[1].r)); + } + + m_Bits = m_Viterbi.Do(m_Angle, m_Metric); + RxBit(m_Bits); +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::DoAFC(void) +{ +// if( m_SN < 1500 ) return; + if( m_SN < 1200 ) return; + + double deg = m_Angle; + if( deg < 0.0 ) deg += 2*PI; + + double w; + if( deg < (PI/4) ){ // ROT 0 + w = deg; + } + else if( deg < (PI/4 + PI/2) ){ // ROT 90 + w = deg - PI/2; + } + else if( deg < (PI/4 + PI) ){ // ROT 180 + w = deg - PI; + } + else if( deg < (PI/4 + PI + PI/2) ){ // ROT 270 + w = deg - PI - PI/2; + } + else { // ROT 0 + w = deg - (2*PI); + } + double err = w * m_SampleFreq / (2 * PI * QPSK_SUBFACTOR * m_Speed); + DoAvg(m_dblAvgAFC, err, (m_SN > 2000) ? 0.025 : 0.0125); + if( m_fLSB ){ + m_NextCarrierFreq = m_CarrierFreq - m_dblAvgAFC * 0.25; + } + else { + m_NextCarrierFreq = m_CarrierFreq + m_dblAvgAFC * 0.25; + } +/* + char bf[32]; + sprintf(bf, "SN=%u, %.03lf", m_SN, m_dblAvgAFC); + Application->MainForm->Caption = bf; +*/ +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::DoATC(BOOL fATC) +{ + if( m_MeasStage >= 7 ){ + m_SyncState = TRUE; + m_MeasClock++; + if( m_MeasClock >= 64 ){ + if( m_MeasStage >= 8 ){ + m_AvgClock.Do(double(m_MeasCounter)/double(m_MeasClock)); +/* + char bf[256]; + sprintf(bf, "%.3lf, %.3lf, %.3lf", m_dBTW, double(m_MeasCounter)/double(m_MeasClock), m_AvgClock.GetAvg()); + Application->MainForm->Caption = bf; +*/ + // ATC処理 + if( m_bATC && fATC ){ + DoAvg(m_dTW, m_AvgClock.GetAvg(), m_SN > 2000 ? 0.5 : 0.25); + if( m_dTW < m_dBTWL ){ m_dTW = m_dBTWL; } + if( m_dTW > m_dBTWH ){ m_dTW = m_dBTWH; } + m_iW = int(m_dTW / QPSK_SUBFACTOR); + m_iWM = m_iW/2; + } + } + else { + m_MeasStage++; + } + m_MeasClock = m_MeasCounter = 0; + } + } +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::DoSync(CLX &z) +{ + int N = int(m_dNow / QPSK_SUBFACTOR); + if( N < 0 ) N += m_iW; + if( N >= m_iW ) N -= m_iW; + m_AmpStg[N] = z.vAbs(); + + float psum = 0.0; + float msum = 0.0; + float *p = m_AmpStg; + float *t = p + m_iWM; + for( N = 0; N < m_iWM; N++, p++, t++ ){ + msum += *p - *t; + psum += *p + *t; + } + if( psum > 0.0 ){ + msum /= psum; + m_dNow -= msum * QPSK_SUBFACTOR * 0.2; + } + + // タイミング計測の開始 + if( m_MeasStage < 7 ){ + m_MeasStage++; + m_SyncState = FALSE; + } +} +//--------------------------------------------------------------------------- +int __fastcall CDecPSK::Do(double d, BOOL fSQ, BOOL fATC) +{ + m_Hilbert.Do(m_sig, d); // 複素数化 + + CLX z; + z.r = m_VCO.Do(); + z.j = m_VCO.DoCos(); + z *= m_sig; // 周波数変換 + + m_LPF1.Do(z); // デシメータ + + m_MeasCounter++; + m_nSubCounter--; + if( m_nSubCounter <= 0 ){ // サブサンプリング + m_nSubCounter = QPSK_SUBFACTOR; + + m_LPF2.Do(z); + m_Z = z; + + if( fSQ ) DoSync(z); + + m_dNow += QPSK_SUBFACTOR; + if( m_dNow >= m_dTW ){ + m_dNow -= m_dTW; + m_Tmg = !m_Tmg; + + if( m_fSQ != fSQ ){ + m_fSQ = fSQ; + m_dblAvgAFC = 0.0; + ResetATC(); + } + DoSym(z); + if( fSQ ){ + DoATC(fATC); + DoAFC(); + } + return TRUE; + } + } + return FALSE; +} +//-------------------------------------------------------------------------- +int __fastcall CDecPSK::GetData(void) +{ + if( m_RxData.GetCount() ){ + return m_RxData.GetData(); + } + else { + return -1; + } +} +//-------------------------------------------------------------------------- +int __fastcall CDecPSK::GetClockError(void) +{ + if( m_AvgClock.GetCount() ){ + return ((m_dTW / m_dBTW) - 1.0) * 1e6; + } + else { + return 0; + } +} +//-------------------------------------------------------------------------- +void __fastcall CDecPSK::SetTmg(int ppm) +{ + if( ppm < -15000 ) ppm = -15000; + if( ppm > 15000 ) ppm = 15000; + + m_dBTW = m_SampleFreq / m_Speed; + m_dTW = m_dBTW = m_dBTW + (m_dBTW * ppm * 1.0e-6); + m_iW = int(m_dTW / QPSK_SUBFACTOR); + m_iWM = m_iW / 2; +} +//-------------------------------------------------------------------------- +int __fastcall CDecPSK::GetD(void) +{ + double d = m_Z.vAbs(); + DoAvg(m_vAvg, d, 0.001); + if( m_vAvg > 0.0 ){ + d /= m_vAvg; + d *= 20000.0; + } + if( d > 40000.0 ) d = 40000.0; + return d - 20000.0; +} + +//-------------------------------------------------------------------------- + + diff --git a/DSP.h b/DSP.h new file mode 100644 index 0000000..9f014c5 --- /dev/null +++ b/DSP.h @@ -0,0 +1,1626 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef DSPH +#define DSPH +#include +#include + +#define DECFIR FALSE + +#include "ComLib.h" +#include "mfsk.h" +//--------------------------------------------------------------------------- +extern int SAMPBASE; +extern int SAMPTYPE; +extern double SAMPFREQ; +extern double DEMSAMPFREQ; +extern double SAMPTXOFFSET; +extern int g_tBpfTaps[]; +extern const DWORD _tBitData[]; + +inline double ATAN2(double x, double y){ + return y ? atan2(x, y) : 0.0; +} +void __fastcall DoAvg(double &av, double in, double factor); + +enum { + MODE_GMSK, + MODE_FSK, + MODE_FSKW, + MODE_BPSK, + MODE_N_BPSK, + MODE_RTTY, + MODE_U_RTTY, + MODE_mfsk_L, + MODE_mfsk_U, + MODE_qpsk_L, + MODE_qpsk_U, + MODE_END, +}; +//--------------------------------------------------------------------------- +BOOL __fastcall IsRTTY(int m); +BOOL __fastcall Is170(int m); +BOOL __fastcall IsBPSK(int m); +BOOL __fastcall IsFSK(int m); +BOOL __fastcall IsMFSK(int m); +BOOL __fastcall IsQPSK(int m); +BOOL __fastcall IsPSK(int m); +#define MIN_SAMP 5000 +#define MAX_SAMP 51000 +//--------------------------------------------------------------------------- +#define CARRIERFREQ 1750 +#define SPEED 31.25 +#define MIN_SPEED 15 +#define MAX_SPEED 300 +//--------------------------------------------------------------------------- +#define PSK_OUTFAC 0.70710678118654752440084436210485 +//--------------------------------------------------------------------------- +#define MIN_CARRIER 250 +//#define MAX_CARRIER 2700 +//--------------------------------------------------------------------------- +#define PI 3.1415926535897932384626433832795 +#define MULI 0.000030517578125 +#define ABS(c) (((c)<0)?(-(c)):(c)) +#define CIRCULATE(A,B) ((A)%(B)) +//-------------------------------------------------------------------------- +inline double __fastcall Limit(double x, double min, double max) +{ + if( x < min ) return min; + if( x > max ) return max; + return x; +} +//--------------------------------------------------------------------------- +#define FIFOMAX 256 +class CFifo +{ +private: + int m_rc; + int m_wc; + int m_cc; + int m_bf[FIFOMAX]; + int m_BusyLimit; + +public: + CFifo(void){ + m_cc = m_rc = m_wc = 0; + m_BusyLimit = FIFOMAX / 2; + }; + void __fastcall Clear(void){ + m_cc = m_rc = m_wc = 0; + }; + void __fastcall PutData(int c){ + m_bf[m_wc] = c; + m_wc++; + if( m_wc >= FIFOMAX ) m_wc = 0; + m_cc++; + }; + int __fastcall GetData(void){ + int c = m_bf[m_rc]; + m_rc++; + if( m_rc >= FIFOMAX ) m_rc = 0; + m_cc--; + return c; + }; + int __fastcall GetCount(void){ + return m_cc; + } + int __fastcall IsBusy(void){ + return (m_cc < m_BusyLimit) ? FALSE : TRUE; + } +}; +//--------------------------------------------------------------------------- +#define TAPMAX 512 +enum { + ffLPF, + ffHPF, + ffBPF, + ffBEF, + ffGAUSSIAN, +}; +typedef struct { + int n; + int typ; + double fs; + double fcl; + double fch; + double att; + double gain; + double fc; + double hp[TAPMAX+1]; /* 係数配列 */ +}FIR; +//--------------------------------------------------------------------------- +class CSinTable +{ +public: + double *m_tSin; + int m_Size; +public: + __fastcall CSinTable(); + __fastcall ~CSinTable(); +}; +//--------------------------------------------------------------------------- +class CVARICODE +{ +public: + int m_TMax; + int m_Max; + DWORD *m_tEncode; + BYTE m_tIndex2Mbcs[128]; +public: + UINT __fastcall Index2Mbcs(int index, BOOL fJA); + int __fastcall Mbcs2Index(UINT mbcs, BOOL fJA); + +public: + __fastcall CVARICODE(); + __fastcall ~CVARICODE(); + void __fastcall Init(void); + void __fastcall Create(int max); + DWORD __fastcall Encode(int &n, DWORD d); + int __fastcall Decode(DWORD d); + + void __fastcall SaveTable(LPCSTR pName); + void __fastcall SaveSource(LPCSTR pName); + void __fastcall SaveBin(LPCSTR pName); + BOOL __fastcall LoadBin(LPCSTR pName); + + int __fastcall DecodeMFSK(DWORD d); + int __fastcall EncodeMFSK(BYTE c); +}; +//--------------------------------------------------------------------------- +class CBAUDOT +{ +private: + int m_OutFig; + int m_CodeB4; +private: + int __fastcall GetOneCode(int &fig, int code); + int __fastcall DblCode(int code); + +public: + __fastcall CBAUDOT(); + __fastcall ~CBAUDOT(); + + int __fastcall GetCode(int &count, int code); + inline void __fastcall Reset(void){m_OutFig = -1; m_CodeB4 = 0;}; +}; +//--------------------------------------------------------------------------- +#pragma option -a- // パックの指示 +typedef struct { + BYTE Code; + BYTE Fig; +}BCODETBL; +#pragma option -a. // パック解除の指示 + +class CRTTY +{ +private: + int m_outfig; + BCODETBL m_TBL[24*4]; + +public: + int m_CodeSet; + int m_fig; + int m_uos; + + int m_txuos; + CRTTY(); + char ConvAscii(int d); + int ConvRTTY(char d); + int ConvRTTY(BYTE *t, LPCSTR p); + inline int IsChar(int d){ + d &= 0x000000ff; + if( !d ) return 0; + if( d == 0x000000ff ) return 0; + return 1; + }; + inline void ClearTX(void){m_outfig = 3;}; + inline void ClearRX(void){m_fig = 0;}; + + int GetShift(char d); + char InvShift(char c); + void SetCodeSet(void); +}; + +//--------------------------------------------------------------------------- +class CBFifo +{ +private: + int m_WP; + int m_RP; + int m_CNT; + int m_MAX; + BOOL *m_pBase; + BOOL m_D; +public: + __fastcall CBFifo(); + __fastcall ~CBFifo(); + + void __fastcall Create(int max); + void __fastcall PutFlag(BOOL f); + BOOL __fastcall GetFlag(void); +}; + + +//--------------------------------------------------------------------------- +class CVCO +{ +private: + double m_c1; // VCOの利得 + double m_c2; // フリーランニング周波数 + double m_z; + + double m_FreeFreq; + double m_SampleFreq; + int m_TableSize; + double m_TableCOS; +public: + __fastcall CVCO(); + __fastcall ~CVCO(); + void __fastcall InitPhase(void); + void __fastcall SetGain(double gain); + void __fastcall SetSampleFreq(double f); + void __fastcall SetFreeFreq(double f); + double __fastcall Do(void); + double __fastcall Do(double d); + double __fastcall DoCos(void); +}; + +//--------------------------------------------------------------------------- +#define IIRMAX 16 +#define IIRVLIMIT (1.0e-37) +class CIIR +{ +public: + double m_rp; + double m_A[IIRMAX*2]; + double m_B[IIRMAX*3]; + int m_order; + int m_bc; +private: + double m_Z[IIRMAX*3]; + int m_orderH; +public: + __fastcall CIIR(); + __fastcall ~CIIR(); + void __fastcall Create(int type, double fc, double fs, int order, int bc, double rp); + double __fastcall Do(double d); + void __fastcall Clear(void); +}; + +//--------------------------------------------------------------------------- +class CIIRTANK +{ +private: + double z1, z2; +public: + double a0; + double b1, b2; + + double m_Freq; + double m_BW; + double m_SampleFreq; +private: + void __fastcall SetFreq(double f, double smp, double bw); +public: + __fastcall CIIRTANK(); + inline void __fastcall SetSampleFreq(double f){m_SampleFreq = f; Create();}; + inline void __fastcall SetFreq(double f){m_Freq = f; Create();}; + void __fastcall Create(void); + double __fastcall Do(double d); +}; + +class CIIRTANK2 +{ +public: + double m_Freq; + double m_BW; + double m_SampleFreq; +private: + CIIRTANK m_Tank1; + CIIRTANK m_Tank2; + +public: + __fastcall CIIRTANK2(); + void __fastcall SetSampleFreq(double f); + void __fastcall Create(void); + double __fastcall Do(double d); + inline CIIRTANK *__fastcall GetTank1(void){return &m_Tank1;}; +}; +//--------------------------------------------------------------------------- +class CFIR +{ +private: + int m_Tap; + double *m_pZ; + double *m_pH; +public: + __fastcall CFIR(); + __fastcall ~CFIR(); + void __fastcall Create(int tap, int type, double fs, double fcl, double fch, double att, double gain); + double __fastcall Do(double d); + void __fastcall SaveCoef(LPCSTR pName); + inline double __fastcall GetHD(int n){return m_pH[n];}; + inline double *__fastcall GetHP(void){return m_pH;}; + inline int __fastcall GetTap(void){return m_Tap;}; +}; + +//--------------------------------------------------------------------------- +// ダブルバッファによるFIRフィルタ +class CFIR2 +{ +private: + int m_Tap; + int m_TapHalf; + double *m_pZ; + double *m_pH; + double *m_pZP; + + int m_W; + double m_fs; +public: + __fastcall CFIR2(); + __fastcall ~CFIR2(); + void __fastcall Delete(void); + void __fastcall Clear(void); + void __fastcall Create(int tap, int type, double fs, double fcl, double fch, double att, double gain); + void __fastcall Create(int tap, double fs, double fcl, double fch); + void __fastcall CreateSamp(int tap, double fs, const double *pSmpFQ); + double __fastcall Do(double d); + double __fastcall Do(double *hp); + void __fastcall Do(CLX &z, double d); + + inline double __fastcall GetHD(int n){return m_pH[n];}; + inline double *__fastcall GetHP(void){return m_pH;}; + inline int __fastcall GetTap(void){return m_Tap;}; + inline double __fastcall GetSampleFreq(void){return m_fs;}; +}; +//--------------------------------------------------------------------------- +// ダブルバッファによるFIRフィルタ(複素数用) +class CFIRX +{ +private: + int m_Tap; + int m_TapHalf; + CLX *m_pZ; + double *m_pH; + CLX *m_pZP; + + int m_W; + double m_fs; +public: + __fastcall CFIRX(); + __fastcall ~CFIRX(); + void __fastcall Clear(void); + void __fastcall Create(int tap, int type, double fs, double fcl, double fch, double att, double gain); + void __fastcall CreateSamp(int tap, double fs, const double *pSmpFQ, int wDB); + void __fastcall Do(CLX &d); + + inline double __fastcall GetHD(int n){return m_pH[n];}; + inline double *__fastcall GetHP(void){return m_pH;}; + inline int __fastcall GetTap(void){return m_Tap;}; + inline double __fastcall GetSampleFreq(void){return m_fs;}; +}; +//--------------------------------------------------------------------------- +// Copy from MMTTY by JE3HHT on Sep.2010 +class CSmooz{ +private: + double *bp; + int Wp; + int Max; + int Cnt; + void __fastcall IncWp(void){ + Wp++; + if( Wp >= Max ) Wp = 0; + }; + double __fastcall Avg(void){ + double d = 0.0; + int i; + for( i = 0; i < Cnt; i++ ){ + d += bp[i]; + } + if( Cnt ){ + return d/double(Cnt); + } + else { + return 0; + } + }; +public: + __fastcall CSmooz(int max = 70){ + Max = max; + bp = new double[max]; + Cnt = 0; + Wp = 0; + }; + __fastcall ~CSmooz(void){ + delete bp; + }; + void __fastcall SetCount(int n){ + double *np = new double[n]; + Max = n; + Cnt = Wp = 0; + double *op = bp; + bp = np; + delete op; + }; + double __fastcall Avg(double d){ + bp[Wp] = d; + IncWp(); + if( Cnt < Max ){ + Cnt++; + } + return Avg(); + }; +}; +//--------------------------------------------------------------------------- +// スライディングFFT +class CSlideFFT +{ +private: + int m_Length; + int m_Base; + int m_Tones; + + CLX m_tData[MFSK_MAXTONES]; + CLX m_tWindow[MFSK_MAXTONES]; + + CLX *m_pCur; + CLX *m_pEnd; + CLX *m_pBase; + + double m_kWindow; +private: +public: + __fastcall CSlideFFT(); + __fastcall ~CSlideFFT(); + + void __fastcall Create(int len, int base, int tones); + CLX* __fastcall Do(const CLX &zIn); +}; +//--------------------------------------------------------------------------- +// 遅延器 +class CDelay +{ +private: + int m_Delay; + int m_CurPnt; + int m_Count; + double *m_pStg; + +public: + __fastcall CDelay(void); + __fastcall ~CDelay(); + + void __fastcall Create(int delay); + void __fastcall Reset(void); + double __fastcall Do(const double &d); + double __fastcall GetData(void); + inline BOOL __fastcall IsFull(void){return m_Count >= m_Delay;}; +}; +//--------------------------------------------------------------------------- +// CICフィルタ +class CCIC +{ +private: + int m_N; + double m_K; + CDelay m_Com; + double m_Z; +public: + __fastcall CCIC(void); + + void __fastcall Create(int n); + double __fastcall Do(double d); +}; +//--------------------------------------------------------------------------- +// 高次のCICフィルタ +class CCICM +{ +private: + int m_N; + CCIC m_tCIC[16]; +public: + __fastcall CCICM(void); + __fastcall ~CCICM(); + + void __fastcall Create(int stages, int N); + double __fastcall Do(double d); +}; +//--------------------------------------------------------------------------- +class CFAVG +{ +private: + double m_Sum; + double m_Avg; + double m_Mul; + int m_Max; + int m_Cnt; +public: + __fastcall CFAVG(); + void __fastcall Reset(void); + void __fastcall Reset(double d); + void __fastcall Create(int max); + double __fastcall DoZ(double d); + double __fastcall Do(double d); + inline double __fastcall GetAvg(void){return m_Avg;}; + inline BOOL __fastcall IsFull(void){return m_Max == m_Cnt;}; + inline BOOL __fastcall IsHalf(void){return m_Max <= (m_Cnt*2);}; + inline int __fastcall GetCount(void){return m_Cnt;}; +}; +//--------------------------------------------------------------------------- +class CAMPCONT +{ +private: + double m_Max; + double m_Cnt; + double m_ADD; + int m_S; + int m_iMax; +public: + __fastcall CAMPCONT(); + void __fastcall SetMax(int max); + void __fastcall Reset(void); + double __fastcall Do(int d); +}; +//--------------------------------------------------------------------------- +class CAVG +{ +private: + int m_Max; + double m_Sum; + double m_Avg; + double *m_pZ; + int m_W; + int m_Cnt; + +public: + __fastcall CAVG(); + __fastcall ~CAVG(); + void __fastcall Create(int max); + double __fastcall Do(double d); + inline BOOL __fastcall IsFull(void){return m_Cnt >= m_Max;}; + void __fastcall Reset(double d); + void __fastcall Reset(void); + inline double __fastcall GetAvg(void){return m_Avg;}; + inline BOOL __fastcall IsCreate(void){return m_pZ != NULL;}; + inline BOOL __fastcall IsHalf(void){return m_Max <= (m_Cnt*2);}; +}; +//--------------------------------------------------------------------------- +class CDECM2{ +private: + double m_O; + int m_Count; +#if DECFIR + CFIR2 m_FIR; +#else + CIIR m_IIR; +#endif +public: + int m_Type; + double m_SampleFreq; +public: + __fastcall CDECM2(); + void __fastcall SetSampleFreq(int type, double f); + BOOL __fastcall Do(double d); + inline double __fastcall GetOut(void){return m_O;}; +#if DECFIR + inline CFIR2* __fastcall GetFIR(void){return &m_FIR;}; +#else + inline CIIR* __fastcall GetIIR(void){return &m_IIR;}; +#endif + inline void __fastcall SetOut(double d){m_O = d;}; +}; + +//-------------------------------------------------------- +// CAGCクラス +class CAGC +{ +private: + double m_Max; + double m_Min; + double m_d; + double m_agc; + + double m_fc; + double m_Gain; + CIIR m_LPF; +// CIIR m_Level; + int m_Count; + int m_TLimit; + CFAVG m_AvgOver; +public: + double m_LimitGain; + double m_MonitorFreq; + double m_CarrierFreq; + double m_SampleFreq; +public: + __fastcall CAGC(); + void __fastcall Create(void); + inline void __fastcall SetSampleFreq(double f){m_SampleFreq = f; Create();}; + void __fastcall SetCarrierFreq(double f); + void __fastcall SetFC(double fc); + void __fastcall Reset(void); + double __fastcall Do(double d); + inline void __fastcall ResetOver(void){m_AvgOver.Reset(1.0);}; + BOOL __fastcall GetOver(void); +}; + +#if DEBUG +//--------------------------------------------------------------------------- +class CQSB +{ +private: + int m_vMax, m_vMin; + BOOL m_fPhaseError; + CVCO m_VCO; + CVCO m_VCOP; + int m_tap; + double m_Z[TAPMAX]; +public: + __fastcall CQSB(); + __fastcall ~CQSB(); + void __fastcall Create(int min, int max, int msec, BOOL perr); + int __fastcall Do(void); + double __fastcall Do(double d); +}; + +//--------------------------------------------------------------------------- +class CNoise // M系列ノイズ N=22 (Tap=1) +{ +private: + double m_SampleFreq; + + DWORD m_reg; + CIIR m_LPF; + CIIR m_HPF; +public: + __fastcall CNoise(); + void __fastcall SetSampleFreq(double f); + void __fastcall Create(double f1, double f2); + DWORD __fastcall Do(void); + double __fastcall DoLPF(void); + double __fastcall DoHPF(void); +}; +#endif + +/*============================================================================= + CPHASEXクラス Added by JE3HHT on Sep.2010 for the new RTTY demodualtor +=============================================================================*/ +#define CPHASEX_BASEFREQ 0.0 +class CPHASEX +{ +public: +// CFIRX m_LPF; +private: + CVCO m_VCO; + CFIR2 m_Hilbert; + CAGC m_AGC; + + FILE *m_fp; +public: + CLX m_sig; + CSlideFFT m_SlideFFT; + + int m_TONES; + double m_SHIFT; + double m_fftSHIFT; + int m_BASEPOINT; + + double m_MixerFreq; + double m_SymbolLen; + double m_CarrierFreq; + double m_SampleFreq; + + double m_dm; + double m_ds; +private: +// void __fastcall CreateFilter(void); +public: + __fastcall CPHASEX(); + void __fastcall Create(void); + void __fastcall SetSampleFreq(double f); + void __fastcall SetCarrierFreq(double f); + inline void __fastcall AddCarrierFreq(double f){ + SetCarrierFreq(m_CarrierFreq + f); + }; + CLX* __fastcall Do(double d); + inline CFIR2* __fastcall GetFIR(void){return &m_Hilbert;}; + + void __fastcall DoFSK(double d); + void __fastcall SetShift(double f); + void __fastcall ShowPara(void); + + inline void SetTones(int n){ + m_TONES = n; + Create(); + } +}; + +//--------------------------------------------------------------------------- +// CLMSクラス +#define LMSTAP 192 +class CLMS +{ +private: + double Z[LMSTAP+1]; // FIR Z Application + double D[LMSTAP+1]; // LMS Delay; + + double m_lmsADJSC; // スケール調整値 + double m_D; +public: + int m_Tap; + int m_lmsDelay; // LMS Delay + int m_lmsAGC; // LMS AGC + double m_lmsMU2; // LMS 2μ + double m_lmsGM; // LMS γ + double H[LMSTAP+1]; // アプリケーションフィルタの係数 +public: + __fastcall CLMS(); + + double __fastcall Do(double d); +}; + +class CAFC +{ +private: +public: + BOOL m_fChange; + int m_Count; + int m_LCount1; + int m_LCount2; + + CAVG m_Avg; + double m_d; + double m_min; + double m_max; + double m_fq; + CIIR m_LPF; +public: + double m_Max, m_Min; + double m_A; + double m_B; + double m_Speed; + double m_SampleFreq; +public: + __fastcall CAFC(); + void __fastcall SetPara(double a, double b); + void __fastcall SetTap(int tap); + void __fastcall SetTone(double fq); + BOOL __fastcall Do(double d); + double __fastcall GetFreq(void){return m_fq;}; +}; + +//--------------------------------------------------------------------------- +enum { + diddleLTR, + diddleBLK, +}; +class CENCODE +{ +public: + DWORD m_Z[32]; + + int m_Type; + int m_Mode; + int m_cData; + int m_cBCount; + int m_out; + int m_outbit; + int m_sync; + int m_Idle; + BOOL m_fJA; + BOOL m_fTWO; + + int m_Cnt; + double m_dCW; + double m_dTW; + double m_dNow; + double m_dNext; + + double m_Speed; + double m_SampleFreq; + + BOOL m_fCW; + BOOL m_Mark; + BOOL m_fReqRX; + + int m_Code; + + int m_rttyDiddle; + int m_rttyCWait; + int m_rttyDWait; + CBAUDOT m_BAUDOT; + + int m_Buff[1024]; + int m_WP; + int m_RP; + int m_CC; + + int __fastcall (*m_pFunc)(void); + CVCO *m_pVCO; + + BOOL m_fChar; + + // Added for MFSK + int m_MFSK_TYPE; + int m_MFSK_TONES; + double m_MFSK_SPEED; + int m_MFSK_BITS; + UINT m_MFSK_MASK; + + CViterbiEncode m_Viterbi; + UINT m_MFSK_SHDATA; + int m_MFSK_SHCount; + CFifo m_Fifo; + CInterLeaver m_InterLeaver; + +private: + int __fastcall GetChar(void); + + void __fastcall MFSKSendBit(BOOL bit); + void __fastcall MFSKSendPair(BYTE pair); + void __fastcall MFSKSendSymBit(BOOL bit); + void __fastcall MFSKSendChar(int c); + void __fastcall MFSKSendIdle(int n); + void __fastcall MFSKSendIdle(void); + + void __fastcall MFSKSendIdleChar(void); + +public: + __fastcall CENCODE(); + inline void __fastcall SetVCO(CVCO *pVCO){m_pVCO = pVCO;}; + void __fastcall SetSampleFreq(double f){m_SampleFreq = f; Create();}; + void __fastcall Create(void); + void __fastcall SetSpeed(double b){m_Speed = b; Create();}; + void __fastcall Reset(BOOL fCW); + int __fastcall Do(void); + void __fastcall SetTmg(double d); + void __fastcall SetCW(int f); + + void __fastcall PutChar(int c); + BOOL __fastcall IsBuffFull(void); + inline int __fastcall GetBuffCount(void){return m_CC;}; + inline void __fastcall SetType(int type){m_Type = type;}; + inline void __fastcall SetDiddle(int diddle){m_rttyDiddle = diddle;}; + inline int __fastcall GetDiddle(void){return m_rttyDiddle;}; + inline void __fastcall SetMark(void){m_Mark = TRUE;}; + inline void __fastcall SetWaitC(int n){m_rttyCWait = n;}; + inline void __fastcall SetWaitD(int n){m_rttyDWait = n;}; + inline int __fastcall GetWaitC(void){return m_rttyCWait;}; + inline int __fastcall GetWaitD(void){return m_rttyDWait;}; + void __fastcall SetMFSKType(int type); +}; + +//--------------------------------------------------------------------------- +// CDECFSKクラス +class CDECFSK +{ +private: +public: + int m_Type; + + int m_cData; + int m_cBCount; + int m_cTCount; + int m_cMode; + int m_s; + int m_a; + + double m_dTW; + double m_dTWH; + double m_dBTW; + double m_dBTWL; + double m_dBTWH; + double m_dNow; + double m_dNext; + double m_dFree; + + int m_cBWave; + int m_T; + int m_T2; + int m_T3; + int m_Error; + + int m_ATCCounter; + int m_ATCLimitH; + int m_ATCLimitL; + + double m_Threshold; + double m_GainA; + double m_GainB; + CAVG m_LPF; + CAVG m_LPFI; + double m_A; + + BOOL m_fSync; + CRTTY m_BAUDOT; + CFAVG m_AvgRTTY; + + BOOL m_fMeasClock; + int m_MeasCounter; + int m_MeasClock; + int m_MeasError; + int m_Meas1st; +public: + int m_Lock; + double m_dTmg3; + double m_dTmg2; + double m_dTmg; + int m_Tmg; + int m_Data; + double m_dAdj; // タイミング補正(ppm) + BOOL m_fATC; + int m_ATCSpeed; + int m_ATCLimit; + + double m_Speed; // 伝送速度(baud) + double m_SampleFreq; // Hz +private: + BOOL __fastcall DoBAUDOT(int s, BOOL sq); + +public: + __fastcall CDECFSK(); + void __fastcall Create(void); + inline void __fastcall SetSpeed(double b){m_Speed = b; Create();}; + BOOL __fastcall Do(double d, BOOL sq, BOOL fATC); + inline void __fastcall SetSampleFreq(double f){ + m_SampleFreq = f; + Create(); + }; + void __fastcall ClearLPF(void); + void __fastcall Reset(void); + void __fastcall SetMeasClock(BOOL f); + void __fastcall SetTmg(int ppm); + inline int __fastcall GetData(void){int r = m_Data; m_Data = -1; return r;}; + inline int __fastcall GetTmg(void){ return m_Tmg ? 1 : -1;}; + void __fastcall CalcIntval(double d); + BOOL __fastcall GetSyncState(void); + void __fastcall SetATCSpeed(int atcspeed); + void __fastcall SetATCLimit(int atclimit); + + inline void __fastcall SetType(int type){m_Type = type;}; + inline void __fastcall SetUOS(int type){ + if( type == 2 ){ + m_BAUDOT.m_uos = !m_BAUDOT.m_uos; + } + else { + m_BAUDOT.m_uos = type; + } + }; + inline BOOL __fastcall GetUOS(void){return m_BAUDOT.m_uos;}; + inline BOOL __fastcall IsRTTYTmg(void){return m_AvgRTTY.IsHalf();}; + inline double __fastcall GetRTTYTmg(void){ + return m_AvgRTTY.GetAvg() * 1000.0 / m_SampleFreq; + }; + inline void __fastcall ResetMeasRTTY(void){m_AvgRTTY.Reset();}; +}; + +/*============================================================================= + CViterbiQPSKクラス Added by JE3HHT on Sep.2010 for QPSK +=============================================================================*/ +class CViterbiQPSK { +private: + double m_tPath[16]; + int m_tBit[16]; +public: + CViterbiQPSK(void); + void __fastcall Reset(void); + BOOL __fastcall Do(double angle, double *pMetric); +}; +/*============================================================================= + CDecPSKクラス Added by JE3HHT on Sep.2010 for QPSK +=============================================================================*/ +#define QPSK_SUBFACTOR 4 // サブサンプリングファクター +#define QPSK_LPF2K 0.70710678118654752440084436210485 // sqrt(2)/2 +#define PSK_AMPSTGMAX int(9000.0/(MIN_SPEED*QPSK_SUBFACTOR)) +enum { + QPSK_ROT_0, + QPSK_ROT_90, + QPSK_ROT_180, + QPSK_ROT_270, +}; +class CDecPSK { +public: + CFIRX m_LPF1; // デシメータ + CFIRX m_LPF2; // 信号用フィルタ + CLX m_Z; +private: + CLX m_sig; + CVCO m_VCO; + CFIR2 m_Hilbert; + + CLX m_StgZ[4]; + CViterbiQPSK m_Viterbi; + double m_Metric[4]; + double m_Angle; + int m_Bits; + int m_SN; + + int m_nSubCounter; // サブサンプリング用カウンタ + + int m_iW; + int m_iWM; + float m_AmpStg[PSK_AMPSTGMAX]; + + UINT m_SHDATA; + + double m_dNow; + double m_dTW; + double m_dBTW; + double m_dBTWL, m_dBTWH; + + BOOL m_fSQ; + + CFAVG m_AvgClock; + int m_MeasClock; + int m_MeasCounter; + int m_MeasStage; + + double m_dblAvgAFC; + double m_vAvg; + +public: + BOOL m_SyncState; + BOOL m_Tmg; + BOOL m_TmgLock; + CFifo m_RxData; + + double m_Speed; + BOOL m_bQPSK; + BOOL m_fLSB; + BOOL m_bATC; + + double m_NextCarrierFreq; + double m_CarrierFreq; + double m_SampleFreq; +private: + void __fastcall RxBit(int bit); + void __fastcall DoSym(const CLX &z); + void __fastcall DoSync(CLX &z); + void __fastcall DoATC(BOOL fATC); + void __fastcall DoAFC(void); + +public: + __fastcall CDecPSK(void); + __fastcall ~CDecPSK(); + + void __fastcall SetSpeed(double d); + void __fastcall SetCarrierFreq(double f); + void __fastcall ResetRX(void); + void __fastcall Reset(void); + void __fastcall SetSampleFreq(double f); + void __fastcall ResetATC(void); + int __fastcall Do(double d, BOOL fSQ, BOOL fATC); + int __fastcall GetData(void); + + inline BOOL __fastcall GetSyncState(void){return m_SyncState;}; + inline BOOL __fastcall GetTmgLock(void){return TRUE;}; + inline BOOL __fastcall GetTmg(void){return m_Tmg;}; + int __fastcall GetD(void); + inline int __fastcall GetS(void){ + return (m_Angle - PI) * 32768.0 * 0.5 / PI; +// return m_zSymStg[0].Abs(); 1. + }; + + int __fastcall GetClockError(void); + void __fastcall SetTmg(int ppm); + void __fastcall SetSN(int SN){ + m_SN = SN; + } +}; + +/*============================================================================= + CPHASEクラス +=============================================================================*/ +#define MFSK_BASEFREQ 1000.0 +class CPHASE +{ +private: + CVCO m_VCO; + CFIR2 m_Hilbert; +public: + CLX m_sig; + CSlideFFT m_SlideFFT; + + int m_MFSK_TONES; + double m_MFSK_SPEED; + int m_MFSK_BASEPOINT; + + double m_MixerFreq; + double m_SymbolLen; + double m_CarrierFreq; + double m_SampleFreq; +private: +public: + __fastcall CPHASE(); + void __fastcall Create(void); + void __fastcall SetSampleFreq(double f); + void __fastcall SetCarrierFreq(double f); + inline void __fastcall AddCarrierFreq(double f){ + SetCarrierFreq(m_CarrierFreq + f); + }; + CLX* __fastcall Do(double d); + inline CFIR2* __fastcall GetFIR(void){return &m_Hilbert;}; + + void __fastcall SetMFSKType(int type); +}; + +/*============================================================================= + CDecMFSKクラス +=============================================================================*/ +#define AMPSTGMAX int(9000.0*2.0/MFSK_MINSPEED) // (MaxDemSamp + ClockAdjust) * 2 / MFSK8_MINSPEED +class CDecMFSK { +private: + int m_AmpStgMax; + int m_AmpStgPtr; + double m_AmpStg[AMPSTGMAX][MFSK_MAXTONES]; + + CInterLeaver m_InterLeaver; + UINT m_SHDATA; + + BYTE m_SymStg[3]; + + double m_AvgMetric; + + double m_dNow; + double m_dTW; + double m_dBTW; + double m_dBTWL, m_dBTWH; + + CViterbi m_Viterbi1; + CViterbi m_Viterbi2; + double m_Metric1; + double m_Metric2; + BYTE m_ViterbiPair[2]; + UINT m_ViterbiPhase; + + BOOL m_fSQ; + BOOL m_fDelaySQ; + int m_SQDelayCount; + + CFAVG m_AvgClock; + int m_MeasClock; + int m_MeasCounter; + int m_MeasStage; + + CFAVG m_AvgAFC; + CLX m_PrevZ; + double m_AFCWidth; + double m_kAFC; + +public: + BOOL m_SyncState; + BOOL m_Tmg; + BOOL m_TmgLock; + CPHASE m_Phase; + CFifo m_RxData; + + int m_MFSK_TYPE; + int m_MFSK_TONES; + double m_MFSK_SPEED; + int m_MFSK_BITS; + double m_MFSK_BW; + + BOOL m_fLSB; + double m_SampleFreq; +private: + double __fastcall GetFactor(void); + void __fastcall StreamSym(BYTE sym); + void __fastcall RecSym(const double *pAmp); + BYTE __fastcall DecodeSym(CLX *pFFT, double *pAmp); + void __fastcall DoSync(void); + void __fastcall DoMeas(void); + void __fastcall DoAFC(CLX *pFFT); +public: + __fastcall CDecMFSK(); + void __fastcall SetSampleFreq(double f); + void __fastcall SetCarrierFreq(double f); + + int __fastcall Do(CLX *pFFT, BOOL fSQ); + int __fastcall GetData(void); + void __fastcall Reset(void); + void __fastcall ResetMeas(void); + + inline BOOL __fastcall GetSyncState(void){return m_SyncState;}; + inline BOOL __fastcall GetTmgLock(void){return TRUE;}; + inline BOOL __fastcall GetTmg(void){return m_Tmg;}; + inline int __fastcall GetS(void){return m_SymStg[2];}; + + int __fastcall GetClockError(void); + inline CFIR2* __fastcall GetFIR(void){return m_Phase.GetFIR();}; + inline BOOL __fastcall IsMetSQ(void){ + return (m_AvgMetric >= 100); + }; + int __fastcall GetMetric(int sw); + void __fastcall SetTmg(int ppm); + + void __fastcall SetMFSKType(int type); + BOOL __fastcall GetAFCShift(double &fq); +}; + + +//--------------------------------------------------------------------------- +// CDEMFSKクラス +#define DEMAFCLIMIT (10*11025/2048) +class CDEMFSK +{ +#if DEBUG +public: + int m_DEBUG; +#endif +//private: +public: + double m_d; + double m_err; + double m_out; + double m_PreBPFFC; + CFIR2 *m_pBPF; +public: + CFIR2 m_inBPF; + CIIR m_LPF1; +// CIIR m_LPF2; + CIIR m_LoopLPF; + CIIR m_OutLPF; + CVCO m_VCO; + CAGC m_AGC; + CAFC m_AFC; + CDECFSK m_Decode; + CFAVG m_FAVG; + CIIRTANK m_TankL; + CIIRTANK m_TankH; + BOOL m_fRTTYTANK; + UINT m_AFCCount; + + BOOL m_fRTTYFFT; + CPHASEX m_PhaseX; + CSmooz m_SmoozM; + CSmooz m_SmoozS; + + double m_BPFLimit; +// CCICM m_CIC; + + BOOL m_fMFSK; + CDecMFSK *m_pMFSK; + BOOL m_fQPSK; + CDecPSK m_DecPSK; + double m_CarrierQPSK; + double m_RxFreqQPSK; + +public: + int m_Type; + double m_RxFreq; + int m_Lock; + int m_LockTh; // 連続キャリア検出のスレッシュホールド + double m_FreqErr; + double m_DemLevel; + + double m_Gain; + double m_SW; + + BOOL m_fEnableAFC; + BOOL m_fAFC; + + double m_Speed; + double m_CarrierFreq; + double m_SampleFreq; + int m_PreBPFTaps; + double m_RTTYShift; + + int m_MFSK_TYPE; + int m_MFSK_TONES; + double m_MFSK_SPEED; + double m_MFSK_BW; + int m_MFSK_BITS; + +#if MEASIMD + +public: + double m_imd; + double m_max; + double m_min; + double m_amax; + double m_amin; + void __fastcall CalcIMD(void); +#endif +private: + void __fastcall DoAFC(double d); + void __fastcall DoAFCPSK(double d); + void __fastcall DoAFCQPSK(double d); + void __fastcall DoAFCRTTY(double d); +public: + __fastcall CDEMFSK(); + __fastcall ~CDEMFSK(); + inline void __fastcall SetSampleFreq(double f){ + m_SampleFreq = f; Create(); + }; + inline void __fastcall SetType(int type){m_Type = type; Create();}; + void __fastcall MakeBPF(int taps); + void __fastcall UpdateBPF(void); + void __fastcall SetCarrierFreq(double f); + inline void __fastcall SetSpeed(double b){m_Speed = b; Create();}; + inline void __fastcall SetRTTYShift(double s){ + m_RTTYShift = s; + if( Is170(m_Type) ) Create(); + }; + void __fastcall Create(void); + int __fastcall Do(double); + int __fastcall Do(double d, BOOL fSQ, BOOL fATC); + int __fastcall GetData(void); + int __fastcall GetTmg(void); + int __fastcall GetTmgLock(void); + int __fastcall GetS(void); + void __fastcall ResetMFSK(void); + void __fastcall ResetMeasMFSK(void); + BOOL __fastcall GetSyncState(void); + int __fastcall GetClockError(void); + void __fastcall SetTmg(int ppm); + + double __fastcall GetFreqErr(void); +#if 0 + inline double __fastcall GetMFSKAFC(void){ + if( m_pMFSK && m_pMFSK->m_AvgAFC.IsFull() ){ + return m_pMFSK->m_AvgAFC.GetAvg(); + } + else { + return 0; + } + }; + inline void __fastcall ClearMFSKAFC(void){ + if( m_pMFSK ){ + m_pMFSK->m_AvgAFC.Reset(); + } + } + +#endif + inline CFIR2* __fastcall GetMFSKHIL(void){ + if( m_pMFSK ){ + return m_pMFSK->GetFIR(); + } + else { + return NULL; + } + }; + inline BOOL __fastcall IsMFSKSQ(void){ + if( m_pMFSK ){ + return m_pMFSK->IsMetSQ(); + } + else { + return FALSE; + } + } + inline int __fastcall GetMFSKMetric(int sw){ + if( m_pMFSK ){ + return m_pMFSK->GetMetric(sw); + } + else { + return 0; + } + } + + void __fastcall SetMFSKType(int type); +}; + +#define MODTABLEMAX (MAX_SAMP/MIN_SPEED) +/* +enum { + MOD_CZ2P, + MOD_VZ2P, + MOD_RZ2P, + MOD_LZ2P, +}; +*/ +enum { + MOD_P2M, + MOD_M2P, + MOD_Z2P, + MOD_Z2M, +}; +//--------------------------------------------------------------------------- +// CDEMFSKクラス +class CMODFSK +{ +#if DEBUG +public: + int m_DEBUG; +#endif +private: + int m_s; + int m_Cnt; + double m_d; + double *m_pTbl; + double m_Tbl[4][MODTABLEMAX]; + CFIR2 m_BPF; + CAMPCONT m_AMPCW; + CAMPCONT m_AMPSIG; +public: + int m_OutVol; + int m_Type; + CENCODE m_Encode; + CVCO m_Carrier; + int m_CWSpeed; + BOOL m_fRTTYLPF; + double m_Speed; + double m_RTTYShift; + double m_CarrierFreq; + double m_SampleFreq; + + BOOL m_fMFSK; + int m_MFSK_TYPE; + int m_MFSK_TONES; + double m_MFSK_SPEED; + double m_MFSK_BW; + + double m_MFSK_K; + + BOOL m_fQPSK; + CLX m_Sym; + CLX m_PrevSym; + BOOL m_fLSB; + UINT m_SHDATA; +private: + void __fastcall CreateGMSK(void); + void __fastcall CreatePSK(void); + void __fastcall CreateRTTY(void); + +public: + __fastcall CMODFSK(); + __fastcall ~CMODFSK(); + inline void __fastcall SetSampleFreq(double f){ + m_SampleFreq = f; Create(); + }; + void __fastcall SetCarrierFreq(double f); + void __fastcall SetCWSpeed(int d); + void __fastcall Reset(void); + inline int __fastcall GetCWSpeed(void){return m_CWSpeed;}; + inline void __fastcall SetSpeed(double b){ m_Speed = b; Create();}; + inline void __fastcall SetType(int type){m_Type = type; Create();}; + inline void __fastcall SetRTTYShift(double s){ + m_RTTYShift = s; + if( Is170(m_Type) ) Create(); + }; + void __fastcall Create(void); + //inline void Reset(void){m_Encode.Reset(FALSE);}; + + double __fastcall Do(void); + double __fastcall DoCarrier(void); + + inline CFIR2* __fastcall GetFIR(void){return &m_BPF;}; + void __fastcall SetMFSKType(int type); +}; + +//--------------------------------------------------------------------------- +class CCOLLECT +{ +public: + int m_Max; + int m_Cnt; + double *m_pZ; +public: + __fastcall CCOLLECT(); + __fastcall ~CCOLLECT(); + void __fastcall Create(int max); + inline void __fastcall Clear(void){m_Cnt = 0;}; + void __fastcall Do(double d); + inline double *__fastcall GetZP(void){return m_pZ;}; + inline int __fastcall GetMax(void){return m_Max;}; + inline int __fastcall GetCount(void){return m_Cnt;}; + inline BOOL __fastcall IsFull(void){return m_Cnt >= m_Max;}; +}; +//--------------------------------------------------------------------------- +class CClock +{ +public: + int m_Width; + int *m_pData; + double m_dNow; + double m_dAdd; + + double m_ToneFreq; + double m_SampleFreq; + CIIRTANK2 m_BPF; + CIIR m_LPF; +public: + __fastcall CClock(); + __fastcall ~CClock(); + void __fastcall Create(int max); + void __fastcall SetSampleFreq(double f); + void __fastcall SetToneFreq(double f); + BOOL __fastcall Do(short ds); + inline int __fastcall GetData(int n){return m_pData[n];}; +}; +/*============================================================================= + CPlayBackクラス +=============================================================================*/ +class CPlayBack +{ +private: + int m_StgMax; + int m_StgWidth; + + int m_StgCnt; + int m_StgW; + + int m_WTimer; + int m_StgRCnt; + int m_StgR; + short *m_pStg; +public: + __fastcall CPlayBack(); + __fastcall ~CPlayBack(); + void __fastcall Delete(void); + void __fastcall Init(int wSize, int SampBase); + void __fastcall Clear(void); + void __fastcall Write(const short *p); + BOOL __fastcall Read(short *p); + void __fastcall StopPlaying(void); + BOOL __fastcall StartPlaying(int s); + + BOOL __fastcall IsActive(void){return m_StgMax;}; + BOOL __fastcall IsPlaying(void){return m_StgRCnt;}; +}; +/*============================================================================= + CNotchesクラス +=============================================================================*/ +typedef struct { + int Freq; + int m_MX; + int m_MY; +}NOTCHCTR; + +class CNotches +{ +public: + int m_Count; + int m_Max; + NOTCHCTR *m_pBase; + + CFIR2 m_FIR; + + int m_NotchWidth; + int m_nBaseTaps; + int m_nTaps; + double m_SampleFreq; + +private: + void __fastcall Alloc(int nIndex); + +public: + __fastcall CNotches(void); + __fastcall ~CNotches(); + void __fastcall Delete(void); + void __fastcall Create(void); + int __fastcall Find(int Freq); + void __fastcall Add(int Freq); + void __fastcall SetFreq(int nIndex, int Freq); + void __fastcall Delete(int nIndex); +}; +//--------------------------------------------------------------------------- +double __fastcall DoFIR(double *hp, double *zp, double d, int tap); +void __fastcall DrawGraph(Graphics::TBitmap *pBitmap, const double *H, int Tap, int &nmax, int init, TColor col, double SampFreq); +void __fastcall DrawGraphIIR(Graphics::TBitmap *pBitmap, double a0, double a1, double a2, double b1, double b2, int &nmax, int init, TColor col, double SampFreq); +void __fastcall DrawGraphIIR(Graphics::TBitmap *pBitmap, CIIR *ip, int &nmax, int init, TColor col, double SampFreq); +void __fastcall MakeHilbert(double *H, int N, double fs, double fc1, double fc2); +void __fastcall MakeGaussian(double *H, int N, double fc, double fs, double B); +void __fastcall AddGaussian(short *pData, int n, double gain); +double __fastcall GetRTTYBW(int taps); +double __fastcall GetMFSKBW(int taps); +extern CVARICODE g_VariCode; +#endif diff --git a/Dump.cpp b/Dump.cpp new file mode 100644 index 0000000..a03bcca --- /dev/null +++ b/Dump.cpp @@ -0,0 +1,1666 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include "Dump.h" +#include "ComLib.h" +#include "Dsp.h" + +#define LXW(c) ((c*4)/5) + +#if DEBUG +//--------------------------------------------------------------------------- +void __fastcall CDump::Debug(LPSTR t) +{ + sprintf(t, "DT:%d,WL:%d,ML:%d,RL:%d,WC:%d,MC:%d,RC:%d,Last:%d,Window:%d,Count:%d", + m_DTop, + m_WLine, m_MLine, m_RLine, + m_WCol, m_MCol, m_RCol, + m_fLastCP, m_fWindow, GetCharCount(TRUE) + ); +} +#endif +//--------------------------------------------------------------------------- +__fastcall CDump::CDump(void) +{ + m_fDisEvent = FALSE; + m_pPanel = NULL; + m_pBase = NULL; + m_pPaintBox = NULL; + m_pFont = NULL; + m_pCanvas = NULL; + m_pScrollBar = NULL; + m_ScreenColMax = DUMPCOLMAX; + m_wfp = NULL; + m_hWnd = NULL; + m_pMBCS = NULL; + + m_Color[0].c = clWhite; + m_Color[1].c = clBlack; + m_Color[2].c = clBlue; + m_Color[3].c = clRed; + m_Color[4].c = TColor(RGB(224,224,224)); + + m_CursorColor = TColor(128,128,128); + m_CursorColor = clBlue; + m_fConvAlpha = FALSE; + m_fShowCtrlCode = FALSE; + + m_CursorType = csCARET; + m_Cursor = 0; + m_fActive = FALSE; + m_CRCount = 0; + + m_MouseWheelCount = 0; + m_fRTTY = FALSE; + + m_ScreenXW = m_ScreenYW = 0; + memset(&m_LogFont, 0, sizeof(m_LogFont)); +} + +//--------------------------------------------------------------------------- +__fastcall CDump::~CDump() +{ + DeleteStg(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DeleteStg(void) +{ + if( m_pBase ){ + int i; + for( i = 0; i < m_StgLineMax; i++ ){ + delete m_pBase[i]; + } + delete m_pBase; + m_pBase = NULL; + } +} + +//--------------------------------------------------------------------------- +void __fastcall CDump::Create(HWND hWnd, TPanel *pPanel, TPaintBox *pPaintBox, TFont *pFont, TScrollBar *pBar, int line) +{ + m_hWnd = hWnd; + m_pPanel = pPanel; + m_pPaintBox = pPaintBox; + m_pFont = pFont; + m_pScrollBar = pBar; + m_pCanvas = pPaintBox->Canvas; + m_ScreenYW = pPaintBox->Height; + m_ScreenXW = pPaintBox->Width; + + m_rcScreen.Left = 0; + m_rcScreen.Top = 0; + m_rcScreen.Right = m_ScreenXW; + m_rcScreen.Bottom = m_ScreenYW; + + if( !m_pBase || (m_StgLineMax != line) ){ + DeleteStg(); + m_pBase = new int *[line]; + for( int i = 0; i < line; i++ ){ + int *ip = new int[DUMPCOLMAX+1]; + memset(ip, 0, sizeof(int)*(DUMPCOLMAX+1)); + m_pBase[i] = ip; + } + } + m_StgLineMax = line; + + m_fLastCP = TRUE; + m_MLine = m_WLine = m_WCol = m_DTop = 0; + m_MCol = m_RLine = m_RCol = 0; + m_X = m_Y = 0; + m_RX = m_RY = 0; + m_fKanji = FALSE; + m_fWindow = TRUE; + m_fCR = FALSE; + m_CRCount = 0; + + m_fSelText = FALSE; + m_fSelect = FALSE; + m_SLine = m_SCol = 0; + m_FLine = 0; + + m_pCanvas->Font = pFont; + m_FontXW = m_pCanvas->TextWidth("W"); + m_FontYW = m_pCanvas->TextHeight("|"); + if( !m_FontXW ) m_FontXW = 8; + if( !m_FontYW ) m_FontYW = 8; + m_ScreenLXW = LXW(m_ScreenXW); + m_ScreenLineMax = m_ScreenYW / m_FontYW; + if( m_ScreenLineMax >= m_StgLineMax ) m_ScreenLineMax = m_StgLineMax - 1; + GetLogFont(&m_LogFont, pFont); + SetScrollBar(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetFont(TFont *pFont) +{ + if( !m_hWnd ) return; + + m_pCanvas->Font = pFont; + m_FontXW = m_pCanvas->TextWidth("W"); + m_FontYW = m_pCanvas->TextHeight("|"); + if( !m_FontXW ) m_FontXW = 8; + if( !m_FontYW ) m_FontYW = 8; + m_ScreenLXW = LXW(m_ScreenXW); + GetLogFont(&m_LogFont, pFont); + Resize(); + int *ip = m_pBase[m_WLine]; + m_X = 0; + for( ; *ip; ip++ ){ + m_X += CharWidth(*ip); + } + ip = m_pBase[m_RLine]; + int col = m_RCol; + m_RX = 0; + for( ; *ip && col; ip++, col-- ){ + m_RX += CharWidth(*ip); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::Resize(void) +{ + if( !m_hWnd ) return; + + Cursor(FALSE); + m_ScreenXW = m_pPaintBox->Width; + m_ScreenYW = m_pPaintBox->Height; + int lmax = m_ScreenYW / m_FontYW; + if( !lmax ) lmax++; + if( lmax >= m_StgLineMax ) lmax = m_StgLineMax - 1; + if( lmax != m_ScreenLineMax ){ + m_ScreenLineMax = lmax; + if( m_WLine >= (lmax-1) ){ + m_DTop = m_WLine - lmax + 1; + if( m_DTop < 0 ) m_DTop = 0; + } + else { + m_DTop = 0; + } + m_Y = (m_WLine - m_DTop) * m_FontYW; + m_RY = (m_RLine - m_DTop) * m_FontYW; + } + SetScrollBar(); + SetCursorPos(); + m_fWindow = TRUE; + Cursor(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::OpenSelect(void) +{ + if( !m_fSelect && !m_fSelText ){ + m_SLine = m_WLine; + m_SCol = m_WCol; + } + m_fSelect = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::CloseSelect(void) +{ + m_fSelect = FALSE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::ClearSelect(BOOL fPaint) +{ + BOOL r = FALSE; + if( m_fSelText ){ + r = ClearAllSelect(fPaint); + } + return r; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::UpdateSelect(void) +{ + if( !m_fSelect ) return; + + ClearSelect(FALSE); + int sno = m_SLine * DUMPCOLMAX + m_SCol; + int wno = m_WLine * DUMPCOLMAX + m_WCol; + int *ip; + int i; + int sline, wline, scol, wcol; + if( sno < wno ){ + sline = m_SLine; wline = m_WLine; + scol = m_SCol; wcol = m_WCol; + } + else { + sline = m_WLine; wline = m_SLine; + scol = m_WCol; wcol = m_SCol; + } + BOOL f = FALSE; + for( i = sline; i <= wline; i++ ){ + ip = m_pBase[i]; + int col = 0; + for( ; *ip; ip++, col++ ){ + if( (i == sline) && (col < scol) ){ + continue; + } + else if( (i == wline) && (col >= wcol) ){ + continue; + } + else { + f = TRUE; + *ip |= 0x80000000; + } + } + } + m_fSelText = f; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::GetSelText(AnsiString &as) +{ + BOOL f = FALSE; + as = ""; + if( !m_fSelText ) return f; + + int i, c; + int *ip; + for( i = 0; i < m_StgLineMax; i++ ){ + ip = m_pBase[i]; + for( ; *ip; ip++ ){ + if( *ip & 0x80000000 ){ + f = TRUE; + c = *ip & 0x0000ffff; + if( c >= 0x8100 ){ + as += char(c>>8); + } + as += char(c); + if( c == '\r' ) as += '\n'; + } + } + } + return f; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::DeleteSelText(void) +{ + if( !m_fSelText ) return FALSE; + if( !CanEdit() ) return FALSE; + +// if( m_RLine > m_SLine ) return FALSE; +// if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return FALSE; + + int i, col; + int *ip; + for( i = 0; i < m_StgLineMax; i++ ){ + ip = m_pBase[i]; + col = 0; + for( ; *ip; ip++, col++ ){ + if( *ip & 0x80000000 ){ + m_WLine = i; + m_WCol = col; + int *bp = CreateContP(i, col, 0); + for( ip = bp; *ip; ip++ ){ + if( !(*ip & 0x80000000) ) break; + } + CloseContP(i, col, bp, ip - bp); + m_Y = (m_WLine - m_DTop) * m_FontYW; + m_X = 0; + col = 0; + ip = m_pBase[m_WLine]; + for( ; *ip && (col < m_WCol); ip++, col++ ){ + m_X += CharWidth(*ip); + } + SetCursorPos(); + m_fSelText = FALSE; + return TRUE; + } + } + } + m_fSelText = FALSE; + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::MoveCursor(int SX, int SY, BOOL fDown) +{ + Cursor(FALSE); + BOOL fPaint = ClearSelect(FALSE); + int line = SY/m_FontYW + m_DTop; + if( line > m_MLine ){ + if( fPaint ) Paint(); + MoveCursor(dmpMoveLAST); + return; + } + + int *bp = m_pBase[line]; + int *ip = bp; + int x, xw; + int col = 0; + for( x = 0; *ip; ip++ ){ + xw = CharWidth(*ip); + if( (x + (xw/2)) >= SX ) break; + x += xw; + col++; + } + if( fDown && !*ip ){ + if( fPaint ) Paint(); + MoveCursor(dmpMoveLAST); + return; + } + m_WLine = line; + m_WCol = col; + m_X = x; + m_Y = (m_WLine - m_DTop) * m_FontYW; + if( m_fSelect ){ + UpdateSelect(); + fPaint = TRUE; + } + m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop)); + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); + SetCursorPos(); + Cursor(TRUE); + if( fPaint ) Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::MoveCursor(int Key) +{ + Cursor(FALSE); + switch(Key){ + case VK_LEFT: + if( m_WCol ){ + m_WCol--; + int *ip = m_pBase[m_WLine] + m_WCol; + int xw = CharWidth(*ip); + m_X -= xw; + } + else if( m_WLine ){ + m_WLine--; + m_Y -= m_FontYW; + int *ip = m_pBase[m_WLine]; + m_X = 0; + for( ; *ip; ip++ ){ + m_X += CharWidth(*ip); + m_WCol++; + } + } + break; + case VK_RIGHT: + { + int *ip = m_pBase[m_WLine] + m_WCol; + if( *ip && ((*ip & 0x0000ffff) != '\r') ){ + m_WCol++; + m_X += CharWidth(*ip); + } + else if( m_WLine < m_MLine ){ + m_WLine++; + m_Y += m_FontYW; + m_WCol = 0; + m_X = 0; + } + } + break; + case VK_UP: + if( m_WLine ){ + m_WLine--; + m_Y -= m_FontYW; + int *ip = m_pBase[m_WLine]; + m_WCol = 0; + int x = 0; + for( ; *ip && (x < m_X); ip++ ){ + x += CharWidth(*ip); + m_WCol++; + } + m_X = x; + } + break; + case VK_DOWN: + if( m_WLine < m_MLine ){ + m_WLine++; + m_Y += m_FontYW; + int *ip = m_pBase[m_WLine]; + m_WCol = 0; + int x = 0; + for( ; *ip && (x < m_X); ip++ ){ + x += CharWidth(*ip); + m_WCol++; + } + m_X = x; + } + break; + case VK_HOME: + if( m_WLine == m_RLine ){ + m_WCol = m_RCol; + m_X = 0; + int *ip = m_pBase[m_WLine]; + int col = 0; + for( ; *ip && (col < m_WCol); ip++, col++ ){ + m_X += CharWidth(*ip); + } + } + else { + m_WCol = 0; + m_X = 0; + } + break; + case dmpMoveTOP: + case VK_HOME+0x0100: + { + m_WLine = m_RLine; + m_WCol = m_RCol; + m_X = 0; + int *ip = m_pBase[m_WLine]; + int col = 0; + for( ; *ip && (col < m_WCol); ip++, col++ ){ + m_X += CharWidth(*ip); + } + m_Y = (m_WLine - m_DTop) * m_FontYW; + } + break; + case VK_END: + if( !m_fLastCP ){ + int *ip = m_pBase[m_WLine]; + m_WCol = 0; + int x = 0; + for( ; *ip; ip++ ){ + x += CharWidth(*ip); + m_WCol++; + } + m_X = x; + } + break; + case VK_END + 0x0100: + case dmpMoveLAST: + if( !m_fLastCP ){ + m_WLine = m_MLine; + m_Y = (m_WLine - m_DTop) * m_FontYW; + int *ip = m_pBase[m_WLine]; + m_WCol = 0; + int x = 0; + for( ; *ip; ip++ ){ + x += CharWidth(*ip); + m_WCol++; + } + m_X = x; + } + break; + } + if( m_WCol ){ + int *ip = m_pBase[m_WLine] + m_WCol - 1; + if( (*ip & 0x0000ffff) == '\r' ) m_WCol--; + } + BOOL fPaint; + if( m_fSelect ){ + UpdateSelect(); + fPaint = TRUE; + } + else { + fPaint = ClearSelect(FALSE); + } + if( (m_Y < 0) || (m_WLine < m_DTop) ){ + m_DTop = m_WLine; + m_Y = (m_WLine - m_DTop) * m_FontYW; + fPaint = TRUE; + } + else if( (m_Y >= m_ScreenYW) || ((m_WLine - m_DTop) >= (m_ScreenLineMax - 1)) ){ + m_DTop = m_WLine - m_ScreenLineMax + 1; + m_Y = (m_WLine - m_DTop) * m_FontYW; + fPaint = TRUE; + } + m_RY = (m_RLine - m_DTop) * m_FontYW; + if( fPaint ) Paint(); + SetScrollBar(); + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); + SetCursorPos(); + Cursor(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::FollowRP(void) +{ + if( m_WLine > m_RLine ) return; + if( m_WLine < m_RLine ){ + m_RLine = m_WLine; + m_RCol = m_WCol; + m_RX = m_X; + } + else if( m_WCol < m_RCol ){ + m_RCol = m_WCol; + m_RX = m_X; + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetBuffer(int c) +{ + c &= 0x0000ffff; + LPSTR t = m_Buffer; + if( c == 0x0200 ){ + strcpy(t, "(i)"); t += 3; + } + else if( c >= 0x0020 ){ + if( c >= 0x8140 ){ + *t++ = BYTE(c >> 8); + } + *t++ = BYTE(c); + } + else if( m_fShowCtrlCode && (c != '\r') ){ + sprintf(t, "[$%02X]", c); t += strlen(t); + } + *t = 0; +} + +int __fastcall CDump::CharWidth(int c) +{ + SetBuffer(c); + return m_Buffer[0] ? m_pCanvas->TextWidth(m_Buffer) : 0; +} + +int __fastcall CDump::DrawChar(int x, int y, int c, BOOL f) +{ + SetBuffer(c); + if( m_Buffer[0] ){ + if( f && (x>=0)&&(y>=0)&&(x> 16) & 3; + if( c & 0x80000000 ){ + TRect rc; + rc.Left = x; rc.Top = y; + rc.Right = x + m_pCanvas->TextWidth(m_Buffer); + rc.Bottom = y + m_FontYW; + m_pCanvas->Brush->Color = m_Color[col].c; + m_pCanvas->FillRect(rc); + m_pCanvas->Brush->Color = m_fWindow ? m_Color[0].c : m_Color[4].c; + col = 0; + } + m_pCanvas->Font->Color = m_Color[col].c; + ::SetBkMode(m_pCanvas->Handle, TRANSPARENT); + m_pCanvas->TextOut(x, y, m_Buffer); + } + x += m_pCanvas->TextWidth(m_Buffer); + } + return x; +} + +void __fastcall CDump::MemScroll(void) +{ + int i; + int **ip = m_pBase; + int *bp = *ip; + for( i = 0; i < (m_StgLineMax - 1); i++, ip++ ){ + *ip = *(ip+1); + } + *ip = bp; + *bp = 0; + if( m_RLine ) m_RLine--; + if( m_FLine ) m_FLine--; + m_SML--; +} + +void __fastcall CDump::FlushLogFile(void) +{ + if( m_wfp ) fflush(m_wfp); +} + +void __fastcall CDump::OpenLogFile(LPCSTR pName) +{ + CloseLogFile(); + FILE *fp = fopen(pName, "rb"); + BOOL f = FALSE; + if( fp ){ + fclose(fp); + f = TRUE; + } + m_wfp = fopen(pName, "ab"); + if( !m_wfp ){ + ErrorMB(sys.m_MsgEng ? "Can not create '%s'":"%sを作成できません.", pName); + } + else if( !f ){ // 初回のオープン + for( int i = 0; i < m_WLine; i++ ){ + WriteLine(i); + } + } +} + +void __fastcall CDump::CloseLogFile(void) +{ + if( m_wfp ){ + fclose(m_wfp); + m_wfp = NULL; + } +} + +void __fastcall CDump::WriteLine(AnsiString &as, int line) +{ + int *ip = m_pBase[line]; + int c; + for( ; *ip; ip++ ){ + c = *ip & 0x0000ffff; + if( c == '\r' ){ + as += '\r'; + as += '\n'; + } + else if( c >= 0x100 ){ + as += char(c>>8); + as += char(c); + } + else { + as += char(c); + } + } +} + +void __fastcall CDump::WriteLine(int line) +{ + if( !m_wfp ) return; + + int *ip = m_pBase[line]; + int c; + for( ; *ip; ip++ ){ + c = *ip & 0x0000ffff; + if( c == '\r' ){ + fputc('\r', m_wfp); + fputc('\n', m_wfp); + } + else if( c >= 0x100 ){ + fputc(c>>8, m_wfp); + fputc(c&0x00ff, m_wfp); + } + else { + fputc(c, m_wfp); + } + } +} + +void __fastcall CDump::PutScroll(void) +{ + if( m_wfp ) WriteLine(m_WLine); + m_WCol = 0; + m_X = 0; + m_WLine++; + if( m_WLine >= m_StgLineMax ){ + m_WLine--; + MemScroll(); + } + if( m_fLastCP ){ + m_MLine = m_WLine; m_MCol = m_WCol; + } + m_Y += m_FontYW; + if( m_WLine >= m_ScreenLineMax ){ + m_Y -= m_FontYW; + if( m_fWindow ){ + m_DTop++; + if( m_DTop >= (m_StgLineMax - m_ScreenLineMax + 1) ){ + m_DTop--; + } + m_RY = (m_RLine - m_DTop) * m_FontYW; + Paint(); + } + } + SetScrollBar(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetScrollBar(void) +{ + if( !m_pScrollBar ) return; + + int max = m_MLine - m_ScreenLineMax + 1; + if( max < 0 ) max = 0; + m_fDisEvent++; + m_pScrollBar->SetParams(m_DTop, 0, max); + m_pScrollBar->Enabled = (m_MLine >= m_ScreenLineMax); + m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop)); + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); + m_fDisEvent--; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::OnScrollBarChange(void) +{ + if( !m_pScrollBar ) return; + if( m_fDisEvent ) return; + + if( m_DTop != m_pScrollBar->Position ){ + m_DTop = m_pScrollBar->Position; + m_Y = (m_WLine - m_DTop) * m_FontYW; + m_RY = (m_RLine - m_DTop) * m_FontYW; + m_fWindow = (m_WLine >= m_DTop) && (m_WLine < (m_ScreenLineMax + m_DTop)); + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); + Paint(); + } +} +//--------------------------------------------------------------------------- +void CALLBACK TimeProc(UINT IDEvent, UINT uReserved, DWORD dwUser, DWORD dwReserved1, DWORD dwReserved2) +{ + if( !dwUser ) return; + + CDump *pDump = (CDump *)dwUser; + pDump->OnTimer(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::OnTimer(void) +{ + BOOL f = FALSE; +// Application->MainForm->Caption = m_MouseWheelCount; + if( m_MouseWheelCount ){ + m_MouseWheelCount -= 3; + if( m_MouseWheelCount > 0 ){ + f = TRUE; + } + else { + m_MouseWheelCount = 0; + } + } + return f; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::OnMouseWheel(int z) +{ + if( !m_pScrollBar ) return FALSE; + if( !m_pScrollBar->Enabled ) return FALSE; + + + m_MouseWheelCount++; + if( m_MouseWheelCount > 6 ) m_MouseWheelCount = 6; + int div = 120; + if( m_MouseWheelCount >= 6 ){ + div = 20; + } + else if( m_MouseWheelCount >= 4 ){ + div = 30; + } + else if( m_MouseWheelCount >= 2 ){ + div = 60; + } + z /= div; + DoWheel(z); + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DoWheel(int z) +{ + while( z ){ + if( z > 0 ){ + if( m_pScrollBar->Position ){ + m_pScrollBar->Position--; + } + else { + break; + } + z--; + } + else { + if( m_pScrollBar->Position < m_pScrollBar->Max ){ + m_pScrollBar->Position++; + } + else { + break; + } + z++; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::Clear(void) +{ + Cursor(FALSE); + m_fLastCP = TRUE; + m_MLine = m_WLine = m_WCol = m_DTop = 0; + m_MCol = m_RLine = m_RCol = 0; + m_X = m_Y = 0; + m_RX = m_RY = 0; + m_fKanji = FALSE; + m_fWindow = TRUE; + m_fCR = FALSE; + m_CRCount = 0; + + m_fSelText = FALSE; + m_fSelect = FALSE; + m_SLine = m_SCol = 0; + + for( int i = 0; i < m_StgLineMax; i++ ){ + *m_pBase[i] = 0; + } + SetScrollBar(); + SetCursorPos(); + Paint(); +// Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DeleteCR2(void) +{ + for( int i = 0; i < m_MLine; i++ ){ + int *ip = m_pBase[i]; + for( ; *ip; ip++ ){ + if( ((*ip & 0x0000ffff) == '\r') && (*(ip+1) & 0x0000ffff) ){ + int *rp = ip; + for( ; *rp; rp++ ){ + *rp = *(rp+1); + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DeleteChar(BOOL fForce) +{ + if( !fForce && !CanEdit() ) return; + + if( m_fSelText ){ + DeleteSelText(); + Invalidate(); + return; + } + if( m_fLastCP ) return; + Cursor(FALSE); + int *bp = CreateContP(m_WLine, m_WCol, 0); + CloseContP(m_WLine, m_WCol, bp, 1); + SetScrollBar(); + Invalidate(); + Cursor(TRUE); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::CanEdit(void) +{ + if( m_fSelText ){ + if( m_RLine > m_SLine ) return FALSE; + if( (m_RLine == m_SLine) && (m_RCol > m_SCol) ) return FALSE; + } + if( m_RLine == m_WLine ){ + if( m_RCol <= m_WCol ) return TRUE; + } + else if( m_RLine < m_WLine ){ + return TRUE; + } + return FALSE; +} +//--------------------------------------------------------------------------- +// 連続データを作成する +int *__fastcall CDump::CreateContP(int line, int col, int add) +{ + int SLine = m_MLine - line + 1; + int *bp = new int[DUMPCOLMAX*SLine + add + 1]; + int *wp = bp; + wp += add; + int *ip = m_pBase[line] + col; + while(line <= m_MLine){ + while(*ip){ + *wp++ = *ip++; + } + line++; + ip = m_pBase[line]; + } + *wp = 0; + return bp; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DupeText(int col) +{ + if( !m_WLine ) return; + if( !CanEdit() ) return; + + int bf[DUMPCOLMAX+1]; + memcpy(bf, m_pBase[m_WLine-1], sizeof(int)*DUMPCOLMAX); + int *ip = bf; + for( ; *ip; ip++ ){ + PutChar(*ip & 0x0000ffff, col); + } +} +//--------------------------------------------------------------------------- +// 連続データを設定する +void __fastcall CDump::CloseContP(int line, int col, int *bp, int offset) +{ + int cc = 0; + int x = 0; + int *ip = m_pBase[line]; + for( ; *ip && (cc < col); ip++, cc++ ){ + x += CharWidth(*ip); + } + int *wp = bp + offset; + if( !*bp ) wp = bp; + m_MCol = col; + while(*wp && (line < m_StgLineMax)){ + int cc = *wp++; + *ip++ = cc; + m_MCol++; + x += CharWidth(cc); + if( (cc & 0x0000ffff) == '\r' ){ + m_MCol = 0; + x = 0; + *ip = 0; + line++; + ip = m_pBase[line]; + } + else if( (x >= (m_ScreenXW - 32)) || (((cc&0x0000ffff)==' ') && (x >= m_ScreenLXW)) ){ + m_MCol = 0; + x = 0; + *ip = 0; + line++; + ip = m_pBase[line]; + } + } +// if( m_MCol ) *ip = 0; + *ip = 0; + delete bp; + m_MLine = line; + if( m_MLine >= m_StgLineMax ) m_MLine = m_StgLineMax - 1; + ip = m_pBase[m_MLine] + m_MCol; + *ip = 0; + + if( m_MLine < (m_DTop + m_ScreenLineMax - 1) ){ + m_DTop = m_MLine - m_ScreenLineMax + 1; + if( m_DTop < 0 ) m_DTop = 0; + m_Y = (m_WLine - m_DTop) * m_FontYW; + m_RY = (m_RLine - m_DTop) * m_FontYW; + SetCursorPos(); + } + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::InsChar(int c, int col) +{ + if( !CanEdit() ) return; + + if( m_MLine >= (m_StgLineMax - 1) ){ // 1行の余裕を作る + if( !m_WLine ) return; + MemScroll(); + if( m_WLine ) m_WLine--; + if( m_DTop ) m_DTop--; + m_MLine--; + + } + + int *bp = CreateContP(m_WLine, m_WCol, 1); + *bp = c | (col << 16); + CloseContP(m_WLine, m_WCol, bp, 0); + + m_X += CharWidth(c); + m_WCol++; + if( ((c & 0x0000ffff) == '\r') || (m_X >= m_ScreenXW - 32) ){ + m_X = 0; + m_WCol = 0; + m_WLine++; + m_Y += m_FontYW; + } + if( (m_Y >= m_ScreenYW) || ((m_WLine - m_DTop) >= m_ScreenLineMax) ){ + m_DTop++; + m_Y -= m_FontYW; + m_RY = (m_RLine - m_DTop) * m_FontYW; + } + m_fLastCP = (m_WLine == m_MLine) && (m_WCol == m_MCol); + SetScrollBar(); + Invalidate(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::PutChar(int c, int col) +{ + BOOL r = FALSE; + + if( m_pMBCS && m_fConvAlpha ) c = m_pMBCS->ConvAlpha(c); + if( m_fSelText ) ClearSelect(TRUE); + Cursor(FALSE); + if( (c == '\r') || (c == '\n') ){ + if( ((c == '\r') || !m_fCR) && (m_CRCount < DUMPCRLIMIT) ){ + if( m_fLastCP ){ + m_CRCount++; + int *ip = m_pBase[m_WLine] + m_WCol; + *ip++ = ('\r' | (col << 16)); + *ip = 0; + PutScroll(); + } + else { + InsChar(('\r' | (col << 16)), col); + } + } + m_fCR = (c == '\r') ? TRUE : FALSE; + r = TRUE; + } + else if( c == '\t' ){ + m_CRCount = 0; + int ax = m_FontXW*4; + int xx = m_X + ax; + xx = xx - (xx % ax); + while(m_X < xx){ + ax = m_X; + PutChar(' ', col); + if( ax >= m_X ) break; + } + m_fCR = FALSE; + r = TRUE; + } + else if( c == '\b' ){ + m_CRCount = 0; + r = BackSpace(); + m_fCR = FALSE; + } +// else if( (c >= 0x0020) || (m_fShowCtrlCode && c) ){ + else if( c ){ + m_CRCount = 0; + if( c < 0x0020 ) col = 3; + m_fCR = FALSE; + if( c ){ + int *ip = m_pBase[m_WLine] + m_WCol; + c = c | (col << 16); + if( m_fLastCP ){ + *ip++ = c; + *ip = 0; + m_X = DrawChar(m_X, m_Y, c, m_fWindow); + m_WCol++; + if( (m_X >= (m_ScreenXW - 32) ) || (m_WCol >= DUMPCOLMAX) ){ + PutScroll(); + } + else if( ((c & 0xffff) == ' ') && (m_X >= m_ScreenLXW) ){ + PutScroll(); + } + } + else if( CanEdit() ){ + InsChar(c, col); + } + } + r = TRUE; + } + if( m_fLastCP ){ + m_MLine = m_WLine; m_MCol = m_WCol; + } + SetCursorPos(); + Cursor(TRUE); + return r; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::PutKey(char c, int col) +{ + BOOL r = FALSE; + int key = BYTE(c); + if( m_fKanji ){ + m_fKanji += key; + r = PutChar(m_fKanji, col); + m_fKanji = 0; + } + else if( m_pMBCS ){ + if( m_pMBCS->IsLead(c) ){ + m_fKanji = key << 8; + } + else { + r = PutChar(key, col); + } + } + else { + if( _mbsbtype((unsigned char *)&key, 0) == _MBC_LEAD ){ + m_fKanji = key << 8; + } + else { + r = PutChar(key, col); + } + } + return r; +} +//--------------------------------------------------------------------------- +void CDump::PutStatus(int col, LPCSTR pFmt, ...) +{ + va_list pp; + char bf[1024]; + va_start(pp, pFmt); + vsprintf( bf, pFmt, pp ); + va_end(pp); + + if( !bf[0] ) return; + + if( m_WCol ){ +// Cursor(FALSE); +// PutScroll(); + PutChar('\r', col); + } + LPCSTR p = bf; + for( ; *p; p++ ){ + PutKey(*p, col); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::BackSpace(void) +{ + Cursor(FALSE); + BOOL r = FALSE; + if( m_WCol ){ + m_WCol--; + int *ip = m_pBase[m_WLine] + m_WCol; + int xw = CharWidth(*ip); + m_X -= xw; + if( m_fWindow ){ + TRect rc; + rc.Left = m_X; rc.Top = m_Y; + rc.Right = m_X + xw; rc.Bottom = m_Y + m_FontYW; + m_pCanvas->Brush->Color = m_Color[0].c; + m_pCanvas->FillRect(rc); + } + if( m_fLastCP ){ + *ip = 0; + } + else { + for( ; *ip; ip++ ){ + *ip = *(ip+1); + if( !*ip ) break; + } + Invalidate(); + } + r = TRUE; + } + else if( m_WLine ){ + if( m_fLastCP ){ + if( m_CRCount ) m_CRCount--; + m_WLine--; + if( m_WLine >= (m_ScreenLineMax - 1) ){ + m_DTop = m_WLine - m_ScreenLineMax + 1; + m_Y = (m_WLine - m_DTop) * m_FontYW; + m_RY = (m_RLine - m_DTop) * m_FontYW; + } + else { + m_Y -= m_FontYW; + } + int *ip = m_pBase[m_WLine]; + m_X = 0; + for( ; *ip; ip++ ){ + m_X += CharWidth(*ip); + m_WCol++; + } + if( m_WCol ){ + ip--; + m_X -= CharWidth(*ip); + m_WCol--; + *ip = 0; + } + Invalidate(); + SetScrollBar(); + } + else { + MoveCursor(VK_LEFT); + DeleteChar(TRUE); + } + } + SetCursorPos(); + FollowRP(); + Cursor(TRUE); + return r; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::Invalidate(void) +{ + if( m_pPaintBox ) m_pPaintBox->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::Paint(void) +{ + if( !m_hWnd ) return; + + Cursor(FALSE); + TColor cBack = m_fWindow ? m_Color[0].c : m_Color[4].c; + if( m_pPanel && (m_Color[0].c != m_Color[4].c) ){ + m_pPanel->Color = cBack; + } + m_pCanvas->Brush->Color = cBack; + int i; + for( i = 0; i < m_ScreenLineMax; i++ ){ + int n = i + m_DTop; + TRect rc; + rc.Left = 0; rc.Right = m_ScreenXW; + rc.Top = i * m_FontYW; + rc.Bottom = rc.Top + m_FontYW; + m_pCanvas->FillRect(rc); + if( (n <= m_MLine) && (n < m_StgLineMax) ){ + int *ip = m_pBase[n]; + int x = 0; + while(*ip){ + if( (*ip & 0x0000ffff) != '\r' ){ + x = DrawChar(x, rc.Top, *ip++, TRUE); + } + else { + ip++; + } + } + } + } + Cursor(TRUE); +} +//--------------------------------------------------------------------------- +static int __fastcall GetCharLength(int *ip) +{ + int n = 0; + for( ; *ip; ip++ ) n++; + return n; +} +//--------------------------------------------------------------------------- +int __fastcall CDump::GetCharCount(BOOL fTX) +{ + int line; + int *ip; + if( fTX ){ + if( m_WLine < m_RLine ) return 0; + if( m_WLine == m_RLine ) return m_WCol - m_RCol; + line = m_RLine; + ip = m_pBase[line++] + m_RCol; + } + else { + if( !m_WLine ) return m_WCol; + line = 0; + ip = m_pBase[line++]; + } + int n = GetCharLength(ip); + while( m_WLine >= line ){ + ip = m_pBase[line++]; + n += GetCharLength(ip); + } + return n; +} +//--------------------------------------------------------------------------- +int __fastcall CDump::GetChar(BOOL fDraw) +{ + int r; + if( m_fSelText ){ + if( m_RLine > m_SLine ) return -1; + if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return -1; + } + if( (m_WLine > m_RLine) || (m_WCol > m_RCol) ){ + int *ip = m_pBase[m_RLine] + m_RCol; + r = *ip; + m_RCol++; + if( !r ){ + m_RX = 0; + m_RCol = 0; + m_RLine++; + if( m_RLine >= m_StgLineMax ) m_RLine--; + r = -1; + } + else { // Color change + m_RY = (m_RLine - m_DTop) * m_FontYW; + r &= 0x0000ffff; + *ip = r | (2<<16); + m_RX = DrawChar(m_RX, m_RY, *ip, m_fWindow && fDraw); + } + } + else { + r = -1; + } + return r; +} +//--------------------------------------------------------------------------- +int __fastcall CDump::IsWord(void) +{ + int r = TRUE; + if( m_fSelText ){ + if( m_RLine > m_SLine ) return TRUE; + if( (m_RLine == m_SLine) && (m_RCol >= m_SCol) ) return TRUE; + } + if( m_WLine > m_RLine ){ + return TRUE; + } + else if( (m_WLine == m_RLine) || (m_WCol > m_RCol) ){ + int *ip = m_pBase[m_RLine] + m_RCol; + r = *ip; + if( !r ){ + r = TRUE; + } + else if( (r & 0x0000ff00) == 0x0100 ){ + r = TRUE; + } + else { + r = FALSE; + int d; + for( ; *ip; ip++ ){ + d = *ip & 0x0000ffff; + if( (d == ' ') || (d == '\r') ) r = TRUE; + } + } + } + return r; +} +//--------------------------------------------------------------------------- +int __fastcall CDump::GetCharNB(void) +{ + int r; + if( (m_WLine > m_RLine) || (m_WCol > m_RCol) ){ + int *ip = m_pBase[m_RLine] + m_RCol; + if( *ip ){ + r = *ip & 0x0000ffff; + } + else { + r = -1; + } + } + else { + r = -1; + } + return r; +} +//--------------------------------------------------------------------------- +static int __fastcall JisType(int c) +{ + if( c <= 0x0100 ){ + return 0; + } + else if( c < 0x8140 ){ + return -1; + } + else if( c == 0x815b ){ // ー + return 3; + } + else if( (c >= 0x8395) && (c <= 0x8396) ){ // カケ + return 4; + } + else if( (c >= 0x824f) && (c <= 0x8258) ){ + return 6; // suuji + } + else if( (c >= 0x829f) && (c <= 0x82f2) ){ // hiragana + return 2; + } + else if( (c >= 0x8340) && (c <= 0x8396) ){ // katakana + return 3; + } + else if( c >= 0x8840 ){ // kanji + return 4; + } + else if( c <= 0x82ff ){ + return 5; // kugiri + } + else { + return 1; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::IsSpace(int c, int ci) +{ + c &= 0x0000ffff; + if( c == ' ' ) return TRUE; + if( ci >= 0x8140 ){ // 初回がShift-JISの場合 + c = JisType(c); + if( (c == 5)||(c == -1) ) return TRUE; + return (c != JisType(ci)); + } + else { // 初回が英数の場合 + if( c == '/' ) return FALSE; + if( c >= 0x100 ) return TRUE; + return !isalnum(c); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::ClearAllSelect(BOOL fPaint) +{ + BOOL f = FALSE; + int i; + int *ip; + for( i = 0; i < m_StgLineMax; i++ ){ + ip = m_pBase[i]; + for( ; *ip; ip++ ){ + if( *ip & 0x80000000 ){ + f = TRUE; + *ip &= 0x7fffffff; + } + } + } + if( fPaint && f ){ + Invalidate(); + } + m_fSelText = FALSE; + return f; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::GetWindowCallsign(AnsiString &as) +{ + AnsiString MyCall = ClipCall(sys.m_CallSign.c_str()); + as = ""; + int line; + for( line = m_WLine; line >= 0; line-- ){ + int *bp = m_pBase[line]; + int *ip = bp; + if( (*ip & 0xffff0000)==0x00020000 ){ // 送信文字 + break; + } + int n = 0; + char bf[256]; + for( ; *ip; ip++ ){ + int c = *ip & 0x0000fff; + if( (c == ' ') || (c == '\r') ){ + bf[n] = 0; + if( (n >= 3) && IsCall(bf) && strcmpi(ClipCall(bf), MyCall.c_str()) ){ + jstrupr(bf); + as = bf; + } + n = 0; + } + else if( (c >= 0x100) || (!isalpha(c) && !isdigit(c) && (c != '/')) ){ + n = 0; + } + else { + bf[n++] = char(c); + if( n >= 250 ) n = 0; + } + } + if( !as.IsEmpty() ) break; + } + return !as.IsEmpty(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CDump::IsWindowText(LPCSTR pText) +{ + int line; + for( line = m_WLine; line >= m_FLine; line-- ){ + int *bp = m_pBase[line]; + int *ip = bp; + if( (*ip & 0xffff0000)==0x00020000 ){ // 送信文字 + break; + } + AnsiString as; + WriteLine(as, line); + if( strstr(as.c_str(), pText) ) return TRUE; + } + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::GetWindowText(AnsiString &as) +{ + as = ""; + for( int i = 0; i <= m_MLine; i++ ){ + WriteLine(as, i); + } +} +//--------------------------------------------------------------------------- +int __fastcall CDump::GetWindowText(AnsiString &as, int SX, int SY) +{ + m_SMX = SX; + as = ""; + int line = SY/m_FontYW + m_DTop; + if( line > m_WLine ) return FALSE; + + m_SML = line; + int *bp = m_pBase[line]; + int *ip = bp; + int x; + for( x = 0; *ip; ip++ ){ + x += CharWidth(*ip); + if( x >= SX ) break; + } + if( !*ip ) return FALSE; + int ci = *ip & 0x0000ffff; + if( m_fRTTY ){ + if( ci == ' ' ) return FALSE; + } + else if( m_pFont->Charset != SHIFTJIS_CHARSET ){ + if( IsSpace(ci, 'A') ) return FALSE; + } + else if( IsSpace(ci, ci) ){ + return FALSE; + } + /* スペースを探す */ + for( ip--; ip >= bp; ip-- ){ + if( IsSpace(*ip, ci) ){ + ip++; + break; + } + } + if( ip < bp ) ip = bp; + /* スペースまでコピー */ + int c; + for( ; *ip; ip++ ){ + if( IsSpace(*ip, ci) ) break; + c = *ip & 0x0000ffff; + if( c >= 0x0100 ){ + as += char(c>>8); + as += char(c); + } + else { + as += char(c); + } + *ip |= 0x80000000; + } + return (ci > 0x0100) ? JisType(ci)+1 : 1; +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SwapLTR(void) +{ + if( (m_SML < 0) || (m_SML > m_WLine) ) return; + + CRTTY rtty; + + int *bp = m_pBase[m_SML]; + int *ip = bp; + int x; + for( x = 0; *ip; ip++ ){ + x += CharWidth(*ip); + if( x >= m_SMX ) break; + } + if( !*ip ) return; + int ci = *ip & 0x0000ffff; + if( ci == ' ' ) return; + + /* スペースを探す */ + for( ip--; ip >= bp; ip-- ){ + if( (*ip & 0x0000ffff) == ' ' ){ + ip++; + break; + } + } + if( ip < bp ) ip = bp; + /* スペースまでコピー */ + int c; + for( ; *ip; ip++ ){ + if( (*ip & 0x0000ffff) == ' ' ) break; + c = *ip & 0x0000ffff; + if( (c >= 0x20) && (c <= 0x7f) ){ + c = rtty.InvShift(char(c)); + *ip = (*ip & 0xffff0000) | c; + } + *ip |= 0x80000000; + } + Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetCursorPos(void) +{ + if( !m_fActive ) return; + + if( m_CursorType == csCARET ){ + SetCaretPos(m_X, m_Y); + SetCompositionWindowPos(FALSE); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::DrawCursor(int x, int y, int sw) +{ + TRect rc; + rc.Left = x; rc.Top = y + m_FontYW - 2; + rc.Right = x + m_FontXW; rc.Bottom = y + m_FontYW; + m_pCanvas->Brush->Color = sw ? m_CursorColor : m_Color[0].c; + m_pCanvas->FillRect(rc); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetCursorType(int type) +{ + Cursor(FALSE); + m_CursorType = type; + Cursor(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall CDump::Cursor(int sw) +{ + if( sw && !m_fWindow ) return; + + switch(m_CursorType){ + case csCARET: // キャレットを使ったカーソル + if( sw ){ + if( !m_fActive ) return; + + if( !m_Cursor ){ + m_Cursor++; + ShowCaret(m_hWnd); + } + } + else { + if( m_Cursor ){ + m_Cursor--; + HideCaret(m_hWnd); + } + } + break; + case csSTATIC: // 描画カーソル + if( sw ){ + DrawCursor(m_X, m_Y, TRUE); + } + else { + DrawCursor(m_X, m_Y, FALSE); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::CreateCaret(void) +{ + if( m_fActive ) return; + m_fActive = TRUE; + + if( m_CursorType == csCARET ){ + ::CreateCaret(m_hWnd, 0, 2, m_FontYW); + ::SetCaretPos(m_X, m_Y); + ::ShowCaret(m_hWnd); + m_Cursor = TRUE; + SetCompositionWindowPos(TRUE); + } +} + +//--------------------------------------------------------------------------- +void __fastcall CDump::DestroyCaret(void) +{ + if( !m_fActive ) return; + m_fActive = FALSE; + + if( m_CursorType == csCARET ){ + m_Cursor = 0; + ::DestroyCaret(); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::SetCompositionWindowPos(BOOL fFont) +{ + if( !m_fActive ) return; + + HIMC hIMC; + COMPOSITIONFORM Composition; + + if( (hIMC = ::ImmGetContext(m_hWnd))!=NULL ){ + if( fFont ){ + ::ImmSetCompositionFont(hIMC, &m_LogFont); + } + Composition.dwStyle = CFS_POINT; + Composition.ptCurrentPos.x = m_X; + Composition.ptCurrentPos.y = m_Y; + ::ImmSetCompositionWindow(hIMC, &Composition); + + ::ImmReleaseContext(m_hWnd, hIMC); + } +} +//--------------------------------------------------------------------------- +void __fastcall CDump::ShowCtrl(BOOL f) +{ + m_fShowCtrlCode = f; + if( m_pPaintBox ) m_pPaintBox->Invalidate(); +} +#pragma package(smart_init) diff --git a/Dump.h b/Dump.h new file mode 100644 index 0000000..adaf6ff --- /dev/null +++ b/Dump.h @@ -0,0 +1,216 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef DumpH +#define DumpH + +#include "stdio.h" +#include "ComLib.h" +//--------------------------------------------------------------------------- +#define DUMPCOLMAX 160 +#define DUMPCRLIMIT 4 +enum { + csNONE, + csCARET, + csSTATIC, +}; +enum { + dmpMoveTOP=0x1000, + dmpMoveLAST, +}; +//--------------------------------------------------------------------------- +class CDump +{ +private: + int **m_pBase; + + TRect m_rcScreen; + BOOL m_fDisEvent; + + int m_ScreenLineMax; + int m_ScreenColMax; + int m_StgLineMax; +// int m_StgColMax; + int m_FontYW; + int m_FontXW; + + BOOL m_fLastCP; + int m_MLine; // 現在の最終行数 + int m_MCol; // 現愛の最終桁 + + int m_WTop; + int m_WLine; + int m_WCol; + + int m_DTop; + int m_X; + int m_Y; + + int m_RLine; + int m_RCol; + int m_RX; + int m_RY; + + int m_fSelText; + int m_fSelect; + int m_SLine; + int m_SCol; + + int m_FLine; + + BOOL m_fWindow; + + char m_Buffer[16]; + + int m_CursorType; + int m_Cursor; + + BOOL m_fKanji; + BOOL m_fCR; + BOOL m_fActive; + int m_CRCount; + + FILE *m_wfp; + + UINT m_nTimerID; + int m_MouseWheelCount; + + BOOL m_fShowCtrlCode; + + BOOL m_fRTTY; + int m_SMX, m_SML; +public: + UCOL m_Color[5]; + TColor m_CursorColor; + BOOL m_fConvAlpha; +private: + HWND m_hWnd; + TPanel *m_pPanel; + TFont *m_pFont; + TCanvas *m_pCanvas; + TPaintBox *m_pPaintBox; + TScrollBar *m_pScrollBar; + CMBCS *m_pMBCS; + int m_ScreenXW; + int m_ScreenYW; + int m_ScreenLXW; + LOGFONT m_LogFont; +private: + void __fastcall DeleteStg(void); + void __fastcall SetBuffer(int c); + int __fastcall CharWidth(int c); + void __fastcall MemScroll(void); + void __fastcall WriteLine(AnsiString &as, int line); + void __fastcall WriteLine(int line); + void __fastcall PutScroll(void); + int __fastcall DrawChar(int x, int y, int c, BOOL f); + void __fastcall DrawCursor(int x, int y, int sw); + void __fastcall SetCursorPos(void); + void __fastcall FollowRP(void); + BOOL __fastcall BackSpace(void); + void __fastcall InsChar(int c, int col); + void __fastcall DeleteCR2(void); + void __fastcall SetCompositionWindowPos(BOOL fFont); + void __fastcall DeleteChar(BOOL fForce); + void __fastcall DoWheel(int z); + BOOL __fastcall IsSpace(int c, int ci); + + int *__fastcall CreateContP(int line, int col, int add); + void __fastcall CloseContP(int line, int col, int *bp, int offset); + +public: + __fastcall CDump(void); + __fastcall ~CDump(); + void __fastcall Create(HWND hWnd, TPanel *pPanel, TPaintBox *pPaintBox, TFont *pFont, TScrollBar *pBar, int line); + BOOL __fastcall PutChar(int c, int col); + BOOL __fastcall PutKey(char c, int col); + void PutStatus(int col, LPCSTR pFmt, ...); + int __fastcall GetCharCount(BOOL fTX); + int __fastcall GetChar(BOOL fDraw); + int __fastcall GetCharNB(void); + void __fastcall Clear(void); + void __fastcall Paint(void); + void __fastcall SetFont(TFont *pFont); + void __fastcall Resize(void); + void __fastcall SetScrollBar(void); + void __fastcall OnScrollBarChange(void); + BOOL __fastcall OnTimer(void); + BOOL __fastcall OnMouseWheel(int z); + void __fastcall SetCursorType(int type); + void __fastcall Cursor(int sw); + void __fastcall CreateCaret(void); + void __fastcall DestroyCaret(void); + void __fastcall MoveCursor(int Key); + void __fastcall MoveCursor(int SX, int SY, BOOL fDown); + inline __fastcall DeleteChar(void){DeleteChar(FALSE);}; + BOOL __fastcall CanEdit(void); + + BOOL __fastcall ClearAllSelect(BOOL fPaint); + BOOL __fastcall IsWindowText(LPCSTR pText); + BOOL __fastcall GetWindowCallsign(AnsiString &as); + void __fastcall GetWindowText(AnsiString &as); + int __fastcall GetWindowText(AnsiString &as, int SX, int SY); + + void __fastcall OpenLogFile(LPCSTR pName); + void __fastcall CloseLogFile(void); + inline __fastcall IsLogging(void){return m_wfp != NULL;}; + void __fastcall FlushLogFile(void); + + void __fastcall DupeText(int col); + + void __fastcall OpenSelect(void); + void __fastcall CloseSelect(void); + void __fastcall UpdateSelect(void); + BOOL __fastcall ClearSelect(BOOL fPaint); + BOOL __fastcall GetSelText(AnsiString &as); + BOOL __fastcall DeleteSelText(void); + inline __fastcall IsSelText(void){return m_fSelText;}; + void __fastcall Invalidate(void); + void __fastcall SwapLTR(void); + + inline int __fastcall GetScreenLine(void){return m_ScreenLineMax;}; + inline void __fastcall GetCursorPos(int &x, int &y){ + x = m_X; y = m_Y; + }; + inline BOOL __fastcall IsCursorLast(void){return m_fLastCP;}; + + inline int __fastcall GetWindowSize(void){ + return (m_ScreenYW << 16) + m_ScreenXW; + } + inline LOGFONT *__fastcall GetLogFontP(void){return &m_LogFont;}; + inline BOOL __fastcall IsCreate(void){return m_hWnd != NULL;}; + inline BOOL __fastcall IsPrinted(void){return m_WLine + m_WCol;}; + inline void __fastcall SetMBCS(CMBCS *pMBCS){ m_pMBCS = pMBCS;}; + inline void __fastcall SetRTTY(BOOL f){m_fRTTY = f;}; + int __fastcall IsWord(void); + void __fastcall ShowCtrl(BOOL f); + + inline void __fastcall UpdateCaptureLimit(void){ + m_FLine = m_WLine; + }; + inline void __fastcall ClearCaptureLimit(void){ + m_FLine = 0; + } + inline BOOL __fastcall IsActive(void){return m_fActive;}; +#if DEBUG + void __fastcall Debug(LPSTR t); +#endif +}; +#endif diff --git a/EHISTORY.TXT b/EHISTORY.TXT new file mode 100644 index 0000000..6be0c24 --- /dev/null +++ b/EHISTORY.TXT @@ -0,0 +1,304 @@ +======================== +BetaVer0.45 2010/OCT/04 +======================== +- Added mfsk4, mfsk8, mfsk32, mfsk64, mfsk11, and mfsk22 modes +- Improved the decoder of the qpsk mode +- Added an option that restores the subchannel window status on a start up +- Enhanced macro +- Applied minor updates + +======================== +BetaVer0.44 2010/SEP/24 +======================== +- Added QPSK mode +- Added a RTTY demodulator based on FFT +- Added the FSK support (TNX to JA7UDE) + When a COM port is selected, the MMVARI internally controls the FSK keying. When EXTFSK is selected, EXTFSK generates the FSK keying. MMVARI and EXTFSK use Windows' multimedia timer so that they might have 1msec jitter. +- Added the English web site URL. +- Updated the JARTS web site URL. +- Added the selection of COM8 to COM16. +- Added the rig control menu. +- Updated the sound device selection. + +======================== +BetaVer0.42 2007/JAN/15 +======================== +- Deleted the start-up warning message in the English environment + +======================== +BetaVer0.41 2005/MAR/20 +======================== +- Enabled the TX capability in the BPSK-VariJA (MBCS) mode (Tnx to JE4IVN) +- Fixed typo in the English mode +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.40 2005/JAN/08 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.39 2004/NOV/06 +======================== +- Improved the gateway to Turbo Hamlog/Win version 5 + +======================== +BetaVer0.38 2004/NOV/03 +======================== +- Added a gateway to Turbo Hamlog/Win version 5 (Tnx to JG1MOU) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.37 2004/OCT/08 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.36 2004/SEP/30 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.35 2004/SEP/22 +======================== +- Expanded the macro capability +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.34 2004/SEP/11 +======================== +- Added event macros (e.g. OnPTT, OnQSO, OnStart) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.33 2004/SEP/08 +======================== +- Improved the AFC for GMSK/PSK +- Added OnTimer event macro +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.32 2004/SEP/04 +======================== +- Improved the decimation speed +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.31 2004/AUG/28 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.30 2004/AUG/15 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.29 2004/AUG/09 +======================== +- Fixed an inexcusable bug and applied some improvements + +======================== +BetaVer0.28 2004/AUG/07 +======================== +- Fixed a bug that disables RX after TX in the RTTY mode +- Added the sound play back option +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.27 2004/AUG/03 +======================== +- Improved mfsk decoder (synchronization, AFC, processing speed, etc.) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.26 2004/JUL/31 +======================== +- Added mfsk mode +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.25 2004/JUL/27 +======================== +- Added Expansion Macro Buttons (View menu) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.24 2004/JUL/22 +======================== +- Expanded the macro capability + Added <%Menu=...> command + Supported Kenwood and JST245 in <%RadioKHz=...> command + Added <%RadioMode=...> command +* For detailed information, refer to the pop-up menu and rig control sections in EMMVARI.TXT. +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.23 2004/JUL/19 +======================== +- Fixed a bug in the AFC detection level calculation +- Added a macro for the rig frequency control +* Three types of macros are now included + <%RadioKHz=YAESU-HF,14073.000> FT1000MP, FT920, etc... + <%RadioKHz=YAESU-VU,14073.000> FT847, FT736, etc... + <%RadioKHz=CI-V,14073.000> ICOM + Example: 500Hz up + <%RadioKHz=YAESU-VU,<%RadioKHz>+0.5> +- Fixed a couple of bugs and applied some improvements + + +======================== +BetaVer0.22 2004/JUL/14 +======================== +- Improved AFC +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.21 2004/JUN/29 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.20 2004/JUN/28 +======================== +- Added several functions to the spectrum right click operation +- Improved the synchronizing scheme for the off-clock signals +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.19 2004/JUN/26 +======================== +- Added notch filter (right click on the spectrum scope window) +- Improved BPF +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.18 2004/JUN/12 +======================== +- Added rtty mode +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.17 2004/JUN/04 +======================== +- Expanded the macro capability +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.16 2004/MAR/20 +======================== +- Added MMTTY/MMSSTV custom sound +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.15 2004/MAR/02 +======================== +- Made the color mapping of the waterfall user-customizable +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.14 2004/FEB/28 +======================== +- Added an automatic TX alphabet character conversion (from two-byte alphabet code to single-byte) +- Added 22050, 44100, 48000Hz sound clock frequencies + +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.13 2004/FEB/22 +======================== +- Fixed a bug that disabled the Kana transmission in the VariSTD/JA mode +- User can customize the background color of the RX window +- Added a pop-up menu in response to the right click on the RX window +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.12 2004/FEB/18 +======================== +- Fixed an exposure happening on some PCs +- Added the 6000Hz clock frequency support for the sound device +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.11 2004/FEB/15 +======================== +- Fixed an exposure happening on some PCs (?) +- Expanded the macro capability +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.10 2004/FEB/12 +======================== +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.09 2004/FEB/09 +======================== +- Added BPSK and bpsk mode + BPSK - Not compatible with HALPSK or WINPSK/J (TX is inhibited on VariJA) + bpsk - Conventional standard varicode compatible with HALPSK and WINPSK/J (BPSK/bpsk have not been tested yet) +- Added amplitude monitor windows for the debug of BPSK modulation. Right click on the Sync button to activate it. +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.08 2004/FEB/04 +======================== +- Improved the TX window editing +- Expanded the macro capability +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.07 2004/JAN/27 +======================== +- Fixed a bug of the PTT control in RadioCommand +- Added FSK modulation (fm=1.0) for V/UHF to accommodate the rig frequency drift +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.06 2004/JAN/23 +======================== +- Added q tool for calibrating the soundcard +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.05 2004/JAN/21 +======================== +- Added English menu and messages (Tnx Kim HL3IB and Sung HL1AQ) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer0.04 2004/JAN/19 +======================== +- Included EProject.txt in the MMVARI package(Tnx JA7UDE) +- Fixed a couple of bugs and applied some improvements + +======================== +BetaVer 0.03 2004/JAN/15 +======================== +- Changed the program name from MMGMSK to MMVARI (the modulation is subject +to change) +- Changed the index mapping for Japanese font ($E040-$FEFF is remapped to +$A040-$BEFF) +- Added an option that allows the user to change TX and TXOFF keys. +- Fixed some bugs and applied minor improvements. + +======================== +BetaVer0.02 +======================== +- Added sound record and replay functions. +- Added RadioCommand. +- Added logging function. +- Added the log linkage to TurboHamlog/Win. +- Fixed some bugs. + +======================== +BetaVer0.01 2004/JAN/09 +======================== +- Added AFC level control in the RX tab. +- Added a character code in the Edit menu. +- Added VARICODE table in the option menu + +======================== +BetaVer0.00 2004/JAN/08 +======================== +- First beta released. diff --git a/EMMVARI.TXT b/EMMVARI.TXT new file mode 100644 index 0000000..b48cb52 --- /dev/null +++ b/EMMVARI.TXT @@ -0,0 +1,1016 @@ +MMVARI operation manual + Version 0.45 (October 5, 2010) by JE3HHT Makoto Mori + Translated into English by JA7UDE Nobuyuki Oba + +========== +PREFACE +========== +First off, please read EPROJECT.TXT, which describes the objective of MMVARI. + +This document explains the basic operation of the MMVARI program. MMVARI is still under development. You could find on-line tips in the status bar at the bottom of the main window by pointing the mouse cursor at the entity of interest. + +========== +Modulations +========== +MMVARI version 0.44 and later support + - qpsk Compatible with HALPSK, WINPSK/J, standard VARICODE +MMVARI version 0.25 and later support the following modulations: + - GMSK Default for MBCS (Multi Byte Character Set) + - FSK For V/UHF rigs, which may have QRH or frequency drifted + - BPSK Not compatible with WINPSK/J in MBCS. Care should be taken for VariJA + - bpsk Compatible with HALPSK, WINPSK/J, standard VARICODE + - rtty This is just a quick addition to MMVARI. Only the standard BAUDOT code has been implemented. Only capital letters, figures, and a few symbols are supported. + - mfsk MFSK16 is implemented. The code is MFSK-VARICODE. + +* Be careful not to overdrive the transmitter for the PSK operation. + (DO NOT USE A SPEECH PROCESSOR) + +* According to the PSK transmission speed, the following names are used: + PSK31 31.25Bps + PSK63 62.5Bps + PSK125 125.0Bps + PSK250 250.0Bps + +* RTTY implemented in MMVARI are: + - 170Hz shift. It can be changed by macro command + <%TxShift...>, <%RxShift...>. + - Carrier frequency is the center frequency + - RTTY-L for LSB (default) and RTTY-U for USB (reverse) + - 5-bit BAUDOT S-BELL only + - UOS on the RX side is ON. It can be changed + by macro command <%UOS=ON/OFF/ONOFF>. + - UOS on the TX side is always ON. + - LTR diddle is always engaged. It can be changed + by macro command <%DIDDLE=BLK/LTR>. + - AFSK only (no FSK support). + +* MFSK implemented in MMVARI are: + mfsk16 mfsk8 mfsk31 mfsk32 mfsk64 mfsk11 mfsk22 +Symbol baudrate 15.625 7.8125 31.25 31.25 62.5 10.767 21.533 +Tones 16 32 8 16 16 16 16 +Tone space(Hz) 15.625 7.8125 31.25 31.25 62.5 10.767 21.533 +MAX FREQ shift(Hz) 234.375 242.1875 218.75 468.75 937.5 161.499 322.988 +Transmission speed(bps) 31.25 19.53125 46.875 62.5 125.0 21.533 43.066 +Viterbi NASA K=7, R=1/2 +Interleaver Diagonal interleaver +VARICODE MFSK standard + +type Speed Actual speed +mfsk4 3.9063 (3.90625 baud, 32 tones) +mfsk8 7.8125 (7.8125 baud, 32 tones) +mfsk11 10.767 (10.7666015625 baud, 16 tones) +mfsk16 15.625 (15.625 baud, 16 tones) +mfsk22 21.533 (21.533203125 baud, 16 tones) +mfsk31 31.25 (31.25 baud, 8 tones) +mfsk32 32.0 (31.25 baud, 16 tones) +mfsk64 62.5 (62.5 baud, 16 tones) + +============================ +How to tune in the signal +============================ +To get tune into the target signal, click on the center of the signal displayed in the FFT or waterfall window. You may want to set the waterfall range to 1K or 2K in order to make this operation easier. Alternatively, you could do it by tweaking the receiver dial, but you have to get used to doing so. + +You could use either LSB or USB for GMSK, FSK, BPSK, and bpsk. You really do not have to care about the LSB or USB. For RTTY, however, use rtty-L for LSB and rtty-U for USB to avoid the reverse shift. + +* To get tuned into the target signals in the mfsk mode, click on the edge of the signals. Click on the right edge in LSB. Click on the left edge in USB. Use mfsk-L for LSB and mfsk-U for USB. + + +===== +BPF +===== +MMVARI provides four bandwidth choices in the built-in band pass filter. Narrower filters are recommended in the QRM condx. It should be noted, however, the narrower the BPF, the more CPU power the MMVARI consumes. + + +===== +ATC +===== +ATC is Automatic Timing Control. It automatically adjusts the RX synchronization timings in accordance with the RX signals. Leave it on in the normal condx. Refer to the clock calibration section for more information. + +* It is NOT Automatic Threshold Control of MMTTY. Do not get them confused. + +* MMVARI version 0.20 or later uses a new synchronization method for receiving signals. It should give better decoding capability even for the signals that the ATC is hard to follow. Bear in mind, however, it is strongly recommended that you calibrate the soundcard clock in order to increase the readability of your signals. Refer to the clock calibration section for more information. + + +================ +RX operation tips +================ +By mouse click, you can capture a word in the RX window and transfer it to the log. MMVARI automatically picks out the call sign and RST, and transfers them to the corresponding logging fields. For the words other than the call sign or RST, you will see a pop-up window, which requests you to specify the destination of the selected words. Right click always gives you the pop-up window. +Use the scroll bar on the right side of the RX window to scroll back the received texts. The RX window memorizes the latest 1024 lines in the buffer. + + +================ +TX operation tips +================ +In the TX window, you can type ahead the characters to send. The characters to the cursor position will be sent. + + +================== +TX/RX switch over +================== +To start transmission, push the TX button at the top left corner of the main window. Push the button again to return to RX. MMVARI sends the characters in the TX window, and then returns to RX after sending all the characters in the TX buffer. + +The TXOFF button forces MMVARI to get back to RX immediately. + +* By default, the ESC key is assigned for the short cut of TXOFF. In case you are using the ESC key for IME, assign another key for TXOFF. It can be done in the TX tab of the MMVARI setup window. + + +============== +Macro +============== +MMVARI is equipped with 144 macro buttons. The bottom part of the main window shows the buttons of the current page. You can scroll up and down the current page by clicking the up and down arrows located on the right of the buttons. +Left click calls the macro. Right click gives you the macro-editing window. You could call a macro by hitting a function key. + +MMVARI macro offers powerful functions, such as text replacement, program control, and conditional operations. Right click on the macro button to open the macro-editing window. Push the MACRO button to get the macro list popped up. Push the COND button to get the conditional execution list popped up. + + +1. Preliminary notes +~~~~~~~~~~ +In the macro-editing window, the sentence containing macro is called a macro sentence. The sentence, which is generated by interpreting macro, is called an unfolded sentence. + +MMVARI does an immediate macro interpretation right after the macro button is pushed. It does not support a delayed interpretation, which MMTTY supported. For example, if you want to execute a macro sentence with <%HisRST> macro, you must have the RST report in the His field BEFORE you hit the macro button. + +Macros are categorized into two groups: + 1) Text macro (e.g., <%HisCALL>, <%HisRST>) + 2) Command macro (e.g., <%TX>, <%NETON>). + + +2. Position and effect of the macro +~~~~~~~~~~~~~~~~~~~~~~~~~~ +<%RX> and <%TX> macros are executed independently of its position in the sentence. For example, the following three sentences work in the same way, that is, MMVARI switches the rig to TX, sends VVV123, and switches the rig back to RX. + <%TX>VVV<%RX>123 + <%TX><%RX>VVV123 + VVV<%TX><%RX>123 + + +<%MoveTop> and <%MoveEnd> are command macros that place the unfolded sentence at the specific position. The example below inserts the unfolded sentences just before the transmitting TX messages. + + <%MoveTop><%HisCall> de <%MyCall> I had QRM in your last transmission. + <%MoveEnd> + +*Conditional execution precedes the macro command. All the macro and sentences in the false condition block are treated as empty. See section 8 below for details. + + +3. Insert position of unfolded sentence +~~~~~~~~~~~~~~~~~~ +The unfolded sentence is inserted at the current cursor position in the TX window. However, if the macro sentence has <%RX> command, the unfolded sentence gets behind the TX messages irrespective of <%MoveEnd> command. + + +4. CWID +~~~~~~ +If the unfolded sentence is composed of CWID only, MMVARI sends the CWID. When the unfolded sentence has both CWID and characters, MMVARI sends them in the specified order. You may want to send CWID and go back to RX without any MMVARI signals. In such a case, do not place a CR (carriage return) at the end of the sentence. The following example would give a clear solution. + <%TX>TNX AGN 73, SK...<%CWID><%RX><%EOF> + + +5. Automatic clear of TX window +~~~~~~~~~~~~~~~~~~~~ +To automatically clear the TX window every time when you go back to RX, use <%AutoClear> macro. + BTU <%HisCall> de <%MyCall> KN + <%RX><%AutoClear> + +* If you canceled the transmission by TXOFF, <%AutoClear> does not work. + + +6. TX repeat +~~~~~~~~~~~~~~ +<%RepeatTX=...> command sends the unfolded sentence repeatedly. It implicitly includes <%TX> and <%RX> commands, so that you do not have to them explicitly (inserting them would even give the same result). The repeat interval is defined in millisecond unit. <%RepeatTX=5000> gives you 5 second interval between repeated transmissions. + +* During this command being active, the macro button stays pushed. Push the button again or push the other button to cancel this operation. + +* Clicking on the spectrum, waterfall, RX window, TX window, and TXOFF also cancels this operation. + +* The following example is to repeatedly send CQ calls until the squelch opens. + #define ReceiveTime 5000 + #if !IsSQ + <%RepeatTX=ReceiveTime><%ClearTXW> + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K + #endif + + +* If you want to repeat a macro without TX, use <%Repeat=...> command. The next example shows a message box when MMVARI receives "CQ" string. + + #define _CaptureString CQ + #if !IsRepeat + #macro <%SetCaptureLimit> + #endif + #if IsCaptureText(<%String=_CaptureString>) + #macro <%Message="<%String=_CaptureString>" was detected> + #else + #macro <%Repeat=1000> + #endif + + +7. Program execution +~~~~~~~~~~~~~~~~~~ +With <%Execute=...> command macro, you can execute any program you want. The parameter field defines the program name and its arguments. If you start a program that uses the soundcard, execute <%Suspend> command to make MMVARI release the soundcard temporarily. + +The following example gets the MMSSTV started. + <%Suspend><%Execute=C:\MMSSTV\MMSSTV.exe> + +You can terminate MMVARI and then start MMSSTV by + <%Suspend><%Execute=C:\MMSSTV\MMSSTV.exe><%Exit> + +* You can override the Windows PATH environment by specifying the full path of the program. + + +8. Conditional unfolding block +~~~~~~~~~~ +MMVARI macro supports conditional unfolding block. Using the conditional unfolding block and macro commands cooperatively, you can compose many useful sentences. + +The syntax of the conditional unfolding block is + + #if test1 Start of conditional unfolding block + | <-- Execute if test1 is true + #elseif test2 Check another condition + | <-- Execute if test1 is false and test2 is true + #else Otherwise + | <-- Execute otherwise + #endif End of conditional unfolding block + +The syntax rules used here are: +1) The conditional unfolding block must start with #if and end with #endif. +2) The conditional command (e.g., #if, #elseif) and its argument (e.g., test1) must be in the same row. The other macro command must not be in the same row. +3) #elseif and #else can be omitted. +4) Nesting is allowed up to 64 levels. +5) ! inverts the true/false condition. For example, "#if !IsCall" is true if the Call box in the main window is unfilled. +6) There are three types of arguments: + Is: Monomial condition + Str: String condition + Val: Value condition +7) Monomial condition returns Boolean value. +8) String and value conditions are used with the following operators and return Boolean value. + = True if equal to + != True if not equal to + > True if greater than + < True if less than + >= True if greater than or equal to + <= True if less than or equal to + >> True if the string contains the specified word + Examples: + #if ValFreq >= 144 True if the frequency is larger than or equal to 144 + #if StrMacro(<%HisQTH>) >> Osaka True if QTH contains Osaka + +9) Multiple conditions using && (AND operator) and || (OR operator) are supported. +Examples: +#if IsNET && IsAFC True if both NET and AFC are turned on +#if IsNET || IsAFC True if either NET and AFC is turned on + +The following example calls him/her only if the call box of the main window has been filled with the call sign. + + #if IsCall + <%TX><%RX> + <%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse k + #endif + +The next example sends different sentences by comparing my entity and his/her entity. + <%TX> + #if IsLocal + It is great to see you again. Thanks for the call. + #else + Hello, thanks for your call. + #endif + +The example below generates CQ call in different modulation methods according to the band. + + #if ValFreq >= 144 + <%MODE=FSK><%SkipCR> + #else + <%MODE=GMSK><%SkipCR> + #endif + <%TX> + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) k + <%RX> + +The next example opens the text input window and transmits the input text in CW. + + #if StrMacro(<%Input=Input CW text>) + <%TX><%RX><%CWID=<%Input$>><%EOF> + #endif + +Right clicking on the spectrum or waterfall window gives you a pop-up menu, Send AS in CW, which actually has the following macro sentences implemented inside MMVARI. This example switches TX pages not to lose the TX sentences you are editing. + + #if !IsTX + <%AutoNET><%AutoReturn><%SkipCR> + #if ValPage!=4 + <%Page=4><%SkipCR> + #else + <%Page=3><%SkipCR> + #endif + <%ClearTXW><%SkipCR> + #endif + <%TX><%CWID=@><%RX><%EOF> + + +9. String variable +~~~~~~~~~~~~ +The MMVARI macro supports string variables. The string variable is defined by using #define, and referred to by using <%String=name>. It can be used for the argument of a conditional statement and for the parameter of macro commands. + +The syntax of #define is + #define Name String + +Name is an arbitrary alphanumeric character string that does not start with a numeric character. String can be a string consisting of any characters. It can be a macro command or other string variables. + + Example: #define Greetings MAIDODESU... + #define NowSpeed <%BAUD> + #define ImaSpeed NowSpeed + +* There is no limitation in the number of the variables defined by #define. If the same variable is redefined, it automatically is preceded by the new value. + +* The variables are all global with respect to macros. Therefore, a macro can refer to the variable defined by another macro. + +* The values of the variables are cleared at the timing of the program termination. + +* #define instruction is executed in the first pass. + +The macro shown below is an example of conditional WX setting. Once the information is set to WX string (TodayWX), the WX string can be unfolded to the macro sentence without asking the user to input the value. + + #if !IsDefined(TodayWX) || !StrMacro(<%String=TodayWX>) + #define TodayWX <%Input=Input_WX> + #endif + #if StrMacro(<%String=TodayWX>) + Today's weather is <%String=TodayWX>. + #endif + +The following example shows how to define the frequently changed portion in the macro. + + #define Boundary 14 + #define MyRIG FT1000MP(50W) + #define MyLANT Vertical(7m) + #define MyHANT Magnetic loop(90cm) + #if ValFreq < Boundary + #define MyANT MyLANT + #else + #define MyANT MyHANT + #endif + My rig is <%String=MyRIG>, and antenna is <%String=MyANT>. + +The next example gives the QTH string by referring to the JCC number. + + #define QTH_HOME Takatsuki-city + #define QTH_25006 Mishima-gun + #define QTH_2701 Kobe-city + #if StrNote >> 25006 + #define MyQTH QTH_25006 + #elseif StrNote >> 2701 + #define MyQTH QTH_2701 + #else + #define MyQTH QTH_HOME + #endif + My QTH is <%String=MyQTH>. + +10. Output print format and built-in calculator +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + <%Format=...> command is a macro, which specifies the output print format with a simple calculation function. The notation is: + <%Format=format,equation> +--- Format ---- +It follows the printf(...) syntax of the C language. You could omit the symbol in []. + + %[-][#][0][w][.p]TYP + + - Left aligned + 0 0s are padded at the head of the output + w Copy the minimum number of characters to the output + .p Copy the minimum fractions to the output + TYP Format type of the output + + TYP Type Output + c Character One character + s String String + d Integer Decimal number with sign + i Integer Decimal number with sign + o Integer Octal number without sign + u Integer Decimal number without sign + x Integer Hexadecimal number without sign (use a, b, c, d, e, and f) + X Integer Hexadecimal number without sign (use A, B, C, D, E, and F) + f Floating num [-]dddd.dddd with sign + e Floating num [-]d.dddd or e[+/-]ddd with sign + g Floating num e or f format with sign + E Floating num Same as e (use E for the exponential symbol) + G Floating num Same as g (use E for the exponential symbol) + +--- Equation --- +As the parameters for the equation, you could assign digits, macro commands, and string variable. The macro command and string variable are immediately interpreted as applied. +Arithmetic operators supported are: + + Addition + - Subtraction + * Multiplication + / Division + % Remainder +The priority of the operators follows the standard arithmetic rule. Use () to control the calculation order. + 10 + 20 * 30 = 610 + (10 + 20) * 30 = 900 + +--- Examples --- +<%BAUD=<%Format=%f,<%BAUD>*2>> + Double the baud rate +<%Format=%c,<%Skip$=1,<%HisRST>>> + Returns the second character of HisRST (579 -> 7) +<%TxCarrier=<%Format=%d,<%RxCarrier>+100>> + Put the RX carrier frequency added by 100Hz to the TX carrier frequency + +11. Custom pop-up menu +~~~~~~~~~~~~~~~~~~~~~~~ + Using macro, the user can make a custom pop-up menu, which is useful for reducing the number of the macro buttons for daily use. + + <%Menu=...> command generates a pop-up menu. The selected string in the menu is obtained by <%Input$> command. Alternatively, the index of the selected string can be retrieved by ValMenu property. + + Menu items are delimited by comma (,). If the string has a comma inside, put the string in the double quotation marks ("string"). The string can recursively have a macro. There is no limitation for the number of menu items. + <%Menu=Menu1, Menu2, Menu3, Menu4, ...> + <%MenuB=Index, Menu1, Menu2, Menu3, Menu4, ...> + +* <%MenuB=...> command can be used to add a black bullet in front of each item. + + Use a minus character (-) to place a separator between the menu items. The access key is defined by an ampersand followed by a character. + <%Menu=Menu&1, Menu&2, -, Menu&3, Menu&4, ...> + <%MenuB=Index1, Menu&1, Menu&2, -, Index2, Menu&3, Menu&4, ...> + + The example below shows a menu including end of QSO messages and put the selected string to the TX window. + <%Menu=<%DearName> Thank you..., Sayonara..., "TNX AGN <%DearName>, 73..."><%Input$> + + To specify the operation by using the index of the menu, use ValMenu property. In this particular case, because the if clause is interpreted in the first path, place #macro to make <%Menu=...> also be interpreted in the first path. + + #macro <%Menu=&73 CU SK, &TU SK EE, &SU, &EE> + #if ValMenu==1 + <%TX><%RX><%CWID=73CU:><%EOF> + #elseif ValMenu==2 + <%TX><%RX><%CWID=TU:EE><%EOF> + #elseif ValMenu==3 + <%TX><%RX><%CWID=SU><%EOF> + #elseif ValMenu==4 + <%TX><%RX><%CWID=EE><%EOF> + #endif + +* If the pop-up menu selection is canceled, ValMenu returns 0 and <%Input$> has null string. +* The separator cannot be selected. The value of ValMenu property does not include the separator. + +12. Rig control using Macro +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + MMVARI can control the rig by using macro commands below. + <%RadioKHz> Returns the VFO frequency + <%RadioKHz=...> Sets the VFO frequency + <%RadioMode> Returns the mode + <%RadioMode=...> Sets the mode + <%RadioOut=...> Sends the command to the rig + #if IsRadioLSB Check up the heterodyne (LSB or USB) + + These commands will be provided for the remote operation over the network, but they sometimes are useful in the situation where the PC is hooked up direct to the rig. + +* These macro commands are effective only when the rig control port has appropriately been set up. If not, these macro commands will be ignored. +* To make <%RadioKHz> and <%RadioMode> effective, the VFO polling should be set up correctly. However, they return the values that are specified by <%RadioKHz=...> and <%RadioMode=...> commands. + + +<%RadioKHz=RigType,RigFreq(KHz)> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + This command sets the VFO frequency of the rig. Currently, RigType supports the following transceiver types: + + RigType Rig + YAESU-VU FT847, FT736, etc. + YAESU-HF FT1000MP, FT920, etc. + YAESU-NEW FT9000, FT2000, etc. + CI-V ICOM + CI-V4 ICOM (four-byte command) + KENWOOD KENWOOD + JST245 JRC JST245 + +*In CI-V, MMVARI sends five-byte commands for the frequency set operation even under 100MHz. In case it fails, try CI-V4, in which MMVARI sends four-byte commands. + + The next example gets the input window popped up and sets the rig frequency. + #define _Rig YAESU-HF + #macro <%IME=OFF> + #if StrMacro(<%Input=Input VFO FREQ(KHz)>) + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001> + #else + #macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001> + #endif + #endif + + The example below shows a menu and sets the rig frequency. + #define _Rig YAESU-VU + #macro <%Menu=7028.5,10141.5,14072.5,18102.5,21072.5,28072.5> + #if ValMenu + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001> + #else + #macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001> + #endif + #endif + + These macro statements increase the rig frequency by 500Hz. + #define _Rig JST245 + #macro <%RadioKHz=_Rig,<%RadioKHz>+0.5> + +The example below forces the RX carrier frequency to 1750Hz and gets the rig frequency tuned to it (to avoid TX with low carrier frequency). #define _Tone 1750 + #define _Rig CI-V + #define _OffKHz <%Format=%f,(<%RxCarrier>-_Tone)*0.001> + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%RadioKHz>-_OffKHz> #else + #macro <%RadioKHz=_Rig,<%RadioKHz>+_OffKHz> + #endif + #macro <%RxCarrier=_Tone> + +<%RadioMode=RigType,RigMode> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This command sets the rig mode. The supported RigType is the same as <%RadioKHz=...>. RigMode can be one of LSB, USB, CW, AM, FM, RTTY, PACKET. + + Example: <%RadioMode=KENWOOD,LSB> + +* It should be noted that not all the rigs support the above modes. If you want to set a rig specific mode, use <%RadioOut=...> command instead. + +The macro statements bellow show a selection menu and set the rig mode. + #define _Rig YAESU-VU + #define _t_Mode LSB,USB,CW,AM,FM,RTTY,PACKET + #macro <%MenuB="<%Table=<%RadioMode>,_t_Mode>",_t_Mode> + #if ValMenu + #macro <%RadioMode=_Rig,<%Input$>> + #endif + +<%RadioOut=character_string> +~~~~~~~~~~~~~~~~~~ + This command sends a radio command to the rig. It will work for any rig. Use the following keyword to specify byte data in hexadecimal number. + + \$##... ##=00-FF Specify the byte data string in the hexadecimal format + (Example: \$FE55AA -> $FE,$55,$AA) + ICOM CI-V address can be expressed by xx + \x## ##=00-FF, Specify one byte in the hexadecimal format + (Example: \xFE\x55\xAA -> $FE, $55, $AA) + \w## ##=00-99, Specify the delay time + (Example: \w05 -> wait 50ms) + \r Send a carriage return + \n Send a line feed + \c.... Comment + + \\ '\' send character + Others Send the character as is + +* For more information on the radio command, refer to the manual of your rig. + + +[Examples] +Set the VFO-A filter width of Yaesu FT-1000MP to 500Hz + <%RadioOut=\$020000008C> +Exchange ICOM IC-706's VFO A and B + <%RadioOut=\$FEFExxE007BOFD> +Put 14.073MHz to VFO-B of Kenwood TRX + <%RadioOut=FB00014073000;> Change the mode of Yaesu FT-847 to CW(W) + (<%RadioMode=YAESU-VU,CW> will change the mode to CW(N) ) + <%RadioOut=\$0200000007> + +#if IsRadioLSB +~~~~~~~~~~~~~~ +This "if clause" checks the rig heterodyne. It can be used for the frequency-offset calculation. MMVARI returns TRUE or FALSE by referring to the rig mode. + Return value Rig mode + TRUE LSB, RTTY, PACKET + FALSE Other modes + Before using this clause, you have to set up the VFO polling and make the frequency adjustment. MMVARI, however, returns TRUE or FALSE if the mode has been set up with <%RadioMode=...>. + +* If the mode is not either LSB or USB, MMVARI would not be able to detect the rig heterodyne correctly. +* Use <%RadioMode> to obtain the original rig mode. + + +13. Event macro +~~~~~~~~~~~~~~~~~ +Event macro is a macro that is called when the specified event occurs. The following macros are provided in MMVARI. + OnTimer: Called every second + OnPTT: Called when the PTT status is changed + OnQSO: Called when the QSO button is depressed + OnFind: Called when HisCall property is set + OnStart: Called once when MMVARI is started + OnBand: Called when the log panel band is changed + OnExit: Called once when MMVARI is terminated + OnMode: Called when the mode is changed + OnSpeed: Called when the transmission speed is changed + OnClick: Called when a text in the RX window is clicked + OnFFTScale: Called when the FFT scale is changed + +[Event macro definition by MMVARI menu] +~~~~~~~~~~~~~~~~~~~~~~ +Event macros can be defined in the TX tab of the MMVARI setup menu. Select the event macro from the drop-down list and push the EDIT button. If you want to disable the macro execution, just erase the content of the macro. + +The example below is defined in the OnTimer event macro, and gets the AFC detected frequency popped on the waterfall every second. + + <%WaterMsg=4,<%AFCFrequency>Hz> + +The next example is defined in the OnQSO event macro, and shows the status on the RX pane if the QSO button is depressed. The status is also recorded in the RX log. + + #if IsQSO + #macro <%RxStatus=LogON <%HisCall> on <%BAND>/<%MODE>> + #else + #macro <%RxStatus=LogOFF <%HisCall>> + #endif + +The next sample macro is defined in the OnMode macro, and switches the macro button page when the mode is changed. + + #if StrMode>>rtty + #macro <%SeekTop><%SeekNext> + #else + #macro <%SeekTop> + #endif + +[Event macro definition by macro command] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Every event macro can be defined in the macro statement as follows: + <%OnTimer=...> + <%OnPTT=...> + <%OnQSO=...> + <%OnFind=...> + <%OnBand=...> + <%OnStart=...> + <%OnExit=...> + <%OnMode=...> + <%OnSpeed=...> + <%OnClick=...> + <%OnFFTScale=...> + +The next macro statement, which could be defined in a macro button, specifies an operation in the OnTimer event. + + <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>> + +If you need to define two or more macro commands in a single macro statement, use \r\n as the delimiter. + + <%OnTimer=#if IsSQ\r\n#macro <%WaterMsg=4,<%AFCFrequency>Hz>\r\n#endif> + +The next sequence of the macro commands shows a popup window, with which the user can select the operation of the OnTimer macro. + + #macro <%Menu=AFC, Metric(MFSK), RadioMode, WaterNoise, UTC, Local, -, Stop> + #if ValMenu == 1 + #macro <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>> + #elseif ValMenu == 2 + #macro <%OnTimer=<%WaterMsg=4,<%MetricMFSK>>> + #elseif ValMenu == 3 + #macro <%OnTimer=<%WaterMsg=4,<%RadioMode>>> + #elseif ValMenu == 4 + #macro <%OnTimer=<%WaterMsg=4,<%WaterNoise>dB>> + #elseif ValMenu == 5 + #macro <%OnTimer=<%WaterMsg=4,<%UTIME>z>> + #elseif ValMenu == 6 + #macro <%OnTimer=<%WaterMsg=4,<%LTIME>>> + #elseif ValMenu == 7 + #macro <%OnTimer=> + #endif + +The next sequence gives a macro edit menu. It is supposed to be defined in a macro button. + + #macro <%Menu=<%Events>> + #if ValMenu + #macro <%EditMacro=<%Input$>> + #endif + + +14. Procedure +~~~~~~~~~~~~ +MMVARI supports a procedure call, which facilitates repeating calls for the same operation. A macro command can the predefined procedure as many times as required. There is no limit in the number of procedures to be defined. The procedure can also be used as a handler for the extended menu. + +[Procedure definition] +~~~~~~~~~~~~~~~~~~~~ +A procedure is defined between #proc and #endp. The format of the procedure is: + + #proc Name Dummy1, Dummy2... + | + #endp + +Name is the name of the procedure. It must begin with an alphabet. +Dummy1, Dummy2... are the symbols are pseudo parameters effective only in the procedure. They are replaced with the arguments of the procedure caller when the procedure is called. Dummy can be omitted. A procedure can have up to 64 Dummy parameters. + +A procedure example + + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +* The definition of the procedure does not evaluate the parameters. The parameters are interpreted when the procedure is actually called. + +* The function of the Dummy is just a simple text replacement. In order to avoid unexpected replacement, it is a good idea to assign a long name to Dummy or to put @ ahead of the name. + +* The procedure definition remains effective until the termination of the MMVARI program. Therefore, the procedure defined in the OnStart event can be called by any macro commands during the MMVARI run. If a procedure is redefined as the same name, the last definition is effective. + +[Procedure call] +~~~~~~~~~~~~~~~~~~~~~~~~ +A macro command calls a procedure by <%CallProc=Name, Arg1, Arg2...>. +Name is the procedure name defined in #proc. +Arg1, Arg2, ... are the argument for the procedure. If the number of arguments is less than that of Dummy(s) in the procedure, Dummy(s) is assigned NULL. If the number of arguments is larger than that of Dummy(s), excessive arguments are just discarded. + +An example of the procedure call + <%CallProc=Slider, CW speed, CWSpeed, 10, 40> + <%CallProc=Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> + <%CallProc=Slider, Play back speed, PlayBackSpeed, 1, 20> + +* The procedures are defined in the first path. The procedure calls <%CallProc=...> are executed in the second path. Therefore, the procedure definition can be placed after the macro command that calls the procedure. However, <%CallProc=...> in #macro is executed in the first path, and thus the procedure must be defined prior to the #macro. + +* Although, recursive call of the procedure is permitted, pay attention to the stack overflow in case of a large number of nesting calls. Here is a simple example using recursive call. + + + <%DisableCR> + <%CallProc=Repeat, 3, CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall><%CR>> + <%BS> pse k...<%CR> + #proc Repeat @N, @Text + <%DisableCR> + #define _RepCount <%Format=%d,@N-1> + #if _RepCount >= 0 + @Text + <%CallProc=Repeat, _RepCount, @Text> + #endif + #endp + + +* Use <%DebugProc=...> instead of <%CallProc=...> for debugging. In the TX window, <%DebugProc=...> shows how the procedure is executed. + +[Extended menu handler] +~~~~~~~~~~~~~~~~~~~~~~ +A procedure can be used as a handler for the extended menu. Using the extended menu, the user can customize the MMVARI menu function. <%AddMenu=...> and <%InsertMenu=...> generate the extended menu. + + <%AddMenu=Name, Caption, Procedure, Arg1, Arg2...> + <%InsertMenu=Name, InsPos, Caption, Procedure, Arg1, Arg2...> + + Name: Name of the menu, access key (&x), or index (1...) + InsPos: Caption of the inserting point, access key (&x), or index (1...) + Caption: Caption of the menu, access key (&x), or index (1...) + Procedure: Name of the handler procedure + Arg: Arguments to the handler procedure (can be omitted) + +A simple example for the extended menu is given below. These macro commands are usually defined in the OnStart event macro. + + <%DisableCR> + #define _Name E&xtension + <%AddMenu=_Name, &CW speed..., Slider, CW speed, CWSpeed, 10, 40> + <%AddMenu=_Name, &Digital output level..., Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> + <%AddMenu=_Name, -> + <%AddMenu=_Name, CQ DX(&1), OnCQDXClick, 1, 3, 3, 4000> + <%AddMenu=_Name, CQ DX(&3), OnCQDXClick, 3, 3, 3, 5000> + + #proc OnCQDXClick @Nline, @Ncq, @Ncall, @Interval + <%DisableCR><%ClearTXW><%AutoClear><%TX><%RX> + <%RepeatText=@Nline,<%RepeatText=@Ncq,CQ DX<%SP>>de<%RepeatText=@Ncall,<%SP><%MyCall>><%CR>> + <%BS><%SP>pse DX k<%CR><%RepeatTX=@Interval> + #endp + + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +* When clicking on the title of the extended menu, the handler procedure below is automatically invoked. This handler procedure is optional. + + On$xxxClick xxx = Name of the menu (e.g. On$E&xtensionClick) + +* If an access key is defined, all the menu commands including <%DoMenu=...>, <%DeleteMenu=...>, <%AddMenu=...> can be called by it. Care must be taken that one access key is not defined for two or more commands. + + <%AddMenu=...> and <%InsertMenu=...> can be used for adding an item to the predefined menu or for replacing it with a new one. It is a good idea to use an access key or index to specify the predefined menu. Here is an example: + + <%DisableCR> + #if !IsDefined(_fShellHelp) + #define _fShellHelp 0 + #endif + <%AddMenu=&E, -> + <%AddMenu=&E, Edit &AS(CW) macro..., OnCommand, <%EditMacro=AS(CW)>> + <%AddMenu=&E, Edit &OnStart event..., OnCommand, <%OnStart>> + <%InsertMenu=&O, &B, &Digital output level..., Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> + <%InsertMenu=&O, &B, -> + <%AddMenu=&H, &P, OnShellEdit, project.txt, e, 1> + <%AddMenu=&H, &O, OnShellEdit, mmvari.txt, e, 1> + <%AddMenu=&H, &S, OnShellEdit, Samples.txt, , 3> + <%AddMenu=&H, &H, OnShellEdit, history.txt, e, 1> + <%InsertMenu=&H, &D, &Use Shell's standard editor, InvRegVal, _fShellHelp> + <%InsertMenu=&H, &D, -> + + #proc On$&HelpClick + <%DisableCR><%CheckMenu=&H, &U, _fShellHelp> + #endp + + #proc OnCommand @Command + <%DisableCR>@Command + #endp + + #proc OnInvVal @Value + <%DisableCR> + #DEFINE @Value <%Inv=@Value> + #endp + + #proc OnShellEdit @File, @Prifix, @Flag + <%DisableCR> + #if IsEnglish + #define _FileName <%Folder>@Prifix@File + #else + #define _FileName <%Folder>@File + #endif + #if _fShellHelp + <%Shell=_FileName> + #else + <%EditFile=_FileName, @Flag> + #endif + #endp + + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +* The pop-up menus are defined as follows: + + PopWATER Menu when right click on the spectrum or waterfall window + PopSQ Menu when right click on the level indicator + PopRXW Menu when right click on the RX window + PopRX Menu when right click on a text in the RX window + PopTX Menu when right click on the TX window + PopPAGE Menu when right click on the page window of the status bar + PopCHARSET Menu when right click on the language selection of the status bar + PopCALLS Menu when click on the button next to the CallBox + +* The menu item that has a sub menu cannot be overridden. +* After inserting a menu, the index number will be changed. Using an access key would avoid this confusion. +* Clicking on the title of the defined menu invokes the following handler procedure. This handler, however, is optional. + + On$&FileClick, On$&EditClick, On$&ViewClick, On$&OptionsClick, + OnRadio&CommandClick, On$&HelpClick + +* When the pop-up menu is poped, MMVARI automatically calls the following handler procedures (they are not necessarily defined, however). + On$PopWATERClick, On$PopSQClick, On$PopRXWClick, On$PopRXClick, + On$PopTXClick, On$PopPAGEClick, On$PopCHARASETClick, On$PopCALLSClick, + +[Repeat block] +~~~~~~~~~~~~~~ +Repeat block is defined as a special procedure by #repeat and #endp. The block is N times repeatedly executed. N is specified by the statement just after #repeat. In case N is 0, the block is not executed. + + #repeat statement + | + #endp + +* In the repeat block, the repeat number "$repeat" and the counter "$counter" are implicitly defined. + + #repeat 3 + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> (<%Format=%d, 1 + $repeat - $counter>) + #endp + +* If the repeat block is nested, each level has independent $repeat and $counter. + + #repeat 3 + <%DisableCR>Outside=($counter/$repeat)[ + #repeat 2 + <%DisableCR> + #if $counter > 1 + , + #endif + Inside=($counter/$repeat) + #endp + ]<%CR> + #endp + + +====================== +Sound playback +====================== +The sound playback function allows the user to replay the latest 15/30/60-second audio data inside MMVARI. To enable this function, go the RX tab of the MMVARI setup window and check the sound playback check box. Three buttons, 60, 30, and 15, appear just under the TXOFF button at the top left corner of the main MMVARI window. Pushing one of these buttons activates the sound playback function. + + 60 Replay the latest 60-second sound data + 30 Replay the latest 30-second sound data + 15 Replay the latest 15-second sound data + +This function is useful for the following situations: +- Somebody was calling me, but I could not get zero-in the signal before he stopped calling. +- Somebody was transmitting signals, but I missed him because of the mode mismatch. + +With the sound playback function, you can receive and decode the same signals as many times as you want. For example, the modes, such as MFSK, require longer time for AFC to get zero-in, and therefore you would not be able to decode the signals in short TX duration. In such a case, push 15/30/60 button to replay the received sound, and make AFC attempt to zero-in again. + +The slider on the right of the sound playback enable check box changes the replay speed from x1 to x20. The default speed is x5 (it takes three seconds to replay 15-second sound). The speed may be limited by the CPU speed. + +MMVARI constantly records the latest 60-second sound data to the memory in the PCM format. The recorded sound data of the 11025Hz sampling frequency uses approximately 1.3MB memory. + + +================ +Soundcard settings +================ +Soundcard settings are available on the MISC tab of Setup MMVARI menu. + +(1) Fifo - RX +~~~~~~~~~~~~ +Increase fifo depth if the RX sound is intermittent. + +(2) Fifo - TX +~~~~~~~~~~~~ +Increase fifo depth if the TX sound is intermittent. However, the deep TX fifo would result in large timing gap between typing and transmitting characters. + +(3) DeviceID +~~~~~~~~~~~ +In case your PC has two or more soundcard devices, specify the DEVICE_ID, which starts with 0. "-1" means the default card to be selected. + +MMVARI supports the custom sound plug-in, which was originally developed for MMTTY/MMSSTV. Make sure you have mmw file in the folder where MMVARI is installed. Select your mmw file in the DeviceID drop-down list. + +For more information on the custom sound, refer to the EReadme.txt and EMMW.txt in the MMW.ZIP package. + +(4) Thread priority +~~~~~~~~~~~~~~~~~ +If the TX sound is intermittent, try increasing the priority. + +(5) Input channel +~~~~~~~~~~~~~~~~~ +Select the RX sound input source from left, right, or stereo. +MMVARI always outputs the TX sound to both left and right. + +(6) Clock - RX +~~~~~~~~~~~~~ +Specify the RX sampling frequency. MMVARI supports the following sound frequencies. The default is 11025Hz. + +1 - 11025Hz: Typical soundcard frequency supported by all the cards in the market. +2 - 12000Hz: Soundcard frequency that is unlikely to have TX offset. Supported by some cards in the market. +3 - 6000Hz: Uses smaller CPU power. Soundcard frequency supported by some cards in the market. + 8000Hz No particular merit. + 18000Hz No particular merit. 22050Hz One of the standard sound frequencies. Nothing particular merit. + 24000Hz No particular merit. + 44100Hz One of the standard sound frequencies. Nothing particular merit. + 48000Hz For the optical connection (S/PDIF). + +* You can see another frequency, 11100Hz, in the drop-down list. This frequency, however, is a sort of calibrated value, and the soundcard works at 11025Hz. + +* 6000Hz is a good choice for a slow CPU. + +* In the 8000Hz and its variant mode, the spectrum scope and waterfall run slightly slower than the other modes. + + +(7) Clock - TxOffset +~~~~~~~~~~~~~~~~~~~ +Specify the TX offset with respect to the RX frequency. If your soundcard has offset between TX and RX frequencies, use this parameter as the following equation. + + TX sampling frequency = RX sampling frequency + TxOffset [Hz] + + +========================== +Clock calibration of the soundcard +========================== +The soundcard clock frequency for MMVARI is not so sensitive as SSTV. However, in case the TX and RX frequencies are far different, the carrier frequencies of them become far apart as a result. That should cause operation inconveniences and difficulties in the signal synchronization. + +1. Using MMSSTV +~~~~~~~~~~~~~~~~~~~~~~ +For MMVARI, you can use the clock and TxOffset values derived by the calibration procedure in MMSSTV. This is the simplest way for the calibration. Make sure you have turned off the automatic slant adjustment function in MMSSTV. + +2. Adjust RX frequency first +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Click on Option Menu and select Calibrating the SoundCard. You will see another window popped up. Follow the instruction shows there. The calibration uses BPM standard radio wave, which can be heard in Eastern Asia. With this procedure, you can adjust the RX clock frequency only. For TX clock frequency calibration, refer to "Adjust TxOffset" below. + +3. Adjust TxOffset +~~~~~~~~~~~~~~~~ +First of all, open the TX tab, select External (full-duplex) loop-back mode, and connect the input and output terminals of the soundcard. It is a simple way of settling the loop-back, but you may not have to connect them with a real wire. That is, you alternatively open the sound input setup window of Windows, and select the stereo mixer or monaural mixer from the line input. + +In the MMVARI main window, do the following operations. +1) Turn NET off, AFC on, and ATC on. +2) Clear the TX window to make idling TX signal. +3) Push the TX button. Make sure you have turned the transceiver off! +4) In the spectrum window, zero in to the RX signal. If your soundcard has the offset between TX and RX, you notice that TX and RX frequencies are not the same. + +After a while, the ATC value becomes stable. Move the mouse cursor over the ATC timing window, and look at the RxOffset value in the status bar. Subtract the value, RxOffset, displayed in the status bar from TxOffset. + + + New TxOffset = Current TxOffset - RxOffset [Hz] + +For example, if the current TxOffset is 0 and RxOffset is displayed -74.40, the new TxOffset will be 74.40. + + +That's all for the calibration. Put the loop-back mode from External to Internal. + +4. Another simple TxOffset calibration +~~~~~~~~~~~~~~~~~~~~ +Put 0 to TxOffset and transmit the idle signal for a while. Get the ATC timing value from the receiving amateur radio station. Reverse the polarity and put it to TxOffset. It is prerequisite that the receiving station is correctly calibrated. + + +================ +Naming convention of MMVARI +================ +For the sake of convenience, MMVARI defines the names of VARICODE as follows. The <%VARITYPE> automatically refers to the definition. + + VariSTD Stardard PSK31 VARICODE (256 codes) + VariJA Japanese VARICODE (12160 codes) + VariHL Hangul VARICODE (24448 codes) + VariBV Chinese (BV) VARICODE (24448 codes) + VariBY Chinese (BY) VARICODE (24448 codes) + +The conventional method, which uses the standard VARICODE and sends two untranslated codes for an MBCS character, is defined as "VariSTD/JA" or "VariSTD/HL" depending on the language selected on the PC. + +The following table gives the modulation and <%VARITYPE> combination. + + GMSK VariJA, VariHL, VariBV, VariBY + FSK VariJA, VariHL, VariBV, VariBY + BPSK VariJA, VariHL, VariBV, VariBY + bpsk VariSTD/JA, VariSTD/HL, VariSTD/BV, VariSTD/BY + +* It should be noted that <%VARITYPE> takes different values according to the language selected in the RX window. If an SBCS language is selected, it always takes "VariSTD." + +* In bpsk, "VariSTD/JA" is not popularized, so "Japanese" should be better. The following macro example can be used for this purpose. + + RRR <%HisCall> de <%MyCall> + #if IsLocal + #if StrVARITYPE == STD/JA + --- Japanese --- + #else + --- <%VARITYPE> --- + #endif + #endif + +73, Mako JE3HHT diff --git a/EPROJECT.TXT b/EPROJECT.TXT new file mode 100644 index 0000000..836ca46 --- /dev/null +++ b/EPROJECT.TXT @@ -0,0 +1,232 @@ +MMVARI project + January 2, 2004 JE3HHT Makoto Mori + Translated into English by JA7UDE Nobuyuki Oba + +[Preface] + +I like having QSOs in Japanese simply because I am Japanese. Even in PSK31, I prefer using Japanese characters for domestic QSOs. As well known, PSK31 is a great means of communication, but I have been aware of an exposure in manipulating Japanese characters; more precisely, in manipulating Eastern Asia languages including Hangul and Chinese. The objective of this project is to give a solution to the exposure. + + +[Character code and structure] + +Eastern Asia languages, such as Japanese, Hangul, and Chinese, have many characters, which are impossible to be fit into the 8-bit code space. The current PSK31 implementation uses MultiByte Character Set (MBCS) to accommodate this requirement. To send one MBCS character, PSK31 sends two bytes, and thus it suffers from a couple of disadvantages below: + +(1) Slow +(2) Once the phase is unlocked, the output becomes unrecoverable garbage for a while. +(3) Characters with different byte lengths are mixed. It makes the backspace operation confusing. + +Let us see these problems one by one. + +(1) It is true that Easter Asia languages have many characters, but this is not only the reason they are not suited for PSK31. The first byte of MBCS is assigned to the range between $81 and $FE. In addition, Hiragana, which appears in Japanese very frequently, is assigned to $9F-$F2. In PSK31's VARICODE, characters in those ranges are assigned to lengthy codes. To make matters worse, a GAP (00) is added between two VARICODE characters that represent one MBCS character. This results in 24 bits for one character. In fact, PSK31 QSO in Japanese is too slow to make smooth communication. It sometimes is slower than CW using Japanese characters. + +(2) Even when only one character is missing in the path, the receiver often outputs a string of garbled characters because the receiver misunderstands the delimiting position of MBCS characters. The first byte and second byte of MBCS share some range of codes, so that the receiver cannot always distinguish whether the received code is the first or second byte only from the range the received byte belongs to. Fortunately, $A0-$DF are not used for the first byte in the Japanese code set, and therefore can be used for phase detection. However, Hangul and Chinese code sets use more number of character codes that are used in the first and second bytes. + +(3) From the application perspective, one-byte and two-byte characters are seen mixed in the transmission. This makes the backspace (BS) operation confusing. Japanese compliant PSK31 programs, such as HALPSK and WINPSK/J, use a crafty trick to solve this problem, but it is not the best approach. The most effective solution is to increase the code space so that each character has a unique code. Theoretically, VARICODE used in PSK31 can have as many codes as desired. + +To support only MBCS, the program has to handle the characters in $00-$FF and $8140-$FEFF, and does not have to handle characters outside of these ranges. The second byte of MBCS is equal to or greater than $40. In Japanese, there is no character assigned in $A040-$DFFF. In Hangul and Chinese, however, some characters are assigned in this range. + +Someone may ask "how about UNICODE?" On UNICODE, a unique code is assigned to a character irrespective of the code set, but all the codes from $0000 to $FFFF must be handled. In real QSOs, we do not use Japanese and Chinese mixed. Hangul characters are assigned in the later portion of the UNICODE, and they tend to be longer in code bit length. UNICODE is not supported in all Windows. For these reasons, I dropped the UNICODE support. + +How about JIS code? It does not take account of any languages other than Japanese, so it should not be suited for amateur radio communication. + +To convert MBCS in $00-$FF and $8140-$FEFF to VARICODE, we need the continuous index values of $0000-$5F7F. VARICODE is based on a rule so that every code starts with bit 1 and ends with bit 1, and has no series of two or more 0s. According to this rule, the index can be defined in the table show below. With this assignment, we can use divide & conquer algorithm to convert the VARICODE to index. + +Index VARICODE +$0000 1 +$0001 11 +$0002 101 +$0003 111 +$0004 1011 +$0005 1101 +$0006 1111 +$0007 10101 +$0008 10111 +$0009 11011 +$000A 11101 +$000B 11111 + : : +$00FF 101101011011 + : : +$5F7F 110111111111101101101 + +Care should be taken that if the index is directly assigned to the code set, not frequently used characters are assigned to short codes, and would result in inefficient coding. ASCII characters in $0000-$007F are assigned to PSK31 codes by optimizing the code length with respect to the frequency in use of characters. Let us use the PSK31 code for this range ($0000-$0007F) for compatibility. + +Well, let's see the frequency of Japanese characters from the MBCS viewpoint. The table below shows the frequency of the first byte in several documents I wrote. + + $81 : 6.33% $89 : 0.95% $91 : 2.44% $99 : 0.00% + $82 : 51.5% $8A : 1.68% $92 : 2.12% $9A : 0.00% + $83 : 8.99% $8B : 0.54% $93 : 2.93% $9B : 0.00% + $84 : 0.00% $8C : 1.79% $94 : 1.74% $9C : 0.00% + $85 : 0.00% $8D : 2.66% $95 : 4.51% $9D : 0.00% + $86 : 0.00% $8E : 3.75% $96 : 1.22% $9E : 0.00% + $87 : 0.00% $8F : 1.47% $97 : 1.38% $9F : 0.00% + $88 : 1.68% $90 : 2.04% $98 : 0.24% + + $E0 : 0.00% $E8 : 0.00% $F0 : 0.00% $F8 : 0.00% + $E1 : 0.00% $E9 : 0.00% $F1 : 0.00% $F9 : 0.00% + $E2 : 0.00% $EA : 0.00% $F2 : 0.00% $FA : 0.00% + $E3 : 0.00% $EB : 0.00% $F3 : 0.00% $FB : 0.00% + $E4 : 0.00% $EC : 0.00% $F4 : 0.00% $FC : 0.00% + $E5 : 0.00% $ED : 0.00% $F5 : 0.00% $FD : 0.00% + $E6 : 0.00% $EE : 0.00% $F6 : 0.00% $FE : 0.00% + $E7 : 0.00% $EF : 0.00% $F7 : 0.00% + +The table shows that the former part of the codes has larger frequency values. The latter part, which is mapped to complicated Kanji characters, has smaller frequency values. Let's get in more details. $82 has significantly high frequency, that is, over 50%. This is the code for Japanese Hiragana. Spoken Japanese language is said to be having over 70% Hiragana. This implies that assigning short codes to Hiragana improves the communication efficiency. In amateur radio conversation, Katakana is also often being used, and it is a good idea to assign short code to them as well as Hiragana. + +In MBCS, Hiragana is defined in the range of $829F-$82F2, which correspond to $021F-$0272 in the index. If this range is directly mapped to VARICODE, the bit length of each code becomes 15 to 16 bits including GAP. However, if it is mapped to $0080-$00D3, the bit length is shortened to 12 or 13 bits. Katakana is mapped to $0280-$02D6 in the index ($8340-$8396 in MBCS), so let us assign Katakana to $00D4-$012A. + +Another point we must consider in the code mapping is the effect to MBCS languages other than Japanese. My quick research shows that $0081-$00FE has no characters assigned (defined as the first byte), and therefore this range should cause no problem. Characters in $0100-$012A are defined in Hangul and Chinese, but I do not know the frequency of them. In addition, non-MBCS language other than English might have characters assigned to this range. For these regions, it is a good idea to perform this translation by referring to the font set in the receiving side. In addition, since the translation scheme must be changed according to font sets, let Japanese characters in range $E040-$FEFF be translated into $A040-$BEFF, which has no Japanese characters assigned. The frequency of characters in this range is not so high, but this translation gives slightly better coding efficiency. In the index, $4840-$5F7F is translated into $1840-$2F7F. + + +Let us summarize the translation and mapping scheme here. + + $0000-$007F Same as PSK31 translation + $0080-$00D3 Translated to $021F-$0272 if Japanese font set + $00D4-$012A Translated to $0280-$02D6 if Japanese font set + $012B-$021E No translation, as is. + $021F-$0272 Translated to $0080-$00D3 if Japanese font set + $0273-$027F No translation, as is. + $0280-$02D6 Translated to $00D4-$012A if Japanese font set + $02D7-$183F No translation, as is. + $1840-$2F7F Translated to $4840-$5F7F if Japanese font set + $2F80-$483F No translation, as is. + $4840-$5F7F Translated to $1840-$2F7F if Japanese font set + +For instance, the longest code made by using this translation scheme is + $5F7F 110111111111101101101 (21Bits) +The last Japanese Character is + $2F7F 10110101111111101111 (20Bits) + + + +[Modulation] + +In Japan, all the PSK31 QSOs using Japanese characters concatenates two VARICODEs to send one MBCS character. If the VARICODE shown above is used, the compatibility with existing PSK31 programs will be lost. + +For this reason, I have decided not to use PSK31, but to make use of GMSK (BT=1.0) as an experimental modulation. GMSK is a sort of FSK, but it also is a brother of PSK in a sense. The sound of GMSK is similar to that of PSK31, but has different spectrum, with which the user can distinguish between them. Theoretically, GMSK have no amplitude component, and therefore does not require the linearity of the transmitter (isn't this FB?). + +Like PSK31, MMVARI sends 0 by reverting the symbol and 1 by keeping the symbol. With this coding, the user does not have to take care of USB/LSB heterodyne. The detail of GMSK is beyond scope of this project. Please refer to other books. + + +[Experimental program] + +I made a PC soundcard program, MMVARI, to implement the proposed scheme. Since the objective of this project is new VARICODE experimentation, MMVARI are: + +1) Implementing only basic functions for standard QSO. +2) Providing Japanese menu only, but can be used in any MBCS languages. Non-MBCS languages, such as English, are out of scope of this project. + +I would like to see the feasibility first, and after then improve the engine and cosmetics. + + +[Appendix] + +An example C code for the index translation + +static int SwapHiragana(int index) +{ + if( index <= 0x00d3 ){ // $80-$D3 + index += 0x21f - 0x0080; // $80-$D3 to Hiragana + } + else if( index <= 0x12a ){ // $D4-$12A + index += 0x280 - 0x00d4; // $D4-$12A to Katakana + } + else if( (index >= 0x021f) && (index <= 0x0272) ){ // Hiragana + index -= 0x21f - 0x0080; // Hiragana to $80-$D3 + } + else if( (index >= 0x0280) && (index <= 0x02d6) ){ // Katakana + index -= 0x280 - 0x00d4; // Katakana to $D4-$12A + } + else if( (index >= 0x1840) && (index <= 0x2f7f) ){ + index += 0x4840 - 0x1840; + } + else if( (index >= 0x4840) && (index <= 0x5f7f) ){ + index -= 0x4840 - 0x1840; + } +} + +UINT Index2Mbc(int index, BOOL fJA) +{ +const BYTE _tIndex2Ascii[]={ + 0x20,0x65,0x74,0x6F,0x61,0x69,0x6E,0x72, /*00*/ + 0x73,0x6C,0x0A,0x0D,0x68,0x64,0x63,0x2D, /*08*/ + 0x75,0x6D,0x66,0x70,0x3D,0x2E,0x67,0x79, /*10*/ + 0x62,0x77,0x54,0x53,0x2C,0x45,0x76,0x41, /*18*/ + 0x49,0x4F,0x43,0x52,0x44,0x30,0x4D,0x31, /*20*/ + 0x6B,0x50,0x4C,0x46,0x4E,0x78,0x42,0x32, /*28*/ + 0x09,0x3A,0x29,0x28,0x47,0x33,0x48,0x55, /*30*/ + 0x35,0x57,0x22,0x36,0x5F,0x2A,0x58,0x34, /*38*/ + 0x59,0x4B,0x27,0x38,0x37,0x2F,0x56,0x39, /*40*/ + 0x7C,0x3B,0x71,0x7A,0x3E,0x24,0x51,0x2B, /*48*/ + 0x6A,0x3C,0x5C,0x23,0x5B,0x5D,0x4A,0x21, /*50*/ + 0x00,0x5A,0x3F,0x7D,0x7B,0x26,0x40,0x5E, /*58*/ + 0x25,0x7E,0x01,0x0C,0x60,0x04,0x02,0x06, /*60*/ + 0x11,0x10,0x1E,0x07,0x08,0x1B,0x17,0x14, /*68*/ + 0x1C,0x05,0x15,0x16,0x0B,0x0E,0x03,0x18, /*70*/ + 0x19,0x1F,0x0F,0x12,0x13,0x7F,0x1A,0x1D, /*78*/ +}; + + if( index <= 0x007f ){ + index = _tIndex2Ascii[index]; + } + else if( fJA ){ + index = SwapHiragana(index); + } + + UINT mbc; + int m, b; + if( index >= 0x0100 ){ + index -= 0x0100; + m = index % 192; + b = index / 192; + mbc = 0x8140 + m + (b * 256); + } + else { + mbc = index; + } + return mbc; +} + +int Mbc2Index(UINT mbc, BOOL fJA) +{ +const BYTE _tAscii2Index[]={ + 0x58,0x62,0x66,0x76,0x65,0x71,0x67,0x6B, /*00*/ + 0x6C,0x30,0x0A,0x74,0x63,0x0B,0x75,0x7A, /*08*/ + 0x69,0x68,0x7B,0x7C,0x6F,0x72,0x73,0x6E, /*10*/ + 0x77,0x78,0x7E,0x6D,0x70,0x7F,0x6A,0x79, /*18*/ + 0x00,0x57,0x3A,0x53,0x4D,0x60,0x5D,0x42, /*20*/ + 0x33,0x32,0x3D,0x4F,0x1C,0x0F,0x15,0x45, /*28*/ + 0x25,0x27,0x2F,0x35,0x3F,0x38,0x3B,0x44, /*30*/ + 0x43,0x47,0x31,0x49,0x51,0x14,0x4C,0x5A, /*38*/ + 0x5E,0x1F,0x2E,0x22,0x24,0x1D,0x2B,0x34, /*40*/ + 0x36,0x20,0x56,0x41,0x2A,0x26,0x2C,0x21, /*48*/ + 0x29,0x4E,0x23,0x1B,0x1A,0x37,0x46,0x39, /*50*/ + 0x3E,0x40,0x59,0x54,0x52,0x55,0x5F,0x3C, /*58*/ + 0x64,0x04,0x18,0x0E,0x0D,0x01,0x12,0x16, /*60*/ + 0x0C,0x05,0x50,0x28,0x09,0x11,0x06,0x03, /*68*/ + 0x13,0x4A,0x07,0x08,0x02,0x10,0x1E,0x19, /*70*/ + 0x2D,0x17,0x4B,0x5C,0x48,0x5B,0x61,0x7D, /*78*/ +}; + int index, m, b; + if( mbc >= 0x8100 ){ + if( (mbc & 0x00ff) >= 0x0040 ){ + mbc -= 0x8100; + m = mbc % 256; + b = mbc / 256; + index = 0x100 - 0x40 + m + (b * 192); + } + else { + return -1; /* error */ + } + } + else { + index = mbc; + } + if( index <= 0x007f ){ + index = _tAscii2Index[index]; + } + else if( fJA ){ + index = SwapHiragana(index); + } + return index; +} + diff --git a/FEdit.cpp b/FEdit.cpp new file mode 100644 index 0000000..bee26a8 --- /dev/null +++ b/FEdit.cpp @@ -0,0 +1,308 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "FEdit.h" +#include "ComLib.h" +#include "Main.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//TFileEdit *FileEdit; +//--------------------------------------------------------------------------- +__fastcall TFileEdit::TFileEdit(TComponent* Owner) + : TForm(Owner) +{ + m_hWnd = NULL; + m_uMsg = 0; + m_FileName = ""; + REdit->Font->Pitch = fpFixed; + if( sys.m_MsgEng ){ + REdit->Font->Name = "Courier New"; + REdit->Font->Charset = ANSI_CHARSET; + } + else { + REdit->Font->Name = "MS ゴシック"; + REdit->Font->Charset = SHIFTJIS_CHARSET; + + KF->Caption = "ファイル(&F)"; + KFN->Caption = "メモ帳に切り替え(&N)"; + KFX->Caption = "終了(&X)"; + KE->Caption = "編集(&E)"; + KFA->Caption = "名前を付けて保存(&A)..."; + KEU->Caption = "元に戻す(&U)"; + KEC->Caption = "切り取り(&T)"; + KECP->Caption = "コピー(&C)"; + KEP->Caption = "貼り付け(&P)"; + KEA->Caption = "すべて選択(&L)"; + KS->Caption = "検索(&S)"; + KSS->Caption = "検索(&F)..."; + KSN->Caption = "次を検索(&N)"; + } + for( int i = 0; i < KE->Count; i++ ){ + TMenuItem *pMenu = new TMenuItem(this); + pMenu->Caption = KE->Items[i]->Caption; + pMenu->OnClick = KE->Items[i]->OnClick; + PopupMenu->Items->Add(pMenu); + } + m_fDelFile = FALSE; + m_InitFirst = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::Execute(LPCSTR pName, BOOL fReadOnly) +{ + DWORD dw = ::GetFileAttributes(pName); + if( (dw != 0xffffffff) && (dw & FILE_ATTRIBUTE_READONLY) ){ + fReadOnly = TRUE; + } + REdit->ReadOnly = fReadOnly; + AnsiString as = pName; + if( fReadOnly ) as += sys.m_MsgEng ? " (Read only)" : " (読み取り専用)"; + Caption = as; + CWaitCursor tw; + m_FileName = pName; + OnWave(); + try { + REdit->Lines->LoadFromFile(pName); + } + catch(...){ + FILE *fp; + if( (fp = fopen(pName, "rt")) != NULL ){ + OnWave(); + char bf[2048]; + REdit->Lines->Clear(); + while(!feof(fp)){ + if( fgets(bf, sizeof(bf), fp) ){ + ClipLF(bf); + REdit->Lines->Add(bf); + } + } + fclose(fp); + REdit->ReadOnly = TRUE; + } + else { + ErrorMB(sys.m_MsgEng ? "Sorry, could not open <%s>...":"<%s>をオープンできませんでした", pName); + Close(); + return; + } + } + if( m_fDelFile ){ + m_fDelFile = FALSE; + unlink(pName); + } + REdit->Modified = FALSE; + m_InitFirst = FALSE; + OnWave(); + AdjustTop(); + Show(); + if( !::IsWindowEnabled(Handle) ) ::EnableWindow(Handle, TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::Execute(AnsiString &as, LPCSTR pTitle, LPCSTR pName) +{ + Caption = pTitle; + m_FileName = pName; + CWaitCursor tw; + REdit->Text = as; + REdit->ReadOnly = FALSE; + REdit->Modified = FALSE; + m_InitFirst = TRUE; + OnWave(); + Show(); +} +//--------------------------------------------------------------------- +void __fastcall TFileEdit::FormCloseQuery(TObject *Sender, bool &CanClose) +{ + if( REdit->Modified ){ + int r = YesNoCancelMB(sys.m_MsgEng ? "Overwrite to the file (%s) ?" : "ファイル (%s) に上書きしますか?", m_FileName.c_str()); + switch(r){ + case IDYES: + { + CWaitCursor w; + REdit->Lines->SaveToFile(m_FileName); + } + break; + case IDCANCEL: + CanClose = FALSE; + return; + } + } + CanClose = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KECClick(TObject *Sender) +{ + REdit->CutToClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KECPClick(TObject *Sender) +{ + REdit->CopyToClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KEPClick(TObject *Sender) +{ + REdit->PasteFromClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KEUClick(TObject *Sender) +{ + if( REdit->HandleAllocated() ){ + SendMessage(REdit->Handle, EM_UNDO, 0, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KEAClick(TObject *Sender) +{ + REdit->SelectAll(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KEClick(TObject *Sender) +{ + BOOL f = !REdit->ReadOnly; + KEU->Enabled = f && REdit->Modified; + KECP->Enabled = REdit->SelLength; + KEC->Enabled = f && KECP->Enabled; + KEP->Enabled = f && ::IsClipboardFormatAvailable(CF_TEXT); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KFAClick(TObject *Sender) +{ + AnsiString FileName = m_FileName.c_str(); + SetEXT(FileName.c_str(), ""); + LPCSTR pEXT = GetEXT(m_FileName.c_str()); + SaveDialog->FileName = FileName; + SaveDialog->DefaultExt = pEXT; + if( SaveDialog->Execute() ) { + // Options + OverwritePrompt = True thus no need to check. + REdit->Lines->SaveToFile(SaveDialog->FileName); + m_FileName = SaveDialog->FileName; + REdit->Modified = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KFXClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::PopupMenuPopup(TObject *Sender) +{ + KEClick(NULL); + for( int i = 0; i < PopupMenu->Items->Count; i++ ){ + PopupMenu->Items->Items[i]->Enabled = KE->Items[i]->Enabled; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KSSClick(TObject *Sender) +{ + FindDialog->Execute(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::FindDialogFind(TObject *Sender) +{ + int FoundAt, StartPos, ToEnd; + // 検索は現在選択されている場所から開始される + // 何も選択されていない場合は, + // テキストの最初から開始される + if(REdit->SelLength){ + StartPos = REdit->SelStart + REdit->SelLength; + } + else { + StartPos = 0; + } + // ToEnd は検索範囲の文字数を示す + ToEnd = REdit->Text.Length() - StartPos; + + + TSearchTypes stype; + if( FindDialog->Options.Contains(frMatchCase) ) stype << stMatchCase; + if( FindDialog->Options.Contains(frWholeWord) ) stype << stWholeWord; + FoundAt = REdit->FindText(FindDialog->FindText, StartPos, ToEnd, stype); + if( FoundAt != -1 ){ + REdit->SetFocus(); + REdit->SelStart = FoundAt; + REdit->SelLength = FindDialog->FindText.Length(); + keybd_event(VK_RIGHT, 0, 0, 0); + keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0); + Application->ProcessMessages(); + REdit->SelStart = FoundAt; + REdit->SelLength = FindDialog->FindText.Length(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KSClick(TObject *Sender) +{ + KSN->Enabled = !FindDialog->FindText.IsEmpty(); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::KFNClick(TObject *Sender) +{ + CWaitCursor w; + REdit->Lines->SaveToFile(m_FileName); + REdit->Modified = FALSE; + + Close(); + + char bf[256]; + sprintf(bf, "NOTEPAD %s", m_FileName.c_str()); + WinExec(bf, SW_SHOWDEFAULT); +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::FormClose(TObject *Sender, TCloseAction &Action) +{ + if( (Action == caHide) && m_hWnd && m_uMsg && m_wParam){ + ::PostMessage(m_hWnd, m_uMsg, m_wParam, DWORD(this)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::SetEvent(HWND hWnd, UINT uMsg, DWORD wParam) +{ + m_hWnd = hWnd; + m_uMsg = uMsg; + m_wParam = wParam; +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::FormPaint(TObject *Sender) +{ + if( m_InitFirst ){ + m_InitFirst = FALSE; + const short _tt[]={ + VK_CONTROL, VK_END, VK_END|0x8000, VK_CONTROL|0x8000, + 0 + }; + KeyEvent(_tt); + AdjustTop(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFileEdit::AdjustTop(void) +{ + int ot = MainVARI->GetOverlayTop(); + if( ot > Top ){ + Top = ot; + } +} +//--------------------------------------------------------------------------- + + + diff --git a/FEdit.dfm b/FEdit.dfm new file mode 100644 index 0000000..4e6b248 Binary files /dev/null and b/FEdit.dfm differ diff --git a/FEdit.h b/FEdit.h new file mode 100644 index 0000000..b33ed43 --- /dev/null +++ b/FEdit.h @@ -0,0 +1,102 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef FEditH +#define FEditH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +enum TFontPitch { fpDefault, fpVariable, fpFixed }; //ja7ude 0522 +//--------------------------------------------------------------------------- +class TFileEdit : public TForm +{ +__published: // IDE 管理のコンポーネント + TRichEdit *REdit; + TMainMenu *MainMenu1; + TMenuItem *KF; + TMenuItem *KE; + TMenuItem *KFA; + TMenuItem *KEC; + TMenuItem *KECP; + TMenuItem *KEP; + TSaveDialog *SaveDialog; + TMenuItem *N1; + TMenuItem *KEU; + TMenuItem *N2; + TMenuItem *KEA; + TMenuItem *N3; + TMenuItem *KFX; + TPopupMenu *PopupMenu; + TFindDialog *FindDialog; + TMenuItem *KS; + TMenuItem *KSS; + TMenuItem *KSN; + TMenuItem *KFN; + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + + void __fastcall KECClick(TObject *Sender); + void __fastcall KECPClick(TObject *Sender); + void __fastcall KEPClick(TObject *Sender); + void __fastcall KFAClick(TObject *Sender); + void __fastcall KEUClick(TObject *Sender); + void __fastcall KEAClick(TObject *Sender); + + void __fastcall KEClick(TObject *Sender); + void __fastcall KFXClick(TObject *Sender); + void __fastcall PopupMenuPopup(TObject *Sender); + + void __fastcall KSSClick(TObject *Sender); + void __fastcall FindDialogFind(TObject *Sender); + void __fastcall KSClick(TObject *Sender); + void __fastcall KFNClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormPaint(TObject *Sender); + +private: // ユーザー宣言 + BOOL m_InitFirst; + AnsiString m_FileName; + HWND m_hWnd; + UINT m_uMsg; + DWORD m_wParam; + BOOL m_fDelFile; +private: + void __fastcall AdjustTop(void); + +public: // ユーザー宣言 + __fastcall TFileEdit(TComponent* Owner); + void __fastcall SetEvent(HWND hWnd, UINT uMsg, DWORD wParam); + void __fastcall Execute(LPCSTR pName, BOOL fReadOnly); + void __fastcall Execute(AnsiString &as, LPCSTR pTitle, LPCSTR pName); + + inline void __fastcall SetWordWrap(BOOL ww){REdit->WordWrap = ww;}; + inline void __fastcall SetDelFile(BOOL fDel){m_fDelFile = fDel;}; +}; +//--------------------------------------------------------------------------- +//extern PACKAGE TFileEdit *FileEdit; +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +#endif + diff --git a/FSK8250/App.ico b/FSK8250/App.ico new file mode 100644 index 0000000..7871a72 Binary files /dev/null and b/FSK8250/App.ico differ diff --git a/FSK8250/Main.cpp b/FSK8250/Main.cpp new file mode 100644 index 0000000..d76b8a1 --- /dev/null +++ b/FSK8250/Main.cpp @@ -0,0 +1,457 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Main.h" +SYS sys; +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//--------------------------------------------------------------------------- +void __fastcall SetDirName(LPSTR t, LPCSTR pName) +{ + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + AnsiString Dir; + + ::_splitpath( pName, drive, dir, name, ext ); + Dir = drive; + Dir += dir; + strncpy(t, Dir.c_str(), MAX_PATH-1); +} +//--------------------------------------------------------------------------- +void __fastcall SetEXT(LPSTR t, LPCSTR pExt) +{ + LPSTR p = LASTP(t); + for( ; p > t; p-- ){ + if( *p == '.' ){ + p++; + strcpy(p, pExt); + return; + } + } +} +//*************************************************************************** +// TExtFSK (MainWindow) class +//--------------------------------------------------------------------------- +__fastcall TComFSK::TComFSK(TComponent* Owner) + : TForm(Owner) +{ + m_DisEvent = 1; + m_Left = 0; + m_Top = 0; + m_hPort = INVALID_HANDLE_VALUE; + m_X = 0; + m_Para = 45 << 16; + + m_fMsg = TRUE; + m_fCheckError = FALSE; + m_fLimitSpeed = FALSE; + m_LimitMargin = 3; + + m_strIniName = sys.m_ModuleName; + SetEXT(m_strIniName.c_str(), "ini"); + PortName->ItemIndex = 0; + + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + + ::_splitpath( sys.m_ModuleName, drive, dir, name, ext ); + strupr(name); + AnsiString as = name; + as += " "VERNO; + Caption = as; + + ReadIniFile(); + + CBERR->Checked = m_fCheckError; + CBLMT->Checked = m_fLimitSpeed; + + Left = m_Left; + Top = m_Top; + WindowState = TWindowState(m_WindowState); + m_DisEvent = 0; +} +//--------------------------------------------------------------------------- +// para: Upper16bits Speed(eg. 45) +// Lower16bits b1-b0 Stop (0-1, 1-1.5, 2-2) +// b5-b2 Length +void __fastcall TComFSK::SetPara(LONG para) +{ + m_Para = para; + AnsiString as = int(para >> 16); + as += " baud"; + LB->Caption = as; + OpenPort(); +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::FormClose(TObject *Sender, TCloseAction &Action) +{ + m_WindowState = WindowState; + if( m_WindowState == wsNormal ){ + m_Left = Left; + m_Top = Top; + } + + if( IsOpen() && m_ptt ){ + SetPTT(FALSE, FALSE); + } + + ClosePort(); + WriteIniFile(); +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::ReadIniFile(void) +{ + TMemIniFile *pIniFile = new TMemIniFile(m_strIniName); + + m_Top = pIniFile->ReadInteger("Window", "Top", m_Top); + m_Left = pIniFile->ReadInteger("Window", "Left", m_Left); + if( m_Top < 0 ) m_Top = 0; + if( m_Left < 0 ) m_Left = 0; + + m_WindowState = (TWindowState)pIniFile->ReadInteger("Window", "State", WindowState); + + AnsiString as = pIniFile->ReadString("Settings", "Port", "COM1"); + int n = PortName->Items->IndexOf(as); + if( n < 0 ){ + n = atoi(as.c_str()); + if( n < 0 ) n = 0; + } + PortName->ItemIndex = n; + RGPTT->ItemIndex = pIniFile->ReadInteger("Settings", "PTT", RGPTT->ItemIndex); + RGSTOP->ItemIndex = pIniFile->ReadInteger("Settings", "STOP", RGSTOP->ItemIndex); + CBInvPTT->Checked = pIniFile->ReadInteger("Settings", "InvPTT", CBInvPTT->Checked); + m_fCheckError = pIniFile->ReadInteger("Settings", "CheckError", m_fCheckError); + m_fLimitSpeed = pIniFile->ReadInteger("Settings", "LimitSpeed", m_fLimitSpeed); + m_LimitMargin = pIniFile->ReadInteger("Settings", "LimitMargin", m_LimitMargin); + int ver = pIniFile->ReadInteger("Settings", "VER", 0); + if( ver < VERINI ) RGSTOP->ItemIndex = 1; + delete pIniFile; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::WriteIniFile(void) +{ + TMemIniFile *pIniFile = new TMemIniFile(m_strIniName); + pIniFile->WriteInteger("Window", "Top", m_Top); + pIniFile->WriteInteger("Window", "Left", m_Left); + pIniFile->WriteInteger("Window", "State", WindowState); + pIniFile->WriteInteger("Settings", "VER", VERINI); + pIniFile->WriteString("Settings", "Port", PortName->Items->Strings[PortName->ItemIndex]); + pIniFile->WriteInteger("Settings", "PTT", RGPTT->ItemIndex); + pIniFile->WriteInteger("Settings", "InvPTT", CBInvPTT->Checked); + pIniFile->WriteInteger("Settings", "STOP", RGSTOP->ItemIndex); + pIniFile->WriteInteger("Settings", "CheckError", m_fCheckError); + pIniFile->WriteInteger("Settings", "LimitSpeed", m_fLimitSpeed); + pIniFile->WriteInteger("Settings", "LimitMargin", m_LimitMargin); + pIniFile->UpdateFile(); + delete pIniFile; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::UpdateComStat(void) +{ + char bf[128]; + + wsprintf(bf, "Status:%s", m_hPort != INVALID_HANDLE_VALUE ? "OK" : "NG"); + LComStat->Color = m_hPort != INVALID_HANDLE_VALUE ? clBtnFace : clRed; + LComStat->Caption = bf; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::OpenPort(void) +{ + ClosePort(); + OpenPort_(); + UpdateComStat(); + SetPTT(FALSE, FALSE); +} +//--------------------------------------------------------------------------- +BOOL __fastcall TComFSK::OpenPort_(void) +{ + AnsiString pname = PortName->Items->Strings[PortName->ItemIndex]; + + m_hPort = ::CreateFile( pname.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if( m_hPort == INVALID_HANDLE_VALUE ){ + AnsiString as = "\\\\.\\"; + as += pname; + m_hPort = ::CreateFile( as.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + } + if( m_hPort == INVALID_HANDLE_VALUE ) return FALSE; + + if( ::SetupComm( m_hPort, DWORD(256), DWORD(2) ) == FALSE ){ + ::CloseHandle(m_hPort); + m_hPort = INVALID_HANDLE_VALUE; + return FALSE; + } + ::PurgeComm( m_hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); + + COMMTIMEOUTS TimeOut; + + TimeOut.ReadIntervalTimeout = 0xffffffff; + TimeOut.ReadTotalTimeoutMultiplier = 0; + TimeOut.ReadTotalTimeoutConstant = 0; + TimeOut.WriteTotalTimeoutMultiplier = 0; + TimeOut.WriteTotalTimeoutConstant = 1000; + if( !::SetCommTimeouts( m_hPort, &TimeOut ) ){ + ::CloseHandle( m_hPort ); + m_hPort = INVALID_HANDLE_VALUE; + return FALSE; + } + + ::GetCommState( m_hPort, &m_dcb ); + m_dcb.fBinary = TRUE; + m_dcb.BaudRate = m_Para >> 16; // BAUD + m_dcb.ByteSize = 5; // 5 bits length + m_dcb.StopBits = BYTE(RGSTOP->ItemIndex); + m_dcb.Parity = NOPARITY; + m_dcb.XonChar = 0x11; // XON + m_dcb.XoffChar = 0x13; // XOFF + m_dcb.fParity = 0; + m_dcb.fOutxCtsFlow = FALSE; + m_dcb.fInX = m_dcb.fOutX = FALSE; + m_dcb.fOutxDsrFlow = FALSE; + m_dcb.EvtChar = 0x0d; + m_dcb.fRtsControl = RTS_CONTROL_DISABLE; + m_dcb.fDtrControl = DTR_CONTROL_DISABLE; + m_dcb.fTXContinueOnXoff = FALSE; + m_dcb.XonLim = USHORT(256/4); + m_dcb.XoffLim = USHORT(256*3/4); + m_dcb.DCBlength = sizeof( DCB ); + + if( !::SetCommState( m_hPort, &m_dcb ) ){ + ::CloseHandle( m_hPort ); + m_hPort = INVALID_HANDLE_VALUE; + return FALSE; + } + + if( !::SetCommMask( m_hPort, EV_RXFLAG ) ){ + ::CloseHandle(m_hPort); + m_hPort = INVALID_HANDLE_VALUE; + return FALSE; + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::ClosePort(void) +{ + DeleteMMTimer(); + if( IsOpen() ){ + ::CloseHandle(m_hPort); + m_hPort = INVALID_HANDLE_VALUE; + } + UpdateComStat(); +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::SetPort(int port, int sw) +{ + switch(port){ + case ptTXD: + ::EscapeCommFunction(m_hPort, sw ? SETBREAK : CLRBREAK); + break; + case ptRTS: + ::EscapeCommFunction(m_hPort, sw ? SETRTS : CLRRTS); + break; + case ptDTR: + ::EscapeCommFunction(m_hPort, sw ? SETDTR : CLRDTR); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::SetPTT(int sw, int msg) +{ + m_ptt = sw; + if( CBInvPTT->Checked ){ + sw = sw ? 0 : 1; + } + if( !m_ptt && m_ummTimerID ){ + DeleteMMTimer(); + } + SetPort(RGPTT->ItemIndex ? ptDTR : ptRTS, sw); + if( m_ptt ){ + m_dwPending = 0; + } + + m_X = 0; + if( msg ){ + if( WindowState == wsMinimized) return; + Memo->Lines->Add(m_ptt ? "PTT ON" : "PTT OFF"); + } +} +//--------------------------------------------------------------------------- +void CALLBACK mmTimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) +{ + ASSERT(dwUser); + + TComFSK *pComm = (TComFSK *)dwUser; + if( uID != pComm->m_ummTimerID ) return; + + pComm->DoTimer(); +} +//----------------------------------------------------------------- +void __fastcall TComFSK::DoTimer(void) +{ + if( m_dwPending ){ + if( m_hPort != INVALID_HANDLE_VALUE ){ + ::TransmitCommChar(m_hPort, BYTE(m_dwPending & 0x00ff)); + } + m_dwPending = 0; + } +} +//----------------------------------------------------------------- +void __fastcall TComFSK::CreateMMTimer(void) +{ + if( !m_fLimitSpeed ) return; + + int baud = m_Para >> 16; + if( baud <= 0 ) return; + + m_ummTimerID = 0; + if( ::timeGetDevCaps(&m_TimeCaps, sizeof(m_TimeCaps)) == TIMERR_NOERROR ){ + ::timeBeginPeriod(m_TimeCaps.wPeriodMin); + double dblSymTime = (14 + RGSTOP->ItemIndex) * 500.0 / double(baud); + double dblLmtTime = dblSymTime + m_LimitMargin; + int lmttime = int(dblLmtTime + 0.5); + if( m_fMsg && (WindowState == wsNormal) ){ + char bf[64]; + wsprintf(bf, "S=%d.%02dms, T=%ums", int(dblSymTime), int(dblSymTime * 100.0) % 100, lmttime); + Memo->Lines->Add(bf); + } + m_ummTimerID = ::timeSetEvent(lmttime, 0, mmTimeProc, DWORD(this), TIME_PERIODIC); + } + if( !m_ummTimerID ){ + if( m_fMsg ){ + Memo->Lines->Add("MM timer is not supported."); + } + } + m_fMsg = FALSE; +} +//----------------------------------------------------------------- +void __fastcall TComFSK::DeleteMMTimer(void) +{ + if( m_ummTimerID ){ + ::timeKillEvent(m_ummTimerID); + m_ummTimerID = 0; + ::timeEndPeriod(m_TimeCaps.wPeriodMin); + } +} +//----------------------------------------------------------------- +// 送信ビジーかどうか調べる +int __fastcall TComFSK::IsBusy(void) +{ + if( m_ummTimerID ){ + return m_dwPending ? 1 : 0; + } + if( IsOpen() ){ + if( m_dwPending ){ + if( TransmitCommChar(m_hPort, BYTE(m_dwPending & 0x00ff)) ){ + m_dwPending = 0; + } + return TRUE; + } + } + if( m_fCheckError || m_fLimitSpeed ) return FALSE; + if( !IsOpen() ) return FALSE; + + COMSTAT ComStat; + DWORD dwErrorFlags; + + ClearCommError(m_hPort, &dwErrorFlags, &ComStat); + return ComStat.fTxim; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::PutChar(BYTE c) +{ + if( !m_ptt ) return; + + if( m_fLimitSpeed && !m_ummTimerID ) CreateMMTimer(); + + if( m_ummTimerID ){ + m_dwPending = c | 0x8000; + } + else if( IsOpen() ){ + if( !TransmitCommChar(m_hPort, c) ){ + if( m_fCheckError ){ + m_dwPending = c | 0x8000; + } + } + } + if( WindowState == wsMinimized) return; + + char bf[128]; + if( m_X ){ + int n = Memo->Lines->Count; + if( n ) n--; + strcpy(bf, AnsiString(Memo->Lines->Strings[n]).c_str()); + wsprintf(&bf[strlen(bf)], " %02X", c); + if( !m_ptt ) return; + Memo->Lines->Strings[n] = bf; + } + else { + wsprintf(bf, "%02X", c); + Memo->Lines->Add(bf); + } + m_X++; + if( m_X >= 8 ) m_X = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::PortNameChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + OpenPort(); +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::SBMinClick(TObject *Sender) +{ + if( m_DisEvent ) return; + + if( WindowState == wsNormal ){ + m_Left = Left; + m_Top = Top; + } + + WindowState = wsMinimized; + m_WindowState = wsMinimized; + + Memo->Lines->Clear(); + m_X = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::CBInvPTTClick(TObject *Sender) +{ + if( m_DisEvent ) return; + SetPTT(m_ptt, FALSE); +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::CBERRClick(TObject *Sender) +{ + m_fCheckError = CBERR->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TComFSK::CBLMTClick(TObject *Sender) +{ + m_fLimitSpeed = CBLMT->Checked; + if( m_ptt && m_fLimitSpeed ){ + CreateMMTimer(); + } + else { + DeleteMMTimer(); + } +} +//--------------------------------------------------------------------------- + diff --git a/FSK8250/Main.dfm b/FSK8250/Main.dfm new file mode 100644 index 0000000..2b6b1d2 Binary files /dev/null and b/FSK8250/Main.dfm differ diff --git a/FSK8250/Main.h b/FSK8250/Main.h new file mode 100644 index 0000000..d1137a2 --- /dev/null +++ b/FSK8250/Main.h @@ -0,0 +1,113 @@ +//--------------------------------------------------------------------------- +#ifndef MainH +#define MainH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#define NDEBUG // Remove this symbol, if you would like to do debug +#include +#define ASSERT(c) assert(c) +//--------------------------------------------------------------------------- +#define VERNO "1.04" +#define VERINI 1 +//--------------------------------------------------------------------------- +template T LASTP(T p){ + int l = strlen(p); + if( l ) p += (l-1); + return p; +}; +enum { + ptTXD, + ptRTS, + ptDTR, +}; +void __fastcall SetDirName(LPSTR t, LPCSTR pName); + +typedef struct { // Should not put a class into the member + DWORD m_dwVersion; + int m_WinNT; + char m_BgnDir[MAX_PATH]; + char m_ModuleName[MAX_PATH]; +}SYS; +extern SYS sys; +//--------------------------------------------------------------------------- +class TComFSK : public TForm +{ +__published: // IDE + TMemo *Memo; + TLabel *L1; + TComboBox *PortName; + TLabel *LComStat; + TRadioGroup *RGPTT; + TCheckBox *CBInvPTT; + TSpeedButton *SBMin; + TLabel *LB; + TRadioGroup *RGSTOP; + TCheckBox *CBERR; + TCheckBox *CBLMT; + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall PortNameChange(TObject *Sender); + + void __fastcall SBMinClick(TObject *Sender); + void __fastcall CBInvPTTClick(TObject *Sender); + + + + void __fastcall CBERRClick(TObject *Sender); + void __fastcall CBLMTClick(TObject *Sender); +private: + int m_Left; + int m_Top; + int m_WindowState; + int m_DisEvent; + int m_ptt; + int m_X; + AnsiString m_strIniName; + + LONG m_Para; + HANDLE m_hPort; + DCB m_dcb; + + BOOL m_fCheckError; + BOOL m_fLimitSpeed; + int m_LimitMargin; + + BOOL m_fBusy; + DWORD m_dwPending; + + BOOL m_fMsg; + TIMECAPS m_TimeCaps; + UINT m_ummTimerID; +private: + void __fastcall ReadIniFile(void); + void __fastcall WriteIniFile(void); + + inline int __fastcall IsOpen(void){ return m_hPort != INVALID_HANDLE_VALUE;}; + void __fastcall UpdateComStat(void); + void __fastcall OpenPort(void); + BOOL __fastcall OpenPort_(void); + void __fastcall ClosePort(void); + void __fastcall SetPort(int port, int sw); + +public: + __fastcall TComFSK(TComponent* Owner); + void __fastcall SetPara(LONG para); + void __fastcall SetPTT(int sw, int msg); + int __fastcall IsBusy(void); + void __fastcall PutChar(BYTE c); + void __fastcall CreateMMTimer(void); + void __fastcall DeleteMMTimer(void); + void __fastcall DoTimer(void); + + friend void CALLBACK mmTimeProc(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); +}; +//--------------------------------------------------------------------------- +#endif diff --git a/FSK8250/api.txt b/FSK8250/api.txt new file mode 100644 index 0000000..e5d2ce6 --- /dev/null +++ b/FSK8250/api.txt @@ -0,0 +1,57 @@ +========================================= +◎MMTTY, MMSSTV, MMVARIとのインターフェース +========================================= + EXTFSK.DLLは以下の5つのファンクションをエクスポートしなければなりません。 + +extern "C" LONG __declspec(dllexport) __stdcall extfskOpen(LONG para) +extern "C" void __declspec(dllexport) __stdcall extfskClose(void) +extern "C" LONG __declspec(dllexport) __stdcall extfskIsTxBusy(void) +extern "C" void __declspec(dllexport) __stdcall extfskPutChar(BYTE c) +extern "C" void __declspec(dllexport) __stdcall extfskSetPTT(LONG tx) + + 各ファンクションは、__stdcall呼び出し規約(ファンクション側でスタックを調整する)で記述され、エクスポートしている名前に修飾があってはいけません。ただし各ファンクションの名前はアンダスコア(_)が1つ付加していても構いません。MMTTYは例えばextfskOpenを探し、それに失敗すると、_extfskOpenを探します。 + + +LONG extfskOpen(LONG para) +~~~~~~~~~~~~~~~~~~~~~~~~~~ +[引数] + para:上位16ビット 速度(例:45) + 下位16ビット b1-b0 Stop (0-1, 1-1.5, 2-2) + b5-b2 Length (5, 6, 7, 8) +[戻値] + TRUE - 成功, FALSE - 失敗 +[解説] + ポートをオープンします。Stop2が指定されてもStop1.5でオープンして下さい。 + + 付属のサンプルではパラメータは無視され常にBaud=45.45, Stop=1.5でオープンされます。 + +void extfskClose(void) +~~~~~~~~~~~~~~~~~~~~~~ +[解説] + オープンしたポートをクローズします。 + +LONG extfskIsTxBusy(void) +~~~~~~~~~~~~~~~~~~~~~~~~~~ +[戻値] + TRUE - バッファがいっぱい, FALSE - バッファは空きがある +[解説] + 送信バッファがいっぱいかどうかを返します。 +[参考] + 快適なDiddle操作を確保するため、送信バッファの個数は可能な限り小さくして下さい。ただし符号の連続タイミングを一定に保つ必要がある場合は最低限1個のバッファが必要です。付属のサンプルは1個のバッファを設けた例です。 + +void extfskPutChar(BYTE c) +~~~~~~~~~~~~~~~~~~~~~~~~~~ +[引数] + c:送信するデータ +[解説] + 送信するデータをバッファに1バイト書き込みます。MMTTYはこのファンクションを呼び出す前に必ずextfskIsTxBusy()を呼び出してバッファに空きがあるかどうかを調査します。 + +void extfskSetPTT(LONG tx) +~~~~~~~~~~~~~~~~~~~~~~~~~~ +[引数] + tx b0: 0-受信に切り替え, 1-送信に切り替え + b1: 0-画像スキャン停止中, 1-画像スキャン中 (MMSSTVのみ) +[解説] + PTTを切り替えます。MMTTYではb0のPTTのみがセットされますが、MMSSTVでは「RTS while SCAN」をONにしている場合、b1の画像スキャン情報もセットされます。 + +73, Mako diff --git a/FSK8250/eapi.txt b/FSK8250/eapi.txt new file mode 100644 index 0000000..139d4e1 --- /dev/null +++ b/FSK8250/eapi.txt @@ -0,0 +1,60 @@ +===== +Interface to MMTTY, MMSSTV, MMVARI +===== +EXTFSK.DLL must export the following five functions: + +extern "C" LONG __declspec(dllexport) __stdcall extfskOpen(LONG para) +extern "C" void __declspec(dllexport) __stdcall extfskClose(void) +extern "C" LONG __declspec(dllexport) __stdcall extfskIsTxBusy(void) +extern "C" void __declspec(dllexport) __stdcall extfskPutChar(BYTE c) +extern "C" void __declspec(dllexport) __stdcall extfskSetPTT(LONG tx) + +Each function must comply with __stdcall call function (stack is adjusted on the called function side). The function name could be preceded by one underscore (_). For example, if MMTTY fails to find extfskOpen(), it then looks for _extfskOpen(). + +----------------------------- +LONG extfskOpen( LONG para ) +----------------------------- +Parameters + Upper 16 bits of para: Speed (45 for example) + Lower 16 bits of para: b1-b0 Stop (0-1, 1-1.5, 2-2) + b5-b2 Length (5, 6, 7 or 8) +Returned value + TRUE = succeeded + FALSE = failed +Note + This function opens the port. Even if Stop 2 is specified, open with Stop 1.5. The sample code ignores the parameters and always opens with Baud = 45.45 and Stop = 1.5. + +------------------------- +void extfskClose( void ) +------------------------- +Note + This function closes the port. + +---------------------------- +LONG extfskIsTxBusy( void ) +---------------------------- +Returned value + TRUE = Buffer is full + FALSE = Buffer is not full +Note + This function returns the buffer status, that is, full or not full. For clean diddling, keep the buffer length as small as possible. For making continuous transmission, however, the buffer should have at least one slot capacity. The sample code has one slot for the buffer. + +------------------------------ +void extfskPutChar( BYTE c ) +------------------------------ +Parameter + c: TX data +Note + This function writes a byte data to the buffer. Before writing the data, MMTTY always calls extfskIsTxBusy() to see if the buffer can accept the new data. + +----------------------------- +void extfskSetPTT( LONG tx ) +----------------------------- +Parameter + tx b0: 0 ? Switch to RX, 1 ? Switch to TX + tx b1: 0 ? Not scanning RX image, 1 ? Scanning RX image (MMSSTV only) +Note + This function makes and breaks PTT. MMTTY uses bit 0 only. MMSSTV set bit 1 while it is scanning a RX image if RTS while scan option is enabled. + +73, Mako + diff --git a/FSK8250/fsk8250.bpr b/FSK8250/fsk8250.bpr new file mode 100644 index 0000000..11e253e --- /dev/null +++ b/FSK8250/fsk8250.bpr @@ -0,0 +1,179 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE セクション +# --------------------------------------------------------------------------- +# プロジェクトメイクファイルの以下のセクションは、IDE によって管理されます。 +# このセクションを変更する場合は、できるだけ IDE を使用するようにして +# ください。 +# --------------------------------------------------------------------------- + +VERSION = BCB.03 +# --------------------------------------------------------------------------- +PROJECT = fsk8250.fsk +OBJFILES = fsk8250.obj Main.obj +RESFILES = +DEFFILE = +RESDEPEN = $(RESFILES) Main.dfm +LIBFILES = +LIBRARIES = inet35.lib VCL35.lib +SPARELIBS = VCL35.lib inet35.lib +PACKAGES = VCLX35.bpi VCL35.bpi VCLDB35.bpi VCLDBX35.bpi bcbsmp35.bpi dclocx35.bpi \ + QRPT35.bpi TEEUI35.bpi VCLSMP35.bpi TEEDB35.bpi TEE35.bpi ibsmp35.bpi \ + NMFAST35.bpi INETDB35.bpi INET35.bpi +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +# --------------------------------------------------------------------------- +CFLAG1 = -WD -O2 -Hc -w -Ve -d -k- -vi -c -b- -w-par -w-inl -Vx +CFLAG2 = -I$(BCB)\include;$(BCB)\include\vcl -H=$(BCB)\lib\vcl35.csm +CFLAG3 = -Tkh30000 +PFLAGS = -U$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) \ + -I$(BCB)\include;$(BCB)\include\vcl -$L- -$D- -v -JPHN -M +RFLAGS = -i$(BCB)\include;$(BCB)\include\vcl +AFLAGS = /i$(BCB)\include /i$(BCB)\include\vcl /mx /w2 /zn /d_RTLDLL /dUSEPACKAGES +LFLAGS = -L$(BCB)\lib\obj;$(BCB)\lib;$(RELEASELIBPATH) -aa -Tpd -x -Gn +IFLAGS = +# --------------------------------------------------------------------------- +ALLOBJ = c0d32.obj sysinit.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=1 +Item0=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlHostApplication] +Count=3 +Item0=D:\mmvari\mmvari.exe +Item1=D:\Temp\mmtty\mmtty.exe +Item2=D:\Mmtty\mmtty.exe + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication=D:\mmvari\mmvari.exe + +!endif + +# --------------------------------------------------------------------------- +# MAKE セクション +# --------------------------------------------------------------------------- +# IDE はプロジェクトファイルのこのセクションは使用していません。 +# コマンドラインの MAKE ユーティリティを使用してビルドするためのものです。 +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = ilink32 +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +$(PROJECT): $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(CFLAG2) $(CFLAG3) -n$(@D) {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -fo$@ $< +# --------------------------------------------------------------------------- + \ No newline at end of file diff --git a/FSK8250/fsk8250.cbproj b/FSK8250/fsk8250.cbproj new file mode 100644 index 0000000..01ff751 --- /dev/null +++ b/FSK8250/fsk8250.cbproj @@ -0,0 +1,191 @@ +サソ + + {3F4B3917-B2FC-437A-834F-3DE31B026A4F} + CppDynamicLibrary + True + Debug + 14.6 + Library + None + Win32 + 1 + + + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + 1041 + rtl.lib;vcl.lib;inet.lib + vclx.bpi;rtl.bpi;vcl.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;bcbsmp.bpi;teeui.bpi;vclsmp.bpi;teedb.bpi;tee.bpi;ibsmp.bpi;inetdb.bpi;inet.bpi;$(PackageImports) + .\;$(BDS)\lib;$(BDS)\lib\obj;$(DCC_UnitSearchPath) + Windows + true + $(BDS)\include;$(BDS)\include\vcl;$(BRCC_IncludePath) + true + $(BDS)\include;$(BDS)\include\vcl;$(BCC_IncludePath) + .\;$(BDS)\lib;$(BDS)\lib\obj;$(DCC_IncludePath) + $(BDS)\include;$(BDS)\include\vcl;$(TASM_IncludePath) + rtl.lib;vcl.lib;inet.lib + . + DLL + None + /w2 + fsk + JPHNE + -M + $(BDS)\lib\obj;$(BDS)\lib;$(BDS)\lib\psdk;$(ILINK_LibraryPath) + + + 1033 + -tWM -Tkh30000 -Vx -tWD -d -Ve + true + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + + + $(BDS)\lib\debug;$(ILINK_LibraryPath);$(ILINK_LibraryPath) + DEBUG;$(DCC_Define);$(DCC_Define) + true + Debug_Build + true + true + true + true + Full + -M -V + true + true + false + + + _DEBUG;$(BCC_Defines);$(BCC_Defines) + -tWM -Tkh30000 -Vx -tWD -d -Ve -k + + + _DEBUG;$(BCC_Defines);$(BCC_Defines) + + + Release_Build + -M -$O+ + $(BDS)\lib\release;$(ILINK_LibraryPath);$(ILINK_LibraryPath) + + + NDEBUG;$(BCC_Defines);$(BCC_Defines) + -tWM -Tkh30000 -Vx -tWD -d -Ve -r + + + NDEBUG;$(BCC_Defines);$(BCC_Defines) + + + + -1 + 0 + + + -1 +
ComFSK
+ Main.h + 1 +
+ + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + + + CPlusPlusBuilder.Personality.12 + CppDynamicLibrary + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1041 + 932 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + False + True + True + + + + False + True + False + + + 12 + +
diff --git a/FSK8250/fsk8250.cbproj.local b/FSK8250/fsk8250.cbproj.local new file mode 100644 index 0000000..b3811b7 --- /dev/null +++ b/FSK8250/fsk8250.cbproj.local @@ -0,0 +1,2 @@ +サソ + diff --git a/FSK8250/fsk8250.cpp b/FSK8250/fsk8250.cpp new file mode 100644 index 0000000..6448abe --- /dev/null +++ b/FSK8250/fsk8250.cpp @@ -0,0 +1,85 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +#include "Main.h" +//--------------------------------------------------------------------------- +extern "C" void __declspec(dllexport) __stdcall extfskClose(void); +//--------------------------------------------------------------------------- +USEFORM("Main.cpp", ComFSK); +//--------------------------------------------------------------------------- +TComFSK *g_pMain; +//--------------------------------------------------------------------------- +int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) +{ + switch(reason){ + case DLL_PROCESS_ATTACH: + g_pMain = NULL; + + memset(&sys, 0, sizeof(sys)); + ::GetModuleFileName(hinst, sys.m_ModuleName, sizeof(sys.m_ModuleName)); + ::SetDirName(sys.m_BgnDir, sys.m_ModuleName); + sys.m_dwVersion = ::GetVersion(); + sys.m_WinNT = (sys.m_dwVersion < 0x80000000) ? TRUE : FALSE; + break; + case DLL_PROCESS_DETACH: + extfskClose(); + break; + } + return 1; +} +//--------------------------------------------------------------------------- +extern "C" LONG __declspec(dllexport) __stdcall +extfskOpen(LONG para) +{ + extfskClose(); + + g_pMain = new TComFSK(NULL); + ASSERT(g_pMain); + if( g_pMain != NULL ){ + g_pMain->SetPara(para); + g_pMain->Show(); + return TRUE; + } + else { + return FALSE; + } +} + +//--------------------------------------------------------------------------- +extern "C" void __declspec(dllexport) __stdcall +extfskClose(void) +{ + if( g_pMain != NULL ){ + g_pMain->Close(); + delete g_pMain; + g_pMain = NULL; + } +} + +//--------------------------------------------------------------------------- +extern "C" LONG __declspec(dllexport) __stdcall +extfskIsTxBusy(void) +{ + if( g_pMain == NULL ) return FALSE; + + return g_pMain->IsBusy(); +} + +//--------------------------------------------------------------------------- +extern "C" void __declspec(dllexport) __stdcall +extfskPutChar(BYTE c) +{ + if( g_pMain == NULL ) return; + + g_pMain->PutChar(c); +} + +//--------------------------------------------------------------------------- +extern "C" void __declspec(dllexport) __stdcall +extfskSetPTT(LONG tx) +{ + if( g_pMain == NULL ) return; + + g_pMain->SetPTT(tx & 1, TRUE); +} + diff --git a/FSK8250/fsk8250.fsk b/FSK8250/fsk8250.fsk new file mode 100644 index 0000000..77cba5a Binary files /dev/null and b/FSK8250/fsk8250.fsk differ diff --git a/FSK8250/fsk8250.ini b/FSK8250/fsk8250.ini new file mode 100644 index 0000000..536c84d --- /dev/null +++ b/FSK8250/fsk8250.ini @@ -0,0 +1,20 @@ +[Window] +Top=275 +Left=639 +State=0 + +[Settings] +Port=COM1 +FSK=0 +PTT=1 +InvFSK=0 +InvPTT=0 + +[Port] +LPT1=3BC +LPT2=378 +LPT3=278 + +[DirectAccess] +LPTADR=378 + diff --git a/FSK8250/fsk8250.map b/FSK8250/fsk8250.map new file mode 100644 index 0000000..61f5a0b --- /dev/null +++ b/FSK8250/fsk8250.map @@ -0,0 +1,6 @@ + + Start Length Name Class + 0001:00401000 0002D7F50H _TEXT CODE + 0002:006D9000 00000EAB8H _DATA DATA + 0003:006E7AB8 00001BD18H _BSS BSS + 0004:00000000 0000000E8H _TLS TLS diff --git a/FSK8250/fsk8250.res b/FSK8250/fsk8250.res new file mode 100644 index 0000000..a64cea3 Binary files /dev/null and b/FSK8250/fsk8250.res differ diff --git a/FSK8250/fsk8250.tds b/FSK8250/fsk8250.tds new file mode 100644 index 0000000..85ace64 Binary files /dev/null and b/FSK8250/fsk8250.tds differ diff --git a/Fft.cpp b/Fft.cpp new file mode 100644 index 0000000..4f3f17b --- /dev/null +++ b/Fft.cpp @@ -0,0 +1,594 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#include +#pragma hdrstop + +#include +#include "fft.h" + +int FFT_SIZE=2048; + +#define PI 3.1415926535897932384626433832795 +#define PI2 (2*PI) + +#define SCALEADJ_1 (-4.4494132) +#define LOGADJ (2.81458e4) + +//------------------------------------------------- +// FFT処理クラス +__fastcall CFFT::CFFT() +{ + m_FFTDIS = 0; +// memset(m_fft, 0, sizeof(m_fft)); + m_tWindow = new double[FFT_BUFSIZE]; + m_tSinCos = new double[FFT_BUFSIZE/2]; + m_Work = new int[SQRT_FFT_SIZE+2]; + memset(m_Work, 0, sizeof(int[SQRT_FFT_SIZE+2])); + pStgBuf = new double[FFT_BUFSIZE]; + m_Work[0] = 0; + makewt(FFT_SIZE/4, m_Work, m_tSinCos); + makect(FFT_SIZE/4, m_Work, m_tSinCos + m_Work[0]); + for(int i = 0; i < FFT_SIZE; i++){ + pStgBuf[i] = 1.0; + m_tWindow[i] = (0.5 - 0.5*cos( (PI2*i)/(FFT_SIZE-1) )); //ハニング窓 + } + m_StgSize = 1; + m_StgScale = 1.0; + m_StgK = 0.0; + m_StgSW = FALSE; + m_FFTGain = 0; +} + +//------------------------------------------------- +// FFT処理クラスの再初期化 +void __fastcall CFFT::InitFFT(void) +{ + memset(m_Work, 0, sizeof(int[SQRT_FFT_SIZE+2])); + makewt(FFT_SIZE/4, m_Work, m_tSinCos); + makect(FFT_SIZE/4, m_Work, m_tSinCos + m_Work[0]); + for(int i = 0; i < FFT_SIZE; i++){ + pStgBuf[i] = 1.0; + m_tWindow[i] = (0.5 - 0.5*cos( (PI2*i)/(FFT_SIZE-1) )); //ハニング窓 + } + m_StgSize = 1; + m_StgScale = 1.0; + m_StgK = 0.0; + m_StgSW = FALSE; + m_FFTDIS = 0; +} + +//------------------------------------------------- +__fastcall CFFT::~CFFT() +{ + m_FFTDIS++; + if(pStgBuf){ + delete pStgBuf; + pStgBuf = NULL; + } + if(m_Work){ + delete m_Work; + m_Work = NULL; + } + if(m_tSinCos){ + delete m_tSinCos; + m_tSinCos = NULL; + } + if(m_tWindow){ + delete m_tWindow; + m_tWindow = NULL; + } +} + +void __fastcall CFFT::makewt(int nw, int *ip, double *w) +{ + int nwh, j; + double delta, x, y; + + ip[0] = nw; + ip[1] = 1; + if(nw > 2){ + nwh = nw >> 1; + delta = atan(1.0) / nwh; + w[0] = 1; + w[1] = 0; + w[nwh] = cos(delta * nwh); + w[nwh + 1] = w[nwh]; + for(j = 2; j < nwh; j += 2){ + x = cos(delta * j); + y = sin(delta * j); + w[j] = x; + w[j + 1] = y; + w[nw - j] = y; + w[nw - j + 1] = x; + } + bitrv2(nw, ip + 2, w); + } +} +//------------------------------------------------- +// データの処理化 +void __fastcall CFFT::makect(int nc, int *ip, double *c) +{ + int nch, j; + 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); + } + } +} +//------------------------------------------------- +// データの処理化 +void __fastcall CFFT::bitrv2(int n, int *ip, double *a) +{ + int j, j1, k, k1, l, m, m2; + double xr, xi; + + ip[0] = 0; + l = n; + m = 1; + while((m << 2) < l){ + l >>= 1; + for (j = 0; j < m; j++) { + ip[m + j] = ip[j] + l; + } + m <<= 1; + } + if((m << 2) > l){ + for (k = 1; k < m; k++) { + for (j = 0; j < k; j++) { + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } else { + m2 = m << 1; + for(k = 1; k < m; k++){ + for(j = 0; j < k; j++){ + j1 = (j << 1) + ip[k]; + k1 = (k << 1) + ip[j]; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + j1 += m2; + k1 += m2; + xr = a[j1]; + xi = a[j1 + 1]; + a[j1] = a[k1]; + a[j1 + 1] = a[k1 + 1]; + a[k1] = xr; + a[k1 + 1] = xi; + } + } + } +} +//------------------------------------------------- +void __fastcall CFFT::cftfsub(int n, double *a, double *w) +{ + int j, j1, j2, j3, l; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + l = 2; + if(n > 8){ + cft1st(n, a, w); + l = 8; + while((l << 2) < n){ + cftmdl(n, l, a, w); + l <<= 2; + } + } + if((l << 2) == n){ + for(j = 0; j < l; j += 2){ + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + } else { + for(j = 0; j < l; j += 2){ + j1 = j + l; + x0r = a[j] - a[j1]; + x0i = a[j + 1] - a[j1 + 1]; + a[j] += a[j1]; + a[j + 1] += a[j1 + 1]; + a[j1] = x0r; + a[j1 + 1] = x0i; + } + } +} +//------------------------------------------------- +void __fastcall CFFT::cft1st(int n, double *a, double *w) +{ + int j, k1, k2; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + x0r = a[0] + a[2]; + x0i = a[1] + a[3]; + x1r = a[0] - a[2]; + x1i = a[1] - a[3]; + x2r = a[4] + a[6]; + x2i = a[5] + a[7]; + x3r = a[4] - a[6]; + x3i = a[5] - a[7]; + a[0] = x0r + x2r; + a[1] = x0i + x2i; + a[4] = x0r - x2r; + a[5] = x0i - x2i; + a[2] = x1r - x3i; + a[3] = x1i + x3r; + a[6] = x1r + x3i; + a[7] = x1i - x3r; + wk1r = w[2]; + x0r = a[8] + a[10]; + x0i = a[9] + a[11]; + x1r = a[8] - a[10]; + x1i = a[9] - a[11]; + x2r = a[12] + a[14]; + x2i = a[13] + a[15]; + x3r = a[12] - a[14]; + x3i = a[13] - a[15]; + a[8] = x0r + x2r; + a[9] = x0i + x2i; + a[12] = x2i - x0i; + a[13] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[10] = wk1r * (x0r - x0i); + a[11] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[14] = wk1r * (x0i - x0r); + a[15] = wk1r * (x0i + x0r); + k1 = 0; + for(j = 16; j < n; j += 16){ + k1 += 2; + k2 = k1 << 1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + x0r = a[j] + a[j + 2]; + x0i = a[j + 1] + a[j + 3]; + x1r = a[j] - a[j + 2]; + x1i = a[j + 1] - a[j + 3]; + x2r = a[j + 4] + a[j + 6]; + x2i = a[j + 5] + a[j + 7]; + x3r = a[j + 4] - a[j + 6]; + x3i = a[j + 5] - a[j + 7]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 4] = wk2r * x0r - wk2i * x0i; + a[j + 5] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 2] = wk1r * x0r - wk1i * x0i; + a[j + 3] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 6] = wk3r * x0r - wk3i * x0i; + a[j + 7] = wk3r * x0i + wk3i * x0r; + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + x0r = a[j + 8] + a[j + 10]; + x0i = a[j + 9] + a[j + 11]; + x1r = a[j + 8] - a[j + 10]; + x1i = a[j + 9] - a[j + 11]; + x2r = a[j + 12] + a[j + 14]; + x2i = a[j + 13] + a[j + 15]; + x3r = a[j + 12] - a[j + 14]; + x3i = a[j + 13] - a[j + 15]; + a[j + 8] = x0r + x2r; + a[j + 9] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j + 12] = -wk2i * x0r - wk2r * x0i; + a[j + 13] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j + 10] = wk1r * x0r - wk1i * x0i; + a[j + 11] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j + 14] = wk3r * x0r - wk3i * x0i; + a[j + 15] = wk3r * x0i + wk3i * x0r; + } +} +//------------------------------------------------- +void __fastcall CFFT::cftmdl(int n, int l, double *a, double *w) +{ + int j, j1, j2, j3, k, k1, k2, m, m2; + double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i; + double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + + m = l << 2; + for(j = 0; j < l; j += 2){ + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x0r - x2r; + a[j2 + 1] = x0i - x2i; + a[j1] = x1r - x3i; + a[j1 + 1] = x1i + x3r; + a[j3] = x1r + x3i; + a[j3 + 1] = x1i - x3r; + } + wk1r = w[2]; + for(j = m; j < l + m; j += 2){ + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + a[j2] = x2i - x0i; + a[j2 + 1] = x0r - x2r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * (x0r - x0i); + a[j1 + 1] = wk1r * (x0r + x0i); + x0r = x3i + x1r; + x0i = x3r - x1i; + a[j3] = wk1r * (x0i - x0r); + a[j3 + 1] = wk1r * (x0i + x0r); + } + k1 = 0; + m2 = m << 1; + for(k = m2; k < n; k += m2){ + k1 += 2; + k2 = k1 << 1; + wk2r = w[k1]; + wk2i = w[k1 + 1]; + wk1r = w[k2]; + wk1i = w[k2 + 1]; + wk3r = wk1r - 2 * wk2i * wk1i; + wk3i = 2 * wk2i * wk1r - wk1i; + for(j = k; j < l + k; j += 2){ + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = wk2r * x0r - wk2i * x0i; + a[j2 + 1] = wk2r * x0i + wk2i * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + wk1r = w[k2 + 2]; + wk1i = w[k2 + 3]; + wk3r = wk1r - 2 * wk2r * wk1i; + wk3i = 2 * wk2r * wk1r - wk1i; + for(j = k + m; j < l + (k + m); j += 2){ + j1 = j + l; + j2 = j1 + l; + j3 = j2 + l; + x0r = a[j] + a[j1]; + x0i = a[j + 1] + a[j1 + 1]; + x1r = a[j] - a[j1]; + x1i = a[j + 1] - a[j1 + 1]; + x2r = a[j2] + a[j3]; + x2i = a[j2 + 1] + a[j3 + 1]; + x3r = a[j2] - a[j3]; + x3i = a[j2 + 1] - a[j3 + 1]; + a[j] = x0r + x2r; + a[j + 1] = x0i + x2i; + x0r -= x2r; + x0i -= x2i; + a[j2] = -wk2i * x0r - wk2r * x0i; + a[j2 + 1] = -wk2i * x0i + wk2r * x0r; + x0r = x1r - x3i; + x0i = x1i + x3r; + a[j1] = wk1r * x0r - wk1i * x0i; + a[j1 + 1] = wk1r * x0i + wk1i * x0r; + x0r = x1r + x3i; + x0i = x1i - x3r; + a[j3] = wk3r * x0r - wk3i * x0i; + a[j3 + 1] = wk3r * x0i + wk3i * x0r; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CFFT::Calc(double * InBuf, int size, double gain, int stg, int* OutBuf) +{ + if( m_FFTDIS ) return; // for math error + m_FFTDIS++; + int i; + + if( stg > 1 ){ + m_StgSW = TRUE; + } + else { + m_StgSW = FALSE; + } + m_StgSize = stg; + if( stg ){ + m_StgScale = 1.0 / double(m_StgSize); + m_StgK = 1.0 - m_StgScale; + } + else { + m_StgScale = 1.0; + m_StgK = 0.0; + } + double *dp = InBuf; + for(i=0; i < FFT_SIZE; i++, dp++){ + (*dp) *= m_tWindow[i]; + } + bitrv2(FFT_SIZE, m_Work + 2, InBuf); + cftfsub(FFT_SIZE, InBuf, m_tSinCos); + rftfsub(FFT_SIZE, InBuf, m_Work[1], m_tSinCos + m_Work[0]); + for( i = 0, dp = pStgBuf; i <= size; i++, dp+=2 ){ + OutBuf[i] = int((gain * (*dp))); + } + m_FFTDIS--; +} +//--------------------------------------------------------------------------- +void __fastcall CFFT::rftfsub(int n, double *a, int nc, double *c) +{ + int j, k, kk, ks, m; + double wkr, wki, xr, xi, yr, yi; +// double d; + + ks = (nc << 2) / n; + kk = 0; + m = n >> 1; + j = n - 2; + if(m_StgSW){ + for (k = 2; k <= m; k += 2, j -= 2 ){ + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[k] - a[j]; + xi = a[k + 1] + a[j + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[k] -= yr; + xi = a[k]*a[k]; + a[k+1] -= yi; // <-- here + xi += ( a[k+1]*a[k+1]); + a[j] += yr; + xr = a[j]*a[j]; + a[j+1] -= yi; + xr += (a[j+1]*a[j+1]); + if( xi <= 0 ) xi = 0.0001; + if( xi >= 1e38 ) xi = 1e38; + if( xr <= 0 ) xr = 0.0001; + if( xr >= 1e38 ) xr = 1e38; + if( FFT_SIZE == 1024 ){ + xi *= 4; + xr *= 4; + } + if( m_FFTGain ){ + pStgBuf[k] = m_StgK*pStgBuf[k] + m_StgScale*pow(xi, 0.25)*0.00345; + pStgBuf[j] = m_StgK*pStgBuf[j] + m_StgScale*pow(xr, 0.25)*0.00345; + } + else { + pStgBuf[k] = m_StgK*pStgBuf[k] + m_StgScale*(log10(xi+LOGADJ) + SCALEADJ_1); + pStgBuf[j] = m_StgK*pStgBuf[j] + m_StgScale*(log10(xr+LOGADJ) + SCALEADJ_1); + } + } + } + else { + for (k = 2; k <= m; k += 2, j -= 2 ){ + kk += ks; + wkr = 0.5 - c[nc - kk]; + wki = c[kk]; + xr = a[k] - a[j]; + xi = a[k + 1] + a[j + 1]; + yr = wkr * xr - wki * xi; + yi = wkr * xi + wki * xr; + a[k] -= yr; + xi = a[k]*a[k]; + if( yi >= 1e38 ) yi = 1e38; + a[k+1] -= yi; // <--- ここ + xi += ( a[k+1]*a[k+1]); + a[j] += yr; + xr = a[j]*a[j]; + a[j+1] -= yi; + xr += (a[j+1]*a[j+1]); + if( xi <= 0 ) xi = 0.0001; + if( xi >= 1e38 ) xi = 1e38; + if( xr <= 0 ) xr = 0.0001; + if( xr >= 1e38 ) xr = 1e38; + if( FFT_SIZE == 1024 ){ + xi *= 4; + xr *= 4; + } + if( m_FFTGain ){ + pStgBuf[k] = pow(xi, 0.25)*0.00345; + pStgBuf[j] = pow(xr, 0.25)*0.00345; + } + else { + pStgBuf[k] = log10(xi+LOGADJ)+SCALEADJ_1; + pStgBuf[j] = log10(xr+LOGADJ)+SCALEADJ_1; + } + } + } + pStgBuf[FFT_SIZE/2] = pStgBuf[(FFT_SIZE/2) - 2]; +} + diff --git a/Fft.h b/Fft.h new file mode 100644 index 0000000..bb6ac13 --- /dev/null +++ b/Fft.h @@ -0,0 +1,60 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef FFT_H +#define FFT_H +//--------------------------------------------------------------------------- +extern int FFT_SIZE; +//#define FFT_SIZE 2048 +#define FFT_BUFSIZE 2048 +#define SQRT_FFT_SIZE 46//sqrt(2048) + +class CFFT +{ +public: + __fastcall CFFT(); + virtual __fastcall ~CFFT(); + void __fastcall InitFFT(void); + + int m_FFTGain; + int m_FFTDIS; + void __fastcall Calc(double * InBuf, int size, double gain, int stg, int* OutBuf); + inline void __fastcall ClearStg(void){ + memset(pStgBuf, 0, sizeof(double[FFT_BUFSIZE])); + } +private: + BOOL m_StgSW; + int m_StgSize; + double m_StgScale; + double m_StgK; + + double *m_tSinCos; + double *m_tWindow; + double *pStgBuf; + int *m_Work; + void __fastcall makewt(int nw, int *ip, double *w); + void __fastcall makect(int nc, int *ip, double *c); + void __fastcall bitrv2(int n, int *ip, double *a); + void __fastcall cftfsub(int n, double *a, double *w); + void __fastcall rftfsub(int n, double *a, int nc, double *c); + void __fastcall cft1st(int n, double *a, double *w); + void __fastcall cftmdl(int n, int l, double *a, double *w); +}; + +#endif diff --git a/FreqDisp.cpp b/FreqDisp.cpp new file mode 100644 index 0000000..1be4943 --- /dev/null +++ b/FreqDisp.cpp @@ -0,0 +1,158 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ComLib.h" +#include "FreqDisp.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TFreqDispDlg *FreqDispDlg; +//--------------------------------------------------------------------- +__fastcall TFreqDispDlg::TFreqDispDlg(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + + m_H1 = NULL; + m_Tap1 = 0; + m_H2 = NULL; + m_Tap2 = 0; + m_Max = 0; + m_SampleFreq = SAMPFREQ; + + pBitmap = new Graphics::TBitmap(); + pBitmap->Width = PaintBox->Width; + pBitmap->Height = PaintBox->Height; + if( sys.m_MsgEng ){ + CancelBtn->Caption = "Close"; + Caption = "frequency characteristic"; + } + FormCenter(this); +} +__fastcall TFreqDispDlg::~TFreqDispDlg() +{ + delete pBitmap; +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(CFIR2 *pFIR, int max, double SampleFreq) +{ + m_type = 0; + m_H1 = pFIR->GetHP(); + m_Tap1 = pFIR->GetTap(); + m_Tap2 = 0; + m_Max = max; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(CFIRX *pFIR, int max, double SampleFreq) +{ + m_type = 0; + m_H1 = pFIR->GetHP(); + m_Tap1 = pFIR->GetTap(); + m_Tap2 = 0; + m_Max = max; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(const double *H, int Tap, int max, double SampleFreq) +{ + m_type = 0; + m_H1 = H; + m_Tap1 = Tap ? Tap : 1; + m_Tap2 = 0; + m_Max = max; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(double a10, double b11, double b12, double a20, double b21, double b22, double SampleFreq) +{ + m_type = 1; + m_a10 = a10; + m_b11 = b11; + m_b12 = b12; + m_a20 = a20; + m_b21 = b21; + m_b22 = b22; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(CIIRTANK &tank, double SampleFreq) +{ + m_type = 4; + m_a10 = tank.a0; + m_b11 = tank.b1; + m_b12 = tank.b2; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::Execute(CIIR *ip, double max, double SampleFreq) +{ + m_type = 2; + m_piir = ip; + m_Max = max; + m_SampleFreq = SampleFreq; + MakeBitmap(); + ShowModal(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::MakeBitmap(void) +{ + OnWave(); + if( m_type == 0 ){ // FIR + DrawGraph(pBitmap, m_H1, m_Tap1, m_Max, 1, clBlue, m_SampleFreq); + if( m_Tap2 ){ + DrawGraph(pBitmap, m_H2, m_Tap2, m_Max, 0, clRed, m_SampleFreq); + } + } + else if( m_type == 1 ){ // IIR Tank + DrawGraphIIR(pBitmap, m_a10, 0, 0, -m_b11, -m_b12, m_Max, 1, clBlue, m_SampleFreq); + DrawGraphIIR(pBitmap, m_a20, 0, 0, -m_b21, -m_b22, m_Max, 0, clRed, m_SampleFreq); + } + else if( m_type == 2 ){ // IIR + DrawGraphIIR(pBitmap, m_piir, m_Max, 1, clBlue, m_SampleFreq); + } + else if( m_type == 3 ){ // FIR-Avg + DrawGraph(pBitmap, m_H1, m_Tap1, m_Max, 1, clBlue, m_SampleFreq); + } + else if( m_type == 4 ){ + DrawGraphIIR(pBitmap, m_a10, 0, 0, -m_b11, -m_b12, m_Max, 1, clBlue, m_SampleFreq); + } + OnWave(); +} +//--------------------------------------------------------------------- +void __fastcall TFreqDispDlg::PaintBoxPaint(TObject *Sender) +{ + PaintBox->Canvas->Draw(0, 0, (TGraphic*)pBitmap); +} +//--------------------------------------------------------------------------- diff --git a/FreqDisp.dfm b/FreqDisp.dfm new file mode 100644 index 0000000..78fe9bf Binary files /dev/null and b/FreqDisp.dfm differ diff --git a/FreqDisp.h b/FreqDisp.h new file mode 100644 index 0000000..7d64e9f --- /dev/null +++ b/FreqDisp.h @@ -0,0 +1,86 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef FreqDispH +#define FreqDispH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +//---------------------------------------------------------------------------- +#include "dsp.h" +//---------------------------------------------------------------------------- +class TFreqDispDlg : public TForm +{ +__published: + TButton *CancelBtn; + TPanel *Panel; + TPaintBox *PaintBox; + TTimer *Timer; + void __fastcall PaintBoxPaint(TObject *Sender); + + +private: + Graphics::TBitmap *pBitmap; + + int m_type; + double m_a10, m_a20; + double m_b11, m_b12; + double m_b21, m_b22; + + CIIR *m_piir; + + const double *m_H1; + int m_Tap1; + const double *m_H2; + int m_Tap2; + double m_SampleFreq; + + double m_HT[TAPMAX+1]; +private: + void __fastcall MakeBitmap(void); + +public: + virtual __fastcall TFreqDispDlg(TComponent* AOwner); + __fastcall ~TFreqDispDlg(); + + void __fastcall Execute(CFIR2 *pFIR, int max, double SampleFreq); + void __fastcall Execute(CFIRX *pFIR, int max, double SampleFreq); + void __fastcall Execute(const double *H, int Tap, int max, double SampleFreq); + void __fastcall Execute(double a10, double b11, double b12, double a20, double b21, double b22, double SampleFreq); + void __fastcall Execute(CIIR *ip, double max, double SampleFreq); + void __fastcall Execute(CIIRTANK &tank, double SampleFreq); + + int m_Max; +}; +//---------------------------------------------------------------------------- +//extern TFreqDispDlg *FreqDispDlg; +//---------------------------------------------------------------------------- +#endif + diff --git a/Hamlog5.cpp b/Hamlog5.cpp new file mode 100644 index 0000000..14eeb74 --- /dev/null +++ b/Hamlog5.cpp @@ -0,0 +1,632 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ComLib.h" +#include "LogFile.h" +#include "Hamlog5.h" +#include "LogConv.h" +//-------------------------------------------- +const LPCSTR g_Hamlog5Key[]={ + "CALLS", "IGN", "DATE", "TIME", "CODE", "GL", "QSL", "FLAG", "HIS", "MY", + "FREQ", "MODE", "NAME", "QTH", "RMK1", "RMK2", NULL +}; +const BYTE g_Hamlog5Len[]={ + 8, 12, 4, 2, 6, 6, 3, 2, 3, 3, + 7, 4, 12, 28, 54, 54, 0 +}; +//-------------------------------------------- +void __fastcall GetHamlog5FieldsLen(AnsiString &as) +{ + as = ""; + for( int i = 8; i < 15; i++ ){ + if( i > 8 ) as += ","; + as += Log.m_LogSet.m_Hamlog5Len[i]; + } +} +//-------------------------------------------- +void __fastcall SetHamlog5FieldsLen(AnsiString &as) +{ + LPSTR pBF = StrDupe(as.c_str()); + LPSTR p, t; + p = pBF; + for( int i = 8; i < 15; i++ ){ + p = StrDlm(t, p); + Log.m_LogSet.m_Hamlog5Len[i] = BYTE(atoin(t, -1)); + } + delete pBF; +} +//-------------------------------------------- +//コンストラクタ +CHamlog5::CHamlog5() +{ + m_fCreate = FALSE; + m_RecMax = 0; // レコード数 + m_FilMax = 0; // フィールド数 + m_RecWidth = 0; // レコードの幅 + m_FilOff = 0; // ヘッダオフセット + m_bp = NULL; + m_OpenFlag = FALSE; + m_WriteFlag = FALSE; // 書き込みフラグ +} + +//-------------------------------------------- +//デストラクタ +CHamlog5::~CHamlog5() +{ + Close(); +} + +//-------------------------------------------- +//ヘッダデータセットアップ +BOOL CHamlog5::SetupHeader(void) +{ + if( fread(&m_Head, 1, sizeof(m_Head), m_fp)!=sizeof(m_Head) ){ + return FALSE; // 異なるフォーマット + } + + if( (m_Head.Type != 0x03)&&(m_Head.Type != 0x1a ) ) return FALSE; + + m_RecMax = m_Head.RecMax; + m_FilOff = m_Head.FilOff; + m_RecWidth = m_Head.RecWidth; + if( !m_FilOff ) return FALSE; + + hamlog5DBRHD slot; + ULONG fPos; + for( m_FilMax = 0; m_FilMax < HamlogDBMAX; m_FilMax++ ){ + fPos = (32L*m_FilMax)+32L; + if( fPos > ULONG(m_FilOff) ) break; + if( fread(&slot, 1, sizeof(slot), m_fp)!=sizeof(slot) ) break; + if( slot.Name[0] == 0x0d ) break; + slot.Name[10] = 0; + m_StrTable[m_FilMax] = slot.Name; + m_TypeTable[m_FilMax] = slot.Type; + m_LenTable[m_FilMax] = USHORT(slot.Len); + } + for( int i = 8; (i < 15) && (i < m_FilMax); i++ ){ + Log.m_LogSet.m_Hamlog5Len[i] = m_LenTable[i]; + } + +// if( (m_Head.Type == 0x1a) && !m_RecMax ){ +// m_RecMax = (m_fStatus.m_size - ULONG(m_FilOff)) / ULONG(m_RecWidth); +// } + + USHORT i; + USHORT Pos = 1; + for( i = 0; i < m_FilMax; i++ ){ + m_PosTable[i] = Pos; + Pos += m_LenTable[i]; + } + return TRUE; +} + +//-------------------------------------------- +//ヘッダデータ作成 +BOOL CHamlog5::MakeHeader(const LPCSTR _NT[], const BYTE _LT[]) +{ + hamlog5DBRHD slot; + + memset(&m_Head, 0, sizeof(m_Head)); + fseek(m_fp, 0, SEEK_SET); + fwrite(&m_Head, 1, sizeof(m_Head), m_fp); + m_FilOff = sizeof(m_Head); + m_RecWidth = 1; + for( m_FilMax = 0; _LT[m_FilMax]; m_FilMax++ ){ + memset(&slot, 0, sizeof(slot)); + strcpy(slot.Name, _NT[m_FilMax]); + slot.Len = _LT[m_FilMax]; + slot.Type = 'C'; + fwrite(&slot, 1, sizeof(slot), m_fp); + m_PosTable[m_FilMax] = m_RecWidth; + m_RecWidth += USHORT(_LT[m_FilMax]); + m_FilOff += USHORT(sizeof(slot)); + m_StrTable[m_FilMax] = _NT[m_FilMax]; + m_TypeTable[m_FilMax] = 'C'; + m_LenTable[m_FilMax] = USHORT(_LT[m_FilMax]); + } + char Term = 0x0d; + fwrite(&Term, 1, 1, m_fp); + m_FilOff++; + m_Head.Type = 3; + SYSTEMTIME st; + ::GetLocalTime(&st); + m_Head.Year = BYTE(st.wYear % 100); + m_Head.Mon = BYTE(st.wMonth); + m_Head.Day = BYTE(st.wDay); + m_Head.RecMax = 0; + m_Head.FilOff = m_FilOff; + m_Head.RecWidth = m_RecWidth; + fseek(m_fp, 0, SEEK_SET); + fwrite(&m_Head, 1, sizeof(m_Head), m_fp); + return TRUE; +} + +//-------------------------------------------- +//オープン +BOOL CHamlog5::Open(LPCSTR Name, BOOL fMsg) +{ + if( (m_OpenFlag == TRUE) ) Close(); + m_WriteFlag = FALSE; // 書き込みフラグ + if( (m_fp = fopen(Name, "rb")) == NULL ){ + if( fMsg ) ErrorMB("%sがオープンできません.", Name); + return FALSE; // ファイルがオープンできない + } + m_OpenFlag = TRUE; + m_fCreate = FALSE; + if( SetupHeader() == FALSE ){ + Close(); + if( fMsg ) ErrorMB("ファイルフォーマットが認識できません."); + return FALSE; + } + if( m_bp ) delete m_bp; + m_bp = new char[m_RecWidth]; + if( Seek(0) == FALSE ){ + Close(); + if( fMsg ) ErrorMB("データーレコードが存在しません."); + return FALSE; + } + return TRUE; +} + +//-------------------------------------------- +//オープン +BOOL CHamlog5::Create(LPCSTR Name) +{ + if( (m_OpenFlag == TRUE) ) Close(); + m_WriteFlag = FALSE; // 書き込みフラグ + if( (m_fp = fopen(Name, "wb")) == NULL ){ + ErrorMB("%sを作成できません.", Name); + return FALSE; // ファイルがオープンできない + } + m_OpenFlag = TRUE; + m_fCreate = TRUE; + if( MakeHeader(g_Hamlog5Key, Log.m_LogSet.m_Hamlog5Len) == FALSE ){ + Close(); + ErrorMB("%sを作成できません.", Name); + return FALSE; + } + if( m_bp ) delete m_bp; + m_bp = new char[m_RecWidth]; + return TRUE; +} + +//-------------------------------------------- +//クローズ +void CHamlog5::Close(void) +{ + if( m_OpenFlag == TRUE ){ + Update(); + if( m_RecMax != m_Head.RecMax ){ // データが追加されている + m_Head.RecMax = m_RecMax; + fseek(m_fp, 0, SEEK_SET); + fwrite(&m_Head, 1, sizeof(m_Head), m_fp); + } + int r = fclose(m_fp); + m_fp = NULL; + if( r && m_fCreate ){ + ErrorMB("ファイルの作成に失敗しました."); + } + m_OpenFlag = FALSE; + } + if( m_bp != NULL ){ + delete m_bp; + m_bp = NULL; + } +} + +//-------------------------------------------- +//レコードシーク +BOOL CHamlog5::Seek(ULONG Index) +{ + if( m_OpenFlag == FALSE ) return FALSE; + if( Update() == FALSE ) return FALSE; + m_Index = Index; + m_Pos = (Index * ULONG(m_RecWidth)) + ULONG(m_FilOff); + fseek(m_fp, m_Pos, SEEK_SET); + if( Index < m_RecMax ){ + if( fread(m_bp, 1, m_RecWidth, m_fp) != ULONG(m_RecWidth) ){ + return FALSE; + } + } + else { + memset(m_bp, ' ', m_RecWidth); + } + return TRUE; +} + +//-------------------------------------------- +//マークのチェック +BOOL CHamlog5::IsData(void) +{ + return (*m_bp == ' ') ? TRUE : FALSE; +} + +//-------------------------------------------- +//データの読み込み +BOOL CHamlog5::GetData(USHORT SubIndex, AnsiString &cs) +{ + char bf[1024]; + + if( SubIndex >= m_FilMax ) return FALSE; + + int len = m_LenTable[SubIndex]; + if( len >= 1023 ) len = 1023; + StrCopy(bf, m_bp + m_PosTable[SubIndex], len); + cs = bf; + return TRUE; +} +//-------------------------------------------- +//データの読み込み +BOOL CHamlog5::GetData(USHORT SubIndex, LPSTR pStore) +{ + if( SubIndex >= m_FilMax ) return FALSE; + + int len = m_LenTable[SubIndex]; + if( len >= 1023 ) len = 1023; + StrCopy(pStore, m_bp + m_PosTable[SubIndex], len); + return TRUE; +} + +//-------------------------------------------- +//データの読み込み +int CHamlog5::GetData(USHORT SubIndex, LPBYTE pData, int len) +{ + if( SubIndex >= m_FilMax ) return 0; + + int rlen = m_LenTable[SubIndex]; + if( rlen >= 1023 ) rlen = 1023; + if( rlen > len ) rlen = len; + memcpy(pData, m_bp + m_PosTable[SubIndex], rlen); + return rlen; +} + +//-------------------------------------------- +//データの書き込み(バッファを更新するのみ) +BOOL CHamlog5::SetData(USHORT SubIndex, LPCSTR p) +{ + if( SubIndex >= m_FilMax ) return FALSE; + + int len = m_LenTable[SubIndex]; + LPSTR t; + int i; + for( i = 0, t = m_bp + m_PosTable[SubIndex]; i < len; i++, t++ ){ + if( *p ){ + *t = *p++; + } + else { + *t = ' '; + } + } + m_WriteFlag = TRUE; + return TRUE; +} +//-------------------------------------------- +//データの書き込み(バッファを更新するのみ) +BOOL CHamlog5::SetBinary(USHORT SubIndex, LPBYTE p) +{ + if( SubIndex >= m_FilMax ) return FALSE; + + int len = m_LenTable[SubIndex]; + LPSTR t; + int i; + for( i = 0, t = m_bp + m_PosTable[SubIndex]; i < len; i++, t++ ){ + *t = *p++; + } + m_WriteFlag = TRUE; + return TRUE; +} + +//-------------------------------------------- +//データの書き込み(バッファの内容を反映させる) +BOOL CHamlog5::Update(void) +{ + if( m_OpenFlag == FALSE ) return FALSE; + + if( m_WriteFlag == TRUE ){ + m_WriteFlag = FALSE; + fseek(m_fp, m_Pos, SEEK_SET); + fwrite(m_bp, 1, m_RecWidth, m_fp); + if( m_Index >= m_RecMax ){ + m_RecMax++; + } + } + return TRUE; +} +//-------------------------------------------- +//データのデコード +void CHamlog5::DecodeData(SDMMLOG *sp) +{ + memset(sp, 0, sizeof(SDMMLOG)); + char bf[1024]; + + + int YY, MM, DD, HH, mm; + GetData(itemhamlog5DATE, LPBYTE(bf), 4); + YY = bf[1]; + MM = bf[2]; + DD = bf[3]; + GetData(itemhamlog5TIME, LPBYTE(bf), 2); + HH = bf[0]; + mm = bf[1] & 0x7f; + if( bf[1] & 0x80 ){ + UTCtoJST(YY, MM, DD, HH); + } + sp->year = BYTE(YY); + sp->date = WORD(MM * 100 + DD); + sp->btime = WORD(((HH * 60 + mm) * 30)); + if(!sp->btime) sp->btime++; + + USHORT usFlag; // コールサインの形式 + GetData(itemhamlog5FLAG, LPBYTE(&usFlag), sizeof(usFlag)); + + LPSTR t, p; + AnsiString call; + if( (usFlag & bithamlog5DX) && (usFlag & bithamlog5RevOdr) ){ // KH6/JE3HHT + AnsiString Add; + GetData(itemhamlog5IGN, bf); + p = bf; + if( *p != ' ' ){ + p = StrDlm(t, p, ' '); + Add = t; + } + p = SkipSpace(p); + p = StrDlm(t, p, '/'); + call = t; + GetData(itemhamlog5CALLS, bf); clipsp(bf); + if( !call.IsEmpty() ) call += '/'; + call += SkipSpace(bf); + call += Add; + if( *p ){ + call += '/'; + call += p; + } + } + else { // JE3HHT/KH6 + GetData(itemhamlog5CALLS, bf); clipsp(bf); + call = SkipSpace(bf); + GetData(itemhamlog5IGN, bf); + p = bf; + if( *p != ' ' ){ + p = StrDlm(t, p, ' '); + call += t; + } + p = SkipSpace(p); + if( *p ){ + call += '/'; + call += p; + } + } + + StrCopy(sp->call, call.c_str(), MLCALL); + GetData(itemhamlog5HIS, bf); clipsp(bf); + StrCopy(sp->ur, bf, MLRST); + GetData(itemhamlog5MY, bf); clipsp(bf); + StrCopy(sp->my, bf, MLRST); + GetData(itemhamlog5MODE, bf); clipsp(bf); + Log.SetMode(sp, bf); + GetData(itemhamlog5FREQ, bf); clipsp(bf); + Log.SetFreq(sp, bf); + GetData(itemhamlog5NAME, bf); clipsp(bf); + StrCopy(sp->name, bf, MLNAME); + GetData(itemhamlog5QTH, bf); clipsp(bf); + StrCopy(sp->qth, bf, MLQTH); + + GetData(itemhamlog5RMK1, bf); + SetMMLOGKey(sp, bf); + clipsp(bf); + StrCopy(sp->rem, SkipSpace(bf), MLREM); + GetData(itemhamlog5RMK2, bf); + SetMMLOGKey(sp, bf); + clipsp(bf); + StrCopy(sp->qsl, SkipSpace(bf), MLQSL); + GetData(itemhamlog5QSL, LPBYTE(bf), 3); + sprintf(&bf[32], "QSL[%.3s]", bf); + Log.SetOptStr(2, sp, &bf[32]); + if( bf[0] == 'N' ){ + sp->send = 'N'; + } + else if( bf[1] == ' ' ){ // 未発送 + if( (bf[0] == 'J')||(bf[0] == ' ') ){ + sp->send = 0; + } + else { + sp->send = BYTE(tolower(bf[0])); + } + } + else { // 発送済み + sp->send = BYTE(toupper(bf[1])); + } + sp->recv = bf[2]; + if( sp->recv == ' ' ) sp->recv = 0; + GetData(itemhamlog5CODE, LPBYTE(bf), 6); clipsp(bf); + StrCopy(sp->opt1, bf, 6); + GetData(itemhamlog5GL, LPBYTE(bf), 6); clipsp(bf); + StrCopy(sp->opt2, bf, 6); + if( !sp->etime ) sp->etime = sp->btime; +} +//-------------------------------------------- +//データのエンコード +void CHamlog5::EncodeData(SDMMLOG *sp) +{ + char bf[1024]; + + int YY = sp->year; + int MM = sp->date / 100; + int DD = sp->date % 100; + int tim = sp->btime / 30; + int HH = tim / 60; + int mm = tim % 60; + switch(Log.m_LogSet.m_THTZ){ + case 0: + if( !IsJA(sp->call) ){ + JSTtoUTC(YY, MM, DD, HH); + mm |= 0x80; + } + break; + case 1: + JSTtoUTC(YY, MM, DD, HH); + mm |= 0x80; + break; + default: + break; + } + bf[0] = BYTE(YY > 50 ? 19 : 20); + bf[1] = BYTE(YY); + bf[2] = BYTE(MM); + bf[3] = BYTE(DD); + SetBinary(itemhamlog5DATE, LPBYTE(bf)); + bf[0] = BYTE(HH); + bf[1] = BYTE(mm); + SetBinary(itemhamlog5TIME, LPBYTE(bf)); + + SetData(itemhamlog5NAME, sp->name); + SetData(itemhamlog5CODE, sp->opt1); + SetData(itemhamlog5GL, sp->opt2); + SetData(itemhamlog5QTH, sp->qth); + strcpy(bf, Log.GetModeString(sp->mode)); + SetData(itemhamlog5MODE, bf); + strcpy(bf, Log.GetFreqString(sp->band, sp->fq)); + SetData(itemhamlog5FREQ, bf); + + SetData(itemhamlog5HIS, sp->ur); + SetData(itemhamlog5MY, sp->my); + + AnsiString REM1, REM2; + REM1 = sp->rem; + REM2 = sp->qsl; + int l = GetLMode(sp->mode); + if( sp->ur[l] ) AddMMLOGKey(REM1, REM2, &sp->ur[l], "SN"); + if( sp->my[l] ) AddMMLOGKey(REM1, REM2, &sp->my[l], "RN"); + + if( sp->etime ){ + tim = sp->etime / 30; + sprintf(bf, "%02u%02u", tim / 60, tim % 60); + AddMMLOGKey(REM1, REM2, bf, "END"); + } + if( sp->env ){ + sprintf(bf, "%u", sp->env); + AddMMLOGKey(REM1, REM2, bf, "ENV"); + } + AddMMLOGKey(REM1, REM2, sp->pow, "POW"); + if( sp->cq ){ + bf[0] = sp->cq; bf[1] = 0; + AddMMLOGKey(REM1, REM2, bf, "M"); + } + strcpy(bf, Log.GetOptStr(2, sp)); + char rbf[32]; + char qsl[3]; + if(RemoveL2(rbf, bf, "QSL", sizeof(rbf)-1) == TRUE){ + qsl[0] = rbf[0]; + qsl[1] = rbf[1]; + qsl[2] = rbf[2]; + } + else { + qsl[2] = sp->recv; + if( !qsl[2] ) qsl[2] = ' '; + if( sp->send == 'N' ){ + qsl[0] = 'N'; + qsl[1] = ' '; + } + else if( !sp->send ){ + qsl[0] = 'J'; + qsl[1] = ' '; + } + else if( (sp->send >= 0x60)||(sp->send == '?') ){ + qsl[0] = BYTE(toupper(sp->send)); + qsl[1] = ' '; + } + else if( isalpha(sp->send) ){ + qsl[0] = sp->send; + qsl[1] = '*'; + } + else { + qsl[0] = 'J'; + qsl[1] = sp->send; + } + } + SetData(itemhamlog5QSL, qsl); + SetData(itemhamlog5RMK1, REM1.c_str()); + SetData(itemhamlog5RMK2, REM2.c_str()); + + BOOL fJA = IsJA(sp->call); + USHORT usFlag = USHORT(fJA ? 0 : bithamlog5DX); + AnsiString Calls, Ign; + strcpy(bf, sp->call); + LPSTR pp, p2, t; + t = bf; + if( (pp = strchr(bf, '/')) != NULL ){ // KH6/JE3HHT or JE3HHT/KH6 の形式 + *pp = 0; + pp++; + int LenC = strlen(t); + int LenP = strlen(pp); + if( (p2 = strchr(pp, '/')) != NULL ){ // KH6/JE3HHT/P JE3HHT/QRP/3 + // t = KH6, pp = JE3HHT, p2 = P + *p2 = 0; p2++; + if( fJA ){ + Calls = t; + Ign = pp; + Ign += "/"; + Ign += p2; + } + else { + Calls = pp; + Ign = t; + Ign += "/"; + Ign += p2; + usFlag |= bithamlog5RevOdr; + } + } + else { + if( LenC < LenP ){ + Calls = pp; + Ign = t; + if( usFlag ) usFlag |= bithamlog5RevOdr; + } + else { + Calls = t; + Ign = pp; + if( usFlag ) usFlag |= bithamlog5NorOdr; + } + } + } + else { + Calls = sp->call; + } + SetBinary(itemhamlog5FLAG, LPBYTE(&usFlag)); + SetData(itemhamlog5CALLS, Calls.c_str()); + LPCSTR pCall = Calls.c_str(); + memset(bf, ' ', 12); bf[13] = 0; + l = strlen(pCall); + if( l > 8 ){ + pCall += 8; + l -= 8; + memcpy(bf, pCall, l); + } + l = strlen(Ign.c_str()); + if( l ){ + if( l > 12 ) l = 12; + memcpy(&bf[12 - l], Ign.c_str(), l); + } + SetData(itemhamlog5IGN, bf); +} + diff --git a/Hamlog5.h b/Hamlog5.h new file mode 100644 index 0000000..8f630fc --- /dev/null +++ b/Hamlog5.h @@ -0,0 +1,119 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef Hamlog5H +#define Hamlog5H + +// MMQSL用Hamlog Ver5のドライバ + +#include "ComLib.h" +#include "LogFile.h" +extern const LPCSTR g_Hamlog5Key[]; +extern const BYTE g_Hamlog5Len[]; + +typedef enum { + itemhamlog5CALLS, + itemhamlog5IGN, + itemhamlog5DATE, + itemhamlog5TIME, + itemhamlog5CODE, + itemhamlog5GL, + itemhamlog5QSL, + itemhamlog5FLAG, + itemhamlog5HIS, + itemhamlog5MY, + itemhamlog5FREQ, + itemhamlog5MODE, + itemhamlog5NAME, + itemhamlog5QTH, + itemhamlog5RMK1, + itemhamlog5RMK2, +}HAMLOG5_ITEMS; + +#define bithamlog5DX 8 +#define bithamlog5NorOdr 1 +#define bithamlog5RevOdr 2 + +#pragma pack(1) +typedef struct { + BYTE Type; + BYTE Year; + BYTE Mon; + BYTE Day; + ULONG RecMax; + USHORT FilOff; + USHORT RecWidth; + BYTE dm1[20]; +}hamlog5DBHD; +typedef struct { + char Name[11]; + BYTE Type; + BYTE dm1[4]; + BYTE Len; + BYTE dm2[15]; +}hamlog5DBRHD; +#pragma pack() + +#define HamlogDBMAX 16 +class CHamlog5 +{ +private: + BOOL m_fCreate; + hamlog5DBHD m_Head; // ヘッダ情報 + ULONG m_RecMax; // レコード数 + USHORT m_FilMax; // フィールド数 + USHORT m_RecWidth; // レコードの幅 + USHORT m_FilOff; // ヘッダオフセット + FILE *m_fp; + AnsiString m_StrTable[HamlogDBMAX]; // テーブル名の配列 + USHORT m_PosTable[HamlogDBMAX]; // フィールド位置の配列 + USHORT m_LenTable[HamlogDBMAX]; // フィールド長さの配列 + char m_TypeTable[HamlogDBMAX]; // 型情報の配列 + BOOL m_OpenFlag; // ファイルオープンフラグ + + ULONG m_Index; // シーク時のインデックス + ULONG m_Pos; // シーク時のファイル位置 + LPSTR m_bp; // バッファのポインタ + BOOL m_WriteFlag; // 書き込みフラグ + BOOL SetupHeader(void); // ヘッダセットアップ + BOOL MakeHeader(const LPCSTR _NT[], const BYTE _LT[]); +public: + CHamlog5(); + ~CHamlog5(); + BOOL Open(LPCSTR Name, BOOL fMsg); + BOOL Create(LPCSTR Name); + void Close(void); + inline ULONG GetRCount(void){return m_RecMax;}; + inline USHORT GetFCount(void){return m_FilMax;}; + AnsiString *GetStrBase(void){return m_StrTable;}; + BOOL Seek(ULONG Index); + BOOL IsData(void); + BOOL GetData(USHORT SubIndex, AnsiString &cs); + BOOL GetData(USHORT SubIndex, LPSTR pStore); + BOOL SetData(USHORT SubIndex, LPCSTR p); + BOOL SetBinary(USHORT SubIndex, LPBYTE p); + int GetData(USHORT SubIndex, LPBYTE pData, int len); + BOOL Update(void); + void DecodeData(SDMMLOG *sp); + void EncodeData(SDMMLOG *sp); +}; + +void __fastcall GetHamlog5FieldsLen(AnsiString &as); +void __fastcall SetHamlog5FieldsLen(AnsiString &as); +#endif diff --git a/History.txt b/History.txt new file mode 100644 index 0000000..36e8b98 --- /dev/null +++ b/History.txt @@ -0,0 +1,310 @@ +======================== +BetaVer0.45 2010/OCT/04 +======================== +◎mfsk4, mfsk8, mfsk32, mfsk64, mfsk11, mfsk22を追加 +◎qpskモードの復調処理の改良 +◎起動時にサブチャネル画面を復元するオプションを追加 +◎マクロ機能の強化 +◎その他の細かい修正 + +======================== +BetaVer0.44 2010/SEP/24 +======================== +◎QPSKモードの追加 +◎RTTY復調器にFFT方式を追加 +◎RTTYのFSK送信(TNX JA7UDE) + COMポートを指定した場合、MMVARI内でタイミングを作成します。 + EXTFSKを指定した場合、EXTFSKがタイミングを作成します。 + いずれもマルチメディアタイマを使っいるので1ms程度のジッタが発生する可能性があります。 +◎英語版Webのアドレスの追加 +◎JARTSWebのアドレスの変更 +◎COM8〜COM16を選択に追加 +◎リグコントロールメニューの追加 +◎サウンドカード指定方法の改善 + +======================== +BetaVer0.42 2007/JAN/15 +======================== +◎英語環境動作時の起動時警告メッセージを削除 + +======================== +BetaVer0.41 2005/MAR/20 +======================== +◎BPSK-VariJA(MBCS)の送信禁止の解除(Tnx to JE4IVN) +◎英語モード時のtypeの修正 +◎バグの修正や小さな改善 + +======================== +BetaVer0.40 2005/JAN/08 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.39 2004/NOV/06 +======================== +◎Turbo Hamlog/Win Ver5とのリンクの改善 + +======================== +BetaVer0.38 2004/NOV/03 +======================== +◎Turbo Hamlog/Win Ver5への対応 (Tnx to JG1MOU) +◎バグの修正や小さな改善 + +======================== +BetaVer0.37 2004/OCT/08 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.36 2004/SEP/30 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.35 2004/SEP/22 +======================== +◎マクロ機能の強化 +◎バグの修正や小さな改善 + +======================== +BetaVer0.34 2004/SEP/11 +======================== +◎イベントマクロ(OnPTT,OnQSO,OnStart,...)の追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.33 2004/SEP/08 +======================== +◎GMSK/PSKのAFCを改善 +◎OnTimerイベントマクロの追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.32 2004/SEP/04 +======================== +◎デシメータの処理高速化 +◎バグの修正や小さな改善 + +======================== +BetaVer0.31 2004/AUG/28 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.30 2004/AUG/15 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.29 2004/AUG/09 +======================== +◎しょうもないバグの修正や小さな改善 + +======================== +BetaVer0.28 2004/AUG/07 +======================== +◎rttyで送信後に受信できなくなるバグを修正 +◎サウンドプレーバックオプションを追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.27 2004/AUG/03 +======================== +◎mfskモードの復調処理(同期処理,AFC動作,処理速度など)を改善 +◎バグの修正や小さな改善 + +======================== +BetaVer0.26 2004/JUL/31 +======================== +◎変調方式にmfskモードの追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.25 2004/JUL/27 +======================== +◎表示メニューに「拡張マクロボタンの表示」を追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.24 2004/JUL/22 +======================== +◎マクロ機能の強化 + <%Menu=...>コマンドを追加 + <%RadioKHz=...>にKENWOODとJST245を追加 + <%RadioMode=...>を追加 + 詳細は操作マニュアルのマクロの解説「ポップアップメニュー」および + 「マクロでのリグコントロール」を参照して下さい。 +◎バグの修正や小さな改善 + +======================== +BetaVer0.23 2004/JUL/19 +======================== +◎AFCの検出レベル計算のバグを修正 +◎リグの周波数の設定マクロ<%RadioKHz=....>を追加 + 現状は以下の3種類 + <%RadioKHz=YAESU-HF,14073.000> FT1000MP, FT920, etc... + <%RadioKHz=YAESU-VU,14073.000> FT847, FT736, etc... + <%RadioKHz=CI-V,14073.000> ICOM + 例:500Hzアップ + <%RadioKHz=YAESU-VU,<%RadioKHz>+0.5> +◎バグの修正や小さな改善 + +======================== +BetaVer0.22 2004/JUL/14 +======================== +◎AFC特性を改善 +◎バグの修正や小さな改善 + +======================== +BetaVer0.21 2004/JUN/29 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.20 2004/JUN/28 +======================== +◎スペクトラム右クリックの操作を改善 +◎クロックズレ信号受信時の同期方法を改善 +◎バグの修正や小さな改善 + +======================== +BetaVer0.19 2004/JUN/26 +======================== +◎ノッチフィルタの追加(スペクトラム右クリック) +◎BPF特性の改善 +◎バグの修正や小さな改善 + +======================== +BetaVer0.18 2004/JUN/12 +======================== +◎変調方式にrttyモードの追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.17 2004/JUN/04 +======================== +◎マクロ機能の強化 +◎バグの修正や小さな改善 + +======================== +BetaVer0.16 2004/MAR/20 +======================== +◎MMTTY/MMSSTVカスタムサウンドの実装 +◎バグの修正や小さな改善 + +======================== +BetaVer0.15 2004/MAR/02 +======================== +◎ウォータフォールの色とレベル配分の設定を増設 +◎バグの修正や小さな改善 + +======================== +BetaVer0.14 2004/FEB/28 +======================== +◎「全角アルファベットを半角に変換」を追加(設定画面-送信タブ) +◎22050,44100,48000Hz系などのクロックの動作を追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.13 2004/FEB/22 +======================== +◎VariSTD/JAの場合に半角のカナが送信できないバグを修正 +◎受信画面スクロール中の背景色を設定可能にした +◎受信画面右クリック(文字がないところ)のポップアップメニューを追加 +◎マクロのファイルへの保存とロードを追加(ファイルメニュー) +◎バグの修正や小さな改善 + +======================== +BetaVer0.12 2004/FEB/18 +======================== +◎一部のPCで動作しないバグを修正(再挑戦...) +◎6000Hz系クロックの動作を追加 +◎バグの修正や小さな改善 + +======================== +BetaVer0.11 2004/FEB/15 +======================== +◎一部のPCで動作しないバグを修正(?) +◎マクロ機能の強化 +◎バグの修正や小さな改善 + +======================== +BetaVer0.10 2004/FEB/12 +======================== +◎バグの修正や小さな改善 + +======================== +BetaVer0.09 2004/FEB/09 +======================== +◎変調方式にBPSK,bpskモードの追加 + BPSK - HALPSK,WINPSK/Jとの互換性なし(当面はVariJAは送信禁止にします) + bpsk - 従来のSTD-VARICODE(互換性あり) + なお、BPSK(bpsk)ははっきり言って作りっぱなしで、まだ一度も + 本チャンの信号は受けていません... +◎振幅成分表示を追加(BPSK変調処理のデバッグ用) + スペクトラム左側の「Sync」ボタンを右クリック +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.08 2004/FEB/04 + +======================== +◎送信画面の編集操作の改善 +◎マクロの拡張 +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.07 2004/JAN/27 +======================== +◎RadioCommand(リグコントロール)のPTTが効かなかったバグを修正 +◎V/UHF帯用にFSK(fm=1.0)を追加(Rigの周波数ドリフト対策) +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.06 2004/JAN/23 +======================== +◎オプションメニューに「サウンドカード校正画面」を追加 +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.05 2004/JAN/21 +======================== +◎英語のメニューメッセージを追加(Tnx Kim, HL3IB and Sung HL1AQ) +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.04 2004/JAN/19 +======================== +◎mmvari.txt(現状はメモ程度)を追加 +◎英語版EProject.txtをパッケージ内に同梱(Tnx JA7UDE) +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.03 2004/JAN/15 +======================== +◎プログラムの名称を変更(変調方式を変更するかも知れないので) +◎日本語のVariCodeインデックス変換方法を変更 + $E040-$FEFF(難しい漢字)の範囲を$A040からに変更し符合を短くした。 +◎TX,TXOFFのキーを変更可能にした(設定画面の「送信」タブ) +◎その他、バグの修正や小さな改善 + +======================== +BetaVer0.02 +======================== +◎サウンドの録音/再生機能(調整用)を追加 +◎RadioCommandを追加 +◎ログ機能を追加 +◎TurboHamlog/Winとのリンク機能を追加 +◎バグの修正 + +======================== +BetaVer0.01 2004/JAN/09 +======================== +◎設定画面「受信」タブにAFC吸い込みレベル(S/N比で設定)を追加 +◎編集メニューに「文字コード表」を追加 +◎オプションメニューに「VARICODEの参照」を追加 + +======================== +BetaVer0.00 2004/JAN/08 +======================== +◎初期バージョン diff --git a/InputWin.cpp b/InputWin.cpp new file mode 100644 index 0000000..d238ad2 --- /dev/null +++ b/InputWin.cpp @@ -0,0 +1,73 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "InputWin.h" +#include "MacroKey.h" +#include "ComLib.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//--------------------------------------------------------------------- +__fastcall TInputWinDlg::TInputWinDlg(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + CancelBtn->Caption = "Cancel"; + } + FormCenter(this); +} +//--------------------------------------------------------------------- +int InputMB(LPCSTR pTitle, LPCSTR pMsg, AnsiString &as, BOOL fMac) +{ + TForm *fp; + if( Screen->ActiveForm != NULL ){ + fp = Screen->ActiveForm; + } + else if( Application->MainForm != NULL ){ + fp = Application->MainForm; + } + else { + fp = NULL; + } + + TInputWinDlg *pBox = new TInputWinDlg(fp); + pBox->LMsg->Caption = pMsg; + pBox->Caption = pTitle ? pTitle : "MMVARI"; + pBox->Edit->Text = as.c_str(); + int r = FALSE; + if( pBox->ShowModal() == IDOK ){ + as = pBox->Edit->Text.c_str(); + r = TRUE; + } + delete pBox; + return r; +} +//--------------------------------------------------------------------- +int InputMB(LPCSTR pTitle, LPCSTR pMsg, AnsiString &as) +{ + return InputMB(pTitle, pMsg, as, FALSE); +} +//--------------------------------------------------------------------- + diff --git a/InputWin.dfm b/InputWin.dfm new file mode 100644 index 0000000..5e49eb1 Binary files /dev/null and b/InputWin.dfm differ diff --git a/InputWin.h b/InputWin.h new file mode 100644 index 0000000..29ae9a0 --- /dev/null +++ b/InputWin.h @@ -0,0 +1,50 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef InputWinH +#define InputWinH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TInputWinDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TEdit *Edit; + TLabel *LMsg; +private: +public: + virtual __fastcall TInputWinDlg(TComponent* AOwner); +}; +int InputMB(LPCSTR pTitle, LPCSTR pMsg, AnsiString &as, BOOL fMac); +int InputMB(LPCSTR pTitle, LPCSTR pMsg, AnsiString &as); +//---------------------------------------------------------------------------- +#endif + diff --git a/LogConv.cpp b/LogConv.cpp new file mode 100644 index 0000000..a51e26e --- /dev/null +++ b/LogConv.cpp @@ -0,0 +1,2231 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include "LogConv.h" +#include "country.h" +#include "main.h" +#include "InputWin.h" +CLogText LogText; +//*************************************************************************** +// CLogConv 基本 クラス +__fastcall CLogConv::CLogConv() +{ + m_Mode = 0; + m_fp = NULL; +} + +__fastcall CLogConv::~CLogConv() +{ +} +//*************************************************************************** +// CLogText クラス +__fastcall CLogText::CLogText() +{ + m_Type = 0; + m_Double = 0; + m_Delm = 0; + m_err = 0; + m_UTC = (sys.m_LCID != 0x0411) ? 1 : 0; + int i; + for( i = 0; i < TEXTCONVMAX; i++ ){ + m_tConv[i].Key = ""; + m_tConv[i].w = 0; + } + m_tConv[0].Key = "%YYYY-MM-DD"; + m_tConv[1].Key = "%HHMM"; + m_tConv[2].Key = "%EHHMM"; + m_tConv[3].Key = "%CALL"; + m_tConv[4].Key = "%HIS"; + m_tConv[5].Key = "%MY"; + m_tConv[6].Key = "%FREQ"; + m_tConv[7].Key = "%MODE"; + m_tConv[8].Key = "%POWER"; + m_tConv[9].Key = "%NAME"; + m_tConv[10].Key = "%QTH"; + m_tConv[11].Key = "%REM"; + m_tConv[12].Key = "%QSL"; + m_tConv[13].Key = "%S"; + m_tConv[14].Key = "%R"; + m_tConv[15].Key = "%EOD"; + for( i = 0; i < TEXTCONVMAX; i++ ){ + m_rConv[i] = m_tConv[i]; + } +} +//--------------------------------------------------------------------------- +// テキストファイルのオープン +int __fastcall CLogText::Open(LPCSTR pName) +{ + Close(); + m_Mode = 0; + m_err = 0; + + m_fp = fopen(pName, "rt"); + + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB( sys.m_MsgEng ? "Can't open '%s'":"'%s'がオープンできません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// テキストファイルの作成 +int __fastcall CLogText::Create(LPCSTR pName) +{ + Close(); + m_Mode = 1; + + m_fp = fopen(pName, "wt"); + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB( sys.m_MsgEng ? "Can't write to '%s'":"'%s'が作成できません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// テキストファイルのオープン +int __fastcall CLogText::Close(void) +{ + int r = 0; + if( m_fp != NULL ){ + r = fclose(m_fp); + m_fp = NULL; + if( r ){ + ErrorMB( sys.m_MsgEng ? "Can't close '%s'":"'%s'が正しくクローズできませんでした.", m_FileName.c_str()); + } + else if( m_Mode ){ + InfoMB(sys.m_MsgEng ? "Done (write to '%s')":"'%s'への書きこみを終了しました.", m_FileName.c_str()); + } + } + return r ? FALSE : TRUE; +} +//--------------------------------------------------------------------------- +// テキストファイルの読み出し +int __fastcall CLogText::Read(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + if( !feof(m_fp) ){ + if( fgets(m_bf, sizeof(m_bf), m_fp) != NULL ){ + ClipLF(m_bf); + return Text2MMLOG(sp, m_bf, m_err); + } + else { + return FALSE; + } + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +// 出力変換 +int __fastcall CLogText::Write(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + MMLOG2Text(m_bf, sp); + fputs(m_bf, m_fp); + fputs("\n", m_fp); + return ferror(m_fp) ? FALSE : TRUE; +} + +const LPCSTR ConvTbl[]={ + "%NULL", + "%YYYY-MM-DD", "%YY-MM-DD", "%YYYY/MM/DD", "%YY/MM/DD", + "%DD MON, YYYY","%YYMMDD", "%YYYYMMDD", + "%YY", "%YYYY", "%MM", "%MON", "%MON2", "%DD", "%HHMM", "%HH:MM","%HH:MM:SS", + "%EHHMM", "%EHH:MM", "%EHH:MM:SS", "%CALL", + "%M", "%MY", "%HIS", "%MYRST", "%HISRST", "%MYNR", "%HISNR", "%FREQ", "%KHZ", + "%MBAND", "%MODE", "%POWER", "%NAME", "%QTH", "%REM", "%QSL", + "%S", "%R", "%ENV", "%OPT1", "%OPT2", "%USR1", "%USR2", + "%EOD", + NULL, +}; + +const char *MONT1[]={"","JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"}; +const char *MONT2[]={"","Jan.","Feb.","Mar.","Apr.","May","June","July","Aug.","Sept.","Oct.","Nov.","Dec."}; + +//--------------------------------------------------------------------------- +void __fastcall MMLOG2Text(LPSTR t, SDMMLOG *sp, AnsiString &Key) +{ + int tim, l; + + if( Key == "%YYYY-MM-DD" ){ + sprintf(t, "%04u-%02u-%02u", YEAR(sp->year), sp->date/100, sp->date%100); + } + else if( Key == "%YY-MM-DD" ){ + sprintf(t, "%2u-%02u-%02u", sp->year, sp->date/100, sp->date%100); + } + else if( Key == "%YYYY/MM/DD" ){ + sprintf(t, "%04u/%02u/%02u", YEAR(sp->year), sp->date/100, sp->date%100); + } + else if( Key == "%YY/MM/DD" ){ + sprintf(t, "%2u/%02u/%02u", sp->year, sp->date/100, sp->date%100); + } + else if( Key == "%DD MON, YYYY" ){ + sprintf(t, "%02u %s, %04u", sp->date%100, MONT1[sp->date/100], YEAR(sp->year)); + } + else if( Key == "%YYYYMMDD" ){ + sprintf(t, "%04u%02u%02u", YEAR(sp->year), sp->date/100, sp->date%100); + } + else if( Key == "%YYMMDD" ){ + sprintf(t, "%02u%02u%02u", sp->year, sp->date/100, sp->date%100); + } + else if( Key == "%YY" ){ + sprintf(t, "%02u", sp->year); + } + else if( Key == "%YYYY" ){ + sprintf(t, "%04u", YEAR(sp->year)); + } + else if( Key == "%MM" ){ + sprintf(t, "%02u", sp->date / 100); + } + else if( Key == "%MON" ){ + strcpy(t, MONT1[sp->date/100]); + } + else if( Key == "%MON2" ){ + strcpy(t, MONT2[sp->date/100]); + } + else if( Key == "%DD" ){ + sprintf(t, "%02u", sp->date % 100); + } + else if( Key == "%HHMM" ){ + if( sp->btime ){ + tim = sp->btime / 30; + sprintf(t, "%02u%02u", tim / 60, tim % 60); + } + else { + *t = 0; + } + } + else if( Key == "%HH:MM" ){ + if( sp->btime ){ + tim = sp->btime / 30; + sprintf(t, "%02u:%02u", tim / 60, tim % 60); + } + else { + *t = 0; + } + } + else if( Key == "%HH:MM:SS" ){ + if( sp->btime ){ + tim = sp->btime / 30; + sprintf(t, "%02u:%02u:%02u", tim / 60, tim % 60, (sp->btime * 2) % 60); + } + else { + *t = 0; + } + } + else if( Key == "%EHHMM" ){ + if( sp->etime ){ + tim = sp->etime / 30; + sprintf(t, "%02u%02u", tim / 60, tim % 60); + } + else { + *t = 0; + } + } + else if( Key == "%EHH:MM" ){ + if( sp->etime ){ + tim = sp->btime / 30; + sprintf(t, "%02u:%02u", tim / 60, tim % 60); + } + else { + *t = 0; + } + } + else if( Key == "%EHH:MM:SS" ){ + if( sp->etime ){ + tim = sp->btime / 30; + sprintf(t, "%02u:%02u:%02u", tim / 60, tim % 60, (sp->etime * 2) % 60); + } + else { + *t = 0; + } + } + else if( Key == "%CALL" ){ + strcpy(t, sp->call); + } + else if( Key == "%M" ){ + *t = sp->send; + *(t+1) = 0; + } + else if( Key == "%HIS" ){ + strcpy(t, sp->ur); + } + else if( Key == "%MY" ){ + strcpy(t, sp->my); + } + else if( Key == "%HISRST" ){ + StrCopy(t, sp->ur, GetLMode(sp->mode)); + } + else if( Key == "%MYRST" ){ + StrCopy(t, sp->my, GetLMode(sp->mode)); + } + else if( Key == "%HISNR" ){ + l = GetLMode(sp->mode); + if( (int)strlen(sp->ur) >= l ){ + strcpy(t, &sp->ur[l]); + } + else { + *t = 0; + } + } + else if( Key == "%MYNR" ){ + l = GetLMode(sp->mode); + if( (int)strlen(sp->my) >= l ){ + strcpy(t, &sp->my[l]); + } + else { + *t = 0; + } + } + else if( Key == "%FREQ" ){ + strcpy(t, Log.GetFreqString(sp->band, sp->fq)); + } + else if( Key == "%MBAND" ){ + strcpy(t, FreqTomBand(sp)); + } + else if( Key == "%KHZ" ){ + char bf[32]; + double dd; + strcpy(bf, Log.GetFreqString(sp->band, sp->fq)); + sscanf(bf, "%lf", &dd); + sprintf(t, "%.2lf", dd * 1000.0); + } + else if( Key == "%MODE" ){ + strcpy(t, Log.GetModeString(sp->mode)); + } + else if( Key == "%POWER" ){ + strcpy(t, sp->pow); + } + else if( Key == "%NAME" ){ + strcpy(t, sp->name); + } + else if( Key == "%QTH" ){ + strcpy(t, sp->qth); + } + else if( Key == "%REM" ){ + strcpy(t, sp->rem); + } + else if( Key == "%QSL" ){ + strcpy(t, sp->qsl); + } + else if( Key == "%S" ){ + *t = sp->send; + *(t+1) = 0; + } + else if( Key == "%R" ){ + *t = sp->recv; + *(t+1) = 0; + } + else if( Key == "%ENV" ){ + sprintf(t, "%u", sp->env); + } + else if( Key == "%OPT1" ){ + strcpy(t, sp->opt1); + } + else if( Key == "%OPT2" ){ + strcpy(t, sp->opt2); + } + else if( Key == "%USR1" ){ + strcpy(t, Log.GetOptStr(2, sp)); + } + else if( Key == "%USR2" ){ + strcpy(t, Log.GetOptStr(3, sp)); + } + else if( (Key == "%EOD")||(Key == "%NULL") ){ + *t = 0; + } + else { + strcpy(t, Key.c_str()); + } +} +//--------------------------------------------------------------------------- +// 1行の出力変換 +void __fastcall CLogText::MMLOG2Text(LPSTR t, SDMMLOG *sp) +{ + char bf[512]; + char dlm = m_Delm ? TAB : ','; + + if( m_UTC ) JSTtoUTC(sp); + int i; + for( i = 0; i < TEXTCONVMAX; i++ ){ + if( (!m_tConv[i].Key.IsEmpty())&&(m_tConv[i].Key != "%EOD") ){ + ::MMLOG2Text(bf, sp, m_tConv[i].Key); + switch(m_Delm){ + case 0: // CSV + case 1: // TAB + if( i ) *t++ = dlm; + if( m_Double || (strchr(bf, dlm) != NULL) ) *t++ = 0x22; + if( m_tConv[i].w ){ + StrCopy(t, bf, m_tConv[i].w); + } + else { + strcpy(t, bf); + } + t += strlen(t); + if( m_Double || (strchr(bf, dlm) != NULL) ) *t++ = 0x22; + break; + default: // Format Text + if( m_tConv[i].w ){ + StrCopy(t, bf, m_tConv[i].w); + FillSpace(t, m_tConv[i].w); + } + else { + strcpy(t, bf); + } + t += strlen(t); + break; + } + } + else { + break; + } + } + *t = 0; +} +//--------------------------------------------------------------------------- +int __fastcall GetMonth(LPCSTR p) +{ + for( int i = 1; i <=12; i++ ){ + if( !strcmpi(MONT1[i], p) ) return i; + if( !strcmpi(MONT2[i], p) ) return i; + } + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall Text2MMLOG(SDMMLOG *sp, LPCSTR s, AnsiString &Key) +{ + int y, m, d, h; + int tim; + + if( (Key == "%YYYY-MM-DD")||(Key == "%YY-MM-DD") ){ + if( sscanf(s, "%u-%u-%u", &y, &m, &d) != 3 ) return FALSE; + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + else if( (Key == "%YYYY/MM/DD")||(Key == "%YY/MM/DD") ){ + if( sscanf(s, "%u/%u/%u", &y, &m, &d) != 3 ) return FALSE; + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + else if( Key == "%DD MON, YYYY" ){ + d = atoin(s, 2); + s += 3; + char bf[4]; + StrCopy(bf, s, 3); + m = GetMonth(bf); + s = SkipSpace(s+1); + y = atoin(s, -1); + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + else if( Key == "%YYYYMMDD" ){ + y = atoin(s, 4); s += 4; + m = atoin(s, 2); s += 2; + d = atoin(s, 2); + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + else if( Key == "%YYMMDD" ){ + y = atoin(s, 2); s += 2; + m = atoin(s, 2); s += 2; + d = atoin(s, 2); + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + else if( (Key == "%YY")||(Key == "%YYYY") ){ + if( sscanf(s, "%u", &y) != 1 ) return FALSE; + sp->year = BYTE(y % 100); + } + else if( Key == "%MM" ){ + if( sscanf(s, "%u", &m) != 1 ) return FALSE; + sp->date = WORD((sp->date % 100) + m * 100); + } + else if( (Key == "%MON")||(Key == "%MON2") ){ + m = GetMonth(s); + sp->date = WORD((sp->date % 100) + m * 100); + } + else if( Key == "%DD" ){ + if( sscanf(s, "%u", &d) != 1 ) return FALSE; + sp->date = WORD(((sp->date / 100) * 100) + d); + } + else if( Key == "%HHMM" ){ + if( *s ){ + if( sscanf(s, "%u", &d) != 1 ) return FALSE; + h = d / 100; + m = d % 100; + tim = (h * 60 + m) * 30; + if( !tim ) tim++; + sp->btime = WORD(tim); + } + } + else if( (Key == "%HH:MM")||(Key == "%HH:MM:SS") ){ + if( *s ){ + if( sscanf(s, "%u:%u:%u", &h, &m, &d ) != 3 ){ + d = 0; + if( sscanf(s, "%u:%u", &h, &m) != 2 ) return FALSE; + } + tim = (h * 60 + m) * 30 + (d / 2); + if( !tim ) tim++; + sp->btime = WORD(tim); + } + } + else if( Key == "%EHHMM" ){ + if( *s ){ + if( sscanf(s, "%u", &d) != 1 ) return FALSE; + h = d / 100; + m = d % 100; + tim = (h * 60 + m) * 30; + if( !tim ) tim++; + sp->etime = WORD(tim); + } + } + else if( (Key == "%EHH:MM")||(Key == "%EHH:MM:SS") ){ + if( *s ){ + if( sscanf(s, "%u:%u:%u", &h, &m, &d ) != 3 ){ + d = 0; + if( sscanf(s, "%u:%u", &h, &m) != 2 ) return FALSE; + } + tim = (h * 60 + m) * 30 + (d / 2); + if( !tim ) tim++; + sp->etime = WORD(tim); + } + } + else if( Key == "%CALL" ){ + if( sp->call[0] ){ + char bf[256]; + sprintf(bf, "%s/%s", sp->call, s); + StrCopy(sp->call, bf, MLCALL); + } + else { + StrCopy(sp->call, s, MLCALL); + } + } + else if( Key == "%M" ){ + sp->send = *s; + } + else if( (Key == "%HIS")||(Key == "%HISRST") ){ + StrCopy(sp->ur, s, MLRST); + } + else if( (Key == "%MY")||(Key=="%MYRST") ){ + StrCopy(sp->my, s, MLRST); + } + else if( Key == "%FREQ" ){ + Log.SetFreq(sp, s); + } + else if( Key == "%MBAND" ){ + mBandToBand(sp, s); + } + else if( Key == "%KHZ" ){ + double dd; + sscanf(s, "%lf", &dd); + char bf[32]; + sprintf(bf, "%.03lf", dd / 1000.0); + Log.SetFreq(sp, bf); + } + else if( Key == "%MODE" ){ + Log.SetMode(sp, s); + } + else if( Key == "%POWER" ){ + StrCopy(sp->pow, s, MLPOW); + } + else if( Key == "%NAME" ){ + StrCopy(sp->name, s, MLNAME); + } + else if( Key == "%QTH" ){ + StrCopy(sp->qth, s, MLQTH); + } + else if( Key == "%REM" ){ + StrCopy(sp->rem, s, MLREM); + } + else if( Key == "%QSL" ){ + StrCopy(sp->qsl, s, MLQSL); + } + else if( Key == "%S" ){ + sp->send = *s; + } + else if( Key == "%R" ){ + sp->recv = *s; + } + else if( Key == "%ENV" ){ + if( sscanf(s, "%u", &d) != 1 ) return FALSE; + sp->env = WORD(d); + } + else if( Key == "%OPT1" ){ + StrCopy(sp->opt1, s, MLOPT); + } + else if( Key == "%OPT2" ){ + StrCopy(sp->opt2, s, MLOPT); + } + else if( Key == "%USR1" ){ + Log.SetOptStr(2, sp, s); + } + else if( Key == "%USR2" ){ + Log.SetOptStr(3, sp, s); + } + else if( (Key != "%EOD")&&(Key != "%NULL") ){ + if( Key != s ){ + return FALSE; + } + } + return TRUE; +} +//--------------------------------------------------------------------------- +// 1行の入力変換 +int __fastcall CLogText::Text2MMLOG(SDMMLOG *sp, LPSTR p, int &err) +{ + char bf[512]; + char dlm = m_Delm ? TAB : ','; + LPSTR t; + + memset(sp, 0, sizeof(SDMMLOG)); + int i; + for( i = 0; i < TEXTCONVMAX; i++ ){ + if( (!m_rConv[i].Key.IsEmpty())&&(m_rConv[i].Key != "%EOD") ){ + if( m_Delm == 2 ){ + StrCopy(bf, p, m_rConv[i].w); + p += strlen(bf); + t = bf; + } + else { + p = StrDlm(t, p, dlm); + } + clipsp(t); + t = SkipSpace(t); + if( ::Text2MMLOG(sp, t, m_rConv[i].Key ) == FALSE ){ + if( !err ){ + ErrorMB(sys.m_MsgEng ? "An error occurred with conversion type [%s]." : "変換式[%s]でエラーが発生しました.", m_rConv[i].Key.c_str() ); + } + err++; + } + } + else { + break; + } + } + if( !sp->etime ) sp->etime = sp->btime; + if( m_UTC ) UTCtoJST(sp); + return err ? FALSE : TRUE; +} +// +// +//*************************************************************************** +// CLog200 クラス +__fastcall CLog200::CLog200() +{ + m_Type = 1; + m_err = 0; +} +//--------------------------------------------------------------------------- +// LOG200ファイルのオープン +int __fastcall CLog200::Open(LPCSTR pName) +{ + Close(); + m_Index = 0; + m_err = 0; + + m_fp = fopen(pName, "rb"); + if( m_fp != NULL ){ + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB("'%s'がオープンできません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// LOG200ファイルの作成 +int __fastcall CLog200::Create(LPCSTR pName) +{ + Close(); + m_Mode = 1; + m_err = 0; + + int add = 0; + if( (m_fp = fopen(pName, "rb"))!=NULL ){ + fclose(m_fp); + m_fp = NULL; + add = 1; + char BackName[256]; + strcpy(BackName, pName); + SetEXT(BackName, ".BAK"); + int r = YesNoCancelMB( "'%s'は既に存在しています.\r\nMMTTYはこのファイルにデータを追加します.\r\n\r\n" + "この操作を実行する前に元のログファイルのバックアップファイル\r\n\r\n" + "'%s' -> '%s'\r\n\r\nを作成しますか?\r\n\r\n" + "[重要]\r\n念のためにバックアップを作成する事をお勧めします.", pName, pName, BackName); + if( r == IDYES ){ + CWaitCursor w; + if( ::CopyFile(pName, BackName, FALSE) == FALSE ){ + ErrorMB("バックアップの作成に失敗しました.\r\nこの処理は中断されます.元のログファイルは変更されません."); + return FALSE; + } + } + else if( r == IDCANCEL ){ + return FALSE; + } + } + m_fp = fopen(pName, add ? "ab":"wb"); + if( m_fp != NULL ){ + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB( "'%s'が作成できません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// LOG200ファイルのクローズ +int __fastcall CLog200::Close(void) +{ + int r = 0; + if( m_fp != NULL ){ + r = fclose(m_fp); + m_fp = NULL; + if( r ){ + ErrorMB("'%s'が正しくクローズできませんでした.", m_FileName.c_str()); + } + else if( m_Mode ){ + InfoMB("'%s'への追加を終了しました.", m_FileName.c_str()); + } + } + return r ? FALSE : TRUE; +} +//--------------------------------------------------------------------------- +// LOG200 -> MMLOG フォーマットの変換 +void __fastcall LOG200toMMLOG(SDMMLOG *sp, LPSTR s) +{ + LPSTR t; + int y, m, d, h, tim; + char bf[256]; + + memset(sp, 0, sizeof(SDMMLOG)); + s = StrDlm(t, s, 0x1e); /* DATE */ + y = atoin(t, 2); t += 2; + m = atoin(t, 2); t += 2; + d = atoin(t, 2); + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + + s = StrDlm(t, s, 0x1e); /* BGN */ + d = atoin(t, 4); + h = d / 100; + m = d % 100; + tim = (h * 60 + m) * 30; + if( !tim ) tim++; + sp->btime = WORD(tim); + + s = StrDlm(t, s, 0x1e); /* END */ + d = atoin(t, 4); + h = d / 100; + m = d % 100; + tim = (h * 60 + m) * 30; + if( !tim ) tim++; + sp->etime = WORD(tim); + + s = StrDlm(t, s, 0x1e); /* CALL */ + clipsp(t); + StrCopy(sp->call, t, MLCALL); + + s = StrDlm(t, s, 0x1e); /* FREQ */ + if( LastC(t) == '.' ){ + *lastp(t) = 0; + } + Log.SetFreq(sp, t); + + s = StrDlm(t, s, 0x1e); /* MODE */ + Log.SetMode(sp, t); + + s = StrDlm(t, s, 0x1e); /* RST */ + clipsp(t); + StrCopy(sp->ur, t, MLRST); + + s = StrDlm(t, s, 0x1e); /* MyRST*/ + clipsp(t); + StrCopy(sp->my, t, MLRST); + + s = StrDlm(t, s, 0x1e); /* QTH */ + clipsp(t); + StrCopy(sp->qth, t, MLQTH); + + s = StrDlm(t, s, 0x1e); /* NAME */ + clipsp(t); + StrCopy(sp->name, t, MLNAME); + + s = StrDlm(t, s, 0x1e); /* RIG */ + clipsp(t); + LPSTR pRIG = t; + + s = StrDlm(t, s, 0x1e); /* CONTEST */ + clipsp(t); + LPSTR pContest = t; + + s = StrDlm(t, s, 0x1e); /* Rem */ + clipsp(t); + + if( (strlen(sp->call) == 15) && (RemoveL2(bf, t, "CALL", sizeof(bf)-1) == TRUE) ){ + StrCopy(sp->call, bf, MLCALL); + } + if( RemoveL2(bf, t, "POW", sizeof(bf)-1) == TRUE ){ + StrCopy(sp->pow, bf, MLPOW); + } + if( RemoveL2(bf, t, "ENV", sizeof(bf)-1) == TRUE ){ + sp->env = WORD(atoin(bf, -1)); + } + if( RemoveL2(bf, t, "M", sizeof(bf)-1) == TRUE ){ + sp->cq = bf[0]; + } + if( RemoveL2(bf, t, "OPT1", sizeof(bf)-1) == TRUE ){ + StrCopy(sp->opt1, bf, MLOPT); + } + if( RemoveL2(bf, t, "OPT2", sizeof(bf)-1) == TRUE ){ + StrCopy(sp->opt2, bf, MLOPT); + } + if( RemoveL2(bf, t, "USR1", sizeof(bf)-1) == TRUE ){ + Log.SetOptStr(2, sp, bf); + } + if( RemoveL2(bf, t, "USR2", sizeof(bf)-1) == TRUE ){ + Log.SetOptStr(3, sp, bf); + } + if( RemoveL2(bf, t, "MQSL", sizeof(bf)-1) == TRUE ){ + StrCopy(sp->qsl, bf, MLQSL); + } + clipsp(t); + t = SkipSpace(t); + StrCopy(sp->rem, t, MLREM); + + s = StrDlm(t, s, 0x1e); /* MyQTH*/ + if( *t ) AddL2(sp->qsl, "MyQTH", t, '[', ']', MLQSL); + + s = StrDlm(t, s, 0x1e); /* MyRig*/ + if( *t ) AddL2(sp->qsl, "MyRIG", t, '[', ']', MLQSL); + + s = StrDlm(t, s, 0x1e); /* Send */ + sp->send = *t; + StrDlm(t, s, 0x1e); /* Recv */ + sp->recv = *t; + + if( *pRIG ) AddL2(sp->qsl, "RIG", pRIG, '[', ']', MLQSL); + if( *pContest ) AddL2(sp->qsl, "TEST", pContest, '[', ']', MLQSL); +} +//--------------------------------------------------------------------------- +// LOG200ファイルの読み出し +int __fastcall CLog200::Read(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + if( fread(m_bf, 1, 200, m_fp) == 200 ){ + LOG200toMMLOG(sp, m_bf); + m_Index++; + return TRUE; + } + else { + return FALSE; + } +} + +//--------------------------------------------------------------------------- +// MMLOG -> LOG200フォーマット変換 +void __fastcall MMLOGtoLOG200(LPSTR t, SDMMLOG *sp, int &err) +{ + LPSTR s = t; + int h, m; + char bf[256]; + + memset(t, ' ', 200); + // YYMMDD + sprintf(t, "%02u%02u%02u\x1e", sp->year, sp->date / 100, sp->date % 100); + t += strlen(t); + // BGN(HHMM) + h = sp->btime / 1800; + m = (sp->btime % 1800) / 30; + sprintf(t, "%02u%02u\x1e", h, m); + t += strlen(t); + // END + h = sp->etime / 1800; + m = (sp->etime % 1800) / 30; + sprintf(t, "%02u%02u\x1e", h, m); + t += strlen(t); + // CALL + StrCopy(t, sp->call, 15); // 15文字に制限されている + t += strlen(t); + *t++ = 0x1e; + // FREQ + sprintf(bf, "%s", Log.GetFreqString(sp->band, sp->fq)); + if( bf[0] ){ + double dd; + if( sscanf(bf, "%lf", &dd) == 1 ){ + sprintf(bf, "%.3lf", dd); + } + } + strcpy(t, bf); + t += strlen(t); + *t++ = 0x1e; + // MODE + sprintf(t, "%s\x1e", Log.GetModeString(sp->mode)); + t += strlen(t); + // HisRST + sprintf(t, "%s\x1e", sp->ur); + t += strlen(t); + // MyRST + sprintf(t, "%s\x1e", sp->my); + t += strlen(t); + // QTH + sprintf(t, "%s\x1e", sp->qth); + t += strlen(t); + // NAME + sprintf(t, "%s\x1e", sp->name); + t += strlen(t); + // RIG + if( RemoveL2(bf, sp->qsl, "Rig", sizeof(bf)-1) == TRUE ){ + strcpy(t, bf); + } + *t++ = 0x1e; + // CONTEST + if( RemoveL2(bf, sp->qsl, "TEST", sizeof(bf)-1) == TRUE ){ + strcpy(t, bf); + } + *t++ = 0x1e; + char MyRig[200]; + char MyQTH[200]; + MyRig[0] = MyQTH[0] = 0; + if( RemoveL2(bf, sp->qsl, "MyRig", sizeof(bf)-1) == TRUE ){ + strcpy(MyRig, bf); + } + if( RemoveL2(bf, sp->qsl, "MyQTH", sizeof(bf)-1) == TRUE ){ + strcpy(MyQTH, bf); + } + clipsp(sp->qsl); + LPSTR p = SkipSpace(sp->qsl); + + // REM + strcpy(bf, sp->rem); + char bbf[128]; + if( strlen(sp->call) > 11 ){ + AddL2(bf, "CALL", sp->call, '[', ']', MLQSL); + } + if( sp->cq ){ + bbf[0] = sp->cq; bbf[1] = 0; + AddL2(bf, "M", bbf, '[', ']', MLQSL); + } + if( sp->pow[0] ) AddL2(bf, "POW", sp->pow, '[', ']', MLQSL); + if( sp->env ){ + sprintf(bbf, "%u", sp->env); + AddL2(bf, "ENV", bbf, '[', ']', MLQSL); + } + if( sp->opt1[0] ) AddL2(bf, "OPT1", sp->opt1, '[', ']', MLQSL); + if( sp->opt2[0] ) AddL2(bf, "OPT2", sp->opt2, '[', ']', MLQSL); + LPCSTR pp = Log.GetOptStr(2, sp); + if( *pp ) AddL2(bf, "USR1", pp, '[', ']', MLQSL); + pp = Log.GetOptStr(3, sp); + if( *pp ) AddL2(bf, "USR2", pp, '[', ']', MLQSL); + + if( *p ) AddL2(bf, "MQSL", p, '[', ']', MLQSL); + int len = (t - s) + strlen(bf) + 1 + strlen(MyQTH) + 1 + strlen(MyRig) + 1 + 2; + if( len >= 199 ){ + if( !err ){ + err++; + WarningMB("変換した結果がLOG200レコード長を越えました.\r\n\r\nリマークフィールドの長さを調整します."); + } + len -= 199; + bf[strlen(bf)-len] = 0; + } + + sprintf(t, "%s\x1e", bf); + t += strlen(t); + + // MyQTH + sprintf(t, "%s\x1e", MyQTH); + t += strlen(t); + // MyRIG + sprintf(t, "%s\x1e", MyRig); + t += strlen(t); + // S + if( sp->send ) *t++ = sp->send; + *t++ = 0x1e; + // R + if( sp->recv ) *t++ = sp->recv; + *t = 0x1e; + + s[198] = '\r'; s[199] = '\n'; +} +//--------------------------------------------------------------------------- +// LOG200ファイルの書きこみ +int __fastcall CLog200::Write(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + MMLOGtoLOG200(m_bf, sp, m_err); + if( fwrite(m_bf, 1, 200, m_fp) != 200 ){ + ErrorMB("'%s'に書き込み中にエラーが発生しました.", m_FileName.c_str()); + return FALSE; + } + else { + m_Index++; + return TRUE; + } +} +// +// +//*************************************************************************** +// CHamLog クラス +//--------------------------------------------------------------------------- +__fastcall CHamLog::CHamLog() +{ + m_Type = 2; + m_err = 0; + + m_DBRName = ""; // DBRファイルの名前 + m_dbrfp = NULL; // DBRファイルのファイルポインタ +} +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +// HamLogファイルのオープン +int __fastcall CHamLog::Open(LPCSTR pName) +{ + Close(); + m_Index = 0; + m_err = 0; + m_Mode = 0; + + m_fp = fopen(pName, "rb"); // DBSのオープン + + if( m_fp == NULL ){ + ErrorMB( "'%s'がオープンできません.", pName); + return FALSE; + } + m_FileName = pName; + if( (fread(&m_hd, 1, sizeof(m_hd), m_fp)!=sizeof(m_hd)) || + (m_hd.Memo != 0x1a) || + (m_hd.HeadLen != 449) || + (m_hd.DataLen != sizeof(m_RecBuf)) + ){ + fclose(m_fp); + m_fp = NULL; + ErrorMB("予期しないファイル形式です."); + return FALSE; + } + char dbrName[256]; + strcpy(dbrName, pName); + SetEXT(dbrName, ".DBR"); + m_DBRName = dbrName; + m_dbrfp = fopen(dbrName, "rb"); + if( m_dbrfp == NULL ){ + WarningMB( "'%s'がオープンできません.", dbrName); + } + else if( fread(&m_dbrhd, 1, sizeof(m_dbrhd), m_dbrfp)!=sizeof(m_dbrhd) ){ + ErrorMB( "'%s'が正常に読みこめません. 処理を中断します.", dbrName); + fclose(m_fp); + m_fp = NULL; + fclose(m_dbrfp); + m_dbrfp = NULL; + return FALSE; + } + + if( Seek(0) == FALSE ){ + Close(); + ErrorMB("最初のレコードが見つかりません."); + return FALSE; + } + return TRUE; +} + +int __fastcall CHamLog::Close(void) +{ + int r = 0; + if( m_fp != NULL ){ + if( m_Mode ){ // 書きこみ + fseek(m_fp, 0, SEEK_SET); + if( fwrite(&m_hd, 1, sizeof(m_hd), m_fp) != sizeof(m_hd) ) r = 1; + } + if( fclose(m_fp) ) r = 1;; + m_fp = NULL; + } + if( m_dbrfp != NULL ){ + if( m_Mode ){ + fseek(m_dbrfp, 0, SEEK_SET); + if( fwrite(&m_dbrhd, 1, sizeof(m_dbrhd), m_dbrfp) != sizeof(m_dbrhd) ) r = 1; + } + if( fclose(m_dbrfp) ) r = 1; + m_dbrfp = NULL; + } + if( r ){ + ErrorMB("ファイルのクローズに失敗しました."); + } + else if( m_Mode ){ + InfoMB("'%s'への追加を終了しました.", m_FileName.c_str()); + } + return r ? FALSE : TRUE; +} + +//--------------------------------------------------------------------------- +// HamLogファイルの作成 +int __fastcall CHamLog::Create(LPCSTR pName) +{ + Close(); + m_Mode = 1; + m_err = 0; + + char dbrName[256]; + strcpy(dbrName, pName); + SetEXT(dbrName, ".DBR"); + + int add = 0; + if( (m_fp = fopen(pName, "rt"))!=NULL ){ + fclose(m_fp); + add = 1; + char BackNameDBS[256]; + strcpy(BackNameDBS, pName); + SetEXT(BackNameDBS, ".$BS"); + char BackNameDBR[256]; + strcpy(BackNameDBR, dbrName); + SetEXT(BackNameDBR, ".$BR"); + int r = YesNoCancelMB( "'%s'は既に存在しています. データはこのファイルに追加されます.\r\n\r\nこの操作を実行する前に元のログファイルのバックアップファイル\r\n\r\n'%s'->'%s'\r\n'%s'->'%s'\r\n\r\nを作成しますか?\r\n\r\n" + "[重要]\r\n念のためにバックアップを作成する事をお勧めします.", pName, pName, BackNameDBS, dbrName, BackNameDBR); + if( r == IDYES ){ + CWaitCursor w; + if( ::CopyFile(pName, BackNameDBS, FALSE) == FALSE ){ + ErrorMB("バックアップの作成に失敗しました.\r\nこの処理は中断されます.元のログファイルは変更されません."); + return FALSE; + } + if( ::CopyFile(dbrName, BackNameDBR, FALSE) == FALSE ){ + ErrorMB("バックアップの作成に失敗しました.\r\nこの処理は中断されます.元のログファイルは変更されません."); + return FALSE; + } + } + else if( r == IDCANCEL ){ + return FALSE; + } + } + m_fp = fopen(pName, add ? "r+b":"wb"); + if( m_fp == NULL ){ + ErrorMB( "'%s'がオープンできません.", pName); + return FALSE; + } + m_dbrfp = fopen(dbrName, add ? "r+b":"wb"); + if( m_dbrfp == NULL ){ + ErrorMB( "'%s'がオープンできません.", dbrName); + return FALSE; + } + + if( add ){ // 追加の時 + if( (fread(&m_hd, 1, sizeof(m_hd), m_fp)!=sizeof(m_hd)) || + (m_hd.Memo != 0x1a) || + (m_hd.HeadLen != 449) || + (m_hd.DataLen != sizeof(m_RecBuf)) + ){ + fclose(m_fp); + m_fp = NULL; + fclose(m_dbrfp); + m_dbrfp = NULL; + ErrorMB("'%s'は予期しないファイル形式です.", pName); + return FALSE; + } + if( (fread(&m_dbrhd, 1, sizeof(m_dbrhd), m_dbrfp)!=sizeof(m_dbrhd)) || + (m_dbrhd.Memo != 0x1a) || + (m_dbrhd.term != 0x1a) + ){ + fclose(m_fp); + m_fp = NULL; + fclose(m_dbrfp); + m_dbrfp = NULL; + ErrorMB("'%s'は予期しないファイル形式です.", dbrName); + return FALSE; + } + fseek(m_dbrfp, 0, SEEK_END); // DBRの最後に移動 + } + else { // 新規の時 + MakeHD(); + } + m_FileName = pName; + m_Mode = 1; + m_DBRName = dbrName; + m_Index = m_hd.Max; + return TRUE; +} + +//---------------------------------------------------------------------- +int __fastcall CHamLog::Seek(DWORD Index) +{ + long Pos = 449 + (Index * sizeof(m_RecBuf)); + if( fseek(m_fp, Pos, SEEK_SET) ) return FALSE; + m_Index = Index; + return TRUE; +} + +//---------------------------------------------------------------------- +//HAMLOGのヘッダを作成 +BOOL __fastcall CHamLog::MakeHD(void) +{ + memset(&m_hd, 0, sizeof(m_hd)); + memset(&m_dbrhd, 0, sizeof(m_dbrhd)); + m_hd.Memo = 0x1a; + SYSTEMTIME st; + ::GetLocal(&st); + m_hd.YY = BYTE(st.wYear % 100); + m_hd.MM = BYTE(st.wMonth); + m_hd.DD = BYTE(st.wDay); + m_hd.Max = 0; + memcpy(&m_dbrhd, &m_hd, sizeof(m_hd)); + m_hd.HeadLen = 449; + m_hd.DataLen = sizeof(m_RecBuf); + if( fwrite(&m_hd, 1, sizeof(m_hd), m_fp) != sizeof(m_hd) ) return FALSE; + + LPCSTR _Name[]={"CALLS","IGN","POTBL","CODE","GL","FREQ","MODE","NAME","QSL","DATE","TIME","RST","OFS"}; + BYTE _Len[]={6, 1, 3, 6, 6, 4, 3, 12, 3, 3, 2, 4, 4, 0}; + DBSLOT slot; + for( int i = 0; _Len[i]; i++ ){ + memset(&slot, 0, sizeof(slot)); + strcpy(slot.Name, _Name[i]); + slot.Type = 'C'; + slot.Len = _Len[i]; + if( fwrite(&slot, 1, sizeof(slot), m_fp)!=sizeof(slot) ) return FALSE; + } + slot.Name[0] = 0x0d; + if( fwrite(&slot, 1, 1, m_fp)!=1 ) return FALSE; + + m_dbrhd.m1 = 1; + m_dbrhd.term = 0x1a; + if( fwrite(&m_dbrhd, 1, sizeof(m_dbrhd), m_dbrfp)!=sizeof(m_dbrhd) ) return FALSE; + return TRUE; +} + +//--------------------------------------------------------------------------- +// HamLogファイルの読み出し +int __fastcall CHamLog::Read(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + Seek(m_Index); + if( fread(&m_RecBuf, 1, sizeof(m_RecBuf), m_fp) == sizeof(m_RecBuf) ){ + HAMLOGtoMMLOG(sp, &m_RecBuf, m_dbrfp); + m_Index++; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +// HamLogファイルの書きこみ +int __fastcall CHamLog::Write(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + if( MMLOGtoHAMLOG(&m_RecBuf, sp, m_dbrfp) == FALSE ){ + ErrorMB("'%s'に書き込み中にエラーが発生しました.", m_DBRName.c_str()); + return FALSE; + } + Seek(m_hd.Max); + if( fwrite(&m_RecBuf, 1, sizeof(m_RecBuf), m_fp) != sizeof(m_RecBuf) ){ + ErrorMB("'%s'に書き込み中にエラーが発生しました.", m_FileName.c_str()); + return FALSE; + } + else { + m_hd.Max++; + m_dbrhd.Max++; + return TRUE; + } +} +//---------------------------------------------------------------------- +//HAMLOGの周波数記録方式を通常の文字列に変換 +void __fastcall DecBand(LPSTR t, BYTE *pBand) +{ + if( pBand[3] & 0x80 ){ // 5〜7文字の文字列 + int DotPos = pBand[3] & 0x7f; + int Len = (DotPos >> 3) & 0x07; + DotPos &= 0x07; + LPSTR p = t; + wsprintf(p, "%-7lu", (*((LONG *)pBand) & 0x00ffffffL)); + if( Len < 4 ){ // Ver3.19までの記録方式 + for(int i = 6; i > 3; i--){ + if(p[i]>'0'){ + break; + } + else if(p[i] == '0'){ + p[i] = ' '; + } + } + } + else { + if( Len < 6 ) p[6] = ' '; + if( Len == 4 ) p[5] = ' '; + } + p[DotPos] = '.'; + p[8] = 0; + } + else { // そのまま + StrCopy(t, (LPCSTR)pBand, 4); + } + clipsp(t); + if( LastC(t) == '.' ){ + *lastp(t) = 0; + } +} + +void __fastcall SetMMLOGKey(SDMMLOG *sp, LPSTR bf) +{ + char rbf[512]; + + if( RemoveL2(rbf, bf, "ToRadio", sizeof(rbf)-1) == TRUE ){ + StrCopy(sp->call, rbf, MLCALL); + } + else if( RemoveL2(rbf, bf, "CALL", sizeof(rbf)-1) == TRUE ){ + StrCopy(sp->call, rbf, MLCALL); + } + + if( RemoveL2(rbf, bf, "ENV", sizeof(rbf)-1) == TRUE ){ + sp->env = WORD(atoin(rbf, -1)); + } + if( RemoveL2(rbf, bf, "END", sizeof(rbf)-1) == TRUE ){ + int tim = atoin(rbf, -1); + int hh = tim / 100; + int mm = tim % 100; + sp->etime = WORD((hh * 60 + mm) * 30); + if( !sp->etime ) sp->etime++; + } + if( RemoveL2(rbf, bf, "POW", sizeof(rbf)-1) == TRUE ){ + StrCopy(sp->pow, rbf, MLPOW); + } + if( RemoveL2(rbf, bf, "M", sizeof(rbf)-1) == TRUE ){ + sp->cq = rbf[0]; + } + if( RemoveL2(rbf, bf, "SN", sizeof(rbf)-1) == TRUE ){ + int l = GetLMode(sp->mode); + if( l ) sp->ur[l] = 0; + strcat(sp->ur, rbf); + } + if( RemoveL2(rbf, bf, "RN", sizeof(rbf)-1) == TRUE ){ + int l = GetLMode(sp->mode); + if( l ) sp->my[l] = 0; + strcat(sp->my, rbf); + } +} +//--------------------------------------------------------------------------- +// HamLog -> MMLOG フォーマットの変換 +void __fastcall HAMLOGtoMMLOG(SDMMLOG *sp, SDHAMLOG *hp, FILE *dbrfp) +{ + int CallOrder = 0; + char bf[512]; + + memset(sp, 0, sizeof(SDMMLOG)); + DecBand(bf, (BYTE *)hp->freq); + Log.SetFreq(sp, bf); + + StrCopy(bf, hp->mode, 3); + clipsp(bf); + if( !strcmp(bf, Log.m_LogSet.m_THRTTY.c_str()) || !strcmp(bf, "RTY") || !strcmp(bf, "TTY") || !strcmp(bf, "RTT") ){ + strcpy(bf, "RTTY"); + } + else if( !strcmp(bf, Log.m_LogSet.m_THSSTV.c_str()) || !strcmp(bf, "STV")|| !strcmp(bf, "SST") ){ + strcpy(bf, "SSTV"); + } + else if( !strcmp(bf, Log.m_LogSet.m_THGMSK.c_str()) ){ + strcpy(bf, "GMSK"); + } + else if( !strcmp(bf, "FTV") ){ + strcpy(bf, "FSTV"); + } + Log.SetMode(sp, bf); + + StrCopy(sp->name, hp->name, 12); + clipsp(sp->name); + + sprintf(sp->ur, "%02u", BYTE(hp->hiss[0])); + if( hp->hiss[1] != ' ' ) sp->ur[2] = hp->hiss[1]; + + sprintf(sp->my, "%02u", BYTE(hp->myrs[0])); + if( hp->myrs[1] != ' ' ) sp->my[2] = hp->myrs[1]; + + int YY, MM, DD, HH, mm; + YY = hp->date[0] & 0x007f; + YY %= 100; + MM = hp->date[1]; + DD = hp->date[2]; + HH = hp->time[0]; + mm = hp->time[1] & 0x7f; + if( hp->time[1] & 0x80 ){ + UTCtoJST(YY, MM, DD, HH); + } + sp->year = BYTE(YY); + sp->date = WORD(MM * 100 + DD); + sp->btime = WORD(((HH * 60 + mm) * 30)); + if(!sp->btime) sp->btime++; + + if( hp->ofs && (dbrfp != NULL) ){ + FHDDBR fhdbr; + if( fseek(dbrfp, hp->ofs, SEEK_SET) ) goto _ex; + if( fread(&fhdbr, 1, sizeof(fhdbr), dbrfp) != sizeof(fhdbr) ){ + goto _ex; + } + if( fhdbr.LenQTH ){ + if( fread(bf, 1, fhdbr.LenQTH, dbrfp)!=size_t(fhdbr.LenQTH) ){ + goto _ex; + } + bf[fhdbr.LenQTH] = 0; + clipsp(bf); + StrCopy(sp->qth, bf, MLQTH); + } + if( fhdbr.LenREM1 ){ + if( fread(bf, 1, fhdbr.LenREM1, dbrfp)!=size_t(fhdbr.LenREM1) ){ + goto _ex; + } + bf[fhdbr.LenREM1] = 0; + SetMMLOGKey(sp, bf); + clipsp(bf); + if( strstr(bf, "$DX" ) != NULL ) CallOrder = 1; + StrCopy(sp->rem, SkipSpace(bf), MLREM); + } + if( fhdbr.LenREM2 ){ + if( fread(bf, 1, fhdbr.LenREM2, dbrfp)!=size_t(fhdbr.LenREM2) ){ + goto _ex; + } + bf[fhdbr.LenREM2] = 0; + SetMMLOGKey(sp, bf); + clipsp(bf); + if( strstr(bf, "$DX" ) != NULL ) CallOrder = 1; + StrCopy(sp->qsl, SkipSpace(bf), MLQSL); + } + } +_ex:; + sprintf(bf, "QSL[%.3s]", hp->qsl); + Log.SetOptStr(2, sp, bf); + if( hp->qsl[0] == 'N' ){ + sp->send = 'N'; + } + else if( hp->send[0] == ' ' ){ // 未発送 + if( (hp->qsl[0] == 'J')||(hp->qsl[0] == ' ') ){ + sp->send = 0; + } + else { + sp->send = BYTE(tolower(hp->qsl[0])); + } + } + else { // 発送済み + sp->send = BYTE(toupper(hp->send[0])); + } + sp->recv = hp->rcv[0]; + if( sp->recv == ' ' ) sp->recv = 0; + + StrCopy(sp->opt1, hp->code, 6); + StrCopy(sp->opt2, hp->glid, 6); + + if( !sp->call[0] ){ + if( CallOrder && (hp->potbl[0] != ' ') ){ /* KH6/JE3HHTの形式 */ + StrCopy(bf, hp->potbl, 3); + clipsp(bf); + strcat(sp->call, bf); + if( sp->call[0] ) strcat(sp->call, "/"); + StrCopy(bf, hp->calls, 7); + clipsp(bf); + strcat(sp->call, bf); + } + else { /* JE3HHT/KH6の形式 */ + StrCopy(bf, hp->calls, 7); + clipsp(bf); + strcat(sp->call, bf); + if( hp->potbl[0] != ' ' ){ + if( sp->call[0] ) strcat(sp->call, "/"); + StrCopy(bf, hp->potbl, 3); + clipsp(bf); + strcat(sp->call, bf); + } + } + } + if( !sp->etime ) sp->etime = sp->btime; +} +//---------------------------------------------------------------------- +//文字列のコピー(ヌルはセットされない) +void __fastcall SpaceCopy(LPSTR t, LPCSTR s, int n) +{ + for( ; n && *s; s++, t++, n-- ){ + *t = *s; + } +} +//---------------------------------------------------------------------- +//RST文字列をHAMLOG形式に変換して格納 +void __fastcall SetRST(char *pRST, LPCSTR p, BYTE mode) +{ + char rs[3]; + int rst; + + StrCopy(rs, p, 2); + if( sscanf(rs, "%d", &rst) == 1 ){ + *pRST = BYTE(rst); + } + else { + *pRST = 59; + } + if( strlen(p) < 3 ) return; + if( GetLMode(mode) == 2 ) return; + pRST[1] = *(p+2); +} +//---------------------------------------------------------------------- +//周波数の文字列をHAMLOGの周波数記録方式に変換 +void __fastcall EncBand(BYTE *pBand, LPCSTR pStr) +{ + char bf[32]; + StrCopy(bf, pStr, 7); + + int Len = strlen(bf); + if( Len <= 4 ){ + memset(pBand, ' ', 4); + SpaceCopy(LPSTR(pBand), bf, 4); + } + else { + LPSTR p = strchr(bf, '.'); + int DotPos; + if( p != NULL ){ + DotPos = p - bf; + *p = '0'; + } + else { + DotPos = Len; + } + long Freq; + sscanf(bf, "%lu", &Freq); + *(ULONG *)pBand = Freq; + pBand[3] = BYTE(0x0080 | (Len << 3) | DotPos); + } +} + +void __fastcall AddMMLOGKey(AnsiString &REM1, AnsiString &REM2, LPCSTR s, LPCSTR pKey) +{ + if( !*s ) return; + + int len1 = strlen(REM1.c_str()); + int len2 = strlen(REM2.c_str()); + int len = strlen(s); + if( pKey == NULL ){ + len++; + } + else { + len += strlen(pKey) + 3; + } + AnsiString *ap; + if( (len2 + len) < 54 ){ + ap = &REM2; + } + else if( (len1 + len) < 54 ){ + ap = &REM1; + } + else { + return; + } + if( !ap->IsEmpty() ){ + *ap += " "; + } + if( pKey != NULL ){ + *ap += pKey; + *ap += '['; + } + *ap += s; + if( pKey != NULL ){ + *ap += ']'; + } +} +//--------------------------------------------------------------------------- +// MMLOG -> HamLog フォーマットの変換 +int __fastcall MMLOGtoHAMLOG(SDHAMLOG *hp, SDMMLOG *sp, FILE *dbrfp) +{ + char bf[512]; + + int CallOrder = FALSE; + memset(hp, ' ', sizeof(SDHAMLOG)); + int YY = sp->year; + int MM = sp->date / 100; + int DD = sp->date % 100; + int tim = sp->btime / 30; + int HH = tim / 60; + int mm = tim % 60; + switch(Log.m_LogSet.m_THTZ){ + case 0: + if( !IsJA(sp->call) ){ + JSTtoUTC(YY, MM, DD, HH); + mm |= 0x80; + } + break; + case 1: + JSTtoUTC(YY, MM, DD, HH); + mm |= 0x80; + break; + default: + break; + } + hp->date[0] = BYTE(YY < 50 ? YY + 128 : YY); + hp->date[1] = BYTE(MM); + hp->date[2] = BYTE(DD); + hp->time[0] = BYTE(HH); + hp->time[1] = BYTE(mm); + + SpaceCopy(hp->name, sp->name, 12); + SpaceCopy(hp->code, sp->opt1, 6); + SpaceCopy(hp->glid, sp->opt2, 6); + AnsiString QTH = sp->qth; + AnsiString REM1 = sp->rem; + AnsiString REM2 = sp->qsl; + + strcpy(bf, sp->call); + LPSTR pp, p2, t; + t = bf; + if( (pp = strchr(bf, '/')) != NULL ){ // KH6/JE3HHT or JE3HHT/KH6 の形式 + *pp = 0; + pp++; + int LenC = strlen(t); + int LenP = strlen(pp); + if( ((p2 = strchr(pp, '/')) != NULL)|| + (LenC > 7) || + (LenP > 7) || + ((LenC > LenP) && (LenP>3)) || + ((LenC < LenP) && (LenC>3)) + ){ + // HAMLOGでは表現できない表記の場合 + AddMMLOGKey(REM1, REM2, sp->call, "ToRadio"); + if( p2 != NULL ){ + *p2 = 0; + LenP = strlen(pp); + } + } + if( LenC < LenP ){ + p2 = t; + t = pp; + pp = p2; + CallOrder = TRUE; + } + SpaceCopy(hp->potbl, pp, 3); + } + else if( strlen(t) > 7 ){ + AddMMLOGKey(REM1, REM2, sp->call, "ToRadio"); + } + SpaceCopy(hp->calls, t, 7); + strcpy(bf, Log.GetModeString(sp->mode)); + if( !strcmp(bf, "RTTY") ){ + StrCopy(bf, Log.m_LogSet.m_THRTTY.c_str(), 3); + } + else if( !strcmp(bf, "SSTV") ){ + StrCopy(bf, Log.m_LogSet.m_THSSTV.c_str(), 3); + } + else if( !strcmp(bf, "GMSK") ){ + StrCopy(bf, Log.m_LogSet.m_THGMSK.c_str(), 3); + } + else if( !strcmp(bf, "FSTV") ){ + strcpy(bf, "FTV"); + } + else if( !strcmp(bf, "BPSK") ){ + strcpy(bf, "PSK"); + } + else if( !strcmp(bf, "QPSK") ){ + strcpy(bf, "PSK"); + } + SpaceCopy(hp->mode, bf, 3); + SetRST(hp->hiss, sp->ur, sp->mode); + SetRST(hp->myrs, sp->my, sp->mode); + + int l = GetLMode(sp->mode); + if( sp->ur[l] ) AddMMLOGKey(REM1, REM2, &sp->ur[l], "SN"); + if( sp->my[l] ) AddMMLOGKey(REM1, REM2, &sp->my[l], "RN"); + + strcpy(bf, Log.GetFreqString(sp->band, sp->fq)); + EncBand((BYTE *)hp->freq, bf); + + + if( CallOrder && (!strstr(sp->rem, "$DX")) && (!strstr(sp->qsl, "$DX")) ){ + AddMMLOGKey(REM1, REM2, "$DX", NULL); + } + + if( sp->etime ){ + tim = sp->etime / 30; + sprintf(bf, "%02u%02u", tim / 60, tim % 60); + AddMMLOGKey(REM1, REM2, bf, "END"); + } + if( sp->env ){ + sprintf(bf, "%u", sp->env); + AddMMLOGKey(REM1, REM2, bf, "ENV"); + } + AddMMLOGKey(REM1, REM2, sp->pow, "POW"); + if( sp->cq ){ + bf[0] = sp->cq; bf[1] = 0; + AddMMLOGKey(REM1, REM2, bf, "M"); + } + strcpy(bf, Log.GetOptStr(2, sp)); + char rbf[32]; + if(RemoveL2(rbf, bf, "QSL", sizeof(rbf)-1) == TRUE){ + hp->qsl[0] = rbf[0]; + hp->send[0] = rbf[1]; + hp->rcv[0] = rbf[2]; + } + else { + hp->rcv[0] = sp->recv; + if( !hp->rcv[0] ) hp->rcv[0] = ' '; + if( sp->send == 'N' ){ + hp->qsl[0] = 'N'; + hp->send[0] = ' '; + } + else if( !sp->send ){ + hp->qsl[0] = 'J'; + hp->send[0] = ' '; + } + else if( (sp->send >= 0x60)||(sp->send == '?') ){ + hp->qsl[0] = BYTE(toupper(sp->send)); + hp->send[0] = ' '; + } + else if( isalpha(sp->send) ){ + hp->qsl[0] = sp->send; + hp->send[0] = '*'; + } + else { + hp->qsl[0] = 'J'; + hp->send[0] = sp->send; + } + } + + if( !QTH.IsEmpty() || !REM1.IsEmpty() || !REM2.IsEmpty() ){ + FHDDBR fhdbr; + memset(&fhdbr, 0, sizeof(fhdbr)); + hp->ofs = ftell(dbrfp); + fhdbr.LenQTH = BYTE(strlen(QTH.c_str())); + fhdbr.LenREM1 = BYTE(strlen(REM1.c_str())); + fhdbr.LenREM2 = BYTE(strlen(REM2.c_str())); + if( fhdbr.LenQTH > 28 ){ + fhdbr.LenQTH = 28; + } + if( fhdbr.LenREM1 > 54 ){ + fhdbr.LenREM1 = 54; + } + if( fhdbr.LenREM2 > 54 ){ + fhdbr.LenREM2 = 54; + } + if( fwrite(&fhdbr, 1, sizeof(fhdbr), dbrfp) != sizeof(fhdbr) ) return FALSE; + if( fhdbr.LenQTH ){ + if( fwrite(QTH.c_str(), 1, fhdbr.LenQTH, dbrfp) != size_t(fhdbr.LenQTH) ) return FALSE; + } + if( fhdbr.LenREM1 ){ + if( fwrite(REM1.c_str(), 1, fhdbr.LenREM1, dbrfp) != size_t(fhdbr.LenREM1) ) return FALSE; + } + if( fhdbr.LenREM2 ){ + if( fwrite(REM2.c_str(), 1, fhdbr.LenREM2, dbrfp) != size_t(fhdbr.LenREM2) ) return FALSE; + } + } + else { + hp->ofs = 0L; + } + return TRUE; +} + +//*************************************************************************** +// CLogADIF クラス +__fastcall CLogADIF::CLogADIF() +{ + m_bf[sizeof(m_bf)-1] = 0; +} +//--------------------------------------------------------------------------- +// ADIFファイルのオープン +int __fastcall CLogADIF::Open(LPCSTR pName) +{ + Close(); + m_Mode = 0; + + m_p = NULL; + m_conv = 1; + m_fp = fopen(pName, "rt"); + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB(sys.m_MsgEng ? "Can't open '%s'": "'%s'がオープンできません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// ADIFファイルの作成 +int __fastcall CLogADIF::Create(LPCSTR pName) +{ + Close(); + m_Mode = 1; + + m_fp = fopen(pName, "wt"); + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 1; + fprintf(m_fp, "ADIF Export from %s\n", VERTTL); + fprintf(m_fp, "\n\n"); + return TRUE; + } + else { + ErrorMB( sys.m_MsgEng ? "Can't write to '%s'":"'%s'が作成できません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// テキストファイルのオープン +int __fastcall CLogADIF::Close(void) +{ + int r = 0; + if( m_fp != NULL ){ + r = fclose(m_fp); + m_fp = NULL; + if( r ){ + ErrorMB(sys.m_MsgEng ? "Can't write to '%s'":"'%s'が正しくクローズできませんでした.", m_FileName.c_str()); + } + else if( m_Mode ){ + InfoMB(sys.m_MsgEng ? "Done (write to '%s')":"'%s'への書きこみを終了しました.", m_FileName.c_str()); + } + } + return r ? FALSE : TRUE; +} +const char *_BandText[]={ + "","160m","80m","80m","40m","30m","20m","17m","15m","12m","10m","6m", + "2m","70cm","23cm","13cm","6cm","3cm","3cm","1.25cm","6mm", + "4mm","2mm","1mm","65m","1.25m",NULL, +}; +//--------------------------------------------------------------------------- +// ADIFファイルの読み出し +void __fastcall CLogADIF::SetData(SDMMLOG *sp, LPCSTR pKey, LPSTR pData) +{ + int l; + + if( !strcmpi(pKey, "CALL") ){ + StrCopy(sp->call, pData, MLCALL); + } + else if( !strcmpi(pKey, "QSO_DATE") ){ + sp->year = BYTE(atoin(pData, 4) % 100); + sp->date = WORD(atoin(pData+4, 4)); + } + else if( !strcmpi(pKey, "TIME_ON") ){ + int hh, mm, ss; + hh = atoin(pData, 2); + mm = atoin(pData+2, 2); + ss = pData[4] ? atoin(pData+4, 2) : 0; + sp->btime = WORD((hh * 60 + mm) * 30 + ss); + if( !sp->btime ) sp->btime++; + } + else if( !strcmpi(pKey, "TIME_OFF") ){ + int hh, mm, ss; + hh = atoin(pData, 2); + mm = atoin(pData+2, 2); + ss = pData[4] ? atoin(pData+4, 2) : 0; + sp->btime = WORD((hh * 60 + mm) * 30 + ss); + if( !sp->etime ) sp->btime++; + } + else if( !strcmpi(pKey, "FREQ") ){ + Log.SetFreq(sp, pData); + } + else if( !strcmpi(pKey, "BAND") ){ + if( !sp->band ){ + int i; + for( i = 1; _BandText[i] != NULL; i++ ){ + if( !strcmpi(_BandText[i], pData) ) break; + } + if( _BandText[i] == NULL ) i = 0; + sp->band = BYTE(i); + } + } + else if( !strcmpi(pKey, "MODE") ){ + Log.SetMode(sp, pData); + } + else if( !strcmpi(pKey, "TX_PWR") ){ + StrCopy(sp->pow, pData, MLPOW); + } + else if( !strcmpi(pKey, "RST_SENT") ){ + if( sp->ur[0] ){ + char bf[MLRST+1]; + strcpy(bf, sp->ur); + StrCopy(sp->ur, pData, MLRST); + l = strlen(sp->ur); + StrCopy(&sp->ur[l], bf, MLRST - l); + } + else { + StrCopy(sp->ur, pData, MLRST); + } + } + else if( !strcmpi(pKey, "RST_RCVD") ){ + if( sp->my[0] ){ + char bf[MLRST+1]; + strcpy(bf, sp->my); + StrCopy(sp->my, pData, MLRST); + l = strlen(sp->my); + StrCopy(&sp->my[l], bf, MLRST - l); + } + else { + StrCopy(sp->my, pData, MLRST); + } + } + else if( !strcmpi(pKey, "STX") ){ + l = strlen(sp->ur); + StrCopy(&sp->ur[l], pData, MLRST - l); + } + else if( !strcmpi(pKey, "SRX") ){ + l = strlen(sp->my); + StrCopy(&sp->my[l], pData, MLRST - l); + } + else if( !strcmpi(pKey, "QSL_SENT") ){ + if( *pData == ' ' ) *pData = 0; + sp->send = *pData; + } + else if( !strcmpi(pKey, "QSL_RCVD") ){ + if( *pData == ' ' ) *pData = 0; + sp->recv = *pData; + } + else if( !strcmpi(pKey, "NAME") ){ + StrCopy(sp->name, pData, MLNAME); + } + else if( !strcmpi(pKey, "QTH") ){ + StrCopy(sp->qth, pData, MLQTH); + } + else if( !strcmpi(pKey, "COMMENT") ){ + StrCopy(sp->rem, pData, MLREM); + } + else if( !strcmpi(pKey, "QSLMSG") ){ + StrCopy(sp->qsl, pData, MLQSL); + } + else if( !strcmpi(pKey, "CONT") ){ + StrCopy(sp->opt2, pData, MLOPT); + } + else if( !strcmpi(pKey, "QSL_VIA") ){ + AddL2(sp->qsl, "QSL", pData, '[', ']', MLQSL); + } +} +//--------------------------------------------------------------------------- +void __fastcall CLogADIF::AdjustData(SDMMLOG *sp) +{ + if( !sp->etime ) sp->etime = sp->btime; + UTCtoJST(sp); + if( sp->call[0] ){ + LPCSTR pCC = ClipCC(sp->call); + Log.SetOptStr(0, sp, Cty.GetCountry(pCC)); + if( !sp->opt2[0] ) Log.SetOptStr(1, sp, Cty.GetCont(pCC)); + } + if( !sp->ur[0] ) StrCopy(sp->ur, "599", GetLMode(sp->mode)); + if( !sp->my[0] ) StrCopy(sp->my, "599", GetLMode(sp->mode)); +} +//--------------------------------------------------------------------------- +// ADIFファイルの読み出し +int __fastcall CLogADIF::Read(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + LPSTR p, t, tt; + char bf[1024]; + + while(1){ + if( (m_p == NULL) || !(*m_p) ){ + if( !feof(m_fp) ){ + if( fgets(m_bf, sizeof(m_bf), m_fp) != NULL ){ + ClipLF(m_bf); + m_p = m_bf; + } + else if( sp->btime && sp->call[0] && m_conv ){ + AdjustData(sp); + m_p = NULL; + return TRUE; + } + else { + return FALSE; + } + } + else { + return FALSE; + } + } + m_p = SkipSpace(m_p); + if( *m_p == '<' ){ + m_p = StrDlm(p, m_p+1, '>'); + p = StrDlm(t, p, ':'); + p = StrDlm(tt, p, ':'); + bf[0] = 0; + int n = *tt ? atoin(tt, -1) : 0; + if( (n >= 0) && (n < 1023) && (n <= (int)strlen(m_p)) ){ + if( n ) memcpy(bf, m_p, n); + bf[n] = 0; + } + if( !strcmpi(t, "EOR") ){ + if( m_conv ){ + AdjustData(sp); + return TRUE; + } + } + if( !strcmpi(t, "EOH") ){ + m_conv = 1; + } + else if( m_conv ){ + SetData(sp, t, bf); +#if 0 + FILE *fp = fopen("F:\\TEST.TXT", "at"); + fprintf(fp, "%s:%s\n", t, bf); + fclose(fp); +#endif + m_p += n; + } + } + else if( *m_p ){ + m_p++; + } + } +} +//--------------------------------------------------------------------------- +void CLogADIF::OutF(int &col, FILE *fp, LPCSTR fmt, ...) +{ + va_list pp; + char bf[512]; + + va_start(pp, fmt); + vsprintf(bf, fmt, pp ); + va_end(pp); + if( col ){ + fputs(" ", fp); + col++; + } + int l = strlen(bf); + if( (col + l) > 80 ){ + fputs("\n", fp); + col = 0; + } + fputs(bf, fp); + col += l; +} +//--------------------------------------------------------------------------- +// 出力変換 +// +//KD4MUL 19930921 223558 150000 +//3.690 80M CW 100 599 +//599 Y N ROY STRUNK +//KY FIRST CW CONTACT WB4TXW +int __fastcall CLogADIF::Write(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; + + int col = 0; + JSTtoUTC(sp); + OutF(col, m_fp, "%s", strlen(sp->call), sp->call); + OutF(col, m_fp, "%04u%02u%02u", YEAR(sp->year), sp->date/100, sp->date%100); + int tim = sp->btime / 30; + OutF(col, m_fp, "%02u%02u%02u", tim/60, tim%60, (sp->btime % 30)*2); + tim = sp->etime / 30; + OutF(col, m_fp, "%02u%02u%02u", tim/60, tim%60, (sp->etime % 30)*2); + LPCSTR p = Log.GetFreqString(sp->band, sp->fq); + if( *p ) OutF(col, m_fp, "%s", strlen(p), p); + p = _BandText[sp->band]; + if( *p ) OutF(col, m_fp, "%s", strlen(p), p); + p = Log.GetModeString(sp->mode); + if( *p ) OutF(col, m_fp, "%s", strlen(p), p); + if( sp->pow[0] ) OutF(col, m_fp, "%s", strlen(sp->pow), sp->pow); + int l = GetLMode(sp->mode); + if( Log.m_LogSet.m_ClipRSTADIF ){ + if( sp->ur[l] ) OutF(col, m_fp, "%s", strlen(&sp->ur[l]), &sp->ur[l]); + if( sp->my[l] ) OutF(col, m_fp, "%s", strlen(&sp->my[l]), &sp->my[l]); + sp->ur[GetLMode(sp->mode)] = 0; + sp->my[GetLMode(sp->mode)] = 0; + } + if( sp->ur[0] ) OutF(col, m_fp, "%s", strlen(sp->ur), sp->ur); + if( sp->my[0] ) OutF(col, m_fp, "%s", strlen(sp->my), sp->my); + if( sp->send ) OutF(col, m_fp, "%c", sp->send); + if( sp->recv ) OutF(col, m_fp, "%c", sp->recv); + if( sp->name[0] ) OutF(col, m_fp, "%s", strlen(sp->name), sp->name); + if( sp->qth[0] ) OutF(col, m_fp, "%s", strlen(sp->qth), sp->qth); + if( sp->rem[0] ) OutF(col, m_fp, "%s", strlen(sp->rem), sp->rem); + if( sp->opt2[0] ) OutF(col, m_fp, "%s", strlen(sp->opt2), sp->opt2); + if( sp->qsl[0] ){ + char via[MLQSL+1]; + char qsl[MLQSL+1]; + StrCopy(qsl, sp->qsl, MLQSL); + if( !RemoveL2(via, qsl, "QSL", sizeof(via)-1) ){ + via[0] = 0; + } + if( qsl[0] ) OutF(col, m_fp, "%s", strlen(qsl), qsl); + if( via[0] ) OutF(col, m_fp, "%s", strlen(via), via); + } + OutF(col, m_fp, "\n"); + return ferror(m_fp) ? FALSE : TRUE; +} + + +//*************************************************************************** +// CLogCabrillo クラス +__fastcall CLogCabrillo::CLogCabrillo() +{ + m_bf[sizeof(m_bf)-1] = 0; +} +//--------------------------------------------------------------------------- +// LogCabrilloファイルのオープン +int __fastcall CLogCabrillo::Open(LPCSTR pName) +{ + Close(); + m_Mode = 0; + + m_p = NULL; + m_SNR = ""; + m_fp = fopen(pName, "rt"); + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 0; + return TRUE; + } + else { + ErrorMB(sys.m_MsgEng ? "Can't open '%s'": "'%s'がオープンできません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// LogCabrilloファイルの作成 +int __fastcall CLogCabrillo::Create(LPCSTR pName) +{ + Close(); + m_Mode = 1; + + m_fp = fopen(pName, "wt"); + if( m_fp != NULL ){ + setvbuf(m_fp, NULL, _IOFBF, 16384); + m_FileName = pName; + m_Mode = 1; + fprintf( m_fp, "START-OF-LOG: 2.0\n"); + fprintf( m_fp, "ARRL-SECTION: \n" ); + fprintf( m_fp, "CONTEST: <== e.g. ARRL-RTTY, CQ-WW-RTTY, CQ-WPX-RTTY, BARTG-SPRINT, BARTG-RTTY\n"); + fprintf( m_fp, "CALLSIGN: %s\n", sys.m_CallSign.c_str() ); + fprintf( m_fp, "CATEGORY: <== e.g. SINGLE-OP ALL HIGH, SINGLE-OP-ASSISTED 20M LOW\n" ); + fprintf( m_fp, "CLAIMED-SCORE: \n"); + fprintf( m_fp, "OPERATORS:\n" ); + fprintf( m_fp, "CLUB:\n" ); + fprintf( m_fp, "NAME: <== your name\n" ); + fprintf( m_fp, "ADDRESS: <== your postal address\n" ); + fprintf( m_fp, "SOAPBOX: \n" ); + fprintf( m_fp, "CREATED-BY: %s\n", VERTTL2); + return TRUE; + } + else { + ErrorMB( sys.m_MsgEng ? "Can't write to '%s'":"'%s'が作成できません.", pName); + return FALSE; + } +} +//--------------------------------------------------------------------------- +// テキストファイルのオープン +int __fastcall CLogCabrillo::Close(void) +{ + int r = 0; + if( m_fp != NULL ){ + fprintf(m_fp, "END-OF-LOG:\n"); + r = fclose(m_fp); + m_fp = NULL; + if( r ){ + ErrorMB(sys.m_MsgEng ? "Can't write to '%s'":"'%s'が正しくクローズできませんでした.", m_FileName.c_str()); + } + else if( m_Mode ){ + InfoMB(sys.m_MsgEng ? "Done (write to '%s')\r\n\r\nMMVARI did only make QSO section.\r\nEdit to the contest name, category, your name and address, etc... in the file.":"'%s'への書きこみを終了しました.\r\n\r\nMMVARIはQSOセクションしか作成しません。\r\nコンテスト名、参加カテゴリ等を編集してください.", m_FileName.c_str()); + sprintf(m_bf, "NOTEPAD.EXE %s", m_FileName.c_str()); + WinExec(m_bf, SW_SHOWDEFAULT); + } + } + return r ? FALSE : TRUE; +} +//--------------------------------------------------------------------------- +// LogCabrilloファイルの読み出し +int __fastcall CLogCabrillo::Read(SDMMLOG *sp) +{ + return FALSE; +} +//--------------------------------------------------------------------------- +// 出力変換 +// +int __fastcall CLogCabrillo::Write(SDMMLOG *sp) +{ + if( !IsOpen() ) return FALSE; +// "","1.9","3.5","3.8","7","10","14","18","21","24","28","50", +// "144","430","1200","2400","5600","10.1G","10.4G","24G","47G", +// "75G","142G","248G","4630","220",NULL, + const char *_bandc[]={ + "??","1800","3500","3500","7000","10000","14000","18000","21000","24000","28000", + "A", "B","D","E","F","H","I","J","K","M", + "N","P","R","?","C",NULL, + }; + +// "CW","SSB","AM","FM","RTTY","PAC","FAX","SSTV","ATV","TV","FSTV", +// "A1","A2","A3","A3A","A3H","A3J","A4","A5","A5C","A5J", +// "A9","A9C","F1","F2","F3","F4","F5","F9","P0","P1", +// "P2D","P2E","P2F","P3D","P3E","P3F","P9", +// "U1","U2","U3","U4", +// "PSK","BPSK","QPSK","HELL","MFSK", + const char *_modec[]={ + "??", + "CW","PH","PH","FM","RY","RY","??","TV","TV","TV","TV", + "CW","CW","PH","PH","PH","PH","??","??","??","??", + "??","??","RY","RY","FM","??","??","??", + "??","??","??","??","??","??","??","??","??", + "??","??","??","??", + "RY","RY","RY","CW","RY", + NULL, + }; + + JSTtoUTC(sp); + int tim = sp->btime / 30; + char SNO[MLRST+1]; + char RNO[MLRST+1]; + int mno = sp->mode >= MODEMAX ? 0 : sp->mode; + int len = GetLMode(BYTE(mno)); + strcpy(SNO, &sp->ur[len]); + strcpy(RNO, &sp->my[len]); + sp->ur[len] = 0; + sp->my[len] = 0; + if( !SNO[0] ){ + if( m_SNR.IsEmpty() ){ + int r; + if( sys.m_MsgEng ){ + r = InputMB("Does not exist the Sent-NR information", "Enter contest number which you sent", m_SNR); + } + else { + r = InputMB("Sent-NR情報が存在しません", "Sent-NRを入力して下さい", m_SNR); + } + if( r == FALSE ) return FALSE; + } + strcpy(SNO, m_SNR.c_str()); + } + fprintf( m_fp, "QSO:%6s %2s %04u-%02u-%02u %02u%02u %-13s %-3s %-6s %-13s %-3s %-6s\n", + _bandc[sp->band], _modec[mno], + (sp->year <= 50) ? sp->year + 2000 : sp->year + 1900, + sp->date / 100, sp->date % 100, + tim/60, tim%60, sys.m_CallSign.c_str(), + sp->ur, SNO, + sp->call, sp->my, RNO + ); + return ferror(m_fp) ? FALSE : TRUE; +} + diff --git a/LogConv.h b/LogConv.h new file mode 100644 index 0000000..ea846c6 --- /dev/null +++ b/LogConv.h @@ -0,0 +1,250 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef LogConvH +#define LogConvH +#include "LogFile.h" + +extern const char *MONT1[]; +extern const char *MONT2[]; +extern const char *_BandText[]; +//************************************************************* +// ログ変換の基本クラス +// +class CLogConv +{ +protected: + int m_Type; // 0-TEXT, 1-LOG200, 2-HAMLOG, 3-DBASE + int m_Mode; // 0-Read, 1-Write + FILE *m_fp; + + AnsiString m_FileName; // 変換中のファイル名 +public: + __fastcall CLogConv(); + virtual __fastcall ~CLogConv(); + virtual int __fastcall IsOpen(void){return m_fp != NULL ? 1 : 0;}; + virtual int __fastcall Open(LPCSTR pName)=0; + virtual int __fastcall Create(LPCSTR pName)=0; + virtual int __fastcall Close(void)=0; + virtual int __fastcall Read(SDMMLOG *sp)=0; + virtual int __fastcall Write(SDMMLOG *sp)=0; +}; + +#define TEXTCONVMAX 64 +typedef struct { + int w; + AnsiString Key; +}TCONV; + +//************************************************************* +// テキストファイルアクセスのクラス +// +class CLogText : public CLogConv +{ +public: + int m_Double; + int m_Delm; + TCONV m_rConv[TEXTCONVMAX]; + TCONV m_tConv[TEXTCONVMAX]; + int m_UTC; + int m_err; +protected: + char m_bf[2048]; // ファイルバッファ + +private: + int __fastcall Text2MMLOG(SDMMLOG *sp, LPSTR p, int &err); + void __fastcall MMLOG2Text(LPSTR t, SDMMLOG *sp); + +public: + __fastcall CLogText(); + virtual int __fastcall Open(LPCSTR pName); + virtual int __fastcall Create(LPCSTR pName); + virtual int __fastcall Close(void); + virtual int __fastcall Read(SDMMLOG *sp); + virtual int __fastcall Write(SDMMLOG *sp); + +}; + +void __fastcall MMLOG2Text(LPSTR t, SDMMLOG *sp, AnsiString &Key); +int __fastcall Text2MMLOG(SDMMLOG *sp, LPCSTR s, AnsiString &Key); +extern const LPCSTR ConvTbl[]; +extern CLogText LogText; + +//************************************************************* +// LOG200ファイルアクセスのクラス +// +#define LOG200WIDTH 200 +class CLog200 : public CLogConv +{ +public: + int m_Index; + int m_err; +protected: + char m_bf[200]; // ファイルバッファ +private: +public: + __fastcall CLog200(); + virtual int __fastcall Open(LPCSTR pName); + virtual int __fastcall Create(LPCSTR pName); + virtual int __fastcall Close(void); + virtual int __fastcall Read(SDMMLOG *sp); + virtual int __fastcall Write(SDMMLOG *sp); +}; + +//************************************************************* +// HAMLOGファイルアクセスのクラス +// +#pragma option -a- // パックの指示 +typedef struct { + char Memo; // 03h=メモフィールド無し 83h=メモフィールド有り(HAMLOGでは 1Ah) + char YY, MM, DD; // 最終更新年月日 + long Max; // レコード件数 + WORD HeadLen; // ヘッダの長さ(HAMLOG.DBSは 449) + WORD DataLen; // レコードの長さ(HAMLOG.DBSは 58) + char dummy[20]; // 00h +}DBSHD; + +typedef struct { + char Memo; // 03h=メモフィールド無し 83h=メモフィールド有り(HAMLOGでは 1Ah) + char YY, MM, DD; // 最終更新年月日 + long Max; // レコード件数 + char dm1; + char m1; // 01h + char dm2; + char dummy[21]; // 00h + char dummy2[255-32]; // 00h + char term; // 1ah +}DBRHD; + +typedef struct { + char Name[11]; + BYTE Type; + BYTE dm1[4]; + BYTE Len; + BYTE dm2[15]; +}DBSLOT; + +typedef struct { + char del[1]; /* 削除マーク */ + char calls[7]; /* コールサイン */ + char potbl[3]; /* 移動エリア */ + char code[6]; /* JCCコード */ + char glid[6]; /* グリッドロケーター */ + char freq[4]; /* 周波数 */ + char mode[3]; /* モード */ + char name[12]; /* 氏名 */ + char qsl [1]; /* QSL via */ + char send[1]; /* QSL SEND */ + char rcv[1]; /* QSL RCV */ + char date[3]; /* 日付 */ + char time[2]; /* 時間 */ + char hiss[2]; /* HIS RST */ + char myrs[2]; /* MY RST */ + long ofs; /* HAMLOG.DBR オフセットアドレス */ +}SDHAMLOG; + +typedef struct { /* DBRのフィールド位置データ */ + BYTE LenQTH; + BYTE LenREM1; + BYTE LenREM2; +}FHDDBR; +#pragma option -a. // パック解除の指示 + +class CHamLog : public CLogConv +{ +public: + int m_Index; + int m_err; +protected: + DBSHD m_hd; // DBSヘッダ + SDHAMLOG m_RecBuf; // レコードバッファ + + AnsiString m_DBRName; // DBRファイルの名前 + FILE *m_dbrfp; // DBRファイルのファイルポインタ + DBRHD m_dbrhd; // DBRヘッダ +private: + int __fastcall Seek(DWORD Index); + BOOL __fastcall MakeHD(void); + +public: + __fastcall CHamLog(); + virtual int __fastcall Open(LPCSTR pName); + virtual int __fastcall Create(LPCSTR pName); + virtual int __fastcall Close(void); + virtual int __fastcall Read(SDMMLOG *sp); + virtual int __fastcall Write(SDMMLOG *sp); +}; + +void __fastcall HAMLOGtoMMLOG(SDMMLOG *sp, SDHAMLOG *hp, FILE *dbrfp); +int __fastcall MMLOGtoHAMLOG(SDHAMLOG *hp, SDMMLOG *sp, FILE *dbrfp); +void __fastcall AddMMLOGKey(AnsiString &REM1, AnsiString &REM2, LPCSTR s, LPCSTR pKey); +void __fastcall SetMMLOGKey(SDMMLOG *sp, LPSTR bf); +void __fastcall SpaceCopy(LPSTR t, LPCSTR s, int n); + +//************************************************************* +// ADIFアクセスのクラス +// +class CLogADIF : public CLogConv +{ +public: +protected: + char m_bf[1024]; // ファイルバッファ + LPSTR m_p; + int m_conv; +private: + void __fastcall MMLOG2ADIF(LPSTR t, SDMMLOG *sp); + void __fastcall SetData(SDMMLOG *sp, LPCSTR pKey, LPSTR pData); + void __fastcall AdjustData(SDMMLOG *sp); + void OutF(int &col, FILE *fp, LPCSTR fmt, ...); + +public: + __fastcall CLogADIF(); + virtual int __fastcall Open(LPCSTR pName); + virtual int __fastcall Create(LPCSTR pName); + virtual int __fastcall Close(void); + virtual int __fastcall Read(SDMMLOG *sp); + virtual int __fastcall Write(SDMMLOG *sp); + +}; + +//************************************************************* +// Cabrillo アクセスのクラス +// +class CLogCabrillo : public CLogConv +{ +public: +protected: + char m_bf[1024]; // ファイルバッファ + LPSTR m_p; + AnsiString m_SNR; +private: + void __fastcall MMLOG2Cabrillo(LPSTR t, SDMMLOG *sp); + void __fastcall AdjustData(SDMMLOG *sp); + +public: + __fastcall CLogCabrillo(); + virtual int __fastcall Open(LPCSTR pName); + virtual int __fastcall Create(LPCSTR pName); + virtual int __fastcall Close(void); + virtual int __fastcall Read(SDMMLOG *sp); + virtual int __fastcall Write(SDMMLOG *sp); +}; + +#endif diff --git a/LogFile.cpp b/LogFile.cpp new file mode 100644 index 0000000..48920ac --- /dev/null +++ b/LogFile.cpp @@ -0,0 +1,1667 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include +#include +#include +#include "LogFile.h" +#include "Main.h" +#include "Hamlog5.h" +CLogFile Log; + + +//--------------------------------------------------------------------------- +// MMLOG Constant +// +enum BD { /* バンドの番号 */ + B_NULL, + B_19, + B_35, + B_38, + B_7, + B_10, + B_14, + B_18, + B_21, + B_24, + B_28, + B_50, + B_144, + B_430, + B_1200, + B_2400, + B_5600, + B_101G, + B_104G, + B_24G, + B_47G, + B_75G, + B_142G, + B_248G, + B_4630, + B_220, + B_SAT, +}; + +const char *_mBand[]={ + "","160","80","75","40","30","20","17","15","12","10","6", + "2","430","1200","2400","5600","10.1G","10.4G","24G","47G", + "75G","142G","248G","4630","220",NULL, +}; +const char *_band[]={ + "","1.9","3.5","3.8","7","10","14","18","21","24","28","50", + "144","430","1200","2400","5600","10.1G","10.4G","24G","47G", + "75G","142G","248G","4630","220",NULL, +}; +static const char *_mode[]={ + "", + "CW","SSB","AM","FM","RTTY","PAC","FAX","SSTV","ATV","TV","FSTV", + "A1","A2","A3","A3A","A3H","A3J","A4","A5","A5C","A5J", + "A9","A9C","F1","F2","F3","F4","F5","F9","P0","P1", + "P2D","P2E","P2F","P3D","P3E","P3F","P9", + "U1","U2","U3","U4", + "PSK","BPSK","QPSK","HELL","MFSK", + NULL, +}; +const char lmode[]={ + 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, + 3, 3, 3, 3, 3, +}; +const char MONN[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; +const char MONU[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; +//--------------------------------------------------------------------------- +// CIndexクラス +int __fastcall GetLMode(BYTE m) +{ + if( m < MODEMAX ){ + return lmode[m]; + } + else { + return 3; + } +} +//--------------------------------------------------------------------------- +// CIndexクラス +__fastcall CIndex::CIndex() +{ + m_IndexMax = 0; // 確保中のインデックスの数 + m_IndexCnt = 0; // 現在のインデックスの数 + pIndex = NULL; // インデックス領域のポインタ(16バイトインデックス) + pMult = NULL; +} +__fastcall CIndex::~CIndex() +{ + if( pIndex != NULL ){ + delete pIndex; + pIndex = NULL; + } + if( pMult != NULL ){ + delete pMult; + pMult = NULL; + } +} +void __fastcall CIndex::AllocIndex(int n) +{ + if( n >= m_IndexMax ){ + int max = m_IndexMax ? (m_IndexMax * 2) : 32768; + LPSTR np = new char[16*max]; + if( pIndex != NULL ){ + memcpy(np, pIndex, m_IndexCnt*16); + delete pIndex; + } + pIndex = np; + m_IndexMax = max; + } +} + +void __fastcall CIndex::ClearIndex(void) +{ + m_IndexCnt = 0; +} + +void __fastcall CIndex::WriteIndex(LPCSTR pCall, int n) +{ + AllocIndex(n); + memcpy(&pIndex[n*16], pCall, 16); + if( n >= m_IndexCnt ) m_IndexCnt = n + 1; +} + +void __fastcall CIndex::ReadIndex(LPSTR pCall, int n) +{ + memcpy(pCall, &pIndex[n*16], 16); + pCall[16] = 0; +} + +LPSTR __fastcall CIndex::PointIndex(int n) +{ + return &pIndex[n*16]; +} + +void __fastcall CIndex::AddBlock(LPCSTR p, int len) +{ + int n = len/16; + AllocIndex(n + m_IndexCnt); + memcpy(&pIndex[m_IndexCnt*16], p, len); + m_IndexCnt += n; +} +//--------------------------------------------------------------------------- +int __fastcall CIndex::ReadIndex(int handle, FHD *hp) +{ + int r = TRUE; + int BUFSIZE=32768; + + CWaitCursor w; + if( lseek(handle, (hp->size * (ULONG)sizeof(SDMMLOG)) + FHDOFF, SEEK_SET) != -1L ){ + if( hp->hash != 2 ){ // 16バイトインデックスと異なる + if( hp->hash ){ // 2バイトインデックスのスキップ + lseek(handle, hp->size * 2, SEEK_CUR); + } + r = FALSE; + } + else { // 16バイトインデックス + LPSTR bp = new char[BUFSIZE]; + int len = hp->size * 16; + int rlen, wlen; + while(len){ + rlen = (len > BUFSIZE) ? BUFSIZE : len; + wlen = read(handle, bp, rlen); + if( rlen != wlen ){ + r = FALSE; + break; + } + AddBlock(bp, wlen); + len -= wlen; + } + delete bp; + } + if( pMult == NULL ) pMult = new BYTE[32768]; + read(handle, pMult, hp->mlt); + } + else { + r = FALSE; + } + return r; +} + +void __fastcall CIndex::MakeIndex(int handle, FHD *hp) +{ + CWaitCursor w; + + lseek(handle, (ULONG)FHDOFF, SEEK_SET); + ClearIndex(); + + FHD fh; + memset(&fh, 0, sizeof(fh)); + + int i, rlen; + SDMMLOG sd; + for( i = 0; i < hp->size; i++ ){ + rlen = read(handle, &sd, sizeof(sd)); + if( rlen != sizeof(sd) ) break; + WriteIndex(sd.call, i); + if( sd.mode >= MODEMAX ){ + int m = sd.mode - MODEMAX; + int f = 0; + int n; + char sbf[7]; + StrCopy(sbf, hp->mode[m], 6); + for( n = 0; (n < UMODEMAX) && fh.mode[n][0] ; n++ ){ + char tbf[7]; + StrCopy(tbf, fh.mode[n], 6); + if( !strcmp(sbf, tbf) ){ + if( m != n ){ + f++; + sd.mode = BYTE(n + MODEMAX); + break; + } + } + } + if( !fh.mode[n][0] ){ + StrCopy(fh.mode[n], sbf, 6); + if( m != n ){ + sd.mode = BYTE(n + MODEMAX); + f++; + } + } + if( f ){ + lseek( handle, -long(sizeof(sd)), SEEK_CUR); + write(handle, &sd, sizeof(sd)); + } + } + } + memcpy(hp->mode, fh.mode, sizeof(fh.mode)); + lseek( handle, (hp->size * (ULONG)sizeof(SDMMLOG)) + FHDOFF, SEEK_SET); + hp->hash = 2; // 16バイトインデックス +} + +//--------------------------------------------------------------------------- +int __fastcall CIndex::WriteIndex(int handle, FHD *hp) +{ + int r = TRUE; + int BUFSIZE=32768; + + CWaitCursor w; + + if( lseek(handle, (hp->size * (ULONG)sizeof(SDMMLOG)) + FHDOFF, SEEK_SET) != -1L ){ + hp->hash = 2; + int len = hp->size * 16; + int vlen, wlen; + LPSTR cp = pIndex; + while(len){ + wlen = (len > BUFSIZE) ? BUFSIZE : len; + vlen = write(handle, cp, wlen); + if( wlen != vlen ) r = FALSE; + len -= vlen; + cp += vlen; + } + if( pMult != NULL ){ + write(handle, pMult, hp->mlt); + } + } + else { + r = FALSE; + } + return r; +} + +//--------------------------------------------------------------------------- +// CLogFindクラス +__fastcall CLogFind::CLogFind() +{ + m_FindCnt = 0; + pFindTbl = new int[FINDMAX]; +} +//--------------------------------------------------------------------------- +__fastcall CLogFind::~CLogFind() +{ + delete pFindTbl; + pFindTbl = NULL; +} +//--------------------------------------------------------------------------- +int __fastcall CLogFind::Add(int n) +{ + if( m_FindCnt >= FINDMAX ) return 0; + + for( int i = 0; i < m_FindCnt; i++ ){ + if( pFindTbl[i] == n ) return 0; + } + pFindTbl[m_FindCnt] = n; + m_FindCnt++; + return 1; +} +//--------------------------------------------------------------------------- +void __fastcall CLogFind::Ins(int n) +{ + if( m_FindCnt >= FINDMAX ) return; + + int i; + for( i = 0; i < m_FindCnt; i++ ){ + if( pFindTbl[i] == n ) return; + } + for( i = m_FindCnt - 1; i > 0; i-- ){ + pFindTbl[i] = pFindTbl[i-1]; + } + pFindTbl[0] = n; + m_FindCnt++; + m_FindCmp1Max++; + m_FindCmp2Max++; + m_FindStr1Max++; + m_FindStr2Max++; +} +//--------------------------------------------------------------------------- +// CLogFileクラス +__fastcall CLogFile::CLogFile() +{ + memset(&m_sd, 0, sizeof(SDMMLOG)); + memset(&m_bak, 0, sizeof(SDMMLOG)); + + m_Open = 0; // オープンフラグ + m_EditFlag = 0; + m_Handle = 0; + memset(&m_fhd, 0, sizeof(m_fhd)); // 現在オープン中のファイルヘッダ + MakePathName("TEMP.MDT"); + m_CurNo = 0; + + // LogSet のデフォルト + + m_LogSet.m_TimeZone = 'I'; // JA + + m_LogSet.m_UpperName = 0; // 大文字への変換 + m_LogSet.m_UpperQTH = 0; // 大文字への変換 + m_LogSet.m_UpperREM = 0; // 大文字への変換 + m_LogSet.m_UpperQSL = 0; // 大文字への変換 + + m_LogSet.m_DefMyRST = 0; // 0-OFF, 1-ON + + m_LogSet.m_CopyFreq = 1; // 0-Band, 1-Freq + m_LogSet.m_CopyHis = 0; // 0-599, 1-599001, 2-599UTC + m_LogSet.m_CopyName = 1; // 0-OFF, 1-ON + m_LogSet.m_CopyQTH = 1; // 0-OFF, 1-ON + m_LogSet.m_CopyREM = 0; // 0-OFF, 1-ON + m_LogSet.m_CopyQSL = 0; // 0-OFF, 1-ON + m_LogSet.m_CopyREMB4 = 0; // 0-OFF, 1-ON + + m_LogSet.m_AutoSave = 1; + m_LogSet.m_CheckBand = 1; + + m_LogSet.m_THRTTY = "RTY"; + m_LogSet.m_THSSTV = "STV"; + m_LogSet.m_THGMSK = "MSK"; + m_LogSet.m_THTZ = 0; + m_LogSet.m_ClipRSTADIF = 1; + m_LogSet.m_DateType = 0; + + m_LogSet.m_Backup = 1; + memcpy(m_LogSet.m_Hamlog5Len, g_Hamlog5Len, 17); +} + +__fastcall CLogFile::~CLogFile() +{ + Close(); +} + +void __fastcall CLogFile::ReadIniFile(LPCSTR pKey, TMemIniFile *pIniFile) +{ + m_LogSet.m_DateType = pIniFile->ReadInteger(pKey, "DateType", m_LogSet.m_DateType); + m_LogSet.m_TimeZone = (char)pIniFile->ReadInteger(pKey, "TimeZone", m_LogSet.m_TimeZone); + + m_LogSet.m_UpperName = pIniFile->ReadInteger(pKey, "UpperName", m_LogSet.m_UpperName); + m_LogSet.m_UpperQTH = pIniFile->ReadInteger(pKey, "UpperQTH", m_LogSet.m_UpperQTH); + m_LogSet.m_UpperREM = pIniFile->ReadInteger(pKey, "UpperREM", m_LogSet.m_UpperREM); + m_LogSet.m_UpperQSL = pIniFile->ReadInteger(pKey, "UpperQSL", m_LogSet.m_UpperQSL); + + m_LogSet.m_DefMyRST = pIniFile->ReadInteger(pKey, "DefMyRST", m_LogSet.m_DefMyRST); + + m_LogSet.m_CopyFreq = pIniFile->ReadInteger(pKey, "CopyFreq", m_LogSet.m_CopyFreq); + m_LogSet.m_CopyHis = pIniFile->ReadInteger(pKey, "CopyHis", m_LogSet.m_CopyHis); + m_LogSet.m_CopyName = pIniFile->ReadInteger(pKey, "CopyName", m_LogSet.m_CopyName); + m_LogSet.m_CopyQTH = pIniFile->ReadInteger(pKey, "CopyQTH", m_LogSet.m_CopyQTH); + m_LogSet.m_CopyREM = pIniFile->ReadInteger(pKey, "CopyREM", m_LogSet.m_CopyREM); + m_LogSet.m_CopyQSL = pIniFile->ReadInteger(pKey, "CopyQSL", m_LogSet.m_CopyQSL); + m_LogSet.m_CopyREMB4 = pIniFile->ReadInteger(pKey, "CopyREMB4", m_LogSet.m_CopyREMB4); + + m_LogSet.m_CheckBand = pIniFile->ReadInteger(pKey, "CheckBand", m_LogSet.m_CheckBand); + + m_LogSet.m_AutoSave = pIniFile->ReadInteger(pKey, "AutoSave", m_LogSet.m_AutoSave); + m_LogSet.m_THRTTY = pIniFile->ReadString(pKey, "THRTTY", m_LogSet.m_THRTTY); + m_LogSet.m_THSSTV = pIniFile->ReadString(pKey, "THSSTV", m_LogSet.m_THSSTV); + m_LogSet.m_THGMSK = pIniFile->ReadString(pKey, "THGMSK", m_LogSet.m_THGMSK); + m_LogSet.m_THTZ = pIniFile->ReadInteger(pKey, "THTZ", m_LogSet.m_THTZ); + m_LogSet.m_ClipRSTADIF = pIniFile->ReadInteger(pKey, "ClipRSTADIF", m_LogSet.m_ClipRSTADIF); + + m_LogSet.m_Backup = pIniFile->ReadInteger(pKey, "Backup", m_LogSet.m_Backup); + AnsiString ss; + GetHamlog5FieldsLen(ss); + AnsiString as = pIniFile->ReadString(pKey, "TH5Fields", ss); + SetHamlog5FieldsLen(as); +} + +void __fastcall CLogFile::WriteIniFile(LPCSTR pKey, TMemIniFile *pIniFile) +{ + pIniFile->WriteInteger(pKey, "TimeZone", m_LogSet.m_TimeZone); + pIniFile->WriteInteger(pKey, "DateType", m_LogSet.m_DateType); + + pIniFile->WriteInteger(pKey, "UpperName", m_LogSet.m_UpperName); + pIniFile->WriteInteger(pKey, "UpperQTH", m_LogSet.m_UpperQTH); + pIniFile->WriteInteger(pKey, "UpperREM", m_LogSet.m_UpperREM); + pIniFile->WriteInteger(pKey, "UpperQSL", m_LogSet.m_UpperQSL); + + pIniFile->WriteInteger(pKey, "DefMyRST", m_LogSet.m_DefMyRST); + + pIniFile->WriteInteger(pKey, "CopyFreq", m_LogSet.m_CopyFreq); + pIniFile->WriteInteger(pKey, "CopyHis", m_LogSet.m_CopyHis); + pIniFile->WriteInteger(pKey, "CopyName", m_LogSet.m_CopyName); + pIniFile->WriteInteger(pKey, "CopyQTH", m_LogSet.m_CopyQTH); + pIniFile->WriteInteger(pKey, "CopyREM", m_LogSet.m_CopyREM); + pIniFile->WriteInteger(pKey, "CopyQSL", m_LogSet.m_CopyQSL); + pIniFile->WriteInteger(pKey, "CopyREMB4", m_LogSet.m_CopyREMB4); + + pIniFile->WriteInteger(pKey, "CheckBand", m_LogSet.m_CheckBand); + + pIniFile->WriteInteger(pKey, "AutoSave", m_LogSet.m_AutoSave); + pIniFile->WriteString(pKey, "THRTTY", m_LogSet.m_THRTTY); + pIniFile->WriteString(pKey, "THSSTV", m_LogSet.m_THSSTV); + pIniFile->WriteString(pKey, "THGMSK", m_LogSet.m_THGMSK); + pIniFile->WriteInteger(pKey, "THTZ", m_LogSet.m_THTZ); + pIniFile->WriteInteger(pKey, "ClipRSTADIF", m_LogSet.m_ClipRSTADIF); + + pIniFile->WriteInteger(pKey, "Backup", m_LogSet.m_Backup); + + AnsiString ss; + GetHamlog5FieldsLen(ss); + pIniFile->WriteString(pKey, "TH5Fields", ss); +} + +void __fastcall CLogFile::MakeIndex(void) +{ + if( !m_Open ) return; + + m_Index.MakeIndex(m_Handle, &m_fhd); + m_EditFlag = 1; +} + +void __fastcall CLogFile::MakePathName(LPCSTR pName) +{ + char bf[256]; + + m_Name = pName; + sprintf(bf, "%s%s", sys.m_LogDir, pName); + SetEXT(bf, ".MDT"); + m_FileName = bf; +} + +void __fastcall CLogFile::MakeName(LPCSTR pPathName) +{ + if( pPathName != m_FileName.c_str() ) m_FileName = pPathName; + + char drive[_MAX_DRIVE]; + char dir[_MAX_DIR]; + char name[_MAX_FNAME]; + char ext[_MAX_EXT]; + AnsiString Dir; + + ::_splitpath( pPathName, drive, dir, name, ext ); + Dir = drive; + Dir += dir; + m_Name = name; + m_Name += ext; + if( Dir.IsEmpty() ){ + if( GetCurrentDirectory(128, sys.m_LogDir) ){ + if( LastC(sys.m_LogDir) != '\\' ) strcat(sys.m_LogDir, "\\"); + MakePathName(m_Name.c_str()); + } + } + else { + strncpy(sys.m_LogDir, Dir.c_str(), 128); + } +} + +void __fastcall CLogFile::DoBackup(void) +{ + if( !Log.m_LogSet.m_Backup ) return; + if( m_FileName.IsEmpty() ) return; + + FILE *sfp = fopen(m_FileName.c_str(), "rb"); + if( sfp == NULL ) return; + + char tname[256]; + strcpy(tname, m_FileName.c_str()); + SetEXT(tname, "_BAK.MDT"); + FILE *tfp = fopen(tname, "rb"); + if( tfp != NULL ){ + long slen = filelength(fileno(sfp)); + long tlen = filelength(fileno(tfp)); + fclose(tfp); + if( slen <= tlen ){ + fclose(sfp); + return; + } + } + fclose(sfp); + ::CopyFile(m_FileName.c_str(), tname, FALSE); +} + +int __fastcall CLogFile::Close(void) +{ + int r = TRUE; + if( m_Open ){ + if( m_EditFlag ){ + if( m_fhd.size ){ + SDMMLOG sd; + + GetData(&sd, m_fhd.size - 1); + if( !sd.date || !sd.btime ){ + DeleteLast(); + } + } + ULONG size = (m_fhd.size * (ULONG)sizeof(SDMMLOG))+(ULONG)FHDOFF; + if( chsize(m_Handle, size) ){ + ErrorFWrite(m_FileName.c_str()); + r = FALSE; + lseek(m_Handle, size, SEEK_SET); + } + m_Index.WriteIndex(m_Handle, &m_fhd); // インデックスの格納 + lseek(m_Handle, 0L, SEEK_SET); + if( write( m_Handle, &m_fhd, sizeof(m_fhd) ) != sizeof(m_fhd) ){ + ErrorFWrite(m_FileName.c_str()); + r = FALSE; + } + } + if( close(m_Handle) ){ + if( r != FALSE ){ + ErrorFWrite(m_FileName.c_str()); + r = FALSE; + } + } +// if( !m_fhd.size ) unlink(m_FileName.c_str()); // 0件の時は消去 + m_Open = 0; + } + m_EditFlag = 0; + m_Index.ClearIndex(); + return r; +} + +void __fastcall CLogFile::InitHeader(void) +{ + memset(&m_fhd, 0, sizeof(m_fhd)); + strcpy(m_fhd.id, MMLOGID); + m_fhd.size = 0L; + m_fhd.mlt = 0; +} + +int __fastcall CLogFile::Open(LPCSTR pName, BOOL fNew) +{ + CWaitCursor w; + Close(); + InitHeader(); + + if( pName == NULL ) pName = m_FileName.c_str(); + int omode = O_RDWR|O_BINARY; // 初回は新規作成なしでオープン + int n = 0; + while(1){ + if( (m_Handle = open(pName, omode, S_IREAD|S_IWRITE)) > 0 ){ + if( read(m_Handle, &m_fhd, sizeof(m_fhd)) == sizeof(m_fhd) ){ + if( !strcmp(m_fhd.id, MMLOGID) ){ + if( m_Index.ReadIndex(m_Handle, &m_fhd) != TRUE ){ + m_Index.MakeIndex(m_Handle, &m_fhd); + } + m_Open = 1; + MakeName(pName); + m_Find.Clear(); + SetLastPos(); + memcpy(&m_asd, &m_sd, sizeof(m_asd)); + return TRUE; + } + else { + close(m_Handle); + ErrorMB("'%s' is not a correct format.", pName); + } + } + else if( omode & O_CREAT ){ // 新規ファイル 2回目のパスのみ + InitHeader(); + if( write(m_Handle, &m_fhd, sizeof(m_fhd)) != sizeof(m_fhd) ){ + close(m_Handle); + ErrorMB("Cannot open '%s'.", pName); + } + else { + m_Open = 1; + MakeName(pName); + m_Index.ClearIndex(); + m_Find.Clear(); + SetLastPos(); + memcpy(&m_asd, &m_sd, sizeof(m_asd)); + return TRUE; + } + } + else { // 既存のフィアル + close(m_Handle); + ErrorMB("Cannot open '%s'.", pName); + } + return FALSE; + } + // オープンエラーの場合 + if( !(omode & O_CREAT) && (errno == ENOENT) ){ // 1回目でファイルが存在しない場合 + n++; + if( n >= 2 ){ + if( fNew ){ + if( YesNoMB(sys.m_MsgEng ? "Log file (%s) does not exist, create it ?" : "ログファイル(%s)が見つかりません. 新規に作成しますか ?", pName) != IDYES ) return FALSE; + } + omode |= O_CREAT; // 2回目は新規作成付きでオープン + } + else { + ::Sleep(200); + } + } + else if( IsFile(pName) && (GetFileAttributes(pName) & FILE_ATTRIBUTE_READONLY) ){ + ErrorMB("'%s' is read-only.", pName); + return FALSE; + } + else { + ErrorMB("Cannot open '%s'.", pName); + return FALSE; + } + } +} + +void __fastcall CLogFile::InitCur(void) +{ + SetLastPos(); +} + +void __fastcall CLogFile::SetLastPos(void) +{ + m_CurNo = m_fhd.size; + memset(&m_sd, 0, sizeof(SDMMLOG)); + + int n = m_CurNo - 1; + if( n >= 0 ){ + SDMMLOG sd; + + GetData(&sd, n); + if( !sd.etime ){ + m_CurNo = n; + memcpy(&m_sd, &sd, sizeof(SDMMLOG)); + } + } + else { + m_sd.band = B_7; + m_sd.fq = 28; + SetMode(&m_sd, g_tLogModeTable[MainVARI->CBMode->ItemIndex]); +// m_sd.mode = 8; + m_sd.env = 1; + } + CopyAF(); + m_CurChg = 0; +} + +int __fastcall CLogFile::GetData(SDMMLOG *sp, int n) +{ + if( !m_Open || (n >= m_fhd.size) ){ + memset(sp, 0, sizeof(SDMMLOG)); + if( !n ){ + m_sd.band = B_14; + m_sd.mode = 5; + } + return FALSE; + } + if( lseek(m_Handle, (ULONG)FHDOFF + ((ULONG)n * (ULONG)sizeof(SDMMLOG)), SEEK_SET) == -1L ){ + memset(sp, 0, sizeof(SDMMLOG)); + return FALSE; + } + if( read( m_Handle, sp, sizeof(SDMMLOG) ) != sizeof(SDMMLOG) ){ + memset(sp, 0, sizeof(SDMMLOG)); + return FALSE; + } + else { + return TRUE; + } +} + +int __fastcall CLogFile::PutData(SDMMLOG *sp, int n) +{ + if( !m_Open ){ + if( m_FileName.IsEmpty() ){ + ErrorMB("ログファイルの名前が定義されていません."); + return FALSE; + } + if( Open(m_FileName.c_str(), TRUE) != TRUE ) return FALSE; + } + if( lseek(m_Handle, (ULONG)FHDOFF + ((ULONG)n * (ULONG)sizeof(SDMMLOG)), SEEK_SET) == -1L ){ + ErrorFWrite(m_FileName.c_str()); + return FALSE; + } + if( write( m_Handle, sp, sizeof(SDMMLOG) ) != sizeof(SDMMLOG) ){ + ErrorFWrite(m_FileName.c_str()); + return FALSE; + } + else { + m_EditFlag = 1; + if( m_CurNo == n ) m_CurChg = 1; + if( n >= m_fhd.size ) m_fhd.size = n + 1; + m_Index.WriteIndex(sp->call, n); + } + return TRUE; +} + +LPCSTR __fastcall CLogFile::GetOptStr(int n, SDMMLOG *sp) +{ + switch(n){ + case 0: + return sp->opt1; + case 1: + return sp->opt2; + case 2: + if( !sp->ur[MLRST-MLOPT-1] && sp->ur[MLRST-MLOPT] ){ + return &sp->ur[MLRST-MLOPT]; + } + else { + return ""; + } + case 3: + if( !sp->my[MLRST-MLOPT-1] && sp->my[MLRST-MLOPT] ){ + return &sp->my[MLRST-MLOPT]; + } + else { + return ""; + } + default: + return ""; + } +} + +void __fastcall CLogFile::SetOptStr(int n, SDMMLOG *sp, LPCSTR pOpt) +{ + switch(n){ + case 0: + StrCopy(sp->opt1, pOpt, MLOPT); + jstrupr(sp->opt1); + break; + case 1: + StrCopy(sp->opt2, pOpt, MLOPT); + jstrupr(sp->opt2); + break; + case 2: + if( *pOpt ){ + StrCopy(&sp->ur[MLRST-MLOPT], pOpt, MLOPT); + jstrupr(&sp->ur[MLRST-MLOPT]); + sp->ur[MLRST-MLOPT-1] = 0; + } + else if( !sp->ur[MLRST-MLOPT-1] ){ + sp->ur[MLRST-MLOPT] = 0; + } + break; + case 3: + if( *pOpt ){ + StrCopy(&sp->my[MLRST-MLOPT], pOpt, MLOPT); + jstrupr(&sp->my[MLRST-MLOPT]); + sp->my[MLRST-MLOPT-1] = 0; + } + else if( !sp->my[MLRST-MLOPT-1] ){ + sp->my[MLRST-MLOPT] = 0; + } + break; + default: + break; + } +} + +void __fastcall CLogFile::SetHisRST(SDMMLOG *sp) +{ + int n, tim; + + switch(m_LogSet.m_CopyHis){ + case 0: + if( sp == NULL ){ + strcpy(m_sd.ur, "599"); + } + else { + strcpy(m_sd.ur, sp->ur); + memcpy(m_sd.ur, "599", 3); + } + break; + case 1: + if( sp == NULL ){ + strcpy(m_sd.ur, "599001"); + } + else { + if( sp->ur[0] ){ + n = atoin(&sp->ur[3], -1); + } + else { + n = 0; + } + n++; + if( n >= 10000 ){ + sprintf(m_sd.ur, "599%04u", n); + } + else { + sprintf(m_sd.ur, "599%03u", n); + } + } + break; + case 2: + if( m_sd.btime ){ + tim = m_sd.btime / 30; + if( tim >= (9 * 60) ){ + tim -= 9 * 60; + } + else { + tim += 15 * 60; + } + sprintf(m_sd.ur, "599%02u%02u", tim/60, tim%60); + } + break; + } +} + +void __fastcall CLogFile::CopyAF(void) +{ + int n = m_CurNo - 1; + if( n >= 0 ){ + SDMMLOG sd; + GetData(&sd, n); + if( !m_sd.band ){ + m_sd.band = sd.band; + if( m_LogSet.m_CopyFreq ){ + m_sd.fq = sd.fq; + } + else { + m_sd.fq = 0; + } + } + if( !m_sd.env ){ + m_sd.env = sd.env; + } + if( !m_sd.pow[0] ){ + strcpy(m_sd.pow, sd.pow); + } + if( !m_sd.ur[0] ){ + SetHisRST(&sd); + } + if( m_LogSet.m_CopyREMB4 ){ + strcpy(m_sd.rem, sd.rem); + } + } + else { + if( !m_sd.band ){ + m_sd.band = B_14; + m_sd.fq = 0; + } + if( !m_sd.env ){ + m_sd.env = 1; + } + if( !m_sd.ur[0] ){ + SetHisRST(NULL); + } + } + if( !m_sd.mode ){ + SetMode(&m_sd, g_tLogModeTable[MainVARI->CBMode->ItemIndex]); +// m_sd.mode = 5; // RTTY + } + if( m_LogSet.m_DefMyRST ){ + if( !m_sd.my[0] ){ + strcpy(m_sd.my, "599"); + } + } +} + +static int _cmpdate(SDMMLOG *s, SDMMLOG *t) +{ + int r = YEAR(s->year) - YEAR(t->year); + if( r ) return r; + r = s->date - t->date; + if( r ) return r; + return s->btime - t->btime; +} + +void __fastcall CLogFile::SortDate(int bb, int eb) +{ + int gap, i, j, em; + SDMMLOG sd1, sd2; + + CWaitCursor w; + if( bb != eb ){ + em = eb - bb; + for( gap = (em + 1)/2; gap > 0; gap /= 2 ){ + for( i = gap; i <= em; i++ ){ + for( j = i - gap; j >= 0; j -= gap ){ + GetData(&sd1, bb+j); + GetData(&sd2, bb+j+gap); + if( _cmpdate(&sd1, &sd2) <= 0 ) break; + PutData(&sd1, bb+j+gap); + PutData(&sd2, bb+j); + } + } + } + } + m_EditFlag = 1; +} + +int __fastcall CLogFile::FindSameBand(BOOL fMode) +{ + if( !m_sd.call[0] ) return 0; + char call[MLCALL+1]; + SDMMLOG sd; + + OnWave(); + int i; + for( i = 0; i < m_Find.GetCount(); i++ ){ + m_Index.ReadIndex(call, m_Find.pFindTbl[i]); + if( !strcmp(call, m_sd.call) ){ + GetData(&sd, m_Find.pFindTbl[i]); + OnWave(); + if( !sd.etime && (i == (m_Find.GetCount()-1)) ) break; + if( fMode ){ + if( (sd.band == m_sd.band)&&(sd.mode == m_sd.mode) ) return 1; + } + else { + if( sd.band == m_sd.band ) return 1; + } + } + } + return 0; +} + +int __fastcall CLogFile::FindSameDate(void) +{ + if( !m_sd.call[0] ) return 0; + char call[MLCALL+1]; + SDMMLOG sd; + + SYSTEMTIME utc; + GetUTC(&utc); + OnWave(); + int i; + for( i = 0; i < m_Find.GetCount(); i++ ){ + m_Index.ReadIndex(call, m_Find.pFindTbl[i]); + if( !strcmp(call, m_sd.call) ){ + GetData(&sd, m_Find.pFindTbl[i]); + OnWave(); + if( !sd.etime && (i == (m_Find.GetCount()-1)) ) break; + JSTtoUTC(&sd); + int yy = sd.year + 2000; + int mm = sd.date / 100; + int dd = sd.date % 100; + if( (sd.mode == 8) && (sd.band >= B_14) && (yy == utc.wYear) && (mm == utc.wMonth) && (dd == utc.wDay) ) return 1; + } + } + return 0; +} + +void __fastcall CLogFile::FindStrSet(CLogFind *fp, LPCSTR pCall) +{ + if( !*pCall ) return; + if( fp->GetCount() >= FINDMAX ) return; + char call[MLCALL+1]; + + OnWave(); + int i; + for( i = m_fhd.size - 1; i >= 0; i-- ){ + m_Index.ReadIndex(call, i); + if( strstr(call, pCall)!=NULL ){ + fp->Add(i); + if( fp->GetCount() >= FINDMAX ) break; + } + } +} + +int __fastcall CLogFile::FindCmpSet(CLogFind *fp, LPCSTR pCall) +{ + if( fp->GetCount() >= FINDMAX ) return 0; + char call[MLCALL+1]; + + OnWave(); + int i; + for( i = m_fhd.size - 1; i >= 0; i-- ){ + if( *pCall ){ + m_Index.ReadIndex(call, i); + if( !strcmp(call, pCall) ){ + fp->Write(i); + } + } + else { + fp->Write(i); + } + if( fp->GetCount() >= FINDMAX ) break; + } + return fp->GetCount(); +} + +int __fastcall CLogFile::FindClipSet(CLogFind *fp, LPCSTR pCall) +{ + if( !*pCall ) return 0; + if( fp->GetCount() >= FINDMAX ) return 0; + char call[MLCALL+1]; + + OnWave(); + int i; + for( i = m_fhd.size - 1; i >= 0; i-- ){ + m_Index.ReadIndex(call, i); + if( !strcmp(ClipCall(call), pCall) ){ + fp->Add(i); + } + if( fp->GetCount() >= FINDMAX ) break; + } + return fp->GetCount(); +} + +int __fastcall CLogFile::FindSet(CLogFind *fp, LPCSTR pCall) +{ + fp->SetText(pCall); + fp->Clear(); + int r = FindCmpSet(fp, pCall); + fp->m_FindCmp1Max = fp->m_FindCnt; + char clipcall[MLCALL+1]; + strcpy(clipcall, ClipCall(pCall)); + if( FindClipSet(fp, clipcall) ){ + r = 1; + } + fp->m_FindCmp2Max = fp->m_FindCnt; + FindStrSet(fp, pCall); + fp->m_FindStr1Max = fp->m_FindStr2Max = fp->m_FindCnt; + if( strcmp(pCall, clipcall) ){ + FindStrSet(fp, clipcall); + fp->m_FindStr2Max = fp->m_FindCnt; + } + return r; +} + +int __fastcall CLogFile::Find(LPCSTR pCall, int b, int dir) +{ + if( !m_fhd.size ) return -1; + char call[MLCALL+1]; + + OnWave(); + int i; + if( dir ){ + for( i = b; i >= 0; i-- ){ + m_Index.ReadIndex(call, i); + if( strstr(call, pCall) != NULL ) return i; + } + } + else { + for( i = b; i < m_fhd.size; i++ ){ + m_Index.ReadIndex(call, i); + if( strstr(call, pCall) != NULL ) return i; + } + } + return -1; +} + +int __fastcall CLogFile::IsAlready(LPCSTR pCall) +{ + if( !m_fhd.size ) return -1; + char call[MLCALL+1]; + + for( int i = m_CurNo; i >= 0; i-- ){ + m_Index.ReadIndex(call, i); + if( !strcmp(call, pCall) ) return i; + } + return -1; +} + +void __fastcall CLogFile::DeleteAll(void) +{ + m_fhd.size = 0; + m_CurNo = m_fhd.size; + m_CurChg = 1; + m_EditFlag = 1; +} + +void __fastcall CLogFile::DeleteLast(void) +{ + if( m_fhd.size ){ + m_fhd.size--; + } + m_CurNo = m_fhd.size; + m_CurChg = 1; + m_EditFlag = 1; +} + +void __fastcall CLogFile::Delete(int top, int end) +{ + if( !m_fhd.size ) return; + + if( end >= (m_fhd.size - 1) ){ // 最後まで削除する場合 + m_fhd.size = top; + m_CurNo = m_fhd.size; + } + else { // 途中を削除する場合 + int i, j; + SDMMLOG sd; + for( i = top, j = end + 1; j < m_fhd.size; i++, j++ ){ + GetData(&sd, j); + PutData(&sd, i); + } + m_fhd.size -= end - top + 1; + m_CurNo = m_fhd.size; + } + SetLastPos(); + m_CurChg = 1; + m_EditFlag = 1; +} + +void __fastcall CLogFile::Insert(int n, SDMMLOG *sp) +{ + if( n >= m_fhd.size ){ // 最終位置の場合は追加と同じ + PutData(sp, n); + m_CurNo++; + } + else { // 途中を削除する場合 + int i, j; + SDMMLOG sd; + i = m_fhd.size; + j = i - 1; + for( ; i > n; i--, j-- ){ + GetData(&sd, j); + PutData(&sd, i); + } + PutData(sp, n); + m_CurNo++; + m_CurChg = 0; + } + m_EditFlag = 1; +} + +LPCSTR __fastcall CLogFile::GetDateString(SDMMLOG *sp, int sw) +{ + static char bf[12]; + + if( sp->date ){ + switch(sw){ + case 1: // yyyy-mm-dd + sprintf(bf, "%04u.%02u.%02u", YEAR(sp->year), sp->date/100, sp->date%100); + break; + case 2: // dd-mm-yy + sprintf(bf, "%02u.%02u.%02u", sp->date%100, sp->date/100, sp->year); + break; + case 3: // dd-mm-yyyy + sprintf(bf, "%02u.%02u.%04u", sp->date%100, sp->date/100, YEAR(sp->year)); + break; + case 4: // mm-dd-yy + sprintf(bf, "%02u.%02u.%02u", sp->date/100, sp->date%100, sp->year); + break; + case 5: // mm-dd-yyyy + sprintf(bf, "%02u.%02u.%04u", sp->date/100, sp->date%100, YEAR(sp->year)); + break; + default: // yy-mm-dd + sprintf(bf, "%02u.%02u.%02u", sp->year, sp->date/100, sp->date%100); + break; + } + } + else { + bf[0] = 0; + } + return bf; +} + +LPCSTR __fastcall CLogFile::GetTimeString(WORD d) +{ + static char bf[8]; + + if( d ){ + d = WORD(d / 30); + sprintf(bf, "%02u%02u", d / 60, d % 60); + } + else { + bf[0] = 0; + } + return bf; +} + +LPCSTR __fastcall CLogFile::GetModeString(BYTE m) +{ + if( m < MODEMAX ){ + return _mode[m]; + } + else { + m -= BYTE(MODEMAX); + StrCopy(m_modebuf, m_fhd.mode[m], 6); + return m_modebuf; + } +} + +void __fastcall CLogFile::SetMode(SDMMLOG *sp, LPCSTR s) +{ + if( !*s ){ + sp->mode = 0; + return; + } + + int n; + const char **t; + char bf[7]; + StrCopy(bf, s, 6); + jstrupr(bf); + s = bf; + int len = strlen(s); + for( n = 0, t = _mode; *t != NULL; t++, n++ ){ + if( !strcmp(*t, s) ){ + sp->mode = BYTE(n); + return; + } + } + for( n = 0; (n < UMODEMAX) && m_fhd.mode[n][0] ; n++ ){ + char vbf[7]; + StrCopy(vbf, m_fhd.mode[n], 6); + if( !strcmp(vbf, s) ){ + sp->mode = BYTE(n + MODEMAX); + return; + } + } + if( n < UMODEMAX ){ + if( len < 6 ){ + strcpy(m_fhd.mode[n], s); + } + else { + memcpy(m_fhd.mode[n], s, 6); + } + sp->mode = BYTE(n + MODEMAX); + } + else { + sp->mode = 0; + } +} + +LPCSTR __fastcall CLogFile::GetFreqString(BYTE b, short fq) +{ + static char bf[12]; + int d; + + if( fq < 0 ){ + sprintf( bf, "%s/%s", _band[b], _band[-fq]); + return(bf); + } + else if( fq ){ + switch(b){ + case 0: + return ""; + case B_19: /* 1.9 */ + if( fq == 800 ){ + strcpy(bf, "1.8"); + } + else { + sprintf( bf, "1.%03u", fq ); + } + break; + case B_35: /* 3.5 */ + sprintf( bf, "3.%03u", fq ); + break; + case B_38: /* 3.8 */ + sprintf( bf, "3.%03u", fq ); + break; + case B_1200: + d = 1240 + (fq / 100); + sprintf( bf, "%u.%02u", d, fq % 100 ); + break; + case B_2400: + d = 2350 + (fq / 100); + sprintf( bf, "%u.%02u", d, fq % 100 ); + break; + case B_220: + d = 220 + (fq / 1000); + sprintf( bf, "%u.%03u", d, fq % 1000 ); + break; + default: + if( b <= B_24 ){ + sprintf( bf, "%s.%03u", _band[b], fq ); + } + else if( b <= B_430 ){ + d = atoin(_band[b], -1) + (fq / 1000); + sprintf( bf, "%u.%03u", d, fq % 1000 ); + } + else { + return(_band[b]); + } + break; + } + return(bf); + } + else { + return(_band[b]); + } +} + +/*#$% +=============================================================== + バンド番号を得る +--------------------------------------------------------------- + p : 文字列のポインタ +--------------------------------------------------------------- +--------------------------------------------------------------- +=============================================================== +*/ +static BYTE __fastcall _bandno_(LPCSTR p) +{ + char n; + const char **t; + + for( n = 0, t = _band; *t != NULL; t++, n++ ){ + if( !strcmp(*t, p) ) return(n); + } + return(0); +} + +/*#$% +=============================================================== + バンド番号を得る +--------------------------------------------------------------- + p : 文字列のポインタ +--------------------------------------------------------------- +--------------------------------------------------------------- +=============================================================== +*/ +void __fastcall CLogFile::SetFreq(SDMMLOG *sp, LPCSTR p) +{ + BYTE n; + char ub[16], db[16]; + int ud, d; + + sp->fq = 0; + if( strchr(p, '/' )!=NULL ){ + p = _strdmcpy(ub, p, '/'); + if( (n = _bandno_(ub))!= 0 ){ + if( (sp->fq = _bandno_(p))!= 0 ){ + sp->fq = SHORT(-sp->fq); + sp->band = n; + return; + } + } + sp->band = 0; + return; + } + if( (n = _bandno_(p))!= 0 ){ + sp->band = n; + return; + } + if( strchr(p, '.')!=NULL ){ + p = _strdmcpy(ub, p, '.'); + memset(db, 0, 4); + strcpy(db, p); + db[3] = 0; + for( n = 0; n < 3; n++ ){ + if( !db[n] ) db[n] = '0'; + } + ud = atoin(ub, -1); + d = atoin(db, -1); + } + else { + ud = atoin(p, -1); + d = 0; + } + if( ud == 1 ){ + sp->fq = SHORT(d); + sp->band = B_19; + } + else if( ud == 3 ){ + sp->fq = SHORT(d); + if( d >= 700 ){ + n = B_38; + } + else { + n = B_35; + } + sp->band = n; + } + else if( (ud >= 7) && (ud <= 24) ){ + sp->fq = SHORT(d); + if( (n = _bandno_(ub))!= 0 ){ + sp->band = n; + return; + } + sp->fq = 0; + sp->band = 0; + } + else if( (ud >= 28)&&(ud <= 29) ){ + sp->fq = SHORT(((ud - 28) * 1000) + d); + sp->band = B_28; + } + else if( (ud >= 50)&&(ud <= 54) ){ + sp->fq = SHORT(((ud - 50) * 1000) + d); + sp->band = B_50; + } + else if( (ud >= 144) && (ud <= 147) ){ + sp->fq = SHORT(((ud - 144) * 1000) + d); + sp->band = B_144; + } + else if( (ud >= 430) && (ud <= 440) ){ + sp->fq = SHORT(((ud - 430) * 1000) + d); + sp->band = B_430; + } + else if( (ud >= 220) && (ud <= 225) ){ + sp->fq = SHORT(((ud - 220) * 1000) + d); + sp->band = B_220; + } + else if( (ud >= 1240) && (ud <= 1300) ){ + sp->fq = SHORT(((ud - 1240) * 100) + (d/10)); + sp->band = B_1200; + } + else if( (ud >= 2350) && (ud <= 2450) ){ + sp->fq = SHORT(((ud - 2350) * 100) + (d/10)); + sp->band = B_2400; + } + else { + sp->band = 0; + } +} + +int __fastcall CLogFile::ReadAscii(SDMMLOG *sp, LPSTR p) +{ + LPSTR t; + int y, m, d; + + memset(sp, 0, sizeof(SDMMLOG)); + p = StrDlm(t, p); /* DATE */ + if( sscanf(t, "%u.%u.%u", &y, &m, &d )!=3 ) return FALSE; + sp->year = BYTE(y % 100); + sp->date = WORD((m * 100) + d); + p = StrDlm(t, p); /* BGN */ + if( sscanf(t, "%u.%u", &d, &y) != 2 ){ + d = atoin(t, -1); + y = 0; + } + m = d / 100; + d = d % 100; + y /= 2; + sp->btime = WORD((((m * 60) + d) * 30) + y); + p = StrDlm(t, p); /* CALL */ + StrCopy(sp->call, t, MLCALL); + p = StrDlm(t, p); /* UR */ + StrCopy(sp->ur, t, MLRST); + p = StrDlm(t, p); /* MY */ + StrCopy(sp->my, t, MLRST); + p = StrDlm(t, p); /* BAND */ + SetFreq(sp, t); + p = StrDlm(t, p); /* MODE */ + SetMode(sp, t); + p = StrDlm(t, p); /* POW */ + StrCopy(sp->pow, t, MLPOW); + p = StrDlm(t, p); /* NAME */ + StrCopy(sp->name, t, MLNAME); + p = StrDlm(t, p); /* QTH */ + StrCopy(sp->qth, t, MLQTH); + p = StrDlm(t, p); /* REM */ + StrCopy(sp->rem, t, MLREM); + p = StrDlm(t, p); /* QSL */ + StrCopy(sp->qsl, t, MLQSL); + p = StrDlm(t, p); /* ETIME*/ + d = atoin(t, -1); + m = d / 100; + d = d % 100; + sp->etime = WORD(((m * 60) + d) * 30); + p = StrDlm(t, p); /* S */ + sp->send = *t; + p = StrDlm(t, p); /* R */ + sp->recv = *t; + p = StrDlm(t, p); /* M */ + sp->cq = *t; + p = StrDlm(t, p); /* ENV */ + sp->env = WORD(atoin(t, -1)); + p = StrDlm(t, p); /* OPT1 */ + StrCopy(sp->opt1, t, MLOPT); + p = StrDlm(t, p); /* OPT2 */ + StrCopy(sp->opt2, t, MLOPT); + p = StrDlm(t, p); /* USR1 */ + if( *t ) SetOptStr(2, sp, t); + StrDlm(t, p); /* USR2 */ + if( *t ) SetOptStr(3, sp, t); + return TRUE; +} + +void __fastcall JSTtoUTC(int &Year, int &Mon, int &Day, int &Hour) +{ + + Hour -= 9; + if( Hour < 0 ){ + Hour += 24; + Day--; + if( Day < 1 ){ + Mon--; + if( Mon < 1 ){ + Mon = 12; + if( Year ){ + Year--; + } + else { + Year = 99; + } + } + if( Year % 4 ){ + Day = MONN[Mon]; + } + else { + Day = MONU[Mon]; + } + } + } +} + +void __fastcall JSTtoUTC(SDMMLOG *sp) +{ + int Year = sp->year; + int Mon = sp->date / 100; + int Day = sp->date % 100; + int Hour = sp->btime / (60*30); + if( sp->date || sp->btime ){ + JSTtoUTC(Year, Mon, Day, Hour); + sp->year = BYTE(Year); + sp->date = WORD(Mon * 100 + Day); + sp->btime = WORD((sp->btime % 1800) + (Hour * 1800)); + } + if( sp->etime ){ + // JST to UTC + if( sp->etime >= (9*60*30) ){ + sp->etime -= WORD(9 * 60 * 30); + } + else { + sp->etime += WORD(15 * 60 * 30); + } + if( !sp->etime ) sp->etime++; + } +} + +void __fastcall UTCtoJST(int &Year, int &Mon, int &Day, int &Hour) +{ + LPCSTR mt; + + Hour += 9; + if( Hour >= 24 ){ + Hour -= 24; + Day++; + if( Year % 4 ){ + mt = MONN; + } + else { + mt = MONU; + } + if( Day > mt[Mon] ){ + Day = 1; + Mon++; + if( Mon > 12 ){ + Mon = 1; + Year++; + if( Year >= 100 ) Year = 0; + } + } + } +} + +void __fastcall UTCtoJST(SDMMLOG *sp) +{ + int Year = sp->year; + int Mon = sp->date / 100; + int Day = sp->date % 100; + int Hour = sp->btime / (60*30); + if( sp->date || sp->btime ){ + UTCtoJST(Year, Mon, Day, Hour); + sp->year = BYTE(Year); + sp->date = WORD(Mon * 100 + Day); + sp->btime = WORD((sp->btime % 1800) + (Hour * 1800)); + } + if( sp->etime ){ + // UTC to JST + if( sp->etime >= (15*60*30) ){ + sp->etime -= WORD(15 * 60 * 30); + } + else { + sp->etime += WORD(9 * 60 * 30); + } + if( !sp->etime ) sp->etime++; + } +} + +void __fastcall UTCtoJST(SYSTEMTIME *tp) +{ + int y = tp->wYear; + int m = tp->wMonth; + int d = tp->wDay; + int h = tp->wHour; + UTCtoJST(y, m, d, h); + tp->wYear = WORD(y); + tp->wMonth = WORD(m); + tp->wDay = WORD(d); + tp->wHour = WORD(h); +} + +void __fastcall mBandToBand(SDMMLOG *sp, LPCSTR p) +{ + int m; + + sp->fq = 0; + if( !strcmpi(p, "SAT") ){ + sp->band = 0; + } + else if( sscanf(p, "%u", &m) == 1 ){ + switch(m){ + case 2: + sp->band = B_144; + break; + case 6: + sp->band = B_50; + break; + case 10: + sp->band = B_28; + break; + case 12: + sp->band = B_24; + break; + case 15: + sp->band = B_21; + break; + case 17: + sp->band = B_18; + break; + case 20: + sp->band = B_14; + break; + case 30: + sp->band = B_10; + break; + case 40: + sp->band = B_7; + break; + case 75: + sp->band = B_38; + break; + case 80: + sp->band = B_35; + break; + case 160: + sp->band = B_19; + sp->fq = 800; + break; + } + } +} + +LPCSTR __fastcall FreqTomBand(SDMMLOG *sp) +{ + return _mBand[sp->band]; +} + + diff --git a/LogFile.h b/LogFile.h new file mode 100644 index 0000000..605f639 --- /dev/null +++ b/LogFile.h @@ -0,0 +1,280 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef LogFileH +#define LogFileH + +#include "ComLib.h" +//--------------------------------------------------------------------------- +#define MMLOGID "MMLOG DATA Ver1.00\032" + +extern const char *_band[]; + +typedef struct { // Logの動作オプション + char m_TimeZone; // 表示用タイムゾーン + + int m_UpperName; // 大文字への変換 + int m_UpperQTH; // 大文字への変換 + int m_UpperREM; // 大文字への変換 + int m_UpperQSL; // 大文字への変換 + + int m_DefMyRST; // 0-OFF, 1-ON + + int m_CopyFreq; // 0-Band, 1-Freq + int m_CopyHis; // 0-599, 1-599001, 2-599UTC + int m_CopyName; // 0-OFF, 1-ON + int m_CopyQTH; // 0-OFF, 1-ON + int m_CopyREM; // 0-OFF, 1-ON + int m_CopyQSL; // 0-OFF, 1-ON + int m_CopyREMB4; // 0-OFF, 1-ON + + int m_AutoSave; // 自動セーブ + + int m_QSOMacroFlag; // 0-OFF, 1-ON + int m_CheckBand; // 同一バンドでの重複をチェック + int m_QSOMacro[5]; // 0-Run 1st, 1-Run 2nd, 2-Run Dupe, 3-S&P 1st, 4-S&P 2nd + WORD m_QSOMacroKey[5]; + AnsiString m_QSOMacroStr[5]; + + AnsiString m_THRTTY; + AnsiString m_THSSTV; + AnsiString m_THGMSK; + int m_THTZ; + int m_ClipRSTADIF; + int m_DateType; + + int m_Backup; // バックアップ作成 + + BYTE m_Hamlog5Len[17]; +}LOGSET; + +#define MLCALL 16 /* コールサインの長さ */ +#define MLRST 20 /* RSTナンバの長さ */ +#define MLREM 56 /* 記事の長さ */ +#define MLNAME 16 /* 名前の長さ */ +#define MLQTH 28 /* QTHの長さ */ +#define MLQSL 54 /* QSLの長さ */ +#define MLPOW 4 /* 電力 */ +#define MLOPT 8 /* オプション */ + +#define MODEMAX 48 + +#define YEAR(c) (((c)<50)?(2000+(c)):(1900+(c))) + +#pragma option -a- // パックの指示 +typedef struct { /* MMLOGデータ形式 */ + BYTE year; /* 年 */ + WORD date; /* 日付 */ + WORD btime; /* 開始時刻 */ + WORD etime; /* 終了時刻 */ + char call[MLCALL+1]; /* コールサイン */ + char ur[MLRST+1]; /* T リポート */ + char my[MLRST+1]; /* R リポート */ + BYTE band; /* バンド */ + SHORT fq; /* 周波数 */ + BYTE mode; /* モード */ + char pow[MLPOW+1]; /* 電力 */ + char name[MLNAME+1]; /* 名前 */ + char qth[MLQTH+1]; /* QTH */ + char qsl[MLQSL+1]; /* QSL */ + char send; /* QSL 送信 */ + char recv; /* QSL 受信 */ + char cq; /* cq/call */ + WORD env; /* 自局環境 */ + char rem[MLREM+1]; /* 記事 */ + char opt1[MLOPT+1]; /* オプション */ + char opt2[MLOPT+1]; /* オプション2 */ +}SDMMLOG; + +#define FHDOFF 256 /* 先頭のヘッダのオフセット */ +#define UMODEMAX 32 +typedef struct { + char id[20]; /* ファイルバージョン */ + char dmy[4]; /* ダミー領域 */ + USHORT mlt; /* マルチ情報のサイズ */ + char td; /* 時差コード */ + char hash; /* ハッシュデータ格納フラグ */ + long size; /* データサイズ */ + char master; /* マスターファイルフラグ */ + char dm2[15]; /* ダミー2 */ + char mode[UMODEMAX][6]; /* ユーザ定義モード */ +}FHD; +#pragma option -a. // パック解除の指示 + +class CIndex +{ +private: + int m_IndexMax; // 確保中のインデックスの数 + int m_IndexCnt; // 現在のインデックスの数 + LPSTR pIndex; // インデックス領域のポインタ(16バイトインデックス) + BYTE *pMult; // マルチ情報のポインタ +public: + __fastcall CIndex(); + __fastcall ~CIndex(); + void __fastcall AllocIndex(int n); + void __fastcall ClearIndex(void); + void __fastcall WriteIndex(LPCSTR pCall, int n); + void __fastcall ReadIndex(LPSTR pCall, int n); + LPSTR __fastcall PointIndex(int n); + void __fastcall AddBlock(LPCSTR p, int len); + int __fastcall ReadIndex(int handle, FHD *hp); + void __fastcall MakeIndex(int handle, FHD *hp); + int __fastcall WriteIndex(int handle, FHD *hp); +}; + +#define FINDMAX 32768 +class CLogFind +{ +public: + int m_FindCnt; + int m_FindCmp1Max; + int m_FindCmp2Max; + int m_FindStr1Max; + int m_FindStr2Max; + + int *pFindTbl; + AnsiString m_FindStr; +public: + __fastcall CLogFind(); + __fastcall ~CLogFind(); + inline int __fastcall GetCount(void){return m_FindCnt;}; + inline void __fastcall Clear(void){ + m_FindCnt = m_FindCmp1Max = m_FindCmp2Max = m_FindStr1Max = m_FindStr2Max = 0; + }; + int __fastcall Add(int n); + void __fastcall Ins(int n); + + inline void __fastcall Write(int n){ + pFindTbl[m_FindCnt] = n; + m_FindCnt++; + }; + inline void __fastcall SetText(LPCSTR p){ + if( p != m_FindStr.c_str() ){ + m_FindStr = p; + } + }; + inline LPCSTR __fastcall GetText(void){ + return m_FindStr.c_str(); + }; + inline void __fastcall ClearText(void){ + m_FindStr = ""; + }; +}; + +class CLogFile +{ +private: + int m_Open; // オープンフラグ + int m_EditFlag; // 編集フラグ + int m_Handle; // ファイルハンドル + CIndex m_Index; // 現在オープン中のインデックス + FHD m_fhd; // 現在オープン中のファイルヘッダ + AnsiString m_Name; // ログファイルの名前 + char m_modebuf[8]; +public: + AnsiString m_FileName; // ログファイルの名前(フルパス) + + int m_CurNo; + int m_CurChg; + SDMMLOG m_sd; + SDMMLOG m_bak; + SDMMLOG m_asd; + + CLogFind m_Find; // カレント検索データ + LOGSET m_LogSet; +private: + void __fastcall SetHisRST(SDMMLOG *sp); + void __fastcall InitHeader(void); + +public: + __fastcall CLogFile(); + __fastcall ~CLogFile(); + + void __fastcall DoBackup(void); + + int __fastcall Open(LPCSTR pName, BOOL fNew); + int __fastcall Close(void); + + void __fastcall ReadIniFile(LPCSTR pKey, TMemIniFile *pIniFile); + void __fastcall WriteIniFile(LPCSTR pKey, TMemIniFile *pIniFile); + + void __fastcall MakeIndex(void); + + inline int __fastcall IsEdit(void){return m_EditFlag;}; + void __fastcall MakePathName(LPCSTR pName); + void __fastcall MakeName(LPCSTR pName); + inline LPCSTR __fastcall GetName(void){return m_Name.c_str();}; + + inline int __fastcall GetCount(void){return m_fhd.size;}; + inline int __fastcall IsOpen(void){return m_Open;}; + int __fastcall GetData(SDMMLOG *sp, int n); + int __fastcall PutData(SDMMLOG *sp, int n); + + LPCSTR __fastcall GetDateString(SDMMLOG *sp, int sw); + inline LPCSTR __fastcall GetDateString(SDMMLOG *sp){ return GetDateString(sp, m_LogSet.m_DateType); }; + LPCSTR __fastcall GetTimeString(WORD d); + + + LPCSTR __fastcall GetModeString(BYTE m); + void __fastcall SetMode(SDMMLOG *sp, LPCSTR s); + + LPCSTR __fastcall GetFreqString(BYTE b, short fq); + void __fastcall SetFreq(SDMMLOG *sp, LPCSTR p); + LPCSTR __fastcall GetOptStr(int n, SDMMLOG *sp); + void __fastcall SetOptStr(int n, SDMMLOG *sp, LPCSTR pOpt); + + void __fastcall CopyAF(void); + + void __fastcall SortDate(int bb, int eb); + int __fastcall FindSameBand(BOOL fMode); + int __fastcall FindSameDate(void); + + void __fastcall FindStrSet(CLogFind *fp, LPCSTR pCall); + int __fastcall FindCmpSet(CLogFind *fp, LPCSTR pCall); + int __fastcall FindClipSet(CLogFind *fp, LPCSTR pCall); + int __fastcall FindSet(CLogFind *fp, LPCSTR pCall); + int __fastcall Find(LPCSTR pCall, int b, int dir); + int __fastcall IsAlready(LPCSTR pCall); + void __fastcall DeleteAll(void); + void __fastcall DeleteLast(void); + void __fastcall Delete(int top, int end); + void __fastcall Insert(int n, SDMMLOG *sp); + + void __fastcall InitCur(void); + void __fastcall SetLastPos(void); + + int __fastcall ReadAscii(SDMMLOG *sp, LPSTR p); + +}; + +void __fastcall JSTtoUTC(int &Year, int &Mon, int &Day, int &Hour); +void __fastcall JSTtoUTC(SDMMLOG *sp); +void __fastcall UTCtoJST(int &Year, int &Mon, int &Day, int &Hour); +void __fastcall UTCtoJST(SDMMLOG *sp); +void __fastcall UTCtoJST(SYSTEMTIME *tp); +void __fastcall mBandToBand(SDMMLOG *sp, LPCSTR p); +LPCSTR __fastcall FreqTomBand(SDMMLOG *sp); +int __fastcall GetLMode(BYTE m); + +extern CLogFile Log; +extern const char MONN[]; +extern const char MONU[]; +#endif + diff --git a/LogList.cpp b/LogList.cpp new file mode 100644 index 0000000..7469f49 --- /dev/null +++ b/LogList.cpp @@ -0,0 +1,1018 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "LogList.h" +#include "QsoDlg.h" +#include "LogConv.h" +#include "LogSet.h" +#include "country.h" +#include "Main.h" +#include "InputWin.h" +#include "Hamlog5.h" +#include "TH5Len.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TLogListDlg *LogListDlg; +//--------------------------------------------------------------------- +__fastcall TLogListDlg::TLogListDlg(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + Grid->Font->Name = ((TForm *)AOwner)->Font->Name; + Grid->Font->Charset = ((TForm *)AOwner)->Font->Charset; + KFile->Caption = "File(&F)"; + KEdit->Caption = "Edit(&E)"; + KFind->Caption = "Find(&S)"; + KOpt->Caption = "Option(&O)"; + + KOpen->Caption = "Open LogData File(&O)..."; + KFlush->Caption = "Save data now(&M)"; + KReIndex->Caption = "Make Index"; + KMTextRead->Caption = "Load MMLOG TextFile(&R)..."; + KMTextWrite->Caption = "Save selected range to MMLOG TextFile(&W)..."; + KImport->Caption = "Import"; + KImportLog200->Caption = "Log200 File..."; + KImportHamlog->Caption = "Hamlog File..."; + KImportADIF->Caption = "ADIF File..."; + KExport->Caption = "Export selected range"; + KExportADIF->Caption = "ADIF File..."; + KExportLog200->Caption = "Log200 File..."; + KExportHamlog->Caption = "Hamlog File..."; + KExportCabrillo->Caption = "Cabrillo file..."; + KExit->Caption = "Return to MMVARI(&X)"; + + KDelCur->Caption = "Cut"; + KInsCur->Caption = "Insert"; + KSelAll->Caption = "Select All"; + KDelSel->Caption = "Delete selected range"; + KSortDate->Caption = "Sort(Date/Time)"; + + KTop->Caption = "Move Top"; + KBottom->Caption = "Move Last"; + KFindTop->Caption = "Search forward..."; + KFindBottom->Caption = "Search backward..."; + KFindConT->Caption = "Search forward again"; + KFindConB->Caption = "Search backward again"; + + KLogOpt->Caption = "Setup Logging..."; + } + + int CX = ::GetSystemMetrics(SM_CXFULLSCREEN); + int CY = ::GetSystemMetrics(SM_CYFULLSCREEN); + if( (CX < Width)||(CY < Height) ){ + Top = 0; + Left = 0; + Width = CX; + Height = CY; + } + m_DateWidth = Grid->ColWidths[0]; + FormCenter(this, CX, CY); + if( Owner != NULL ){ + WindowState = ((TForm *)Owner)->WindowState; + } + SetTimeZone(); + KExportCabrillo->Visible = FALSE; // Delete this function by JE3HHT on Sep.2010 +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::SetTimeZone(void) +{ + switch(Log.m_LogSet.m_TimeZone){ + case 'I': + if( sys.m_LCID == 0x0412 ){ + m_TimeZone = "KST"; + } + else { + m_TimeZone = "JST"; + } + break; + default: + m_TimeZone = "UTC"; + break; + } + if(Log.m_LogSet.m_DateType & 1){ + Grid->ColWidths[0] = (m_DateWidth * 10) / 8; + } + else { + Grid->ColWidths[0] = m_DateWidth; + } +} +//--------------------------------------------------------------------------- +// アイドル処理 +void __fastcall TLogListDlg::OnIdle(TObject *Sender, bool &Done) +{ + UpdateMenu(); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::UpdateLogCount(int sw) +{ + Grid->RowCount = Log.GetCount() + 2; + + if( sw ){ + Grid->Row = Log.GetCount() + 1; + AdjustTopRow(); + char bf[256]; + if( Log.IsOpen() ){ + sprintf(bf, sys.m_MsgEng ? "%s - [%u QSO data(s)]" : "%s - [%u件のデータがあります]", Log.m_FileName.c_str(), Log.GetCount()); + } + else { + sprintf(bf, "%s is not opened.", Log.m_FileName.c_str()); + } + Caption = bf; + } + Grid->Col = 0; + Grid->Invalidate(); +} + +void __fastcall TLogListDlg::AdjustTopRow(void) +{ + int GridLine = Grid->GridHeight/Grid->RowHeights[1] - 1; + int Top = Grid->Row - GridLine + 1; + if( Top < 1 ) Top = 1; + Grid->TopRow = Top; + Grid->Invalidate(); +} + +void __fastcall TLogListDlg::Execute(void) +{ + if( !Log.IsOpen() ){ + Log.Open(NULL, TRUE); + } + Application->OnIdle = OnIdle; + UpdateLogCount(1); + ShowModal(); + Application->OnIdle = NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::GridDrawCell(TObject *Sender, int Col, + int Row, TRect &Rect, TGridDrawState State) +{ + + char bf[256]; + SDMMLOG sd; + + Grid->Canvas->FillRect(Rect); + int X = Rect.Left + 4; + int Y = Rect.Top + 2; + + if( Row ){ + Row--; + bf[0] = 0; + if( Row < Log.GetCount() ){ + Log.GetData(&sd, Row); + } + else { + memset(&sd, 0, sizeof(SDMMLOG)); + } + if( Log.m_LogSet.m_TimeZone != 'I' ){ + JSTtoUTC(&sd); + } + switch(Col){ + case 0: // Date + OnWave(); + strcpy(bf, Log.GetDateString(&sd)); + break; + case 1: // Time + strcpy(bf, Log.GetTimeString(sd.btime)); + break; + case 2: // Call + strcpy(bf, sd.call); + break; + case 3: // M + bf[0] = sd.cq; + bf[1] = 0; + break; + case 4: // HisRST + strcpy(bf, sd.ur); + break; + case 5: // MyRST + strcpy(bf, sd.my); + break; + case 6: // Band + strcpy(bf, Log.GetFreqString(sd.band, sd.fq)); + break; + case 7: // Mode + strcpy(bf, Log.GetModeString(sd.mode)); + break; + case 8: // Pow + strcpy(bf, sd.pow); + break; + case 9: // Name + strcpy(bf, sd.name); + break; + case 10: // QTH + strcpy(bf, sd.qth); + break; + case 11: // S + bf[0] = sd.send; + bf[1] = 0; + break; + case 12: // R + bf[0] = sd.recv; + bf[1] = 0; + break; + case 13: // REM + strcpy(bf, sd.rem); + break; + case 14: // QSL + strcpy(bf, sd.qsl); + break; + case 15: // etime; + strcpy(bf, Log.GetTimeString(sd.etime)); + break; + case 16: // Env + if( sd.env ) sprintf(bf, "%u", sd.env); + break; + case 17: // Opt1 + strcpy(bf, sd.opt1); + break; + case 18: // Opt2 + strcpy(bf, sd.opt2); + break; + case 19: // Usr1 + strcpy(bf, Log.GetOptStr(2, &sd)); + break; + case 20: // Usr2 + strcpy(bf, Log.GetOptStr(3, &sd)); + break; + } + Grid->Canvas->TextRect(Rect, X, Y, bf); + } + else { // タイトル + LPCSTR _tt[]={ + "Date","JST","Call","M", "His","My","Band","Mode","Pow","Name","QTH","S","R", + "Note","QSL", "End", "Env", "Opt1", "Opt2", "Usr1", "Usr2", + }; + if( Col == 1 ){ + Grid->Canvas->TextRect(Rect, X, Y, m_TimeZone.c_str()); + } + else { + Grid->Canvas->TextRect(Rect, X, Y, _tt[Col]); + } + } +} +//--------------------------------------------------------------------------- +// リターンキーの処理 +void __fastcall TLogListDlg::GridKeyPress(TObject *Sender, char &Key) +{ + if( Key == 0x0d ){ + GridDblClick(NULL); + Key = 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::UpdateMenu(void) +{ + int f = Log.IsOpen(); + KFlush->Enabled = f && Log.IsEdit(); + KDelCur->Enabled = f && (Grid->Row <= Log.GetCount()) && (Grid->Row >= 1); + KInsCur->Enabled = f && (Grid->Row <= Log.GetCount()) && (Grid->Row >= 1); + KDelSel->Enabled = f && (Grid->Selection.Top < Grid->Selection.Bottom); + KTop->Enabled = f && Log.GetCount(); + KBottom->Enabled = f && Log.GetCount(); + KFindTop->Enabled = f && Log.GetCount(); + KFindBottom->Enabled = f && Log.GetCount(); + KFindConT->Enabled = f && Log.GetCount(); + KFindConB->Enabled = f && Log.GetCount(); + KSortDate->Enabled = f && Log.GetCount() && (Grid->Selection.Top < Grid->Selection.Bottom); + KSelAll->Enabled = f && Log.GetCount(); + KMTextRead->Enabled = f; + KMTextWrite->Enabled = f && Log.GetCount() && (Grid->Selection.Top <= Log.GetCount()); + KExport->Enabled = f && Log.GetCount() && (Grid->Selection.Top <= Log.GetCount()); + KReIndex->Enabled = f; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KOpenClick(TObject *Sender) +{ +#if 1 + MainVARI->KFLOClick(NULL); + UpdateLogCount(1); +#else + OpenDialog->Options >> ofCreatePrompt; + OpenDialog->Options >> ofFileMustExist; + if(MsgEng){ + OpenDialog->Title = "Open LogData File"; + OpenDialog->Filter = "MMLOG Data File(*.mdt)|*.mdt|"; + } + else { + OpenDialog->Title = "ログファイルのオープン"; + OpenDialog->Filter = "MMLOG Data File(*.mdt)|*.mdt|"; + } + OpenDialog->FileName = ""; + OpenDialog->DefaultExt = "mdt"; + OpenDialog->InitialDir = MMLogDir; + NormalWindow(this); + if( OpenDialog->Execute() == TRUE ){ + Log.Close(); + Log.MakeName(OpenDialog->FileName.c_str()); + Log.Open(NULL, TRUE); + UpdateLogCount(1); + } + TopWindow(this); +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KFlushClick(TObject *Sender) +{ + Log.Close(); + Log.Open(NULL, TRUE); + UpdateLogCount(0); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KDelCurClick(TObject *Sender) +{ + int n = Grid->Row - 1; + SDMMLOG sd; + Log.GetData(&sd, n); + memcpy(&Log.m_bak, &sd, sizeof(SDMMLOG)); + Log.Delete(n, n); + UpdateLogCount(0); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KInsCurClick(TObject *Sender) +{ + int n = Grid->Row - 1; + Log.Insert(n, &Log.m_bak); + UpdateLogCount(0); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KDelSelClick(TObject *Sender) +{ + if( YesNoMB( sys.m_MsgEng ? "Delete Selection.(will not be able to restore) Are you sure?":"現在選択されている範囲を削除します.削除した内容は復元できません\r\n\r\nよろしおまっか?") == IDYES ){ + int top = Grid->Selection.Top - 1; + int end = Grid->Selection.Bottom - 1; + Log.Delete(top, end); + UpdateLogCount(0); + Grid->Row = top + 1; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KExitClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KFindTopClick(TObject *Sender) +{ + if( m_FindCall.IsEmpty() || (Sender == KFindTop) ){ + AnsiString as = m_FindCall; + if( InputMB(NULL, sys.m_MsgEng ? "Callsign":"検索するコールサイン", as) == FALSE ) return; + jstrupr(as.c_str()); + m_FindCall = as; + } + int n = Log.Find(m_FindCall.c_str(), Grid->Row, 0); + if( n >= 0 ){ + Grid->Row = n + 1; + } + else { + WarningMB(sys.m_MsgEng ? "'%s' was not found" : "'%s'は見つかりませんでした.", m_FindCall.c_str()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KFindBottomClick(TObject *Sender) +{ + if( m_FindCall.IsEmpty() || (Sender == KFindBottom) ){ + AnsiString as = m_FindCall; + if( InputMB(NULL, sys.m_MsgEng ? "Callsign":"検索するコールサイン", as) == FALSE ) return; + jstrupr(as.c_str()); + m_FindCall = as; + } + int n = Log.Find(m_FindCall.c_str(), Grid->Row - 2, 1); + if( n >= 0 ){ + Grid->Row = n + 1; + } + else { + WarningMB(sys.m_MsgEng ? "'%s' was not found" : "'%s'は見つかりませんでした.", m_FindCall.c_str()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KTopClick(TObject *Sender) +{ + Grid->Row = 1; + Grid->TopRow = 1; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KBottomClick(TObject *Sender) +{ + Grid->Row = Log.GetCount() + 1; + AdjustTopRow(); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KSortDateClick(TObject *Sender) +{ + if( YesNoMB( sys.m_MsgEng ? "It may take substantial time. Are you sure?":"この処理はメチャンコ時間がかかるかも知れません.\r\n\r\nよろしおまっか?" ) == IDYES ){ + int top = Grid->Selection.Top - 1; + int end = Grid->Selection.Bottom - 1; + if( top == end ){ + top = 0; + end = Log.GetCount() - 1; + } + Log.SortDate(top, end); + Grid->Invalidate(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::GridDblClick(TObject *Sender) +{ + int n = Grid->Row - 1; + if( (n >= 0) && (n < Log.GetCount()) ){ + TQSODlgBox *pBox = new TQSODlgBox(this); + SDMMLOG sd; + Log.GetData(&sd, n); + CLogFind Find; + + Log.FindSet(&Find, sd.call); + + pBox->Execute(&Find, &sd, n); + Grid->Invalidate(); + delete pBox; + } +} +//--------------------------------------------------------------------------- +// MMLOGテキストファイルのロード +void __fastcall TLogListDlg::KMTextReadClick(TObject *Sender) +{ + OpenDialog->Options >> ofCreatePrompt; + OpenDialog->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + OpenDialog->Title = "Load MMLOG Text file"; + OpenDialog->Filter = "MMLOG Text Files(*.log)|*.log|"; + } + else { + OpenDialog->Title = "MMLOGテキストファイルのロード"; + OpenDialog->Filter = "MMLOGテキストファイル(*.log)|*.log|"; + } + OpenDialog->FileName = ""; + OpenDialog->DefaultExt = "log"; + OpenDialog->InitialDir = sys.m_LogDir; + if( OpenDialog->Execute() == TRUE ){ + LoadMmlogText(AnsiString(OpenDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KMTextWriteClick(TObject *Sender) +{ + SaveDialog->Options << ofOverwritePrompt; + if( sys.m_MsgEng ){ + SaveDialog->Title = "Save MMLOG Text File"; + SaveDialog->Filter = "MMLOG Text Files(*.log)|*.log|"; + } + else { + SaveDialog->Title = "MMLOGテキストファイルの作成"; + SaveDialog->Filter = "MMLOGテキストファイル(*.log)|*.log|"; + } + char bf[256]; + strcpy(bf, Log.GetName()); + SetEXT(bf, ".log"); + SaveDialog->FileName = bf; + SaveDialog->DefaultExt = "log"; + SaveDialog->InitialDir = sys.m_LogDir; + if( SaveDialog->Execute() == TRUE ){ + SaveMmlogText(AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SureRead(void) +{ + int r; + if( sys.m_MsgEng ){ + r = YesNoCancelMB("MMVARI has QSO data(s) already. Add QSO data from file?\r\n\r\n\tAdded to the end\r\n\tOverwrite\r\n\t(All the current data are deleted, and replaced by the read data)\r\n\tAbort this function"); + } + else { + r = YesNoCancelMB("現在MMVARIにログデータが存在します. 追加読みこみしますか?\r\n\r\n<はい>\t現在のログデータの最後に読み込んだデータが追加される.\r\n<いいえ>\t現在のログデータは全て削除され読み込んだデータに置き換わる.\r\n<キャンセル>\t処理中止"); + } + switch(r){ + case IDCANCEL: + return 0; + case IDNO: + if( sys.m_MsgEng ){ + r = OkCancelMB("Delete All QSO data(s)...(will not be able to restore) Are you sure?"); + } + else { + r = OkCancelMB("現在MMVARIが保持しているログデータを全て失います.\r\n\r\nほんまにええでっか?"); + } + switch(r){ + case IDOK: + Log.DeleteAll(); + break; + case IDCANCEL: + return 0; + } + break; + default: + break; + } + return 1; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::LoadMmlogText(LPCSTR pName) +{ + char bf[1024]; + + if( Log.GetCount() ){ + if( !SureRead() ) return; + } + FILE *fp = fopen(pName, "rt"); + if( fp != NULL ){ + int r = IDNO; + if( sys.m_MsgEng ){ + r = YesNoMB("This function exists for compatibility with old software which handle JST.\r\n\r\nAre recorded data UTC?"); + } + CWaitCursor w; + SDMMLOG sd; + while(!feof(fp)){ + if( fgets(bf, 1023, fp) != NULL ){ + ClipLF(bf); + if( bf[0] ){ + if( Log.ReadAscii(&sd, bf) == TRUE ){ + if( r == IDYES ) UTCtoJST(&sd); + Log.PutData(&sd, Log.GetCount()); + } + } + } + } + fclose(fp); + } + else { + ErrorMB(sys.m_MsgEng ? "Can't open '%s'" : "'%s'が見つかりません.", pName); + } + UpdateLogCount(1); +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::SaveMmlogText(LPCSTR pName) +{ + FILE *fp = fopen(pName, "wt"); + if( fp != NULL ){ + int r = IDNO; + if( sys.m_MsgEng ){ + r = YesNoMB("This function exists for compatibility with old software which handle JST.\r\n\r\nDo you want UTC?"); + } + SDMMLOG sd; + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + int i; + CWaitCursor w; + for( i = b; i <= e; i++ ){ + Log.GetData(&sd, i); + if( r == IDYES ) JSTtoUTC(&sd); + fprintf(fp, "\042%s\042,\042%s.%02u\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,", + Log.GetDateString(&sd, 0), + Log.GetTimeString(sd.btime), (sd.btime % 30 * 2), + sd.call, sd.ur, sd.my, + Log.GetFreqString(sd.band, sd.fq) + ); + + fprintf(fp, "\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,", + Log.GetModeString(sd.mode), + sd.pow, sd.name, sd.qth, sd.rem, sd.qsl + ); + fprintf(fp, "\042%s\042,\042%.1s\042,\042%.1s\042,\042%.1s\042,\042%u\042,", + Log.GetTimeString(sd.etime), + &sd.send, &sd.recv, &sd.cq, sd.env + ); + fprintf(fp, "\042%s\042,\042%s\042,", sd.opt1, sd.opt2 ); + fprintf(fp, "\042%s\042,", Log.GetOptStr(2, &sd)); + fprintf(fp, "\042%s\042\n", Log.GetOptStr(3, &sd)); + if( ferror(fp) ) break; + } + if( fclose(fp) ){ + ErrorMB( sys.m_MsgEng ? "Can't save to '%s'" : "'%s'が正しく作成できませんでした.", pName); + } + } + else { + ErrorMB(sys.m_MsgEng ? "Can't save to '%s'" : "'%s'が作成できません.", pName); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KSelAllClick(TObject *Sender) +{ + TGridRect gRect; + gRect.Top = 1; + gRect.Bottom = Grid->RowCount - 1; + gRect.Left = 0; + gRect.Right = 20; + + Grid->Selection = gRect; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KReIndexClick(TObject *Sender) +{ + Log.MakeIndex(); +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::LoadLog200(LPCSTR pName) +{ + if( Log.GetCount() ){ + if( !SureRead() ) return FALSE; + } + + CLog200 log200; + if( log200.Open(pName) ){ + SDMMLOG sd; + CWaitCursor w; + while(log200.Read(&sd)==TRUE){ + Log.PutData(&sd, Log.GetCount()); + } + log200.Close(); + } + else { + UpdateLogCount(1); + return FALSE; + } + UpdateLogCount(1); + return TRUE; +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SaveLog200(LPCSTR pName) +{ + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + + CLog200 log200; + if( log200.Create(pName) ){ + SDMMLOG sd; + int i; + CWaitCursor w; + for( i = b; i <= e; i++ ){ + Log.GetData(&sd, i); + if( log200.Write(&sd) == FALSE ) break; + } + log200.Close(); + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KExportLog200Click(TObject *Sender) +{ + SaveDialog->Options << ofOverwritePrompt; + if( sys.m_MsgEng ){ + SaveDialog->Title = "Save LOG200 Data file"; + SaveDialog->Filter = "LOG200 Data File(*.l2)|*.l2|"; + } + else { + SaveDialog->Title = "LOG200データファイルの作成"; + SaveDialog->Filter = "LOG200データファイル(*.l2)|*.l2|"; + } + char bf[256]; + strcpy(bf, Log.GetName()); + SetEXT(bf, ".l2"); + SaveDialog->FileName = bf; + SaveDialog->DefaultExt = "l2"; + SaveDialog->InitialDir = sys.m_ExtLogDir; + if( SaveDialog->Execute() == TRUE ){ + SaveLog200(AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + SetDirName(sys.m_ExtLogDir, AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KImportLog200Click(TObject *Sender) +{ + OpenDialog->Options >> ofCreatePrompt; + OpenDialog->Options >> ofFileMustExist; + if( sys.m_MsgEng ){ + OpenDialog->Title = "Load LOG200 Data File"; + OpenDialog->Filter = "LOG200 Data File(*.l2)|*.l2|"; + } + else { + OpenDialog->Title = "LOG200データファイルのロード"; + OpenDialog->Filter = "LOG200データファイル(*.l2)|*.l2|"; + } + OpenDialog->FileName = ""; + OpenDialog->DefaultExt = "l2"; + OpenDialog->InitialDir = sys.m_ExtLogDir; + if( OpenDialog->Execute() == TRUE ){ + LoadLog200(AnsiString(OpenDialog->FileName).c_str()); //JA7UDE 0428 + SetDirName(sys.m_ExtLogDir, AnsiString(OpenDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::LoadHamLog(LPCSTR pName) +{ + if( Log.GetCount() ){ + if( !SureRead() ) return FALSE; + } + + CHamLog HamLog; + if( HamLog.Open(pName) ){ + SDMMLOG sd; + CWaitCursor w; + while(HamLog.Read(&sd)==TRUE){ + Log.PutData(&sd, Log.GetCount()); + } + HamLog.Close(); + } + else { + UpdateLogCount(1); + return FALSE; + } + UpdateLogCount(1); + return TRUE; +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::LoadHamLog5(LPCSTR pName) +{ + if( Log.GetCount() ){ + if( !SureRead() ) return FALSE; + } + + CHamlog5 HamLog; + if( HamLog.Open(pName, TRUE) ){ + SDMMLOG sd; + CWaitCursor w; + DWORD Pos; + for( Pos = 0; Pos < HamLog.GetRCount(); Pos++ ){ + if( HamLog.Seek(Pos) ){ + HamLog.DecodeData(&sd); + Log.PutData(&sd, Log.GetCount()); + } + } + HamLog.Close(); + } + else { + UpdateLogCount(1); + return FALSE; + } + UpdateLogCount(1); + return TRUE; +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SaveHamLog(LPCSTR pName) +{ + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + + CHamLog HamLog; + if( HamLog.Create(pName) ){ + SDMMLOG sd; + int i; + CWaitCursor w; + for( i = b; i <= e; i++ ){ + Log.GetData(&sd, i); + if( HamLog.Write(&sd) == FALSE ) break; + } + HamLog.Close(); + } + return TRUE; +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SaveHamLog5(LPCSTR pName) +{ + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + + + char master[256]; + SetDirName(master, pName); + strcat(master, "HAMLOG.HDB"); + CHamlog5 HamLog; + if( HamLog.Open(master, FALSE) ){ // フィールド情報を読み込む + HamLog.Close(); + } + else { // フィールド情報を問い合わせ + TTH5LenDlg *pBox = new TTH5LenDlg(this); + if( !pBox->Execute() ){ + return FALSE; + } + } + + if( HamLog.Create(pName) ){ + SDMMLOG sd; + int i; + int n = 0; + CWaitCursor w; + for( i = b; i <= e; i++, n++ ){ + Log.GetData(&sd, i); + HamLog.Seek(n); + HamLog.EncodeData(&sd); + if( HamLog.Update() == FALSE ) break; + } + HamLog.Close(); + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KImportHamlogClick(TObject *Sender) +{ + OpenDialog->Options >> ofCreatePrompt; + OpenDialog->Options >> ofFileMustExist; + if( sys.m_MsgEng ){ + OpenDialog->Title = "Load HamLog Data File"; + OpenDialog->Filter = "HamLog Data File(*.hdb;*.dbs)|*.hdb;*.dbs|"; + } + else { + OpenDialog->Title = "HamLogデータファイルのロード"; + OpenDialog->Filter = "HamLogデータファイル(*.hdb;*.dbs)|*.hdb;*.dbs|"; + } + OpenDialog->FileName = ""; + OpenDialog->DefaultExt = "hdb"; + OpenDialog->InitialDir = sys.m_ExtLogDir; + if( OpenDialog->Execute() == TRUE ){ + LPCSTR pName = AnsiString(OpenDialog->FileName).c_str(); //JA7UDE 0428 + if( !strcmpi(GetEXT(pName), "HDB") ){ + LoadHamLog5(pName); + } + else { + LoadHamLog(pName); + } + SetDirName(sys.m_ExtLogDir, pName); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KExportHamlogClick(TObject *Sender) +{ + SaveDialog->Options << ofOverwritePrompt; + if( sys.m_MsgEng ){ + SaveDialog->Title = "Save HAMLOG Data File"; + SaveDialog->Filter = "HAMLOG (Ver5) Data File(*.hdb)|*.hdb|HAMLOG Data File(*.dbs)|*.dbs|"; + } + else { + SaveDialog->Title = "HAMLOGデータファイルの作成"; + SaveDialog->Filter = "HAMLOG (Ver5) データファイル(*.hdb)|*.hdb|HAMLOGデータファイル(*.dbs)|*.dbs|"; + } + char bf[256]; + strcpy(bf, Log.GetName()); + SetEXT(bf, ".hdb"); + SaveDialog->FileName = bf; + SaveDialog->DefaultExt = "hdb"; + SaveDialog->InitialDir = sys.m_ExtLogDir; + if( SaveDialog->Execute() == TRUE ){ + LPCSTR pName = AnsiString(SaveDialog->FileName).c_str(); //JA7UDE 0428 + if( !strcmpi(GetEXT(pName), "HDB") ){ + SaveHamLog5(pName); + } + else { + SaveHamLog(pName); + } + SetDirName(sys.m_ExtLogDir, pName); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KLogOptClick(TObject *Sender) +{ + TLogSetDlg *pBox = new TLogSetDlg(this); + pBox->Execute(); + delete pBox; + SetTimeZone(); + Grid->Invalidate(); +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SaveADIF(LPCSTR pName) +{ + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + + CLogADIF logADIF; + if( logADIF.Create(pName) ){ + SDMMLOG sd; + int i; + CWaitCursor w; + for( i = b; i <= e; i++ ){ + Log.GetData(&sd, i); + if( logADIF.Write(&sd) == FALSE ) break; + } + logADIF.Close(); + } + return TRUE; +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::LoadADIF(LPCSTR pName) +{ + if( Log.GetCount() ){ + if( !SureRead() ) return FALSE; + } + + CLogADIF logADIF; + if( logADIF.Open(pName) ){ + SDMMLOG sd; + memset(&sd, 0, sizeof(sd)); + CWaitCursor w; + while(logADIF.Read(&sd)==TRUE){ + Log.PutData(&sd, Log.GetCount()); + memset(&sd, 0, sizeof(sd)); + } + logADIF.Close(); + } + else { + UpdateLogCount(1); + return FALSE; + } + UpdateLogCount(1); + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KExportADIFClick(TObject *Sender) +{ + SaveDialog->Options << ofOverwritePrompt; + if( sys.m_MsgEng ){ + SaveDialog->Title = "Save ADIF File"; + SaveDialog->Filter = "ADIF Files(*.adi)|*.adi|"; + } + else { + SaveDialog->Title = "ADIF ファイルの作成"; + SaveDialog->Filter = "ADIF ファイル(*.adi)|*.adi|"; + } + char bf[256]; + strcpy(bf, Log.GetName()); + SetEXT(bf, ".adi"); + SaveDialog->FileName = bf; + SaveDialog->DefaultExt = "adi"; + SaveDialog->InitialDir = sys.m_ExtLogDir; + if( SaveDialog->Execute() == TRUE ){ + SaveADIF(AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + SetDirName(sys.m_ExtLogDir, AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KImportADIFClick(TObject *Sender) +{ + OpenDialog->Options >> ofCreatePrompt; + OpenDialog->Options >> ofFileMustExist; + if( sys.m_MsgEng ){ + OpenDialog->Title = "Load ADIF File"; + OpenDialog->Filter = "ADIF Files(*.adi;*.txt)|*.adi;*.txt|"; + } + else { + OpenDialog->Title = "ADIF ファイルのロード"; + OpenDialog->Filter = "ADIF ファイル(*.adi;*.txt)|*.adi;*.txt|"; + } + OpenDialog->FileName = ""; + OpenDialog->DefaultExt = "adi"; + OpenDialog->InitialDir = sys.m_ExtLogDir; + if( OpenDialog->Execute() == TRUE ){ + LoadADIF(AnsiString(OpenDialog->FileName).c_str()); //JA7UDE 0428 + SetDirName(sys.m_ExtLogDir, AnsiString(OpenDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- +int __fastcall TLogListDlg::SaveCabrillo(LPCSTR pName) +{ + int b = Grid->Selection.Top - 1; + int e = Grid->Selection.Bottom - 1; + if( e >= Log.GetCount() ) e--; + + CLogCabrillo logCabrillo; + if( logCabrillo.Create(pName) ){ + SDMMLOG sd; + int i; + CWaitCursor w; + for( i = b; i <= e; i++ ){ + Log.GetData(&sd, i); + if( logCabrillo.Write(&sd) == FALSE ) break; + } + logCabrillo.Close(); + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TLogListDlg::KExportCabrilloClick(TObject *Sender) +{ + SaveDialog->Options << ofOverwritePrompt; + if( sys.m_MsgEng ){ + SaveDialog->Title = "Save Cabrillo File"; + SaveDialog->Filter = "Cabrillo Files(*.txt)|*.txt|"; + } + else { + SaveDialog->Title = "Cabrillo ファイルの作成"; + SaveDialog->Filter = "Cabrillo ファイル(*.txt)|*.txt|"; + } + char bf[256]; + strcpy(bf, Log.GetName()); + SetEXT(bf, ".txt"); + SaveDialog->FileName = bf; + SaveDialog->DefaultExt = "txt"; + SaveDialog->InitialDir = sys.m_ExtLogDir; + if( SaveDialog->Execute() == TRUE ){ + SaveCabrillo(AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + SetDirName(sys.m_ExtLogDir, AnsiString(SaveDialog->FileName).c_str()); //JA7UDE 0428 + } +} +//--------------------------------------------------------------------------- + + diff --git a/LogList.dfm b/LogList.dfm new file mode 100644 index 0000000..eb24d07 Binary files /dev/null and b/LogList.dfm differ diff --git a/LogList.h b/LogList.h new file mode 100644 index 0000000..81d7fb8 --- /dev/null +++ b/LogList.h @@ -0,0 +1,150 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef LogListH +#define LogListH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +//---------------------------------------------------------------------------- +#include "LogFile.h" +#include //JA7UDE 0428 +#include +#include +//---------------------------------------------------------------------------- +class TLogListDlg : public TForm +{ +__published: + TStringGrid *Grid; + TMainMenu *MainMenu; + TMenuItem *KFile; + TMenuItem *KOpen; + TOpenDialog *OpenDialog; + TMenuItem *KEdit; + TMenuItem *KFlush; + TMenuItem *KDelCur; + TMenuItem *KDelSel; + TMenuItem *N1; + TMenuItem *KExit; + TMenuItem *KFind; + TMenuItem *KFindTop; + TMenuItem *KFindBottom; + TMenuItem *KFindConT; + TMenuItem *KFindConB; + TMenuItem *N2; + TMenuItem *KTop; + TMenuItem *KBottom; + TMenuItem *N3; + TMenuItem *KSortDate; + TMenuItem *KInsCur; + TMenuItem *N4; + TMenuItem *N5; + TMenuItem *KMTextRead; + TMenuItem *KMTextWrite; + TSaveDialog *SaveDialog; + TMenuItem *KSelAll; + TMenuItem *N6; + TMenuItem *KReIndex; + TMenuItem *N7; + TMenuItem *KExport; + TMenuItem *KImport; + TMenuItem *KImportLog200; + TMenuItem *KExportLog200; + TMenuItem *KImportHamlog; + TMenuItem *KExportHamlog; + TMenuItem *KLogOpt; + TMenuItem *KOpt; + TMenuItem *KExportADIF; + TMenuItem *KImportADIF; + TMenuItem *KExportCabrillo;void __fastcall GridKeyPress(TObject *Sender, char &Key); + void __fastcall KOpenClick(TObject *Sender); + void __fastcall KFlushClick(TObject *Sender); + void __fastcall KDelCurClick(TObject *Sender); + void __fastcall KDelSelClick(TObject *Sender); + void __fastcall KExitClick(TObject *Sender); + void __fastcall KFindTopClick(TObject *Sender); + void __fastcall KFindBottomClick(TObject *Sender); + void __fastcall KTopClick(TObject *Sender); + void __fastcall KBottomClick(TObject *Sender); + void __fastcall KSortDateClick(TObject *Sender); + + void __fastcall GridDblClick(TObject *Sender); + void __fastcall KInsCurClick(TObject *Sender); + void __fastcall KMTextReadClick(TObject *Sender); + void __fastcall KMTextWriteClick(TObject *Sender); + void __fastcall KSelAllClick(TObject *Sender); + void __fastcall KReIndexClick(TObject *Sender); + + void __fastcall KExportLog200Click(TObject *Sender); + void __fastcall KImportLog200Click(TObject *Sender); + void __fastcall KImportHamlogClick(TObject *Sender); + void __fastcall KExportHamlogClick(TObject *Sender); + void __fastcall KLogOptClick(TObject *Sender); + void __fastcall KExportADIFClick(TObject *Sender); + void __fastcall KImportADIFClick(TObject *Sender); + void __fastcall KExportCabrilloClick(TObject *Sender); + void __fastcall GridDrawCell(TObject *Sender, int Col, int Row, + TRect &Rect, TGridDrawState State); +private: + void __fastcall AdjustTopRow(void); + void __fastcall UpdateLogCount(int sw); + void __fastcall UpdateMenu(void); + void __fastcall OnIdle(TObject *Sender, bool &Done); + + int __fastcall SureRead(void); + + void __fastcall LoadMmlogText(LPCSTR pName); + void __fastcall SaveMmlogText(LPCSTR pName); + int __fastcall LoadLog200(LPCSTR pName); + int __fastcall SaveLog200(LPCSTR pName); + int __fastcall LoadHamLog(LPCSTR pName); + int __fastcall LoadHamLog5(LPCSTR pName); + int __fastcall SaveHamLog(LPCSTR pName); + int __fastcall SaveHamLog5(LPCSTR pName); + + int __fastcall LoadADIF(LPCSTR pName); + int __fastcall SaveADIF(LPCSTR pName); + + int __fastcall SaveCabrillo(LPCSTR pName); + + AnsiString m_FindCall; + + void __fastcall SetTimeZone(void); + AnsiString m_TimeZone; + int m_DateWidth; +public: + virtual __fastcall TLogListDlg(TComponent* AOwner); + + void __fastcall TLogListDlg::Execute(void); +}; +//---------------------------------------------------------------------------- +//extern TLogListDlg *LogListDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/LogSet.cpp b/LogSet.cpp new file mode 100644 index 0000000..4b4e11b --- /dev/null +++ b/LogSet.cpp @@ -0,0 +1,253 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "LogSet.h" +#include "country.h" +#include "Loglink.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TLogSetDlg *LogSetDlg; +static int PageIndex = 0; +//--------------------------------------------------------------------- +__fastcall TLogSetDlg::TLogSetDlg(TComponent* AOwner) + : TForm(AOwner) +{ + m_DisEvent = 1; + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + TabConv->Caption = "Conversion"; + TabMisc->Caption = "Misc"; + CancelBtn->Caption = "Cancel"; + Caption = "Setup Logging"; + TabFlag->Caption = "Input"; + GrpConv->Caption = "Convert UpperCase"; + GrpCopy->Caption = "Copy Before Data"; + CopyFreq->Caption = "Copy Band or Freq."; + CopyFreq->Items->Strings[0] = "Copy Band"; + CopyFreq->Items->Strings[1] = "Copy Freq."; + DefMyRST->Caption = "599 Default"; + + RGDupe->Caption = "Dupe Check (Show Red)"; + RGDupe->Items->Strings[0] = "Callsign only"; + RGDupe->Items->Strings[1] = "Hit on the same band"; + RGDupe->Items->Strings[2] = "Same band and same mode"; + AutoZone->Caption = "Ignore daylight saving"; + CBBackup->Caption = "Make backup"; + CBRemC->Visible = FALSE; + + GB3->Caption = "Link"; + RGLink->Caption = "Application"; + + GrpConv->Hint = ""; + GB1->Hint = ""; + RGLink->Hint = "Set linking Log program"; + CBPoll->Hint = "Get FREQ information from the Log program"; + CBPTT->Hint = "PTT controls via the Log program"; + GTime->Hint = ""; + AutoSave->Hint = "Flush(Save) Log file at the every QSO"; + CBBackup->Hint = ""; + RGDupe->Hint = ""; + + GB9->Caption = "Mode"; + } + else { + LLink->Caption = "Hamlogの環境設定-設定1で\r\n「交信履歴表示で一旦停止」のチェックは付けないで下さい."; + } + if( sys.m_LCID == 0x0412 ){ // LANG_KOREAN + TimeZone->Items->Strings[0] = "Korea"; + } + else { + TimeZone->Items->Strings[0] = "Japan"; + } + m_MMList.QueryList("MML"); + for( int i = 0; i < m_MMList.GetCount(); i++ ){ + CBMMLink->Items->Add(m_MMList.GetItemName(i)); + } + FormCenter(this); +} +//--------------------------------------------------------------------------- +void __fastcall TLogSetDlg::DisplayHint(TObject *Sender) +{ + LH->Caption = GetLongHint(Application->Hint); +} +//--------------------------------------------------------------------- +void __fastcall TLogSetDlg::UpdateUI(void) +{ + int f = !AutoZone->Checked; + TimeOff->Enabled = f; + MinOff->Enabled = f; + UDOffset->Enabled = f; + UDMin->Enabled = f; + ClearOff->Enabled = f; + CBPoll->Enabled = RGLink->ItemIndex ? TRUE : FALSE; + if( !sys.m_MsgEng ){ + LLink->Visible = (RGLink->ItemIndex == 1) ? TRUE : FALSE; + } + CBMMLink->Enabled = (RGLink->ItemIndex == 2) ? TRUE : FALSE; + LT->Enabled = CBMMLink->Enabled; +} +//--------------------------------------------------------------------- +int __fastcall TLogSetDlg::Execute(void) +{ +// int i; + UpperName->Checked = Log.m_LogSet.m_UpperName; + UpperQTH->Checked = Log.m_LogSet.m_UpperQTH; + UpperREM->Checked = Log.m_LogSet.m_UpperREM; + UpperQSL->Checked = Log.m_LogSet.m_UpperQSL; + + DefMyRST->Checked = Log.m_LogSet.m_DefMyRST; + + CopyFreq->ItemIndex = Log.m_LogSet.m_CopyFreq; + CopyHis->ItemIndex = Log.m_LogSet.m_CopyHis; + CopyName->Checked = Log.m_LogSet.m_CopyName; + CopyQTH->Checked = Log.m_LogSet.m_CopyQTH; + CopyREM->Checked = Log.m_LogSet.m_CopyREM; + CopyQSL->Checked = Log.m_LogSet.m_CopyQSL; + CBBackup->Checked = Log.m_LogSet.m_Backup; + CBRemC->Checked = Log.m_LogSet.m_CopyREMB4; + + if( Log.m_LogSet.m_TimeZone != 'I' ){ + TimeZone->ItemIndex = 1; + } + else { + TimeZone->ItemIndex = 0; + } + AutoSave->Checked = Log.m_LogSet.m_AutoSave; + RGDupe->ItemIndex = Log.m_LogSet.m_CheckBand; + + THRTTY->Text = Log.m_LogSet.m_THRTTY; + THSSTV->Text = Log.m_LogSet.m_THSSTV; + THGMSK->Text = Log.m_LogSet.m_THGMSK; + THTZ->ItemIndex = Log.m_LogSet.m_THTZ; + ClipRSTADIF->Checked = Log.m_LogSet.m_ClipRSTADIF; + DateType->ItemIndex = Log.m_LogSet.m_DateType; + AutoZone->Checked = sys.m_AutoTimeOffset; + UDOffset->Position = short(sys.m_TimeOffset); + UDMin->Position = short(sys.m_TimeOffsetMin); + RGLink->ItemIndex = sys.m_LogLink; + CBPoll->Checked = LogLink.IsPolling(); + CBPTT->Checked = LogLink.GetPTTEnabled(); + CBMMLink->ItemIndex = CBMMLink->Items->IndexOf(LogLink.GetItemName()); + if( m_MMList.GetCount() ){ + RGLink->Controls[2]->Enabled = TRUE; + if( CBMMLink->ItemIndex < 0 ){ + CBMMLink->ItemIndex = 0; + } + } + else { + RGLink->Controls[2]->Enabled = FALSE; + } + if( (PageIndex >= 0) && (PageIndex < Page->PageCount) ){ + if( Page->Pages[PageIndex]->TabVisible == FALSE ){ + PageIndex = 0; + } + Page->ActivePage = Page->Pages[PageIndex]; + } + UpdateUI(); + m_DisEvent = 0; + m_fnHintProc = Application->OnHint; + Application->OnHint = DisplayHint; + int r = ShowModal(); + Application->OnHint = m_fnHintProc; + PageIndex = GetActiveIndex(Page); + if( r == IDOK ){ + Log.m_LogSet.m_UpperName = UpperName->Checked; + Log.m_LogSet.m_UpperQTH = UpperQTH->Checked; + Log.m_LogSet.m_UpperREM = UpperREM->Checked; + Log.m_LogSet.m_UpperQSL = UpperQSL->Checked; + + Log.m_LogSet.m_DefMyRST = DefMyRST->Checked; + + Log.m_LogSet.m_CopyFreq = CopyFreq->ItemIndex; + Log.m_LogSet.m_CopyHis = CopyHis->ItemIndex; + Log.m_LogSet.m_CopyName = CopyName->Checked; + Log.m_LogSet.m_CopyQTH = CopyQTH->Checked; + Log.m_LogSet.m_CopyREM = CopyREM->Checked; + Log.m_LogSet.m_CopyQSL = CopyQSL->Checked; + Log.m_LogSet.m_CopyREMB4 = ( Font->Charset != SHIFTJIS_CHARSET ) ? 0 : CBRemC->Checked; + + if( TimeZone->ItemIndex ){ + Log.m_LogSet.m_TimeZone = 'Z'; + } + else { + Log.m_LogSet.m_TimeZone = 'I'; + } + + Log.m_LogSet.m_AutoSave = AutoSave->Checked; + Log.m_LogSet.m_CheckBand = RGDupe->ItemIndex; + + Log.m_LogSet.m_THRTTY = THRTTY->Text; + Log.m_LogSet.m_THSSTV = THSSTV->Text; + Log.m_LogSet.m_THGMSK = THGMSK->Text; + Log.m_LogSet.m_THTZ = THTZ->ItemIndex; + Log.m_LogSet.m_ClipRSTADIF = ClipRSTADIF->Checked; + Log.m_LogSet.m_DateType = DateType->ItemIndex; + Log.m_LogSet.m_Backup = CBBackup->Checked; + + sys.m_AutoTimeOffset = AutoZone->Checked; + sys.m_TimeOffset = UDOffset->Position; + sys.m_TimeOffsetMin = UDMin->Position; + if( sys.m_AutoTimeOffset ){ + SetTimeOffsetInfo(sys.m_TimeOffset, sys.m_TimeOffsetMin); + } + sys.m_LogLink = RGLink->ItemIndex; + LogLink.SetPolling(CBPoll->Checked); + LogLink.SetPTTEnabled(CBPTT->Checked); + if( CBMMLink->ItemIndex >= 0 ){ + LogLink.SetItemName(AnsiString(CBMMLink->Items->Strings[CBMMLink->ItemIndex]).c_str()); //JA7UDE 0428 + } + r = TRUE; + } + else { + r = FALSE; + } + return r; +} +//--------------------------------------------------------------------- +void __fastcall TLogSetDlg::ClearOffClick(TObject *Sender) +{ + UDOffset->Position = 0; + UDMin->Position = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TLogSetDlg::AutoZoneClick(TObject *Sender) +{ + if( AutoZone->Checked ){ + int hour, min; + SetTimeOffsetInfo(hour, min); + UDOffset->Position = short(hour); + UDMin->Position = short(min); + } + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TLogSetDlg::RGLinkClick(TObject *Sender) +{ + if( m_DisEvent ) return; + + UpdateUI(); +} +//--------------------------------------------------------------------------- + diff --git a/LogSet.dfm b/LogSet.dfm new file mode 100644 index 0000000..21d4fe0 Binary files /dev/null and b/LogSet.dfm differ diff --git a/LogSet.h b/LogSet.h new file mode 100644 index 0000000..177f34d --- /dev/null +++ b/LogSet.h @@ -0,0 +1,131 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef LogSetH +#define LogSetH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +//---------------------------------------------------------------------------- +#include "LogFile.h" +#include "MMLink.h" +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TLogSetDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TPageControl *Page; + TTabSheet *TabFlag; + TGroupBox *GrpConv; + TCheckBox *UpperName; + TCheckBox *UpperQTH; + TCheckBox *UpperREM; + TCheckBox *UpperQSL; + TGroupBox *GrpCopy; + TCheckBox *CopyName; + TCheckBox *CopyQTH; + TCheckBox *CopyREM; + TCheckBox *CopyQSL; + TRadioGroup *CopyHis; + TRadioGroup *CopyFreq; + TGroupBox *GB5; + TCheckBox *DefMyRST; + TRadioGroup *TimeZone; + TTabSheet *TabConv; + TGroupBox *GB1; + TGroupBox *GB2; + TCheckBox *ClipRSTADIF; + TTabSheet *TabMisc; + TGroupBox *GTime; + TEdit *TimeOff; + TUpDown *UDOffset; + TRadioGroup *DateType; + TEdit *MinOff; + TUpDown *UDMin; + TLabel *Label4; + TLabel *Label5; + TButton *ClearOff; + TCheckBox *AutoSave; + TCheckBox *AutoZone; + TGroupBox *GB3; + TRadioGroup *RGLink; + TCheckBox *CBPoll; + TRadioGroup *THTZ; + TRadioGroup *RGDupe; + TLabel *LLink; + TCheckBox *CBRemC; + TComboBox *CBMMLink; + TLabel *LT; + TCheckBox *CBBackup; + TLabel *LH; + TCheckBox *CBPTT; + TGroupBox *GB9; + TLabel *Label2; + TEdit *THRTTY; + TLabel *Label3; + TEdit *THSSTV; + TLabel *L10; + TEdit *THGMSK; + void __fastcall ClearOffClick(TObject *Sender); + void __fastcall AutoZoneClick(TObject *Sender); + + + + void __fastcall RGLinkClick(TObject *Sender); + +private: + int m_DisEvent; + TNotifyEvent m_fnHintProc; +// AnsiString m_MacroStr[5]; +// WORD m_MacroKey[5]; + + CMMList m_MMList; + + void __fastcall MacroBtnClick(int n); + void __fastcall UpdateUI(void); + +public: + virtual __fastcall TLogSetDlg(TComponent* AOwner); + void __fastcall DisplayHint(TObject *Sender); + + int __fastcall Execute(void); + +}; +//---------------------------------------------------------------------------- +//extern TLogSetDlg *LogSetDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/Loglink.cpp b/Loglink.cpp new file mode 100644 index 0000000..3c91678 --- /dev/null +++ b/Loglink.cpp @@ -0,0 +1,866 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "LogLink.h" +CLogLink LogLink; +//--------------------------------------------------------------------------- +// CLogLinkクラス +CLogLink::CLogLink() +{ + m_Enabled = FALSE; + m_Count = m_Count2 = 0; + m_hLog = NULL; + m_hLogIn = NULL; + m_CStat = 0; + m_hApp = NULL; + m_hMain = NULL; + m_Error = 0; + m_1stSession = TRUE; + m_fHLV5 = TRUE; + + m_Polling = 1; + m_PTTEnabled = FALSE; + + m_AStat = FALSE; + m_MMStat = FALSE; + m_pLink = NULL; + m_strMode[0] = 0; +} + +CLogLink::~CLogLink() +{ + CloseMMLink(); +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::CloseMMLink(void) +{ + if( m_pLink != NULL ){ + delete m_pLink; + m_pLink = NULL; + } +} +//--------------------------------------------------------------------------- +// 送信用ウインドウハンドルの設定 +void CLogLink::SetHandle(HWND hMain, UINT uMsg) +{ + m_hMain = hMain; + m_uMsg = uMsg; + m_hApp = Application->Handle; + if( m_pLink == NULL ) return; + m_pLink->SetHandle(hMain, uMsg); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CLogLink::IsLink(void) +{ + switch(m_Enabled){ + case 1: + return m_hLog != NULL ? TRUE : FALSE; + case 2: + return m_MMStat; + default: + return FALSE; + } +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall CLogLink::GetSessionName(void) +{ + switch(m_Enabled){ + case 1: +// return "Turbo HAMLOG/Win"; + return m_AppName.c_str(); + case 2: + if( m_pLink == NULL ) return NULL; + return m_pLink->GetSessionName(); + default: + return NULL; + } +} +//--------------------------------------------------------------------------- +// リンクの許可設定 +void CLogLink::UpdateLink(int sw) +{ + if( (m_Enabled != sw) || + ((m_pLink != NULL) && strcmp(m_ItemName.c_str(), m_pLink->GetItemName()) ) + ){ + m_Enabled = sw; + switch(sw){ + case 0: + m_hLog = NULL; + m_hLogIn = NULL; + CloseMMLink(); + break; + case 1: + m_Count = 0; + m_Error = 0; + CloseMMLink(); + break; + case 2: + m_Count = 0; + m_Error = 0; + if( !m_pLink ){ + m_pLink = new CMMLink(m_hMain, m_uMsg); + } + m_pLink->Open(m_ItemName.c_str()); + break; + } + } +} +//--------------------------------------------------------------------------- +// コールサインを分離 +static void DevCall(AnsiString &CALL, AnsiString &PTB, LPCSTR pCall) +{ + char bf[1024]; + + CALL = ""; + PTB = ""; + strcpy(bf, pCall); + LPSTR pp, p2, t; + t = bf; + if( (pp = strchr(bf, '/')) != NULL ){ // KH6/JE3HHT or JE3HHT/KH6 の形式 + *pp = 0; + pp++; + int LenC = strlen(t); + int LenP = strlen(pp); + if( ((p2 = strchr(pp, '/')) != NULL)|| + (LenC > 7) || + (LenP > 7) || + ((LenC > LenP) && (LenP>3)) || + ((LenC < LenP) && (LenC>3)) + ){ + // HAMLOGでは表現できない表記の場合 + if( p2 != NULL ){ + *p2 = 0; + LenP = strlen(pp); + } + } + if( LenC < LenP ){ + p2 = t; + t = pp; + pp = p2; + } + PTB = pp; + } + CALL = t; +} +//--------------------------------------------------------------------------- +static void __fastcall SetHamlogMode(LPSTR bf) +{ + if( !strcmp(bf, "RTTY") ){ + StrCopy(bf, Log.m_LogSet.m_THRTTY.c_str(), 3); + } + else if( !strcmp(bf, "SSTV") ){ + StrCopy(bf, Log.m_LogSet.m_THSSTV.c_str(), 3); + } + else if( !strcmp(bf, "GMSK") ){ + StrCopy(bf, Log.m_LogSet.m_THGMSK.c_str(), 3); + } + else if( !strcmp(bf, "FSTV") ){ + strcpy(bf, "FTV"); + } + else if( !strcmp(bf, "BPSK") ){ + strcpy(bf, "PSK"); + } + else if( !strcmp(bf, "QPSK") ){ + strcpy(bf, "PSK"); + } +} +//--------------------------------------------------------------------------- +// MM -> HamLog フォーマットの一括変換 +static void MMtoHAMLOG(LPSTR tp, SDMMLOG *sp, BOOL fHLV5) +{ + char bf[512]; + + AnsiString DATE; + AnsiString TIME; + + int CallOrder = FALSE; + + if( sp->btime ){ + int YY = sp->year; + int MM = sp->date / 100; + int DD = sp->date % 100; + int tim = sp->btime / 30; + int HH = tim / 60; + int mm = tim % 60; + char tz = 'J'; + switch(Log.m_LogSet.m_THTZ){ + case 0: + if( !IsJA(sp->call) ){ + JSTtoUTC(YY, MM, DD, HH); + tz = 'U'; + } + break; + case 1: + JSTtoUTC(YY, MM, DD, HH); + tz = 'U'; + break; + default: + break; + } + sprintf(bf, "%02u/%02u/%02u", YY, MM, DD); + DATE = bf; + sprintf(bf, "%02u:%02u%c", HH, mm, tz); + TIME = bf; + } + + AnsiString NAME = sp->name; + AnsiString QTH = sp->qth; + AnsiString REM1 = sp->rem; + AnsiString REM2 = sp->qsl; + + AnsiString CALL; + AnsiString PTB; + + if( fHLV5 ){ // Ver 5.00以降 + CALL = sp->call; + } + else { // Ver 4.xx + strcpy(bf, sp->call); + LPSTR pp, p2, t; + t = bf; + if( (pp = strchr(bf, '/')) != NULL ){ // KH6/JE3HHT or JE3HHT/KH6 の形式 + *pp = 0; + pp++; + int LenC = strlen(t); + int LenP = strlen(pp); + if( ((p2 = strchr(pp, '/')) != NULL)|| + (LenC > 7) || + (LenP > 7) || + ((LenC > LenP) && (LenP>3)) || + ((LenC < LenP) && (LenC>3)) + ){ + // HAMLOGでは表現できない表記の場合 + AddMMLOGKey(REM1, REM2, sp->call, "ToRadio"); + if( p2 != NULL ){ + *p2 = 0; + LenP = strlen(pp); + } + } + if( LenC < LenP ){ + p2 = t; + t = pp; + pp = p2; + CallOrder = TRUE; + } + PTB = pp; + } + else if( strlen(t) > 7 ){ + AddMMLOGKey(REM1, REM2, sp->call, "ToRadio"); + } + CALL = t; + } + strcpy(bf, Log.GetModeString(sp->mode)); + if( !fHLV5 ){ +#if 1 + SetHamlogMode(bf); +#else + if( !strcmp(bf, "RTTY") ){ + StrCopy(bf, Log.m_LogSet.m_THRTTY.c_str(), 3); + } + else if( !strcmp(bf, "SSTV") ){ + StrCopy(bf, Log.m_LogSet.m_THSSTV.c_str(), 3); + } + else if( !strcmp(bf, "GMSK") ){ + StrCopy(bf, Log.m_LogSet.m_THGMSK.c_str(), 3); + } + else if( !strcmp(bf, "FSTV") ){ + strcpy(bf, "FTV"); + } + else if( !strcmp(bf, "BPSK") ){ + strcpy(bf, "PSK"); + } + else if( !strcmp(bf, "QPSK") ){ + strcpy(bf, "PSK"); + } +#endif + } + AnsiString MODE = bf; + + AnsiString HIS, MY; + int l = GetLMode(sp->mode); + if( fHLV5 ){ + HIS = sp->ur; + MY = sp->my; + } + else { + strcpy(bf, sp->ur); + bf[l] = 0; + HIS = bf; + strcpy(bf, sp->my); + bf[l] = 0; + MY = bf; + } + if( sp->ur[l] ) AddMMLOGKey(REM1, REM2, &sp->ur[l], "SN"); + if( sp->my[l] ) AddMMLOGKey(REM1, REM2, &sp->my[l], "RN"); + + strcpy(bf, Log.GetFreqString(sp->band, sp->fq)); + AnsiString FREQ = bf; + + if( !fHLV5 ){ + if( CallOrder && (!strstr(sp->rem, "$DX")) && (!strstr(sp->qsl, "$DX")) ){ + AddMMLOGKey(REM1, REM2, "$DX", NULL); + } + } + + if( sp->etime ){ + int tim = sp->etime / 30; + sprintf(bf, "%02u%02u", tim / 60, tim % 60); + AddMMLOGKey(REM1, REM2, bf, "END"); + } + if( sp->env ){ + sprintf(bf, "%u", sp->env); + AddMMLOGKey(REM1, REM2, bf, "ENV"); + } + AddMMLOGKey(REM1, REM2, sp->pow, "POW"); + if( sp->cq ){ + bf[0] = sp->cq; bf[1] = 0; + AddMMLOGKey(REM1, REM2, bf, "M"); + } + AnsiString CODE; + if( (strlen(sp->opt1) >= 3) && isdigit(sp->opt1[0]) && isdigit(sp->opt1[1]) ){ + CODE = sp->opt1; + } + sprintf(bf, "%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n", + CALL.c_str(), PTB.c_str(), DATE.c_str(), TIME.c_str(), + HIS.c_str(), MY.c_str(), FREQ.c_str(), MODE.c_str(), CODE.c_str(), "", "", + NAME.c_str(), QTH.c_str(), REM1.c_str(), REM2.c_str() + ); + strcpy(tp, bf); +} +//--------------------------------------------------------------------------- +// ウインドウフォーカスを自身に戻す +void CLogLink::Foreground(void) +{ + if( m_Enabled != 1 ) return; + + ::SetWindowPos(m_hApp, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + ::SetFocus(m_hApp); +} +//--------------------------------------------------------------------------- +// ログのリンクのチェック +BOOL CLogLink::CheckLink(void) +{ + if( m_Error ) return FALSE; + + switch(m_Enabled){ + case 1: + { + HWND hLog = ::FindWindow("TThwin", NULL); + if( hLog != m_hLog ){ + if( hLog ){ + m_AppVer = 0; + char bf[128]; + LPSTR p; + ::GetWindowText(hLog, bf, sizeof(bf)); + clipsp(bf); + m_AppName = bf; + if( (p = strstr(bf, "Ver")) != NULL ){ + p += 3; + LPSTR t; + for( t = p; *t; t++ ){ + if( (*t != '.') && !isdigit(*t) ) break; + } + *t = 0; + double d; + if( sscanf(p, "%lf", &d) == 1 ){ + m_AppVer = d * 100; + } + } + else { + m_Count = 1000/LINKINTERVAL; + return FALSE; + } + m_fHLV5 = (m_AppVer >= 500); + } + m_hLog = hLog; + m_CStat = TRUE; + } + return m_hLog != NULL ? TRUE : FALSE; + } + case 2: + { + if( m_pLink == NULL ) return FALSE; + m_MMStat = m_pLink->IsConnected(); + if( m_MMStat != m_AStat ){ + m_AStat = m_MMStat; + m_CStat = TRUE; + } + return m_MMStat; + } + default: + return FALSE; + } +} +//--------------------------------------------------------------------------- +// 定期的なログのリンクの監視(200ms毎にコール) +BOOL CLogLink::TimerLogLink(void) +{ + if( !m_Enabled ) return FALSE; + + if( !m_Count ){ + m_Count = 5000/LINKINTERVAL; // 5[s]毎のチェック + BOOL f = m_hLog != NULL; + CheckLink(); + if( m_hLog && !f ) m_1stSession = TRUE; + } + m_Count--; + if( m_CStat ){ + m_CStat = 0; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +// 定期的な周波数ポーリング +void CLogLink::EventGetFreq(void) +{ + if( !m_Polling ) return; + + if( !m_Count2 ){ + m_Count2 = 2000/LINKINTERVAL; // 2[s]毎のチェック + switch(m_Enabled){ + case 1: + { + if( m_hLog == NULL ) return; + int af = Application->Active; + m_cds.dwData = 106; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hMain), LPARAM(&m_cds)); + if( af && m_1stSession ) Foreground(); + m_1stSession = FALSE; + } + break; + case 2: + if( m_pLink == NULL ) return; + m_pLink->EventVFO(); + break; + } + } + m_Count2--; +} +//--------------------------------------------------------------------------- +// 周波数の設定 +void CLogLink::SetFreq(LPSTR pFreq) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + m_cds.dwData = 6; + m_cds.cbData = strlen(pFreq); + m_cds.lpData = pFreq; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + break; + case 2: + if( m_pLink == NULL ) return; + m_pLink->SetFreq(pFreq); + break; + } +} +//--------------------------------------------------------------------------- +// モードの設定 +void CLogLink::SetMode(LPCSTR pMode) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + if( pMode && (pMode != m_strMode) ){ + StrCopy(m_strMode, pMode, sizeof(m_strMode)-1); + if( !m_fHLV5 ){ + SetHamlogMode(m_strMode); + } + } + if( m_strMode[0] ){ + m_cds.dwData = 7; + m_cds.cbData = strlen(m_strMode); + m_cds.lpData = m_strMode; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + } + break; + case 2: +// if( m_pLink == NULL ) return; +// m_pLink->SetMode(pMode); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::SetPTT(int ptt) +{ + if( !m_PTTEnabled ) return; + if( !CheckLink() ) return; + switch(m_Enabled){ + case 1: + { + int af = Application->Active; + m_cds.dwData = ptt ? 23 : 24; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, af ? WPARAM(m_hApp) : NULL, LPARAM(&m_cds)); + if( af && m_1stSession ) Foreground(); + m_1stSession = FALSE; + } + break; + case 2: + if( !m_pLink ) return; + m_pLink->SetPTT(ptt); + break; + } +} +//--------------------------------------------------------------------------- +// クリア +void CLogLink::Clear(void) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + { + int af = Application->Active; + m_cds.dwData = 16; + m_cds.cbData = 0; + m_cds.lpData = NULL; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, af ? WPARAM(m_hApp) : NULL, LPARAM(&m_cds)); +// m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, NULL, LPARAM(&m_cds)); + if( !::IsWindow(m_hLogIn) ){ + m_hLog = NULL; + m_CStat = TRUE; + m_Error = TRUE; + } + if( af ) Foreground(); + break; + } + case 2: + m_QueryCall = ""; + if( m_pLink == NULL ) return; + m_pLink->Clear(); + break; + } +} +//--------------------------------------------------------------------------- +// Hamlogにフォーカスを設定 +void CLogLink::SetFocus(void) +{ + if( m_Enabled != 1 ) return; + if( m_hLog == NULL ) return; + if( m_hLogIn == NULL ) return; + + ::SetForegroundWindow(m_hLogIn); +} +//--------------------------------------------------------------------------- +// コールサインの転送 +void CLogLink::SetCall(LPSTR pCall, int sw) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + { + if( m_hLog == NULL ) return; + int af = Application->Active; + Clear(); + OnWave(); + AnsiString CALL; + AnsiString PTB; + if( m_fHLV5 ){ + CALL = pCall; + m_cds.dwData = IsJA(pCall) ? 26 : 25; + m_cds.cbData = 0; + m_cds.lpData = NULL; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + m_cds.dwData = 0; + if( sw ) m_cds.dwData |= THW_ENTER; + m_cds.cbData = strlen(CALL.c_str()); + m_cds.lpData = CALL.c_str(); + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + } + else { + DevCall(CALL, PTB, pCall); + m_cds.dwData = 0; + if( sw ) m_cds.dwData |= THW_ENTER; + m_cds.cbData = strlen(CALL.c_str()); + m_cds.lpData = CALL.c_str(); + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + OnWave(); + m_cds.dwData = 1; + if( sw ) m_cds.dwData |= THW_ENTER; + m_cds.cbData = strlen(PTB.c_str()); + m_cds.lpData = PTB.c_str(); + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + } + if( af ) Foreground(); + } + case 2: + m_QueryCall = pCall; + if( m_pLink == NULL ) return; + m_pLink->Query(pCall); + break; + } +} +//--------------------------------------------------------------------------- +// コールサインの検索 +void CLogLink::FindCall(LPSTR pCall) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + { + int af = Application->Active; + SetCall(pCall, FALSE); + if( m_hLog == NULL ) return; + OnWave(); + + OnWave(); + m_cds.dwData = 17; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + OnWave(); + m_cds.dwData = 115; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hMain), LPARAM(&m_cds)); + if( af ) Foreground(); + } + break; + case 2: + m_QueryCall = pCall; + if( m_pLink == NULL ) return; + m_pLink->Query(pCall); + break; + } +} +//--------------------------------------------------------------------------- +// ログの記録 +// 0-データの設定のみ +// 1-データの設定とRETキー/問い合わせの実行(QSOの開始時) +// 2-書きこみを実行(QSOの終了時) +void CLogLink::Write(SDMMLOG *sp, int sw) +{ + if( !CheckLink() ) return; + + switch(m_Enabled){ + case 1: + { + int af = Application->Active; + if( m_fHLV5 && (sw == 1) ){ + m_cds.dwData = IsJA(sp->call) ? 26 : 25; + m_cds.cbData = 0; + m_cds.lpData = NULL; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + m_cds.dwData = 0; + m_cds.cbData = strlen(sp->call); + m_cds.lpData = sp->call; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + } + char bf[1024]; + MMtoHAMLOG(bf, sp, m_fHLV5); + m_cds.dwData = 15; + if( sw ) m_cds.dwData |= THW_ENTER; + m_cds.cbData = strlen(bf); + m_cds.lpData = bf; + m_hLogIn = (HWND)::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + OnWave(); + switch(sw){ + case 1: + m_cds.dwData = 115; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hMain), LPARAM(&m_cds)); + break; + case 2: + m_cds.dwData = 18 | THW_SAVEBOX_OFF; + m_cds.cbData = 0; + m_cds.lpData = NULL; + ::SendMessage(m_hLog, WM_COPYDATA, WPARAM(m_hApp), LPARAM(&m_cds)); + break; + } + if( af ) Foreground(); + } + break; + case 2: + if( m_pLink == NULL ) return; + m_QueryCall = sp->call; + m_pLink->LogWrite(sp, sw); + break; + } +} +//--------------------------------------------------------------------------- +int __fastcall GetLFCount(LPCSTR p) +{ + int n = 0; + for(; *p; p++ ){ + if( *p == LF ) n++; + } + return n; +} +//--------------------------------------------------------------------------- +// Hamlogからの返信メッセージからName,QTH,REM1を得る +int CLogLink::AnaData(SDMMLOG *sp, COPYDATASTRUCT *cp) +{ + BOOL r = FALSE; + + char bf[1024]; + int len = cp->cbData; + if( len >= 1023 ) len = 1023; + if( len && (cp->lpData != NULL) ){ + StrCopy(bf, LPCSTR(cp->lpData), len); + int lfLen = GetLFCount(bf); + LPSTR t, p; + if( len < 10 ){ // 周波数情報 + if( m_Polling ){ + t = SkipSpace(bf); ClipLF(t); clipsp(t); + if( *t ){ + Log.SetFreq(&Log.m_sd, t); + r = 106; + } + } + } + else if( lfLen >= 10 ){ // 検索結果情報 + p = StrDlm(t, bf, LF); // Call + p = StrDlm(t, p, LF); // PTB + p = StrDlm(t, p, LF); // Date + p = StrDlm(t, p, LF); // Time + p = StrDlm(t, p, LF); // His + p = StrDlm(t, p, LF); // My + p = StrDlm(t, p, LF); // Freq + p = StrDlm(t, p, LF); // Mode + p = StrDlm(t, p, LF); // Code + t = SkipSpace(t); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->opt1, t, MLOPT); + r = 115; + } + p = StrDlm(t, p, LF); // GL + p = StrDlm(t, p, LF); // QSL + p = StrDlm(t, p, LF); // Name + if( !sp->name[0] ){ + t = SkipSpace(t); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->name, t, MLNAME); + r = 115; + } + } + p = StrDlm(t, p, LF); // QTH +// if( !sp->qth[0] ){ + if( !sp->qth[0] || !IsJA(sp->call) ){ + t = SkipSpace(t); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->qth, t, MLQTH); + r = 115; + } + } + StrDlm(t, p, LF); // REM1 + if( !sp->rem[0] ){ + t = SkipSpace(t); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->rem, t, MLREM); + r = 115; + } + } + } + } + return r; +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::NotifySession(LPCSTR pSession) +{ + if( m_pLink == NULL ) return; + + m_pLink->NotifySession(pSession); + CheckLink(); +} +//--------------------------------------------------------------------------- +int __fastcall CLogLink::QReturn(SDMMLOG *sp, const mmLOGDATA *pLog) +{ + if( pLog == NULL ) return FALSE; + int r = FALSE; + + mmLOGDATA logdata; + memcpy(&logdata, pLog, sizeof(logdata)); + + if( stricmp(logdata.m_Call, m_QueryCall.c_str()) ) return FALSE; + LPSTR t; + if(!sp->name[0] ){ + t = SkipSpace(logdata.m_Name); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->name, t, MLNAME); + r = TRUE; + } + } + if( !sp->qth[0] ){ + t = SkipSpace(logdata.m_QTH); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->qth, t, MLQTH); + r = TRUE; + } + } + if( !sp->rem[0] ){ + t = SkipSpace(logdata.m_Note); ClipLF(t); clipsp(t); + if( *t ){ + StrCopy(sp->rem, t, MLREM); + r = TRUE; + } + } + return r; +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::SetTime(SYSTEMTIME *tp, int sw) +{ + if( m_pLink == NULL ) return; + + m_pLink->SetTime(tp, sw); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall CLogLink::GetItemName(void) +{ + return m_ItemName.c_str(); +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::SetItemName(LPCSTR pName) +{ + m_ItemName = pName; +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::LoadMMLink(TMemIniFile *pIni) +{ + m_ItemName = pIni->ReadString("MMLink", "Name", ""); +} +//--------------------------------------------------------------------------- +void __fastcall CLogLink::SaveMMLink(TMemIniFile *pIni) +{ + pIni->WriteString("MMLink", "Name", m_ItemName); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CLogLink::IsCopyData(void) +{ + if( m_Enabled != 2 ) return FALSE; + if( !m_pLink ) return FALSE; + return (m_pLink->GetCaps() & capWMCOPYDATA); +} +//--------------------------------------------------------------------------- + diff --git a/Loglink.h b/Loglink.h new file mode 100644 index 0000000..b9a4465 --- /dev/null +++ b/Loglink.h @@ -0,0 +1,123 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef LogLinkH +#define LogLinkH + +#include +#include +#include + +#include "ComLib.h" +#include "LogConv.h" +#include "MMLink.h" + +#define LINKINTERVAL 1000 +// +//------------ Command of Hamlog ------------- +#define THW_ENTER 0x10000 +#define THW_FOCUS 0x20000 +#define THW_SAVEBOX_ON 0x40000 +#define THW_SAVEBOX_OFF 0x80000 +#define THW_APPLIHWND 0x100000 + +//--------------------------------------------------------------------------- +// CLogLinkクラス +class CLogLink +{ +private: + int m_Enabled; // リンクの許可 + int m_Polling; // 周波数ポーリング + BOOL m_PTTEnabled; // PTTコントロール + BOOL m_1stSession; + + HWND m_hLog; // Hamlogプログラムのハンドル + HWND m_hLogIn; // Hamlog入力ウインドウのハンドル + + COPYDATASTRUCT m_cds; // インターフェース構造体 + int m_Count; // 監視カウンタ + int m_CStat; // 状態変更セマフォ + int m_Count2; // ポーリングカウンタ + + HWND m_hMain; // メイン画面のウインドウハンドル + HWND m_hApp; // アプリケーションのウインドウハンドル + BOOL m_fHLV5; // Hamlog Ver 5.0 + + int m_Error; + + AnsiString m_ItemName; + AnsiString m_QueryCall; + AnsiString m_AppName; + int m_AppVer; + int m_MMStat; + int m_AStat; + UINT m_uMsg; + + char m_strMode[16]; +public: + CMMLink *m_pLink; +private: + void __fastcall CloseMMLink(void); + +public: + CLogLink(); + ~CLogLink(); + void SetHandle(HWND hMain, UINT uMsg); + BOOL IsEnabled(void){return m_Enabled;}; + void UpdateLink(int sw); + void Foreground(void); + BOOL IsError(void){return m_Error;}; + void ClearError(void){m_Error = 0;}; + BOOL __fastcall IsLink(void); + LPCSTR __fastcall GetSessionName(void); + + BOOL CheckLink(void); + BOOL TimerLogLink(void); + void Clear(void); + void SetFocus(void); + void SetCall(LPSTR pCall, int sw); + void FindCall(LPSTR pCall); + void Write(SDMMLOG *sp, int sw); + int AnaData(SDMMLOG *sp, COPYDATASTRUCT *cp); + + BOOL IsPolling(void){return m_Polling;}; + void SetPolling(int sw){m_Polling = sw;}; + void EventGetFreq(void); + void SetFreq(LPSTR pFreq); + void SetMode(LPCSTR pMode); + void __fastcall SetPTT(int ptt); + + void __fastcall SetTime(SYSTEMTIME *tp, int sw); + +public: + void __fastcall LoadMMLink(TMemIniFile *pIni); + void __fastcall SaveMMLink(TMemIniFile *pIni); + void __fastcall NotifySession(LPCSTR pSession); + int __fastcall QReturn(SDMMLOG *sp, const mmLOGDATA *pLog); + LPCSTR __fastcall GetItemName(void); + void __fastcall SetItemName(LPCSTR pName); + BOOL __fastcall IsCopyData(void); + + inline BOOL __fastcall GetPTTEnabled(void){return m_PTTEnabled;}; + inline void __fastcall SetPTTEnabled(BOOL e){m_PTTEnabled = e;}; +}; +extern CLogLink LogLink; +#endif + diff --git a/MMCG.DEF b/MMCG.DEF new file mode 100644 index 0000000..7c76346 --- /dev/null +++ b/MMCG.DEF @@ -0,0 +1,1546 @@ +!=========================================================================== +! AJA番号定義ファイル For MMCG.EXE +! +!※ このファイルを変更した場合は「MMCG.BIN」を消去して「MMCG.EXE」を +! 起動して下さい。新しい「MMCG.BIN」が生成されます。 +! +!※ 読みは<,>で区切って複数個記述する事ができます。ひらがなやカタカナ +! を記述しても良いでしょう。 +! +! 例> 2509 高槻市 TAKATUKI,たかつき,タカツキ,タカツキ +! +! ただし、あまりファイルサイズが大きくなると、レスポンスが悪くなり +! ますので注意が必要です。 +! +!※ このファイルをネット等に流通させる場合は、変更履歴を追加記載する +! 事をお勧めします。 +! +!<<<変更履歴>>> +! Feb 4, 1996 - 1029(あきる野市)追加 JE3HHT +! Jun 5, 1997 - 0134(北広島市)追加 JE3HHT +! Jun 5, 1997 - 2212(京田辺市)追加 JE3HHT +! Jan 10, 2000 - 0135,1231,1343,1422,2722,4029追加 +! SBAE=>SABAE,SINNANJO=>SINNANYOU,UDO=>UTO +! 27017,01029消滅    JQ3UDL +!========================================================================== +01 % HOKKAIDO +0101 札幌市 SAPPORO +0102 旭川市 ASAHIKAWA +0103 小樽市 OTARU +0104 函館市 HAKODATE +0105 室蘭市 MURORAN +0106 釧路市 KUSIRO +0107 帯広市 OBIHIRO +0108 北見市 KITAMI +0109 夕張市 YUBARI +0110 岩見沢市 IWAMIZAWA +0111 網走市 ABASIRI +0112 留萌市 RUMOI +0113 苫小牧市 TOMAKOMAI +0114 稚内市 WAKKANAI +0115 美唄市 BIBAI +0116 芦別市 ASIBETU +0117 江別市 EBETU +0118 赤平市 AKABIRA +0119 紋別市 MONBETU +0120 士別市 SIBETU +0121 名寄市 NAYORO +0122 三笠市 MIKASA +0123 根室市 NEMURO +0124 千歳市 CITOSE +0125 滝川市 TAKIKAWA +0126 砂川市 SUNAGAWA +0127 歌志内市 UTASINAI +0128 深川市 FUKAGAWA +0129 富良野市 FURANO +0130 登別市 NOBORIBETU +0131 恵庭市 ENIWA +0132 亀田市* +0133 伊達市 DATE +0134 北広島市 KITAHIROSIMA +0135 石狩市 ISIKARI +01001 阿寒郡 AKAN +01002 足寄郡 ASYORO +01003 厚岸郡 AKKESI +01004 厚田郡 ATUTA +01005 網走郡 ABASIRI +01006 虻田郡(後志) ABUTA +01007 虻田郡(胆振) ABUTA +01008 石狩郡 ISIKARI +01009 磯谷郡 ISOYA +01010 岩内郡 IWANAI +01011 有珠郡 USU +01012 歌棄郡* +01013 浦河郡 URAKAWA +01014 雨竜郡 URYU +01015 枝幸郡 ESASI +01016 奥尻郡 OKUSIRI +01017 忍路郡* +01018 河西郡 KASAI +01019 河東郡 KATOU +01020 樺戸郡 KABATO +01021 上磯郡 KAMIISO +01022 上川郡(十勝) KAMIKAWA +01023 上川郡(上川) KAMIKAWA +01024 亀田郡 KAMEDA +01025 茅部郡 KAYABE +01026 川上郡 KAWAKAMI +01027 釧路郡 KUSIRO +01028 久遠郡 KUDO +01029 札幌郡* +01030 様似郡 SAMANI +01031 沙流郡 SARU +01032 静内郡 SIZUNAI +01033 標津郡 SIBETU +01034 島牧郡 SIMAMAKI +01035 積丹郡 SYAKOTAN +01036 斜里郡 SYARI +01037 白老郡 SIRAOI +01038 白糠郡 SIRANUKA +01039 寿都郡 SUTTU +01040 瀬棚郡 SETANA +01041 宗谷郡 SOUYA +01042 空知郡(空知) SOUCI +01043 空知郡(上川) SOUCI +01044 千歳郡* +01045 天塩郡(留萌) TESIO +01046 天塩郡(宗谷) TESIO +01047 十勝郡 TOKACI +01048 常呂郡 TOKORO +01049 苫前郡 TOMAMAE +01050 中川郡(上川) NAKAGAWA +01051 中川郡(十勝) NAKAGAWA +01052 新冠郡 NIIKABUTU +01053 爾志郡 NISI +01054 根室郡* +01055 野付郡 NOTUKE +01056 花咲郡* +01057 浜益郡 HAMAMASU +01058 美国郡* +01059 桧山郡 HIYAMA +01060 広尾郡 HIRO +01061 太櫓郡* +01062 古宇郡 FURU +01063 古平郡 FURUBIRA +01064 幌泉郡 HOROIZUMI +01065 幌別郡* +01066 増毛郡 MASIKE +01067 松前郡 MATUMAE +01068 三石郡 MITUISI +01069 目梨郡 MENASI +01070 紋別郡 MONBETU +01071 山越郡 YAMAKOSI +01072 夕張郡 YUBARI +01073 勇払郡(胆振) YUFUTU +01074 勇払郡(上川) YUFUTU +01075 余市郡 YOICI +01076 利尻郡 RISIRI +01077 留萌郡 RUMOI +01078 礼文郡 REBUN +010101 札幌市中央区 CYUO +010102 札幌市北区 KITA +010103 札幌市東区 HIGASI +010104 札幌市白石区 SIROISI +010105 札幌市豊平区 TOYOHIRA +010106 札幌市南区 MINAMI +010107 札幌市西区 NISI +010108 札幌市厚別区 ATUBETU +010109 札幌市手稲区 TEINE +02 % AOMORI +0201 青森市 AOMORI +0202 弘前市 HIROSAKI +0203 八戸市 HACINOHE +0204 黒石市 KUROISI +0205 五所川原市 GOSYOGAWARA +0206 十和田市 TOWADA +0207 三沢市 MISAWA +0208 むつ市 MUTU +02001 上北郡 KAMIKITA +02002 北津軽郡 KITATUGARU +02003 三戸郡 SANNOHE +02004 下北郡 SIMOKITA +02005 中津軽郡 NAKATUGARU +02006 西津軽郡 NISITUGARU +02007 東津軽郡 HIGASITUGARU +02008 南津軽郡 MINAMITUGARU +03 % IWATE +0301 盛岡市 MORIOKA +0302 釜石市 KAMAISI +0303 宮古市 MIYAKO +0304 一関市 ICINOSEKI +0305 大船渡市 OOFUNATO,OFUNATO +0306 水沢市 MIZUSAWA +0307 花巻市 HANAMAKI +0308 北上市 KITAKAMI +0309 久慈市 KUJI +0310 遠野市 TOONO,TONO +0311 陸前高田市 RIKUZENTAKADA +0312 江刺市 ESASI +0313 二戸市 NINOHE +03001 胆沢郡 ISAWA +03002 岩手郡 IWATE +03003 江刺郡* +03004 上閉伊郡 KAMIHEI +03005 九戸郡 KUNOHE +03006 気仙郡 KESEN +03007 下閉伊郡 SIMOHEI +03008 紫波郡 SIWA +03009 西磐井郡 NISIIWAI +03010 二戸郡 NINOHE +03011 稗貫郡 HIENUKI +03012 東磐井郡 HIGASIIWAI +03013 和賀郡 WAGA +04 % AKITA +0401 秋田市 AKITA +0402 能代市 NOSIRO +0403 大館市 OODATE,ODATE +0404 横手市 YOKOTE +0405 本荘市 HONJO +0406 男鹿市 OGA +0407 湯沢市 YUZAWA +0408 大曲市 OOMAGARI,OMAGARI +0409 鹿角市 KAZUNO +04001 雄勝郡 OGACI +04002 鹿角郡 KAZUNO +04003 河辺郡 KAWABE +04004 北秋田郡 KITAAKITA +04005 仙北郡 SENBOKU +04006 平鹿郡 HIRAKA +04007 南秋田郡 MINAMIAKITA +04008 山本郡 YAMAMOTO +04009 由利郡 YURI +05 % YAMAGATA +0501 山形市 YAMAGATA +0502 米沢市 YOBEZAWA +0503 鶴岡市 TURUOKA +0504 酒田市 SAKATA +0505 新庄市 SINJO +0506 寒河江市 SAGAE +0507 上山市 KAMINOYAMA +0508 村山市 MURAYAMA +0509 長井市 NAGAI +0510 天童市 TENDO +0511 東根市 HIGASINE +0512 尾花沢市 OBANAZAWA +0513 南陽市 NANYO +05001 飽海郡 AKUMI +05002 北村山郡 KITAMURAYAMA +05003 西置賜郡 NISIOKITAMA +05004 西田川郡 NISITAGAWA +05005 西村山郡 NISIMURAYAMA +05006 東置賜郡 HIGASIOKITAMA +05007 東田川郡 HIGASITAGAWA +05008 東村山郡 HIGASIMURAYAMA +05009 南置賜郡* +05010 南村山郡* +05011 最上郡 MOGAMI +06 % MIYAGI +0601 仙台市 SENDAI +0602 石巻市 ISINOMAKI +0603 塩釜市 SIOGAMA +0604 古川市 FURUKAWA +0605 気仙沼市 KESENNUMA +0606 白石市 SIROISI +0607 名取市 NATORI +0608 角田市 KAKUDA +0609 多賀城市 TAGAJO +0610 泉市* +0611 岩沼市 IWANUMA +06001 伊具郡 IGU +06002 牡鹿郡 OSIKA +06003 刈田郡 KATUTA +06004 加美郡 KAMI +06005 栗原郡 KURIHARA +06006 黒川郡 KUROKAWA +06007 志田郡 SIDA +06008 柴田郡 SIBATA +06009 玉造郡 TAMATUKURI +06010 遠田郡 TOODA,TODA +06011 登米郡 TOME +06012 名取郡* +06013 宮城郡 MIYAGI +06014 本吉郡 MOTOYOSI +06015 桃生郡 MONO +06016 亘理郡 WATARI +060101 仙台市青葉区 AOBA +060102 仙台市宮城野区 MIYAGINO +060103 仙台市若林区 WAKABAYASI +060104 仙台市太白区 TAIHAKU +060105 仙台市泉区 IZUMI +07 % FUKUSIMA +0701 福島市 FUKUSIMA +0702 会津若松市 AIZUWAKAMATU +0703 郡山市 KOORIYAMA,KORIYAMA +0704 平市* +0705 白河市 SIRAKAWA +0706 原町市 HARAMACI +0707 須賀川市 SUKAGAWA +0708 喜多方市 KITAKATA +0709 常磐市* +0710 磐城市* +0711 相馬市 SOUMA +0712 内郷市* +0713 勿来市* +0714 二本松市 NIHONMATU +0715 いわき市 IWAKI +0716 若松市* +07001 安積郡* +07002 安達郡 ADACI +07003 石川郡 ISIKAWA +07004 石城郡* +07005 岩瀬郡 IWASE +07006 大沼郡 OONUMA,ONUMA +07007 河沼郡 KAWANUMA +07008 北会津郡 KITAAIZU +07009 信夫郡* +07010 相馬郡 SOMA +07011 伊達郡 DATE +07012 田村郡 TAMURA +07013 西白河郡 NISISIRAKAWA +07014 東白川郡 HIGASISIRAKAWA +07015 双葉郡 FUTABA +07016 南会津郡 MINAMIAIZU +07017 耶麻郡 YAMA +08 % NIIGATA +0801 新潟市 NIIGATA +0802 長岡市 NAGAOKA +0803 高田市* +0804 三条市 SANJO +0805 柏崎市 KASIWAZAKI +0806 新発田市 SIBATA +0807 新津市 NIITU +0808 小千谷市 OJIYA +0809 加茂市 KAMO +0810 十日町市 TOOKAMACI,TOKAMACI +0811 見附市 MITUKE +0812 村上市 MURAKAMI +0813 燕市 TUBAME +0814 直江津市* +0815 栃尾市 TOCIO +0816 糸魚川市 ITOIGAWA +0817 新井市 ARAI +0818 五泉市 GOSEN +0819 両津市 RYOTU +0820 白根市 SIRONE +0821 豊栄市 TOYOSAKA +0822 上越市 JOETU +08001 岩船郡 IWAFUNE +08002 刈羽郡 KARIWA +08003 北魚沼郡 KITAUONUMA +08004 北蒲原郡 KITAKANBARA +08005 古志郡 KOSI +08006 佐渡郡 SADO +08007 三島郡 SANTOU +08008 中魚沼郡 NAKAUONUMA +08009 中蒲原郡 NAKAKANBARA +08010 中頚城郡 NAKAKUBIKI +08011 西蒲原郡 NISIKANBARA +08012 西頚城郡 NISIKUBIKI +08013 東蒲原郡 HIGASIKANBARA +08014 東頚城郡 HIGASIKUBIKI +08015 南魚沼郡 MINAMIUONUMA +08016 南蒲原郡 MINAMIKANBARA +09 % NAGANO +0901 長野市 NAGANO +0902 松本市 MATUMOTO +0903 上田市 UEDA +0904 岡谷市 OKAYA +0905 飯田市 IIDA +0906 諏訪市 SUWA +0907 須坂市 SUZAKA +0908 小諸市 KOMORO +0909 伊那市 INE +0910 駒ヶ根市 KOMAGANE +0911 中野市 NAKANO +0912 大町市 OOMACI,OMACI +0913 飯山市 IIYAMA +0914 茅野市 CINO +0915 塩尻市 SIOJIRI +0916 篠ノ井市* +0917 更埴市 KOUSYOKU +0918 佐久市 SAKU +09001 上伊那郡 KAMIINA +09002 上高井郡 KAMITAKAI +09003 上水内郡 KAMIMINOCI +09004 木曽郡 KISO +09005 北安曇郡 KITAAZUMI +09006 北佐久郡 KITASAKU +09007 更級郡 SARASINA +09008 下伊那郡 SIMOINA +09009 下高井郡 SIMOTAKAI +09010 下水内郡 SIMOMINOCI +09011 諏訪郡 SUWA +09012 小県郡 CISAGATA +09014 埴科郡 HANISINA +09015 東筑摩郡 HIGASICIKUMA +09016 南安曇郡 MINAMIAZUMI +09017 南佐久郡 MINAMISAKU +10 % TOUKYO,TOKYO +1001 23区 TOUKYO,TOKYO +1002 八王子市 HACIOJI +1003 立川市 TACIKAWA +1004 武蔵野市 MUSASINO +1005 三鷹市 MITAKA +1006 青梅市 OUME +1007 府中市 FUCYU +1008 昭島市 AKISIMA +1009 調布市 CYOFU +1010 町田市 MACIDA +1011 小金井市 KOGANEI +1012 小平市 KODAIRA +1013 日野市 HINO +1014 東村山市 HIGASIMURAYAMA +1015 国分寺市 KOKUBUNJI +1016 国立市 KUNITACI +1017 保谷市 HOUYA +1018 田無市 TANASI +1019 福生市 FUSSA +1020 狛江市 KOMAE +1021 東大和市 HIGASIYAMATO +1022 清瀬市 KIYOSE +1023 東久留米市 HIGASIKURUME +1024 武蔵村山市 MUSASIMURAYAMA +1025 多摩市 TAMA +1026 稲城市 INAGI +1027 秋川市 AKIGAWA +1028 羽村市 HAMURA +1029 あきる野市 AKIRUNO +10001 北多摩郡* +10002 西多摩郡 NISITAMA +10003 南多摩郡* +10004 大島支庁 OOSIMA,OSIMA +10005 三宅支庁 MIYAKE +10006 八丈支庁 HACIJO +10007 小笠原支庁 OGASAWARA +100101 東京都千代田区 CIYODA +100102 東京都中央区 CYUO +100103 東京都港区 MINATO +100104 東京都新宿区 SINJUKU +100105 東京都文京区 BUNKYO +100106 東京都台東区 TAITOU +100107 東京都墨田区 SUMIDA +100108 東京都江東区 KOUTOU +100109 東京都品川区 SINAGAWA +100110 東京都目黒区 MEGURO +100111 東京都大田区 OOTA,OTA +100112 東京都世田谷区 SETAGAYA +100113 東京都渋谷区 SIBUYA +100114 東京都中野区 NAKANO +100115 東京都杉並区 SUGINAMI +100116 東京都豊島区 TOSIMA +100117 東京都北区 KITA +100118 東京都荒川区 ARAKAWA +100119 東京都板橋区 ITABASI +100120 東京都練馬区 NERIMA +100121 東京都足立区 ADACI +100122 東京都葛飾区 KATUSIKA +100123 東京都江戸川区 EDOGAWA +11 % KANAGAWA +1101 横浜市 YOKOHAMA +1102 横須賀市 YOKOSUKA +1103 川崎市 KAWASAKI +1104 平塚市 HIRATUKA +1105 鎌倉市 KAMAKURA +1106 藤沢市 FUJISAWA +1107 小田原市 ODAWARA +1108 茅ヶ崎市 CIGASAKI +1109 逗子市 ZUSI +1110 相模原市 SAGAMIHARA +1111 三浦市 MIURA +1112 秦野市 HADANO +1113 厚木市 ATUGI +1114 大和市 YAMATO +1115 伊勢原市 ISEHARA +1116 海老名市 EBINA +1117 座間市 ZAMA +1118 南足柄市 MINAMIASIGARA +1119 綾瀬市 AYASE +11001 愛甲郡 AIKOU +11002 足柄上郡 ASIGARAKAMI +11003 足柄下郡 ASIGARASIMO +11004 高座郡 KOUZA +11005 津久井郡 TUKUI +11006 中郡 NAKA +11007 三浦郡 MIURA +110101 横浜市鶴見区 TURUMI +110102 横浜市神奈川区 KANAGAWA +110103 横浜市西区 NISI +110104 横浜市中区 NAKA +110105 横浜市南区 MINAMI +110106 横浜市保土ヶ谷区 HODOGAYA +110107 横浜市磯子区 ISOGO +110108 横浜市金沢区 KANAZAWA +110109 横浜市港北区 KOUHOKU +110110 横浜市戸塚区 TOTUKA +110111 横浜市港南区 KOUNAN +110112 横浜市旭区 ASAHI +110113 横浜市緑区 MIDORI +110114 横浜市瀬谷区 SEYA +110115 横浜市栄区 SAKAE +110116 横浜市泉区 IZUMI +110117 横浜市青葉区 AOBA +110118 横浜市都筑区 TUZUKI +110301 川崎市川崎区 KAWASAKI +110302 川崎市幸区 SAIWAI +110303 川崎市中原区 NAKAHARA +110304 川崎市高津区 TAKATU +110305 川崎市多摩区 TAMA +110306 川崎市宮前区 MIYAMAE +110307 川崎市麻生区 ASAO +12 % CIBA +1201 千葉市 CIBA +1202 銚子市 CYOSI +1203 市川市 ICIKAWA +1204 船橋市 FUNABASI +1205 館山市 TATEYAMA +1206 木更津市 KISARAZU +1207 松戸市 MATUDO +1208 野田市 NODA +1209 佐原市 SAWARA +1210 茂原市 BOBARA +1211 成田市 NARITA +1212 佐倉市 SAKURA +1213 東金市 TOUGANE +1214 八日市場市 YOKAICIBA +1215 旭市 ASAHI +1216 習志野市 NARASINO +1217 柏市 KASIWA +1218 勝浦市 KATUURA +1219 市原市 ICIHARA +1220 流山市 NAGAREYAMA +1221 八千代市 YACIYO +1222 我孫子市 ABIKO +1223 鴨川市 KAMOGAWA +1224 君津市 KIMITU +1225 鎌ヶ谷市 KAMAGAYA +1226 富津市 FUTTU +1227 浦安市 URAYASU +1228 四街道市 YOTUKAIDO +1229 袖ヶ浦市 SODEGAURA +1230 八街市 YACIMATA +1231 印西市     INZAI +12001 安房郡 AWA +12002 夷隅郡 ISUMI +12003 市原郡* +12004 印旛郡 INBA +12005 海上郡 KAIJO +12006 香取郡 KATORI +12007 君津郡* +12008 山武郡 SANBU +12009 匝瑳郡 SOSA +12010 千葉郡* +12011 長生郡 CYOSEI +12012 東葛飾郡 HIGASIKATUSIKA +120101 千葉市中央区 CYUO +120102 千葉市花見川区 HANAMIGAWA +120103 千葉市稲毛区 INAGE +120104 千葉市若葉区 WAKABA +120105 千葉市緑区 MIDORI +120106 千葉市美浜区 MIHAMA +13 % SAITAMA +1301 浦和市 URAWA +1302 川越市 KAWAGOE +1303 熊谷市 KUMAGAYA +1304 川口市 KAWAGUCI +1305 大宮市 OOMIYA,OMIYA +1306 行田市 GYODA +1307 秩父市 CICIBU +1308 所沢市 TOKOROZAWA +1309 飯能市 HANNO +1310 加須市 KAZO +1311 本庄市 HONJO +1312 東松山市 HIGASIMATUYAMA +1313 岩槻市 IWATUKI +1314 春日部市 KASUKABE +1315 狭山市 SAYAMA +1316 羽生市 HANYU +1317 鴻巣市 KOUNOSU +1318 深谷市 FUKAYA +1319 上尾市 AGEO +1320 与野市 YONO +1321 草加市 SOKA +1322 越谷市 KOSIGAYA +1323 蕨市 WARABI +1324 戸田市 TODA +1325 入間市 IRUMA +1326 鳩ヶ谷市 HATOGAYA +1327 朝霞市 ASAKA +1328 志木市 SIKI +1329 和光市 WAKOU +1330 新座市 NIIZA +1331 桶川市 OKEGAWA +1332 久喜市 KUKI +1333 北本市 KITAMOTO +1334 八潮市 YASIO +1335 上福岡市 KAMIFUKUOKA +1336 富士見市 FUJIMI +1337 三郷市 MISATO +1338 蓮田市 HASUDA +1339 坂戸市 SAKADO +1340 幸手市 SATTE +1341 鶴ケ島市 TURUGASIMA +1342 日高市 HIDAKA +1343 吉川市     YOSIKAWA +13001 入間郡 IRUMA +13002 大里郡 OOSATO,OSATO +13003 北足立郡 KITAADACI +13004 北葛飾郡 KITAKATUSIKA +13005 北埼玉郡 KITASAITAMA +13006 児玉郡 KODAMA +13007 秩父郡 CICIBU +13008 比企郡 HIKI +13009 南埼玉郡 MINAMISAITAMA +14 % IBARAKI +1401 水戸市 MITO +1402 日立市 HITACI +1403 土浦市 TUCIURA +1404 古河市 KOGA +1405 石岡市 ISIOKA +1406 下館市 SIMODATE +1407 結城市 YUKI +1408 竜ヶ崎市 RYUGASAKI +1409 那珂湊市* +1410 下妻市 SIMOTUMA +1411 水海道市 MITUKAIDO +1412 常陸太田市 HITACIOOTA +1413 勝田市* +1414 高萩市 TAKAHAGI +1415 北茨城市 KITAIBARAKI +1416 笠間市 KASAMA +1417 取手市 TORIDE +1418 岩井市 IWAI +1419 牛久市 USIKU +1420 つくば市 TUKUBA +1421 ひたちなか市 HITACINAKA +1422 鹿嶋市     KASIMA +14001 稲敷郡 INASIKI +14002 鹿島郡 KASIMA +14003 北相馬郡 KITASOMA +14004 久慈郡 KUJI +14005 猿島郡 SASIMA +14006 多賀郡 TAGA +14007 筑波郡 TUKUBA +14008 那珂郡 NAKA +14009 行方郡 NAMEGATA +14010 新治郡 NIIHARI +14011 西茨城郡 NISIIBARAKI +14012 東茨城郡 HIGASIIBARAKI +14013 真壁郡 MAKABE +14014 結城郡 YUKI +15 % TOCIGI +1501 宇都宮市 UTUNOMIYA +1502 足利市 ASIKAGA +1503 栃木市 TOCIGI +1504 佐野市 SANO +1505 鹿沼市 KANUMA +1506 日光市 NIKKO +1507 今市市 IMAICI +1508 小山市 OYAMA +1509 真岡市 MOOKA +1510 大田原市 OOTAWARA,OTAWARA +1511 矢板市 YAITA +1512 黒磯市 KUROISO +15001 足利郡* +15002 安蘇郡 ASO +15003 上都賀郡 KAMITUGA +15004 河内郡 KAWACI +15005 塩谷郡 SIOYA +15006 下都賀郡 SIMOTUGA +15007 那須郡 NASU +15008 芳賀郡 HAGA +16 % GUNMA +1601 前橋市 MAEBASI +1602 高崎市 TAKASAKI +1603 桐生市 KIRYU +1604 伊勢崎市 ISEZAKI +1605 太田市 OOTA,OTA +1606 沼田市 NUMATA +1607 館林市 TATEBAYASI +1608 渋川市 SIBUKAWA +1609 藤岡市 FUJIOKA +1610 富岡市 TOMIOKA +1611 安中市 ANNAKA +16001 吾妻郡 AGATUMA +16002 碓氷郡 USUI +16003 邑楽郡 OURA +16004 甘楽郡 KANRA +16005 北群馬郡 KITAGUNMA +16006 群馬郡 GUNMA +16007 佐波郡 SAWA +16008 勢多郡 SETA +16009 多野郡 TANO +16010 利根郡 TONE +16011 新田郡 NITTA +16012 山田郡 YAMADA +17 % YAMANASI +1701 甲府市 KOUFU,KOFU +1702 富士吉田市 FUJIYOSIDA +1703 塩山市 ENZAN +1704 都留市 TURU +1705 山梨市 YAMANASI +1706 大月市 OOTUKI,OTUKI +1707 韮崎市 NIRASAKI +17001 北巨摩郡 KITAKOMA +17002 北都留郡 KITATURU +17003 中巨摩郡 NAKAKOMA +17004 西八代郡 NISIYATUSIRO +17005 東八代郡 HIGASIYATUSIRO +17006 東山梨郡 HIGASIYAMANASI +17007 南巨摩郡 MINAMIKOMA +17008 南都留郡 MINAMITURU +18 % SIZUOKA +1801 静岡市 SIZUOKA +1802 浜松市 HAMAMATU +1803 沼津市 NUMAZU +1804 清水市 SIMIZU +1805 熱海市 ATAMI +1806 三島市 MISIMA +1807 富士宮市 FUJINOMIYA +1808 伊東市 ITOU +1809 島田市 SIMADA +1810 吉原市* +1811 磐田市 IWATA +1812 焼津市 YAIZU +1813 富士市 FUJI +1814 掛川市 KAKEGAWA +1815 藤枝市 FUJIEDA +1816 御殿場市 GOTENBA +1817 袋井市 FUKUROI +1818 天竜市 TENRYU +1819 浜北市 HAMAKITA +1820 下田市 SIMODA +1821 裾野市 SUSONO +1822 湖西市 KOSAI +18001 安倍郡* +18002 引佐郡 INASA +18003 庵原郡 IHARA +18004 磐田郡 IWATA +18005 小笠郡 OGASA +18006 賀茂郡 KAMO +18007 志太郡 SIDA +18008 周智郡 SYUCI +18009 駿東郡 SUNTOU +18010 田方郡 TAGATA +18011 榛原郡 HAIBARA +18012 浜名郡 HAMANA +18013 富士郡 FUJI +19 % GIFU +1901 岐阜市 GIFU +1902 大垣市 OOGAKI,OGAKI +1903 高山市 TAKAYAMA +1904 多治見市 TAJIMI +1905 関市 SEKI +1906 中津川市 NAKATUGAWA +1907 美濃市 MINO +1908 瑞浪市 MIZUNAMI +1909 羽島市 HASIMA +1910 恵那市 ENA +1911 美濃加茂市 MINOKAMO +1912 土岐市 TOKI +1913 各務原市 KAKAMIGAHARA +1914 可児市 KANI +19001 安八郡 ANPACI +19002 稲葉郡* +19003 揖斐郡 IBI +19004 恵那郡 ENA +19005 大野郡 OONO,ONO +19006 海津郡 KAIZU +19007 可児郡 KANI +19008 加茂郡 KAMO +19009 郡上郡 GUJO +19010 土岐郡 TOKI +19011 羽島郡 HASIMA +19012 不破郡 FUWA +19013 益田郡 MASITA +19014 武儀郡 MUGI +19015 本巣郡 MOTOSU +19016 山県郡 YAMAGATA +19017 養老郡 YORO +19018 吉城郡 YOSIKI +20 % AICI +2001 名古屋市 NAGOYA +2002 豊橋市 TOYOHASI +2003 岡崎市 OKAZAKI +2004 一宮市 ICINOMIYA +2005 瀬戸市 SETO +2006 半田市 HANDA +2007 春日井市 KASUGAI +2008 豊川市 TOYOKAWA +2009 津島市 TUSIMA +2010 碧南市 HEKINAN +2011 刈谷市 KARIYA +2012 豊田市 TOYODA +2013 安城市 ANJO +2014 西尾市 NISIO +2015 蒲郡市 KAMAGORI +2016 犬山市 INUYAMA +2017 常滑市 TOKONAME +2018 守山市* +2019 江南市 KOUNAN +2020 尾西市 BISAI +2021 小牧市 KOMAKI +2022 稲沢市 INAZAWA +2023 新城市 SINSIRO +2024 東海市 TOUKAI,TOKAI +2025 大府市 OOBU,OBU +2026 知多市 CITA +2027 高浜市 TAKAHAMA +2028 知立市 CIRYU +2029 尾張旭市 OWARIASAHI +2030 岩倉市 IWAKURA +2031 豊明市 TOYOAKE +2032 日進市 NISSIN +20001 愛知郡 AICI +20002 渥美郡 ATUMI +20003 海部郡 AMA +20004 北設楽郡 KITASITARA +20005 知多郡 CITA +20006 中島郡 NAKASIMA +20007 西春日井郡 NISIKASUGAI +20008 西加茂郡 NISIKAMO +20009 丹羽郡 NIWA +20010 額田郡 NUKATA +20011 葉栗郡 HAGURI +20012 幡豆郡 HAZU +20013 東春日井郡* +20014 東加茂郡 HIGASIKAMO +20015 碧海郡* +20016 宝飯郡 HOI +20017 南設楽郡 MINAMISITARA +20018 八名郡* +200101 名古屋市千種区 CIKUSA +200102 名古屋市東区 HIGASI +200103 名古屋市北区 KITA +200104 名古屋市西区 NISI +200105 名古屋市中村区 NAKAMURA +200106 名古屋市中区 NAKA +200107 名古屋市昭和区 SYOUWA +200108 名古屋市瑞穂区 MIZUHO +200109 名古屋市熱田区 ATUTA +200110 名古屋市中川区 NAKAGAWA +200111 名古屋市港区 MINATO +200112 名古屋市南区 MINAMI +200113 名古屋市守山区 MORIYAMA +200114 名古屋市緑区 MIDORI +200115 名古屋市名東区 MEITOU +200116 名古屋市天白区 TENPAKU +21 % MIE +2101 津市 TU +2102 四日市市 YOKKAICI +2103 伊勢市 ISE +2104 松阪市 MATUSAKA +2105 桑名市 KUWANA +2106 上野市 UENO +2107 鈴鹿市 SUZUKA +2108 名張市 NABARI +2109 尾鷲市 OWASE +2110 亀山市 KAMEYAMA +2111 鳥羽市 TOBA +2112 熊野市 KUMANO +2113 久居市 HISAI +2114 宇治山田市* +21001 安芸郡 AGE +21002 安濃郡* +21003 阿山郡 AYAMA +21004 飯南郡 IINAN +21005 一志郡 ICISI +21006 員弁郡 INABE +21007 河芸郡* +21008 北牟婁郡 KITAMURO +21009 桑名郡 KUWANA +21010 志摩郡 SIMA +21011 鈴鹿郡 SUZUKA +21012 多気郡 TAKI +21013 名賀郡 NAGA +21014 三重郡 MIE +21015 南牟婁郡 MINAMIMURO +21016 度会郡 WATARAI +22 % KYOUTO,KYOTO +2201 京都市 KYOUTO,KYOTO +2202 福知山市 FUKUCIYAMA +2203 舞鶴市 MAIZURU +2204 綾部市 AYABE +2205 宇治市 UJI +2206 宮津市 MIYAZU +2207 亀岡市 KAMEOKA +2208 城陽市 JOYO +2209 長岡京市 NAGAOKAKYO +2210 向日市 MUKOU +2211 八幡市 YAWATA +2212 京田辺市 KYOTANABE +22001 天田郡 AMATA +22002 何鹿郡* +22003 乙訓郡 OTOKUNI +22004 加佐郡 KASA +22005 北桑田郡 KITAKUWADA +22006 久世郡 KUZE +22007 熊野郡 KUMANO +22008 相楽郡 SOURAKU,SORAKU +22009 竹野郡 TAKENO +22010 綴喜郡 TUZUKI +22011 中郡 NAKA +22012 船井郡 FUNAI +22013 南桑田郡* +22014 与謝郡 YOSA +220101 京都市北区 KITA +220102 京都市上京区 KAMIKYO +220103 京都市左京区 SAKYO +220104 京都市中京区 NAKAKYO +220105 京都市東山区 HIGASIYAMA +220106 京都市下京区 SIMOKYO +220107 京都市南区 MINAMI +220108 京都市右京区 UKYO +220109 京都市伏見区 FUSIMI +220110 京都市山科区 YAMASINA +220111 京都市西京区 NISIKYO +23 % SIGA +2301 大津市 OOTU,OTU +2302 彦根市 HIKONE +2303 長浜市 NAGAHAMA +2304 近江八幡市 OOMIHACIMAN,OMIHACIMAN +2305 八日市市 YOKAICI +2306 草津市 KUSATU +2307 守山市 MORIYAMA +23001 伊香郡 IKA +23002 犬上郡 INUKAMI +23003 愛知郡 ECI +23004 蒲生郡 GAMO +23005 神崎郡 KANZAKI +23006 栗太郡 KURITA +23007 甲賀郡 KOUKA +23008 坂田郡 SAKATA +23009 滋賀郡 SIGA +23010 高島郡 TAKASIMA +23011 東浅井郡 HIGASIASAI +23012 野洲郡 YASU +24 % NARA +2401 奈良市 NARA +2402 大和高田市 YAMATOTAKADA +2403 大和郡山市 YAMATOKORIYAMA +2404 天理市 TENRI +2405 橿原市 KASIHARA +2406 桜井市 SAKURAI +2407 五條市 GOJO +2408 御所市 GOSE +2409 生駒市 IKOMA +2410 香芝市 KASIBA +24001 生駒郡 IKOMA +24002 宇陀郡 UDA +24003 宇智郡* +24004 北葛城郡 KITAKATURAGI +24005 磯城郡 SIKI +24006 添上郡 SOEKAMI +24007 高市郡 TAKAICI +24008 南葛城郡* +24009 山辺郡 YAMABE +24010 吉野郡 YOSINO +25 % OOSAKA,OSAKA +2501 大阪市 OOSAKA,OSAKA +2502 堺市 SAKAI +2503 岸和田市 KISIWADA +2504 豊中市 TOYONAKA +2505 布施市* +2506 池田市 IKEDA +2507 吹田市 SUITA +2508 泉大津市 IZUMIOTU +2509 高槻市 TAKATUKI +2510 貝塚市 KAIZUKA +2511 守口市 MORIGUCI +2512 枚方市 HIRAKATA +2513 茨木市 IBARAKI +2514 八尾市 YAO +2515 泉佐野市 IZUMISANO +2516 富田林市 TONDABAYASI +2517 寝屋川市 NEYAGAWA +2518 河内長野市 KAWACINAGANO +2519 枚岡市* +2520 河内市* +2521 松原市 MATUBARA +2522 大東市 DAITOU +2523 和泉市 IZUMI +2524 箕面市 MINO +2525 柏原市 KASIWARA +2526 羽曳野市 HABIKINO +2527 門真市 KADOMA +2528 摂津市 SETTU +2529 藤井寺市 FUJIIDERA +2530 高石市 TAKAISI +2531 東大阪市 HIGASIOSAKA +2532 泉南市 SENNAN +2533 四条畷市 SIJONAWATE +2534 交野市 KATANO +2535 大阪狭山市 OOSAKASAYAMA,OSAKASAYAMA +2536 阪南市 HANNAN +25001 北河内郡* +25002 泉南郡 SENNAN +25003 泉北郡 SENBOKU +25004 豊能郡 TOYONO +25005 中河内郡* +25006 三島郡 MISIMA +25007 南河内郡 MINAMIKAWACI +250101 大阪市北区 KITA +250102 大阪市都島区 MIYAKOJIMA +250103 大阪市福島区 FUKUSIMA +250104 大阪市此花区 KONOHANA +250105 大阪市東区* +250106 大阪市西区 NISI +250107 大阪市港区 MINATO +250108 大阪市大正区 TAISYO +250109 大阪市天王寺区 TENNOUJI,TENNOJI +250110 大阪市南区* +250111 大阪市浪速区 NANIWA +250112 大阪市大淀区* +250113 大阪市西淀川区 NISIYODOGAWA +250114 大阪市東淀川区 HIGASIYODOGAWA +250115 大阪市東成区 HIGASINARI +250116 大阪市生野区 IKUNO +250117 大阪市旭区 ASAHI +250118 大阪市城東区 JOTO +250119 大阪市阿倍野区 ABENO +250120 大阪市住吉区 SUMIYOSI +250121 大阪市東住吉区 HIGASISUMIYOSI +250122 大阪市西成区 NISINARI +250123 大阪市淀川区 YODOGAWA +250124 大阪市鶴見区 TURUMI +250125 大阪市住之江区 SUMINOE +250126 大阪市平野区 HIRANO +250127 大阪市中央区 CYUO +26 % WAKAYAMA +2601 和歌山市 WAKAYAMA +2602 新宮市 SINGU +2603 海南市 KAINAN +2604 田辺市 TANABE +2605 御坊市 GOBO +2606 橋本市 HASIMOTO +2607 有田市 ARIDA +26001 有田郡 ARIDA +26002 伊都郡 ITO +26003 海草郡 KAISO +26004 那賀郡 NAGA +26005 西牟婁郡 NISIMURO +26006 東牟婁郡 HIGASIMURO +26007 日高郡 HIDAKA +27 % HYOGO +2701 神戸市 KOUBE,KOBE +2702 姫路市 HIMEJI +2703 尼崎市 AMAGASAKI +2704 明石市 AKASI +2705 西宮市 NISINOMIYA +2706 洲本市 SUMOTO +2707 芦屋市 ASIYA +2708 伊丹市 ITAMI +2709 相生市 AIOI +2710 豊岡市 TOYOOKA +2711 加古川市 KAKOGAWA +2712 龍野市 TATUNO +2713 赤穂市 AKO +2714 西脇市 NISIWAKI +2715 宝塚市 TAKARAZUKA +2716 三木市 MIKI +2717 高砂市 TAKASAGO +2718 川西市 KAWANISI +2719 小野市 ONO +2720 三田市 SANDA +2721 加西市 KASAI +2722 篠山市 SASAYAMA +27001 赤穂郡 AKO +27002 朝来郡 ASAGO +27003 有馬郡* +27004 出石郡 IZUSI +27005 揖保郡 IBO +27006 印南郡* +27007 加古郡 KAKO +27008 加西郡* +27009 加東郡 KATOU +27010 川辺郡 KAWABE +27011 神崎郡 KANZAKI +27012 城崎郡 KINOSAKI +27013 佐用郡 SAYO +27014 飾磨郡 SIKAMA +27015 宍粟郡 SISO +27016 多可郡 TAKA +27017 多紀郡* +27018 津名郡 TUNA +27019 氷上郡 HIKAMI +27020 美方郡 MIKATA +27021 美嚢郡 MINO +27022 三原郡 MIHARA +27023 武庫郡* +27024 養父郡 YABU +270101 神戸市東灘区 HIGASINADA +270102 神戸市灘区 NADA +270103 神戸市兵庫区 HYOGO +270104 神戸市長田区 NAGATA +270105 神戸市須磨区 SUMA +270106 神戸市垂水区 TARUMI +270107 神戸市北区 KITA +270108 神戸市中央区 CYUO +270109 神戸市西区 NISI +28 % TOYAMA +2801 富山市 TOYAMA +2802 高岡市 TAKAOKA +2803 新湊市 SINMINATO +2804 魚津市 UOZU +2805 氷見市 HIMI +2806 滑川市 NAMERIKAWA +2807 黒部市 KUROBE +2808 礪波市 TONAMI +2809 小矢部市 OYABE +28001 射水郡 IMIZU +28002 上新川郡 KAMINIIKAWA +28003 下新川郡 SIMONIIKAWA +28004 中新川郡 NAKANIIKAWA +28005 西砺波郡 NISITONAMI +28006 婦負郡 NEI +28007 氷見郡* +28008 東砺波郡 HIGASITONAMI +29 % FUKUI +2901 福井市 FUKUI +2902 敦賀市 TURUGA +2903 武生市 TAKEFU +2904 小浜市 OBAMA +2905 大野市 OONO,ONO +2906 勝山市 KATUYAMA +2907 鯖江市 SABAE +29001 足羽郡 ASUWA +29002 今立郡 IMADATE +29003 大飯郡 OOI,OI +29004 大野郡 OONO,ONO +29005 遠敷郡 ONYU +29006 坂井郡 SAKAI +29007 敦賀郡* +29008 南条郡 NANJO +29009 丹生郡 NYU +29010 三方郡 MIKATA +29011 吉田郡 YOSIDA +30 % ISIKAWA +3001 金沢市 KANAZAWA +3002 七尾市 NANAO +3003 小松市 KOMATU +3004 輪島市 WAJIMA +3005 珠洲市 SUZU +3006 加賀市 KAGA +3007 羽咋市 HAKUI +3008 松任市 MATUTOU +30001 石川郡 ISIKAWA +30002 江沼郡 ENUMA +30003 鹿島郡 KASIMA +30004 河北郡 KAHOKU +30005 珠洲郡 SUZU +30006 能美郡 NOMI +30007 羽咋郡 HAKUI +30008 鳳至郡 FUGESI +31 % OKAYAMA +3101 岡山市 OKAYAMA +3102 倉敷市 KURASIKI +3103 津山市 TUYAMA +3104 玉野市 TAMANO +3105 児島市* +3106 玉島市* +3107 笠岡市 KASAOKA +3108 西大寺市* +3109 井原市 IBARA +3110 総社市 SOJA +3111 高梁市 TAKAHASI +3112 新見市 NIIMI +3113 備前市 BIZEN +31001 英田郡 AIDA +31002 赤磐郡 AKAIWA +31003 浅口郡 ASAKUCI +31004 阿哲郡 ATETU +31005 邑久郡 OKU +31006 小田郡 ODA +31007 勝田郡 KATUTA +31008 川上郡 KAWAKAMI +31009 吉備郡 KIBI +31010 久米郡 KUME +31011 児島郡 KOJIMA +31012 後月郡 SITUKI +31013 上道郡* +31014 上房郡 JOBO +31015 都窪郡 TUKUBO +31016 苫田郡 TOMATA +31017 真庭郡 MANIWA +31018 御津郡 MITU +31019 和気郡 WAKE +32 % SIMANE +3201 松江市 MATUE +3202 浜田市 HAMADA +3203 出雲市 IZUMO +3204 益田市 MASUDA +3205 大田市 OODA,ODA +3206 安来市 YASUGI +3207 江津市 KOUZU +3208 平田市 HIRATA +32001 安濃郡* +32002 海士郡* +32003 飯石郡 IISI +32004 邑智郡 OCI +32005 大原郡 OHARA +32006 隠岐郡 OKI +32007 穏地郡* +32008 鹿足郡 KANOASI +32009 周吉郡* +32010 知夫郡* +32011 那賀郡 NAKA +32012 仁多郡 NITA +32013 迩摩郡 NIMA +32014 能義郡 NOGI +32015 簸川郡 HIKAWA +32016 美濃郡 MINO +32017 八束郡 YATUKA +33 % YAMAGUCI +3301 山口市 YAMAGUCI +3302 下関市 SIMONOSEKI +3303 宇部市 UBE +3304 萩市 HAGI +3305 徳山市 TOKUYAMA +3306 防府市 BOFU +3307 下松市 KUDAMATU +3308 岩国市 IWAKUNI +3309 小野田市 ONODA +3310 光市 HIKARI +3311 長門市 NAGATO +3312 柳井市 YANAI +3313 美祢市 MINE +3314 新南陽市 SINNANYOU +33001 厚狭郡 ASA +33002 阿武郡 ABU +33003 大島郡 OOSIMA,OSIMA +33004 大津郡 OOTU,OTU +33005 玖珂郡 KUGA +33006 熊毛郡 KUMAGE +33007 佐波郡 SABA +33008 都濃郡 TUNO +33009 豊浦郡 TOYOURA +33010 美祢郡 MINE +33011 吉敷郡 YOSIKI +34 % TOTTORI +3401 鳥取市 TOTTORI +3402 倉吉市 KURAYOSI +3403 米子市 YONAGO +3404 境港市 SAKAIMINATO +34001 岩美郡 IWAMI +34002 気高郡 KETAKA +34003 西伯郡 SAIHAKU +34004 東伯郡 TOUHAKU +34005 日野郡 HINO +34006 八頭郡 YAZU +35 % HIROSIMA +3501 広島市 HIROSIMA +3502 呉市 KURE +3503 竹原市 TAKEHARA +3504 三原市 MIHARA +3505 尾道市 ONOMICI +3506 因島市 INNOSIMA +3507 松永市* +3508 福山市 FUKUYAMA +3509 府中市 FUCYU +3510 三次市 MIYOSI +3511 庄原市 SYOBARA +3512 大竹市 OOTAKE,OTAKE +3513 東広島市 HIGASIHIROSIMA +3514 廿日市市 HATUKAICI +35001 安芸郡 AKI +35002 安佐郡* +35003 芦品郡 ASINA +35004 賀茂郡 KAMO +35005 甲奴郡 KOUNU +35006 佐伯郡 SAEKI +35007 神石郡 JINSEKI +35008 世羅郡 SERA +35009 高田郡 TAKATA +35010 豊田郡 TOYOTA +35011 沼隈郡 NUMAKUMA +35012 比婆郡 HIBA +35013 深安郡 FUKAYASU +35014 双三郡 FUTAMI +35015 御調郡 MITUGI +35016 山県郡 YAMAGATA +350101 広島市中区 NAKA +350102 広島市東区 HIGASI +350103 広島市南区 MINAMI +350104 広島市西区 NISI +350105 広島市安佐南区 ASAMINAMI +350106 広島市安佐北区 ASAKITA +350107 広島市安芸区 AKI +350108 広島市佐伯区 SAEKI +36 % KAGAWA +3601 高松市 TAKAMATU +3602 丸亀市 MARUGAME +3603 坂出市 SAKAIDE +3604 善通寺市 ZENTUJI +3605 観音寺市 KANONJI +36001 綾歌郡 AYAUTA +36002 大川郡 OOKAWA,OKAWA +36003 香川郡 KAGAWA +36004 木田郡 KITA +36005 小豆郡 SYOZU +36006 仲多度郡 NAKATADO +36007 三豊郡 MITOYO +37 % TOKUSIMA +3701 徳島市 TOKUSIMA +3702 鳴門市 NARUTO +3703 小松島市 KOMATUSIMA +3704 阿南市 ANAN +37001 阿波郡 AWA +37002 板野郡 ITANO +37003 麻植郡 OE +37004 海部郡 KAIFU +37005 勝浦郡 KATUURA +37006 那賀郡 NAKA +37007 名西郡 MYOZAI +37008 名東郡 MYODO +37009 美馬郡 MIMA +37010 三好郡 MIYOSI +38 % EHIME +3801 松山市 MATUYAMA +3802 今治市 IMABARI +3803 宇和島市 UWAJIMA +3804 八幡浜市 YAWATAHAMA +3805 新居浜市 NIHAMA +3806 西条市 SAIJO +3807 大洲市 OOZU,OZU +3808 伊予三島市 IYOMISIMA +3809 川之江市 KAWANOE +3810 伊予市 IYO +3811 北条市 HOJO +3812 東予市 TOUYO +38001 伊予郡 IYO +38002 宇摩郡 UMA +38003 越智郡 OCI +38004 温泉郡 ONSEN +38005 上浮穴郡 KAMIUKENA +38006 喜多郡 KITA +38007 北宇和郡 KITAUWA +38008 周桑郡 SYUSO +38009 新居郡* +38010 西宇和郡 NISIUWA +38011 東宇和郡 HIGASIUWA +38012 南宇和郡 MINAMIUWA +39 % KOUCI,KOCI +3901 高知市 KOUCI,KOCI +3902 室戸市 MUROTO +3903 安芸市 AKI +3904 土佐市 TOSA +3905 須崎市 SUSAKI +3906 中村市 NAKAMURA +3907 宿毛市 SUKUMO +3908 土佐清水市 TOSASIMIZU +3909 南国市 NANGOKU +39001 吾川郡 AGAWA +39002 安芸郡 AKI +39003 香美郡 KAMI +39004 高岡郡 TAKAOKA +39005 土佐郡 TOSA +39006 長岡郡 NAGAOKA +39007 幡多郡 HATA +40 % FUKUOKA +4001 福岡市 FUKUOKA +4002 小倉市* +4003 門司市* +4004 八幡市* +4005 戸畑市* +4006 若松市* +4007 久留米市 KURUME +4008 大牟田市 OOMUTA,OMUTA +4009 直方市 NOOGATA,NOGATA +4010 飯塚市 IIZUKA +4011 田川市 TAGAWA +4012 柳川市 YANAGAWA +4013 甘木市 AMAGI +4014 山田市 YAMADA +4015 八女市 YAME +4016 筑後市 CIKUGO +4017 大川市 OOKAWA,OKAWA +4018 行橋市 YUKUHASI +4019 豊前市 BUZEN +4020 中間市 NAKAMA +4021 北九州市 KITAKYUSYU +4022 小郡市 OGOORI,OGORI +4023 春日市 KASUGA +4024 筑紫野市 CIKUSINO +4025 大野城市 OONOJO,ONOJO +4026 宗像市 MUNAKATA +4027 太宰府市 DAZAIFU +4028 前原市 MAEBARU +4029 古賀市     KOGA +40001 朝倉郡 ASAKURA +40002 糸島郡 ITOSIMA +40003 浮羽郡 UKIHA +40004 遠賀郡 ONGA +40005 粕屋郡 KASUYA +40006 嘉穂郡 KAHO +40007 鞍手郡 TEKURA +40008 早良郡* +40009 田川郡 TAGAWA +40010 筑紫郡 CIKUSI +40011 築上郡 CIKUJO +40012 三井郡 MII +40013 三池郡 MIIKE +40014 三潴郡 MIZUMA +40015 京都郡 MIYAKO +40016 宗像郡 MUNAKATA +40017 山門郡 YAMATO +40018 八女郡 YAME +400101 福岡市東区 HIGASI +400102 福岡市博多区 HAKATA +400103 福岡市中央区 CYUO +400104 福岡市南区 MINAMI +400105 福岡市西区 NISI +400106 福岡市城南区 JYOUNAN,JYONAN +400107 福岡市早良区 SAWARA +402101 北九州市門司区 MOJI +402102 北九州市若松区 WAKAMATU +402103 北九州市戸畑区 TOBATA +402104 北九州市小倉北区 KOKURAKITA +402105 北九州市小倉南区 KOKURAMINAMI +402106 北九州市八幡東区 YAHATAHIGASI +402107 北九州市八幡西区 YAHATANISI +41 % SAGA +4101 佐賀市 SAGA +4102 唐津市 KARATU +4103 鳥栖市 TOSU +4104 多久市 TAKU +4105 伊万里市 IMARI +4106 武雄市 TAKEO +4107 鹿島市 KASIMA +41001 小城郡 OGI +41002 神埼郡 KANZAKI +41003 杵島郡 KISIMA +41004 佐賀郡 SAGA +41005 西松浦郡 NISIMATUURA +41006 東松浦郡 HIGASIMATUURA +41007 藤津郡 FUJITU +41008 三養基郡 MIYAKI +42 % NAGASAKI +4201 長崎市 NAGASAKI +4202 佐世保市 SASEBO +4203 島原市 SIMABARA +4204 諌早市 ISAHAYA +4205 大村市 OOMURA,OMURA +4206 福江市 FUKUE +4207 平戸市 HIRADO +4208 松浦市 MATUURA +42001 壱岐郡 IKI +42002 上県郡 KAMIAGATA +42003 北高来郡 KITATAKAKI +42004 北松浦郡 KITAMATUURA +42005 下県郡 SIMOAGATA +42006 西彼杵郡 NISISONOGI +42007 東彼杵郡 HIGASISONOGI +42008 南高来郡 MINAMITAKAKI +42009 南松浦郡 MINAMIMATUURA +43 % KUMAMOTO +4301 熊本市 KUMAMOTO +4302 八代市 YATUSIRO +4303 人吉市 HITOYOSI +4304 荒尾市 ARAO +4305 水俣市 MINAMATA +4306 玉名市 TAMANA +4307 本渡市 HONDO +4308 山鹿市 YAMAGA +4309 牛深市 USIBUKA +4310 菊池市 KIKUCI +4311 宇土市 UTO +43001 芦北郡 ASIKITA +43002 阿蘇郡 ASO +43003 天草郡 AMAKUSA +43004 宇土郡 UTO +43005 上益城郡 KAMIMASIKI +43006 鹿本郡 KAMOTO +43007 菊池郡 KIKUCI +43008 球磨郡 KUMA +43009 下益城郡 SIMOMASIKI +43010 玉名郡 TAMANA +43011 飽託郡* +43012 八代郡 YATUSIRO +44 % OOITA,OITA +4401 大分市 OOITA,OITA +4402 別府市 BEPPU +4403 中津市 NAKATU +4404 日田市 HITA +4405 佐伯市 SAIKI +4406 臼杵市 USUKI +4407 津久見市 TUKUMI +4408 竹田市 TAKEDA +4409 鶴崎市* +4410 豊後高田市 BUNGOTAKADA +4411 杵築市 KITUKI +4412 宇佐市 USA +44001 宇佐郡 USA +44002 大分郡 OOITA,OITA +44003 大野郡 OONO,ONO +44004 北海部郡 KITAAMABE +44005 玖珠郡 KUSU +44006 下毛郡 SIMOGE +44007 直入郡 NAOIRI +44008 西国東郡 NISIKUNISAKI +44009 速見郡 HAYAMI +44010 東国東郡 HIGASIKUNISAKI +44011 日田郡 HITA +44012 南海部郡 MINAMIAMABE +45 % MIYAZAKI +4501 宮崎市 MIYAZAKI +4502 都城市 MIYAKONOJO +4503 延岡市 NOBEOKA +4504 日南市 NICINAN +4505 小林市 KOBAYASI +4506 日向市 HYUGA +4507 串間市 KUSIMA +4508 西都市 SAITO +4509 えびの市 EBINO +45001 北諸県郡 KITAMOROKATA +45002 児湯郡 KOYU +45003 西臼杵郡 NISIUSUKI +45004 西諸県郡 NISIMOROKATA +45005 東臼杵郡 HIGASIUSUKI +45006 東諸県郡 HIGASIMOROKATA +45007 南那珂郡 MINAMINAKA +45008 宮崎郡 MIYAZAKI +46 % KAGOSIMA +4601 鹿児島市 KAGOSIMA +4602 川内市 SENDAI +4603 鹿屋市 KANOYA +4604 枕崎市 MAKURAZAKI +4605 串木野市 KUSIKINO +4606 阿久根市 AKUNE +4607 出水市 IZUMI +4608 名瀬市 NAZE +4609 大口市 OOKUCI,OKUCI +4610 指宿市 IBUSUKI +4611 加世田市 KASEDA +4612 国分市 KOKUBU +4613 谷山市* +4614 西之表市 NISINOOMOTE +4615 垂水市 TARUMIZU +46001 姶良郡 AIRA +46002 伊佐郡 ISA +46003 出水郡 IZUMI +46004 揖宿郡 IBUSUKI +46005 大島郡 OOSIMA,OSIMA +46006 鹿児島郡 KAGOSIMA +46007 川辺郡 KAWANABE +46008 肝属郡 KIMOTUKI +46009 熊毛郡 KUMAGE +46010 薩摩郡 SATUMA +46011 曽於郡 SOO +46012 日置郡 HIOKI +47 % OKINAWA +4701 那覇市 NAHA +4702 石川市 ISIKAWA +4703 平良市 HIRARA +4704 石垣市 ISIGAKI +4705 コザ市* +4706 宜野湾市 GINOWAN +4707 具志川市 GUSIKAWA +4708 名護市 NAGO +4709 浦添市 URASOE +4710 糸満市 ITOMAN +4711 沖縄市 OKINAWA +47001 国頭郡 KUNIGAMI +47002 島尻郡 SIMAJIRI +47003 中頭郡 NAKAGAMI +47004 宮古郡 MIYAKO +47005 八重山郡 YAEYAMA + \ No newline at end of file diff --git a/MMLink.cpp b/MMLink.cpp new file mode 100644 index 0000000..2c54902 --- /dev/null +++ b/MMLink.cpp @@ -0,0 +1,408 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "MMLink.h" +//--------------------------------------------------------------------------- +__fastcall CMMList::CMMList(void) +{ + m_pList = NULL; +} +//--------------------------------------------------------------------------- +__fastcall CMMList::~CMMList() +{ + delete m_pList; +} +//--------------------------------------------------------------------------- +int __fastcall CMMList::QueryList(LPCSTR pFilter) +{ + if( m_pList == NULL ) m_pList = new TStringList; + m_pList->Clear(); + m_FilterLen = strlen(pFilter); + + HANDLE hFind; + WIN32_FIND_DATA fd; + + char Name[MAX_PATH]; + sprintf(Name, "%s*.%s", sys.m_BgnDir, pFilter); + hFind = ::FindFirstFile(Name, &fd); + if( hFind != INVALID_HANDLE_VALUE ){ + while(1){ + m_pList->Add(fd.cFileName); + if( !FindNextFile(hFind, &fd) ) break; + } + ::FindClose(hFind); + } + return m_pList->Count; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall CMMList::GetItemName(int n) +{ + if( n < 0 ) return NULL; + if( n >= m_pList->Count ) return NULL; + + m_Name = m_pList->Strings[n].c_str(); + LPSTR p = lastp(m_Name.c_str()); + p -= m_FilterLen; + *p = 0; + return m_Name.c_str(); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall CMMList::GetFileName(int n) +{ + if( n < 0 ) return NULL; + if( n >= m_pList->Count ) return NULL; + + m_Name = m_pList->Strings[n]; + return m_Name.c_str(); +} +//--------------------------------------------------------------------------- +int __fastcall CMMList::IndexOf(LPCSTR pKey) +{ + for( int i = 0; i < m_pList->Count; i++ ){ + if( !strcmpi(GetItemName(i), pKey) ) return i; + } + return -1; +} +//*************************************************************************** +// CMMLink class +//--------------------------------------------------------------------------- +__fastcall CMMLink::CMMLink(HWND hWnd, UINT uMsg) +{ + m_hLib = NULL; + m_hWnd = hWnd; + m_uMsg = uMsg; + m_Caps = 0; +} +//--------------------------------------------------------------------------- +__fastcall CMMLink::~CMMLink() +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::FreeLib(void) +{ + if( m_hLib ){ + FreeLibrary(m_hLib); + m_hLib = NULL; + } +} +//--------------------------------------------------------------------------- +FARPROC __fastcall CMMLink::GetProc(LPCSTR pName) +{ + if( !m_hLib ) return NULL; + + FARPROC fn = ::GetProcAddress(m_hLib, pName+1); + if( fn == NULL ){ + fn = ::GetProcAddress(m_hLib, pName); + if( fn == NULL ) FreeLib(); + } + return fn; +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::Close(void) +{ + if( IsLib() ){ + fmmlClose(); + FreeLib(); + } + m_Connected = FALSE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CMMLink::Open(LPCSTR pItemName) +{ + Close(); + + m_ItemName = pItemName; + m_SessionName = m_ItemName; + char LibName[MAX_PATH]; + if( !*GetEXT(pItemName) ){ + sprintf(LibName, "%s.mml", pItemName); + pItemName = LibName; + } + + m_hLib = ::LoadLibrary(pItemName); + if( m_hLib ){ + + fmmlOpen = (tmmlOpen)GetProc("_mmlOpen"); + fmmlClose = (tmmlClose)GetProc("_mmlClose"); + fmmlSetHandle = (tmmlSetHandle)GetProc("_mmlSetHandle"); + fmmlIsCap = (tmmlIsCap)GetProc("_mmlIsCap"); + fmmlIsConnected = (tmmlIsConnected)GetProc("_mmlIsConnected"); + fmmlGetSessionName = (tmmlGetSessionName)GetProc("_mmlGetSessionName"); + fmmlQuery = (tmmlQuery)GetProc("_mmlQuery"); + fmmlSetFreq = (tmmlSetFreq)GetProc("_mmlSetFreq"); + fmmlLog = (tmmlLog)GetProc("_mmlLog"); + fmmlLogClear = (tmmlLogClear)GetProc("_mmlLogClear"); + fmmlSetPTT = (tmmlSetPTT)GetProc("_mmlSetPTT"); + fmmlOnCopyData = (tmmlOnCopyData)GetProc("_mmlOnCopyData"); + fmmlEventVFO = (tmmlEventVFO)GetProc("_mmlEventVFO"); + + if( m_hLib ){ + if( fmmlOpen(m_hWnd, m_uMsg) ){ + m_Caps = fmmlIsCap(); + } + else { + FreeLib(); + } + } + } + return IsLib(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::SetHandle(HWND hWnd, UINT uMsg) +{ + m_hWnd = hWnd; + m_uMsg = uMsg; + if( !IsLib() ) return; + fmmlSetHandle(hWnd, m_uMsg); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::NotifySession(LPCSTR pSession) +{ + if( pSession ){ + m_Connected = TRUE; + m_SessionName = pSession; + } + else { + m_Connected = FALSE; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CMMLink::IsConnected(void) +{ + if( !IsLib() ) return FALSE; + if( m_Caps & capNOTIFYSESSION ) return m_Connected; + return fmmlIsConnected(); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall CMMLink::GetSessionName(void) +{ + if( !IsLib() ) return NULL; + if( m_Caps & capNOTIFYSESSION ) return m_SessionName.c_str(); + return fmmlGetSessionName(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::Query(LPCSTR pCall) +{ + if( !IsLib() ) return; + fmmlQuery(pCall); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::SetFreq(LPCSTR pFreq) +{ + if( !IsLib() ) return; + fmmlSetFreq(pFreq); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::SetPTT(int ptt) +{ + if( !IsLib() ) return; + fmmlSetPTT(ptt); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::LogWrite(SDMMLOG *sp, int sw) +{ + if( !IsLib() ) return; + mmLOGDATA ml; + ConvFormat(&ml, sp); + fmmlLog(&ml, sw); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::Clear(void) +{ + if( !IsLib() ) return; + fmmlLogClear(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::EventVFO(void) +{ + if( !IsLib() ) return; + fmmlEventVFO(); +} +//--------------------------------------------------------------------------- +LONG __fastcall CMMLink::OnCopyData(HWND hSender, const COPYDATASTRUCT *pcds) +{ + if( !IsLib() ) return FALSE; + if( !(m_Caps & capWMCOPYDATA) ) return FALSE; + return fmmlOnCopyData(hSender, pcds); +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::SetTime(SYSTEMTIME *tp, int sw) +{ + if( sw ){ + m_TimeLogOFF = *tp; + } + else { + m_TimeLogON = *tp; + } +} +//--------------------------------------------------------------------------- +void __fastcall CMMLink::ConvFormat(mmLOGDATA *pLog, const SDMMLOG *sp) +{ + memset(pLog, 0, sizeof(mmLOGDATA)); + + if( sp->btime ) pLog->m_TimeLogON = m_TimeLogON; + if( sp->etime ) pLog->m_TimeLogOFF = m_TimeLogOFF; + StrCopy(pLog->m_Call, sp->call, sizeof(pLog->m_Call)- 1); + strcpy(pLog->m_Mode, Log.GetModeString(sp->mode)); + strcpy(pLog->m_Freq, Log.GetFreqString(sp->band, sp->fq)); + memcpy(pLog->m_His, sp->ur, sizeof(pLog->m_His)); + memcpy(pLog->m_My, sp->my, sizeof(pLog->m_My)); + StrCopy(pLog->m_Name, sp->name, sizeof(pLog->m_Name)- 1); + StrCopy(pLog->m_QTH, sp->qth, sizeof(pLog->m_QTH)- 1); + StrCopy(pLog->m_Pow, sp->pow, sizeof(pLog->m_Pow)- 1); + StrCopy(pLog->m_Note, sp->rem, sizeof(pLog->m_Note)- 1); + StrCopy(pLog->m_QSL, sp->qsl, sizeof(pLog->m_QSL)- 1); + StrCopy(pLog->m_DXCC, sp->opt1, sizeof(pLog->m_DXCC)- 1); + StrCopy(pLog->m_Cont, sp->opt2, sizeof(pLog->m_Cont)- 1); + pLog->m_QSLS = sp->send; + pLog->m_QSLR = sp->recv; +} + + +//*************************************************************************** +// CMMRadio class +//--------------------------------------------------------------------------- +__fastcall CMMRadio::CMMRadio(HWND hWnd, UINT uMsg) +{ + m_hLib = NULL; + m_hWnd = hWnd; + m_uMsg = uMsg; +} +//--------------------------------------------------------------------------- +__fastcall CMMRadio::~CMMRadio() +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::FreeLib(void) +{ + if( m_hLib ){ + FreeLibrary(m_hLib); + m_hLib = NULL; + } +} +//--------------------------------------------------------------------------- +FARPROC __fastcall CMMRadio::GetProc(LPCSTR pName) +{ + if( !m_hLib ) return NULL; + + FARPROC fn = ::GetProcAddress(m_hLib, pName+1); + if( fn == NULL ){ + fn = ::GetProcAddress(m_hLib, pName); + if( fn == NULL ) FreeLib(); + } + return fn; +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::Close(void) +{ + if( IsLib() ){ + fmmrpClose(); + FreeLib(); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CMMRadio::Open(LPCSTR pItemName) +{ + Close(); + + m_ItemName = pItemName; + char LibName[MAX_PATH]; + if( !*GetEXT(pItemName) ){ + sprintf(LibName, "%s.mmr", pItemName); + pItemName = LibName; + } + m_hLib = ::LoadLibrary(pItemName); + if( m_hLib ){ + + fmmrpOpen = PROC(mmrpOpen); + fmmrpClose = PROC(mmrpClose); + fmmrpSetHandle = PROC(mmrpSetHandle); + fmmrpGetStatus = PROC(mmrpGetStatus); + fmmrpSetPTT = PROC(mmrpSetPTT); + fmmrpPutChar = PROC(mmrpPutChar); + fmmrpGetChar = PROC(mmrpGetChar); + fmmrpPolling = PROC(mmrpPolling); + fmmrpGetFreq = PROC(mmrpGetFreq); + fmmrpGetDefCommand = PROC(mmrpGetDefCommand); + + if( m_hLib ){ + if( !fmmrpOpen(m_hWnd, m_uMsg) ){ + FreeLib(); + } + } + } + return IsLib(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::SetHandle(HWND hWnd, UINT uMsg) +{ + m_hWnd = hWnd; + m_uMsg = uMsg; + if( !IsLib() ) return; + fmmrpSetHandle(hWnd, uMsg); +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::SetPTT(int ptt) +{ + if( !IsLib() ) return; + fmmrpSetPTT(ptt); +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::PutChar(BYTE c) +{ + if( !IsLib() ) return; + fmmrpPutChar(c); +} +//--------------------------------------------------------------------------- +BYTE __fastcall CMMRadio::GetChar(void) +{ + if( !IsLib() ) return 0; + return fmmrpGetChar(); +} +//--------------------------------------------------------------------------- +DWORD __fastcall CMMRadio::GetStatus(void) +{ + if( !IsLib() ) return 0; + return fmmrpGetStatus(); +} +//--------------------------------------------------------------------------- +void __fastcall CMMRadio::Polling(void) +{ + if( !IsLib() ) return; + fmmrpPolling(); +} +//--------------------------------------------------------------------------- +DWORD __fastcall CMMRadio::GetFreq(void) +{ + if( !IsLib() ) return 0; + return fmmrpGetFreq(); +} +//--------------------------------------------------------------------------- +DWORD __fastcall CMMRadio::GetDefCommand(void) +{ + if( !IsLib() ) return 0; + return fmmrpGetDefCommand(); +} + diff --git a/MMLink.h b/MMLink.h new file mode 100644 index 0000000..80eaded --- /dev/null +++ b/MMLink.h @@ -0,0 +1,154 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + + +#ifndef MMLinkH +#define MMLinkH + +#include "ComLib.h" +#include "LogConv.h" +#include "mml.h" +#include "mmrp.h" + +#define PROC(Key) ((t##Key)GetProc("_" #Key)) + +class CMMList +{ +private: + TStringList *m_pList; + AnsiString m_Name; + int m_FilterLen; +public: + __fastcall CMMList(void); + __fastcall ~CMMList(); +public: // List functions + int __fastcall QueryList(LPCSTR pFilter); + int __fastcall GetCount(void){return m_pList->Count;}; + LPCSTR __fastcall GetItemName(int n); + LPCSTR __fastcall GetFileName(int n); + int __fastcall IndexOf(LPCSTR pKey); + inline BOOL __fastcall IsQuery(void){return m_pList != NULL;}; +}; + +class CMMLink +{ +private: + AnsiString m_ItemName; + + HWND m_hWnd; + UINT m_uMsg; + + //HANDLE m_hLib; + HINSTANCE m_hLib; //ja7ude 0522 + DWORD m_Caps; + + int m_Connected; + AnsiString m_SessionName; + + SYSTEMTIME m_TimeLogON; + SYSTEMTIME m_TimeLogOFF; +private: + tmmlOpen fmmlOpen; + tmmlClose fmmlClose; + tmmlSetHandle fmmlSetHandle; + tmmlIsCap fmmlIsCap; + tmmlIsConnected fmmlIsConnected; + tmmlGetSessionName fmmlGetSessionName; + tmmlQuery fmmlQuery; + tmmlSetFreq fmmlSetFreq; + tmmlLog fmmlLog; + tmmlLogClear fmmlLogClear; + tmmlSetPTT fmmlSetPTT; + tmmlOnCopyData fmmlOnCopyData; + tmmlEventVFO fmmlEventVFO; +private: + void __fastcall FreeLib(void); + FARPROC __fastcall GetProc(LPCSTR pName); + void __fastcall ConvFormat(mmLOGDATA *pLog, const SDMMLOG *sp); +public: + __fastcall CMMLink(HWND hWnd, UINT uMsg); + __fastcall ~CMMLink(); +public: // LogLink functions + BOOL __fastcall Open(LPCSTR pLibName); + void __fastcall Close(void); + void __fastcall SetHandle(HWND hWnd, UINT uMsg); + inline BOOL __fastcall IsLib(void){ return (m_hLib != NULL);}; + inline LPCSTR __fastcall GetItemName(void){return m_ItemName.c_str();}; + + void __fastcall NotifySession(LPCSTR pSession); + + BOOL __fastcall IsConnected(void); + LPCSTR __fastcall GetSessionName(void); + void __fastcall Query(LPCSTR pCall); + void __fastcall SetFreq(LPCSTR pFreq); + void __fastcall SetPTT(int ptt); + void __fastcall LogWrite(SDMMLOG *sp, int sw); + void __fastcall Clear(void); + void __fastcall EventVFO(void); + LONG __fastcall OnCopyData(HWND hSender, const COPYDATASTRUCT *pcds); + inline DWORD __fastcall GetCaps(void){return m_Caps;}; + void __fastcall SetTime(SYSTEMTIME *tp, int sw); + +}; + + +class CMMRadio +{ +private: + AnsiString m_ItemName; + + //HANDLE m_hLib; + HINSTANCE m_hLib; + HWND m_hWnd; + UINT m_uMsg; + +private: + tmmrpSetHandle fmmrpSetHandle; + tmmrpOpen fmmrpOpen; + tmmrpClose fmmrpClose; + tmmrpGetStatus fmmrpGetStatus; + tmmrpSetPTT fmmrpSetPTT; + tmmrpPutChar fmmrpPutChar; + tmmrpGetChar fmmrpGetChar; + tmmrpPolling fmmrpPolling; + tmmrpGetFreq fmmrpGetFreq; + tmmrpGetDefCommand fmmrpGetDefCommand; + +private: + void __fastcall FreeLib(void); + FARPROC __fastcall GetProc(LPCSTR pName); +public: + __fastcall CMMRadio(HWND hWnd, UINT uMsg); + __fastcall ~CMMRadio(); +public: + void __fastcall SetHandle(HWND hWnd, UINT uMsg); + BOOL __fastcall Open(LPCSTR pLibName); + void __fastcall Close(void); + inline BOOL __fastcall IsLib(void){ return (m_hLib != NULL);}; + inline LPCSTR __fastcall GetItemName(void){return m_ItemName.c_str();}; + + void __fastcall SetPTT(int ptt); + void __fastcall PutChar(BYTE c); + BYTE __fastcall GetChar(void); + DWORD __fastcall GetStatus(void); + void __fastcall Polling(void); + DWORD __fastcall GetFreq(void); + DWORD __fastcall GetDefCommand(void); +}; +#endif diff --git a/MMVARI.BPR b/MMVARI.BPR new file mode 100644 index 0000000..755e3d8 --- /dev/null +++ b/MMVARI.BPR @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[Language] +ActiveLang= +ProjectLang= +RootDir= + + \ No newline at end of file diff --git a/MMVARI.cbproj b/MMVARI.cbproj new file mode 100644 index 0000000..d670749 --- /dev/null +++ b/MMVARI.cbproj @@ -0,0 +1,445 @@ +サソ + + {B74A1F86-E21B-4660-8AD0-C595B4167159} + CppVCLApplication + MMVARI.cpp + True + Debug + 14.6 + Application + VCL + Win32 + 1 + + + true + + + true + Base + true + + + true + Base + true + + + true + Base + true + + + true + Cfg_1 + true + true + + + true + Cfg_1 + true + true + + + true + Base + true + + + true + Cfg_2 + true + true + + + true + Cfg_2 + true + true + + + Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) + CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= + 1041 + rtl.lib;vcl.lib + vclx.bpi;rtl.bpi;vcl.bpi;dbrtl.bpi;vcldb.bpi;bdertl.bpi;vcldbx.bpi;bcbsmp.bpi;teeui.bpi;vclsmp.bpi;teedb.bpi;tee.bpi;ibsmp.bpi;inetdb.bpi;inet.bpi;$(PackageImports) + .\;$(BDS)\lib;$(BDS)\lib\obj;$(DCC_UnitSearchPath) + Windows + true + ..\vsais10;res;$(BDS)\include;$(BDS)\include\vcl;$(BRCC_IncludePath) + true + ..\vsais10;res;$(BDS)\include;$(BDS)\include\vcl;$(BCC_IncludePath) + .\;$(BDS)\lib;$(BDS)\lib\obj;$(DCC_IncludePath) + ..\vsais10;res;$(BDS)\include;$(BDS)\include\vcl;$(TASM_IncludePath) + . + true + rtl.lib;vcl.lib + None + /w2 + exe + JPHNE + -M + ..\vsais10;res;$(BDS)\lib\obj;$(BDS)\lib;$(BDS)\lib\psdk;$(ILINK_LibraryPath) + + + Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) + -tWM -Tkh30000 -Vx -d -Ve + $(BDSINCLUDE)\windows\vcl;$(IncludePath) + $(BDS)\bin\default_app.manifest + 1033 + MMVARI_Icon.ico + true + + + $(BDSINCLUDE)\windows\vcl;$(IncludePath) + MMVARI_Icon.ico + + + $(BDS)\lib\debug;$(ILINK_LibraryPath);$(ILINK_LibraryPath) + DEBUG;$(DCC_Define);$(DCC_Define) + true + Debug_Build + true + true + true + true + Full + -M -V + true + true + false + + + None + true + -tWM -Tkh30000 -Vx -d -Ve -k + 1033 + _DEBUG;$(BCC_Defines);$(BCC_Defines) + + + _DEBUG;$(BCC_Defines);$(BCC_Defines) + + + Release_Build + -M -$O+ + $(BDS)\lib\release;$(ILINK_LibraryPath);$(ILINK_LibraryPath) + + + -tWM -Tkh30000 -Vx -d -Ve -r + NDEBUG;$(BCC_Defines);$(BCC_Defines) + + + NDEBUG;$(BCC_Defines);$(BCC_Defines) + + + + 33 +
ClockAdjDlg
+ ClockAdj.h + 17 +
+ + 28 + CLX.h + 2 + + + 30 +
CodeView
+ CodeVw.h + 16 +
+ + 7 + ComLib.h + 23 + + + 35 + Comm.h + 11 + + + 25 + country.h + 1 + + + 30 + cradio.h + 16 + + + 3 + DSP.h + 27 + + + 8 + Dump.h + 22 + + + 34 +
FileEdit
+ FEdit.h + 14 +
+ + 6 + Fft.h + 20 + + + 36 +
FreqDispDlg
+ FreqDisp.h + 10 +
+ + 36 + Hamlog5.h + 10 + + + 33 +
InputWinDlg
+ InputWin.h + 17 +
+ + 4 + LogConv.h + 24 + + + 6 + LogFile.h + 20 + + + 5 + Loglink.h + 21 + + + 8 +
LogListDlg
+ LogList.h + 22 +
+ +
LogSetDlg
+ LogSet.h + 19 +
+ + 9 +
MacEditDlg
+ MacEdit.h + 29 +
+ + 37 +
MacroKeyDlg
+ MacroKey.h + 13 +
+ + 4 +
MainVARI
+ Main.h + 24 +
+ + -1 + mfsk.h + 1 + + + 3 + Mmcg.h + 27 + + + 28 +
MmcgDlgBox
+ MmcgDlg.h + 2 +
+ + 7 + MMLink.h + 23 + + + -1 + 0 + + + 32 + 18 + + + 38 +
OptDlgBox
+ Option.h + 12 +
+ + 32 +
PlayDlgBox
+ PlayDlg.h + 18 +
+ + 26 +
QSODlgBox
+ Qsodlg.h + 0 +
+ + 9 +
RADIOSetDlg
+ RadioSet.h + 29 +
+ + 38 +
RMenuDialog
+ RMenuDlg.h + 12 +
+ + 31 +
RxViewDlg
+ RxView.h + 15 +
+ + 35 +
TestDlg
+ Test.h + 11 +
+ + 37 +
TH5LenDlg
+ TH5Len.h + 13 +
+ + 34 +
TrackDlgBox
+ TrackDlg.h + 14 +
+ + 31 +
VerDspDlg
+ VerDsp.h + 15 +
+ + 5 + Wave.h + 21 + + + + + + + + + + + + + + + + + + + + + + + + Cfg_2 + Base + + + Base + + + Cfg_1 + Base + +
+ + + + CPlusPlusBuilder.Personality.12 + CppVCLApplication + + + + False + False + 1 + 0 + 0 + 0 + False + False + False + False + False + 1041 + 932 + + + + + 1.0.0.0 + + + + + + 1.0.0.0 + + + + $(BCB)\source\vcl + + + + + 0 + + + 0 + 0 + 0 + + + False + True + True + + + MMVARI.cpp + + + + True + False + + + 12 + +
diff --git a/MMVARI.cbproj.local b/MMVARI.cbproj.local new file mode 100644 index 0000000..b3811b7 --- /dev/null +++ b/MMVARI.cbproj.local @@ -0,0 +1,2 @@ +サソ + diff --git a/MMVARI.cpp b/MMVARI.cpp new file mode 100644 index 0000000..1b85160 --- /dev/null +++ b/MMVARI.cpp @@ -0,0 +1,76 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +USEUNIT("mfsk.cpp"); +USEUNIT("CLX.cpp"); +USEUNIT("DSP.cpp"); +USEFORM("Main.cpp", MainVARI); +USEUNIT("Wave.cpp"); +USEUNIT("Fft.cpp"); +USEUNIT("ComLib.cpp"); +USEUNIT("Dump.cpp"); +USEFORM("MacEdit.cpp", MacEditDlg); +USEFORM("FreqDisp.cpp", FreqDispDlg); +USEUNIT("Comm.cpp"); +USEFORM("Option.cpp", OptDlgBox); +USEFORM("MacroKey.cpp", MacroKeyDlg); +USEFORM("FEdit.cpp", FileEdit); +USEFORM("VerDsp.cpp", VerDspDlg); +USEFORM("CodeVw.cpp", CodeView); +USEFORM("InputWin.cpp", InputWinDlg); +USEFORM("PlayDlg.cpp", PlayDlgBox); +USEFORM("LogSet.cpp", LogSetDlg); +USEUNIT("LogFile.cpp"); +USEUNIT("Loglink.cpp"); +USEFORM("LogList.cpp", LogListDlg); +USEUNIT("MMLink.cpp"); +USEUNIT("LogConv.cpp"); +USEUNIT("country.cpp"); +USEFORM("Qsodlg.cpp", QSODlgBox); +USEUNIT("Mmcg.cpp"); +USEFORM("MmcgDlg.cpp", MmcgDlgBox); +USEFORM("RadioSet.cpp", RADIOSetDlg); +USEUNIT("cradio.cpp"); +USEFORM("RxView.cpp", RxViewDlg); +USERES("mmvari.res"); +USEFORM("ClockAdj.cpp", ClockAdjDlg); +USEFORM("TrackDlg.cpp", TrackDlgBox); +USEFORM("Test.cpp", TestDlg); +USEUNIT("Hamlog5.cpp"); +USEFORM("TH5Len.cpp", TH5LenDlg); +USEFORM("RMenuDlg.cpp", RMenuDialog); +//--------------------------------------------------------------------------- +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + Application->Initialize(); + Application->CreateForm(__classid(TMainVARI), &MainVARI); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + return 0; +} +//--------------------------------------------------------------------------- diff --git a/MMVARI.map b/MMVARI.map new file mode 100644 index 0000000..67ead1a --- /dev/null +++ b/MMVARI.map @@ -0,0 +1,6 @@ + + Start Length Name Class + 0001:00401000 000388EB8H _TEXT CODE + 0002:0078A000 000040310H _DATA DATA + 0003:007CA310 000021914H _BSS BSS + 0004:00000000 0000000F8H _TLS TLS diff --git a/MMVARI.res b/MMVARI.res new file mode 100644 index 0000000..8d1237a Binary files /dev/null and b/MMVARI.res differ diff --git a/MMVARI.tds b/MMVARI.tds new file mode 100644 index 0000000..d64e9c6 Binary files /dev/null and b/MMVARI.tds differ diff --git a/MMVARI_Icon.ico b/MMVARI_Icon.ico new file mode 100644 index 0000000..9f8ccd8 Binary files /dev/null and b/MMVARI_Icon.ico differ diff --git a/MacEdit.cpp b/MacEdit.cpp new file mode 100644 index 0000000..c5a11b2 --- /dev/null +++ b/MacEdit.cpp @@ -0,0 +1,403 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "MacEdit.h" +#include "MacroKey.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//--------------------------------------------------------------------- +__fastcall TMacEditDlg::TMacEditDlg(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; +// Memo->Font->Charset = MainGMSK->PCTX->Font->Charset; + if( sys.m_MsgEng ){ +// Caption = "Edit button"; + L1->Caption = "Button"; + SBMac->Caption = "Macro"; + SBCond->Caption = "Cond."; + SBClear->Caption = "Clear"; + CancelBtn->Caption = "Cancel"; + + ELabel->Hint = "Button name"; + SBB->Hint = "Bold"; + SBI->Hint = "Italic"; + SBU->Hint = "Under line"; + SBMac->Hint = "Choose macro-command"; + SBCond->Hint = "Choose condition-command"; + SBClear->Hint = "All clear"; + + KE->Caption = "&Edit"; + KEU->Caption = "&Undo"; + KEC->Caption = "Cu&T"; + KECP->Caption = "&Copy"; + KEP->Caption = "&Paste"; + KEA->Caption = "Select AL&L"; + + KFL->Caption = "&Load text..."; + KFS->Caption = "Save &As..."; + } + KEIM->Caption = SBMac->Hint; + KEIC->Caption = SBCond->Hint; + KF->Caption = MainVARI->KF->Caption; + KH->Caption = MainVARI->KH->Caption; + KHO->Caption = MainVARI->KHO->Caption; + KHS->Caption = MainVARI->KHS->Caption; + m_pKeyDlg = NULL; + m_pOverWrite = NULL; + m_InsCount = 0; + OnWave(); + if( sys.m_PosMacEdit.right ){ + Position = poDesigned; + if( sys.m_PosMacEdit.bottom >= 0 ){ + SetBounds(sys.m_PosMacEdit.left, sys.m_PosMacEdit.top, sys.m_PosMacEdit.right, sys.m_PosMacEdit.bottom); + } + else { + WindowState = wsMaximized; + } + } + else { + FormCenter(this); + SaveBounds(); + } + m_MacroDir = sys.m_MacroDir; +} +//--------------------------------------------------------------------- +void __fastcall TMacEditDlg::SaveBounds(void) +{ + if( WindowState == wsNormal ){ + sys.m_PosMacEdit.left = Left; + sys.m_PosMacEdit.top = Top; + sys.m_PosMacEdit.right = Width; + sys.m_PosMacEdit.bottom = Height; + } + else { + sys.m_PosMacEdit.bottom = -1; + } +} +//--------------------------------------------------------------------- +int __fastcall TMacEditDlg::Execute(MACBUTTON *pList, int n) +{ + char bf[128]; + sprintf(bf, sys.m_MsgEng ? "Edit button (No.%u)" : "ボタンの編集 (No.%u)", n+1); + Caption = bf; + sprintf(bf, "Button%d", n+1); + m_Name = bf; + Memo->Text = pList->Text; + ELabel->Text = pList->Name; + PC->Color = pList->Color; + SBB->Down = pList->Style & FSBOLD; + SBI->Down = pList->Style & FSITALIC; + SBU->Down = pList->Style & FSUNDERLINE; + Memo->SelStart = strlen(pList->Text.c_str()); + OnWave(); + int r = ShowModal(); + if( m_pKeyDlg ){ + delete m_pKeyDlg; + m_pKeyDlg = NULL; + OnWave(); + } + if( r == IDOK ){ + pList->Text = Memo->Text; + if( Memo->Text.IsEmpty() && !ELabel->Text.IsEmpty() ){ + sprintf(bf, "M%d", n+1); + pList->Name = bf; + } + else { + pList->Name = ELabel->Text; + } + pList->Color = PC->Color; + pList->Style = 0; + if( SBB->Down ) pList->Style |= FSBOLD; + if( SBI->Down ) pList->Style |= FSITALIC; + if( SBU->Down ) pList->Style |= FSUNDERLINE; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------- +int __fastcall TMacEditDlg::Execute(AnsiString &as, LPCSTR pTitle) +{ + L1->Enabled = FALSE; + ELabel->Enabled = FALSE; + PC->Enabled = FALSE; + SBB->Enabled = FALSE; + SBI->Enabled = FALSE; + SBU->Enabled = FALSE; + + AnsiString ts = sys.m_MsgEng ? "Edit macro" : "マクロ文の編集"; + if( pTitle ){ + ts += " - "; + ts += pTitle; + } + Caption = ts; + m_Name = pTitle; + Memo->Text = as.c_str(); + ELabel->Text = ""; + Memo->SelStart = strlen(as.c_str()); + OnWave(); + int r = ShowModal(); + if( m_pKeyDlg ){ + delete m_pKeyDlg; + m_pKeyDlg = NULL; + OnWave(); + } + if( r == IDOK ){ + as = Memo->Text; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------- +int __fastcall TMacEditDlg::Execute(LPCSTR pName) +{ + CWaitCursor w; + mkdir(sys.m_MacroDir); + + m_pOverWrite = new TMenuItem(this); + m_pOverWrite->Caption = sys.m_MsgEng ? "&Over write":"上書き保存(&O)"; + m_pOverWrite->OnClick = KFSClick; + KF->Insert(KF->IndexOf(KFS), m_pOverWrite); + + L1->Enabled = FALSE; + ELabel->Enabled = FALSE; + PC->Enabled = FALSE; + SBB->Enabled = FALSE; + SBI->Enabled = FALSE; + SBU->Enabled = FALSE; + + GetFullPathName(m_FullName, pName, sys.m_MacroDir); + GetFileName(m_Name, pName); + char bf[256]; + SetDirName(bf, m_FullName.c_str()); + m_MacroDir = bf; + AnsiString ts = sys.m_MsgEng ? "Edit macro" : "マクロ文の編集"; + ts += " - "; + ts += m_FullName; + Caption = ts; + if( IsFile(m_FullName.c_str()) ){ + try { + Memo->Lines->LoadFromFile(m_FullName); + } + catch(...){ + } + } + ELabel->Text = ""; + OnWave(); + int r = ShowModal(); + if( m_pKeyDlg ){ + delete m_pKeyDlg; + m_pKeyDlg = NULL; + OnWave(); + } + if( r == IDOK ){ + CWaitCursor w; + Memo->Lines->SaveToFile(m_FullName); + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------- +void __fastcall TMacEditDlg::PCClick(TObject *Sender) +{ + ColorDialog->Color = PC->Color; + if( ColorDialog->Execute() ){ + PC->Color = ColorDialog->Color; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::SBMacClick(TObject *Sender) +{ + int type = ((Sender == SBMac) || (Sender == KEIM)) ? 0 : 1; + m_InsCount = 0; + if( !m_pKeyDlg ){ + m_pKeyDlg = new TMacroKeyDlg(this); + m_pKeyDlg->Execute(Left+48, Top+60, this, type); + } + else { + m_pKeyDlg->Execute(-1, -1, this, type); + } + if( m_pKeyDlg ) m_pKeyDlg->UpdateUndo(m_InsCount); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::SBClearClick(TObject *Sender) +{ + Memo->Clear(); +} +//--------------------------------------------------------------------- +void __fastcall TMacEditDlg::Undo(void) +{ + if( m_InsCount ){ + for( ; m_InsCount; m_InsCount-- ){ + ::PostMessage(Memo->Handle, WM_CHAR, '\b', 0); + } + if( m_pKeyDlg ) m_pKeyDlg->UpdateUndo(m_InsCount); + } +} +//--------------------------------------------------------------------- +void __fastcall TMacEditDlg::OnInsertText(LPCSTR pText) +{ + m_InsCount = 0; + for( LPCSTR p = pText; *p; p++ ){ + ::PostMessage(Memo->Handle, WM_CHAR, *p, 0); + m_InsCount++; + } + if( m_pKeyDlg ) m_pKeyDlg->UpdateUndo(m_InsCount); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::FormDestroy(TObject *Sender) +{ + if( m_pKeyDlg ){ + delete m_pKeyDlg; + m_pKeyDlg = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::FormResize(TObject *Sender) +{ + CancelBtn->Left = PB->Width - CancelBtn->Width - 1; + OKBtn->Left = CancelBtn->Left - OKBtn->Width - 1; + SaveBounds(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::FormClose(TObject *Sender, + TCloseAction &Action) +{ + SaveBounds(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KEClick(TObject *Sender) +{ + KEU->Enabled = Memo->Modified; + KEC->Enabled = Memo->SelLength; + KECP->Enabled = KEC->Enabled; + KEP->Enabled = ::IsClipboardFormatAvailable(CF_TEXT); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KEUClick(TObject *Sender) +{ + if( Memo->HandleAllocated() ){ + SendMessage(Memo->Handle, EM_UNDO, 0, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KECClick(TObject *Sender) +{ + Memo->CutToClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KECPClick(TObject *Sender) +{ + Memo->CopyToClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KEPClick(TObject *Sender) +{ + Memo->PasteFromClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KEAClick(TObject *Sender) +{ + Memo->SelectAll(); +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KHOClick(TObject *Sender) +{ + if( Sender == KHO ){ + MainVARI->ShowManual(); + } + else { + MainVARI->ShowMacroSample(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KFSClick(TObject *Sender) +{ + mkdir(sys.m_MacroDir); + if( Sender == KFS ){ + TSaveDialog *pBox = new TSaveDialog(this); + pBox->Options << ofOverwritePrompt; + pBox->Options << ofNoReadOnlyReturn; + if( sys.m_MsgEng ){ + pBox->Title = "Save macro text"; + } + else { + pBox->Title = "テキストファイルにセーブ"; + } + pBox->Filter = "Text Files(*.txt)|*.txt"; + pBox->FileName = m_Name; + pBox->DefaultExt = "txt"; + pBox->InitialDir = m_MacroDir; + OnWave(); + if( pBox->Execute() == TRUE ){ + OnWave(); + Memo->Lines->SaveToFile(pBox->FileName); + } + delete pBox; + } + else { + Memo->Lines->SaveToFile(m_FullName); + Memo->Modified = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KFLClick(TObject *Sender) +{ + mkdir(sys.m_MacroDir); + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Load macro text"; + } + else { + pBox->Title = "テキストファイルからロード"; + } + pBox->Filter = "Text Files(*.txt)|*.txt"; + pBox->FileName = m_Name; + pBox->DefaultExt = "txt"; + pBox->InitialDir = m_MacroDir; + OnWave(); + if( pBox->Execute() == TRUE ){ + OnWave(); + Memo->Lines->LoadFromFile(pBox->FileName); + Memo->Modified = TRUE; + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TMacEditDlg::KFClick(TObject *Sender) +{ + if( m_pOverWrite ) m_pOverWrite->Enabled = Memo->Modified; + KFS->Enabled = !Memo->Text.IsEmpty(); +} +//--------------------------------------------------------------------------- + diff --git a/MacEdit.dfm b/MacEdit.dfm new file mode 100644 index 0000000..9344621 Binary files /dev/null and b/MacEdit.dfm differ diff --git a/MacEdit.h b/MacEdit.h new file mode 100644 index 0000000..009441f --- /dev/null +++ b/MacEdit.h @@ -0,0 +1,123 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef MacEditH +#define MacEditH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +#include "Main.h" +#include +#include "MacroKey.h" +#include +//---------------------------------------------------------------------------- +class TMacEditDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TMemo *Memo; + TEdit *ELabel; + TLabel *L1; + TColorDialog *ColorDialog; + TPanel *PC; + TSpeedButton *SBMac; + TSpeedButton *SBClear; + TSpeedButton *SBB; + TSpeedButton *SBI; + TSpeedButton *SBU; + TSpeedButton *SBCond; + TPanel *PB; + TMainMenu *Menu; + TMenuItem *KE; + TMenuItem *KEC; + TMenuItem *KECP; + TMenuItem *KEP; + TMenuItem *KEU; + TMenuItem *KEA; + TMenuItem *N1; + TMenuItem *N2; + + + TMenuItem *KH; + TMenuItem *KHO; + TMenuItem *KHS; + TMenuItem *N3; + TMenuItem *KEIM; + TMenuItem *KEIC; + TMenuItem *KF; + TMenuItem *KFS; + TMenuItem *KFL; + TMenuItem *N4; + void __fastcall PCClick(TObject *Sender); + void __fastcall SBMacClick(TObject *Sender); + void __fastcall SBClearClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + + void __fastcall FormResize(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + + void __fastcall KEClick(TObject *Sender); + void __fastcall KEUClick(TObject *Sender); + void __fastcall KEAClick(TObject *Sender); + void __fastcall KECClick(TObject *Sender); + void __fastcall KECPClick(TObject *Sender); + void __fastcall KEPClick(TObject *Sender); + void __fastcall KHOClick(TObject *Sender); + + + void __fastcall KFSClick(TObject *Sender); + void __fastcall KFLClick(TObject *Sender); + void __fastcall KFClick(TObject *Sender); + + +private: + AnsiString m_Name; + AnsiString m_FullName; + AnsiString m_MacroDir; + int m_InsCount; + TMacroKeyDlg *m_pKeyDlg; + TMenuItem *m_pOverWrite; + + void __fastcall SaveBounds(void); + +public: + virtual __fastcall TMacEditDlg(TComponent* AOwner); + + int __fastcall Execute(MACBUTTON *pList, int n); + int __fastcall Execute(AnsiString &as, LPCSTR pTitle); + int __fastcall Execute(LPCSTR pName); + + void __fastcall OnInsertText(LPCSTR pText); + void __fastcall Undo(void); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TMacEditDlg *MacEditDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/MacroKey.cpp b/MacroKey.cpp new file mode 100644 index 0000000..724a18b --- /dev/null +++ b/MacroKey.cpp @@ -0,0 +1,906 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include + +#include "MacroKey.h" +#include "MacEdit.h" +#include "ComLib.h" +#include "InputWin.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TMacroKeyDlg *MacroKeyDlg; +MACKEY mackeycom[]={ + {1, "<%TX>","送信に切り替え", "Switch to TX"}, + {1, "<%RX>","受信に切り替え", "Switch to RX"}, + {1, "<%TXRX>","送受の切り替え", "Turns over TX/RX"}, + {1, "<%TXOFF>","送信の強制終了", "Abort TX (Switch to RX immediately)"}, + {1, "<%AutoClear>","自動的に送信画面をクリア", "Clear TX window automatically"}, + {1, "<%ClearTXW>","送信画面をクリア", "Clear TX window"}, + {1, "<%ClearRXW>","受信画面をクリア", "Clear RX window"}, + {1, "<%MyCall>","自局のコールサイン", "My callsign"}, + {1, "<%HisCall>","相手局のコールサイン", "His/her callsign"}, + {1, "<%HisName>","相手局の名前", "His/her name"}, + {1, "<%DearName>","Dear xxx または xxxさん", "Dear xxx"}, + {1, "<%HisRST>","相手局のRST", "His/her RST"}, + {1, "<%MyRST>","自局の(伝えられた)RST", "My RST"}, + {1, "<%FREQ>","運用周波数(例 7)", "Logging FREQ (e.g. 7)"}, + {1, "<%BAND>","運用バンド(例 40m)", "Logging BAND (e.g. 40m)"}, + {1, "<%HisQTH>","相手局のQTH", "His/her QTH"}, + {1, "<%Note>","Note(備考)", "Note (Remarks)"}, + {1, "<%UDATE>","日付(UTC)", "UTC date"}, + {1, "<%UTIME>","時刻(UTC) hh:mm", "UTC time (hh:mm)"}, + {1, "<%UTIMES>","時刻(UTC) hh:mm:ss", "UTC time (hh:mm:ss)"}, + {1, "<%LDATE>","日付(Local)", "Local date"}, + {1, "<%LTIME>","時刻(Local) hh:mm", "Local time (hh:mm)"}, + {1, "<%LTIMES>","時刻(Local) hh:mm:ss", "Local time (hh:mm:ss)"}, + {1, "<%PTIME>","1980/JAN/6 からの経過秒(UTC時刻)", "Passing time from 1980/JAN/6 (UTC)"}, + {1, "<%LPTIME>","1980/JAN/6 からの経過秒(ローカル時刻)", "Passing time from 1980/JAN/6 (local time)"}, + {1, "<%QPTIME>","QSO開始UTC時刻(1980/JAN/6 からの経過秒)", "QSO Starting time (passing time from 1980/JAN/6 (UTC)"}, + {1, "<%VALTIME=year,<%PTIME>>","PTIMEを分解 (year/month/day/hour/minute/second..., PTIME)", "Takes the PTIME apart (year/month/day/hour/minute/second..., PTIME)"}, + {1, "<%Capture>","コールサインの捕獲", "Capture callsign"}, + {2, "<%HisGreetings=3>","自動挨拶(例 1-GA, 2-Good morning, 3-おはようございます)", NULL}, + {3, "<%HisGreetings=2>","Auto Greetings (e.g. 1-GA, 2-Good morning)", NULL}, + {1, "<%HisNR>","HisRSTのコンテストNR", "Only the contest number part of his/her RST"}, + {1, "<%MyNR>","MyRSTのコンテストNR", "Only the contest number part of my RST"}, + {1, "<%Entity=<%HisCall>>","エンティティコード", "Code of the entity"}, + {1, "<%EntityName=<%HisCall>>","エンティティ名", "Name of the entity"}, + {1, "<%Continent=<%HisCall>>","大陸コード", "Code of the continent"}, + {1, "<%PLATFORM>","OSのプラットフォーム", "Platform of the OS"}, + {1, "<%CodePage>","OSのコードページ", "Code page of the OS"}, + {1, "<%LanguageID>","OSの言語ID", "Language ID of the OS"}, + {1, "<%VER>","MMVARIのバージョン", "Program version of MMVARI"}, + {1, "<%VERMINOR>","MMVARIのマイナーバージョン", "Program minor version of MMVARI"}, + {1, "<%VARITYPE>","バリコード種別(VariSTD, VariJA, VariHL, ...)", "Type of the VARICODE(VariSTD, VariJA, VariHL, ...)"}, + {1, "<%MODE>","現在のモード(変調方式)種別(GMSK, FSK, ...)", "Current type of the mode(GMSK, FSK, ...)"}, + {1, "<%Level>","信号のS/Nレベル(dB)", "S/N level of the signals"}, + {1, "<%PeakLevel>","信号のピークS/Nレベル(dB)", "Peak S/N level of the signals"}, + {1, "<%AverageLevel>","信号の平均S/Nレベル(dB)", "Average S/N level of the signals"}, + {1, "<%MetricMFSK>","mfsk信号のメトリックレベル", "Metric level in mfsk"}, + {1, "<%MetricMFSK=even>","mfsk信号のビタビ別メトリックレベル(even/odd)", "Metric level of the viterbi in mfsk (even/odd)"}, + {1, "<%SquelchLevel=3.0>","スケルチレベル(S/N=dB)の設定", "Set squelch level (S/N=dB)"}, + {1, "<%CWID>","My callsignをCWで送信", "CWID of the MyCallsign"}, + {1, "<%CWID= 73 :>","文字列をCWで送信 (AS @ SK : AR ; KN ] BT =)", "CWID of the strings (AS @ SK : AR ; KN ] BT =)"}, + {1, "<%CWSpeed=20>","CW速度(10 - 60)を設定", "CWID speed (10-60)"}, + {1, "<%MODE=GMSK>","モード(変調方式)の設定(GMSK, FSK, ...)", "Set the mode(GMSK, FSK, ...)"}, + {1, "<%AutoNET>","自動的にNETをONにする", "Turns NET into ON automatically"}, + {1, "<%NETON>","NETをONにする", "Turns NET into ON"}, + {1, "<%NETOFF>","NETをOFFにする", "Turns NET into OFF"}, + {1, "<%AFCON>","AFCをONにする", "Turns AFC into ON"}, + {1, "<%AFCOFF>","AFCをOFFにする", "Turns AFC into OFF"}, + {1, "<%ATCON>","ATCをONにする", "Turns ATC into ON"}, + {1, "<%ATCOFF>","ATCをOFFにする", "Turns ATC into OFF"}, + {1, "<%RxCarrier>","受信キャリア周波数(Hz)", "RX carrier FREQ(Hz)"}, + {1, "<%TxCarrier>","送信キャリア周波数(Hz)", "TX carrier FREQ(Hz)"}, + {1, "<%RxCarrier=1750>","受信キャリア周波数(Hz)を設定", "Set RX carrier FREQ(Hz)"}, + {1, "<%TxCarrier=1750>","送信キャリア周波数(Hz)を設定", "Set TX carrier FREQ(Hz)"}, + {1, "<%AFCFrequency>","AFC検出周波数(Hz)", "AFC FREQ(Hz)"}, + {1, "<%MouseFrequency>","スペクトラム/ウォータフォールでのマウス周波数(Hz)", "Mouse frequency on Waterfall(Hz)"}, + {1, "<%TONE>","シングルトーンを送信", "Transmit single tone"}, + {1, "<%BPF=0>","BPF帯域幅(0-3)を設定", "Set BPF width (0-3)"}, + {1, "<%BPFTaps=64,80,128,256>","BPFのタップ数を設定", "Set BPF taps"}, + {1, "<%Notch=ONOFF>","ノッチフィルタのON/OFF (ON/OFF/ONOFF)", "Turns Notch into ON or OFF (ON/OFF/ONOFF)"}, + {1, "<%Notch=1750>","ノッチフィルタの周波数(Hz)を設定", "Set Notch FREQ (Hz)"}, + {1, "<%NotchTaps=128>","ノッチフィルタのタップ数を設定(16〜512)", "Set taps of the Notch filter (16-512)"}, + {1, "<%NotchWidth=1>","ノッチフィルタの帯域を設定(1〜1000)", "Set width of the Notch filter (1-1000)"}, + {1, "<%BAUD>","伝送ボーレート", "BaudRate"}, + {1, "<%BAUD=31.25>","伝送ボーレート(20〜300)を設定", "Set BaudRate(20-300)"}, + {1, "<%AFCWidth=50>","AFC吸い込み幅(Hz)を設定", "Set AFC FREQ width(Hz)"}, + {1, "<%AFCLevel=12>","AFC吸い込みレベル(dB)を設定", "Set AFC sense level(dB)"}, + {1, "<%ATCSpeed=0>","ATC応答速度(0-5)を設定", "Set ATC speed(0-5)"}, + {1, "<%ATCLevel=15>","ATC検出レベル(dB)を設定", "Set ATC sense level(dB)"}, + {1, "<%ATCPPM>","ATC値(ppm)", "ATC value (ppm)"}, + {1, "<%PTT=COM1>","PTTポートを設定", "Set PTT port"}, + {1, "<%COMFSK=ONOFF>","PTTポート FSKのON/OFF (ON/OFF/ONOFF)", "Turns FSK into ON or OFF (ON/OFF/ONOFF)"}, + {1, "<%COMFSKINV=ONOFF>","PTTポート FSKの論理反転のON/OFF (ON/OFF/ONOFF)", "Turns inverting logic (FSK) into ON or OFF (ON/OFF/ONOFF)"}, + {1, "<%Radio=COM2>","Radioポートを設定", "Set Radio port"}, + {1, "<%RadioOut=\\$000000000F>","Radioポートにデータを出力", "Output data to the radio port"}, + {1, "<%RadioCarrierKHz>","リグの補正キャリア周波数(KHz)", "Adjusted carrier FREQ(KHz) of the radio"}, + {1, "<%RadioKHz>","リグのVFO周波数(KHz)", "VFO FREQ(KHz) of the radio"}, + {1, "<%RadioKHz=YAESU-HF,14073.000>","リグのVFO周波数(KHz)の設定", "Set VFO FREQ(KHz) of the radio"}, + {1, "<%RadioMode>","リグのモード", "Mode of the radio"}, + {1, "<%RadioMode=CI-V,LSB>","リグのモードを設定", "Set Mode of the radio"}, + {1, "<%PTTON>","PTTをONにする", "Turns PTT into ON"}, + {1, "<%PTTOFF>","PTTをOFFにする", "Turns PTT into OFF"}, + {1, "<%FFTScale>","FFTスケール(0-100dB, 1-60dB, 2-二乗振幅)", "FFT scale (0-100dB, 1-60dB, 2-Square amplitude)"}, + {1, "<%FFTScale=2>","FFTスケールを設定", "Set FFT scale"}, + {1, "<%FFTWidth=1000>","FFT表示幅(500/1000/2000/3000)", "Choose FFT width(500/1000/2000/3000)"}, + {1, "<%SyncWidth=14>","Sync/Wave表示幅(4-24)", "Choose Sync/Waveform width(4-24)"}, + {1, "<%ShowCH=1,ONOFF>","サブチャンネル(1-8)表示, ON/OFF/ONOFF", "Show sub-channel(1-8), ON/OFF/ONOFF"}, + {1, "<%SetCHSpeed=1,31.25>","サブチャンネル(1-8)のボーレート設定, 15〜300", "Set speed to the sub-channel(1-8), 15-300"}, + {1, "<%SetCHMode=1,GMSK>","サブチャンネル(1-8)のモード設定", "Set mode to the sub-channel(1-8)"}, + {1, "<%ClearCHW=1>","サブチャンネル(1-8)の画面クリア", "Clear window of the sub-channel(1-8)"}, + {1, "<%QSOON>","QSOの開始(ログに記録)", "Start QSO (logging)"}, + {1, "<%QSOOFF>","QSOの終了(ログに記録)", "End of the QSO (logging)"}, + {1, "<%FREQ=7>","ログの運用周波数を設定", "Set logging FREQ"}, + {1, "<%BAND=40m>","ログの運用バンドを設定", "Set logging BAND"}, + {1, "<%LogMODE=SSB>","ログの運用モードを設定(ヌル文字列で自動設定)", "Set logging MODE (null is auto)"}, + {1, "<%HisCall=<%Capture>>","相手局のコールを設定", "Set his/her callsign"}, + {1, "<%HisRST=599>","相手局のRSTを設定", "Set his/her RST"}, + {1, "<%MyRST=599>","自局のRSTを設定", "Set my RST"}, + {1, "<%Note=<%VARITYPE>>","Note(備考)に設定", "Set note (Remarks)"}, + {1, "<%RefRXW>","受信画面の参照画面を開く", "Show RX window with the editor"}, + {1, "<%EditFile=memo.txt, 0>","テキストファイル編集画面を開く(Name, ReadOnly)", "Open text editer(Name, ReadOnly)"}, + {1, "<%SendFile=test.txt>","テキストファイルの送信", "Send file"}, + {1, "<%EditMacro=2>","マクロボタン(1〜160)を編集", "Edit macro button (1-160)"}, + {1, "<%EditMacro=OnStart>","イベントマクロを編集(Event名)", "Edit event macro (Name of the event)"}, + {1, "<%EditMacro=AS(CW)>","AS(CW)マクロを編集(Event)", "Edit AS(CW) macro"}, + {1, "<%EditMacro=MacroTxt.txt>","テキストファイルのマクロを編集", "Edit macro written in the text file"}, + {1, "<%MacroText=MacroTxt.txt>","テキストファイルのマクロを実行", "Execute macro written in the text file"}, + {1, "<%SaveMacro=Macros.mac>","全てのマクロをファイルに保存", "Save all Macros"}, + {1, "<%LoadMacro=Macros.mac>","全てのマクロをファイルからロード", "Load all Macros"}, + {1, "<%HEX2DEC=ABCD>","16進数を10進数に変換", "Convert decimal to HEX"}, + {1, "<%CHAR=A>","文字コード(10進数)に変換", "Convert character code (decimal)"}, + {1, "<%CHARX=A>","文字コード(16進数)に変換", "Convert character code (HEX)"}, + {1, "<%CODE=82A0>","文字コード(16進数)で入力", "Input as the character code (HEX)"}, + {1, "<%SP>","スペースを入力", "Input space"}, + {1, "<%CR>","CRを入力", "Input CR"}, + {1, "<%BS>","BSを入力", "Input BS"}, + {1, "<%TAB>","TABを入力", "Input TAB"}, + {1, "<%SkipCR>","マクロ文内の次のCR(改行)をスキップ", "Skip next CR(Enter) in the macro sentence"}, + {1, "<%DisableCR>","マクロ文内のCR(改行)を無効にする", "Disable CR(Enter) in the macro sentence"}, + {1, "<%EnableCR>","マクロ文内のCR(改行)を有効にする", "Enable CR(Enter) in the macro sentence"}, + {1, "<%DisableTAB>","マクロ文内のTABを無効にする", "Disable TAB in the macro sentence"}, + {1, "<%EnableTAB>","マクロ文内のTABを有効にする", "Enable TAB in the macro sentence"}, + {1, "<%DisableSP>","マクロ文内のスペースを無効にする", "Disable SPACE in the macro sentence"}, + {1, "<%EnableSP>","マクロ文内のスペースを有効にする", "Enable SPACE in the macro sentence"}, + {1, "<%Skip$=3,<%HisCall>>","指定の文字数をスキップ(Ascii)", "Skip Ascii characters"}, + {1, "<%MSkip$=3,<%Note>>","指定の文字数をスキップ(MBCS)", "Skip MBCS characters"}, + {1, "<%Find$=xx,ABCxxVVV>","指定の文字列を検索", "Find string"}, + {1, "<%StrLen=<%HisCall>>","文字列の長さ", "String length"}, + {1, "<%MStrLen=<%Note>>","MBCS文字列の長さ", "MBSC string length"}, + {1, "<%ONOFF=<%Cond=IsSQ>>","ON/OFFを得る", "Get ON/OFF"}, + {1, "<%RepeatText=3,<%RepeatText=33,RY><%CR>>","マクロ文字列の繰り返し", "Repeating the macro string"}, + {1, "<%IDLE>","アイドル信号を挿入", "Insert idle signals"}, + {1, "<%DIDDLE=LTR>","RTTYのDIDDLEコードを設定(BLK/LTR)", "Set DIDDLE code in RTTY (BLK/LTR)"}, + {1, "<%UOS=ON>","RTTYのUOSを設定(ON/OFF/ONOFF)", "Set UOS in RTTY (ON/OFF/ONOFF)"}, + {1, "<%RTTYWaitC=0>","RTTYの文字ウエイトを設定(0-100)", "Set character wait in RTTY (0-100)"}, + {1, "<%RTTYWaitD=0>","RTTYのDIDDLEウエイトを設定(0-100)", "Set DIDDLE wait in RTTY (0-100)"}, + {1, "<%RTTYWordOut=ON>","RTTYのワード単位出力を設定(ON/OFF/ONOFF)", "Set word out in RTTY (ON/OFF/ONOFF)"}, + {1, "<%RTTYDEM=FFT>","RTTYの復調器を設定(IIR/FFT)", "Set demodulator in RTTY (IIR/FFT)"}, + {1, "<%TxShift=170.0>","RTTY/FSK-Wの送信シフト幅を設定(10-450)", "Set TX's shift width in RTTY/FSK-W (10-450)"}, + {1, "<%RxShift=170.0>","RTTY/FSK-Wの受信シフト幅を設定(10-450)", "Set RX's shift width in RTTY/FSK-W (10-450)"}, + {1, "<%ToUpper=<%HisName>>","アッパーケース(大文字)に変換", "Convert to upper case"}, + {1, "<%ToLower=<%HisCall> de <%MyCall>>","ロワーケース(小文字)に変換", "Convert to lower case"}, + {1, "<%IME=ON>","IMEを制御する (ON/OFF/ONOFF)", "Control IME (ON/OFF/ONOFF)"}, + {1, "<%RepeatTX=3000>","繰り返し送信の受信時間(ms)を設定", "Repeating TX mode (=RX times(ms))"}, + {1, "<%Repeat=10000>","マクロの繰り返し(ms)を設定", "Repeating the macro (ms)"}, + {1, "<%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>>","OnTimerマクロを設定", "Set OnTimer macro"}, + {1, "<%OnTimerInterval=1000>","OnTimerマクロの時間間隔(ms)を設定", "Set time interval(ms) of OnTimer macro"}, + {1, "<%Page=1>","送信画面ページを切り替え (1〜4)", "Choose TXW-page (1-4)"}, + {1, "<%AutoReturn>","自動的に送信画面ページを戻す", "Return TXW-page automatically"}, + {1, "<%MoveTop>","カーソルを先頭に移動", "Move cursor to the TOP"}, + {1, "<%MoveEnd>","カーソルを最後に移動", "Move cursor to the END"}, + {1, "<%ResetScroll>","受信画面のスクロール状態を解除", "Reset scroll in the RX window"}, + {1, "<%PopupTXW>","送信画面のポップアップメニューを開く", "Open Popup menu"}, + {1, "<%DupeText>","1つ前の行と同じ内容を挿入", "Create dupe text"}, + {1, "<%SeekNext>","ボタンページを次へ", "Seek to the next Button page"}, + {1, "<%SeekPrev>","ボタンページを前へ", "Seek to the previous Button page"}, + {1, "<%SeekTop>","ボタンページを先頭へ", "Seek to the top Button page"}, + {1, "<%DigitalLevel=16384>","デジタル出力レベルを設定(1024 - 32768)", "Set digital output level (1024 - 32768)"}, + {1, "<%OutputVolume>","出力ボリューム調整画面を開く", "Open output volume"}, + {1, "<%InputVolume>","入力ボリューム調整画面を開く", "Open input volume"}, + {1, "<%Setup>","設定画面を開く", "Open Setup window"}, + {1, "<%SetupLog>","ログ設定画面を開く", "Open Setup logging window"}, + {1, "<%SetupRadio>","リグコントロール設定画面を開く", "Open Setup radio command window"}, + {1, "<%Calibration>","クロック較正画面を開く", "Open calibration window"}, + {1, "<%BaseClock>","ベースクロック値(Hz)", "Base clock(Hz)"}, + {1, "<%Clock>","RXクロック値(Hz)", "RX clock(Hz)"}, + {1, "<%Clock=11025.00>","RXクロック値を設定", "Set RX clock"}, + {1, "<%TxOffset>","TXオフセット値(Hz)", "TX offset clock(Hz)"}, + {1, "<%TxOffset=0.00>","TXオフセット値を設定", "Set TX offset clock"}, + {1, "<%DemodulatorClock>","復調器クロック値(Hz)", "Demodulator clock(Hz)"}, + {1, "<%FFTClock>","FFTクロック値(Hz)", "FFT clock(Hz)"}, + {1, "<%FFTSize>","FFTのサイズ(点数)", "FFT size(points)"}, + {1, "<%WaterNoise>","ウォータフォールの検出ノイズレベル(dB)", "Sense noise level (dB) in WaterFall"}, + {1, "<%WaterNoise=35,65>","ウォータフォールのノイズレベル範囲(dB)を設定", "Set noise level range (dB) in WaterFall"}, + {1, "<%WaterLevels>","ウォータフォールのレベル配分", "Levels in WaterFall"}, + {1, "<%WaterLevels=10,60,134,192,220,240>","ウォータフォールのレベル配分を設定", "Set levels in WaterFall"}, + {1, "<%WaterColors>","ウォータフォールの配色", "Colors in WaterFall"}, + {1, "<%WaterColors=0,FF0000,FFFFFF,FF,FFFF00,FF0000,FFFF00,FFFF,80FF,FF,FF,FF>","ウォータフォールの配色を設定", "Set colors in WaterFall"}, + {1, "<%SpectrumColors>","スペクトラムの配色", "Colors in Spectrum"}, + {1, "<%SpectrumColors=0,FF00,FFFFFF,808080,FFFF00,FF0000>","スペクトラムの配色を設定", "Set colors in Spectrum"}, + {1, "<%RxColors>","受信画面の配色", "Colors in RX window"}, + {1, "<%RxColors=FFFFFF,0,FF0000,FF,E0E0E0>","受信画面の配色を設定", "Set colors in RX window"}, + {1, "<%TxColors>","送信画面の配色", "Colors in TX window"}, + {1, "<%TxColors=FFFFFF,0,FF0000,FF,FFFFFF>","送信画面の配色を設定", "Set colors in TX window"}, + {1, "<%SoundName>","入力サウンドの名前", "Name of the input sound device"}, + {1, "<%SoundOutName>","出力サウンドの名前", "Name of the output sound device"}, + {1, "<%SoundDevice=MONO,-1>","サウンドCH(MONO/LEFT/RIGHT)とデバイスIDの設定", "Set CH.(MONO/LEFT/RIGHT) es device ID of the sound"}, + {1, "<%Suspend>","サスペンドにする", "Suspend MMVARI"}, + {1, "<%Resume>","サスペンドを解除する", "Resume MMVARI"}, + {1, "<%Wait=1000>","指定時間(ms)ウエイトする", "Wait the time (ms)"}, + {1, "<%Execute=notepad.exe <%Folder>memo.txt>","プログラムの実行", "Execute other program"}, + {1, "<%Shell=<%Folder>emmvari.txt>","シェルでドキュメントを開く", "Open document by Shell32"}, + {1, "<%Exit>","MMVARIを終了する", "Exit MMVARI"}, + {1, "<%ShutDown>","Windowsをシャットダウンする", "Shut down Windows"}, + {1, "<%YesNo=String>","Yes/Noのメッセージボックス(Yes=6,No=7)", "Show Yes/No message(Yes=6,No=7)"}, + {1, "<%YesNoCancel=String>","Yes/No/Cancelのメッセージボックス(Yes=6,No=7,Cancel=2)", "Show Yes/No/Cancel message(Yes=6,No=7,Cancel=2)"}, + {1, "<%OkCancel=String>","Ok/Cancelのメッセージボックス(Ok=1,Cancel=2)", "Show Ok/Cancel message(Ok=1,Cancel=2)"}, + {1, "<%Error=Macro ERROR>","エラーメッセージを表示", "Show error message"}, + {1, "<%Warning=Macro WARNING>","警告メッセージを表示", "Show warning message"}, + {1, "<%Message=Macro message>","メッセージを表示", "Show message"}, + {1, "<%WaterMsg=4,Metric=<%MetricMFSK>><%Repeat=1000>","ウォータフォールにメッセージを表示(位置=0-4)", "Show message in the WaterFall (Pos. 0-4)"}, + {1, "<%RxStatus=Status>","受信画面にステータスを表示", "Show status in the RX window"}, + {1, "<%TableCount=AAA,BBB,CCC>","テーブルの項目数を得る", "Get count of the table"}, + {1, "<%TableStr=1,AAA,BBB,CCC>","テーブルの文字列を得る", "Get string of the table"}, + {1, "<%Table=<%BAUD>,20.0,31.25,45.0>","テーブルのインデクッスを得る", "Get index of the table"}, + {1, "<%Menu=A,B,C,D>","メニューの表示(Input$に入る)", "Show menu (Put into Input$)"}, + {1, "<%MenuB=\x22<%Table=<%BAUD>,20.0,31.25,45.45,62.5>\x22,20.0,31.25,45.45,62.5>","マーク付きメニューの表示(Input$に入る)", "Show menu with mark (Put into Input$)"}, + {1, "<%Menu>","メニューインデックス", "menu index"}, + {1, "<%Input=Input strings>","文字列の入力", "Input strings"}, + {1, "<%Input$>","入力された文字列", "The strings which was entered"}, + {1, "<%Click$>","受信画面でクリックした文字列", "The strings which was clicked in the RX window"}, + {1, "<%CLICK$>","受信画面でクリックした文字列(大文字)", "The strings (upper case) which was clicked in the RX window"}, + {1, "<%vvv>","テストメッセージ(英語)", "test message"}, + {2, "<%VVV>","テストメッセージ(日本語)", "test message"}, + {1, "<%KeyStroke=41>","キー(VK code)を押して離す", "Down and up the keyboard (VK code)"}, + {1, "<%KeyDown=12><%KeyStroke=<%CHARX=V>><%KeyUp=12>","キー(VK code)を押す(Shift=10,Ctrl=11,Alt=12)", "Down the keyboard(VK code, Shift=10,Ctrl=11,Alt=12)"}, + {1, "<%KeyUp=12>","キー(VK code)を離す(Shift=10,Ctrl=11,Alt=12)", "Up the keyboard(VK code, Shift=10,Ctrl=11,Alt=12)"}, + {1, "<%DoMacro=2>","マクロボタン(1〜160)を実行", "Execute macro button (1-160)"}, + {1, "<%DoEvent=OnMode>","イベントマクロを実行", "Execute event macro"}, + {1, "<%Events>","イベントのリスト", "List of the events"}, + {1, "<%ButtonName=1,Clear>","マクロボタン(1〜160)の名前を設定", "Set name of the button (1-160)"}, + {1, "<%ButtonContents=1,<%ClearTXW>>","マクロボタン(1〜160)の内容を設定", "Set contents of the button (1-160)"}, + {1, "<%PlayBack=ON>","サウンドプレーバックボタン機能の設定(ON/OFF/ONOFF)", "Set Sound Playback function (ON/OFF/ONOFF)"}, + {1, "<%PlayBack=10>","サウンドプレーバック(0〜60秒)を実行", "Execute Sound Playback (0-60s)"}, + {1, "<%PlayBackSpeed=5>","サウンドプレーバックの速度(1〜20)を設定", "Set speed of the Sound Playback (1-20)"}, + {1, "<%PlayBackButtons=60,30,15>","サウンドプレーバックボタンの時間を設定", "Set time of the Sound Playback buttons"}, + {1, "<%PlaySound=sound.mmv>","サウンドファイルの再生", "Sound playing from the file"}, + {1, "<%PlaySound>","サウンドファイルの再生ダイアログを表示する", "Show sound playing dialog"}, + {1, "<%RecordSound=sound.mmv>","サウンドファイルの録音", "Sound recording to the file"}, + {1, "<%RecordSound>","サウンドファイルの録音ダイアログを表示する", "Show sound recording dialog"}, + {1, "<%QuickRecordSound>","サウンドファイルの録音", "Sound recording (filename = Time stamp)"}, + {1, "<%StopPlayRecord>","サウンド再生/録音の停止", "Close recording or playing"}, + {1, "<%SoundTime>","再生/録音時間(秒)", "Time (sec) of sound (playing or recording)"}, + {1, "<%Slider=CW speed,<%CWSpeed>,10,60,1,10>","スライダーを表示(タイトル,値,Min,Max,ステップ,目盛の数) Input$に入る", "Show slider (Title,Value,Min,Max,Step,Scale) Put into Input$"}, + {1, "<%FileDialog=Text file,Text Files(*.txt)|*.txt|,Default,txt,>","ファイル選択ダイアログを表示(Input$に入る)", "Show choose file dialog box (Put into Input$)"}, + {1, "<%CPUBENCHMARK>","CPUベンチマーク値 (us)", "The values of CPU-benchmark (us)"}, + {1, "<%RANDOM=<%PTIME>>","乱数の種の初期化", "Initialization of a random seed"}, + {1, "<%RANDOM>","乱数(0〜32767)", "A random values (0 - 32767)"}, + {1, "<%String=Name>","#defineで定義した文字列を展開", "Defined strings by #define"}, + {1, "<%CallProc=Name>","プロシジャーを実行", "Execute the procedure"}, + {1, "<%DebugProc=Name>","<%CallProc=...>のデバッグ版", "Debug version of <%CallProc=...>"}, + {1, "<%Format=%.3f,<%BAUD>>","書式変換(C言語)指定で展開 (書式文字列,式)", "Convert format (C Language) string"}, + {1, "<%Inv=<%Cond=IsSQ>>","論理を反転", "Invert logic"}, + {1, "<%Floor=<%BAUD>>","小数点以下を切り捨て", "Returns the largest integer that is not greater than the argument"}, + {1, "<%Log=10>","自然対数を計算", "Calculates logarithms"}, + {1, "<%Exp=2.302585092994046>","指数関数 e の x 乗を計算", "Calculates the exponential"}, + {1, "<%Sqrt=10>","平方根を計算", "Calculates the square root"}, + {1, "<%Pow=10,2>","x の y 乗を計算", "Calculates x raised to the power of y"}, + {1, "<%Sin=0.5>","sin(x)を計算", "Calculates the sin(x)"}, + {1, "<%Cos=0.5>","cos(x)を計算", "Calculates the cos(x)"}, + {1, "<%Tan=0.5>","tan(x)を計算", "Calculates the tan(x)"}, + {1, "<%ArcTan=0.5>","arc-tan(x)を計算", "Calculates the arc-tan(x)"}, + {1, "<%Cond=IsSQ>","条件命令のテスト結果(0-FALSE, 1-TRUE)", "Test result of condition command (0-FALSE, 1-TRUE)"}, + {1, "<%ListSpeed=15.625,31.25,62.5,93.75,125.0,250.0>","Speedボックスのリストを設定", "Set list of Speed box"}, + {1, "<%ListCarrier=500,800,1000,1200,1500,1750,2000,2210>","Carrierボックスのリストを設定", "Set list of Carrier box"}, + {1, "<%ListRST=599,579,559,449,339>","RSTボックスのリストを設定", "Set list of RST box"}, + {1, "<%ListLogFreq=1.8,3.5,7,10,14,18,21,24,28,50,144,430,1200>","ログ周波数ボックスのリストを設定", "Set list of Log-FREQ box"}, + {1, "<%SetCaptureLimit>","文字列捕獲の検索範囲を設定", "Set the limit of the capturing range"}, + {1, "<%ClearCaptureLimit>","文字列捕獲の検索範囲をクリア", "Clear the limit of the capturing range"}, + {1, "<%Font>","受信画面のフォントパラメータ(Name, Size, Charset)", "Font parameters of the RX window (Name, Size, Charset)"}, + {1, "<%Font=,14,>","受信/送信画面のフォントを設定(=Name, Size, Charset)", "Sets font into the TX/RX window (=Name, Size, Charset)"}, + {1, "<%SetFocus>","送信画面にキーボードフォーカスを設定する", "Sets keyboard focus to the TX window"}, + {1, "<%Folder>","MMVARIのフォルダ", "MMVARI's folder"}, + {1, "<%AddMenu=E&X,Caption&1,OnCaption1Click>","拡張メニューの追加 (=Name,Caption,Procedure,Arg...)", "Add extension menu (=Name,Caption,Procedure,Arg...)"}, + {1, "<%InsertMenu=&H,&P,Caption&1, OnCaption1Click>","拡張メニューの挿入 (=Name,InsPos,Caption,Procedure,Arg...)", "Insert extension menu (=Name,InsPos,Caption,Procedure,Arg...)"}, + {1, "<%ShowMenu=&F, ONOFF>","メニューの表示 (=Name...,ON/OFF/ONOFF)", "Show the menu (=Name...,ON/OFF/ONOFF)"}, + {1, "<%EnableMenu=&F, ONOFF>","メニューの許可 (=Name...,ON/OFF/ONOFF)", "Enable the menu (=Name...,ON/OFF/ONOFF)"}, + {1, "<%ShortCut=&V, &C, &1, Ctrl+1>","メニューにショートカットを設定 (=Name...,Key)", "Set menu short cut (=Name...,Key)"}, + {1, "<%CheckMenu=&H, &P, ONOFF>","メニューにチェックの付ける (=Name...,ON/OFF/ONOFF)", "Set menu check (=Name...,ON/OFF/ONOFF)"}, + {1, "<%DeleteMenu=&X>","メニューを削除 (=Name...)", "Delete menu (=Name...)"}, + {1, "<%DoMenu=&V,&C,&1>","メニューを実行 (=Name...)", "Execute the menu (=Name...)"}, + {1, "<%DoButton=FFT>","ボタンをクリックする", "Click the button"}, + {1, "<%ShowHTML=home>","HTML/ウェーブサイトを表示", "Show html or Web site"}, + {1, "<%SendMessage=PSKGNRFUNC,0,1>","ウインドウメッセージの送信 (=Name, wParam, lParam)", "Send window message (=Name, wParam, lParam)"}, +// {1, "<%SendMessage=this,16,0,0>","ウインドウメッセージの送信 (this, uMsg, wParam, lParam)", "Send window message (this, uMsg, wParam, lParam)"}, +// {1, "<%CallDLL=QRZ.DLL,FuncName,<%HisCall>>","DLLファンクションの呼び出し", "Call the function in the DLL"}, + {1, "<%Memory>","メモリ状態(Load[%],Total[MB],Free[MB])", "Memory status(Load[%],Total[MB],Free[MB])"}, + {1, "<%BuffSize=4096>","マクロバッファの最小のサイズを設定(512-65536)", "Set minimum buffer size for Macro function (512-65536)"}, + {1, "<%EOF>","定義の終了", "End of the macro"}, + {0, NULL, NULL}, +}; + +#if AN(mackeycom) >= MACLISTMAX +#error macro key over follow +#endif + +MACKEY condcom[]={ + {1, "IsCall","Callに文字が存在する時", "Letters exists in the Call-box"}, + {1, "IsName","Nameに文字が存在する時", "Letters exists in the Name-box"}, + {1, "IsHisRST","Hisに文字が存在する時", "Letters exists in the His-box"}, + {1, "IsMyRST","Myに文字が存在する時", "Letters exists in the My-box"}, + {1, "IsQTH","QTHに文字が存在する時", "Letters exists in the QTH-box"}, + {1, "IsNote","Noteに文字が存在する時", "Letters exists in the Note-box"}, + {1, "IsLocal","同じエンティティの時", "Same entity (country)"}, + {1, "IsQSO","QSOボタンを押している時", "QSO button down"}, + {1, "IsDupe","重複QSOの場合", "Is dupe QSO?"}, + {1, "IsAFC","AFCがONの時", "Is AFC ON?"}, + {1, "IsNET","NETがONの時", "Is NET ON?"}, + {1, "IsTX","送信中の時", "Is transmitting?"}, + {1, "IsPTT","PTTがONの時", "Is PTT ON?"}, + {1, "IsSQ","スケルチが開いている時", "Is Squelch open?"}, + {1, "IsTone","シングルトーン送信中の時", "Is single tone transmitting?"}, + {1, "IsTXEmpty","未送信文字が存在しない時", "Letters do not exist in the TX window"}, + {1, "IsRXScroll","受信画面がスクロール中の時", "Is RX window scrolling?"}, + {1, "IsRepeat","マクロが繰り返し中の時", "Is the macro repeating?"}, + {1, "IsIME","IMEがONの時", "Is IME ON?"}, + {1, "IsPlaying","サウンド再生中の時", "Is sound playing?"}, + {1, "IsFileSending","ファイル送信中の時", "Is file sending?"}, + {1, "IsRecording","サウンド録音中の時", "Is sound recording?"}, + {1, "IsFile(test.txt)","ファイルが存在する時", "File exists"}, + {1, "IsDefined(Name)","文字列変数が存在する時", "Variable strings exists"}, + {1, "IsMBCS(<%HisName>)","文字列にMBCSが含まれる時", "Is string including MBCS?"}, + {1, "IsAlpha(<%MyNR>)","文字列がアルファベットの時", "Is string alphabet?"}, + {1, "IsNumber(<%MyNR>)","文字列が数字の時", "Is string number?"}, + {1, "IsUOS","RTTYのUOSがONの時", "Is UOS active in RTTY?"}, + {1, "IsRadioLSB","RigがLSBモードの時", "Is LSB of the radio?"}, + {1, "IsCaptureText(CQ)","受信テキストに文字列が存在する時", "Does string exist in the received text?"}, + {1, "IsOnTimer","OnTimerマクロを実行中の時", "Is OnTimer executing?"}, + {1, "IsIdle","アイドル状態の時", "Is idle?"}, + {1, "IsEnglish","英語モードの時", "Is English mode running?"}, + {1, "IsMfskCenter","mfskが中心周波数合わせの時", "Is center FREQ handling in mfsk?"}, + {1, "IsMfskMetricSq","mfskがメトリックスケルチの時", "Is squelch metric in mfsk?"}, + {1, "Is1stCR","送信開始時に自動でCR/LF出力する時", "Is CR/LF sending automatically at the beginning?"}, + {1, "IsPlayBack","サウンドプレーバック機能がONの時", "Is sound play back enabled?"}, + {1, "IsCodeMM","MMVARIコード(VariJA, VariHL,...)の時", "Is MMVARI code (VariJA, VariHL,...)?"}, + {1, "IsCall(<%CLICK$>)","文字列がコールサインの時", "Is the strings call sign?"}, + {1, "IsRST(<%CLICK$>)","文字列がRSTの時", "Is the strings RST?"}, + {1, "IsMenu(&H, &U)","メニューが存在する時", "Menu exists?"}, + {1, "IsMenuEnabled(&H, &U)","メニューが許可されている時", "Is the menu enabled?"}, + {1, "IsMenuChecked(&H, &U)","メニューがチェックされている時", "Is the menu checked?"}, + {1, "IsMenuVisible(&H, &U)","メニューが表示されている時", "Is the menu visible?"}, + {1, "IsButton(QSO)","ボタンが存在する時", "Button exists?"}, + {1, "IsButtonEnabled(QSO)","ボタンが許可されている時", "Is the button enabled?"}, + {1, "IsButtonDown(QSO)","ボタンが押されている時", "Is the button down?"}, + {1, "ValFreq>=144","ログ周波数の比較", "Compare logging FREQ"}, + {1, "ValBaud==31.25","伝送速度(Bps)の比較", "Compare speed (baudrate)"}, + {1, "ValCarrierRX<1500","受信キャリア周波数の比較", "Compare RX carrier FREQ"}, + {1, "ValCarrierTX<1500","送信キャリア周波数の比較", "Compare TX carrier FREQ"}, + {1, "ValPage!=1","送信画面ページの比較", "Compare TX window page"}, + {1, "ValTimeLocal<1200","時刻(Local)の比較", "Compare Local time"}, + {1, "ValTimeUTC>=0900","時刻(UTC)の比較", "Compare UTC time"}, + {1, "ValDateLocal>=0801","日付(Local)の比較", "Compare Local date"}, + {1, "ValDateUTC<0401","日付(UTC)の比較", "Compare UTC date"}, + {1, "ValScope","スコープの状態を比較(FFT=0, WF=1, SYNC=2)", "Compare condition of the scope (FFT=0, WF=1, SYNC=2)"}, + {1, "ValMacro(<%VER>)>="VERNO,"マクロ展開文字列の数値を比較", "Compare value of the Macro"}, + {1, "ValMenu","選択された<%Menu=...>のインデックス番号を比較", "Compare value of the selected <%Menu=...> index"}, + {1, "StrCall==JA3QRZ","コールサインの比較", "Compare his callsign"}, + {1, "StrMode==GMSK","モードの比較", "Compare current Mode"}, + {1, "StrBand==40m","ログ周波数(バンド)の比較", "Compare logging BAND"}, + {1, "StrHisRST==599","HisRSTの比較", "Compare HisRST"}, + {1, "StrMyRST==599","MyRSTの比較", "Compare MyRST"}, + {1, "StrNote==???","Noteの比較", "Compare Note"}, + {1, "StrEntity==JA","エンティティの比較", "Compare the entity of his callsign"}, + {1, "StrContinent==AS","大陸の比較", "Compare the continent of his callsign"}, + {1, "StrVARITYPE==JA","VARICODE種別(JA/HL/BV/BY/STD)の比較", "Compare type of the VARICODE(JA/HL/BV/BY/STD)"}, + {1, "StrPLATFORM==XP","Windowsプラットフォーム(95/98/98SE/ME/NT/2000/XP)の比較", "Compare platform of the Windows(95/98/98SE/ME/NT/2000/XP)"}, + {1, "StrMacro(<%VER>)=="VERNO,"マクロ展開文字列の比較", "Compare strings of the Macro"}, + {1, "#else","残りのすべてで真", "Rest of all"}, + {1, "#endif","条件ブロックを終了", "Exit condition block"}, + {1, "#macro <%TX>","マクロコマンドをパス1で実行", "Execute macro at the pass 1"}, + {1, "#proc Name","プロシジャーの登録 (Name, Dummy...)", "Register procedure (Name, Dummy...)"}, + {1, "#endp","プロシジャーの登録の終了", "End of the procedure"}, + {1, "#repeat 3","#repeat 〜 #endpまでを繰り返し", "Repeat the block #repeat to #endp"}, + {1, "#define Name Strings","文字列を名前変数に定義", "Define variable strings to the name"}, + {1, "#DEFINE Name Strings","文字列を名前変数に定義(INIフィアルに保存)", "Define variable strings to the name (Save to INI file)"}, + {1, "#DELETE Name", "名前変数またはプロシジャーを削除", "Delete variable string or procedure"}, + {1, "#DELETEALL", "すべての名前変数を削除", "Delete all variable strings and procedures"}, + {1, "#exit","マクロ文の終了(パス1で終了)", "Exit macro at the pass 1"}, + {1, "#comment","コメント行", "Comment line"}, + {0, NULL, NULL}, +}; +static int g_Pos[2]={0,0}; +static int g_TopPos[2]={0,0}; +static POINT g_xySave;//={0,0}; +//--------------------------------------------------------------------- +__fastcall TMacroKeyDlg::TMacroKeyDlg(TComponent* AOwner) + : TForm(AOwner) +{ + g_xySave.x = 0; + g_xySave.y = 0; + m_pDlg = NULL; + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ +// Caption = "Choose macro"; + CancelBtn->Caption = "Close"; + SBIns->Caption = "Insert"; + SBSpace->Caption = "Space"; + SBCR->Caption = "Enter"; + SBUndo->Caption = "Undo"; + SBFind->Caption = "Find"; + SBPrint->Caption = "Print"; + + SBIns->Hint = "Insert current command"; + SBSpace->Hint = "Insert 'Space'"; + SBCR->Hint = "Insert 'Enter'"; + SBUndo->Hint = "Cancel of the operation"; + SBFind->Hint = "Find strings"; + SBPrint->Hint = "Print the list (Right click for create file)"; + Grid->Hint = "Insert command for double click (Sort - click the title)"; + } + OnWave(); + m_Type = 0; + m_fSort = FALSE; + m_fSortType = 0; + m_fDisDblClick = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::FormDestroy(TObject *Sender) +{ + g_xySave.x = Left; + g_xySave.y = Top; + g_Pos[m_Type] = Grid->Row; + g_TopPos[m_Type] = Grid->TopRow; +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::UpdateUI(int row) +{ + int r = row - 1; + if( r >= 0 ){ + SBIns->Enabled = TRUE; + } + else { + SBIns->Enabled = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::UpdateUndo(BOOL undo) +{ + SBUndo->Enabled = undo; +} +//--------------------------------------------------------------------- +int __fastcall TMacroKeyDlg::AddMacKey(MACKEY *mp, int n) +{ + for( ; mp->r; mp++){ + if( (mp->r == 2) && sys.m_MsgEng ) continue; + if( (mp->r == 3) && !sys.m_MsgEng ) continue; + mackey[n] = *mp; + n++; + } + return n; +} +//--------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::Execute(int x, int y, TMacEditDlg *pDlg, int type) +{ + m_fSort = FALSE; + m_Type = type; + Grid->RowCount = AddMacKey(type ? condcom : mackeycom, 0) + 1; + if( (g_Pos[type] > 0) && (g_Pos[type] < Grid->RowCount) ){ + Grid->Row = g_Pos[type]; + Grid->TopRow = g_TopPos[type]; + } + UpdateUI(Grid->Row); + if( type ){ + Caption = sys.m_MsgEng ? "Choose Condition command (pass 1 command)" : "条件命令(パス1命令)の選択"; + } + else { + Caption = sys.m_MsgEng ? "Choose Macro command (pass 2 command)" : "マクロコマンド(パス2命令)の選択"; + } + SBSpace->Enabled = !type; + SBCR->Enabled = !type; +#if DEBUG + char bf[256]; + sprintf(bf, "%s (Commands=%u/%u)", Caption.c_str(), Grid->RowCount-1, MACLISTMAX); + Caption = bf; +#endif + m_pDlg = pDlg; + if( (x >= 0) && (y >= 0) ){ + if( g_xySave.x && g_xySave.y ){ + Left = g_xySave.x; + Top = g_xySave.y; + } + else { + Left = x; + Top = y; + } + } + Visible = TRUE; + OnWave(); + Grid->SetFocus(); +} +//--------------------------------------------------------------------- +LPCSTR __fastcall TMacroKeyDlg::GetComment(const MACKEY *mp) +{ + LPCSTR pCom; + + if( sys.m_MsgEng ){ + pCom = mp->pEng; + if( pCom == NULL ){ + pCom = mp->pJpn; + } + } + else { + pCom = mp->pJpn; + } + return pCom; +} +//--------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::GridDrawCell(TObject *Sender, int Col, + int Row, TRect &Rect, TGridDrawState State) +{ + char bf[256]; + Grid->Canvas->Font->Height = -12; + Grid->Canvas->FillRect(Rect); + int X = Rect.Left + 4; + int Y = Rect.Top + 2; + + if( Row ){ + Row--; + bf[0] = 0; + switch(Col){ + case 0: + OnWave(); + strcpy(bf, mackey[Row].pKey); + break; + case 1: + strcpy(bf, GetComment(&mackey[Row])); + break; + } + Grid->Canvas->TextRect(Rect, X, Y, bf); + } + else { // タイトル + LPCSTR _tt[]={ + "Commands","Comments", + }; + Grid->Canvas->TextRect(Rect, X, Y, _tt[Col]); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::GridSelectCell(TObject *Sender, int Col, + int Row, bool &CanSelect) +{ + UpdateUI(Row); +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::CancelBtnClick(TObject *Sender) +{ + g_Pos[m_Type] = Grid->Row; + g_TopPos[m_Type] = Grid->TopRow; + Visible = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBInsClick(TObject *Sender) +{ + if( m_pDlg ){ + if( Grid->Row ){ + LPCSTR p = mackey[Grid->Row - 1].pKey; + if( m_Type ){ + char bf[256]; + sprintf(bf, (*p == '#') ? "%s\r" : "#if %s\r", p); + p = bf; + } + m_pDlg->OnInsertText(p); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBSpaceClick(TObject *Sender) +{ + if( m_pDlg ){ + m_pDlg->OnInsertText(" "); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBCRClick(TObject *Sender) +{ + if( m_pDlg ){ + m_pDlg->OnInsertText("\r"); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBUndoClick(TObject *Sender) +{ + if( m_pDlg ){ + m_pDlg->Undo(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::GridMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Y < Grid->DefaultRowHeight ){ + if( Button == mbLeft ){ + int type = (X <= Grid->ColWidths[0]) ? 0 : 1; + if( type == m_fSortType ){ + m_fSort = m_fSort ? FALSE : TRUE; + } + else { + m_fSort = TRUE; + } + m_fSortType = type; + Sort(m_fSort, type); + Grid->Invalidate(); + m_fDisDblClick = TRUE; + } + } + else { + m_fDisDblClick = FALSE; + } +} +//--------------------------------------------------------------------------- +static int _USERENTRY _cmpK(const void *s, const void *t) +{ + const MACKEY *sp = (const MACKEY *)s; + const MACKEY *tp = (const MACKEY *)t; + return strcmpi(sp->pKey, tp->pKey); +} +//--------------------------------------------------------------------------- +static int _USERENTRY _cmpC(const void *s, const void *t) +{ + const MACKEY *sp = (const MACKEY *)s; + const MACKEY *tp = (const MACKEY *)t; + LPCSTR pComS, pComT; + if( sys.m_MsgEng ){ + pComS = sp->pEng; + if( pComS == NULL ) pComS = sp->pJpn; + pComT = tp->pEng; + if( pComT == NULL ) pComT = tp->pJpn; + } + else { + pComS = sp->pJpn; + pComT = tp->pJpn; + } + return strcmpi(pComS, pComT); +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::Sort(BOOL fSort, int type) +{ + if( fSort ){ + qsort(mackey, Grid->RowCount - 1, sizeof(MACKEY), type ? _cmpC : _cmpK); + } + else { + AddMacKey(m_Type ? condcom : mackeycom, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::GridDblClick(TObject *Sender) +{ + if( m_fDisDblClick ){ + m_fDisDblClick = FALSE; + return; + } + SBInsClick(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::FormKeyPress(TObject *Sender, char &Key) +{ + if( isalpha(Key) ){ + int c = toupper(Key); + if( !m_fSort || m_fSortType ){ + m_fSort = TRUE; + m_fSortType = 0; + Sort(m_fSort, m_fSortType); + } + MACKEY *mp = mackey; + LPCSTR p; + for( int i = 0; i < Grid->RowCount - 1; i++, mp++ ){ + p = mp->pKey; + if( p ){ + if( *p == '<' ) p++; + if( *p == '%' ) p++; + if( toupper(*p) == c ){ + int top = i; + if( top < 1 ) top = 1; + Grid->TopRow = top; + Grid->Row = i + 1; + break; + } + } + } + Grid->Invalidate(); + } +} +//--------------------------------------------------------------------------- +static BOOL __fastcall jstrstr(LPCSTR s, LPCSTR p) +{ + CMBCS *pM = &MainVARI->m_RxSet[0].m_MBCS; + int l = strlen(p); + for( ; *s; s++ ){ + if( !strnicmp(s, p, l) ) return TRUE; + if( pM->IsLead(BYTE(*s)) ) s++; + if( !*s ) break; + } + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBFindClick(TObject *Sender) +{ + AnsiString as; + if( InputMB("MMVARI", sys.m_MsgEng ? "Find string" : "検索文字列", as) ){ + if( as.IsEmpty() ) return; + MACKEY mac[MACLISTMAX]; + memset(mac, 0, sizeof(mac)); + int N = 0; + MACKEY *wp = mac; + MACKEY *mp = mackey; + LPCSTR p; + int i; + for( i = 0; i < Grid->RowCount - 1; i++, mp++ ){ + p = mp->pKey; + if( p ){ + if( jstrstr(p, as.c_str()) ){ + memcpy(wp, mp, sizeof(MACKEY)), wp++; + N++; + } + else { + p = GetComment(mp); + if( p && jstrstr(p, as.c_str()) ){ + memcpy(wp, mp, sizeof(MACKEY)), wp++; + N++; + } + } + } + } + mp = mackey; + for( i = 0; i < Grid->RowCount - 1; i++, mp++ ){ + BOOL f = FALSE; + MACKEY *rp = mac; + for( int j = 0; j < N; j++, rp++ ){ + if( !memcmp(rp, mp, sizeof(MACKEY)) ){ + f = TRUE; + break; + } + } + if( !f ){ + memcpy(wp, mp, sizeof(MACKEY)), wp++; + N++; + } + } + memcpy(mackey, mac, sizeof(mackey)); + m_fSort = FALSE; + Grid->TopRow = 1; + Grid->Row = 1; + Grid->Invalidate(); + } +} +//--------------------------------------------------------------------------- +// リストの印刷 +void __fastcall TMacroKeyDlg::SBPrintClick(TObject *Sender) +{ + CWaitCursor w; +#if 1 // 設定ダイアログ + TPrinterSetupDialog *pBox = new TPrinterSetupDialog(this); +#else // 印刷ダイアログ + TPrintDialog *pBox = new TPrintDialog(this); + pBox->Options.Clear(); +#endif + OnWave(); + if( pBox->Execute() ){ + OnWave(); + char bf[512]; + + Printer()->Title = VERTTL2; + Printer()->BeginDoc(); + + int kcount = Grid->RowCount - 1; // 項目の数 + int pyw = Printer()->PageHeight; // 用紙の縦幅 + int pxw = Printer()->PageWidth; // 用紙の横幅 + int xoff = pxw * 5 / 100; // 左右のマージン + int yoff = pyw * 5 / 100; // 上下のマージン + int yw = pyw - (yoff*2); // 印刷領域の縦幅 + int xw = pxw - (xoff*2); // 印刷領域の横幅 + int pline; + if( yw > xw ){ // 縦長 + pline = 50; + } + else { // 横長 + pline = 25; + } + int lyw = yw / (pline + 2); // 1行あたりのピクセル数 + yw = lyw * (pline + 2); + + TCanvas *pCanvas = Printer()->Canvas; + pCanvas->Font->Name = Font->Name; + pCanvas->Font->Charset = Font->Charset; + pCanvas->Font->Height = -(lyw * 8 / 10); + pCanvas->Font->Color = clBlack; + pCanvas->Pen->Color = clBlack; + int pagemax = (kcount + pline - 1) / pline; // ページの数 + TRect rc; // 表の枠の範囲 + rc.Left = xoff; rc.Top = yoff; + rc.Right = rc.Left + xw; rc.Bottom = rc.Top + yw; + int xt = (lyw * 1) / 10; // 文字のオフセット + int yt = (lyw * 1) / 10; // 文字のオフセット + if( !xt ) xt++; + if( !yt ) yt++; + int xp = ((rc.Right - rc.Left) * 4 / 10); // 垂直分割線の位置 + const MACKEY *mp = mackey; + int n = 0; + for( int i = 1; i <= pagemax; i++ ){ + OnWave(); + int y = rc.Top; + for( int j = 0; j < (pline+2); j++, y += lyw ){ + switch(j){ + case 0: // タイトルの描画 + sprintf(bf, "%s - " VERTTL2, m_Type ? "Conditions" : "Macros"); + pCanvas->TextOut(rc.Left, y, bf); + sprintf(bf, "%u/%u", i, pagemax); + pCanvas->TextOut(rc.Right - pCanvas->TextWidth(bf), y, bf); + break; + case 1: // 項目名の描画 + pCanvas->TextOut(rc.Left+xt, y+yt, sys.m_MsgEng ? "Commands" : "コマンド"); + pCanvas->TextOut(rc.Left+xp+xt, y+yt, sys.m_MsgEng ? "Comments" : "機能/動作"); + break; + default: // 各項目の描画 + if( n < kcount ){ + pCanvas->TextOut(rc.Left + xt, y+yt, mp->pKey); + pCanvas->TextOut(rc.Left + xp + xt, y+yt, GetComment(mp)); + n++; mp++; + } + break; + } + pCanvas->MoveTo(rc.Left, y+lyw); pCanvas->LineTo(rc.Right, y+lyw); + } + y = rc.Top + lyw; + pCanvas->MoveTo(rc.Left, y); + pCanvas->LineTo(rc.Right, y); + pCanvas->LineTo(rc.Right, rc.Bottom); + pCanvas->LineTo(rc.Left, rc.Bottom); + pCanvas->LineTo(rc.Left, y); + pCanvas->MoveTo(rc.Left + xp, y); pCanvas->LineTo(rc.Left + xp, rc.Bottom); + if( i < pagemax ) Printer()->NewPage(); + } + Printer()->EndDoc(); + OnWave(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TMacroKeyDlg::SBPrintMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + TSaveDialog *pBox = new TSaveDialog(this); + pBox->Options << ofOverwritePrompt; + pBox->Options << ofNoReadOnlyReturn; + if( sys.m_MsgEng ){ + pBox->Title = "Create list file"; + pBox->Filter = "Text Files(*.txt)|*.txt|"; + } + else { + pBox->Title = "一覧表ファイルを作成"; + pBox->Filter = "テキストファイル(*.txt)|*.txt|"; + } + pBox->FileName = "Temp"; + pBox->DefaultExt = "txt"; + pBox->InitialDir = sys.m_TextDir; + OnWave(); + if( pBox->Execute() == TRUE ){ + OnWave(); + FILE *fp = fopen(AnsiString(pBox->FileName).c_str(), "wt"); //JA7UDE 0428 + if( fp ){ + const MACKEY *mp = mackey; + for( int i = 1; i < Grid->RowCount; i++, mp++ ){ + fprintf(fp, "%d\t%s\t%s\n", i, mp->pKey, GetComment(mp)); + } + fclose(fp); + } + } + delete pBox; + } +} +//--------------------------------------------------------------------------- diff --git a/MacroKey.dfm b/MacroKey.dfm new file mode 100644 index 0000000..5fcbe56 Binary files /dev/null and b/MacroKey.dfm differ diff --git a/MacroKey.h b/MacroKey.h new file mode 100644 index 0000000..13a6255 --- /dev/null +++ b/MacroKey.h @@ -0,0 +1,101 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef MacroKeyH +#define MacroKeyH +//---------------------------------------------------------------------------- +// JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//---------------------------------------------------------------------------- +#define MACLISTMAX 288 +//---------------------------------------------------------------------------- +#pragma option -a- // パックの指示 +typedef struct { + BYTE r; + LPCSTR pKey; + LPCSTR pJpn; + LPCSTR pEng; +}MACKEY; +#pragma option -a. // パック解除の指示 +class TMacEditDlg; +class TMacroKeyDlg : public TForm +{ +__published: + TButton *CancelBtn; + TStringGrid *Grid; + TSpeedButton *SBIns; + TSpeedButton *SBSpace; + TSpeedButton *SBCR; + TSpeedButton *SBUndo; + TSpeedButton *SBFind; + TSpeedButton *SBPrint; + void __fastcall GridDrawCell(TObject *Sender, int Col, int Row, + TRect &Rect, TGridDrawState State); + void __fastcall GridSelectCell(TObject *Sender, int Col, int Row, + bool &CanSelect); + void __fastcall CancelBtnClick(TObject *Sender); + void __fastcall SBInsClick(TObject *Sender); + void __fastcall SBSpaceClick(TObject *Sender); + void __fastcall SBCRClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall SBUndoClick(TObject *Sender); + void __fastcall GridMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall GridDblClick(TObject *Sender); + void __fastcall FormKeyPress(TObject *Sender, char &Key); + void __fastcall SBFindClick(TObject *Sender); + + void __fastcall SBPrintClick(TObject *Sender); + void __fastcall SBPrintMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); +private: + int m_Type; + BOOL m_fSort; + int m_fSortType; + BOOL m_fDisDblClick; + MACKEY mackey[MACLISTMAX]; + int __fastcall AddMacKey(MACKEY *mp, int n); + LPCSTR __fastcall GetComment(const MACKEY *mp); + void __fastcall UpdateUI(int row); + void __fastcall Sort(BOOL fSort, int type); + + TMacEditDlg *m_pDlg; + +public: + virtual __fastcall TMacroKeyDlg(TComponent* AOwner); + + void __fastcall Execute(int x, int y, TMacEditDlg *pDlg, int type); + void __fastcall UpdateUndo(BOOL undo); +}; +//---------------------------------------------------------------------------- +//extern TMacroKeyDlg *MacroKeyDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/MacroTxt/AddMenu.txt b/MacroTxt/AddMenu.txt new file mode 100644 index 0000000..6157202 --- /dev/null +++ b/MacroTxt/AddMenu.txt @@ -0,0 +1,29 @@ +<%DisableCR> +#define _Name1 拡張(&1) +<%DeleteMenu=_Name1> +<%AddMenu=_Name1, CWの速度(&C)..., Slider, CWの速度, CWSpeed, 10, 40> +<%AddMenu=_Name1, デジタル出力レベル(&D)..., Slider, デジタル出力レベル, DigitalLevel, 1024, 32768, 1024> +<%AddMenu=_Name1, -> +<%AddMenu=_Name1, CQ DX(&1) (リピート), OnCQDXClick, 1, 3, 3, 4000> +<%AddMenu=_Name1, CQ DX(&3) (リピート), OnCQDXClick, 3, 3, 3, 5000> +<%AddMenu=_Name1, -> +<%AddMenu=_Name1, リモート接続(&M)..., OnCommand, "<%SoundDevice=MONO,WLClient><%Radio=RPClient>"> +<%AddMenu=_Name1, リモート接続の解除(&R)..., OnCommand, "<%SoundDevice=MONO,-1><%Radio=NONE>"> + +#proc OnCommand @Command +<%DisableCR>@Command +#endp + +#proc OnCQDXClick @Nline, @Ncq, @Ncall, @Interval +<%DisableCR><%ClearTXW><%AutoClear><%TX><%RX> +<%RepeatText=@Nline,<%RepeatText=@Ncq,CQ DX<%SP>>de<%RepeatText=@Ncall,<%SP><%MyCall>><%CR>> +<%BS><%SP>pse DX k<%CR><%RepeatTX=@Interval> +#endp + +#proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales +<%DisableCR> +#macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> +#if StrMacro(<%Input$>) +<%@Command=<%Input$>> +#endif +#endp diff --git a/MacroTxt/Button101.txt b/MacroTxt/Button101.txt new file mode 100644 index 0000000..d9eb572 --- /dev/null +++ b/MacroTxt/Button101.txt @@ -0,0 +1,23 @@ +<%DisableCR><%DisableTAB> +#define _tButtons "60-30-15<%TAB>(Default)","60-20-10","60-40-15" +#define _tReplays Replay latest 10sec, Replay latest 15sec, Replay latest 20sec, Replay latest 30sec +#define _strMenu OFF, ON, -, 0, <%String=_tButtons>, -, 0, <%String=_tReplays> +#define _iSwitch <%Format=%d,<%Cond=IsPlayBack>+1> +#if IsPlayBack +#macro <%MenuB=_iSwitch, _strMenu> +#else +#macro <%MenuB=_iSwitch, OFF, ON> +#endif +#if ValMenu + #if StrMacro(<%Input$>) >> - + #define _strButtons <%Format=%.2s,<%Input$>>,<%Format=%.2s,<%Skip$=3,<%Input$>>>,<%Format=%.2s,<%Skip$=6,<%Input$>>> + #macro <%PlayBackButtons=_strButtons> + #elseif StrMacro(<%Input$>) >> Replay + #define _strTime <%Format=%d,<%Input$>> + #macro <%WaterMsg=3,_strTime> + #macro <%PlayBack=_strTime> + #else + #macro <%PlayBack=<%Input$>> + #endif +#endif +<%EOF> diff --git a/MacroTxt/Button86.txt b/MacroTxt/Button86.txt new file mode 100644 index 0000000..aca625c --- /dev/null +++ b/MacroTxt/Button86.txt @@ -0,0 +1,12 @@ +<%DisableCR> +<%CallProc=Repeat, 3, CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall><%CR>> +<%BS> pse k...<%CR> + +#proc Repeat @N, @Text +<%DisableCR> +#define _RepCount <%Format=%d,@N-1> +#if _RepCount >= 0 +@Text +<%CallProc=Repeat, _RepCount, @Text> +#endif +#endp diff --git a/MacroTxt/File1.txt b/MacroTxt/File1.txt new file mode 100644 index 0000000..240332e --- /dev/null +++ b/MacroTxt/File1.txt @@ -0,0 +1,5 @@ +<%TX><%RX> +#repeat 3 +CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> (<%Format=%d, 1 + $repeat - $counter>)<%SP><%CallProc=DateTime, <%LPTIME>> +#endp +pse k...<%CR> diff --git a/Macros.mac b/Macros.mac new file mode 100644 index 0000000..f49c860 --- /dev/null +++ b/Macros.mac @@ -0,0 +1,960 @@ +[MB1] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB2] +Name=CQ +Text="#if StrVARITYPE>>STD || StrVARITYPE==BAUDOT\r\n<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse K<%RX>\r\n#else\r\n<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K<%RX>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB3] +Name=CQ2 +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB4] +Name=1x1 +Text="<%NETON><%TX><%HisCall> de <%MyCall>\r\n<%RX>" +Color=0 +Style=0 + +[MB5] +Name=2x2 +Text="<%NETON><%TX><%IDLE><%IDLE><%HisCall> <%HisCall> de <%MyCall> <%MyCall>\r\n<%RX>" +Color=0 +Style=0 + +[MB6] +Name=RRR +Text="<%IDLE><%IDLE>RRR <%HisCall> de <%MyCall> <%RxCarrier>\r\n#if IsLocal\r\n#if StrVARITYPE == STD/JA\r\n--- ---\r\n#else\r\n--- <%VARITYPE> ---\r\n#endif\r\n#endif\r\n" +Color=0 +Style=0 + +[MB7] +Name=BTU +Text="BTU <%HisCall> de <%MyCall> KN\r\n<%CWID=]><%RX><%AutoClear><%EOF>" +Color=0 +Style=0 + +[MB8] +Name=Test +Text="(1)◎はじめに\r\n(2) 私は日本人なので日本語での会話が好きです。PSK31においても国内局同士\r\n(3)であればできるだけ日本語で会話します。ご存知の通り、PSK31は素晴らしい\r\n(4)伝送方式ですが、日本語を伝送する場合、若干の問題があることが気になって\r\n(5)いました。そして他の東アジア系言語(ハングル、中国語)でも同じ問題を持つと\r\n(6)考えられます。\r\n(7) このプロジェクトは、この問題を低減する方法について考察し、それを実験する\r\n(8)ことを目的とします。\r\n" +Color=0 +Style=0 + +[MB9] +Name=CH1 +Text="<%ShowCH=1,ONOFF>" +Color=0 +Style=4 + +[MB10] +Name=PTT +Text="#if IsPTT\r\n#macro <%PTTOFF>\r\n#else\r\n#macro <%PTTON>\r\n#endif" +Color=0 +Style=0 + +[MB11] +Name=M11 +Text="<%SeekPrev>" +Color=0 +Style=0 + +[MB12] +Name=M12 +Text="<%SeekNext>" +Color=0 +Style=0 + +[MB13] +Name=CWID +Text="<%TX><%CWID=DE <%MyCall>><%RX><%EOF>" +Color=0 +Style=4 + +[MB14] +Name=TU SK +Text="<%TX><%CWID=TU:><%RX><%EOF>" +Color=0 +Style=4 + +[MB15] +Name=AS +Text="#if !IsTX\r\n<%AutoNET><%AutoReturn><%SkipCR>\r\n#if ValPage!=4\r\n<%Page=4><%SkipCR>\r\n#else\r\n<%Page=3><%SkipCR>\r\n#endif\r\n<%ClearTXW><%SkipCR>\r\n#endif\r\n<%TX><%CWID=@><%RX><%EOF>\r\n" +Color=0 +Style=4 + +[MB16] +Name=1750 +Text="<%RxCarrier=_DefaultCarrier>" +Color=0 +Style=0 + +[MB17] +Name=NEST +Text="#define\t_CW\t<%CWID=de <%MyCall>>\r\n<%TX><%RX><%String=_CW><%EOF>" +Color=0 +Style=0 + +[MB18] +Name=FIN +Text="#if IsLocal\r\nRRR <%DearName>有難うございました。 73 SK....<%RX>\r\n#else\r\nRRR Thanks again, <%DearName> CUL, 73 SK....<%RX>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB19] +Name=DemLPF +Text="<%ShowDemLPF>" +Color=0 +Style=0 + +[MB20] +Name=DearName +Text="<%DearName>" +Color=0 +Style=0 + +[MB21] +Name=CH2 +Text="<%ShowCH=2,ONOFF>" +Color=0 +Style=4 + +[MB22] +Name=IDLE +Text="<%IDLE><%IDLE>" +Color=0 +Style=0 + +[MB23] +Name=M23 +Text="" +Color=0 +Style=0 + +[MB24] +Name=M24 +Text="#if !IsDefined(TodayWX) || !StrMacro(<%String=TodayWX>)\r\n#define\tTodayWX\t<%Input=WXを入力>\r\n#endif\r\n#if StrMacro(<%String=TodayWX>)\r\n本日のお天気は、<%String=TodayWX>です。\r\n#endif\r\n" +Color=0 +Style=0 + +[MB25] +Name=REP +Text="#define\tReceiveTime\t5000\r\n#if !IsSQ\r\n<%RepeatTX=ReceiveTime><%ClearTXW><%SkipCR>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n#elseif StrMacro(<%Capture>)\r\n#macro <%HisCall=<%Capture>>\r\n#else\r\n#macro <%Repeat=1000>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB26] +Name=Sound +Text="<%WaterMsg=3,<%SoundName>>" +Color=0 +Style=0 + +[MB27] +Name=CH1,GMSK +Text="<%SetCHMode=1,GMSK>" +Color=0 +Style=0 + +[MB28] +Name=CH1,250 +Text="<%SetCHSpeed=1,250.5>" +Color=0 +Style=0 + +[MB29] +Name=MMSSTV +Text="<%Suspend><%Execute=D:\\MMSSTV\\MMSSTV.exe>" +Color=0 +Style=0 + +[MB30] +Name=Tx BPF +Text="<%ShowTxBPF>" +Color=0 +Style=0 + +[MB31] +Name=DECM +Text="<%ShowDECM>" +Color=0 +Style=0 + +[MB32] +Name=SQ=3.0 +Text="<%SquelchLevel=3.0>" +Color=0 +Style=0 + +[MB33] +Name=ShowMFSK +Text="<%ShowMFSK>" +Color=0 +Style=0 + +[MB34] +Name=CW +Text="#if StrMacro(<%Input=Input CW text, vvv vvv vvv>)\r\n<%TX><%RX><%CWID=<%Input$>><%EOF>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB35] +Name=M35 +Text="#define\tMyRIG\t\tFT1000MP 50W\r\n#define\tMyANT80m\tVertical(7m)\r\n#define\tMyANT40m\tVertical(7m)\r\n#define\tMyANT30m\tMagnetic loop(90cm)\r\n#define\tMyANT20m\tMagnetic loop(90cm)\r\n#define\tMyANT17m\tMagnetic loop(90cm)\r\n#define\tMyANT15m\tMagnetic loop(90cm)\r\n#define\tMyANT12m\tMagnetic loop(90cm)\r\n#define\tMyANT10m\tMagnetic loop(90cm)\r\n#if StrBand==80m\r\n#define\tMyANT\t\tMyANT80m\r\n#elseif StrBand==40m\r\n#define\tMyANT\t\tMyANT40m\r\n#elseif StrBand==30m\r\n#define\tMyANT\t\tMyANT30m\r\n#elseif StrBand==20m\r\n#define\tMyANT\t\tMyANT20m\r\n#elseif StrBand==17m\r\n#define\tMyANT\t\tMyANT17m\r\n#elseif StrBand==15m\r\n#define\tMyANT\t\tMyANT15m\r\n#elseif StrBand==12m\r\n#define\tMyANT\t\tMyANT12m\r\n#else\r\n#define\tMyANT\t\tMyANT10m\r\n#endif\r\n私のリグは<%String=MyRIG>、アンテナは<%String=MyANT>です。\r\n" +Color=0 +Style=0 + +[MB36] +Name=M36 +Text="#define\tQTH_HOME\t大阪府高槻市\r\n#define\tQTH_25006\t大阪府三島郡\r\n#define\tQTH_2701\t兵庫県神戸市\r\n#if StrNote >> 25006\r\n#define\tMyQTH\t\tQTH_25006\r\n#elseif StrNote >> 2701\r\n#define\tMyQTH\t\tQTH_2701\r\n#else\r\n#define\tMyQTH\t\tQTH_HOME\r\n#endif\r\n私の現在のQTHは、<%String=MyQTH>です。\r\n" +Color=0 +Style=0 + +[MB37] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB38] +Name=RAND +Text="<%WaterMsg=3,<%RANDOM>>" +Color=0 +Style=0 + +[MB39] +Name=GPS +Text="#define\t_T_NOW\t<%PTIME>\r\n#define\t_T_DIFF\t<%Format=%d,_T_NOW-_T_B4>\r\n#define\t_T_B4\t_T_NOW\r\n<%String=_T_DIFF>\r\n" +Color=0 +Style=0 + +[MB40] +Name=CPU +Text="<%WaterMsg=4,<%CPUBENCHMARK>><%Repeat=1000>" +Color=0 +Style=0 + +[MB41] +Name=TIMEVAL +Text="<%DisableCR>\r\n#define\t_PT\t<%Format=%u,<%PTIME>+9*60*60>\r\n<%WaterMsg=3,<%VALTIME=HOUR,_PT>:<%VALTIME=MINUTE,_PT>:<%VALTIME=SECOND,_PT>>" +Color=0 +Style=0 + +[MB42] +Name=M42 +Text="<%VALTIME=LMonth,<%PTIME>>" +Color=0 +Style=0 + +[MB43] +Name=atcppm +Text="<%ATCPPM>\r\n" +Color=0 +Style=0 + +[MB44] +Name=MLEN +Text="<%MStrLen=<%Note>>" +Color=0 +Style=0 + +[MB45] +Name=M45 +Text="#define AAA 50" +Color=0 +Style=0 + +[MB46] +Name=M46 +Text="<%SeekTop>" +Color=0 +Style=0 + +[MB47] +Name=M47 +Text="<%SeekPrev>" +Color=0 +Style=0 + +[MB48] +Name=M48 +Text="<%SeekNext>" +Color=0 +Style=0 + +[MB49] +Name=RadioKHz +Text="<%WaterMsg=3,<%RadioKHz>>" +Color=0 +Style=0 + +[MB50] +Name=M50 +Text="" +Color=0 +Style=0 + +[MB51] +Name=M51 +Text="<%TxIMM=<%CWID=JE3HHT>>" +Color=0 +Style=0 + +[MB52] +Name=M52 +Text="#DEFINE\t_DefaultCarrier\t1500\r\n#DEFINE\t_DefaultTEST\t0\r\n" +Color=0 +Style=0 + +[MB53] +Name=M53 +Text="#DELETE _DefaultCarrier\r\n#DELETE _DefaultTEST" +Color=0 +Style=0 + +[MB54] +Name=B/2 +Text="<%BAUD=<%Format=%f,<%BAUD>/2>>" +Color=0 +Style=0 + +[MB55] +Name=M55 +Text="" +Color=0 +Style=0 + +[MB56] +Name=M56 +Text="" +Color=0 +Style=0 + +[MB57] +Name=M57 +Text="" +Color=0 +Style=0 + +[MB58] +Name=M58 +Text="" +Color=0 +Style=0 + +[MB59] +Name=M59 +Text="" +Color=0 +Style=0 + +[MB60] +Name=M60 +Text="<%MODE=rtty-U>" +Color=0 +Style=0 + +[MB61] +Name=RxFile +Text="<%RxFile=history.txt>" +Color=0 +Style=0 + +[MB62] +Name=RST +Text="<%HisRST>\r\n" +Color=0 +Style=0 + +[MB63] +Name=NR +Text="<%HisNR>" +Color=0 +Style=0 + +[MB64] +Name=Format +Text="<%Format=%g,<%FREQ> % 1>" +Color=0 +Style=0 + +[MB65] +Name=MOD +Text="#define\tVAL\t<%Format=%d,<%FREQ>*1000>\r\n#define\tMOD\t<%Format=%d,VAL % 1000>\r\n<%String=MOD>\r\n" +Color=0 +Style=0 + +[MB66] +Name=Bx2 +Text="<%BAUD=<%Format=%f,<%BAUD>*2>>" +Color=0 +Style=0 + +[MB67] +Name=M67 +Text="#register\t_MenuSub\t3,6,1\r\n#macro <%DoMenu=_MenuSub>" +Color=0 +Style=0 + +[MB68] +Name=AAA +Text="<%OutputVolume><%Wait=200><%KeyStroke=<%CHAR=I>><%KeyDown=12><%KeyStroke=<%CHAR=P>><%KeyUp=12><%KeyStroke=<%CHAR=R>>" +Color=0 +Style=0 + +[MB69] +Name=DoMenu +Text="#define\tMenuSub\t3,6,1\r\n#macro <%DoMenu=MenuSub>" +Color=0 +Style=0 + +[MB70] +Name=EHistory +Text="<%Execute=notepad.exe ehistory.txt>" +Color=0 +Style=0 + +[MB71] +Name=EMmvari +Text="<%Execute=notepad.exe emmvari.txt>" +Color=0 +Style=0 + +[MB72] +Name=EProject +Text="<%Execute=notepad.exe eproject.txt>" +Color=0 +Style=0 + +[MB73] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB74] +Name=MacTxt +Text="#macro <%MacroText=d:\\Temp\\Macro.txt>" +Color=0 +Style=0 + +[MB75] +Name=M75 +Text="" +Color=0 +Style=0 + +[MB76] +Name=M76 +Text="" +Color=0 +Style=0 + +[MB77] +Name=0x2 - 2x4 +Text="<%DisableCR><%DisableTAB>\r\n#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4>\r\n#if ValMenu\r\n\t#define\t_His\t<%Format=%c,<%Input$>>\r\n\t#define\t_My\t<%Format=%c,<%Skip$=2,<%Input$>>>\r\n\t<%TX><%RX>\r\n\t#if !Is1stCR\r\n\t\t<%CR>\r\n\t#endif\r\n\t#if IsCall\r\n\t\t<%RepeatText=_His,<%HisCall> >\r\n\t#endif\r\n\tde\r\n\t<%RepeatText=_My, <%MyCall>>\r\n\t pse K<%CR>\r\n#endif" +Color=0 +Style=0 + +[MB78] +Name=M78 +Text="" +Color=0 +Style=0 + +[MB79] +Name=M79 +Text="" +Color=0 +Style=0 + +[MB80] +Name=M80 +Text="" +Color=0 +Style=0 + +[MB81] +Name=M81 +Text="" +Color=0 +Style=0 + +[MB82] +Name=M82 +Text="" +Color=0 +Style=0 + +[MB83] +Name=M83 +Text="<%SeekPrev>" +Color=0 +Style=0 + +[MB84] +Name=M84 +Text="<%SeekNext>" +Color=0 +Style=0 + +[MB85] +Name=M85 +Text="" +Color=0 +Style=0 + +[MB86] +Name=M86 +Text="" +Color=0 +Style=0 + +[MB87] +Name=M87 +Text="" +Color=0 +Style=0 + +[MB88] +Name=M88 +Text="" +Color=0 +Style=0 + +[MB89] +Name=M89 +Text="" +Color=0 +Style=0 + +[MB90] +Name=M90 +Text="" +Color=0 +Style=0 + +[MB91] +Name=M91 +Text="" +Color=0 +Style=0 + +[MB92] +Name=M92 +Text="" +Color=0 +Style=0 + +[MB93] +Name=M93 +Text="" +Color=0 +Style=0 + +[MB94] +Name=M94 +Text="" +Color=0 +Style=0 + +[MB95] +Name=M95 +Text="" +Color=0 +Style=0 + +[MB96] +Name=M96 +Text="" +Color=0 +Style=0 + +[MB97] +Name=M97 +Text="<%ClearTXW><%TX><%RX>CQ CQ CQ de <%CWID=<%MyCall>><%IDLE><%IDLE><%IDLE> <%MyCall> <%MyCall> <%MyCall> pse k\r\n" +Color=0 +Style=0 + +[MB98] +Name=CQ +Text="<%DisableCR><%ClearTXW><%TX><%RX>\r\n#macro <%Menu=CQ3, CQ4, CQ5>\r\n#if ValMenu\r\n#define\t_cLine\t<%Format=%c,<%Skip$=2,<%Input$>>>\r\n<%RepeatText=_cLine,<%RepeatText=3,CQ >de<%RepeatText=3, <%MyCall>><%CR>>pse k...<%CR>\r\n#endif\r\n<%EOF>\r\n" +Color=0 +Style=0 + +[MB99] +Name=RY +Text="<%RepeatText=3,<%RepeatText=33,RY><%CR>>" +Color=0 +Style=0 + +[MB100] +Name=M100 +Text="<%PlayBackButtons=60,30,15>" +Color=0 +Style=0 + +[MB101] +Name=PlayBack +Text="#macro <%MenuB="<%Format=%d,2-<%Cond= IsPlayBack>>",ON,OFF>\r\n#if ValMenu\r\n#macro <%PlayBack=<%Input$>>\r\n#endif" +Color=0 +Style=0 + +[MB102] +Name=Sound +Text="#define\t_tCH\tMONO,LEFT,RIGHT\r\n#define\t_strCH\t<%TableStr=1,<%SoundDevice>>\r\n#define\t_iCH\t<%Table=_strCH,_tCH>\r\n#macro <%MenuB=_iCH,_tCH>\r\n#if ValMenu\r\n#macro <%SoundDevice=<%Input$>><%WaterMsg=3,Sound=<%SoundDevice>>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB103] +Name=M103 +Text="<%WaterMsg=3,<%EntityName=<%HisCall>>/<%Continent=<%HisCall>>>" +Color=0 +Style=0 + +[MB104] +Name=ShutDown +Text="<%DisableCR>\r\n#if <%YesNo=Windows will be shut down, are you sure?> == 6\r\n<%ShutDown>\r\n#endif" +Color=0 +Style=0 + +[MB105] +Name=Exit +Text="<%DisableCR>\r\n#if <%YesNo=MMVARIを終了します. ほんまにええですか?> == 6\r\n<%Exit>\r\n#endif" +Color=0 +Style=0 + +[MB106] +Name=DigiOut +Text="<%DisableCR>\r\n#define\t_tLevel\t8192,16384,24576,32768\r\n#define\t_tLabel\tLow, Midium(Default), High, VeryHigh\r\n#define\t_iLevel\t<%Table=<%DigitalLevel>,_tLevel>\r\n#macro <%MenuB=_iLevel,_tLabel>\r\n#if ValMenu\r\n<%DigitalLevel=<%TableStr=<%Menu>,_tLevel>>\r\n#endif" +Color=0 +Style=0 + +[MB107] +Name=M107 +Text="" +Color=0 +Style=0 + +[MB108] +Name=ShowClock +Text="<%OnTimer=<%WaterMsg=4,Dem=<%DemodulatorClock>(<%Format=%.2lf,<%DemodulatorClock>*0.5>), FFT=<%FFTClock>/<%FFTSize>>>" +Color=0 +Style=0 + +[MB109] +Name=M109 +Text="#if StrVARITYPE>>STD\r\n<%ClearTXW><%TX><%IDLE>CQ CQ CQ<%IDLE><%IDLE> de <%MyCall> <%MyCall> <%MyCall> pse K<%RX>\r\n#else\r\n<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K<%RX>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB110] +Name=BLK +Text="<%DIDDLE=BLK>" +Color=0 +Style=0 + +[MB111] +Name=LTR +Text="<%DIDDLE=LTR>" +Color=0 +Style=0 + +[MB112] +Name=WaterNoise +Text="#if !IsRepeat\r\n#macro <%Menu=35-65, 30-60, 30-55, 30-50, 10-65>\r\n#if ValMenu == 1\r\n#macro <%WaterNoise=35,65>\r\n#elseif ValMenu == 2\r\n#macro <%WaterNoise=30,60>\r\n#elseif ValMenu == 3\r\n#macro <%WaterNoise=30,55>\r\n#elseif ValMenu == 4\r\n#macro <%WaterNoise=30,50>\r\n#elseif ValMenu == 5\r\n#macro <%WaterNoise=10,65>\r\n#endif\r\n#endif\r\n#macro <%OnTimer=<%WaterMsg=4,<%WaterNoise>dB>>" +Color=0 +Style=0 + +[MB113] +Name=Metric +Text="<%OnTimer=<%WaterMsg=4,Metric=<%MetricMFSK>/<%MetricMFSK=even>/<%MetricMFSK=odd>>>" +Color=0 +Style=0 + +[MB114] +Name=AFCFreq +Text="<%OnTimer=<%WaterMsg=<%AFCFrequency>/<%AFCCount>/<%MetricMFSK>>>" +Color=0 +Style=0 + +[MB115] +Name=DecBench +Text="#macro <%Menu=CPU BENCH, DECM BENCH>\r\n#if ValMenu == 1\r\n#macro <%OnTimer=<%WaterMsg=4,<%CPUBENCHMARK>>>\r\n#elseif ValMenu==2\r\n#macro <%OnTimer=<%WaterMsg=4,<%BENCHDECM>>>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB116] +Name=CQ2 +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB117] +Name=Notch256 +Text="<%NotchTaps=128><%WaterMsg=3,<%NotchTaps>>" +Color=0 +Style=0 + +[MB118] +Name=Notch +Text="<%Notch=ONOFF>" +Color=0 +Style=0 + +[MB119] +Name=FileDialog +Text="#if 1\r\n#macro <%FileDialog=, MMV Files(*.mmv)|*.mmv|, Default,mmv, C:\\Sound>\r\n#macro <%WaterMsg=3,<%Input$>>\r\n#if IsFile(<%Input$>)\r\n#macro <%PlaySound=<%Input$>>\r\n#endif\r\n#else\r\n#macro <%PlaySound>\r\n#endif" +Color=0 +Style=0 + +[MB120] +Name=EditEvent +Text="\t#macro <%Menu=OnTimer,OnPTT,OnQSO,OnFind,OnStart,OnExit,OnMode,OnSpeed>\r\n\t#if ValMenu == 1\r\n\t#macro <%OnTimer>\r\n\t#elseif ValMenu == 2\r\n\t#macro <%OnPTT>\t\r\n\t#elseif ValMenu == 3\r\n\t#macro <%OnQSO>\r\n\t#elseif ValMenu == 4\r\n\t#macro <%OnFind>\r\n\t#elseif ValMenu == 5\r\n\t#macro <%OnStart>\r\n\t#elseif ValMenu == 6\r\n\t#macro <%OnExit>\r\n\t#elseif ValMenu == 7\r\n\t#macro <%OnMode>\r\n\t#elseif ValMenu == 8\r\n\t#macro <%OnSpeed>\r\n\t#endif\r\n" +Color=0 +Style=0 + +[MB121] +Name=Capture +Text="#if StrMacro(<%Capture>)\r\n#macro <%HisCall=<%Capture>>\r\n#else\r\n#macro <%Repeat=1000>\r\n#endif" +Color=0 +Style=0 + +[MB122] +Name=UOS_OFF +Text="<%UOS=OFF>" +Color=0 +Style=0 + +[MB123] +Name=UOS_ON +Text="<%UOS=ON>" +Color=0 +Style=0 + +[MB124] +Name=OnTimer +Text="\t#macro <%Menu=AFC, Metric(MFSK), RadioMode, WaterNoise, S/N, UTC, Local, -, Stop>\r\n\t#if ValMenu == 1\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>>\r\n\t#elseif ValMenu == 2\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%MetricMFSK>>>\r\n\t#elseif ValMenu == 3\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%RadioMode>>>\r\n\t#elseif ValMenu == 4\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%WaterNoise>dB>>\r\n\t#elseif ValMenu == 5\r\n\t#macro <%OnTimer=<%WaterMsg=4,S/N=<%AverageLevel>/<%PeakLevel>dB>>\r\n\t#elseif ValMenu == 6\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%UTIME>z>>\r\n\t#elseif ValMenu == 7\r\n\t#macro <%OnTimer=<%WaterMsg=4,<%LTIME>>>\r\n\t#else\r\n\t#macro <%OnTimer=>\r\n\t#endif\r\n" +Color=0 +Style=0 + +[MB125] +Name=WaitC-0 +Text="<%RTTYWaitC=0>" +Color=0 +Style=0 + +[MB126] +Name=WaitD-0 +Text="<%RTTYWaitD=0>" +Color=0 +Style=0 + +[MB127] +Name=BAUD +Text="<%WaterMsg=3,<%BAUD>>" +Color=0 +Style=0 + +[MB128] +Name=PlayBack +Text="<%PlayBack=10>" +Color=0 +Style=0 + +[MB129] +Name=NotchWidth +Text="<%WaterMsg=3,<%NotchWidth>>" +Color=0 +Style=0 + +[MB130] +Name=200 +Text="<%TxShift=200><%RxShift=200>" +Color=0 +Style=0 + +[MB131] +Name=NextMode +Text="<%DisableCR>\r\n#define\t_Table\tGMSK,bpsk,rtty-L\r\n#define\t_Count\t<%Format=%d,<%TableCount=_Table>>\r\n#define\t_CurMode\t<%Format=%d,(_CurMode%_Count)+1>\r\n#macro <%WaterMsg=4,<%String=_CurMode>/<%String=_Count>>\r\n#macro <%WaterMsg=3,<%TableStr=_CurMode,_Table>>\r\n#macro <%MODE=<%TableStr=_CurMode,_Table>>\r\n<%Repeat=3000>" +Color=0 +Style=0 + +[MB132] +Name=SimBaud +Text="#if StrMacro(<%Input=Input ppm>)\r\n#define\t_ppm\t<%Format=%f,<%Input$>*1e-6>\r\n#define\t_baud\t<%Format=%f,<%BAUD> - <%BAUD>*_ppm>\r\n#macro <%SimBAUD=<%Format=%f,_baud>>\r\n#macro <%WaterMsg=3,<%String=_baud>>\r\n#endif" +Color=0 +Style=0 + +[MB133] +Name=M133 +Text="RYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRYRY\r\n" +Color=0 +Style=0 + +[MB134] +Name=Menu +Text="#macro <%Menu=&73 CU SK, &TU SK EE, &SU, &EE>\r\n#if ValMenu==1\r\n<%TX><%RX><%CWID=73CU:><%EOF>\r\n#elseif ValMenu==2\r\n<%TX><%RX><%CWID=TU:EE><%EOF>\r\n#elseif ValMenu==3\r\n<%TX><%RX><%CWID=SU><%EOF>\r\n#elseif ValMenu==4\r\n<%TX><%RX><%CWID=EE><%EOF>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB135] +Name=Final +Text="<%Menu=<%DearName>まいどおおきに..., ほなさいなら..., "TNX AGN <%DearName>, CUL..."><%Input$>" +Color=0 +Style=0 + +[MB136] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB137] +Name=WaitC +Text="<%RTTYWaitC=50>" +Color=0 +Style=0 + +[MB138] +Name=WaitD +Text="<%RTTYWaitD=40>" +Color=0 +Style=0 + +[MB139] +Name=Dupe +Text="<%DupeText>" +Color=0 +Style=0 + +[MB140] +Name=MTTY +Text="#define\t_W\t<%Format="%f",<%BAUD>*0.5>\r\n<%TxShift=_W><%RxShift=_W>\r\n" +Color=0 +Style=0 + +[MB141] +Name=170 +Text="<%TxShift=170><%RxShift=170>" +Color=0 +Style=0 + +[MB142] +Name=450 +Text="<%TxShift=450><%RxShift=450>" +Color=0 +Style=0 + +[MB143] +Name=DLL +Text="#define\t_CallArg\td:\\test\\MacDLL\\MacDLL.dll, mmmacTest, <%MyCall>\r\n#macro <%WaterMsg=3,<%CallDLL=_CallArg>>" +Color=0 +Style=0 + +[MB144] +Name=Sim. +Text="<%TestSignal>" +Color=0 +Style=0 + +[MB145] +Name=CQ +Text="<%DisableCR><%ClearTXW><%TX><%CODE=7F><%CODE=7F><%CODE=02><%CR>\r\nCQ CQ CQ de NOCALL NOCALL NOCALL<%CR>\r\nCQ CQ CQ de NOCALL NOCALL NOCALL<%CR>\r\nCQ CQ CQ de NOCALL NOCALL NOCALL<%CR>\r\npse K<%CODE=7F><%CODE=7F><%CODE=04>\r\n<%RX>" +Color=0 +Style=0 + +[MB146] +Name=FreqMenu +Text="#if !IsDefined(_Rig)\r\n#define\t_Rig\tCI-V\r\n#endif\r\n\t#macro <%Menu=7028.5,10141.5,14072.5,18102.5,21072.5,28072.5,50980.0,144450.0>\r\n\t#if ValMenu\r\n\t#if IsRadioLSB\r\n\t#macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001>\r\n\t#else\r\n\t#macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001>\r\n\t#endif\r\n\t#endif\r\n" +Color=0 +Style=0 + +[MB147] +Name=MODE +Text="#define\t_Rig\tCI-V\r\n#define\t_t_Mode\tLSB,USB,CW,AM,FM,RTTY,PACKET\r\n#macro <%MenuB="<%Table=<%RadioMode>,_t_Mode>",_t_Mode>\r\n#if ValMenu\r\n#macro <%RadioMode=_Rig,<%Input$>>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB148] +Name=+500 +Text="#define\t_FQ\t7.028\r\n#define\t_Rig\tCI-V\r\n#if <%RadioKHz>\r\n#macro <%RadioKHz=_Rig,<%RadioKHz>+0.5>\r\n#else\r\n#macro <%RadioKHz=_Rig,_FQ*1000>\r\n#endif" +Color=0 +Style=0 + +[MB149] +Name=-500 +Text="#define\t_FQ\t7.028\r\n#define\t_Rig\tCI-V\r\n#if <%RadioKHz>\r\n#macro <%RadioKHz=_Rig,<%RadioKHz>-0.5>\r\n#else\r\n#macro <%RadioKHz=_Rig,_FQ*1000>\r\n#endif" +Color=0 +Style=0 + +[MB150] +Name=SetTone +Text="#define\t_Tone\t1750\r\n#define\t_Rig\tCI-V\r\n#macro <%Menu=1000,1200,1500,1750,2000>\r\n#if ValMenu\r\n#define\t_Tone\t<%Input$>\r\n#define\t_OffKHz\t<%Format=%f,(<%RxCarrier>-_Tone)*0.001>\r\n#if IsRadioLSB\r\n#macro <%RadioKHz=_Rig,<%RadioKHz>-_OffKHz>\r\n#else\r\n#macro <%RadioKHz=_Rig,<%RadioKHz>+_OffKHz>\r\n#endif\r\n#macro <%RxCarrier=_Tone>\r\n#endif" +Color=0 +Style=0 + +[MB151] +Name=RigQuery? +Text="#if IsRadioLSB\r\n#macro <%WaterMsg=3,<%RadioKHz> <%RadioMode> IsRadioLSB=TRUE>\r\n#else\r\n#macro <%WaterMsg=3,<%RadioKHz> <%RadioMode> IsRadioLSB=FALSE>\r\n#endif\r\n" +Color=0 +Style=0 + +[MB152] +Name=M152 +Text="" +Color=0 +Style=0 + +[MB153] +Name=M153 +Text="" +Color=0 +Style=0 + +[MB154] +Name=M154 +Text="" +Color=0 +Style=0 + +[MB155] +Name=M155 +Text="" +Color=0 +Style=0 + +[MB156] +Name=M156 +Text="" +Color=0 +Style=0 + +[MB157] +Name=M157 +Text="" +Color=0 +Style=0 + +[MB158] +Name=M158 +Text="" +Color=0 +Style=0 + +[MB159] +Name=M159 +Text="" +Color=0 +Style=0 + +[MB160] +Name=M160 +Text="" +Color=0 +Style=0 + diff --git a/Main.cpp b/Main.cpp new file mode 100644 index 0000000..1db43af --- /dev/null +++ b/Main.cpp @@ -0,0 +1,13772 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include "clipbrd.hpp" +#include +#include "Main.h" +#include "LogFile.h" +#include "MacEdit.h" +#include "FreqDisp.h" +#include "Option.h" +#include "VerDsp.h" +#include "InputWin.h" +#include "CodeVw.h" +#include "Country.h" +#include "Mmcg.h" +#include "LogLink.h" +#include "LogList.h" +#include "QSODlg.h" +#include "LogSet.h" +#include "RadioSet.h" +#include "TrackDlg.h" +#include "mml.h" +#if DEBUG +#include "Test.h" +#endif + +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TMainVARI *MainVARI; +//アプリケーションメッセージのハンドラ--------------------------------------------- +void __fastcall TMainVARI::OnAppMessage(tagMSG &Msg, bool &Handled) +{ +/* +Msg.hwnd := Handle; +Msg.message := WM_KEYDOWN; +Msg.wParam := Message.WParam; +Msg.lParam := Message.LParam; +*/ + switch(Msg.message){ + case WM_KEYUP: + if( !Active ) return; + if( ActiveControl != PCTX ) return; + if( Msg.wParam == VK_SHIFT ){ + m_fKeyShift = FALSE; + m_Edit[m_CurrentEdit].CloseSelect(); + } + break; + case WM_KEYDOWN: + if( !Active ) return; + if( ActiveControl != PCTX ) return; + switch(Msg.wParam){ + case VK_SHIFT: + m_fKeyShift = TRUE; + break; + case VK_DOWN: + case VK_UP: + case VK_LEFT: + case VK_RIGHT: + if( m_fKeyShift ) m_Edit[m_CurrentEdit].OpenSelect(); + m_Edit[m_CurrentEdit].MoveCursor(Msg.wParam); + Handled = TRUE; + break; + case VK_PRIOR: + if( m_fKeyShift ){ + SBarRX->Position--; + } + else { +// if( m_fKeyShift ) m_Edit[m_CurrentEdit].OpenSelect(); + for( int i = 0; i < m_Edit[m_CurrentEdit].GetScreenLine()/2; i++ ){ + m_Edit[m_CurrentEdit].MoveCursor(VK_UP); + } + } + Handled = TRUE; + break; + case VK_NEXT: + if( m_fKeyShift ){ + SBarRX->Position++; + } + else { +// if( m_fKeyShift ) m_Edit[m_CurrentEdit].OpenSelect(); + for( int i = 0; i < m_Edit[m_CurrentEdit].GetScreenLine()/2; i++ ){ + m_Edit[m_CurrentEdit].MoveCursor(VK_DOWN); + } + } + Handled = TRUE; + break; + case VK_TAB: + m_Edit[m_CurrentEdit].PutKey('\t', 1); + Handled = TRUE; + break; + } + break; +#if KEY_DIRECT + case WM_CHAR: + if( !Active ) return; + if( ActiveControl != PCTX ) return; +// if( !m_Edit[m_CurrentEdit].IsActive() ) return; + OnChar(Msg.wParam & (sys.m_WinNT ? 0x0000ffff : 0x000000ff)); + Handled = TRUE; + break; +#endif + } +} +//ウインドウメッセージのハンドラ--------------------------------------------- +void __fastcall TMainVARI::WndProc(TMessage &Message) +{ + switch(Message.Msg){ + case WM_COPYDATA: + WndCopyData(Message); + break; + default: + TForm::WndProc(Message); + break; + } +} +//--------------------------------------------------------------------------- +// WM_COPYDATAの処理 +void __fastcall TMainVARI::WndCopyData(TMessage &Message) +{ + COPYDATASTRUCT *cp = (COPYDATASTRUCT *)Message.LParam; + if( LogLink.IsCopyData() ){ + Message.Result = LogLink.m_pLink->OnCopyData(HWND(Message.WParam), cp); + return; + } + switch(cp->dwData){ + case 0: + case 1: // Hamlogからの返信 + if( sys.m_LogLink != 1 ) return; + switch(LogLink.AnaData(&Log.m_sd, cp)){ + case 115: + UpdateTextData(); + break; + case 106: + LogFreq->Text = Log.GetFreqString(Log.m_sd.band, Log.m_sd.fq); + OnLogFreq(FALSE); + break; + } + Message.Result = TRUE; + break; + case 0x80001212: // 周波数データの指定 + if( cp->cbData && (cp->lpData != NULL) ){ + char bf[16]; + int len = cp->cbData; + if( len > 15 ) len = 15; + memcpy(bf, cp->lpData, len); + bf[len] = 0; + LogFreq->Text = bf; + OnLogFreq(FALSE); + } + Message.Result = TRUE; + break; + case 0x80001217: // 送信/受信の切り替え + if( cp->cbData && (cp->lpData != NULL) ){ + if( *(const BYTE *)(cp->lpData) ){ + if( !m_TX ){ + ToTX(); + } + } + else if( m_TX ){ + ToRX(); + } + } + Message.Result = TRUE; + break; + case 0x8000121a: // PTT + if( cp->cbData && (cp->lpData != NULL) ){ + BOOL bPTT = *(const BYTE *)(cp->lpData); + SetPTT(bPTT); + } + break; + case 0x8000121b: // status + { + DWORD dw = m_TX ? 1 : 0; + Message.Result = dw; + } + break; + default: + Message.Result = FALSE; + break; + } +} +//--------------------------------------------------------------------------- +int __fastcall OnGetChar(void) +{ + CDump *pEdit = &MainVARI->m_Edit[MainVARI->m_SendingEdit]; + if( MainVARI->IsRTTY() && MainVARI->m_fRttyWordOut ){ + if( !MainVARI->m_fReqRX && !pEdit->IsWord() ){ + return 0; + } + } + int c = pEdit->GetChar(MainVARI->m_SendingEdit==MainVARI->m_CurrentEdit); + if( c < 0 ) c = pEdit->GetChar(MainVARI->m_SendingEdit==MainVARI->m_CurrentEdit); + if( c == '\r' ){ + MainVARI->m_ModFSK.m_Encode.PutChar('\n'); + } + if( c >= 0 ) MainVARI->m_fSendChar = TRUE; + return c; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::GetHintStatus(LPCSTR pHint) +{ + if( m_WaveFile.m_mode ){ + m_fHintUpdate = TRUE; + LPCSTR pFmt; + if( sys.m_MsgEng ){ + pFmt = m_WaveFile.m_mode == 1 ? "Sound playing... [%s] %u:%02u:%02u" : "Sound recording... [%s] %u:%02u:%02u (%.1lfMB)"; + } + else { + pFmt = m_WaveFile.m_mode == 1 ? "サウンドを再生中... [%s] %u:%02u:%02u" : "サウンドを録音中... [%s] %u:%02u:%02u (%.1lfMB)"; + } + int mb = m_WaveFile.GetPos(); + int h = int(mb * 0.5 / SAMPFREQ); + int s = h % 60; + h /= 60; + int m = h % 60; + h /= 60; + sprintf(m_HintText, pFmt, m_WaveFile.m_Name.c_str(), h, m, s, double(mb)/(1024.0*1024.0)); + return m_HintText; + } + else if( !strcmp(pHint, "%SQ") ){ + m_fHintUpdate = TRUE; + sprintf(m_HintText, sys.m_MsgEng ? "Squelch level (S/N) = %.1lfdB (Right click for menu)":"スケルチレベル(S/N) = %.1lfdB (右クリックでメニュー)", double((m_RxSet[0].m_SQLevel) / 100.0)); + return m_HintText; + } + else if( !strcmp(pHint, "%SP") ){ + if( SBFFT->Down || SBWater->Down ){ + if( m_fSubWindow || m_Notches.m_Count ) m_fHintUpdate = TRUE; + if( m_MouseNotch ){ + return sys.m_MsgEng ? "Drag for changing Notch FREQ":"ノッチ周波数を変更(ドラッグ操作)"; + } + else if( m_fSubWindow && m_MouseSubChannel ){ + sprintf(m_HintText, sys.m_MsgEng ? "Drag for changing RX FREQ (CH%d)":"チャンネル%uの受信キャリア周波数を変更(ドラッグ操作)", m_MouseSubChannel); + return m_HintText; + } + else { + return sys.m_MsgEng ? "RX FREQ(Left click), open the popup menu(Right click)":"左クリック=受信キャリア周波数, 右クリック=サブメニューを開く"; + } + } + else if( m_WaveType ){ + return sys.m_MsgEng ? "Amplitude ingredient" : "振幅成分表示"; + } + else if( m_RxSet[0].IsMFSK() || m_RxSet[0].IsQPSK() ){ + return sys.m_MsgEng ? "Timing" : "タイミングを表示"; + } + else { + return sys.m_MsgEng ? "Timing of the CODE" : "タイミングを符号単位で表示"; + } + } + else if( !strcmp(pHint, "%SD") ){ + if( m_RxSet[0].IsMFSK() ){ + CDEMFSK *pDem = m_RxSet[0].m_pDem; + char bf[64]; + sprintf(m_HintText, "mfsk%.0f %s baud %u tones (R=1/2, K=7) %.2lf bps", pDem->m_MFSK_SPEED, StrDbl(bf, pDem->m_MFSK_SPEED), pDem->m_MFSK_TONES, pDem->m_MFSK_SPEED * pDem->m_MFSK_BITS * 0.5); + } + else { + sprintf(m_HintText, sys.m_MsgEng ? "Baudrate (Standard = %sbps)" : "伝送速度(BPS) 標準は%s", IsRTTY() ? "45.45":"31.25"); + } + return m_HintText; + } + else if( !strcmp(pHint, "%TX") ){ + sprintf(m_HintText, sys.m_MsgEng ? "Switch TX/RX - %s (Right click for TONE)" : "送信/受信の切り替え - %s (右クリックでTONE)", GetKeyName(sys.m_DefKey[kkTX])); + return m_HintText; + } + else if( !strcmp(pHint, "%TXOFF") ){ + sprintf(m_HintText, sys.m_MsgEng ? "Abort TX - %s":"強制的に受信に切り替え - %s", GetKeyName(sys.m_DefKey[kkTXOFF])); + return m_HintText; + } + else if( !strcmp(pHint, "%RX") ){ + if( IsRTTY() ){ + m_fHintUpdate = TRUE; + int cf = UdRxCarrier->Position; + int mf = m_RxSet[0].m_pDem->m_RTTYShift * 0.5; + if( m_RxSet[0].m_Mode == MODE_U_RTTY ) mf = -mf; + mf = cf - mf; + sprintf(m_HintText, sys.m_MsgEng ? "RX Carrier FREQ=%uHz, Mark=%uHz":"受信キャリア周波数=%uHz, マーク周波数=%uHz", cf, mf); + return m_HintText; + } + else { + return sys.m_MsgEng ? "RX Carrier FREQ" : "受信キャリア周波数"; + } + } + else if( !strcmp(pHint, "%TXW") ){ + if( m_fpText ){ + return sys.m_MsgEng ? "Sending text file...":"テキストファイルを送信中..."; + } + else if( m_ReqMacroTimer || m_pMacroTimer ){ + sprintf(m_HintText, sys.m_MsgEng ? "Repeating...(Interval=%ums)":"繰り返し中...(時間間隔=%dms)", m_ReqMacroTimer); + return m_HintText; + } + else { + return sys.m_MsgEng ? "TX window" :"送信画面"; + } + } + else if( !strcmp(pHint, "%ATC") ){ + m_fHintUpdate = TRUE; + if( !SBATC->Enabled || (m_TX == txINTERNAL) ){ + return sys.m_MsgEng ? "Sync timing":"同期タイミング"; + } + else { + double ppm = m_RxSet[0].m_pDem->m_Decode.m_dTmg2; + double fq = SAMPFREQ * ppm * 1e-6; + sprintf(m_HintText, sys.m_MsgEng ? "Sync timing [%.0fppm, RxOffset=%.2lfHz]":"同期タイミング [%.0fppm, RxOffset=%.2lfHz]", ppm, fq); + return m_HintText; + } + } + else if( !strncmp(pHint, "%PB", 3) ){ + int i; + sscanf(pHint+3, "%d", &i); + switch(i){ + case 0: + i = m_PlayBackTime[0]; + break; + case 1: + i = m_PlayBackTime[1]; + break; + default: + i = m_PlayBackTime[2]; + break; + } + sprintf(m_HintText, sys.m_MsgEng ? "Replay the latest %u(sec)":"%u秒前からプレーバック", i); + return m_HintText; + } + else if( !strncmp(pHint, "%M", 2) ){ + int i; + sscanf(pHint+2, "%d", &i); + int f = i - UdMac->Position * (MACBUTTONXW*m_MacButtonVW); + m_HintText[0] = 0; + if( i < MACBUTTONMAX ){ + if( (f >= 0) && (f <= 11) ){ + sprintf(m_HintText, "F%u", f + 1); + } + else if( (f >= 12) && (f <= 23) ){ + sprintf(m_HintText, "Shift+F%u", f + 1 - 12); + } + else if( (f >= 24) && (f <= 35) ){ + sprintf(m_HintText, "Alt+F%u", f + 1 - 24); + } + else if( (f >= 36) && (f <= 47) ){ + sprintf(m_HintText, "Ctrl+F%u", f + 1 - 36); + } + WORD dkey = GetKeyCode(m_HintText); + if( (dkey == sys.m_DefKey[kkTX]) || (dkey == sys.m_DefKey[kkTXOFF]) ){ + m_HintText[0] = 0; + } + } + MACBUTTON *pList = &m_tMacButton[i]; + if( pList->Text.IsEmpty() ){ + strcat(m_HintText, sys.m_MsgEng ? " -Right click for registration":" -右クリックで登録"); + } + else { + LPSTR t = &m_HintText[strlen(m_HintText)]; + *t++ = ' '; + *t++ = '['; + LPCSTR p = pList->Text.c_str(); + int n = 128; + for( ; *p && n; n--, p++ ){ + if( *p == '\t' ){ + *t++ = ' '; + } + else if( (BYTE(*p) >= 0x20) ){ + *t++ = *p; + } + } + *t++ = ']'; + *t = 0; + } + return m_HintText; + } + else { + return pHint; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnFontChange(BOOL fTX) +{ + if( fTX ){ + m_Edit[m_CurrentEdit].SetFont(PCTX->Font); + } + else { + m_Dump.SetFont(PCRX->Font); + UpdateCharset(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DisplayHint(TObject *Sender) +{ + m_HintKey = GetLongHint(Application->Hint); + m_fHintUpdate = FALSE; + DrawHint(); +} +//--------------------------------------------------------------------------- +// サウンドカードのオープンのトライ(オープンできない時のリカバリ処理) +void __fastcall TMainVARI::SoundTimer(TObject *Sender) +{ + if( m_fSuspend ) return; + + BOOL r; + if( m_RecoverSoundMode ){ + r = ReOutOpen(); + } + else { + r = OpenSound(FALSE); + } + if( r ){ + m_pSoundTimer->Enabled = FALSE; + delete m_pSoundTimer; + m_pSoundTimer = NULL; + } + else { + m_SoundMsgTimer -= m_pSoundTimer->Interval; + if( m_SoundMsgTimer < 0 ){ + m_fShowMsg = TRUE; + } + PBoxFFTPaint(NULL); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::LogLinkTimer(TObject *Sender) +{ + if( LogLink.IsEnabled() ){ + if( LogLink.TimerLogLink() ){ + UpdateLogLink(); + } + if( LogLink.IsPolling() && LogLink.IsLink() && !m_TX ){ + LogLink.EventGetFreq(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::RadioTimer(TObject *Sender) +{ + if( m_pRadio != NULL ){ + m_pRadio->Timer(m_TX, m_pRadioTimer->Interval); + if( m_pRadio->IsFreqChange(AnsiString(LogFreq->Text).c_str()) ){ //JA7UDE 0428 + LogFreq->Text = m_pRadio->GetFreq(); + LogFreqChange(NULL); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::MacroTimer(TObject *Sender) +{ + if( m_pMacroTimer ){ + m_pMacroTimer->Enabled = FALSE; + if( m_CurrentMacro >= 0 ){ + m_fMacroRepeat = TRUE; + SendButton(m_CurrentMacro); + } + else if( (m_CurrentMacro == -1) && IsXMenu(m_pCurrentMacroMenu) ){ + m_fMacroRepeat = TRUE; + OnXClick(m_pCurrentMacroMenu); + } + else { + delete m_pMacroTimer; + m_pMacroTimer = NULL; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::WheelTimer(TObject *Sender) +{ + if( m_pWheelTimer ){ + if( !m_pDump || !m_pDump->OnTimer() ){ + m_pWheelTimer->Enabled; + delete m_pWheelTimer; + m_pWheelTimer = NULL; + m_pDump = NULL; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnActiveApp(TMessage &Message) +{ + if( LogLink.IsEnabled() ){ + if( LogLink.TimerLogLink() ){ + UpdateLogLink(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnActiveFormChange(TObject *Sender) +{ + if( m_pHelp ){ + if( !::IsWindowEnabled(m_pHelp->Handle) ) ::EnableWindow(m_pHelp->Handle, TRUE); + } + if( m_pEdit ){ + if( !::IsWindowEnabled(m_pEdit->Handle) ) ::EnableWindow(m_pEdit->Handle, TRUE); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormCreate(TObject *Sender) +{ + Application->OnMessage = OnAppMessage; + Application->OnHint = DisplayHint; + Screen->OnActiveFormChange = OnActiveFormChange; +#if !DEBUG || SHOWERRCOUNT + Application->OnException = AppException; +#endif +} +//--------------------------------------------------------------------------- +// アプリケーション例外 +void __fastcall TMainVARI::AppException(TObject *Sender, Exception *E) +{ + m_AppErr++; +#if SHOWERRCOUNT + sprintf(m_TextBuff, "%u (%u): %s", m_AppErr, sys.m_ErrPhase, E->Message.c_str()); + Caption = m_TextBuff; +#endif + if( m_AppErr < 128 ){ + if( m_AppErr == 3 ){ + ErrorMB(sys.m_MsgEng? + "The indistinct error was detected.": + "予想外のエラーが発生しました. 回復を試みます." + ); + } + if( m_FFT.m_FFTDIS ){ + m_FFT.InitFFT(); + m_FFT.m_FFTDIS = FALSE; + } +#if 0 + if( !m_TX ){ + m_Wave.InClose(); + OpenSound(FALSE); + } +#endif + } +} +//--------------------------------------------------------------------------- +__fastcall TMainVARI::TMainVARI(TComponent* Owner) + : TForm(Owner) +{ + m_fInitFirst = TRUE; + m_fDisEvent = TRUE; + + sys.m_dwVersion = ::GetVersion(); + if( sys.m_dwVersion < 0x80000000 ){ + sys.m_WinNT = TRUE; // NT,2000,XP,Vista + + OSVERSIONINFO osvi; + + ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + + GetVersionEx(&osvi); + if (osvi.dwMajorVersion == 5) { + sys.m_WinVista=FALSE; + } + else { + sys.m_WinVista=TRUE; + } + } + else { // win95/98/ME + sys.m_WinNT = FALSE; + sys.m_WinVista=FALSE; + } + + // 言語 + sys.m_LCID = GetThreadLocale(); +#if FORCELANG + sys.m_wLang = FORCELANG; +#else + sys.m_wLang = LANGIDFROMLCID(sys.m_LCID); +#endif + if( sys.m_wLang == 0x0411 ){ // 日本語 + sys.m_FontName = "MS Pゴシック"; + sys.m_FontCharset = SHIFTJIS_CHARSET; + sys.m_LogLink = 1; + sys.m_MsgEng = FALSE; + } + else { + sys.m_FontName = "Arial"; + sys.m_FontCharset = ANSI_CHARSET; + Log.m_LogSet.m_TimeZone = 'Z'; + sys.m_LogLink = 0; + sys.m_MsgEng = TRUE; + } + sys.m_fShowLangMsg = TRUE; + sys.m_fBaseMBCS = SetLangFont(NULL, sys.m_wLang); + sys.m_DefaultMode = sys.m_fBaseMBCS ? MODE_GMSK : MODE_N_BPSK; + + sys.m_fRestoreSubChannel = FALSE; + sys.m_fFixWindow = FALSE; + sys.m_rcWindow.left = Left; + sys.m_rcWindow.top = Top; + sys.m_rcWindow.right = Width; + sys.m_rcWindow.bottom = Height; + + sys.m_AutoTimeOffset = 0; + sys.m_TimeOffset; + sys.m_TimeOffsetMin; + sys.m_LogName = "NOCALL.MDT"; + InitRADIOPara(); + InitDefKey(); + + if( ParamCount() >= 0 ){ + SetDirName(sys.m_BgnDir, AnsiString(ParamStr(0)).c_str()); //JA7UDE 0428 + } + else { + SetCurDir(sys.m_BgnDir, sizeof(sys.m_BgnDir)); + } + strcpy(sys.m_SoundDir, sys.m_BgnDir); + strcpy(sys.m_LogDir, sys.m_BgnDir); + strcpy(sys.m_ExtLogDir, sys.m_BgnDir); + strcpy(sys.m_TextDir, sys.m_BgnDir); + sprintf(sys.m_MacroDir, "%sMacroTxt\\", sys.m_BgnDir); + + g_VariCode.Init(); // バリコードテーブルを初期化 + + LogLink.SetHandle(Handle, CM_CMML); + sys.m_CallSign = "NOCALL"; + sys.m_bFSKOUT = FALSE; + sys.m_bINVFSK = FALSE; + sys.m_PTTCOM = "NONE"; + sys.m_PTTLock = TRUE; + sys.m_fSendSingleTone = TRUE; + sys.m_fPlayBack = FALSE; + sys.m_PlayBackSpeed = 5; + sys.m_fShowCtrlCode = FALSE; + sys.m_MFSK_Center = FALSE; + sys.m_MFSK_SQ_Metric = FALSE; + sys.m_MacroError = FALSE; + sys.m_MaxCarrier = 2700; + sys.m_DecCutOff = 2700; + memset(&sys.m_PosMacEdit, 0, sizeof(sys.m_PosMacEdit)); + sys.m_MacBuffSize = 4096; + sys.m_OnTimerInterval = 1000; + + m_QSOStart = 0; + m_WaterNoiseL = 35; + m_WaterNoiseH = 65; + m_TX = txRX; + m_AppErr = 0; + m_pCom = NULL; + m_pRadio = NULL; + m_pHelp = NULL; + m_pEdit = NULL; + m_fReqRX = FALSE; + m_pPlayBox = NULL; + m_pSoundTimer = NULL; + m_pLogLinkTimer = NULL; + m_pRadioTimer = NULL; + m_pMacroTimer = NULL; + m_pWheelTimer = NULL; + m_pMacroOnTimer = NULL; + m_pDump = NULL; + m_pClockView = NULL; + sys.m_LoopBack = loopINTERNAL; + m_fpText = NULL; + m_fpTest = NULL; + m_BufferSize = 2048; + m_fHPF = FALSE; + m_NotchFreq = 1750; +// m_NotchTaps = 128; +// m_NotchWidth = 1; +// m_Notches.m_nBaseTaps = 128; +// m_Notches.m_NotchWidth = 1; + + m_MouseNotch = 0; + m_MouseSubChannel = FALSE; + m_fSubWindow = FALSE; + m_MouseDown = FALSE; + m_CurrentMacro = 0; + m_pCurrentMacroMenu = NULL; + m_ReqMacroTimer = 0; + m_fHintUpdate = FALSE; + m_LostSoundRX = 0; + m_LostSoundTX = 0; + m_fShowMsg = FALSE; + m_InfoMsgFlag = 0; + m_cErrorMsg = FALSE; + m_fKeyShift = FALSE; + m_ReqAutoClear = FALSE; + m_fSuspend = FALSE; + m_fTone = FALSE; + m_ReqAutoReturn = FALSE; + m_ReqAutoNET = FALSE; + m_pMacroPopup = NULL; + m_MacroMenuNo = 0; + m_fMacroRepeat = FALSE; + + m_ModGain = MODGAIN; + m_FFTVType = 2; + m_ScaleAsRigFreq = 0; + m_ScaleDetails = TRUE; + m_CurrentEdit = 0; + m_SendingEdit = 0; + + m_WaveType = 0; + m_fRttyWordOut = TRUE; + m_ListBAUD = "15.625,20.0,31.25,62.5,93.75,125.0,250.0"; + + m_AFCWidth = 50; + m_AFCLevel = 12; // SN=12dB + m_ATCLevel = 15; // SN=15dB + m_ATCSpeed = 0; + m_ATCLimit = 25000; + m_AFCKeyTimer = 0; + + m_FFTSmooth = 2; + m_FFTW = 1000; + m_fMBCS = TRUE; + m_fConvAlpha = TRUE; + + m_PlayBackTime[0]=60; + m_PlayBackTime[1]=30; + m_PlayBackTime[2]=15; + + m_CPUBENCHType = -1; + m_ParentMenu = NULL; + + m_strLogMode = ""; + + m_StatusUTC = FALSE; + m_Priority = 1; + m_RxSet[0].m_CarrierFreq = 1750; + m_RxSet[0].Create(FALSE); + + m_RxSet[1].m_CarrierFreq = 1600; + m_RxSet[2].m_CarrierFreq = 1900; + m_RxSet[3].m_CarrierFreq = 1450; + m_RxSet[4].m_CarrierFreq = 2050; + m_RxSet[5].m_CarrierFreq = 2210; + m_RxSet[6].m_CarrierFreq = 2210; + m_RxSet[7].m_CarrierFreq = 2210; + m_RxSet[8].m_CarrierFreq = 2210; + for( int i = 1; i < RXMAX; i++ ){ + m_RxSet[i].m_rcView.left = 10 + (i * 16); + m_RxSet[i].m_rcView.top = 10 + (i * 16); + m_RxSet[i].m_rcView.right = 500; + m_RxSet[i].m_rcView.bottom = 124; + } +#if DEBUG + sys.m_test = FALSE; + sys.m_testSN = 13; + sys.m_testName = "eproject.txt"; + sys.m_testGain = 0; + sys.m_testCarrier1 = 1750; + sys.m_testCarrier2 = 0; + sys.m_testDB2 = 0; + sys.m_testQSBTime = 8000; + sys.m_testQSBDB = 0; + sys.m_test500 = FALSE; + sys.m_testPhase = FALSE; + sys.m_testClockErr = 0; + m_pDebugButton = NULL; +#endif + + sys.m_fAutoTS = FALSE; + sys.m_EnableMouseWheel = TRUE; + + sys.m_SoundIDRX = -1; + sys.m_SoundIDTX = -1; + + sys.m_OptionPage = 1; + sys.m_EventIndex = 0; + sys.m_fFontFam = FALSE; + memset(sys.m_tFontFam, 0, sizeof(sys.m_tFontFam)); + memset(m_fftbuf, 0, sizeof(m_fftbuf)); + + SetLangFont(PCRX->Font, sys.m_wLang); + PCTX->Font->Assign(PCRX->Font); + + m_tWaterLevel[0] = 28; + m_tWaterLevel[1] = 100; + m_tWaterLevel[2] = 168; + m_tWaterLevel[3] = 192; + m_tWaterLevel[4] = 220; + m_tWaterLevel[5] = 240; + + m_tWaterColset[0].c = clBlack; // back + m_tWaterColset[1].d = RGB(0,255,255); // low + m_tWaterColset[2].c = clWhite; // char + m_tWaterColset[3].c = clRed; // WAKU + m_tWaterColset[4].d = RGB(0,255,255); // RX + m_tWaterColset[5].c = clBlue; // TX + m_tWaterColset[6].c = clYellow; // mid-low + m_tWaterColset[7].d = RGB(255,128,0); // mid + m_tWaterColset[8].d = RGB(255,0,128); // mid-high + m_tWaterColset[9].c = clRed; // Peak + m_tWaterColset[10].c = clRed; // Peak + m_tWaterColset[11].c = clRed; // Peak + + m_tFFTColset[0].c = clBlack; // back + m_tFFTColset[1].d = RGB(0,255,0); // high + m_tFFTColset[2].c = clWhite; // char + m_tFFTColset[3].c = clGray; // Gage + m_tFFTColset[4].d = RGB(0,255,255); // RX + m_tFFTColset[5].c = clBlue; // TX + + m_MacButtonVW = 3; + int i; + char bf[256]; + MACBUTTON *pList = m_tMacButton; + for( i = 0; i < MACBUTTONALL; i++, pList++ ){ + pList->pButton = NULL; + sprintf(bf, "M%u", i + 1); + pList->Name = bf; + pList->Color = clBlack; + pList->Text = ""; + pList->Style = 0; + } + pList = m_tMacButton; + pList->Name = "Clear"; + pList->Text = "<%ClearTXW>"; + pList++; + pList->Name = "CQ"; +// pList->Text = "<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>"; + pList->Text = "<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse "; + if( sys.m_fBaseMBCS ) pList->Text += "(<%VARITYPE>) "; + pList->Text += "K\r\n<%RX>"; + pList++; + pList->Name = "CQ2"; + pList->Text = "<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse "; + if( sys.m_fBaseMBCS ) pList->Text += "(<%VARITYPE>) "; + pList->Text += "K\r\n<%RX>"; + pList++; + pList->Name = "1x1"; + pList->Text = "<%NETON><%TX><%HisCall> de <%MyCall> pse K\r\n<%RX>"; + pList++; + pList->Name = "2x2"; + pList->Text = "<%NETON><%TX><%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse K\r\n<%RX>"; + pList++; + pList->Name = "RRR"; + pList->Text = "\r\nRRR <%HisCall> de <%MyCall>\r\n"; + if( sys.m_fBaseMBCS ) pList->Text += "--- <%VARITYPE> ---\r\n"; + pList++; + pList->Name = "BTU"; + pList->Text = "BTU <%HisCall> de <%MyCall> KN\r\n<%RX>"; + pList = &m_tMacButton[12]; + pList->Name = "CWID"; + pList->Text = "<%TX><%CWID=DE <%MyCall>><%RX><%EOF>"; + pList->Style = FSUNDERLINE; + pList++; + pList->Name = "TU SK"; + pList->Text = "<%TX><%CWID=TU:><%RX><%EOF>"; + pList->Style = FSUNDERLINE; + pList++; + pList++; + pList->Name = "0x2 - 2x4"; + pList->Text = "<%DisableCR>\r\n#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4>\r\n#if ValMenu\r\n#define\t_His\t<%Format=%c,<%Input$>>\r\n#define\t_My\t<%Format=%d,<%Find$=x,<%Input$>>>\r\n<%TX><%RX>\r\n#if !Is1stCR\r\n<%CR>\r\n#endif\r\n#if IsCall\r\n<%RepeatText=_His,<%HisCall> >\r\n#endif\r\nde\r\n<%RepeatText=_My, <%MyCall>>\r\n pse K<%CR>\r\n#endif\r\n<%EOF>"; + + sys.m_AS = "<%DisableCR>\r\n#if !IsTX\r\n<%AutoNET><%AutoReturn>\r\n#if ValPage!=4\r\n<%Page=4>\r\n#else\r\n<%Page=3>\r\n#endif\r\n<%ClearTXW>\r\n#endif\r\n<%TX><%CWID=@><%RX><%EOF>\r\n"; + + CBMode->Clear(); + CBMode->DropDownCount = MODE_END; + for( i = 0; i < MODE_END; i++ ){ + CBMode->Items->Add(g_tDispModeTable[i]); + } +// InitStgFFT(&m_StgFFT); +// m_StgFFT.Timer = 0; + + m_fftMX = 0; + m_fftSC = 109; + + m_nRadioMenu = 4; + m_RadioMenu[0].strTTL = "7.030 LSB (FT847)"; + m_RadioMenu[0].strCMD = "\\$0070300001\\w10\\$0000000007\\w10"; + m_RadioMenu[1].strTTL = "14.073 LSB (FT847)"; + m_RadioMenu[1].strCMD = "\\$0140730001\\w10\\$0000000007\\w10"; + m_RadioMenu[2].strTTL = "21.073 LSB (FT847)"; + m_RadioMenu[2].strCMD = "\\$0210730001\\w10\\$0000000007\\w10"; + m_RadioMenu[3].strTTL = "28.073 LSB (FT847)"; + m_RadioMenu[3].strCMD = "\\$0280730001\\w10\\$0000000007\\w10"; + + ReadRegister(); + m_Wave.SetSoundID(); + SampleFreq(SAMPFREQ); + UpdateModGain(); + m_FFT.InitFFT(); + InitWater(iniwBOTH); + + SetSystemFont(); + UpdateLogHeight(); + InitWFX(); + m_Dec2.SetSampleFreq(m_fDec, SAMPFREQ); + m_ModFSK.m_Encode.m_pFunc = OnGetChar; + m_ModFSK.SetMFSKType(m_RxSet[0].m_MFSK_TYPE); + m_ModFSK.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_RxSet[0].SetSampleFreq(DEMSAMPFREQ); + InitCollect(m_RxSet, IsRTTY() ? 7 : 14); + m_HPF.Create(ffHPF, 300, SAMPFREQ, 2, 1, 0.3); + m_ModFSK.SetSpeed(m_RxSet[0].m_Speed); + m_ModFSK.SetType(m_RxSet[0].m_Mode); + m_RxSet[0].m_pDem->m_fRTTYFFT = m_RxSet[0].m_RTTYFFT; + m_RxSet[0].SetMFSKType(m_RxSet[0].m_MFSK_TYPE); + m_RxSet[0].SetMode(m_RxSet[0].m_Mode); + m_RxSet[0].m_pDem->SetSpeed(m_RxSet[0].m_Speed); + m_RxSet[0].SetCarrierFreq(UdRxCarrier->Position); + m_ModFSK.SetCarrierFreq(UdTxCarrier->Position); + m_Notches.Create(); + SetATCSpeed(m_ATCSpeed); + SetATCLimit(m_ATCLimit); + if( sys.m_fPlayBack ) m_PlayBack.Init(m_BufferSize, SAMPBASE); + +#if DEBUG + m_ModTest.SetMFSKType(m_RxSet[0].m_MFSK_TYPE); + m_ModTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_ModTest.SetSpeed(m_RxSet[0].m_Speed); + m_ModTest.SetType(m_RxSet[0].m_Mode); + if( sys.m_testCarrier1 ) m_ModTest.SetCarrierFreq(sys.m_testCarrier1); + if( sys.m_testCarrier1 ) m_BPF500.Create(96, ffBPF, SAMPFREQ+SAMPTXOFFSET, sys.m_testCarrier1-250, sys.m_testCarrier1+250, 60.0, 1.0); + + m_VCOTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + if( sys.m_testCarrier2 ) m_VCOTest.SetFreeFreq(sys.m_testCarrier2); +#endif + + if( m_FFTW < 750 ){ + m_FFTW = 500; + SBFFT500->Down = TRUE; + } + else if( m_FFTW < 1500 ){ + SBFFT1K->Down = TRUE; + } + else if( m_FFTW < 2500 ){ + SBFFT2K->Down = TRUE; + } + else { + m_FFTW = 3000; + SBFFT3K->Down = TRUE; + } + m_FFTWindow = m_FFTW * FFT_SIZE / m_FFTSampFreq; + CalcFFTCenter(UdRxCarrier->Position); + for( i = 0; i < RXMAX; i++ ){ + m_RxSet[i].m_AFCTimerW = 3 * SAMPFREQ / m_BufferSize; + m_RxSet[i].m_AFCTimerN = 3 * SAMPFREQ / m_BufferSize; + } + m_pBitmapFFT = new Graphics::TBitmap; + m_pBitmapFFT->Width = PBoxFFT->Width; + m_pBitmapFFT->Height = PBoxFFT->Height; + m_fftYW = m_pBitmapFFT->Height; + m_fftXW = m_pBitmapFFT->Width; + + m_pBitmapLevel = new Graphics::TBitmap; + m_pBitmapLevel->Width = PBoxLevel->Width; + m_pBitmapLevel->Height = PBoxLevel->Height; + m_levelYW = m_pBitmapLevel->Height; + m_levelXW = m_pBitmapLevel->Width; + + m_pBitmapPF = new Graphics::TBitmap; + m_pBitmapPF->Width = PBoxPF->Width; + m_pBitmapPF->Height = PBoxPF->Height; + m_pfXW = m_pBitmapPF->Width; + m_pfYW = m_pBitmapPF->Height; + m_pfXC = m_pfXW / 2; + m_PFTimer = 0; + + CreateWaterColors(); + Draw(FALSE); + DrawLevel(FALSE); + DrawPF(FALSE); + + UpdateCharset(); + m_Dump.Create(PCRX->Handle, PCRX, PBoxRX, PCRX->Font, SBarRX, 1024); +#if DEBUG + m_Edit[0].Create(PCTX->Handle, PCTX, PBoxTX, PCTX->Font, SBarTX, 256); +#else + m_Edit[0].Create(PCTX->Handle, PCTX, PBoxTX, PCTX->Font, SBarTX, 512); +#endif + m_Edit[0].SetCursorType(csCARET); + m_Edit[0].SetMBCS(&m_RxSet[0].m_MBCS); + m_Edit[0].m_fConvAlpha = m_fConvAlpha; + m_Dump.SetCursorType(csSTATIC); + m_Dump.SetRTTY(IsRTTY()); + m_Dump.ShowCtrl(sys.m_fShowCtrlCode); + + SetTXCaption(); + UpdateTitle(); + if( m_MacButtonVW != 3 ){ + UpdateMacButtonVW(m_MacButtonVW); + } + else { + SetMacButtonMax(); + CreateMacButton(); + } + if( m_Priority ) UpdatePriority(-m_Priority); + OpenCom(); + OpenRadio(); + UpdateSpeedList(m_RxSet[0].m_Mode); + UpdateUI(); + UpdateWaveCaption(); + SampleStatus(); + PageStatus(); + UpdateMode(m_RxSet, 0); + if( sys.m_fFixWindow ){ + SetBounds(sys.m_rcWindow.left, sys.m_rcWindow.top, sys.m_rcWindow.right, sys.m_rcWindow.bottom); + if( sys.m_WindowState == wsMaximized ) WindowState = wsMaximized; + } + if( KVMX->Checked ) CreateMacExButton(); + m_fDisEvent = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetSystemFont(void) +{ + Font->Name = sys.m_FontName; + Font->Charset = sys.m_FontCharset; + sys.m_MsgEng = (sys.m_FontCharset != SHIFTJIS_CHARSET); + + KECall->Caption = "<%HisCall> \t(&H)"; + KEName->Caption = "<%HisName>\t(&N)"; + KEDear->Caption = "<%DearName>\t(&D)"; + KERST->Caption = "<%HisRST> \t(&R)"; + KEMyCall->Caption = "<%MyCall> \t(&M)"; + KESeq->Caption = "<%HisCall> de <%MyCall> \t(&S)"; + KEFinal->Caption = "<%CR>CUL, TU SK...<%CR><%RX>\t(&F)"; + if( sys.m_MsgEng ){ + KF->Caption = "&File"; + KE->Caption = "&Edit"; + KV->Caption = "&View"; + KO->Caption = "&Options"; + KH->Caption = "&Help"; + + KFL->Caption = "Save RX log file (Filename = &Date)"; + KFLR->Caption = "Show &RX log file..."; + KFS->Caption = "Send &Text file..."; + KFLO->Caption = "&Open QSO Log file..."; + KFLF->Caption = "Save QSO data no&w"; + KFMS->Caption = "&Save all Macros"; + KFML->Caption = "&Load all Macros"; + KFWST->Caption = "Sound recording (&Filename = Time stamp)"; + KFWS->Caption = "So&und recording..."; + KFRS->Caption = "Sound &Playing..."; + KFES->Caption = "&Close recording or playing"; + KFX->Caption = "E&xit MMVARI"; + + KEX->Caption = "Cu&t and copy to the clipboard"; + KECP->Caption = "&Copy to the clipboard"; + KEP->Caption = "&Paste from the clipboard"; + KEC->Caption = "Character code &List..."; + + KVF->Caption = "&FFT scale"; + KVF3->Caption = "&Square amplitude"; + KVFS->Caption = "FFT S&moothing"; + KVSF->Caption = "Frequency &Scale"; + KVSFT->Caption = "&Tone(AF) frequencies"; + KVSFR->Caption = "&Rig(RF) frequencies"; + KVSD->Caption = "&Detailed scale"; + KVWA->Caption = "Waterfall &AGC"; + KVSP->Caption = "Show sound &Playing panel"; + KVS->Caption = "Sub &Channels"; + KVCR->Caption = "Clear &RX window"; + KVCT->Caption = "Clear &TX window"; + KVM->Caption = "Row of Macro &Buttons"; + KVMX->Caption = "S&how expansion macro buttons"; + KVLA->Caption = "Log panel size &Extension"; + KVL->Caption = "Show &Log list..."; + + KOVO->Caption = "Soundcard output le&vel..."; + KOVI->Caption = "Soundcard &Input level..."; + KOAI->Caption = "Add CR/LF at the &Beginning"; + KOAO->Caption = "Add CR/LF at the &Ending"; + KORS->Caption = "&Way to send for RTTY"; + KORSC->Caption = "&Character out"; + KORSW->Caption = "&Word out"; + KOV->Caption = "Show V&ARICODE mapping..."; + KOA->Caption = "&Calibrating the SoundCard..."; + KOR->Caption = "Setup &Radio command..."; + KOL->Caption = "Setup &Logging..."; + KOO->Caption = "Setup &MMVARI..."; + + KR->Caption = "&RadioCommand"; + KRM->Caption = "Edit menu"; + KRL->Caption = "&Load..."; + KRO->Caption = "&Setup..."; + KRADD->Caption = "&Add menu..."; + + KHA->Caption = "About &Project..."; + KHO->Caption = "MMVARI &Operations..."; + KHS->Caption = "Macro &Samples..."; + KHH->Caption = "&History..."; + KHN->Caption = "JE3HHT WebSite(Japanese)..."; + KHJ->Caption = "&JARTS Web site..."; + KHM->Caption = "MM Hamsoft Web Site..."; + KHM->Hint = "http://mmhamsoft.amateur-radio.ca/"; + KHV->Caption = "&About MMVARI..."; + + KRXNAME->Caption = "Put into the Name"; + KRXQTH->Caption = "Put into the QTH"; + KRXNOTE->Caption = "Put into the Note"; + KRXCALL->Caption = "Put into the Callsign"; + KRXMY->Caption = "Put into the MyRST"; + KRXADDMY->Caption = "Add into the MyRST"; + KRXADDNAME->Caption = "Add into the Name"; + KRXADDNOTE->Caption = "Add into the Note"; + KRXADDQSL->Caption = "Add into the QSL"; + KRXCopy->Caption = "Copy to the clipboard"; + KRXINV->Caption = "Swap LTR/FIG (for RTTY)"; + + KSAS->Caption = "Send &AS in CW on here"; + KSTX->Caption = "Set TX Carrier FREQ on here"; + KSRX->Caption = "Set RX Carrier FREQ on here"; + KSN->Caption = "Set Notch on here"; + KSNR->Caption = "Delete this notch"; + KSNRA->Caption = "Delete all notches"; + KSS->Caption = "Open sub channel on here"; + KSCan->Caption = "Cancel"; + + KRWC->Caption = "&Clear window"; + KRWE->Caption = "Open &Editer..."; + KRWT->Caption = "Move to the &Top"; + KRWB->Caption = "Move to the &Bottom"; + KRSC->Caption = "Show CTRL code"; + + Splitter->Hint = "Drag & Drop for to change size of TX window"; + CBMode->Hint = "Choose mode"; + PLog->Hint = "Log panel (Right click for size extension/reduction)"; + SBFFT->Hint = "Spectrum scope"; + SBWater->Hint = "Waterfall scope"; + SBWave->Hint = "Timing/Amplitude scope (Right click for switch)"; + PF->Hint = "AFC level"; + SBFFT500->Hint = "500Hz width"; + SBFFT1K->Hint = "1KHz width"; + SBFFT2K->Hint = "2KHz width"; + SBFFT3K->Hint = "3KHz width"; + SBBPFW->Hint = "Broad (Right click for the characteristic display)"; + SBBPFM->Hint = "Narrow (Right click for the characteristic display)"; + SBBPFN->Hint = "Sharp (Right click for the characteristic display)"; + SBBPFS->Hint = "Very sharp (Right click for the characteristic display)"; + SBAFC->Hint = "Auto frequency control"; + SBNET->Hint = "TX Carrier FREQ = RX Carrier FREQ"; + CBTxCarrier->Hint = "TX Carrier FREQ"; + SBATC->Hint = "Auto timing control (Right click for clear)"; + SBInit->Hint = "Clear current QSO data"; + SBQSO->Hint = "Start/End logging"; + SBData->Hint = "Show current data"; + SBFind->Hint = "Find callsign"; + SBList->Hint = "Show log list"; + SBM->Hint = "Recent inquiry callsign"; + HisCall->Hint = "His/her callsign"; + HisName->Hint = "His/her name"; + HisRST->Hint = "His/her RST"; + MyRST->Hint = "My RST"; + HisQTH->Hint = "His/her QTH"; + EditNote->Hint = "Note (Remarks)"; + EditQSL->Hint = "QSL information or Note"; + LogFreq->Hint = "FREQ(MHz)"; + PBoxRX->Hint = "Left (or Right) click for capturing window text"; + UdMac->Hint = "Switch button page (Right click for seeking top)"; + } + + CreateSubMenu(); + HisRST->SelLength = 0; + MyRST->SelLength = 0; + LogFreq->SelLength = 0; + + for( int i = 0; i < KE->Count; i++ ){ + TMenuItem *pMenu; + BOOL f = FALSE; + if( PupTX->Items->Count <= i ){ + pMenu = new TMenuItem(PupTX); + f = TRUE; + } + else { + pMenu = PupTX->Items->Items[i]; + } + pMenu->Caption = KE->Items[i]->Caption; + pMenu->OnClick = KE->Items[i]->OnClick; + pMenu->ShortCut = KE->Items[i]->ShortCut; + if( f ) PupTX->Items->Add(pMenu); + } +#if DEBUG + EATC->Color = clWhite; +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateCharset(void) +{ + SetMBCP(PCRX->Font->Charset); + m_RxSet[0].m_MBCS.Create(); + m_RxSet[0].m_MBCS.SetCharset(PCRX->Font->Charset); + m_RxSet[0].m_fJA = (PCRX->Font->Charset == SHIFTJIS_CHARSET); + m_ModFSK.m_Encode.m_fJA = m_RxSet[0].m_fJA; + + LPCSTR pKey; + switch(PCRX->Font->Charset){ + case SHIFTJIS_CHARSET: + pKey = "JA"; + m_fMBCS = TRUE; +// KJA->Checked = TRUE; + break; + case JOHAB_CHARSET: + case HANGEUL_CHARSET: + pKey = "HL"; + m_fMBCS = TRUE; +// KHL->Checked = TRUE; + break; + case CHINESEBIG5_CHARSET: // + pKey = "BV"; + m_fMBCS = TRUE; +// KBV->Checked = TRUE; + break; + case 134: // 簡略 + pKey = "BY"; + m_fMBCS = TRUE; +// KBY->Checked = TRUE; + break; + case ANSI_CHARSET: + pKey = "ANSI"; + m_fMBCS = FALSE; +// KANSI->Checked = TRUE; + break; + case SYMBOL_CHARSET: + pKey = "SYM"; + m_fMBCS = FALSE; +// KMISC->Checked = TRUE; + break; + default: + pKey = "Other"; + m_fMBCS = FALSE; +// KMISC->Checked = TRUE; + break; + } + DrawStatus(statusVARI, pKey); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormDestroy(TObject *Sender) +{ + if( m_fpText ) fclose(m_fpText); + if( m_fpTest ) fclose(m_fpTest); + m_fpText = m_fpTest = NULL; + + if( m_pHelp ) delete m_pHelp; + if( m_pEdit ) delete m_pEdit; + if( m_pPlayBox ) delete m_pPlayBox; + if( m_pClockView ) delete m_pClockView; + if( m_pMacroPopup ) delete m_pMacroPopup; + delete m_pBitmapFFT; + delete m_pBitmapLevel; + m_pBitmapFFT = NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormCloseQuery(TObject *Sender, bool &CanClose) +{ +#if !DEBUG || SHOWERRCOUNT + Application->OnException = NULL; +#endif + Screen->OnActiveFormChange = NULL; + DoEvent(macOnExit); + SBTXOFFClick(NULL); + sys.m_rcWindow.left = Left; + sys.m_rcWindow.top = Top; + sys.m_rcWindow.right = Width; + sys.m_rcWindow.bottom = Height; + + m_Dump.CloseLogFile(); + for( int i = 0; i < RXMAX; i++ ){ + m_RxSet[i].Delete(); + } + WriteRegister(); + + sys.m_EnableMouseWheel = FALSE; + if( m_pSoundTimer ) delete m_pSoundTimer; + if( m_pLogLinkTimer ) delete m_pLogLinkTimer; + if( m_pRadioTimer ) delete m_pRadioTimer; + if( m_pMacroTimer ) delete m_pMacroTimer; + if( m_pWheelTimer ) delete m_pWheelTimer; + if( m_pMacroOnTimer ) delete m_pMacroOnTimer; + m_Wave.OutAbort(); + m_Wave.InClose(); + if( m_pCom ) delete m_pCom; + if( m_pRadio ) delete m_pRadio; + UpdatePriority(0); + Log.Close(); + Log.DoBackup(); + CanClose = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateTitle(void) +{ + if( !Log.IsOpen() || !strcmp(sys.m_CallSign.c_str(), "NOCALL") ){ + strcpy(m_TextBuff, VERTTL); + } + else { + sprintf(m_TextBuff, "%s (%s) - "VERTTL2, sys.m_CallSign.c_str(), Log.GetName()); + } + + if( LogLink.IsLink() ){ + char bf[256]; + sprintf(bf, " [Link to %s]", LogLink.GetSessionName()); + strcat(m_TextBuff, bf); + } +#if DEBUG + strcat(m_TextBuff, " (Running on debug mode)"); + sprintf(&m_TextBuff[strlen(m_TextBuff)], " %08X:%d", m_RxSet[0].m_pDem, m_RxSet[0].m_pDem->m_DEBUG); +#endif +#if SHOWERRCOUNT + strcat(m_TextBuff, " (Enable ERRMSG)"); +#endif + Caption = m_TextBuff; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdatePriority(int Priority) +{ + if( Priority == m_Priority ) return; + + m_Priority = ABS(Priority); + if( m_TX ) ToRX(); + BOOL f = m_Wave.IsInOpen(); + if( f ) m_Wave.InClose(); + HANDLE hThread = GetCurrentThread(); + switch(m_Priority){ + case 1: + ::SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); + break; + case 2: + ::SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); + break; + default: + ::SetThreadPriority(hThread, THREAD_PRIORITY_NORMAL); + break; + } + if( f ) OpenSound(FALSE); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ReadRegister(void) +{ + char bf[256]; + sprintf(bf, "%sMmvari.ini", sys.m_BgnDir); + TMemIniFile *pIniFile = new TMemIniFile(bf); + + int i; + + // サウンドカード + AnsiString as; + sprintf(bf, "%.2lf", SAMPFREQ); + as = pIniFile->ReadString("SoundCard", "Clock", bf); + double fq; + sscanf(as.c_str(), "%lf", &fq); + LimitDbl(&fq, MIN_SAMP, MAX_SAMP); + SampleFreq(fq); + sprintf(bf, "%.2lf", SAMPTXOFFSET); + as = pIniFile->ReadString("SoundCard", "TxOffset", bf); + sscanf(as.c_str(), "%lf", &fq); + if( fabs(fq) <= 500.0 ){ + SAMPTXOFFSET = fq; + } + m_Wave.m_InFifoSize = pIniFile->ReadInteger("SoundCard", "RxFIFO", m_Wave.m_InFifoSize); + m_Wave.m_OutFifoSize = pIniFile->ReadInteger("SoundCard", "TxFIFO", m_Wave.m_OutFifoSize); + m_Wave.m_SoundStereo = pIniFile->ReadInteger("SoundCard", "Source", m_Wave.m_SoundStereo); + sys.m_SoundIDRX = pIniFile->ReadString("SoundCard", "ID", sys.m_SoundIDRX); + sys.m_SoundIDTX = pIniFile->ReadString("SoundCard", "IDTX", sys.m_SoundIDTX); +// sys.m_SoundMMW = pIniFile->ReadString("SoundCard", "MMW", sys.m_SoundMMW); + + LimitInt(&m_Wave.m_InFifoSize, 4, 32); + LimitInt(&m_Wave.m_OutFifoSize, 4, 32); + + /* SYSTEM */ + int IniSchema = pIniFile->ReadInteger("System", "Schema", 0); + m_Priority = pIniFile->ReadInteger("System", "Priority", m_Priority); + sys.m_FontName = pIniFile->ReadString("System", "FontName", sys.m_FontName); + sys.m_FontCharset = (BYTE)pIniFile->ReadInteger("System", "FontCharset", sys.m_FontCharset); + + /* Window */ + sys.m_fFixWindow = pIniFile->ReadInteger("Window", "Fixed", sys.m_fFixWindow); + sys.m_rcWindow.left = pIniFile->ReadInteger("Window", "Left", sys.m_rcWindow.left); + sys.m_rcWindow.top = pIniFile->ReadInteger("Window", "Top", sys.m_rcWindow.top); + sys.m_rcWindow.right = pIniFile->ReadInteger("Window", "Width", sys.m_rcWindow.right); + sys.m_rcWindow.bottom = pIniFile->ReadInteger("Window", "Height", sys.m_rcWindow.bottom); + sys.m_WindowState = pIniFile->ReadInteger("Window", "WindowState", wsNormal); + KVLA->Checked = pIniFile->ReadInteger("Window", "LogExtension", KVLA->Checked); + sys.m_fRestoreSubChannel = pIniFile->ReadInteger("Window", "RestoreSubChannels", sys.m_fRestoreSubChannel); + + /* Folder */ + as = pIniFile->ReadString("Folder", "Sound", sys.m_SoundDir); + strcpy(sys.m_SoundDir, as.c_str()); + as = pIniFile->ReadString("Folder", "Log", sys.m_LogDir); + strcpy(sys.m_LogDir, as.c_str()); + as = pIniFile->ReadString("Folder", "ExtLog", sys.m_ExtLogDir); + + strcpy(sys.m_ExtLogDir, as.c_str()); + as = pIniFile->ReadString("Folder", "Text", sys.m_TextDir); + strcpy(sys.m_TextDir, as.c_str()); + + /* PTT */ + sys.m_PTTCOM = pIniFile->ReadString("PTT", "Name", sys.m_PTTCOM); + sys.m_PTTLock = pIniFile->ReadInteger("PTT", "Lock", sys.m_PTTLock); + sys.m_bFSKOUT = pIniFile->ReadInteger("PTT", "OUTFSK", sys.m_bFSKOUT); + sys.m_bINVFSK = pIniFile->ReadInteger("PTT", "INVFSK", sys.m_bINVFSK); + + /* TX */ + sys.m_LoopBack = pIniFile->ReadInteger("TX", "LoopBack", sys.m_LoopBack); + int f = pIniFile->ReadInteger("TX", "AutoCR", KOAI->Checked | (KOAO->Checked << 1)); + KOAI->Checked = (f & 1); + KOAO->Checked = (f & 2); + UdTxCarrier->Position = (short)pIniFile->ReadInteger("TX", "Carrier", UdTxCarrier->Position); + SBNET->Down = pIniFile->ReadInteger("TX", "NET", SBNET->Down); + m_ModGain = pIniFile->ReadInteger("TX", "ModGain", m_ModGain); + m_fRttyWordOut = pIniFile->ReadInteger("TX", "RttyWordOut", m_fRttyWordOut); + + as = pIniFile->ReadString("TX", "Mode", g_tDispModeTable[sys.m_DefaultMode]); + m_RxSet[0].m_Mode = GetModeIndex(as.c_str()); + CBMode->ItemIndex = m_RxSet[0].m_Mode; + as = pIniFile->ReadString("TX", "Speed", "31.25"); + sscanf(as.c_str(), "%lf", &m_RxSet[0].m_Speed); + LimitDbl(&m_RxSet[0].m_Speed, MIN_SPEED, MAX_SPEED); + m_fConvAlpha = pIniFile->ReadInteger("TX", "ConvAlpha", m_fConvAlpha); + m_RxSet[0].m_MFSK_TYPE = pIniFile->ReadInteger("TX", "MFSK_TYPE", m_RxSet[0].m_MFSK_TYPE); + SetCBSpeed(); + sys.m_MFSK_Center = pIniFile->ReadInteger("TX", "MFSK_CENTER", sys.m_MFSK_Center); + sys.m_fSendSingleTone = pIniFile->ReadInteger("TX", "SendSingleTone", sys.m_fSendSingleTone); + + /* RX */ + UdRxCarrier->Position = (short)pIniFile->ReadInteger("RX", "Carrier", UdRxCarrier->Position); + SetBPFType(pIniFile->ReadInteger("RX", "BPF", GetBPFType())); + SBAFC->Down = pIniFile->ReadInteger("RX", "AFC", SBAFC->Down); + m_RxSet[0].m_pDem->m_fAFC = m_RxSet[0].m_fAFC = SBAFC->Down; + SBATC->Down = pIniFile->ReadInteger("RX", "ATC", SBATC->Down); + m_RxSet[0].m_pDem->m_Decode.m_fATC = SBATC->Down; + m_RxSet[0].m_SQLevel = pIniFile->ReadInteger("RX", "SQLevel", m_RxSet[0].m_SQLevel); + m_AFCWidth = pIniFile->ReadInteger("RX", "AFCWidth", m_AFCWidth); + m_AFCLevel = pIniFile->ReadInteger("RX", "AFCLevel", m_AFCLevel); + if( IniSchema < 3 ){ // For old version + if( m_AFCWidth > 50 ) m_AFCWidth = 50; + if( m_AFCLevel < 12 ) m_AFCLevel = 12; + } + m_fHPF = pIniFile->ReadInteger("RX", "HPF", m_fHPF); + m_ATCLevel = pIniFile->ReadInteger("RX", "ATCLevel", m_ATCLevel); + m_ATCSpeed = pIniFile->ReadInteger("RX", "ATCSpeed", m_ATCSpeed); + m_ATCLimit = pIniFile->ReadInteger("RX", "ATCLimit", m_ATCLimit); + sys.m_fAutoTS = pIniFile->ReadInteger("RX", "SWL_TS", sys.m_fAutoTS); + m_NotchFreq = pIniFile->ReadInteger("RX", "NotchFreq", m_NotchFreq); + sys.m_fPlayBack = pIniFile->ReadInteger("RX", "PlayBack", sys.m_fPlayBack); + sys.m_PlayBackSpeed = pIniFile->ReadInteger("RX", "PlayBackSpeed", sys.m_PlayBackSpeed); + sys.m_MFSK_SQ_Metric = pIniFile->ReadInteger("RX", "MFSK_SQ_METRIC", sys.m_MFSK_SQ_Metric); + m_RxSet[0].m_RTTYFFT = pIniFile->ReadInteger("RX", "RTTY_FFT", m_RxSet[0].m_RTTYFFT); + + /* View */ + m_FFTW = pIniFile->ReadInteger("FFT", "Width", m_FFTW); + m_FFTSmooth = pIniFile->ReadInteger("FFT", "Smooth", m_FFTSmooth); + m_FFTVType = pIniFile->ReadInteger("FFT", "Type", m_FFTVType); + if( m_FFTSmooth < 2 ) m_FFTSmooth = 2; + m_FFT.m_FFTGain = (m_FFTVType < 2) ? 0 : 1; + for( i = 0; i < 12; i++ ){ + sprintf(bf, "Col%u", i + 1); + if( i < 6 ){ + m_tFFTColset[i].d = pIniFile->ReadInteger("Spec", bf, m_tFFTColset[i].d); + } + m_tWaterColset[i].d = pIniFile->ReadInteger("WF", bf, m_tWaterColset[i].d); + if( i < 6 ){ + sprintf(bf, "Lvl%u", i + 1); + m_tWaterLevel[i] = pIniFile->ReadInteger("WF", bf, m_tWaterLevel[i]); + } + } + SetDrawType(pIniFile->ReadInteger("View", "DrawType", GetDrawType())); + m_WaveType = pIniFile->ReadInteger("View", "WaveForm", m_WaveType); + m_ScaleAsRigFreq = pIniFile->ReadInteger("View", "RigFreqScale", m_ScaleAsRigFreq); + m_ScaleDetails = pIniFile->ReadInteger("View", "ScaleDetails", m_ScaleDetails); + if( IniSchema >= 2 ){ + KVWA->Checked = pIniFile->ReadInteger("View", "WaterAGC", FALSE); + } + + /* RXW */ + for( i = 0; i < 5; i++ ){ + sprintf(bf, "Color%d", i + 1); + m_Dump.m_Color[i].d = pIniFile->ReadInteger("RXW", bf, m_Dump.m_Color[i].d); + } + LoadFontFromInifile(PCRX->Font, "RXW", pIniFile); + m_StatusUTC = pIniFile->ReadInteger("RXW", "StatusUTC", m_StatusUTC); + sys.m_EnableMouseWheel = pIniFile->ReadInteger("RXW", "MouseWheel", sys.m_EnableMouseWheel); + sys.m_fShowCtrlCode = pIniFile->ReadInteger("RXW", "ShowCtrl", sys.m_fShowCtrlCode); + + /* TXW */ + for( i = 0; i < 4; i++ ){ + sprintf(bf, "Color%d", i + 1); + m_Edit[0].m_Color[i].d = pIniFile->ReadInteger("TXW", bf, m_Edit[0].m_Color[i].d); + for( int j = 1; j < 4; j++ ){ + m_Edit[j].m_Color[i] = m_Edit[0].m_Color[i]; + } + } + for( i = 0; i < 4; i++ ){ + m_Edit[i].m_Color[4] = m_Edit[i].m_Color[0]; + } + LoadFontFromInifile(PCTX->Font, "TXW", pIniFile); + PCRX->Color = m_Dump.m_Color[0].c; + PCTX->Color = m_Edit[0].m_Color[0].c; + + /* Macro */ + sys.m_CallSign = pIniFile->ReadString("Macro", "CallSign", sys.m_CallSign); + m_MacButtonVW = pIniFile->ReadInteger("Macro", "ButtonRow", m_MacButtonVW); + UdMac->Position = (short)pIniFile->ReadInteger("Macro", "ButtonPos", UdMac->Position); + LoadMacro(pIniFile); + AnsiString ws; + CrLf2Yen(as, sys.m_AS); + ws = pIniFile->ReadString("Macro", "CWAS", as); + Yen2CrLf(sys.m_AS, ws); + for( i = 0; i < macOnEnd; i++ ){ + CrLf2Yen(as, sys.m_MacEvent[i]); + ws = pIniFile->ReadString("Macro", g_tMacEvent[i], as); + Yen2CrLf(sys.m_MacEvent[i], ws); + } + KVMX->Checked = pIniFile->ReadInteger("Macro", "Expand", FALSE); + + /* Log */ + Log.m_FileName = pIniFile->ReadString("Log", "Name", ""); + if( Log.m_FileName.IsEmpty() ){ + as = sys.m_CallSign; + Log.MakePathName(ClipCall(as.c_str())); + } + else { + Log.MakeName(Log.m_FileName.c_str()); + } + + /* LogSet */ + Log.ReadIniFile("LogSet", pIniFile); + sys.m_LogLink = pIniFile->ReadInteger("LogSet", "LogLink", sys.m_LogLink); + LogLink.LoadMMLink(pIniFile); + LogLink.SetPolling(pIniFile->ReadInteger("LogSet", "LinkPoll", 0)); + LogLink.SetPTTEnabled(pIniFile->ReadInteger("LogSet", "LinkPTT", FALSE)); + + LoadRADIOSetup(pIniFile); + + for( i = 0; i < kkEOF; i++ ){ + sprintf(bf, "K%u", i+1); + sys.m_DefKey[i] = (WORD)pIniFile->ReadInteger("DefKey", bf, sys.m_DefKey[i]); + } + if( !IniSchema && (sys.m_DefKey[1] == VK_ESCAPE) ) sys.m_DefKey[1] = VK_PAUSE; + + /* Sub channel */ + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++, pRxSet++ ){ + sprintf(bf, "Channel%u", i); + pRxSet->m_fShowed = pIniFile->ReadInteger(bf, "Show", FALSE); + as = pIniFile->ReadString(bf, "Mode", g_tDispModeTable[sys.m_DefaultMode]); + pRxSet->m_Mode = GetModeIndex(as.c_str()); + pRxSet->m_CarrierFreq = pIniFile->ReadInteger(bf, "Carrier", pRxSet->m_CarrierFreq); + LimitInt(&pRxSet->m_CarrierFreq, MIN_CARRIER, sys.m_MaxCarrier); + pRxSet->m_WaterW = pIniFile->ReadInteger(bf, "WaterWidth", pRxSet->m_WaterW); + LimitInt(&pRxSet->m_WaterW, 200, 800); + pRxSet->m_rcView.left = pIniFile->ReadInteger(bf, "Left", pRxSet->m_rcView.left); + pRxSet->m_rcView.top = pIniFile->ReadInteger(bf, "Top", pRxSet->m_rcView.top); + pRxSet->m_rcView.right = pIniFile->ReadInteger(bf, "Width", pRxSet->m_rcView.right); + pRxSet->m_rcView.bottom = pIniFile->ReadInteger(bf, "Height", pRxSet->m_rcView.bottom); + LoadFontFromInifile(&pRxSet->m_FontData, bf, pIniFile); + pRxSet->m_RTTYFFT = pIniFile->ReadInteger(bf, "RTTYFFT", pRxSet->m_RTTYFFT); + pRxSet->m_MFSK_TYPE = pIniFile->ReadInteger(bf, "MFSK_TYPE", pRxSet->m_MFSK_TYPE); + as = pIniFile->ReadString(bf, "Speed", "31.25"); + sscanf(as.c_str(), "%lf", &pRxSet->m_Speed); + LimitDbl(&pRxSet->m_Speed, MIN_SPEED, MAX_SPEED); + pRxSet->m_fAFC = pIniFile->ReadInteger(bf, "AFC", TRUE); + } + //RadioMenu + m_nRadioMenu = pIniFile->ReadInteger("RadioMenu", "Menus", m_nRadioMenu); + for( i = 0; i < m_nRadioMenu; i++ ){ + sprintf(bf, "Cap%d", i+1); + m_RadioMenu[i].strTTL = pIniFile->ReadString("RadioMenu", bf, m_RadioMenu[i].strTTL); + sprintf(bf, "Cmd%d", i+1); + m_RadioMenu[i].strCMD = pIniFile->ReadString("RadioMenu", bf, m_RadioMenu[i].strCMD); + } + /* Callsign */ + for( i = 0; i < STGCALLMAX; i++ ){ + sprintf(bf, "C%d", i+1); + as = pIniFile->ReadString("Calls", bf, ""); + if( as.IsEmpty() ) break; + LPSTR p; + for( p = as.c_str(); *p; p++ ){ + if( *p == '_' ) *p = '\t'; + } + TMenuItem *pm = new TMenuItem(PupCalls); + pm->Caption = as.c_str(); + pm->RadioItem = FALSE; + pm->OnClick = KCallClick; + pm->Checked = FALSE; + pm->Enabled = TRUE; + PupCalls->Items->Add(pm); + } + + m_MacroVal.ReadInifile(pIniFile, "MacroVal"); + + sys.m_fShowLangMsg = pIniFile->ReadInteger("Misc", "ShowLangMsg", sys.m_fShowLangMsg); + +#if DEBUG +//debug + sys.m_testSN = pIniFile->ReadInteger("DEBUG", "testSN", sys.m_testSN); + sys.m_testName = pIniFile->ReadString("DEBUG", "testName", sys.m_testName); + sys.m_testGain = pIniFile->ReadInteger("DEBUG", "testGain", sys.m_testGain); + sys.m_testCarrier1 = pIniFile->ReadInteger("DEBUG", "testCarrier1", sys.m_testCarrier1); + sys.m_testCarrier2 = pIniFile->ReadInteger("DEBUG", "testCarrier2", sys.m_testCarrier2); + sys.m_testDB2 = pIniFile->ReadInteger("DEBUG", "testDB2", sys.m_testDB2); + sys.m_testQSBTime = pIniFile->ReadInteger("DEBUG", "testQSBTime", sys.m_testQSBTime); + sys.m_testQSBDB = pIniFile->ReadInteger("DEBUG", "testQSBDB", sys.m_testQSBDB); + sys.m_test500 = pIniFile->ReadInteger("DEBUG", "test500", sys.m_test500); + sys.m_testPhase = pIniFile->ReadInteger("DEBUG", "testPhase", sys.m_testPhase); + sys.m_testClockErr = pIniFile->ReadInteger("DEBUG", "testClockErr", sys.m_testClockErr); +#endif + + delete pIniFile; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::WriteRegister(void) +{ + int i; + char bf[256]; + sprintf(bf, "%sMmvari.ini", sys.m_BgnDir); + TMemIniFile *pIniFile = new TMemIniFile(bf); + + // サウンドカード + sprintf(bf, "%.2lf", SAMPFREQ); + pIniFile->WriteString("SoundCard", "Clock", bf); + sprintf(bf, "%.2lf", SAMPTXOFFSET); + pIniFile->WriteString("SoundCard", "TxOffset", bf); + pIniFile->WriteInteger("SoundCard", "RxFIFO", m_Wave.m_InFifoSize); + pIniFile->WriteInteger("SoundCard", "TxFIFO", m_Wave.m_OutFifoSize); + pIniFile->WriteInteger("SoundCard", "Source", m_Wave.m_SoundStereo); + pIniFile->WriteString("SoundCard", "ID", sys.m_SoundIDRX); + pIniFile->WriteString("SoundCard", "IDTX", sys.m_SoundIDTX); +// pIniFile->WriteString("SoundCard", "MMW", sys.m_SoundMMW); + + /* SYSTEM */ + pIniFile->WriteInteger("System", "Schema", INI_SCHEMA); + pIniFile->WriteInteger("System", "Priority", m_Priority); + pIniFile->WriteString("System", "FontName", sys.m_FontName); + pIniFile->WriteInteger("System", "FontCharset", sys.m_FontCharset); + + /* Window */ + if( WindowState == wsNormal ){ + pIniFile->WriteInteger("Window", "Fixed", sys.m_fFixWindow); + pIniFile->WriteInteger("Window", "Left", sys.m_rcWindow.left); + pIniFile->WriteInteger("Window", "Top", sys.m_rcWindow.top); + pIniFile->WriteInteger("Window", "Width", sys.m_rcWindow.right); + pIniFile->WriteInteger("Window", "Height", sys.m_rcWindow.bottom); + } + pIniFile->WriteInteger("Window", "WindowState", WindowState); + pIniFile->WriteInteger("Window", "LogExtension", KVLA->Checked); + pIniFile->WriteInteger("Window", "RestoreSubChannels", sys.m_fRestoreSubChannel); + + /* Folder */ + pIniFile->WriteString("Folder", "Sound", sys.m_SoundDir); + pIniFile->WriteString("Folder", "Log", sys.m_LogDir); + pIniFile->WriteString("Folder", "ExtLog", sys.m_ExtLogDir); + pIniFile->WriteString("Folder", "Text", sys.m_TextDir); + + /* PTT */ + pIniFile->WriteString("PTT", "Name", sys.m_PTTCOM); + pIniFile->WriteInteger("PTT", "Lock", sys.m_PTTLock); + pIniFile->WriteInteger("PTT", "OUTFSK", sys.m_bFSKOUT); + pIniFile->WriteInteger("PTT", "INVFSK", sys.m_bINVFSK); + + /* TX */ + pIniFile->WriteInteger("TX", "LoopBack", sys.m_LoopBack); + pIniFile->WriteInteger("TX", "AutoCR", KOAI->Checked | (KOAO->Checked << 1)); + pIniFile->WriteInteger("TX", "Carrier", UdTxCarrier->Position); + pIniFile->WriteInteger("TX", "NET", SBNET->Down); + pIniFile->WriteString("TX", "Mode", g_tDispModeTable[m_RxSet[0].m_Mode]); + pIniFile->WriteString("TX", "Speed", StrDbl(bf, m_RxSet[0].m_Speed)); + pIniFile->WriteInteger("TX", "ModGain", m_ModGain); + pIniFile->WriteInteger("TX", "ConvAlpha", m_fConvAlpha); + pIniFile->WriteInteger("TX", "RttyWordOut", m_fRttyWordOut); + pIniFile->WriteInteger("TX", "MFSK_TYPE", m_RxSet[0].m_MFSK_TYPE); + pIniFile->WriteInteger("TX", "MFSK_CENTER", sys.m_MFSK_Center); + pIniFile->WriteInteger("TX", "SendSingleTone", sys.m_fSendSingleTone); + + /* View */ + pIniFile->WriteInteger("FFT", "Width", m_FFTW); + pIniFile->WriteInteger("FFT", "Smooth", m_FFTSmooth); + pIniFile->WriteInteger("FFT", "Type", m_FFTVType); + for( i = 0; i < 12; i++ ){ + sprintf(bf, "Col%u", i + 1); + if( i < 6 ){ + pIniFile->WriteInteger("Spec", bf, m_tFFTColset[i].d); + } + pIniFile->WriteInteger("WF", bf, m_tWaterColset[i].d); + if( i < 6 ){ + sprintf(bf, "Lvl%u", i + 1); + pIniFile->WriteInteger("WF", bf, m_tWaterLevel[i]); + } + } + pIniFile->WriteInteger("View", "DrawType", GetDrawType()); + pIniFile->WriteInteger("View", "WaveForm", m_WaveType); + pIniFile->WriteInteger("View", "RigFreqScale", m_ScaleAsRigFreq); + pIniFile->WriteInteger("View", "ScaleDetails", m_ScaleDetails); + pIniFile->WriteInteger("View", "WaterAGC", KVWA->Checked); + + /* RXW */ + for( i = 0; i < 5; i++ ){ + sprintf(bf, "Color%d", i + 1); + pIniFile->WriteInteger("RXW", bf, m_Dump.m_Color[i].d); + } + SaveFontToInifile(PCRX->Font, "RXW", pIniFile); + pIniFile->WriteInteger("RXW", "StatusUTC", m_StatusUTC); + pIniFile->WriteInteger("RXW", "MouseWheel", sys.m_EnableMouseWheel); + pIniFile->WriteInteger("RXW", "ShowCtrl", sys.m_fShowCtrlCode); + + /* TXW */ + for( i = 0; i < 4; i++ ){ + sprintf(bf, "Color%d", i + 1); + pIniFile->WriteInteger("TXW", bf, m_Edit[0].m_Color[i].d); + } + SaveFontToInifile(PCTX->Font, "TXW", pIniFile); + + /* RX */ + pIniFile->WriteInteger("RX", "Carrier", UdRxCarrier->Position); + pIniFile->WriteInteger("RX", "BPF", GetBPFType()); + pIniFile->WriteInteger("RX", "AFC", SBAFC->Down); + pIniFile->WriteInteger("RX", "ATC", SBATC->Down); + pIniFile->WriteInteger("RX", "SQLevel", m_RxSet[0].m_SQLevel); + pIniFile->WriteInteger("RX", "AFCWidth", m_AFCWidth); + pIniFile->WriteInteger("RX", "AFCLevel", m_AFCLevel); + pIniFile->WriteInteger("RX", "HPF", m_fHPF); + pIniFile->WriteInteger("RX", "ATCLevel", m_ATCLevel); + pIniFile->WriteInteger("RX", "ATCSpeed", m_ATCSpeed); + pIniFile->WriteInteger("RX", "ATCLimit", m_ATCLimit); + pIniFile->WriteInteger("RX", "SWL_TS", sys.m_fAutoTS); + pIniFile->WriteInteger("RX", "NotchFreq", m_NotchFreq); + pIniFile->WriteInteger("RX", "PlayBack", sys.m_fPlayBack); + pIniFile->WriteInteger("RX", "PlayBackSpeed", sys.m_PlayBackSpeed); + pIniFile->WriteInteger("RX", "MFSK_SQ_METRIC", sys.m_MFSK_SQ_Metric); + pIniFile->WriteInteger("RX", "RTTY_FFT", m_RxSet[0].m_RTTYFFT); + + /* Log */ + pIniFile->WriteString("Log", "Name", Log.m_FileName); + + /* LogSet */ + Log.WriteIniFile("LogSet", pIniFile); + pIniFile->WriteInteger("LogSet", "LogLink", sys.m_LogLink); + pIniFile->WriteInteger("LogSet", "LinkPoll", LogLink.IsPolling()); + pIniFile->WriteInteger("LogSet", "LinkPTT", LogLink.GetPTTEnabled()); + LogLink.SaveMMLink(pIniFile); + + /* Radio */ + SaveRADIOSetup(pIniFile); + + /* Macro */ + pIniFile->WriteString("Macro", "CallSign", sys.m_CallSign); + pIniFile->WriteInteger("Macro", "ButtonRow", m_MacButtonVW); + pIniFile->WriteInteger("Macro", "ButtonPos", UdMac->Position); + SaveMacro(pIniFile); + AnsiString as; + CrLf2Yen(as, sys.m_AS); + pIniFile->WriteString("Macro", "CWAS", as); + for( i = 0; i < macOnEnd; i++ ){ + CrLf2Yen(as, sys.m_MacEvent[i]); + pIniFile->WriteString("Macro", g_tMacEvent[i], as); + } + pIniFile->WriteInteger("Macro", "Expand", PBoxFFT->Align != alClient); + + /* DefKey */ + for( i = 0; i < kkEOF; i++ ){ + sprintf(bf, "K%u", i+1); + pIniFile->WriteInteger("DefKey", bf, sys.m_DefKey[i]); + } + + /* Sub channel */ + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++, pRxSet++ ){ + sprintf(bf, "Channel%u", i); + pIniFile->WriteInteger(bf, "Show", pRxSet->m_fShowed); + pIniFile->WriteString(bf, "Mode", g_tDispModeTable[pRxSet->m_Mode]); + pIniFile->WriteInteger(bf, "Carrier", pRxSet->m_CarrierFreq); + pIniFile->WriteInteger(bf, "WaterWidth", pRxSet->m_WaterW); + pIniFile->WriteInteger(bf, "Left", pRxSet->m_rcView.left); + pIniFile->WriteInteger(bf, "Top", pRxSet->m_rcView.top); + pIniFile->WriteInteger(bf, "Width", pRxSet->m_rcView.right); + pIniFile->WriteInteger(bf, "Height", pRxSet->m_rcView.bottom); + SaveFontToInifile(&m_RxSet[i].m_FontData, bf, pIniFile); + pIniFile->WriteInteger(bf, "RTTYFFT", pRxSet->m_RTTYFFT); + char bbf[64]; + pIniFile->WriteString(bf, "Speed", StrDbl(bbf, pRxSet->m_Speed)); + pIniFile->WriteInteger(bf, "MFSK_TYPE", pRxSet->m_MFSK_TYPE); + pIniFile->WriteInteger(bf, "AFC", pRxSet->m_fAFC); + } + +//RadioMenu + try{ + pIniFile->EraseSection("RadioMenu"); + } + catch(...){ + } + pIniFile->WriteInteger("RadioMenu", "Menus", m_nRadioMenu); + for( i = 0; i < m_nRadioMenu; i++ ){ + sprintf(bf, "Cap%d", i+1); + pIniFile->WriteString("RadioMenu", bf, m_RadioMenu[i].strTTL); + sprintf(bf, "Cmd%d", i+1); + pIniFile->WriteString("RadioMenu", bf, m_RadioMenu[i].strCMD); + } + + for( i = 0; i < PupCalls->Items->Count; i++ ){ + sprintf(bf, "C%d", i+1); + char bbf[64]; + StrCopy(bbf, AnsiString(PupCalls->Items->Items[i]->Caption).c_str(), 63); //JA7UDE 0428 + LPSTR p; + for( p = bbf; *p; p++ ){ + if( *p == '\t' ) *p = '_'; + } + pIniFile->WriteString("Calls", bf, bbf); + } + + m_MacroVal.WriteInifile(pIniFile, "MacroVal"); + + pIniFile->WriteInteger("Misc", "ShowLangMsg", sys.m_fShowLangMsg); + +#if DEBUG +//debug + pIniFile->WriteInteger("DEBUG", "testSN", sys.m_testSN); + pIniFile->WriteString("DEBUG", "testName", sys.m_testName); + pIniFile->WriteInteger("DEBUG", "testGain", sys.m_testGain); + pIniFile->WriteInteger("DEBUG", "testCarrier1", sys.m_testCarrier1); + pIniFile->WriteInteger("DEBUG", "testCarrier2", sys.m_testCarrier2); + pIniFile->WriteInteger("DEBUG", "testDB2", sys.m_testDB2); + pIniFile->WriteInteger("DEBUG", "testQSBTime", sys.m_testQSBTime); + pIniFile->WriteInteger("DEBUG", "testQSBDB", sys.m_testQSBDB); + pIniFile->WriteInteger("DEBUG", "test500", sys.m_test500); + pIniFile->WriteInteger("DEBUG", "testPhase", sys.m_testPhase); + pIniFile->WriteInteger("DEBUG", "testClockErr", sys.m_testClockErr); +#endif + + pIniFile->UpdateFile(); + delete pIniFile; +} +//--------------------------------------------------------------------------- +/* + Clock 復調器 FFT + 6000Hz 6000Hz 6000Hz 1024 + 8000Hz 8000Hz 8000Hz 2048 + 11025Hz 5513Hz 11025Hz 2048 + 12000Hz 6000Hz 6000Hz 1024 + 16000Hz 5333Hz 10667Hz 2048 + 18000Hz 6000Hz 6000Hz 1024 + 22050Hz 5513Hz 11025Hz 2048 + 24000Hz 6000Hz 6000Hz 1024 + 44100Hz 6300Hz 6300Hz 1024 + 48000Hz 6000Hz 6000Hz 1024 + 50000Hz 6250Hz 6250Hz 1024 +*/ +BOOL __fastcall TMainVARI::SampleFreq(double f) +{ + int fftsize = FFT_SIZE; + if( f >= 49000.0 ){ // 50000Hz + SAMPFREQ = f; + SAMPBASE = 50000; + m_fDec = 7; + m_DecFactor = 0.125; + SAMPTYPE = 10; + m_BufferSize = 8192; + FFT_SIZE = 1024; + m_FFTFactor = 0.125; + sys.m_DecCutOff = 2900; + sys.m_MaxCarrier = 3000; + } + else if( f >= 46000.0 ){ // 48000Hz + SAMPFREQ = f; + SAMPBASE = 48000; + m_fDec = 7; + m_DecFactor = 0.125; + SAMPTYPE = 9; + m_BufferSize = 8192; + FFT_SIZE = 1024; + m_FFTFactor = 0.125; + sys.m_DecCutOff = 2800; + sys.m_MaxCarrier = 2950; + } + else if( f >= 43000.0 ){ // 44100Hz + SAMPFREQ = f; + SAMPBASE = 44100; + m_fDec = 6; + m_DecFactor = 1.0/7.0; + SAMPTYPE = 8; + m_BufferSize = 8192; + FFT_SIZE = 1024; + m_FFTFactor = 1.0/7.0; + sys.m_DecCutOff = 2900; + sys.m_MaxCarrier = 3000; + } + else if( f >= 23000.0 ){ // 24000Hz + SAMPFREQ = f; + SAMPBASE = 24000; + m_fDec = 3; + m_DecFactor = 0.25; + SAMPTYPE = 7; + m_BufferSize = 4096; + FFT_SIZE = 1024; + m_FFTFactor = 0.25; + sys.m_DecCutOff = 2800; + sys.m_MaxCarrier = 2950; + } + else if( f >= 20000.0 ){ // 22050Hz + SAMPFREQ = f; + SAMPBASE = 22050; + m_fDec = 2; + m_DecFactor = 1.0/3.0; + SAMPTYPE = 6; + m_BufferSize = 6144; + FFT_SIZE = 2048; + m_FFTFactor = 1.0/3.0; + sys.m_DecCutOff = 2700; + sys.m_MaxCarrier = 2700; + } + else if( f >= 17000.0 ){ // 18000Hz + SAMPFREQ = f; + SAMPBASE = 18000; + m_fDec = 2; + m_DecFactor = 1.0/3.0; + SAMPTYPE = 5; + m_BufferSize = 3072; + FFT_SIZE = 1024; + m_FFTFactor = 1.0/3.0; + sys.m_DecCutOff = 2800; + sys.m_MaxCarrier = 2950; + } + else if( f >= 15000.0 ){ // 16000Hz + SAMPFREQ = f; + SAMPBASE = 16000; + m_fDec = 2; + m_DecFactor = 1.0/3.0; + SAMPTYPE = 4; + m_BufferSize = 6144; + FFT_SIZE = 2048; + m_FFTFactor = 1.0/3.0; + sys.m_DecCutOff = 2600; + sys.m_MaxCarrier = 2600; + } + else if( f >= 11600.0 ){ // 12000Hz系 + SAMPFREQ = f; + SAMPBASE = 12000; + m_fDec = 1; + m_DecFactor = 0.5; + SAMPTYPE = 3; + m_BufferSize = 2048; + FFT_SIZE = 1024; + m_FFTFactor = 0.5; + sys.m_DecCutOff = 2900; + sys.m_MaxCarrier = 2950; + } + else if( f > 10000.0 ){ // 11025Hz系 + SAMPFREQ = f; + SAMPBASE = 11025; + m_fDec = 1; + m_DecFactor = 0.5; + SAMPTYPE = 0; + m_BufferSize = 2048; + FFT_SIZE = 2048; + m_FFTFactor = 1.0; + sys.m_DecCutOff = 2700; + sys.m_MaxCarrier = 2700; + } + else if( f > 7000.0 ){ // 8000Hz系 + SAMPFREQ = f; + SAMPBASE = 8000; + m_fDec = 0; + m_DecFactor = 1.0; + SAMPTYPE = 1; + m_BufferSize = 2048; + FFT_SIZE = 2048; + m_FFTFactor = 1.0; + sys.m_DecCutOff = 3000; + sys.m_MaxCarrier = 3000; + } + else if( f > 5000 ){ // 6000Hz系 + SAMPFREQ = f; + SAMPBASE = 6000; + m_fDec = 0; + m_DecFactor = 1.0; + SAMPTYPE = 2; + m_BufferSize = 1024; + FFT_SIZE = 1024; + m_FFTFactor = 1.0; + sys.m_DecCutOff = 2950; + sys.m_MaxCarrier = 2950; + } + else { + return FALSE; + } + DEMSAMPFREQ = SAMPFREQ * m_DecFactor; + m_FFTSampFreq = SAMPFREQ * m_FFTFactor; + if( fftsize != FFT_SIZE ) m_FFT.InitFFT(); + UdRxCarrier->Max = short(sys.m_MaxCarrier); + UdTxCarrier->Max = short(sys.m_MaxCarrier); + + m_Notches.m_SampleFreq = m_FFTSampFreq; + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FFTSampleFreq(double fq) +{ + m_FFTSampFreq = fq * m_FFTFactor; + m_FFTWindow = m_FFTW * FFT_SIZE / m_FFTSampFreq; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SampleStatus(void) +{ + if( SAMPTXOFFSET ){ + sprintf(m_TextBuff, "%.2lf/%.2lf", SAMPFREQ, SAMPTXOFFSET); + } + else { + sprintf(m_TextBuff, "%.2lfHz", SAMPFREQ); + } + DrawStatus(statusSAMP, m_TextBuff); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PageStatus(void) +{ + sprintf(m_TextBuff, "Page%d", m_CurrentEdit + 1); + DrawStatus(statusPAGE, m_TextBuff); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetSampleFreq(double f, BOOL fForce) +{ + if( !fForce && (SAMPFREQ == f) ) return; + + if( !SampleFreq(f) ) return; + BOOL fi = m_Wave.IsInOpen(); + BOOL fo = m_Wave.IsOutOpen(); + m_Wave.InClose(); m_Wave.OutAbort(); + InitWFX(); + m_Dec2.SetSampleFreq(m_fDec, SAMPFREQ); + CRxSet *pRxSet = m_RxSet; + for( int i = 0; i < RXMAX; i++, pRxSet++ ){ + pRxSet->SetSampleFreq(DEMSAMPFREQ); + } + m_FFTWindow = m_FFTW * FFT_SIZE / m_FFTSampFreq; + InitCollect(); + m_HPF.Create(ffHPF, 300, SAMPFREQ, 2, 1, 0.3); + m_ModFSK.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_Notches.Create(); +#if DEBUG + m_ModTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_VCOTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_TestHPF.Create(ffHPF, 700, SAMPFREQ+SAMPTXOFFSET, 3, 0, 0); + if( sys.m_testCarrier1 ) m_BPF500.Create(96, ffBPF, SAMPFREQ+SAMPTXOFFSET, sys.m_testCarrier1-250, sys.m_testCarrier1+250, 60.0, 1.0); +#endif + if( sys.m_fPlayBack ) m_PlayBack.Init(m_BufferSize, SAMPBASE); + + SampleStatus(); + if( fi ) OpenSound(FALSE); + if( fo ) ReOutOpen(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTxOffset(double f) +{ + if( SAMPTXOFFSET == f ) return; + + SAMPTXOFFSET = f; + m_ModFSK.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); +#if DEBUG + m_ModTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + m_VCOTest.SetSampleFreq(SAMPFREQ+SAMPTXOFFSET); + if( sys.m_testCarrier1 ) m_BPF500.Create(96, ffBPF, SAMPFREQ+SAMPTXOFFSET, sys.m_testCarrier1-250, sys.m_testCarrier1+250, 60.0, 1.0); +#endif + SampleStatus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetRXFifo(int d) +{ + if( d == m_Wave.m_InFifoSize ) return; + + BOOL f = m_Wave.IsInOpen(); + m_Wave.InClose(); + m_Wave.m_InFifoSize = d; + if( f ) OpenSound(FALSE); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTXFifo(int d) +{ + if( d == m_Wave.m_OutFifoSize ) return; + + BOOL f = m_Wave.IsOutOpen(); + m_Wave.OutAbort(); + m_Wave.m_OutFifoSize = d; + if( f ) ReOutOpen(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::ReOutOpen(void) +{ + if( !OpenSound(TRUE) ) return FALSE; + memset(m_wBuffer, 0, sizeof(m_wBuffer)); +#if 1 + while(!m_Wave.IsOutBufFull()) m_Wave.OutWrite(m_wBuffer); +#else + for( int i = 0; i < m_Wave.m_OutFifoSize; i++ ) m_Wave.OutWrite(m_wBuffer); +#endif + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetSoundCard(int ch, LPCSTR pID, LPCSTR pIDTX) +{ + int id = m_Wave.m_SoundID; + int idtx = m_Wave.m_SoundTxID; + BOOL f = FALSE; + + if( pID ){ + if( !strcmpi(pID, "default") ) pID = "-1"; + if( !strcmpi(pIDTX, "default") ) pIDTX = "-1"; + + AnsiString as = sys.m_SoundMMW; + sys.m_SoundIDRX = pID; + sys.m_SoundIDTX = pIDTX; + m_Wave.SetSoundID(id, idtx); + if( id == -2 ) f = strcmp(as.c_str(), pID); + } + + if( (m_Wave.m_SoundStereo != ch) || (id != m_Wave.m_SoundID) || (idtx != m_Wave.m_SoundTxID) || f ){ + if( m_TX ) ToRX(); + BOOL f = m_Wave.IsInOpen(); + m_Wave.InClose(); + m_Wave.m_SoundStereo = ch; + m_Wave.m_SoundID = id; + m_Wave.m_SoundTxID = idtx; + InitWFX(); + if( f ) OpenSound(FALSE); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::OpenSound(BOOL fTX) +{ + m_Wave.m_hWnd = Handle; + m_Wave.UpdateDevice(m_Wave.m_SoundID); + BOOL r; + if( fTX ){ + r = m_Wave.OutOpen(&m_WFX, m_Wave.m_SoundTxID, m_BufferSize); + } + else { + r = m_Wave.InOpen(&m_WFX, m_Wave.m_SoundID, m_BufferSize); + } + if( r || m_pSoundTimer || m_fSuspend ) return r; + + // サウンドカードリカバリタイマーを起動 +// m_fShowMsg = TRUE; + m_SoundMsgTimer = m_Wave.GetTimeout(); + m_RecoverSoundMode = fTX; + m_pSoundTimer = new TTimer(this); + m_pSoundTimer->OnTimer = SoundTimer; + m_pSoundTimer->Interval = 1000; + return r; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetCBSpeed(void) +{ + m_fDisEvent++; + char bf[256]; + CBSpeed->Text = StrDbl(bf, m_RxSet[0].GetSpeed()); + m_fDisEvent--; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateUI(void) +{ + BOOL f = m_TX != txINTERNAL; +// SBTX->Enabled = !m_RxSet[0].m_fJA || CBMode->ItemIndex != MODE_BPSK; + CBRXCarrier->Enabled = f; + UdRxCarrier->Enabled = f; + SBATC->Enabled = (!IsRTTY() && !m_RxSet[0].IsMFSK()); +// CBSpeed->Enabled = !m_RxSet[0].IsMFSK(); + SetCBSpeed(); + f = f && SBATC->Enabled; + f = f && !SBATC->Down; + EATC->Enabled = f; + UdATC->Enabled = f; + f = m_TX || !SBNET->Down; + CBTxCarrier->Enabled = f; + UdTxCarrier->Enabled = f; + SBM->Enabled = (PupCalls->Items->Count != 0); + if( m_PlayBack.IsActive() ){ + SBP60->Visible = TRUE; + SBP30->Visible = TRUE; + SBP15->Visible = TRUE; + f = !m_TX; + SBP60->Enabled = f; + SBP30->Enabled = f; + SBP15->Enabled = f; + } + else { + SBP60->Visible = FALSE; + SBP30->Visible = FALSE; + SBP15->Visible = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateLogPanel(void) +{ + if( Log.IsOpen() ){ + if( Log.m_CurChg ){ + Log.SetLastPos(); + UpdateTextData(); + Log.m_CurChg = 0; + SBQSO->Down = Log.m_sd.btime ? 1 : 0; + } + + SBQSO->Enabled = !HisCall->Text.IsEmpty(); + SBData->Enabled = TRUE; + SBFind->Enabled = SBQSO->Enabled; + SBList->Enabled = TRUE; + } + else { + SBQSO->Enabled = FALSE; + SBData->Enabled = FALSE; + SBFind->Enabled = FALSE; + SBList->Enabled = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OpenCom(void) +{ + if( m_pCom ){ + delete m_pCom; + m_pCom = NULL; + } + if( strcmpi(sys.m_PTTCOM.c_str(), "NONE") ){ + m_pCom = new CComm(); + m_pCom->m_Baud = IsRTTY() ? int(m_RxSet[0].m_Speed) : 45; + if( m_pCom->Open(sys.m_PTTCOM.c_str()) ){ + m_pCom->SetFSK(sys.m_bFSKOUT, sys.m_bINVFSK); + m_pCom->SetPTT(m_TX); + } + else { + delete m_pCom; + m_pCom = NULL; + } + } + DrawStatus(statusCOM); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OpenRadio(void) +{ + if( m_pRadio ){ + delete m_pRadio; + m_pRadio = NULL; + } + if( m_pRadioTimer ){ + delete m_pRadioTimer; + m_pRadioTimer = NULL; + } + if( strcmp(RADIO.StrPort, "NONE" ) ){ + m_pRadio = new CCradio(TRUE); + m_pRadio->Open(&RADIO, Handle, CM_CMMR, CM_CRADIO); + if( m_pRadio->m_CreateON != TRUE ){ + delete m_pRadio; + m_pRadio = NULL; + ErrorMB( sys.m_MsgEng ? "Could not open '%s' for Radio commands":"Radioコマンドポート'%s'がオープンできません.", RADIO.StrPort); + } + else { + m_pRadio->SendCommand(RADIO.CmdInit.c_str()); + if( RADIO.PollScan ){ + m_fDisEvent++; + LogFreq->Text = "???"; + m_fDisEvent--; + RADIO.Cmdxx = 0x00; + m_pRadio->m_ScanAddr = 1; + } + if( RADIO.PollType ){ + m_pRadioTimer = new TTimer(this); + m_pRadioTimer->OnTimer = RadioTimer; + int intval = ((RADIO.PollInterval + 2) * 100)/2; + m_pRadioTimer->Interval = intval; + } + } + } + RADIO.change = 0; +} +//--------------------------------------------------------------------------- +// サウンドカード初期化パラメータの生成 +void __fastcall TMainVARI::InitWFX(void) +{ + m_WFX.wFormatTag = WAVE_FORMAT_PCM; + m_WFX.nChannels = WORD(m_Wave.m_SoundStereo ? 2 : 1); + m_WFX.wBitsPerSample = 16; + m_WFX.nSamplesPerSec = SAMPBASE; + m_WFX.nBlockAlign = WORD(m_WFX.nChannels *(m_WFX.wBitsPerSample/8)); + m_WFX.nAvgBytesPerSec = m_WFX.nBlockAlign * m_WFX.nSamplesPerSec; + m_WFX.cbSize = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxFFTPaint(TObject *Sender) +{ + PBoxFFT->Canvas->Draw(0, 0, m_pBitmapFFT); + if( !SBWave->Down && (m_fSubWindow || m_Notches.m_Count) ){ + DrawSubChannel(PBoxFFT); + } + DrawErrorMsg(PBoxFFT->Canvas, m_fftXW, m_fftYW, TRUE); +// if( SBWave->Down && (m_fftMX > 0) ){ + if( m_fftMX > 0 ){ + TCanvas *pCanvas = PBoxFFT->Canvas; + pCanvas->Pen->Style = psDot; + pCanvas->Pen->Color = clYellow; + pCanvas->Brush->Color = clBlack; + pCanvas->MoveTo(m_fftMX, 0); + pCanvas->LineTo(m_fftMX, m_fftYW); + pCanvas->Pen->Style = psSolid; + if( SBWave->Down ){ + sprintf(m_TextBuff, "%.1lfms", 1000.0 * m_fftMX * m_Collect1.GetMax() / (m_fftXW * DEMSAMPFREQ) ); + } + else { + sprintf(m_TextBuff, "%uHz", m_RightFreq); + } + DrawMessage(pCanvas, PBoxFFT->Width, PBoxFFT->Height, m_TextBuff, m_fftMX); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxLevelPaint(TObject *Sender) +{ + PBoxLevel->Canvas->Draw(0, 0, m_pBitmapLevel); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::Draw(BOOL fPaint) +{ + if( SBWave->Down ){ + DrawWave(fPaint); + } + else if( SBFFT->Down ){ + DrawFFT(fPaint); + } + else { + DrawWater(fPaint, TRUE); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CalcFFTCenter(int fo) +{ + if( m_FFTW == 3000 ){ + m_FFTB = 0; + m_FFTU = m_FFTB + m_FFTW; + } + int fb = fo - m_FFTW/2; + if( fb < 0 ) fb = 0; + fb /= 100; + fb *= 100; + if( m_FFTW == 3000 ){ + fb = 0; + } + else if( (fb + m_FFTW) >= 3000 ){ + fb = 3000 - m_FFTW; + } + m_FFTB = fb; + m_FFTU = m_FFTB + m_FFTW; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CalcFFTFreq(void) +{ + int fo = m_RxSet[0].m_pDem->m_CarrierFreq; + int edge = 100; + if( m_RxSet[0].IsMFSK() ){ + edge = 200; + if( !sys.m_MFSK_Center ){ + int off = m_RxSet[0].m_pDem->m_MFSK_BW/2; + if( m_RxSet[0].m_Mode == MODE_mfsk_L ){ + fo -= off; + } + else { + fo += off; + } + } + } + else if( m_RxSet[0].IsRTTY() ){ + edge = 200; + } + if( m_FFTW == 3000 ){ + m_FFTB = 0; + m_FFTU = m_FFTB + m_FFTW; + } + if( (m_FFTB >= 0) && ((m_FFTB+m_FFTW) <= 3000 ) ){ + if( (fo > m_FFTB+edge) && (fo < (m_FFTB+m_FFTW)-edge) ){ + return; + } + } + CalcFFTCenter(fo); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawSubChannel(TPaintBox *pBox) +{ + TCanvas *pCanvas = pBox->Canvas; + int fw = pCanvas->TextWidth("2"); + int fh = pCanvas->TextHeight("2"); + int ffw = fw - 2; + int ffh = fh - 3; + int i; + POINT pt[6]; + char bf[256]; + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ){ + int fo = pRxSet->m_pDem->m_CarrierFreq + 0.5; + int xx = 0.5 + (fo - m_FFTB) * m_fftXW / m_FFTW; + pt[0].x = xx - ffw; pt[0].y = 0; + pt[1].x = xx + ffw; pt[1].y = 0; + pt[2].x = xx + ffw; pt[2].y = ffh; + pt[3].x = xx; pt[3].y = ffh + 3; + pt[4].x = xx - ffw; pt[4].y = ffh; + pt[5].x = xx - ffw; pt[5].y = 0; + pCanvas->Brush->Color = clWhite; + pCanvas->Pen->Color = clRed; + pCanvas->Polygon(pt, 5); + pRxSet->m_X = xx; + pRxSet->m_Y = fh/2; + sprintf(bf, "%u", i); + fw = pCanvas->TextWidth(bf); + xx -= fw/2; + ::SetBkMode(pCanvas->Handle, TRANSPARENT); + pCanvas->TextOut(xx, 0, bf); + } + } + if( m_Notches.m_Count ){ + for( i = 0; i < m_Notches.m_Count; i++ ){ + int fo = m_Notches.m_pBase[i].Freq; + int xx = 0.5 + (fo - m_FFTB) * m_fftXW / m_FFTW; + pt[0].x = xx - ffw; pt[0].y = 0; + pt[1].x = xx + ffw; pt[1].y = 0; + pt[2].x = xx + ffw; pt[2].y = ffh; + pt[3].x = xx; pt[3].y = ffh + 3; + pt[4].x = xx - ffw; pt[4].y = ffh; + pt[5].x = xx - ffw; pt[5].y = 0; + pCanvas->Brush->Color = clYellow; + pCanvas->Pen->Color = clRed; + pCanvas->Polygon(pt, 5); + m_Notches.m_pBase[i].m_MX = xx; + m_Notches.m_pBase[i].m_MY = fh/2; + strcpy(bf, "N"); + fw = pCanvas->TextWidth(bf); + xx -= fw/2; + ::SetBkMode(pCanvas->Handle, TRANSPARENT); + pCanvas->TextOut(xx, 0, bf); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawFreqScale(TCanvas *pCanvas, int XW, int YW, int fftb, int fftw, int fh, BOOL fRadio) +{ + int fw; + char bf[128]; + int A, B, L; + switch(fftw){ + case 500: + B = 50; A = 100; L = 100; + break; + case 1000: + B = 50; A = 100; L = 200; + break; + case 2000: + B = 100; A = 500; L = 500; + break; + case 3000: + B = 100; A = 500; L = 500; + break; + } + BOOL fReal = fRadio && m_ScaleAsRigFreq && m_pRadio && m_pRadio->m_FreqHz; + BOOL fLSB = (fReal && m_pRadio->IsRigLSB()); + UINT f, fb, fu; + if( fReal ){ + int rfo = m_pRadio->m_CarrierFreq; + if( fLSB ){ + fb = m_pRadio->m_FreqHz + rfo - m_FFTB; + fu = fb - fftw; + } + else { + fb = m_pRadio->m_FreqHz - rfo + m_FFTB; + fu = fb + fftw; + } + } + else { + fb = fftb; + fu = fftb+fftw; + } + int xx; + f = fb - (fb % A); + if( !fReal && (int(f) < 0) ) f = 0; +#if 0 // For Debug + sprintf(m_TextBuff, "%u,%u,%u,%u", m_pRadio ? m_pRadio->m_FreqHz:0, fb, fu, f); + Caption = m_TextBuff; +#endif + int _yt; + TColor LCol, FCol; + if( m_ScaleDetails ){ + LCol = pCanvas->Pen->Color; + FCol = pCanvas->Font->Color; + _yt = 2; + } + else { + B = A; + _yt = 0; + } + int vy = pCanvas->TextHeight("0") + _yt; + if( fLSB ){ + for( ; f > fu; f -= B ){ + xx = int(fb - f) * XW / fftw; + if( xx >= XW ) break; + if( !(f % 1000) || !(f % L) ){ + sprintf(bf, "%.1lf", double(f) * 0.001); + fw = pCanvas->TextWidth(bf)/2; + if( (xx - fw) > 0 ){ + pCanvas->TextOut(xx - fw, _yt, bf); + if( fh ){ + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, YW); + } + else { + pCanvas->MoveTo(xx, vy); pCanvas->LineTo(xx, vy+3); + } + } + } + else if( fh && !(f % A) ){ + pCanvas->MoveTo(xx, _yt); pCanvas->LineTo(xx, YW); + } + if( m_ScaleDetails && !(f % B) ){ + pCanvas->Pen->Color = FCol; + pCanvas->MoveTo(xx, 0); pCanvas->LineTo(xx, 2); + pCanvas->Pen->Color = LCol; + } + } + } + else { + for( ; f < fu; f += B ){ + xx = int(f - fb) * XW / fftw; + if( xx >= XW ) break; + if( !(f % 1000) || !(f % L) ){ + if( fReal ){ + sprintf(bf, "%.1lf", double(f) * 0.001); + } + else { + sprintf(bf, "%u", f); + } + fw = pCanvas->TextWidth(bf)/2; + if( (xx - fw) > 0 ){ + pCanvas->TextOut(xx - fw, _yt, bf); + if( fh ){ + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, YW); + } + else { + pCanvas->MoveTo(xx, vy); pCanvas->LineTo(xx, vy+3); + } + } + } + else if( fh && !(f % A) ){ + pCanvas->MoveTo(xx, _yt); pCanvas->LineTo(xx, YW); + } + if( m_ScaleDetails && !(f % B) ){ + pCanvas->Pen->Color = FCol; + pCanvas->MoveTo(xx, 0); pCanvas->LineTo(xx, 2); + pCanvas->Pen->Color = LCol; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetInfoMsg(LPCSTR pStr) +{ + SetInfoMsg(pStr, 1); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetMsgCount(void) +{ + if( SBWave->Down ){ + int n = DEMSAMPFREQ * 3 / m_Collect1.GetMax(); + if( !n ) n++; + return n; + } + else { + return 15; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetInfoMsg(LPCSTR pStr, int pos) +{ + if( (pos >= 0) && (pos < 5) ){ + m_InfoMsg[pos] = pStr; + m_InfoMsgFlag |= _tBitData[pos]; + m_cInfoMsg[pos] = GetMsgCount(); + m_fShowMsg = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetErrorMsg(LPCSTR pStr) +{ + m_ErrorMsg = pStr; + m_cErrorMsg = GetMsgCount(); + m_fShowMsg = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawErrorMsg(TCanvas *pCanvas, int XW, int YW, BOOL fReset) +{ + LPCSTR p = NULL; + if( m_fShowMsg ){ + if( m_fSuspend ){ + p = sys.m_MsgEng ? "Suspend..." : "サスペンド中..."; + } + else if( m_pSoundTimer ){ + p = sys.m_MsgEng ? "SoundCard open error. Now trying to open every 1sec." : "サウンドカードオープンエラー, 再試行中(1秒毎)..."; + } + else if( m_LostSoundRX ){ + if( fReset ) m_LostSoundRX--; + p = sys.m_MsgEng ? "Lost RX Sound":"受信サウンド欠落"; + } + else if( m_LostSoundTX ){ + if( fReset ) m_LostSoundTX--; + p = sys.m_MsgEng ? "Lost TX Sound":"送信サウンド欠落"; + } + else if( m_cErrorMsg ){ + m_cErrorMsg--; + p = m_ErrorMsg.c_str(); + } + else if( m_InfoMsgFlag ){ + for( int i = 0; i < 5; i++ ){ + if( m_InfoMsgFlag & _tBitData[i] ){ + DrawMessage(pCanvas, XW, YW, m_InfoMsg[i].c_str(), i); + m_cInfoMsg[i]--; + if( !m_cInfoMsg[i] ) m_InfoMsgFlag &= ~_tBitData[i]; + } + } + } + else { + m_fShowMsg = FALSE; + } + } + else if( m_ScaleAsRigFreq && m_pRadio ){ + if( fReset ) m_RadioScaleCounter++; + if( m_RadioScaleCounter & 4 ){ + if( m_pRadio->m_FreqHz ){ + if( (RADIO.PollOffset == 3) && !m_pRadio->m_LSB ){ + p = sys.m_MsgEng ? "Invalid RIG MODE":"未対応のRIGモード"; + } + } + else { + p = sys.m_MsgEng ? "NO RIG DATA" : "RIGデータ未受信"; + } + } + } +#if 0 + if( !p && !SBAFC->Down && m_RxSet[0].m_SQ && m_RxSet[0].m_pDem->IsFreqErr() ){ + DrawMessage(pCanvas, XW, YW, sys.m_MsgEng ? "OFF FREQ":"Fズレ", 3); + } +#endif + if( p ) DrawMessage(pCanvas, XW, YW, p, 3); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawFFT(BOOL fPaint) +{ + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_fftXW; rc.Bottom = m_fftYW; + pCanvas->Brush->Color = m_tFFTColset[0].c; + pCanvas->Pen->Color = m_tFFTColset[0].c; + pCanvas->FillRect(rc); + + if( !m_MouseDown ) CalcFFTFreq(); + pCanvas->Pen->Style = psDot; + + int xx, y; + int fh = pCanvas->TextHeight("A"); + + switch(m_FFTVType){ + case 0: + pCanvas->Pen->Color = m_tFFTColset[3].c; + for( y = 6; y <= 86; y += 20 ){ + xx = y * m_fftYW / 100; + pCanvas->MoveTo(0, xx); pCanvas->LineTo(m_fftXW, xx); + } + break; + case 1: + pCanvas->Pen->Color = m_tFFTColset[3].c; + for( y = 6; y <= 66; y += 20 ){ + xx = y * m_fftYW / 60; + pCanvas->MoveTo(0, xx); pCanvas->LineTo(m_fftXW, xx); + } + break; + } + pCanvas->Font->Height = -12; + pCanvas->Font->Color = m_tFFTColset[2].c; + pCanvas->Pen->Color = m_tFFTColset[3].c; + int rfo = UdRxCarrier->Position; + DrawFreqScale(pCanvas, m_fftXW, m_fftYW, m_FFTB, m_FFTW, fh, TRUE); + + if( m_RxSet[0].m_pDem->GetSyncState() && m_RxSet[0].m_SQ && m_RxSet[0].m_pDem->m_Lock ){ +// DrawMessage(pCanvas, m_fftXW, m_fftYW, "SYNC", 1); + pCanvas->TextOut(1, m_ScaleDetails ? 3 : 1, "SYNC"); + } +// pCanvas->Pen->Color = clYellow; +// xx = m_Hilbert.m_CarrierFreq * m_fftXW / m_FFTW; +// pCanvas->MoveTo(xx, 0); pCanvas->LineTo(xx, m_fftYW); + pCanvas->Pen->Color = clGreen; + xx = (DEMSAMPFREQ*0.5 - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + int tfo = UdTxCarrier->Position; + POINT pt[4]; + if( (tfo != rfo) && !SBNET->Down ){ + pCanvas->Pen->Color = m_tFFTColset[5].c; + xx = 0.5 + (tfo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + pt[0].x = xx; pt[0].y = fh; + pt[1].x = xx - 3; pt[1].y = fh+3; + pt[2].x = xx; pt[2].y = fh + 6; + pt[3].x = xx + 3; pt[3].y = fh+3; + pCanvas->Brush->Color = m_tFFTColset[5].c; + pCanvas->Polygon(pt, 3); + if( Is170() ){ + double hw = m_RxSet[0].m_pDem->m_RTTYShift * 0.5; + xx = 0.5 + (tfo - m_FFTB - hw) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + xx = 0.5 + (tfo - m_FFTB + hw) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + else if( m_RxSet[0].IsMFSK() ){ + xx = 0.5 + (tfo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + double bw = m_RxSet[0].m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + int x = 0.5 + (tfo - m_FFTB - bw*0.5) * m_fftXW / m_FFTW; + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + x = 0.5 + (tfo - m_FFTB + bw*0.5) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+3); + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + } + else { + xx = 0.5 + (tfo - m_FFTB + (m_RxSet[0].m_Mode == MODE_mfsk_U ? bw : -bw)) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + } + } + pCanvas->Pen->Color = m_tFFTColset[4].c; + xx = 0.5 + (rfo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh); pCanvas->LineTo(xx, m_fftYW); + pt[0].x = xx; pt[0].y = fh; + pt[1].x = xx - 3; pt[1].y = fh+3; + pt[2].x = xx; pt[2].y = fh + 6; + pt[3].x = xx + 3; pt[3].y = fh+3; + pCanvas->Brush->Color = m_tFFTColset[4].c; + pCanvas->Polygon(pt, 3); + if( Is170() ){ + double hw = m_RxSet[0].m_pDem->m_RTTYShift * 0.5; + xx = 0.5 + (rfo - m_FFTB - hw) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + xx = 0.5 + (rfo - m_FFTB + hw) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + else if( m_RxSet[0].IsMFSK() ){ + xx = 0.5 + (rfo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + double bw = m_RxSet[0].m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + int x = 0.5 + (rfo - m_FFTB - bw*0.5) * m_fftXW / m_FFTW; + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + x = 0.5 + (rfo - m_FFTB + bw*0.5) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+3); + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + } + else { + xx = 0.5 + (rfo - m_FFTB + (m_RxSet[0].m_Mode == MODE_mfsk_U ? bw : -bw)) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + } + if( (m_Wave.IsInOpen() || m_Wave.IsOutOpen()) && SBFFT->Down ){ + pCanvas->Pen->Style = psSolid; + pCanvas->Pen->Color = m_tFFTColset[1].c; + + int x, y; +#if 1 + int xo = (m_FFTB*FFT_SIZE/m_FFTSampFreq) + 0.5; + int xe = (m_FFTW*FFT_SIZE/m_FFTSampFreq) + 0.5; + double kx = double(m_fftXW) / double(xe); + xe += xo; +#else + int xo = ((m_FFTB+(m_FFTSampFreq/FFT_SIZE))*FFT_SIZE/m_FFTSampFreq) + 0.5; +#endif + switch(m_FFTVType){ + case 0:{ // 100dB + double k = m_fftYW*0.01/m_fftSC; + for( x = xo; x <= xe; x++ ){ + y = m_fftout[x]; + y = m_fftYW - y * k; + xx = int((x - xo) * kx); + if( x > xo ){ + pCanvas->LineTo(xx, y); + } + else { + pCanvas->MoveTo(xx, y); + } + } + break;} + case 1:{ // 60dB + double k = double(m_fftYW)/double(m_fftSC); + int yo = m_fftYW * 40 / k; + k = k / 60.0; + for( x = xo; x <= xe; x++ ){ + y = m_fftout[x]; + y = m_fftYW - ((y-yo)*k); + xx = int((x - xo) * kx); + if( x > xo ){ + pCanvas->LineTo(xx, y); + } + else { + pCanvas->MoveTo(xx, y); + } + } + break;} + default:{ // SQR + for( x = xo; x <= xe; x++ ){ + y = m_fftout[x]; + y = m_fftYW - (y/100); + xx = int((x - xo) * kx); + if( x > xo ){ + pCanvas->LineTo(xx, y); + } + else { + pCanvas->MoveTo(xx, y); + } + } + break;} + } + } + if( fPaint ) PBoxFFTPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitWater(int sw) +{ + if( m_WaterNoiseL > m_WaterNoiseH ){ + int f = m_WaterNoiseL; + m_WaterNoiseL = m_WaterNoiseH; + m_WaterNoiseH = f; + } + if( m_FFT.m_FFTGain ){ + if( sw & iniwMETRIC ){ + m_StgWater.Sum = 1000; + m_StgWater.Max = 5120; + m_StgWater.VW = 5120; + } + if( sw & iniwLIMIT ){ + m_StgWater.LimitL = DBToSqrt(m_WaterNoiseL*100-500); + m_StgWater.LimitH = DBToSqrt(m_WaterNoiseH*100-500); + } + } + else { + if( sw & iniwMETRIC ){ + m_StgWater.Sum = 5000; + m_StgWater.Max = 8000; + m_StgWater.VW = 6000; + } + if( sw & iniwLIMIT ){ + m_StgWater.LimitL = m_WaterNoiseL * 100 - 500; + m_StgWater.LimitH = m_WaterNoiseH * 100 - 500; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawWater(BOOL fPaint, BOOL fClear) +{ + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + int fh = pCanvas->TextHeight("A"); + int ft = fh + 8; + + int b = m_FFTB; + int fo = UdRxCarrier->Position; + if( !m_MouseDown ) CalcFFTFreq(); + + TRect rc; + rc.Left = 0; rc.Top = 0; rc.Right = m_fftXW; + if( fClear || (b != m_FFTB)){ + rc.Bottom = m_fftYW; + InitWater(iniwMETRIC); + } + else { + rc.Bottom = ft; + } + pCanvas->Brush->Color = m_tWaterColset[0].c; + pCanvas->Pen->Color = m_tWaterColset[0].c; + pCanvas->Pen->Style = psSolid; + pCanvas->FillRect(rc); + rc.Bottom = m_fftYW; + + pCanvas->Font->Height = -12; + pCanvas->Font->Color = m_tWaterColset[2].c; + pCanvas->Pen->Color = m_tWaterColset[2].c; + DrawFreqScale(pCanvas, m_fftXW, m_fftYW, m_FFTB, m_FFTW, 0, TRUE); + + if( m_RxSet[0].m_pDem->GetSyncState() && m_RxSet[0].m_SQ && m_RxSet[0].m_pDem->m_Lock ){ + pCanvas->TextOut(1, m_ScaleDetails ? 3 : 1, "SYNC"); + } + + int xx; + POINT pt[3]; + int tfo = UdTxCarrier->Position; + if( tfo != fo && !SBNET->Down ){ + if( Is170() ){ + double hw = m_RxSet[0].m_pDem->m_RTTYShift * 0.5; + pCanvas->Pen->Color = m_tWaterColset[5].c; + xx = 0.5 + (tfo - m_FFTB - hw) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + xx = 0.5 + (tfo - m_FFTB + hw) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + else if( m_RxSet[0].IsMFSK() ){ + pCanvas->Pen->Color = m_tWaterColset[5].c; + xx = 0.5 + (tfo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + double bw = m_RxSet[0].m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + int x = 0.5 + (tfo - m_FFTB - bw*0.5) * m_fftXW / m_FFTW; + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + x = 0.5 + (tfo - m_FFTB + bw*0.5) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+3); + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + } + else { + xx = 0.5 + (tfo - m_FFTB + (m_RxSet[0].m_Mode == MODE_mfsk_U ? bw : -bw)) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + } + xx = 0.5 + (tfo - m_FFTB) * m_fftXW / m_FFTW; + pt[0].x = xx - 4; pt[0].y = fh; + pt[1].x = xx + 4; pt[1].y = fh; + pt[2].x = xx; pt[2].y = fh + 6; + pCanvas->Pen->Color = m_tWaterColset[3].c; + pCanvas->Brush->Color = m_tWaterColset[5].c; + pCanvas->Polygon(pt, 2); + } + pCanvas->Pen->Color = m_tWaterColset[3].c; + if( Is170() ){ + double hw = m_RxSet[0].m_pDem->m_RTTYShift * 0.5; + pCanvas->Pen->Color = m_tWaterColset[4].c; + xx = 0.5 + (fo - m_FFTB - hw) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + xx = 0.5 + (fo - m_FFTB + hw) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + else if( m_RxSet[0].IsMFSK() ){ + pCanvas->Pen->Color = m_tWaterColset[4].c; + xx = 0.5 + (fo - m_FFTB) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+5); + pCanvas->LineTo(xx, fh+3); + double bw = m_RxSet[0].m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + int x = 0.5 + (fo - m_FFTB - bw*0.5) * m_fftXW / m_FFTW; + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + x = 0.5 + (fo - m_FFTB + bw*0.5) * m_fftXW / m_FFTW; + pCanvas->MoveTo(xx, fh+3); + pCanvas->LineTo(x, fh+3); + pCanvas->LineTo(x, fh+6); + } + else { + xx = 0.5 + (fo - m_FFTB + (m_RxSet[0].m_Mode == MODE_mfsk_U ? bw : -bw)) * m_fftXW / m_FFTW; + pCanvas->LineTo(xx, fh+3); + pCanvas->LineTo(xx, fh+6); + } + } + xx = 0.5 + (fo - m_FFTB) * m_fftXW / m_FFTW; + pt[0].x = xx - 4; pt[0].y = fh; + pt[1].x = xx + 4; pt[1].y = fh; + pt[2].x = xx; pt[2].y = fh + 6; + pCanvas->Pen->Color = m_tWaterColset[3].c; + pCanvas->Brush->Color = m_tWaterColset[4].c; + pCanvas->Polygon(pt, 2); + + if( (m_Wave.IsInOpen() || m_Wave.IsOutOpen()) && SBWater->Down ){ + TRect trc = rc; + rc.Top += ft; + rc.Bottom--; + trc.Top += ft + 1; + pCanvas->CopyRect(trc, pCanvas, rc); + int xo = ((m_FFTB+(m_FFTSampFreq/FFT_SIZE))*FFT_SIZE/m_FFTSampFreq) + 0.5; + int x, y; + int n = 0; + int sum = m_StgWater.LimitL; + int max = 0; + int wmax = 0; + int xl = 0.5 + (fo - m_RxSet[0].m_Speed - m_FFTB) * m_fftXW / m_FFTW; + int xh = 0.5 + (fo + m_RxSet[0].m_Speed - m_FFTB) * m_fftXW / m_FFTW; + double k = 256.0 / m_StgWater.VW; + for( x = 0; x < m_fftXW; x++ ){ + xx = xo + (x * m_FFTWindow / m_fftXW); + y = m_fftout[xx]; + if( max < y ) max = y; + if( (x >= xl) && (x <= xh) ){ + if( wmax < y ) wmax = y; + } + if( (y > m_StgWater.LimitL) && (y < m_StgWater.LimitH) ){ + sum += y; + n++; + } + y = (y - m_StgWater.Sum) * k; + if( y < 0 ) y = 0; + if( y >= 256 ) y = 255; + pCanvas->Pixels[x][ft] = m_tWaterColors[y]; + } + if( m_TX == txINTERNAL ){ + sum = m_StgWater.LimitL; + if( m_RxSet[0].IsMFSK() || m_RxSet[0].Is170() ){ + sum = (sum + m_StgWater.LimitH)/2; + } + } + else if( n < 16 ){ + sum = m_StgWater.LimitL; + } + else { + sum /= n; + } + m_StgWater.Sum = (m_StgWater.Sum + sum) / 2; + if( m_StgWater.Sum >= m_StgWater.LimitH ) m_StgWater.Sum = m_StgWater.LimitH; + if( (wmax-sum) >= 320 ){ + max = wmax; + } + m_StgWater.Max = (m_StgWater.Max + max) / 2; + m_StgWater.VW = m_StgWater.Max - m_StgWater.Sum; +#if DEBUG +// sprintf(m_TextBuff, "Max:%d, Sum:%d, DB:%d, VW:%d", max, sum, int(DBToSqrt(4000)), m_StgWater.VW); +// Caption = m_TextBuff; +#endif + int low, high; + if( KVWA->Checked ){ // AGC + if( m_FFT.m_FFTGain ){ + low = 3000; high = 7000; + } + else { + low = 4000; high = 10000; + } + } + else { + low = high = m_FFT.m_FFTGain ? 5120 : 5000; + } + if( m_TX == txINTERNAL ) high = 100000; + if( m_StgWater.VW < low ) m_StgWater.VW = low; + if( m_StgWater.VW > high ) m_StgWater.VW = high; + } + if( fPaint ) PBoxFFTPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawWave(BOOL fPaint) +{ + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_fftXW; rc.Bottom = m_fftYW; + pCanvas->Brush->Color = clBlack; + pCanvas->Pen->Color = clBlack; + pCanvas->FillRect(rc); + + pCanvas->Pen->Color = clGray; + pCanvas->Pen->Style = psDot; + int O1 = m_fftYW / 4; + pCanvas->MoveTo(0, O1); pCanvas->LineTo(m_fftXW, O1); + int O2 = m_fftYW * 3 / 4; + pCanvas->MoveTo(0, O2); pCanvas->LineTo(m_fftXW, O2); + + if( (m_Wave.IsInOpen() || m_Wave.IsOutOpen()) && SBWave->Down ){ + double k = m_fftYW * 0.3 / 32768.0; + pCanvas->Pen->Style = psSolid; + pCanvas->Pen->Color = TColor(RGB(0,255,0)); + int x, y, xx; + int W = m_Collect1.GetMax(); + int M = m_Collect1.GetCount(); + double *t1 = m_Collect1.GetZP(); + double *t2 = m_Collect2.GetZP(); + for( x = 0; x < m_fftXW; x++ ){ + xx = x * W / m_fftXW; + if( xx >= W ) xx = W - 1; + if( xx >= M ){ + break; + } + y = O1 - (t1[xx] * k); + if( x ){ pCanvas->LineTo(x, y); } else { pCanvas->MoveTo(x, y); } + } + if( m_WaveType ){ + double d; + double max = 128; + for( x = 0; x < M; x++ ){ + d = fabs(t2[x]); + if( max < d ) max = d; + } + k = m_fftYW * 0.2 / max; + for( x = 0; x < M; x++ ){ + xx = x * m_fftXW / W; + y = O2 - (t2[x] * k); + if( x ){ pCanvas->LineTo(xx, y); } else { pCanvas->MoveTo(xx, y); } + } + } + else { + for( x = 0; x < m_fftXW; x++ ){ + xx = x * W / m_fftXW; + if( xx >= W ) xx = W - 1; + if( xx >= M ){ + break; + } + y = O2 - (t2[xx] * k); + if( x ){ pCanvas->LineTo(x, y); } else { pCanvas->MoveTo(x, y); } + } + } + if( m_RxSet[0].m_pDem->GetSyncState() && m_RxSet[0].m_SQ ){ + pCanvas->TextOut(1, 1, "SYNC"); + } + } + if( fPaint ) PBoxFFTPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawLevel(BOOL fPaint) +{ + TCanvas *pCanvas = m_pBitmapLevel->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_levelXW; rc.Bottom = m_levelYW; + pCanvas->Brush->Color = clBlack; + pCanvas->Pen->Color = clBlack; + pCanvas->FillRect(rc); + +// pCanvas->Pen->Color = clYellow; + int d = m_RxSet[0].m_StgFFT.Sig - 500; + if( (m_TX != txINTERNAL) && m_RxSet[0].IsMFSK() && sys.m_MFSK_SQ_Metric ){ + d = m_RxSet[0].m_pDem->GetMFSKMetric(0); + } + if( d > LEVELMAX ) d = LEVELMAX; + if( m_Wave.IsInOpen() || m_Wave.IsOutOpen() ){ + if( m_RxSet[0].m_pDem->m_AGC.GetOver() && !m_TX ){ + pCanvas->Brush->Color = clRed; + } + else if( !m_RxSet[0].m_pDem->m_Lock ){ + pCanvas->Brush->Color = m_RxSet[0].m_SQ ? clBlue : clGray; + } + else { + TColor col = (m_TX == txINTERNAL) ? clYellow : TColor(RGB(0,255,0)); + pCanvas->Brush->Color = m_RxSet[0].m_SQ ? col : clGray; + } + rc.Top = m_levelYW - (d * m_levelYW / LEVELMAX); + pCanvas->FillRect(rc); + } + else { + m_RxSet[0].m_SQ = FALSE; + } + pCanvas->Pen->Color = m_RxSet[0].m_SQ ? clBlack : clWhite; + d = m_levelYW - (m_RxSet[0].m_SQLevel * m_levelYW / LEVELMAX); + pCanvas->MoveTo(0, d); pCanvas->LineTo(m_levelXW, d); + + if( fPaint ) PBoxLevelPaint(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::RemoveUselessMessage(UINT wParam) +{ + MSG msg; + while( ::PeekMessage(&msg, Handle, WM_WAVE, WM_WAVE, PM_NOREMOVE) ){ + if( msg.wParam == wParam ){ + ::PeekMessage(&msg, Handle, WM_WAVE, WM_WAVE, PM_REMOVE); +#if DEBUG + RxStatus(m_RxSet, "Remove"); +#endif + } + else { + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnWave(void) +{ + OnWaveIn(); + OnWaveOut(); +} +//--------------------------------------------------------------------------- +// サウンドカードからのイベント +void __fastcall TMainVARI::OnWaveEvent(TMessage &Message) +{ + switch(Message.WParam){ + case waveIN: // 入力イベント + OnWaveIn(); + break; + case waveOUT: // 出力イベント + OnWaveOut(); + break; + case waveCloseFileEdit: // OnCloseFileEdit + if( Message.LParam == int(m_pHelp) ){ + if( m_pHelp ){ + delete m_pHelp; + m_pHelp = NULL; + } + } + else if( Message.LParam == int(m_pEdit) ){ + if( m_pEdit ){ + delete m_pEdit; + m_pEdit = NULL; + } + } + break; + case waveCodeView: // CodeView + if( Message.LParam & 0x10000000 ){ + PCTX->Font->Name = PCRX->Font->Name; + PCTX->Font->Charset = PCRX->Font->Charset; + OnFontChange(FALSE); OnFontChange(TRUE); + } + else { + int c = Message.LParam & 0x0000ffff; + if( c == '\b' ){ + OnChar(c); + } + else { + m_Edit[m_CurrentEdit].PutChar(c, 1); + } + } + break; + case wavePlayDlg: // PlayDlg + if( Message.LParam == int(m_pPlayBox) ){ + KFESClick(NULL); + } + break; + case waveCloseRxView: // RxView + case waveSwapRxView: + for( int i = 1; i < RXMAX; i++ ){ + if( Message.LParam == int(m_RxSet[i].m_pView) ){ + CRxSet *pRxSet = &m_RxSet[i]; + switch(Message.WParam){ + case waveCloseRxView: + pRxSet->Delete(); + break; + case waveSwapRxView: // 入れ替え + { + int fq = pRxSet->m_pDem->m_CarrierFreq; + pRxSet->m_pDem->m_Decode.Reset(); + pRxSet->m_pDem->ResetMeasMFSK(); + pRxSet->SetCarrierFreq(UdRxCarrier->Position); +// pRxSet->m_pDem->SetCarrierFreq(UdRxCarrier->Position); + SetRxFreq(fq); + SetTxFreq(fq); + int sf = pRxSet->m_pDem->m_RTTYShift; + pRxSet->m_pDem->SetRTTYShift(m_RxSet[0].m_pDem->m_RTTYShift); + m_RxSet[0].m_pDem->SetRTTYShift(sf); + + int ModeSub = pRxSet->m_Mode; + int ModeMain = CBMode->ItemIndex; + double SpeedSub = pRxSet->GetSpeed(); + double SpeedMain = m_RxSet[0].GetSpeed(); + int MfskSub = pRxSet->m_MFSK_TYPE; + int MfskMain = m_RxSet[0].m_MFSK_TYPE; + + pRxSet->m_pView->SetMode(ModeMain); + SetMode(ModeSub); + m_RxSet[0].m_pDem->m_Decode.Reset(); + m_RxSet[0].m_pDem->ResetMeasMFSK(); + + pRxSet->SetSpeed(SpeedMain); + m_RxSet[0].SetSpeed(SpeedSub); + + pRxSet->SetMFSKType(MfskMain); + m_RxSet[0].SetMFSKType(MfskSub); + m_ModFSK.SetMFSKType(m_RxSet[0].m_MFSK_TYPE); + SetCBSpeed(); + SetSpeedInfo(m_RxSet[0].m_Speed); + } + break; + } + break; + } + } + UpdateSubWindow(); + break; + case waveClockAdj: // Clock ADJ window + if( Message.LParam == int(m_pClockView) ){ + delete m_pClockView; + m_pClockView = NULL; + } + break; + case waveSeekMacro: // Seek macro + if( Message.LParam ){ + int d = int(UdMac->Position) + Message.LParam; + if( d < 0 ) d += UdMac->Max+1; + if( d > UdMac->Max ) d -= UdMac->Max+1; + UdMac->Position = short(d); + CreateMacButton(); + + } + break; + case waveDoMacro: // Do Macro + SendButton(Message.LParam); + break; + case waveLoadMacro: // Load Macro + if( Message.LParam ){ + LPCSTR p = (LPCSTR)Message.LParam; + LoadMacro(p); + delete p; + } + break; +#if DEBUG + case waveRepeatMacro: + { + TSpeedButton *pButton = (TSpeedButton *)Message.LParam; + pButton->Down = TRUE; + pButton->Click(); + } + break; +#endif + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnWaveIn(void) +{ + while(m_Wave.IsInOpen() && !m_Wave.IsInBufNull()){ + if( !m_Wave.InRead(m_wBuffer) ){ + m_Wave.InClose(); + OpenSound(FALSE); + m_LostSoundRX = LOSTMSGTIME * int(SAMPFREQ) / m_BufferSize; + m_fShowMsg = TRUE; + } + m_WaveFile.ReadWrite(m_wBuffer, m_BufferSize); + if( m_PlayBack.IsActive() && !m_TX ){ + if( m_PlayBack.IsPlaying() ){ + for( int i = 0; i < sys.m_PlayBackSpeed; i++ ){ + if( m_PlayBack.Read(m_wBuffer) ){ + DoDem(); + } + else { + break; + } +/* + MSG msg; + if( ::PeekMessage(&msg, Handle, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE) ){ + break; + } +*/ + } + if( !m_PlayBack.IsPlaying() ){ + StopPlayBack(); + } + } + else { + m_PlayBack.Write(m_wBuffer); + DoDem(); + } + } + else { + DoDem(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnWaveOut(void) +{ +#if DEBUG + if( sys.m_test ){ + while(m_Wave.IsOutOpen() && !m_Wave.IsOutBufFull()){ + m_WaveFile.ReadWrite(m_wBuffer, m_BufferSize); + DoDem(); + if( !m_Wave.OutWrite(m_wBuffer) ){ + m_Wave.OutAbort(); + OpenSound(TRUE); + m_LostSoundTX = LOSTMSGTIME * int(SAMPFREQ) / m_BufferSize; + m_fShowMsg = TRUE; + } + } + if( m_fpTest ){ + while(!m_ModTest.m_Encode.IsBuffFull()){ + int c = fgetc(m_fpTest); + if( m_RxSet[0].m_MBCS.IsLead(BYTE(c)) ){ + c = c << 8; + c += fgetc(m_fpTest); + } + m_ModTest.m_Encode.PutChar(c); + if( feof(m_fpTest) ){ + rewind(m_fpTest); + } + } + } + } + else { +#endif + while(m_Wave.IsOutOpen() && !m_Wave.IsOutBufFull()){ + if( (m_WaveFile.m_mode == 1) && (!m_TX) ){ // Read func + m_WaveFile.ReadWrite(m_wBuffer, m_BufferSize); + DoDem(); + } + else { + DoMod(); + if( (sys.m_LoopBack == loopINTERNAL) ) DoDem(); + } + if( !m_Wave.OutWrite(m_wBuffer) ){ + m_Wave.OutAbort(); + OpenSound(TRUE); + m_LostSoundTX = LOSTMSGTIME * int(SAMPFREQ) / m_BufferSize; + m_fShowMsg = TRUE; + } + if( m_WaveFile.m_mode == 2 ){ // Write func + m_WaveFile.ReadWrite(m_wBuffer, m_BufferSize); + } + } +#if DEBUG + } +#endif + if( m_fReqRX ){ + if( m_fTone ){ + if( m_fReqRX == 1 ){ + m_ModFSK.m_OutVol = 0; + m_Wave.SetOutBCC(m_Wave.GetOutBC()); + m_fReqRX++; + SetTXCaption(); + } + else if( m_Wave.GetOutBCC() < 0 ){ + ToRX(); + } + } + else if( m_ModFSK.m_Encode.m_Idle && !m_Edit[m_SendingEdit].GetCharCount(TRUE) && m_Edit[m_SendingEdit].IsCursorLast() ){ + if( m_fReqRX == 1 ){ + m_fReqRX++; + SetTXCaption(); + if( KOAO->Checked && m_fSendChar ){ + m_ModFSK.m_Encode.PutChar('\r'); + m_ModFSK.m_Encode.PutChar('\n'); + } + else { + if( m_pCom ) m_pCom->SetMark(); + m_ModFSK.m_Encode.SetMark(); + m_Wave.SetOutBCC(m_Wave.GetOutBC()); + m_fReqRX++; + } + } + else if( m_fReqRX == 2 ){ + if( m_pCom ) m_pCom->SetMark(); + m_ModFSK.m_Encode.SetMark(); + m_Wave.SetOutBCC(m_Wave.GetOutBC()); + m_fReqRX++; + } + else if( m_Wave.GetOutBCC() < 0 ){ + if( !sys.m_bFSKOUT || !IsRTTY() || !m_pCom || m_pCom->m_QueueExtfsk.IsEmpty() ){ + ToRX(); + } + } + else { + m_ModFSK.m_OutVol = 0; + } + } + } + if( m_pPlayBox ) m_pPlayBox->UpdateItem(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoDem(double d) +{ + if( m_SkipTmg > 0 ){ + m_SkipTmg--; + return; + } + CRxSet *pRxSet = &m_RxSet[0]; + CDEMFSK *pDem = pRxSet->m_pDem; + int c; + if( pDem->Do(d, pRxSet->m_SQ, pRxSet->m_fATC ) ){ + while((c = pDem->GetData())!=-1){ + PutDumpChar(c, pRxSet, &m_Dump); + } + } + if( SBWave->Down ){ + BOOL fMFSK = pRxSet->IsMFSK(); + BOOL fQPSK = pRxSet->IsQPSK(); + if( m_WaveType ){ + m_Collect1.Do(pDem->GetS()); + m_Collect2.Do(pDem->m_d); + if( m_Collect1.IsFull() ){ + DrawWave(TRUE); + m_Collect1.Clear(); m_Collect2.Clear(); + m_Lock = FALSE; + } + } + else if(fMFSK || fQPSK){ + m_Collect1.Do(pDem->GetTmg()*16384); + if( fQPSK ){ + m_Collect2.Do(pDem->m_DecPSK.GetD()); + } + else { + m_Collect2.Do(pDem->GetS()); + } + if( m_Collect1.IsFull() ){ + DrawWave(TRUE); + m_Collect1.Clear(); m_Collect2.Clear(); + m_Lock = FALSE; + } + } + else { + if( pDem->GetTmgLock() && pDem->m_Lock ){ + m_Collect1.Do(pDem->GetTmg()*16384); + m_Collect2.Do(pDem->GetS()); + m_Lock = TRUE; + } + else if( m_Lock ){ + DrawWave(TRUE); + m_Collect1.Clear(); m_Collect2.Clear(); + m_Lock = FALSE; + } + } + } + if( m_fSubWindow ){ + pRxSet = &m_RxSet[1]; + for( int i = 1; i < RXMAX; i++, pRxSet++ ){ + pDem = pRxSet->m_pDem; + if( pRxSet->IsActive() ){ + if( pDem->Do(d, pRxSet->m_SQ, pRxSet->m_fATC ) ){ + while((c = pDem->GetData())!=-1){ + PutDumpChar(c, pRxSet, &pRxSet->m_pView->m_Dump); + } + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoDem(void) +{ + int i; + SHORT *wp = m_wBuffer; + +#if DEBUG + if( sys.m_test ){ + if( m_TestTimer ) m_TestTimer--; + for( i = 0; i < m_BufferSize; i++, wp++ ){ + if( !m_TestTimer ){ + if( sys.m_testCarrier1 ) *wp = SHORT(m_QSB.Do(m_ModTest.Do())); + if( sys.m_testCarrier2 ) *wp += SHORT(m_VCOTest.Do(0)*sys.m_testGain2); + } + else { + *wp = 0; + } + } + if( SAMPFREQ < 7000.0 ){ + AddGaussian(m_wBuffer, m_BufferSize, sys.m_testNoiseGain*0.5); + } + else { + AddGaussian(m_wBuffer, m_BufferSize, sys.m_testNoiseGain); + } + wp = m_wBuffer; + for( i = 0; i < m_BufferSize; i++, wp++ ){ + *wp = m_TestHPF.Do(*wp); + if( sys.m_test500 ) *wp = m_BPF500.Do(*wp); + } + wp = m_wBuffer; + } + if( m_pDebugButton ){ + ::PostMessage(Handle, WM_WAVE, waveRepeatMacro, DWORD(m_pDebugButton)); + m_pDebugButton = NULL; + } +#endif + double *dp = m_fftbuf; + BOOL fNOTCH = m_Notches.m_Count && (m_TX != txINTERNAL); + switch(SAMPTYPE){ + case 0: // 11025Hz + for( i = 0; i < m_BufferSize; i++, wp++ ){ + if( m_fHPF ) *wp = m_HPF.Do(*wp); + if( fNOTCH ) *wp = m_Notches.m_FIR.Do(*wp); + if( m_Dec2.Do(*wp) ){ + DoDem(m_Dec2.GetOut()); + } + *dp++ = *wp; + } + break; + case 1: // 8000Hz + case 2: // 6000Hz + for( i = 0; i < m_BufferSize; i++, wp++ ){ + if( m_fHPF ) *wp = m_HPF.Do(*wp); + if( fNOTCH ) *wp = m_Notches.m_FIR.Do(*wp); + DoDem(*wp); + *dp++ = *wp; + } + break; + default: +// // 16000Hz +// // 22050Hz +// 12000Hz +// 18000Hz +// 24000Hz +// 44100Hz +// 48000Hz +// 50000Hz + for( i = 0; i < m_BufferSize; i++, wp++ ){ + if( m_fHPF ) *wp = m_HPF.Do(*wp); + if( m_Dec2.Do(*wp) ){ + if( fNOTCH ) m_Dec2.SetOut(m_Notches.m_FIR.Do(m_Dec2.GetOut())); + DoDem(m_Dec2.GetOut()); + *dp++ = m_Dec2.GetOut(); + } + } + break; + } + try { + m_FFT.Calc(m_fftbuf, 3001 * FFT_SIZE / m_FFTSampFreq, m_fftSC * 10.0, m_FFTSmooth, m_fftout); + } + catch(...){ + m_FFT.InitFFT(); + m_FFT.m_FFTDIS = 0; + } + for( i = 0; i < RXMAX; i++ ){ + CalcStgFFT(&m_RxSet[i]); + } + if( SBFFT->Down ){ + DrawFFT(TRUE); + } + else if( SBWater->Down ){ + DrawWater(TRUE, FALSE); + } + DrawLevel(TRUE); + DrawPF(TRUE); + +#if MEASIMD + m_RxSet[0].m_pDem->CalcIMD(); +#endif + + m_fDisEvent++; + if( m_TX != txINTERNAL ){ + if( m_AFCKeyTimer ){ + m_AFCKeyTimer--; + } + else if( SBAFC->Down ){ + UdRxCarrier->Position = short(m_RxSet[0].m_pDem->m_CarrierFreq+0.5); + if( m_pRadio ) m_pRadio->SetCarrierFreq(UdRxCarrier->Position); +#if 0 + if( !m_TX && SBNET->Down ){ + UdTxCarrier->Position = UdRxCarrier->Position; + } +#endif + m_RxSet[0].m_pDem->UpdateBPF(); + } + if( IsRTTY() ){ + if( m_RxSet[0].m_pDem->m_Decode.IsRTTYTmg() ){ + sprintf(m_TextBuff, "%.2lf", m_RxSet[0].m_pDem->m_Decode.GetRTTYTmg()); + EATC->Text = m_TextBuff; + } + else { + EATC->Text = "***"; + } + } + else if( m_RxSet[0].IsMFSK() ){ + sprintf(m_TextBuff, "%d", m_RxSet[0].m_pDem->GetClockError()); + EATC->Text = m_TextBuff; + } + else if( SBATC->Down ){ + int d = m_RxSet[0].m_pDem->GetClockError(); + EATC->Text = d; + } + } + m_fDisEvent--; + +// StatusBar->Panels->Items[statusSYNC]->Text = (m_RxSet[0].m_SQ && m_RxSet[0].m_pDem->m_Decode.GetSyncState()) ? "SYNC" : ""; + + if( m_fSubWindow ){ + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ){ + pRxSet->m_pDem->UpdateBPF(); + pRxSet->m_pView->UpdateStatus(); + } + } + } + if( m_fHintUpdate ){ + DrawHint(); + } + if( m_pClockView ){ + wp = m_wBuffer; + for( i = 0; i < m_BufferSize; i++ ){ + m_pClockView->Do(*wp++); + } + m_pClockView->UpdateFFT(); + } +#if DEBUG && 0 + + sprintf(m_TextBuff, "%9.1lf, %9.4lf, %4u", + m_RxSet[0].m_pDem->m_RxFreq, + m_RxSet[0].m_pDem->m_out, + m_RxSet[0].m_AFCFQ, + ); + Caption = m_TextBuff; +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoMod(void) +{ + if( m_fpText ){ + while(m_Edit[m_CurrentEdit].GetCharCount(TRUE) < int(16 * m_RxSet[0].GetSpeed() / 31.25) ){ +#if 1 + int c = 0; + int len = fread(&c, 1, 1, m_fpText); + if( len <= 0 ){ + fclose(m_fpText); m_fpText = NULL; + break; + } + if( m_RxSet[0].m_MBCS.IsLead(BYTE(c)) ){ + c = c << 8; + int len = fread(&c, 1, 1, m_fpText); + if( len <= 0 ){ + fclose(m_fpText); m_fpText = NULL; + break; + } + } + m_Edit[m_CurrentEdit].PutChar(c, 1); +#else + int c = fgetc(m_fpText); + if( m_RxSet[0].m_MBCS.IsLead(BYTE(c)) ){ + c = c << 8; + c += fgetc(m_fpText); + } + m_Edit[m_CurrentEdit].PutChar(c, 1); + if( feof(m_fpText) ){ + fclose(m_fpText); + m_fpText = NULL; + } +#endif + } + } + + int i; + SHORT *wp = m_wBuffer; + if( m_fTone ){ + for( i = 0; i < m_BufferSize; i++, wp++ ){ + *wp = SHORT(m_ModFSK.DoCarrier()*m_ModGainR); + } + } + else { + for( i = 0; i < m_BufferSize; i++, wp++ ){ + *wp = SHORT(m_ModFSK.Do()*m_ModGainR); + } + } +} +//--------------------------------------------------------------------------- +//Added by JA7UDE on April 5, 2010 +int MungeBits( int r ) +{ + int oc = 0; + if( r & 0x00000010 ) + oc += 0x01; + if( r & 0x00000008 ) + oc += 0x02; + if( r & 0x00000004 ) + oc += 0x04; + if( r & 0x00000002 ) + oc += 0x08; + if( r & 0x00000001 ) + oc += 0x10; + return (int)oc; +} +void __fastcall TMainVARI::ExtFskIt( int r ) +{ + if( m_pCom && m_pCom->m_bFSKOUT && IsRTTY() ) m_pCom->m_QueueExtfsk.Push( (BYTE)MungeBits(r) ); +} +//Till here +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PutDumpChar(int d, CRxSet *pRxSet, CDump *pDump) +{ + if( pRxSet->IsRTTY() ){ + if( d ) pDump->PutChar(d, m_TX ? 2 : 1); + } + else { + int m; + if( pRxSet->IsMFSK() ){ + m = d; + } + else { + m = g_VariCode.Index2Mbcs(d, (pRxSet->m_fJA && !pRxSet->m_fTWO)); + } + if( pRxSet->m_fTWO ){ + if( (m >= 0) && (m < 256) ){ + if( pRxSet->m_fMBCS ){ + m |= pRxSet->m_fMBCS; + pRxSet->m_fMBCS = 0; + } + else if( pRxSet->m_MBCS.IsLead(BYTE(m)) ){ + pRxSet->m_fMBCS = (m << 8); + } + if( !pRxSet->m_fMBCS ) pDump->PutChar(m, m_TX ? 2 : 1); + } + } + else { + pDump->PutChar(m, m_TX ? 2 : 1); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitStgFFT(FFTSTG *pStg) +{ + if( m_FFT.m_FFTGain ){ + pStg->Sum = 1024; + pStg->Max = 1024; + pStg->WMax = 1024; + } + else { + pStg->Sum = 5000; + pStg->Max = 5000; + pStg->WMax = 5000; + } + pStg->Sig = 0; +} +//--------------------------------------------------------------------------- +double __fastcall TMainVARI::SqrtToDB(double d) +{ + d /= (0.00345 * 10.0 * m_fftSC); + d = d * d; + d = d * d; + return m_fftSC * 10.0 * (log10(d+2.81458e4) - 4.4494132); +} +//--------------------------------------------------------------------------- +double __fastcall TMainVARI::DBToSqrt(double d) +{ + d /= m_fftSC * 10.0; + d += 4.4494132; + d = pow(10, d) - 2.81458e4; + d = pow(d, 0.25); + return d * (0.00345 * 10.0 * m_fftSC); +} +//--------------------------------------------------------------------------- +double __fastcall TMainVARI::AdjDB(double d) +{ + if( m_FFT.m_FFTGain ){ + return SqrtToDB(d); + } + else { + return d * 100.0 / m_fftSC; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CalcStgFFT(CRxSet *pRxSet) +{ + if( !pRxSet->IsActive() ) return; + + CDEMFSK *pDem = pRxSet->m_pDem; + int fo = pDem->m_CarrierFreq; + + int fm, xl, xh, xnl, xnh, xol, xoh; + switch(pRxSet->m_Mode){ + case MODE_GMSK: + fm = pRxSet->m_Speed * 2 + 100; + xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + xnl = (fo - pRxSet->m_Speed*1.6) * FFT_SIZE / m_FFTSampFreq; + xnh = (fo + pRxSet->m_Speed*1.6) * FFT_SIZE / m_FFTSampFreq; + xol = (fo - pRxSet->m_Speed/4) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + pRxSet->m_Speed/4) * FFT_SIZE / m_FFTSampFreq; + break; + case MODE_FSK: + fm = pRxSet->m_Speed * 4 + 100; + xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + xnl = (fo - pRxSet->m_Speed*3.2) * FFT_SIZE / m_FFTSampFreq; + xnh = (fo + pRxSet->m_Speed*3.2) * FFT_SIZE / m_FFTSampFreq; + xol = (fo - pRxSet->m_Speed/2) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + pRxSet->m_Speed/2) * FFT_SIZE / m_FFTSampFreq; + break; + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + fm = pRxSet->m_Speed * 2 + 100; + xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + xnl = (fo - pRxSet->m_Speed*1.6) * FFT_SIZE / m_FFTSampFreq; + xnh = (fo + pRxSet->m_Speed*1.6) * FFT_SIZE / m_FFTSampFreq; + xol = (fo - pRxSet->m_Speed*0.6) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + pRxSet->m_Speed*0.6) * FFT_SIZE / m_FFTSampFreq; + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: +#if 1 + fm = (pRxSet->m_pDem->m_RTTYShift * 0.5) + 150; + if( fm > 1500 ) fm = 1500; + xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + xnl = xl; + xnh = xh; + fm = (pRxSet->m_pDem->m_RTTYShift * 0.5) + 15; + xol = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; +#else + fm = (pRxSet->m_pDem->m_RTTYShift * 500)/170; + if( fm > 1500 ) fm = 1500; + xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + xnl = (fo - (fm/2)) * FFT_SIZE / m_FFTSampFreq; + xnh = (fo + (fm/2)) * FFT_SIZE / m_FFTSampFreq; + fm = (pRxSet->m_pDem->m_RTTYShift * 0.5) + 15; + xol = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; +#endif + break; + case MODE_mfsk_L: + fm = pRxSet->m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + xl = (fo - fm/2 - 150) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm/2 + 150) * FFT_SIZE / m_FFTSampFreq; + xnl = xl; + xnh = xh; + xol = (fo - fm/2 - 15) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + fm/2 + 15) * FFT_SIZE / m_FFTSampFreq; + } + else { + xl = (fo - fm - 150) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + 150) * FFT_SIZE / m_FFTSampFreq; + xnl = xl; + xnh = xh; + xol = (fo - fm - 15) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + 15) * FFT_SIZE / m_FFTSampFreq; + } + break; + case MODE_mfsk_U: + fm = pRxSet->m_pDem->m_MFSK_BW; + if( sys.m_MFSK_Center ){ + xl = (fo - fm/2 - 150) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm/2 + 150) * FFT_SIZE / m_FFTSampFreq; + xnl = xl; + xnh = xh; + xol = (fo - fm/2 - 15) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + fm/2 + 15) * FFT_SIZE / m_FFTSampFreq; + } + else { + xl = (fo - 150) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + fm + 150) * FFT_SIZE / m_FFTSampFreq; + xnl = xl; + xnh = xh; + xol = (fo - 15) * FFT_SIZE / m_FFTSampFreq; + xoh = (fo + fm + 15) * FFT_SIZE / m_FFTSampFreq; + } + break; + } + fm = 200 * FFT_SIZE / m_FFTSampFreq; + if( xl < fm ) xl = fm; + if( xol == xoh ){xol--; xoh++;} + if( xol < fm ) xol = fm; + + int i, y; + int sum = 0; + int sumn = 0; + int max = 0; + int wmax = 0; + int m = 0; + int n = 0; + for( i = xl; i < xh; i++ ){ + y = m_fftout[i]; + if( max < y ) max = y; + if( (i >= xol) && (i <= xoh) ){ + if( wmax < y ) wmax = y; + } + else if( (i >= xnl) && (i <= xnh) ){ + sumn += y; + n++; + } + else { + sum += y; + m++; + } + } + if( m ) sum /= m; + if( n ) sumn /= n; + if( !m || (sumn < sum) ) sum = sumn; + pRxSet->m_StgFFT.Sum = (pRxSet->m_StgFFT.Sum + sum) / 2; + pRxSet->m_StgFFT.Max = (pRxSet->m_StgFFT.Max + max) / 2; + pRxSet->m_StgFFT.WMax = (pRxSet->m_StgFFT.WMax + wmax) / 2; + if( m_FFT.m_FFTGain ){ + pRxSet->m_StgFFT.dBSum = SqrtToDB(pRxSet->m_StgFFT.Sum); + pRxSet->m_StgFFT.dBMax = SqrtToDB(pRxSet->m_StgFFT.Max); + pRxSet->m_StgFFT.dBWMax = SqrtToDB(pRxSet->m_StgFFT.WMax); + if( m_TX == txINTERNAL ) pRxSet->m_StgFFT.dBSum = 0; + } + else { + double k = 100.0 / m_fftSC; + pRxSet->m_StgFFT.dBSum = pRxSet->m_StgFFT.Sum * k; + pRxSet->m_StgFFT.dBMax = pRxSet->m_StgFFT.Max * k; + pRxSet->m_StgFFT.dBWMax = pRxSet->m_StgFFT.WMax * k; + if( m_TX == txINTERNAL ) pRxSet->m_StgFFT.dBSum = -200; + } + + BOOL fMFSKMet = FALSE; + int d = pRxSet->m_StgFFT.Sig - 500; + if( d > LEVELMAX ) d = LEVELMAX; + int sq = pRxSet->m_SQ; + if( (m_TX != txINTERNAL) && pRxSet->IsMFSK() && sys.m_MFSK_SQ_Metric ){ + pRxSet->m_SQ = (pRxSet->m_pDem->GetMFSKMetric(0)) >= pRxSet->m_SQLevel; + } + else { + if( pRxSet->m_pDem->IsMFSKSQ() && (d < pRxSet->m_SQLevel) ){ + fMFSKMet = TRUE; + pRxSet->m_SQ = TRUE; + } + else { + pRxSet->m_SQ = (d >= pRxSet->m_SQLevel); + } + if( pRxSet->m_SQLevel < 50 ) pRxSet->m_SQ = TRUE; + } + if( pRxSet->m_SQ ){ + pRxSet->m_SQTimer++; + if( !sq ){ + pRxSet->m_pDem->m_AFCCount = 0; + pRxSet->m_pDem->m_Decode.m_BAUDOT.ClearRX(); + pRxSet->m_fMBCS = 0; + if( !m_TX ){ + if( sys.m_fAutoTS && (!pRxSet->m_cAutoTS1 || !pRxSet->m_cAutoTS2) ){ + RxStatus(pRxSet, "SON"); + } + pRxSet->m_PeakSig = 0; + pRxSet->m_AvgSig.Create(32); + } + } + if( m_TX ){ + pRxSet->m_cAutoTS1 = -5 * SAMPFREQ/m_BufferSize; + } + else if( pRxSet->m_cAutoTS1 >= 0 ){ + pRxSet->m_cAutoTS1 = 10 * SAMPFREQ/m_BufferSize; + } + } + else { + pRxSet->m_SQTimer = 0; + if( pRxSet->m_cAutoTS1 ){ + if( pRxSet->m_cAutoTS1 > 0 ){ + pRxSet->m_cAutoTS1--; + if( sys.m_fAutoTS && !pRxSet->m_cAutoTS1 ){ + RxStatus(pRxSet, "SOFF"); + } + } + else { + pRxSet->m_cAutoTS1++; + } + } + } + if( pRxSet->m_cAutoTS2 ) pRxSet->m_cAutoTS2--; + + if( pRxSet->m_AFCTimerN ){ + pRxSet->m_AFCTimerN--; + pRxSet->m_pDem->m_fEnableAFC = FALSE; + } + else if( pRxSet->Is170() ){ + pRxSet->m_pDem->m_fEnableAFC = pRxSet->m_SQ && (pRxSet->m_SQTimer > 4) && (pRxSet->m_StgFFT.Sig >= (600+500)); + } + else { + pRxSet->m_pDem->m_fEnableAFC = pRxSet->m_SQ; + } + + if( pRxSet->m_StgFFT.Timer ){ + pRxSet->m_StgFFT.Timer--; + return; + } + else { + pRxSet->m_StgFFT.Sig = (pRxSet->m_StgFFT.dBWMax - pRxSet->m_StgFFT.dBSum); + pRxSet->m_fATC = (pRxSet->m_StgFFT.Sig >= ((m_ATCLevel*100)+300)); + m = pRxSet->Is170() ? (1700+300) : (2000+300); + pRxSet->m_pDem->m_Decode.SetMeasClock((pRxSet->m_StgFFT.Sig >= m)); + pRxSet->m_pDem->m_DecPSK.SetSN(pRxSet->m_StgFFT.Sig); + } + + // 広域AFCの動作 + BOOL fAFC = pRxSet->m_pDem->m_fAFC && m_AFCWidth && (m_TX != txINTERNAL); + if( fAFC ){ + switch(pRxSet->m_Mode){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + case MODE_GMSK: + sq = (pRxSet->m_SQTimer >= 8) ? pRxSet->m_AFCSQ : (d >= pRxSet->m_StgFFT.dBMax/3); + break; + case MODE_FSKW: + case MODE_FSK: + sq = (pRxSet->m_SQTimer >= 32) ? pRxSet->m_AFCSQ : (d >= pRxSet->m_StgFFT.dBMax/2); + break; + case MODE_RTTY: + case MODE_U_RTTY: + sq = (pRxSet->m_SQTimer >= 32) ? pRxSet->m_AFCSQ : (d >= pRxSet->m_StgFFT.dBMax/2); + break; + case MODE_mfsk_L: + case MODE_mfsk_U: + sq = (pRxSet->m_SQTimer >= 8) ? pRxSet->m_AFCSQ : (d >= pRxSet->m_StgFFT.dBMax/2); + break; + } + if( !sq ){ + if( (m_AFCWidth > 50) && !pRxSet->IsMFSK() ){ + xl = (fo - m_AFCWidth) * FFT_SIZE / m_FFTSampFreq; + xh = (fo + m_AFCWidth) * FFT_SIZE / m_FFTSampFreq; + int o = (xh + xl)/2; + int m = (xh - xl)/2; + int rmax = 0; + int lmax = 0; + int rc = 0; + int lc = 0; + int lm = 200 * FFT_SIZE / m_FFTSampFreq; + for( i = 1; i < m; i++ ){ + if( (o - i) > lm ){ + y = m_fftout[o-i]; + if( y > lmax ){ + lc = i; + lmax = y; + } + } + y = m_fftout[o+i]; + if( y > rmax ){ + rc = i; + rmax = y; + } + } + int th = ((m_AFCLevel*100) + 450); + if( pRxSet->IsMFSK() && (th < 1650) ) th = 1650; + lmax = AdjDB(lmax) - pRxSet->m_StgFFT.dBSum; + rmax = AdjDB(rmax) - pRxSet->m_StgFFT.dBSum; + if( pRxSet->IsRTTY() ){ + if( (lmax > th) && (rmax > th) ){ + o += (rc - lc); + } + else if( !sq ){ + if( lmax > th ){ + o -= lc; + } + else if( rmax > th ){ + o += rc; + } + else { + o = 0; + } + } + else { + o = 0; + } + } + else if( (lmax > th) && (rmax > th) ){ + if( (rc + lc) < 10 ){ + if( rmax > lmax ){ + o += rc; + } + else { + o -= lc; + } + } + else { + if( rc < lc ){ + o += rc; + } + else { + o -= lc; + } + } + } + else if( lmax > th ){ + o -= lc; + } + else if( rmax > th ){ + o += rc; + } + else { + o = 0; + } + if( o ){ + int fq = o * m_FFTSampFreq / FFT_SIZE; + o = fq - fo; + m = ABS(o); + if( m < m_AFCWidth ){ + int diff; + BOOL bPSK = FALSE; + switch(pRxSet->m_Mode){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + bPSK = TRUE; + diff = pRxSet->m_Speed*1.2; + break; + case MODE_GMSK: + diff = pRxSet->m_Speed; + break; + case MODE_FSK: + diff = pRxSet->m_Speed*2; + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + diff = pRxSet->m_pDem->m_RTTYShift; + break; + case MODE_mfsk_L: + if( !sys.m_MFSK_Center ) fq += pRxSet->m_pDem->m_MFSK_BW/2; + diff = pRxSet->m_pDem->m_MFSK_BW*1.5; + break; + case MODE_mfsk_U: + if( !sys.m_MFSK_Center ) fq -= pRxSet->m_pDem->m_MFSK_BW/2; + diff = pRxSet->m_pDem->m_MFSK_BW*1.5; + break; + } + if( !pRxSet->m_AFCTimerW && (pRxSet->m_AFCTimerW2 > 8) && + (ABS(pRxSet->m_AFCFQ - fq) < diff) + ){ + if( (m < 30) || (bPSK && (m < 50)) || (pRxSet->IsRTTY() && (m < 220)) ){ + fo = GetSignalFreq(fo+o, 50, pRxSet); + o = 0; + } + else if( m < 80 ){ + o /= 3; + } + else if( m < 160 ){ + o /= 8; + } + else { + o /= 10; + } + pDem->SetCarrierFreq(fo + o); + } + pRxSet->m_AFCTimerW2++; +// pRxSet->m_AFCFQ = (pRxSet->m_AFCFQ + (fq * 2)) / 3; + pRxSet->m_AFCFQ = pRxSet->m_AvgAFC.DoZ(fq); + } + } + else { + pRxSet->m_AFCTimerW2 -= pRxSet->IsRTTY() ? 3 : 2; + if( pRxSet->m_AFCTimerW2 < 0 ) pRxSet->m_AFCTimerW2 = 0; + } + } + else { + pRxSet->m_AFCFQ = fo; + } + } + else if( pRxSet->IsMFSK() ){ + if( !fMFSKMet ){ + DoAFCMFSK(pRxSet, fo, TRUE); + } + } + else { + double bw = pRxSet->GetBandWidth(); + if( bw > 25.0 ){ + fm = GetSignalFreq(fo, bw*0.75, pRxSet, pRxSet->m_SQ ? 600 : (m_AFCLevel*100)+450); + pRxSet->m_AFCFQ = pRxSet->m_AvgAFC.DoZ(fm); + if( pRxSet->m_SQ ){ + m = ABS(fo - pRxSet->m_AFCFQ); + fm = bw * 0.5; + if( fm < m_AFCWidth ) fm = m_AFCWidth; + if( (m >= int(bw*0.2)) && (m < fm) ){ + pRxSet->m_AFCTimerPSK++; + if( pRxSet->m_AFCTimerPSK >= UINT(IsBPSK() ? 6 : 8) ){ + fm = (pRxSet->m_AFCFQ - fo)*0.75; + pDem->SetCarrierFreq(fo+fm); + } + } + else { + pRxSet->m_AFCTimerPSK = 0; + } + } + } + } + } + else if( pRxSet->IsMFSK() ){ + DoAFCMFSK(pRxSet, fo, FALSE); + } + else { + double bw = pRxSet->GetBandWidth(); + fm = GetSignalFreq(fo, bw*0.75, pRxSet, pRxSet->m_SQ ? 600 : (m_AFCLevel*100)+450); + pRxSet->m_AFCFQ = pRxSet->m_AvgAFC.DoZ(fm); + } + pRxSet->m_AFCSQ = pRxSet->m_SQ; + if( pRxSet->m_SQ ){ + pRxSet->m_AFCTimerW = 3 * SAMPFREQ / m_BufferSize; + } + else if( pRxSet->m_AFCTimerW ){ + pRxSet->m_AFCTimerW--; + pRxSet->m_AFCTimerW2 = 0; + } + sum = int((pRxSet->m_StgFFT.Sig-500)*0.01); + if( m_TX != txINTERNAL ){ + if( m_FFT.m_FFTGain ){ + if( sum >= 38 ){ + sum += (sum - 38) * 1.75; + } + } + else { + if( sum >= 32 ){ + sum += (sum - 32) * 0.357; + } + } + } + if( sum < 0 ) sum = 0; + if( sum > 96 ) sum = 96; + pRxSet->m_StgFFT.DispSig = sum; + if( pRxSet == &m_RxSet[0] ){ + sprintf(m_TextBuff, "S/N=%ddB", sum); + DrawStatus(statusSN, m_TextBuff); + } + if( !m_TX ){ + if( pRxSet->m_PeakSig < sum ) pRxSet->m_PeakSig = sum; + if( pRxSet->m_SQ ) pRxSet->m_AvgSig.Do(sum); + } +} +//--------------------------------------------------------------------------- +#define MFSKAFC_1stATACK (8*11025/2048) // 最初の8秒は範囲広い +#define MFSKAFC_2ndATACK (30*11025/2048) // 30秒経過後は範囲狭い +#define MFSKAFC_MAX (60*11025/2048) +void __fastcall TMainVARI::DoAFCMFSK(CRxSet *pRxSet, int fo, BOOL fUpdate) +{ + if( !m_AFCWidth ) return; + + int bw; + int xl, xh, x, xx; + CDEMFSK *pDem = pRxSet->m_pDem; + + if( sys.m_MFSK_Center ){ + bw = (pDem->m_MFSK_BW*0.5) + 0.5; + xl = fo - bw; + xh = fo + bw; + } + else { + bw = pDem->m_MFSK_BW + 0.5; + if( pRxSet->m_Mode == MODE_mfsk_U ){ + xl = fo; xh = fo + bw; + } + else { + xl = fo - bw; xh = fo; + } + } + xl = int((xl * FFT_SIZE / m_FFTSampFreq)); + xh = int((xh * FFT_SIZE / m_FFTSampFreq) + 0.5); + int f; + if( pRxSet->m_AFCTimerMFSK < MFSKAFC_2ndATACK ){ + if( pRxSet->m_AFCTimerMFSK < MFSKAFC_1stATACK ){ + f = m_AFCWidth; + if( f >= 32 ) f = 32; + } + else { + f = pDem->m_MFSK_SPEED; + } + f = f * FFT_SIZE / m_FFTSampFreq; + xl -= f; xh += f; + } + else { + if( pDem->m_MFSK_TONES == 8 ){ + xl-=2; xh+=2; + } + else { + xl--; xh++; + } + } + + if( pRxSet->m_AFCTimerMFSK < MFSKAFC_MAX ){ + pRxSet->m_AFCTimerMFSK++; + if( pDem->GetMFSKMetric(0) >= 800 ){ + pRxSet->m_AFCTimerMFSK+=8; + } + } + + int d; + int avg = 0; + int max = 0; + xx = xl; + for( x = xl; x <= xh; x++ ){ + d = m_fftout[x]; + avg += d; + if( max < d ){ + max = d; + xx = x; + } + } + avg /= (xh - xl); + int maxdb, avgdb; + if( m_FFT.m_FFTGain ){ + avgdb = SqrtToDB(avg); + maxdb = SqrtToDB(max); + } + else { + double k = 100.0 / m_fftSC; + avgdb = avg * k; + maxdb = max * k; + } + if( (maxdb - avgdb) < 750 ) return; + + xl = m_fftout[xx] - m_fftout[xx-1]; + xh = m_fftout[xx] - m_fftout[xx+1]; + if( (xl > 0) && (xh > 0) ){ // FFT間隔補正 + double off = double(xl - xh) * 0.5 / double(xl + xh); + x = ((xx + off) * m_FFTSampFreq / FFT_SIZE) + 0.5; +// sprintf(m_TextBuff, "%u", x); +// Caption = m_TextBuff; + } + else { + x = (xx * m_FFTSampFreq / FFT_SIZE) + 0.5; + } + f = 0; + if( sys.m_MFSK_Center ){ + if( x < (fo - bw) ){ + f = x + bw; + } + else if( x > (fo + bw) ){ + f = x - bw; + } + } + else if( pRxSet->m_Mode == MODE_mfsk_U ){ + if( x < fo ){ + f = x; + } + else if( x > (fo + bw) ){ + f = x - bw; + } + } + else { + if( x < (fo - bw) ){ + f = x + bw; + } + else if( x > fo ){ + f = x; + } + } + double fq; + if( pDem->m_pMFSK->GetAFCShift(fq) ){ +#if 0 + static int Cnt = 0; + char bf[256]; + sprintf(bf, "%.1lf (%d)", fq, Cnt++); + Application->MainForm->Caption = bf; +#endif + fq += pDem->m_CarrierFreq; + pRxSet->m_AvgAFC.Do(fq); + pRxSet->m_AFCFQ = pRxSet->m_AvgAFC.Do(fq) + 0.5; + pDem->m_RxFreq = pRxSet->m_AFCFQ; + if( fUpdate ){ + if( pRxSet->m_AFCFQ != int(pDem->m_CarrierFreq) ){ + pDem->SetCarrierFreq(pRxSet->m_AFCFQ); + } + } + } + else if( f ){ + pRxSet->m_AFCFQ = pRxSet->m_AvgAFC.Do(f)+0.5; + pDem->m_RxFreq = pRxSet->m_AFCFQ; + if( fUpdate ){ + if( pRxSet->m_AFCFQ != int(pDem->m_CarrierFreq) ){ + pDem->SetCarrierFreq(pRxSet->m_AFCFQ); + } + } + else { + pRxSet->m_AFCTimerMFSK = 0; + } + } + else if( !fUpdate ){ + DoAvg(pDem->m_RxFreq, fo, (pRxSet->m_AFCTimerMFSK >= (15*4)) ? 0.1 : 0.005); + pRxSet->m_AvgAFC.Do(pDem->m_RxFreq); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxRXPaint(TObject *Sender) +{ + m_Dump.Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxTXPaint(TObject *Sender) +{ + m_Edit[m_CurrentEdit].Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::AttachFocus(void) +{ + SetTXFocus(); + m_Edit[m_CurrentEdit].CreateCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DettachFocus(void) +{ + m_Edit[m_CurrentEdit].DestroyCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormActivate(TObject *Sender) +{ + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormDeactivate(TObject *Sender) +{ + DettachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PCTXEnter(TObject *Sender) +{ + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PCTXExit(TObject *Sender) +{ + DettachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxTXClick(TObject *Sender) +{ + DeleteMacroTimer(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnChar(int Key) +{ + CDump *pEdit = &m_Edit[m_CurrentEdit]; + if( m_TX ){ + if( Key == '\b' ){ + if( !pEdit->CanEdit() ) return; + if( !pEdit->GetCharCount(TRUE) && pEdit->GetCharCount(FALSE) ){ + if( IsRTTY() ){ + Key = 'X'; + } + else { + m_ModFSK.m_Encode.PutChar(Key); + } + } + } + } + if( Key >= 0x8140 ){ + pEdit->PutChar(Key, 1); + } + else { + if( IsRTTY() ) Key = toupper(Key); + pEdit->PutKey(char(Key), 1); + } + if( m_TX && (m_fReqRX == 1) ){ + m_fReqRX = 0; + m_ModFSK.m_Encode.m_fReqRX = FALSE; + SetTXCaption(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormKeyPress(TObject *Sender, char &Key) +{ +#if !KEY_DIRECT + if( ActiveControl == PCTX ){ + OnChar(Key & 0x00ff); + } +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateWaveCaption(void) +{ + SBWave->Caption = m_WaveType ? "Wav.":"Sync"; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTXCaption(void) +{ + if( m_fReqRX ){ + SBTX->Caption = m_fReqRX > 1 ? "Wait" : "ReqRX"; + } + else if( m_fTone ){ + SBTX->Caption = "TONE"; + } + else { + AnsiString as = m_TX ? "RX" : "TX"; + LPCSTR pKey = GetKeyName(sys.m_DefKey[kkTX]); + if( *pKey && (strlen(pKey) < 5) ){ + sprintf(m_TextBuff, "(%s)", pKey); + as += m_TextBuff; + } + SBTX->Caption = as; + } + + AnsiString as = "TXOFF"; + LPCSTR pKey = GetKeyName(sys.m_DefKey[kkTXOFF]); + if( *pKey && (strlen(pKey) < 3) ){ + sprintf(m_TextBuff, "(%s)", pKey); + as += m_TextBuff; + } + SBTXOFF->Caption = as; + +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetPTT(BOOL fTX) +{ + if( m_pCom ) m_pCom->SetPTT(fTX); + if( m_pRadio ){ + if( fTX ) WaitICOM(); + m_pRadio->SetPTT(fTX); + } + m_Wave.SetPTT(fTX); + LogLink.SetPTT(fTX); + DoEvent(macOnPTT); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::RxStatus(CRxSet *pRxSet, LPCSTR p) +{ + CDump *pDump; + if( pRxSet == &m_RxSet[0] ){ + pDump = &m_Dump; + } + else if( pRxSet->m_pView ){ + pDump = &pRxSet->m_pView->m_Dump; + } + else { + return; + } + if( m_StatusUTC ){ + ::GetUTC(&m_LocalTime); + } + else { + ::GetLocal(&m_LocalTime); + } + pDump->PutStatus(3, "[%s %u/%u/%u %02u:%02u:%02u]\r", + p, + m_LocalTime.wYear, + m_LocalTime.wMonth, + m_LocalTime.wDay, + m_LocalTime.wHour, + m_LocalTime.wMinute, + m_LocalTime.wSecond + ); + pRxSet->m_cAutoTS2 = 600 * SAMPFREQ/m_BufferSize; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTXInternal(void) +{ + if( sys.m_LoopBack == loopINTERNAL ){ + m_RxSet[0].SetCarrierFreq(UdTxCarrier->Position * SAMPFREQ/(SAMPFREQ+SAMPTXOFFSET)); + CRxSet *pRxSet = m_RxSet; + for( int i = 0; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ){ + if( i ){ + pRxSet->SetSampleFreq((SAMPFREQ+SAMPTXOFFSET)*m_DecFactor); + if( pRxSet->m_fAFC ){ + int f = pRxSet->m_pDem->m_CarrierFreq - UdTxCarrier->Position; + f = ABS(f); + if( f < (pRxSet->m_Speed * 0.5) ) pRxSet->SetCarrierFreq(UdTxCarrier->Position); + } + } + pRxSet->m_pDem->MakeBPF(8); // CPU負荷低減のため + pRxSet->m_pDem->m_Decode.m_fATC = FALSE; + pRxSet->m_pDem->m_DecPSK.m_bATC = FALSE; + pRxSet->m_pDem->m_fAFC = FALSE; + pRxSet->m_pDem->m_Decode.Create(); +// pRxSet->m_pDem->m_Decode.SetTmg(i ? 0 : 1e6*((SAMPFREQ+SAMPTXOFFSET)/SAMPFREQ - 1.0)); + pRxSet->m_pDem->SetTmg(i ? 0 : 1e6*((SAMPFREQ+SAMPTXOFFSET)/SAMPFREQ - 1.0)); + pRxSet->m_pDem->m_AGC.Reset(); +// pRxSet->m_PeakSig = 0; +// pRxSet->m_AvgSig.Create(32); + for( int j = 0; j < m_BufferSize; j++ ){ + pRxSet->m_pDem->Do(0); + } + pRxSet->InitStgFFT(); + } + } + FFTSampleFreq(SAMPFREQ + SAMPTXOFFSET); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ToTone(void) +{ + if( m_fSuspend ) return; + if( !SBTX->Enabled ) return; + m_fTone = TRUE; + SBTX->Down = TRUE; + m_TX = (sys.m_LoopBack == loopINTERNAL) ? txINTERNAL : txEXTERNAL; + if( sys.m_LoopBack == loopINTERNAL ){ + m_Wave.InClose(); + DeleteSoundTimer(); + } + if( SBNET->Down ){ + m_fDisEvent++; + UdTxCarrier->Position = UdRxCarrier->Position; + m_fDisEvent--; + } + m_ModFSK.Reset(); // For Signal/CW gain + m_ModFSK.SetCarrierFreq(UdTxCarrier->Position); + SetTXInternal(); + m_fSendChar = FALSE; + m_Wave.m_hWnd = Handle; + InitWater(iniwMETRIC); + if( !m_Wave.IsOutOpen() ) OpenSound(TRUE); + memset(m_wBuffer, 0, sizeof(m_wBuffer)); + if( m_pCom ){ + m_pCom->SetSendChar(FALSE); + } + SetPTT(TRUE); + SetTXCaption(); + RxStatus(&m_RxSet[0], "TX"); + if( m_Wave.IsOutFirst() ){ + while(!m_Wave.IsOutBufFull()){ + DoMod(); + if( sys.m_LoopBack == loopINTERNAL ) DoDem(); + m_Wave.OutWrite(m_wBuffer); + } + } + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ToTX(void) +{ +#if DEBUG + if( m_fpTest ){ + fclose(m_fpTest); + m_fpTest = NULL; + } + if( sys.m_test ){ + m_Wave.OutAbort(); + sys.m_test = FALSE; + } +#endif + if( m_fSuspend ) return; + if( !SBTX->Enabled ) return; + StopPlayBack(); + m_SendingEdit = m_CurrentEdit; + BOOL fATone = m_fTone; + m_fTone = FALSE; + SBTX->Down = TRUE; + m_TX = (sys.m_LoopBack == loopINTERNAL) ? txINTERNAL : txEXTERNAL; + if( sys.m_LoopBack == loopINTERNAL ){ + m_Wave.InClose(); + DeleteSoundTimer(); + } + if( SBNET->Down ){ + m_fDisEvent++; + UdTxCarrier->Position = UdRxCarrier->Position; + m_fDisEvent--; + } + CDump *pEdit = &m_Edit[m_CurrentEdit]; + BOOL fCW = (pEdit->GetCharNB() & 0xff00) == 0x100; + if( !fATone ) m_ModFSK.Reset(); // For Signal/CW gain + m_ModFSK.m_Encode.Reset(fCW); + while(pEdit->GetCharNB() == 0x200){ + pEdit->GetChar(TRUE); + m_ModFSK.m_Encode.PutChar(0x200); + } + if( KOAI->Checked && !fCW ){ + m_ModFSK.m_Encode.PutChar('\r'); + m_ModFSK.m_Encode.PutChar('\n'); + } + if( !fATone ) m_ModFSK.SetCarrierFreq(SBNET->Down ? m_RxSet[0].m_pDem->m_CarrierFreq : UdTxCarrier->Position); + m_RxSet[0].m_pDem->ResetMFSK(); + SetTXInternal(); + m_fSendChar = FALSE; + m_Wave.m_hWnd = Handle; + InitWater(iniwMETRIC); + if( !m_Wave.IsOutOpen() ) OpenSound(TRUE); + if( m_pCom ){ + m_pCom->SetDiddle(m_ModFSK.m_Encode.GetDiddle()); + m_pCom->SetSendChar(IsRTTY()); + } + if( !fATone ){ + SetPTT(TRUE); + memset(m_wBuffer, 0, sizeof(m_wBuffer)); + } + if( sys.m_LoopBack == loopINTERNAL ){ + DoDem(); + if( !m_RxSet[0].IsMFSK() ){ + for( int i = 0; i < 8192; i++ ){ + m_RxSet[0].m_pDem->m_Decode.Do(1, TRUE, FALSE); + } + if( m_RxSet[0].IsQPSK() ) m_RxSet[0].m_pDem->m_DecPSK.ResetRX(); + } + } + if( !fATone ) RxStatus(&m_RxSet[0], "TX"); + if( m_Wave.IsOutFirst() ){ + while(!m_Wave.IsOutBufFull()){ + DoMod(); + if( sys.m_LoopBack == loopINTERNAL ) DoDem(); + m_Wave.OutWrite(m_wBuffer); + } + } + UpdateUI(); + if( m_fReqRX ){ + m_fReqRX = 1; + m_ModFSK.m_Encode.m_fReqRX = TRUE; + SBTX->Caption = "ReqRX"; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ToRX(void) +{ + m_fTone = FALSE; + RxStatus(&m_RxSet[0], "RX"); + + if( m_fpText ){ + fclose(m_fpText); + m_fpText = NULL; + } + SBTX->Down = FALSE; + m_TX = txRX; + m_fReqRX = FALSE; + m_ModFSK.m_Encode.m_fReqRX = FALSE; + SetTXCaption(); + if( m_WaveFile.m_mode != 1 ){ + m_Wave.OutAbort(); + DeleteSoundTimer(); + } + SetPTT(FALSE); + InitWater(iniwMETRIC); + if( !m_Wave.IsInOpen() ){ // Loopback == loopINTERNAL + SetBPFType(GetBPFType()); + m_RxSet[0].SetCarrierFreq( (UdRxCarrier->Position != int(m_ModFSK.m_CarrierFreq+0.5)) ? UdRxCarrier->Position : m_ModFSK.m_CarrierFreq); + CRxSet *pRxSet = m_RxSet; + int atctmg; + if( sscanf(AnsiString(EATC->Text).c_str(), "%d", &atctmg) != 1 ) atctmg = 0; //JA7UDE 0428 + for(int i = 0; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ){ + if( i ){ + pRxSet->SetSampleFreq(DEMSAMPFREQ); + pRxSet->m_pDem->MakeBPF(m_RxSet[0].m_pDem->m_PreBPFTaps); + } + pRxSet->m_pDem->m_AFCCount = 0; + pRxSet->m_pDem->m_fAFC = i ? pRxSet->m_fAFC : SBAFC->Down; + pRxSet->m_pDem->m_Decode.m_fATC = i ? TRUE : SBATC->Down; + pRxSet->m_pDem->m_DecPSK.m_bATC = pRxSet->m_pDem->m_Decode.m_fATC; +// if( !pRxSet->IsRTTY() ) pRxSet->m_pDem->m_Decode.SetTmg(i ? 0 : atctmg); + pRxSet->m_pDem->SetTmg((i || pRxSet->IsMFSK()||pRxSet->IsQPSK()) ? 0 : atctmg); + pRxSet->m_pDem->m_Decode.ResetMeasRTTY(); + pRxSet->m_pDem->ResetMFSK(); + for( int j = 0; j < m_BufferSize; j++ ){ + pRxSet->m_pDem->Do(0); + pRxSet->m_pDem->m_Decode.Do(0, 0, FALSE); + } + pRxSet->m_pDem->m_DecPSK.ResetRX(); + pRxSet->m_pDem->m_AGC.Reset(); + pRxSet->InitStgFFT(); + pRxSet->m_SQ = FALSE; + pRxSet->m_AFCTimerW = 5 * SAMPFREQ / m_BufferSize; + pRxSet->m_AFCTimerN = SAMPFREQ / m_BufferSize; + pRxSet->m_SQTimer = 0; + pRxSet->m_AFCTimerPSK = 0; + pRxSet->m_AFCTimerMFSK = MFSKAFC_MAX; + pRxSet->m_PeakSig = 0; + pRxSet->m_AvgSig.Create(32); + } + } + if( m_WaveFile.m_mode != 1 ) OpenSound(FALSE); + FFTSampleFreq(SAMPFREQ); + m_FFT.ClearStg(); + } + else { // loopEXTERNAL + m_RxSet[0].m_AFCTimerN = 3 * SAMPFREQ / m_BufferSize; + } + m_RxSet[0].m_PeakSig = 0; + m_RxSet[0].m_AFCTimerPSK = 0; + m_RxSet[0].m_AFCTimerMFSK = MFSKAFC_MAX; + + if( m_ReqMacroTimer ) CreateMacroTimer(m_ReqMacroTimer); + UpdateUI(); + if( m_ReqAutoClear ) KVCTClick(NULL); + if( m_ReqAutoReturn ){ + m_ReqAutoReturn = FALSE; + SetEditPage(m_SaveEditPage); + } + if( m_ReqAutoNET ){ + m_ReqAutoNET = FALSE; + if( !SBNET->Down ){ + SBNET->Down = TRUE; + SBNETClick(NULL); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DeleteSoundTimer(void) +{ + if( m_pSoundTimer ){ + m_pSoundTimer->Enabled = FALSE; + delete m_pSoundTimer; + m_pSoundTimer = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBTXMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + if( m_TX ){ + if( m_fTone && (m_fReqRX != 1) ){ + m_fReqRX = 1; + m_ModFSK.m_Encode.m_fReqRX = TRUE; + } + } + else { + ToTone(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBTXClick(TObject *Sender) +{ + DeleteMacroTimerS(); + if( SBTX->Down ){ + ToTX(); + } + else if( m_fReqRX ){ + if( m_fReqRX == 1 ){ + m_fReqRX = FALSE; + m_ModFSK.m_Encode.m_fReqRX = FALSE; + } + SBTX->Down = SBTX->Enabled ? TRUE : FALSE; + if( !SBTX->Down ) m_TX = txRX; + } + else { + m_fReqRX = TRUE; + m_ModFSK.m_Encode.m_fReqRX = TRUE; + SBTX->Down = SBTX->Enabled ? TRUE : FALSE; + if( !SBTX->Down ) m_TX = txRX; + m_Edit[m_CurrentEdit].MoveCursor(dmpMoveLAST); + } + SetTXCaption(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBTXOFFClick(TObject *Sender) +{ + m_ReqAutoClear = FALSE; + DeleteMacroTimer(); + if( m_TX ){ + ToRX(); + } + else if( m_fReqRX ){ + m_fReqRX = FALSE; + SetTXCaption(); + } + m_Edit[m_CurrentEdit].MoveCursor(dmpMoveLAST); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PCRXResize(TObject *Sender) +{ + m_Dump.Resize(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PCTXResize(TObject *Sender) +{ + m_Edit[m_CurrentEdit].Resize(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBFFTClick(TObject *Sender) +{ + m_fftMX = 0; + Draw(TRUE); +} +//--------------------------------------------------------------------------- +TSpeedButton *__fastcall TMainVARI::GetDraw(int n) +{ + switch(n){ + case 1: + return SBWater; + case 2: + return SBWave; + default: + return SBFFT; + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetDrawType(void) +{ + for( int i = 0; i < 3; i++ ){ + if( GetDraw(i)->Down ) return i; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetDrawType(int n) +{ + TSpeedButton *pButton = GetDraw(n); + pButton->Down = TRUE; +} +//--------------------------------------------------------------------------- +TSpeedButton *__fastcall TMainVARI::GetBPF(int n) +{ + switch(n){ + case 1: + return SBBPFM; + case 2: + return SBBPFN; + case 3: + return SBBPFS; + default: + return SBBPFW; + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetBPFType(void) +{ + for( int i = 0; i < 4; i++ ){ + if( GetBPF(i)->Down ) return i; + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetBPFType(int n) +{ + TSpeedButton *pButton = GetBPF(n); + pButton->Down = TRUE; + m_RxSet[0].m_pDem->MakeBPF(GetBPFTaps(pButton)); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetBPFTaps(TObject *Sender) +{ + for( int i = 0; i < 4; i++ ){ + if( Sender == (TObject *)GetBPF(i) ){ + return g_tBpfTaps[i]; + } + } + return 64; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBBPFWClick(TObject *Sender) +{ + if( m_fDisEvent ) return; + + int taps = GetBPFTaps(Sender); + CDEMFSK *pDem = m_RxSet[0].m_pDem; + int delay = (pDem->m_inBPF.GetTap() - taps)/2; + pDem->MakeBPF(taps); + CRxSet *pRxSet = &m_RxSet[1]; + for( int i = 1; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ){ + pRxSet->m_pDem->MakeBPF(pDem->m_PreBPFTaps); + pRxSet->m_pDem->m_pBPF = &pDem->m_inBPF; + } + } + if( !m_Wave.IsInOpen() ) return; + + if( delay < 0 ){ + while( delay < 0 ){ + DoDem(0); + delay++; + } + } + else { + m_SkipTmg = delay; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTxFreq(int fq) +{ + if( (fq >= MIN_CARRIER) && (fq <= sys.m_MaxCarrier) ){ + m_ModFSK.SetCarrierFreq(fq); + m_fDisEvent++; + UdTxCarrier->Position = short(fq); + if( m_TX && SBNET->Down ){ + UdRxCarrier->Position = short(fq); + } + if( UdTxCarrier->Position != UdRxCarrier->Position ) SBNET->Down = FALSE; + m_fDisEvent--; + if( (m_TX == txINTERNAL) || SBNET->Down ){ + m_RxSet[0].SetCarrierFreq(fq); + } + UpdateUI(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetRxFreq(int fq) +{ + if( (fq >= MIN_CARRIER) && (fq <= sys.m_MaxCarrier) ){ + if( m_TX != txINTERNAL ){ + m_RxSet[0].SetCarrierFreq(fq); + } + m_fDisEvent++; + UdRxCarrier->Position = short(fq); + if( m_pRadio ) m_pRadio->SetCarrierFreq(fq); + if( !m_TX && SBNET->Down ){ + UdTxCarrier->Position = short(fq); + } + m_fDisEvent--; + m_RxSet[0].m_AFCTimerW = 1; + m_RxSet[0].m_SQTimer = 0; + if( !m_RxSet[0].IsBPSK() ) m_PFTimer = 4; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UdTxCarrierClick(TObject *Sender, + TUDBtnType Button) +{ + if( m_fDisEvent ) return; + + SetTxFreq(UdTxCarrier->Position); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CBTxCarrierChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + int fq; + sscanf(AnsiString(CBTxCarrier->Text).c_str(), "%u", &fq); //JA7UDE 0428 + SetTxFreq(fq); + if( m_fDrop ){ + m_fDrop = FALSE; + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UdRxCarrierClick(TObject *Sender, + TUDBtnType Button) +{ + if( m_fDisEvent ) return; + + SetRxFreq(UdRxCarrier->Position); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CBRXCarrierChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + int fq; + sscanf(AnsiString(CBRXCarrier->Text).c_str(), "%u", &fq); + SetRxFreq(fq); + if( m_fDrop ){ + m_fDrop = FALSE; + SetTXFocus(); + } + else { + m_AFCKeyTimer = 3 * SAMPBASE / m_BufferSize; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetSpeedInfo(double b) +{ + if( m_RxSet[0].IsMFSK() ){ + switch(m_RxSet[0].m_MFSK_TYPE){ + case typMFSK16: + strcpy(m_TextBuff, "mfsk16 (15.625 baud, 16 tones)"); + break; + case typMFSK8: + strcpy(m_TextBuff, "mfsk8 (7.8125 baud, 32 tones)"); + break; + case typMFSK31: + strcpy(m_TextBuff, "mfsk31 (31.25 baud, 8 tones)"); + break; + case typMFSK11: + strcpy(m_TextBuff, "mfsk11 (10.767 baud, 16 tones)"); + break; + case typMFSK22: + strcpy(m_TextBuff, "mfsk22 (21.533 baud, 16 tones)"); + break; + case typMFSK32: + strcpy(m_TextBuff, "mfsk32 (31.25 baud, 16 tones)"); + break; + case typMFSK64: + strcpy(m_TextBuff, "mfsk64 (62.5 baud, 16 tones)"); + break; + case typMFSK4: + strcpy(m_TextBuff, "mfsk4 (3.90625 baud, 32 tones)"); + break; + } + } + else { + StrDbl(m_TextBuff, b); + strcat(m_TextBuff, "Bps"); + } + switch( m_RxSet[0].m_Mode ){ + case MODE_BPSK: + case MODE_N_BPSK: + if( b == 31.25 ){ + strcat(m_TextBuff, " (PSK31)"); + } + else if( b == 62.5 ){ + strcat(m_TextBuff, " (PSK63)"); + } + else if( b == 125 ){ + strcat(m_TextBuff, " (PSK125)"); + } + else if( b == 250 ){ + strcat(m_TextBuff, " (PSK250)"); + } + break; + case MODE_qpsk_L: + case MODE_qpsk_U: + if( b == 31.25 ){ + strcat(m_TextBuff, " (QPSK31)"); + } + else if( b == 62.5 ){ + strcat(m_TextBuff, " (QPSK63)"); + } + else if( b == 125 ){ + strcat(m_TextBuff, " (QPSK125)"); + } + else if( b == 250 ){ + strcat(m_TextBuff, " (QPSK250)"); + } + break; + case MODE_RTTY: + case MODE_U_RTTY: + if( b == 45.45 ){ + strcat(m_TextBuff, sys.m_MsgEng ? "(Standard)":"(標準)"); + } + break; + } + if( IsRTTY() ){ + if( b != 45.45 ){ + strcat(m_TextBuff, sys.m_MsgEng ? " : 45.45Bps is standard" : " : 標準は45.45Bps"); + } + } + else if( !m_RxSet[0].IsMFSK() ){ + if( b != 31.25 ){ + strcat(m_TextBuff, sys.m_MsgEng ? " : 31.25Bps is standard" : " : 標準は31.25Bps"); + } + } + SetInfoMsg(m_TextBuff); + DoEvent(macOnSpeed); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CBSpeedChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + double b; + sscanf(AnsiString(CBSpeed->Text).c_str(), "%lf", &b); //JA7UDE 0428 + SpeedChange(b); + if( m_fDrop ){ + m_fDrop = FALSE; + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SpeedChange(double b) +{ + if( m_RxSet[0].IsMFSK() ){ + m_RxSet[0].SetMFSKType(MFSK_Speed2Type(b)); +#if DEBUG + m_ModTest.SetMFSKType(m_RxSet[0].m_MFSK_TYPE); +#endif + m_ModFSK.SetMFSKType(m_RxSet[0].m_MFSK_TYPE); + InitCollect(); + SetSpeedInfo(b); + } + else if( (b >= MIN_SPEED) && (b <= MAX_SPEED) && (b != m_RxSet[0].m_Speed) ){ + m_RxSet[0].SetSpeed(b); +#if DEBUG + m_ModTest.SetSpeed(b); +#endif + m_ModFSK.SetSpeed(b); + InitCollect(); + SetSpeedInfo(b); + if( IsRTTY() && sys.m_bFSKOUT && m_pCom && m_pCom->IsBaudChange(b) ){ + OpenCom(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateSpeed(CRxSet *pRxSet, double b) +{ + if( pRxSet == &m_RxSet[0] ){ + if( pRxSet->IsMFSK() ){ + SpeedChange(b); + UpdateUI(); + } + else { + m_fDisEvent++; + char bf[256]; + CBSpeed->Text = StrDbl(bf, b); + m_fDisEvent--; + CBSpeedChange(NULL); + } + } + else if( pRxSet->IsMFSK() ){ + pRxSet->SetMFSKType(MFSK_Speed2Type(b)); + } + else { + pRxSet->SetSpeed(b); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateMode(CRxSet *pRxSet, int offset) +{ + if( pRxSet == &m_RxSet[0] ){ + if( IsRTTY() ){ + GBTiming->Caption = "Timing(ms)"; + } + else { + GBTiming->Caption = "Timing(ppm)"; + } + if( offset ){ + SetRxFreq(UdRxCarrier->Position + offset); + if( m_TX || !SBNET->Down ){ + SetTxFreq(UdTxCarrier->Position + offset); + } + } + } + else if( offset ){ + pRxSet->SetCarrierFreq(pRxSet->m_CarrierFreq + offset); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFSClick(TObject *Sender) +{ + if( m_fpText ){ + fclose(m_fpText); + m_fpText = NULL; + } + else { + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Send text file"; + pBox->Filter = "Text Files(*.txt)|*.txt|"; + } + else { + pBox->Title = "テキストファイルの送信"; + pBox->Filter = "テキストファイル(*.txt)|*.txt|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "txt"; + pBox->InitialDir = sys.m_TextDir; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + SetDirName(sys.m_TextDir, AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + OnWave(); + m_fpText = fopen(AnsiString(pBox->FileName).c_str(), "rb"); //JA7UDE 0428 + if( !m_TX ) ToTX(); + } + delete pBox; + AttachFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetFFTWidth(int fw) +{ +// int fo = m_FFTB + m_FFTW/2; + if( SBWater->Down ) InitWater(iniwMETRIC); + int fo = UdRxCarrier->Position; + switch(fw){ + case 500: + SBFFT500->Down = TRUE; + break; + case 1000: + SBFFT1K->Down = TRUE; + break; + case 2000: + SBFFT2K->Down = TRUE; + break; + default: + SBFFT3K->Down = TRUE; + fw = 3000; + break; + } + m_FFTW = fw; + m_FFTWindow = m_FFTW * FFT_SIZE / m_FFTSampFreq; + CalcFFTCenter(fo); + Draw(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBFFT500Click(TObject *Sender) +{ + int fw; + if( SBFFT3K->Down ){ + fw = 3000; + } + else if( SBFFT2K->Down ){ + fw = 2000; + } + else if( SBFFT500->Down ){ + fw = 500; + } + else { + fw = 1000; + } + SetFFTWidth(fw); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UdATCClick(TObject *Sender, + TUDBtnType Button) +{ + if( m_fDisEvent ) return; + + int d; + sscanf(AnsiString(EATC->Text).c_str(), "%d", &d); //JA7UDE 0428 + d = d - (d % 200); + if( Button == Comctrls::btNext ){ + d += 200; + } + else { + d -= 200; + } + if( d < -m_ATCLimit ) d = -m_ATCLimit; + if( d > m_ATCLimit ) d = m_ATCLimit; + m_RxSet[0].m_pDem->m_Decode.SetTmg(d); + m_RxSet[0].m_pDem->m_DecPSK.SetTmg(d); + EATC->Text = d; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBAFCClick(TObject *Sender) +{ + if( m_TX != txINTERNAL ){ + CDEMFSK *pDem = m_RxSet[0].m_pDem; + m_RxSet[0].m_fAFC = pDem->m_fAFC = SBAFC->Down; + if( pDem->m_fAFC && m_RxSet[0].IsMFSK() ){ + m_RxSet[0].m_AFCFQ = pDem->m_CarrierFreq; + m_RxSet[0].m_AvgAFC.Reset(pDem->m_CarrierFreq); + pDem->m_RxFreq = pDem->m_CarrierFreq; + if( m_RxSet[0].m_AFCTimerMFSK < MFSKAFC_1stATACK ){ + m_RxSet[0].m_AFCTimerMFSK = MFSKAFC_1stATACK; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBATCClick(TObject *Sender) +{ + UpdateUI(); + if( m_TX == txINTERNAL ) return; + + m_RxSet[0].m_pDem->m_Decode.m_fATC = SBATC->Down; + m_RxSet[0].m_pDem->m_DecPSK.m_bATC = SBATC->Down; + if( !SBATC->Down ){ + int atctmg; + if( sscanf(AnsiString(EATC->Text).c_str(), "%d", &atctmg) == 1 ){ //JA7UDE 0428 + m_RxSet[0].m_pDem->m_Decode.SetTmg(atctmg); + m_RxSet[0].m_pDem->m_DecPSK.SetTmg(atctmg); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxFFTMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + DeleteMacroTimer(); + m_MouseDown = FALSE; + if( SBFFT->Down || SBWater->Down ){ + double fq = m_FFTB + X * m_FFTW / m_fftXW; + if( fq < MIN_CARRIER ) fq = MIN_CARRIER; + if( fq > sys.m_MaxCarrier ) fq = sys.m_MaxCarrier; + if( Button == mbRight ){ + m_RightX = X; + m_RightFreq = fq + 0.5; + RECT rc; + ::GetWindowRect(PFFT->Handle, &rc); + rc.left += X; + if( !m_MouseNotch && (!m_fSubWindow || !m_MouseSubChannel) ){ + m_fftMX = ((fq - m_FFTB) * m_fftXW / m_FFTW) + 0.5; + PBoxFFTPaint(NULL); + } + PupSpec->Popup(rc.left, rc.bottom); + m_fftMX = 0; + PBoxFFTPaint(NULL); + } + else if( Button == mbLeft ){ + if( m_MouseSubChannel || m_MouseNotch ){ + m_MouseDown = TRUE; + } + else if( m_TX != txINTERNAL ){ + m_RxSet[0].m_pDem->m_Decode.Reset(); + m_RxSet[0].m_pDem->ResetMeasMFSK(); + m_RxSet[0].m_PeakSig = 0; + m_RxSet[0].m_AFCTimerMFSK = (SBFFT500->Down || SBFFT1K->Down) ? MFSKAFC_MAX : 0; + if( !SBFFT500->Down ){ + fq = GetSignalFreq(fq, SBFFT3K->Down ? 50 : 32, &m_RxSet[0]); + } + SetRxFreq(fq); + m_MouseDown = TRUE; + } + } + } + else { + if( Button == mbRight ){ + m_fftMX = 0; + } + else { + m_fftMX = X; + } + PBoxFFTPaint(NULL); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::PBoxLevelMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbLeft ){ + int sq = (m_levelYW - Y) * LEVELMAX / m_levelYW; + m_RxSet[0].m_SQLevel = ((sq + 5)/ 10) * 10; + DrawLevel(TRUE); + m_MouseDown = TRUE; + } + else if( Button == mbRight ){ + RECT rc; + ::GetWindowRect(PCLevel->Handle, &rc); + PupSQ->PopupComponent = this; + PupSQ->Popup(rc.left + X, rc.top + Y); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxLevelMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_MouseDown ){ + X = (m_levelYW - Y) * LEVELMAX / m_levelYW; + if( (X >= 0) && (X <= LEVELMAX) ){ + m_RxSet[0].m_SQLevel = X; + DrawLevel(TRUE); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxLevelMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + m_MouseDown = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormResize(TObject *Sender) +{ + if( !m_pBitmapFFT ) return; + + if( (ClientWidth < 600) || (ClientHeight < 400) ){ + if( ClientWidth < 600 ) ClientWidth = 600; + if( ClientHeight < 400 ) ClientHeight = 400; + return; + } + PFFT->Font->Charset = sys.m_FontCharset; + PFFT->Font->Height = -12; + int x = SBFFT->Left + SBFFT->Width + PCLevel->Width + 2; + PFFT->Width = ClientWidth - x; + if( PBoxFFT->Align != alClient ) CreateMacExButton(); + m_fftXW = PBoxFFT->Width; + if( m_fftXW != m_pBitmapFFT->Width ){ + m_pBitmapFFT->Width = m_fftXW; + DrawWater(FALSE, TRUE); + } + UdMac->Left = PCMac->Width - UdMac->Width; + CreateMacButton(); +// StatusBar->SizeGrip = (WindowState == wsNormal); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFClick(TObject *Sender) +{ + KFS->Checked = m_fpText != NULL; + KFES->Enabled = m_WaveFile.m_mode; + KFRS->Enabled = m_WaveFile.m_mode != 2; + KFWS->Enabled = m_WaveFile.m_mode != 1; + KFWST->Enabled = m_WaveFile.m_mode != 1; + if( m_WaveFile.m_mode != 2 ){ + KFWS->Checked = FALSE; + KFWST->Checked = FALSE; + } + KFLF->Enabled = Log.IsEdit(); + KFL->Checked = m_Dump.IsLogging(); + OnMenuProc(KF, "&File"); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::CBRXCarrierDropDown(TObject *Sender) +{ + m_fDrop = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CBRXCarrierKeyPress(TObject *Sender, char &Key) +{ + m_fDrop = FALSE; + if( Key == VK_RETURN ){ + Key = 0; + if( Sender == HisCall ){ + FindCall(); + UpdateUI(); + } + else if( Sender == CBSpeed ){ + double speed; + if( m_RxSet[0].IsMFSK() ){ + speed = m_RxSet[0].m_pDem->m_MFSK_SPEED; + } + else { + speed = m_RxSet[0].m_Speed; + } + SetCBSpeed(); + SetSpeedInfo(speed); + } + SetTXFocus(); + } + else if( Sender == HisCall ){ + Key = char(toupper(Key)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetMacButtonMax(void) +{ + int m = MACBUTTONXW * m_MacButtonVW; + UdMac->Max = short((MACBUTTONMAX-1) / m); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CreateMacButton(void) +{ + int xw = PCMac->Width - UdMac->Width - 6; + xw /= MACBUTTONXW; + int xa = xw * MACBUTTONXW; + xa = ((PCMac->Width - UdMac->Width) - xa) / 2; + int yw = PCMac->Height / m_MacButtonVW; + + int low = UdMac->Position * (MACBUTTONXW*m_MacButtonVW); + int high = low + (MACBUTTONXW*m_MacButtonVW); + MACBUTTON *pList = m_tMacButton; + for( int i = 0; i < MACBUTTONMAX; i++, pList++ ){ + if( (i < low) || (i >= high) ){ + if( pList->pButton ){ + PCMac->RemoveControl(pList->pButton); + delete pList->pButton; + pList->pButton = NULL; + } + } + else { + int n = i - low; + int y = (n / MACBUTTONXW) * yw; + int xm = n % MACBUTTONXW; + int x = xm * xw; + if( xm >= 4 ) x+=xa; + if( xm >= 8 ) x+=xa; + TSpeedButton *pButton = pList->pButton; + if( !pButton ){ + pButton = new TSpeedButton(PCMac); + PCMac->InsertControl(pButton); + pButton->Parent = PCMac; + pButton->OnClick = OnMacButtonClick; + pButton->OnMouseDown = OnMacButtonDown; + pButton->GroupIndex = 1; + pButton->AllowAllUp = TRUE; + char bf[16]; + sprintf(bf, "%%M%u", i); + pButton->Hint = bf; + pButton->Down = (i == m_CurrentMacro) && (m_ReqMacroTimer || m_pMacroTimer); + pList->pButton = pButton; + } + else { + pButton->Font->Name = sys.m_FontName; + pButton->Font->Charset = sys.m_FontCharset; + } + pButton->Caption = ConvAndChar(m_TextBuff, pList->Name.c_str()); + pButton->SetBounds(x, y, xw, yw); + pButton->Font->Height = -(yw-4); + pButton->Font->Color = pList->Text.IsEmpty() ? clGrayText : pList->Color; + TFontStyles fs = Code2FontStyle(pList->Style); + pButton->Font->Style = fs; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UdMacClick(TObject *Sender, TUDBtnType Button) +{ + CreateMacButton(); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetMacButtonNo(TSpeedButton *pButton) +{ + MACBUTTON *pList = m_tMacButton; + int i; + for( i = 0; i < MACBUTTONALL; i++, pList++ ){ + if( pButton == pList->pButton ) return i; + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnMacButtonClick(TObject *Sender) +{ + TSpeedButton *pButton = (TSpeedButton *)Sender; + MACBUTTON *pList = m_tMacButton; + int i; + for( i = 0; i < MACBUTTONALL; i++, pList++ ){ + if( pButton == pList->pButton ){ + if( pButton->Down ){ + m_fMacroRepeat = FALSE; + SendButton(i); + } + else { + DeleteMacroTimer(); + } + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnMacButtonDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + TSpeedButton *pButton = (TSpeedButton *)Sender; + + MACBUTTON *pList = m_tMacButton; + int i; + for( i = 0; i < MACBUTTONALL; i++, pList++ ){ + if( pButton == pList->pButton ){ + if( Button == mbRight ){ + TMacEditDlg *pBox = new TMacEditDlg(this); + DettachFocus(); + if( pBox->Execute(pList, i) ){ + pButton->Caption = ConvAndChar(m_TextBuff, pList->Name.c_str()); + pButton->Font->Color = pList->Text.IsEmpty() ? clGrayText : pList->Color; + TFontStyles fs = Code2FontStyle(pList->Style); + pButton->Font->Style = fs; + } + delete pBox; + AttachFocus(); + } + return; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupRXPopup(TObject *Sender) +{ + int n = GetPopupIndex(PupRX->PopupComponent); + if( n ){ + KRXINV->Visible = m_RxSet[n].IsRTTY(); + } + else { + KRXINV->Visible = IsRTTY(); + } + KRXN->Visible = KRXINV->Visible; + OnMenuProc(PupRX->Items, "PopRX"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXINVClick(TObject *Sender) +{ + int n = GetPopupIndex(PupRX->PopupComponent); + CDump *pDump; + if( n ){ + pDump = &m_RxSet[n].m_pView->m_Dump; + } + else { + pDump = &m_Dump; + } + pDump->SwapLTR(); +} +//--------------------------------------------------------------------------- +static void __fastcall AdjustCallsign(AnsiString &as) +{ + AnsiString cs; + + LPCSTR p; + int nl = 0; + int nu = 0; + for(p = as.c_str(); *p; p++ ){ + if( isupper(*p) ) nu++; + if( islower(*p) ) nl++; + } + for( p = as.c_str(); *p; p++ ){ + if( isdigit(*p) ) break; + if( nl > nu ){ + if( islower(*p) ) break; + } + else { + if( isupper(*p) ) break; + } + } + for( ; *p; p++ ){ + if( *p != '/' ){ + if( nl > nu ){ + if( isupper(*p) ) break; + } + else { + if( islower(*p) ) break; + } + } + cs += *p; + } + if( IsCall(cs.c_str()) ){ + as = cs; + } + jstrupr(as.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXCALLClick(TObject *Sender) +{ + if( Sender == NULL ){ + AnsiString as = m_StrSel; + AdjustCallsign(as); + HisCall->Text = as; // m_UStrSel; + } + else { + HisCall->Text = m_UStrSel; + } + FindCall(); + UpdateUI(); + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXMYClick(TObject *Sender) +{ + LPCSTR p = m_UStrSel.c_str(); + if( PCRX->Font->Charset == SHIFTJIS_CHARSET ){ + LPSTR t = m_TextBuff; + for( ; *p; p++ ){ + if( m_RxSet[0].m_MBCS.IsLead((const unsigned char *)p) ){ + int c = *p & 0x000000ff; + c = c << 8; p++; + c |= (*p & 0x00ff); + if( (c >= 0x824f) && (c <= 0x8258) ){ + *t++ = BYTE(c + 0x30 - 0x824f); + } + else { + *t++ = BYTE(c >> 8); + *t++ = *p; + } + } + else { + *t++ = *p; + } + } + *t = 0; + p = m_TextBuff; + } + MyRST->Text = p; + SetTXFocus(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KRXQTHClick(TObject *Sender) +{ + HisQTH->Text = m_StrSel; + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXNAMEClick(TObject *Sender) +{ + HisName->Text = m_StrSel; + SetTXFocus(); +} +//--------------------------------------------------------------------------- +static BOOL FindDlmStr(LPCSTR v, LPCSTR s) +{ + LPSTR pBF = StrDupe(v); + BOOL f = FALSE; + LPSTR p = pBF; + LPSTR t; + while(*p){ + p = StrDlm(t, p, -1); + if( *t && !strcmpi(t, s) ){ + f = TRUE; + break; + } + } + delete pBF; + return f; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXADDMYClick(TObject *Sender) +{ + AnsiString as = MyRST->Text; + as += m_StrSel; + MyRST->Text = as; + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXADDNAMEClick(TObject *Sender) +{ + if( !FindDlmStr(AnsiString(HisName->Text).c_str(), m_StrSel.c_str()) ){ //JA7UDE 0428 + AnsiString as = HisName->Text; + if( !as.IsEmpty() ) as += char(','); + as += m_StrSel; + HisName->Text = as; + } + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXADDNOTEClick(TObject *Sender) +{ + if( !FindDlmStr(AnsiString(EditNote->Text).c_str(), m_StrSel.c_str()) ){ //JA7UDE 0428 + AnsiString as = EditNote->Text; + if( !as.IsEmpty() ) as += char(','); + as += m_StrSel; + EditNote->Text = as; + } + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXADDQSLClick(TObject *Sender) +{ + if( !FindDlmStr(AnsiString(EditQSL->Text).c_str(), m_StrSel.c_str()) ){ //JA7UDE 0428 + AnsiString as = EditQSL->Text; + if( !as.IsEmpty() ) as += char(','); + as += m_StrSel; + EditQSL->Text = as; + } + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXNOTEClick(TObject *Sender) +{ + EditNote->Text = m_StrSel; + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRXCopyClick(TObject *Sender) +{ + Clipboard()->AsText = m_StrSel; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxRXMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + DeleteMacroTimer(); + BOOL f = m_Dump.ClearAllSelect(FALSE); + int r = m_Dump.GetWindowText(m_StrSel, X, Y); + if( f || r ) m_Dump.Paint(); + if( r ){ + m_UStrSel = m_StrSel.c_str(); + jstrupr(m_UStrSel.c_str()); + RECT rc; + ::GetWindowRect(PCRX->Handle, &rc); + rc.left += X; rc.top += Y+8; + if( Button == mbLeft ){ + if( r == 1 ){ // ASCII + if( IsCall(m_UStrSel.c_str()) ){ + KRXCALLClick(NULL); + } + else if( IsRST(m_UStrSel.c_str()) ){ + KRXMYClick(NULL); + } + else { + PupRX->PopupComponent = this; + PupRX->Popup(rc.left, rc.top); + } + } + else { // Shift-JIS + PupRX->PopupComponent = this; + PupRX->Popup(rc.left, rc.top); + } + DoEvent(macOnClick); + } + else if( Button == mbRight ){ + PupRX->PopupComponent = this; + PupRX->Popup(rc.left, rc.top); + } + } + else if( Button == mbRight ){ + RECT rc; + ::GetWindowRect(PCRX->Handle, &rc); + rc.left += X; rc.top += Y+8; + PupRXW->PopupComponent = StatusBar; + PupRXW->Popup(rc.left, rc.top); + } + else { + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + TShiftState sc1, sc2, sa1, sa2, ss1, ss2; + + WORD nKey = WORD(Key & 0x00ff); + sc1 << ssCtrl; + sc2 << ssCtrl; + sc1 *= Shift; + + sa1 << ssAlt; + sa2 << ssAlt; + sa1 *= Shift; + + ss1 << ssShift; + ss2 << ssShift; + ss1 *= Shift; + + if( sc1 == sc2 ){ // Ctrl+Any + nKey |= 0x0100; + } + else if( sa1 == sa2 ){ // Alt + Any + nKey |= 0x0200; + } + else if( ss1 == ss2 ){ // Shift + Any + nKey |= 0x0400; + } + + if( nKey == sys.m_DefKey[kkTX] ){ + if( SBTX->Enabled ){ + SBTX->Down = SBTX->Down ? FALSE : TRUE; + SBTXClick(NULL); + } + SetTXFocus(); + Key = 0; + } + else if( nKey == sys.m_DefKey[kkTXOFF] ){ + SBTXOFFClick(NULL); + SetTXFocus(); + Key = 0; + } + else { + CDump *pEdit = &m_Edit[m_CurrentEdit]; + switch(nKey){ + case VK_DELETE: + if( ActiveControl == PCTX ){ + pEdit->DeleteChar(); + } + break; + case VK_HOME: + case VK_END: + case VK_END + 0x0100: + case VK_HOME + 0x0100: + if( ActiveControl == PCTX ){ + pEdit->MoveCursor(nKey); + } + break; + default: + if( (Key >= VK_F1) && (Key <= VK_F12) ){ + int m = Key - VK_F1; + Key = 0; + if( nKey & 0x0400 ){ // Shift + m += 12; + } + else if( nKey & 0x0200 ){ // Alt + if( m_MacButtonVW < 3 ) break; + m += 24; + } + else if( nKey & 0x0100 ){ // Ctrl + if( m_MacButtonVW < 4 ) break; + m += 36; + } + m_fMacroRepeat = FALSE; + SendButton(m + UdMac->Position * (MACBUTTONXW*m_MacButtonVW)); + } + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBQSOClick(TObject *Sender) +{ + UpdateLogData(); + UpdateLogMode(); + SYSTEMTIME now; + GetUTC(&now); + int Year = now.wYear % 100; + int Month = now.wMonth; + int Day = now.wDay; + int Hour = now.wHour; + UTCtoJST(Year, Month, Day, Hour); + +// Log.m_sd.cq = m_Running ? 'A' : 'C'; + if( SBQSO->Down ){ // Start QSO + m_QSOStart = SystemTime2GPS(&now); + AddCall(AnsiString(HisCall->Text).c_str()); //JA7UDE 0428 + LogLink.SetTime(&now, 0); + Log.m_sd.year = char(Year % 100); + Log.m_sd.date = WORD(Month * 100 + Day); + Log.m_sd.btime = WORD((Hour * 60 + now.wMinute) * 30 + now.wSecond/2); + if( !Log.m_sd.btime ) Log.m_sd.btime++; + CWaitCursor w; + if( Log.FindSet(&Log.m_Find, Log.m_sd.call) ){ + OnWave(); + SDMMLOG sd; + Log.GetData(&sd, Log.m_Find.pFindTbl[0]); // 一番最新のデータ + if( !Log.m_sd.name[0] && Log.m_LogSet.m_CopyName ) strcpy(Log.m_sd.name, sd.name); + if( !Log.m_sd.qth[0] && Log.m_LogSet.m_CopyQTH ) strcpy(Log.m_sd.qth, sd.qth); + if( !Log.m_sd.rem[0] && Log.m_LogSet.m_CopyREM ) strcpy(Log.m_sd.rem, sd.rem); + if( !Log.m_sd.qsl[0] && Log.m_LogSet.m_CopyQSL ) strcpy(Log.m_sd.qsl, sd.qsl); + } + Log.CopyAF(); + if( Log.m_sd.call[0] ){ + LPCSTR pCC = ClipCC(Log.m_sd.call); + Log.SetOptStr(0, &Log.m_sd, Cty.GetCountry(pCC)); + Log.SetOptStr(1, &Log.m_sd, Cty.GetCont(pCC)); + } + UpdateTextData(); + if( Log.PutData(&Log.m_sd, Log.m_CurNo) == FALSE ){ + SBQSO->Down = FALSE; + } + + if( Log.m_Find.m_FindCmp1Max ){ + switch(Log.m_LogSet.m_CheckBand){ + case 1: + if( Log.FindSameBand(FALSE) ) m_Dupe = 1; + break; + case 2: + if( Log.FindSameBand(TRUE) ) m_Dupe = 1; + break; + default: + m_Dupe = 1; + break; + } + } + else { + m_Dupe = 0; + } + Log.m_Find.Ins(Log.m_CurNo); + Log.m_CurChg = 0; + DoEvent(macOnQSO); + LogLink.Write(&Log.m_sd, 1); + } + else { // Finish QSO + LogLink.SetTime(&now, 1); + Log.m_sd.etime = WORD((Hour * 60 + now.wMinute) * 30 + now.wSecond/2); + if( !Log.m_sd.etime ) Log.m_sd.etime++; + if( !Log.m_sd.ur[0] ){ + strcpy(Log.m_sd.ur, "599"); + } + if( !Log.m_sd.my[0] ){ + strcpy(Log.m_sd.my, "599"); + } + Log.PutData(&Log.m_sd, Log.m_CurNo); + LogLink.Write(&Log.m_sd, 2); + DoEvent(macOnQSO); + + memcpy(&Log.m_asd, &Log.m_sd, sizeof(Log.m_asd)); + Log.m_CurNo++; + Log.m_CurChg = 0; + Log.m_Find.Clear(); + Log.InitCur(); + UpdateTextData(); + AutoLogSave(); + } + UpdateCallsign(); + UpdateUI(); + SetTXFocus(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KVClick(TObject *Sender) +{ + switch(m_FFTVType){ + case 0: + KVF1->Checked = TRUE; + break; + case 1: + KVF2->Checked = TRUE; + break; + default: + KVF3->Checked = TRUE; + break; + } + switch(m_FFTSmooth){ + case 3: + KVFS3->Checked = TRUE; + break; + case 4: + KVFS4->Checked = TRUE; + break; + default: + KVFS2->Checked = TRUE; + break; + } + switch(m_MacButtonVW){ + case 2: + KVM2->Checked = TRUE; + break; + case 4: + KVM4->Checked = TRUE; + break; + default: + KVM3->Checked = TRUE; + break; + } + KVSP->Enabled = m_pPlayBox != NULL; + KVSP->Checked = (m_pPlayBox != NULL) && m_pPlayBox->Active; + for( int i = 1; i < RXMAX; i++ ){ + TMenuItem *pm = KVS->Items[i-1]; + pm->Checked = m_RxSet[i].IsActive(); + } + switch(m_ScaleAsRigFreq){ + case 1: + KVSFR->Checked = TRUE; + break; + default: + KVSFT->Checked = TRUE; + break; + } + KVSD->Checked = m_ScaleDetails; + KVMX->Checked = PBoxFFT->Align != alClient; + OnMenuProc(KV, "&View"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVF1Click(TObject *Sender) +{ + int vtype = m_FFTVType; + if( Sender == KVF1 ){ + m_FFTVType = 0; + m_FFT.m_FFTGain = 0; + } + else if( Sender == KVF2 ){ + m_FFTVType = 1; + m_FFT.m_FFTGain = 0; + } + else { + m_FFTVType = 2; + m_FFT.m_FFTGain = 1; + } + if( vtype == m_FFTVType ) return; + + InitWater(iniwBOTH); + for( int i = 0; i < RXMAX; i++ ){ + m_RxSet[i].m_StgFFT.Timer = SAMPFREQ/m_BufferSize; + m_RxSet[i].m_AFCTimerW = SAMPFREQ / m_BufferSize; + } + DoEvent(macOnFFTScale); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBNETClick(TObject *Sender) +{ + UpdateUI(); + if( SBNET->Down && !m_TX ){ + SetTxFreq(UdRxCarrier->Position); + } + m_ReqAutoNET = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVFS2Click(TObject *Sender) +{ + m_FFTSmooth = 2; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVFS3Click(TObject *Sender) +{ + m_FFTSmooth = 3; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVFS4Click(TObject *Sender) +{ + m_FFTSmooth = 4; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFXClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KEClick(TObject *Sender) +{ + CDump *pEdit = &m_Edit[m_CurrentEdit]; + BOOL f = pEdit->CanEdit(); + KEX->Enabled = pEdit->IsSelText() && f; + KECP->Enabled = pEdit->IsSelText(); + KEP->Enabled = ::IsClipboardFormatAvailable(CF_TEXT) && f; + OnMenuProc(KE, "&Edit"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupTXPopup(TObject *Sender) +{ + if( KE->Count != PupTX->Items->Count ) return; + KEClick(NULL); + for( int i = 0; i < KE->Count; i++ ){ + PupTX->Items->Items[i]->Enabled = KE->Items[i]->Enabled; + for( int j = 0; j < KE->Items[i]->Count; j++ ){ + PupTX->Items->Items[i]->Items[j]->Checked = KE->Items[i]->Items[j]->Checked; + } + } + OnMenuProc(PupTX->Items, "PopTX"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KEPClick(TObject *Sender) +{ + AnsiString as = Clipboard()->AsText.c_str(); + LPCSTR p = as.c_str(); + for( ; *p; p++ ){ + m_Edit[m_CurrentEdit].PutKey(*p, 1); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBarRXChange(TObject *Sender) +{ + m_Dump.OnScrollBarChange(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBarTXChange(TObject *Sender) +{ + m_Edit[m_CurrentEdit].OnScrollBarChange(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::SBBPFWMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + CFIR2 fir; + int fo = UdRxCarrier->Position; + switch(CBMode->ItemIndex){ + case MODE_N_BPSK: + case MODE_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + case MODE_GMSK: + fir.Create(GetBPFTaps(Sender), ffBPF, DEMSAMPFREQ, fo-m_RxSet[0].m_Speed, fo+m_RxSet[0].m_Speed, 60, 1.0); + break; + case MODE_FSK: + fir.Create(GetBPFTaps(Sender), ffBPF, DEMSAMPFREQ, fo-m_RxSet[0].m_Speed*2, fo+m_RxSet[0].m_Speed*2, 60, 1.0); + break; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + { + int taps = GetBPFTaps(Sender); + double hw = m_RxSet[0].m_pDem->m_RTTYShift*0.5; + double bw = GetRTTYBW(taps); + fir.Create(taps, ffBPF, DEMSAMPFREQ, fo-hw-bw, fo+hw+bw, 60, 1.0); + } + break; + case MODE_mfsk_L: + { + int taps = GetBPFTaps(Sender); + double bw = GetMFSKBW(taps); + if( sys.m_MFSK_Center ){ + fir.Create(taps, ffBPF, DEMSAMPFREQ, fo-m_RxSet[0].m_pDem->m_MFSK_BW/2-bw, fo+m_RxSet[0].m_pDem->m_MFSK_BW/2+bw, 60, 1.0); + } + else { + fir.Create(taps, ffBPF, DEMSAMPFREQ, fo-m_RxSet[0].m_pDem->m_MFSK_BW-bw, fo+bw, 60, 1.0); + } + } + break; + case MODE_mfsk_U: + { + int taps = GetBPFTaps(Sender); + double bw = GetMFSKBW(taps); + if( sys.m_MFSK_Center ){ + fir.Create(taps, ffBPF, DEMSAMPFREQ, fo-m_RxSet[0].m_pDem->m_MFSK_BW/2-bw, fo+m_RxSet[0].m_pDem->m_MFSK_BW/2+bw, 60, 1.0); + } + else { + fir.Create(taps, ffBPF, DEMSAMPFREQ, fo-bw, fo+m_RxSet[0].m_pDem->m_MFSK_BW+bw, 60, 1.0); + } + } + break; + } + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&fir, 3000, DEMSAMPFREQ); + delete pBox; + AttachFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOVOClick(TObject *Sender) +{ + HWND hWnd = ::FindWindow("Volume Control", NULL); + if( hWnd != NULL ){ + ::PostMessage(hWnd, WM_CLOSE, 0, 0); + ::Sleep(200); + OnWave(); + } + + char cmd[128]; + if( sys.m_WinVista ){ + if( Sender != KOVO ){ + strcpy(cmd, "control.exe mmsys.cpl,,1"); + } + else { + strcpy(cmd, "sndvol.exe"); + } + } + else { + strcpy(cmd, "SNDVOL32.EXE"); + if( sys.m_WinNT && (Sender != KOVO) ) strcat(cmd, " /R"); + } + + WinExec(cmd, SW_SHOW); + if( !sys.m_WinNT && (Sender != KOVO) ){ + CWaitCursor w; + int i; + for( i = 0; i < 30; i++ ){ + OnWave(); + ::Sleep(100); + hWnd = ::FindWindow("Volume Control", NULL); + if( hWnd != NULL ) break; + } + if( i < 30 ){ + ::SetForegroundWindow(hWnd); + ::Sleep(100); + OnWave(); + const short _tt[]={ + VK_MENU, 'P', 'P'|0x8000, VK_MENU|0x8000, + 'R', 'R'|0x8000, VK_TAB, VK_TAB|0x8000, + VK_DOWN, VK_DOWN|0x8000, VK_RETURN, VK_RETURN|0x8000, + 0 + }; + KeyEvent(_tt); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOOClick(TObject *Sender) +{ + TOptDlgBox *pBox = new TOptDlgBox(this); + DettachFocus(); + if( pBox->Execute(DWORD(Sender)) ){ + if( pBox->m_fComChange ) OpenCom(); + if( RADIO.change ) OpenRadio(); + if( pBox->m_fLangChange ){ + SetSystemFont(); + CreateMacButton(); + if( PBoxFFT->Align != alClient ) CreateMacExButton(); + } + if( sys.m_fPlayBack ){ + if( !m_PlayBack.IsActive() ) m_PlayBack.Init(m_BufferSize, SAMPBASE); + } + else { + m_PlayBack.Delete(); + } + OnWave(); + SetTXCaption(); + UpdateUI(); + OnWave(); + UpdateShowCtrl(); + PCRX->Color = m_Dump.m_Color[0].c; + PCTX->Color = m_Edit[0].m_Color[0].c; + m_Dump.Paint(); + m_Edit[m_CurrentEdit].Paint(); + CreateWaterColors(); + InitWater(iniwLIMIT); + UpdateMacroOnTimer(); + } + delete pBox; + OnWave(); + UpdateCharset(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitCheckValKey(LPCSTR pKey, AnsiString *pAS) +{ + m_pCheckKey = pKey; + m_pCheckBuff = pAS; +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::CheckKey(LPCSTR pTemplate) +{ + if( *m_pCheckKey != *pTemplate ) return FALSE; + return !strcmp(m_pCheckKey, pTemplate); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::CheckValKey(LPCSTR pTemplate) +{ + return CheckValKey(m_pCheckKey, pTemplate); +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::CheckValKey(LPCSTR pKey, LPCSTR pTemplate) +{ + if( *pKey != *pTemplate ) return NULL; + + BOOL f = TRUE; + LPCSTR pBase = pKey; + LPCSTR pEnd = NULL; + int seq = 0; + for( ; *pKey && *pTemplate; pKey++, pTemplate++ ){ + switch(*pTemplate){ + case '*': + pBase = pKey; + for( ; *pKey; pKey++ ){ + if( (*pKey == '<') && (*(pKey+1) == '%') ){ + seq++; + } + else if( *pKey == '>' ){ + if( seq ){ + seq--; + } + else { + pEnd = pKey; + break; + } + } + } + pTemplate++; + break; + default: +// if( *pKey != *pTemplate ) f = FALSE; + if( *pKey != *pTemplate ) return NULL; + break; + } + } + if( *pKey != *pTemplate ) f = FALSE; + if( f && pEnd ){ + int len = pEnd - pBase; + if( len < 0 ) len = 0; + if( len >= 4095 ) len = 4095; + LPSTR pBF = new char[len+1]; + if( len > 0 ){ + memcpy(pBF, pBase, len); pBF[len] = 0; + } + else { + pBF[0] = 0; + } + *m_pCheckBuff = pBF; + pBase = m_pCheckBuff->c_str(); + delete pBF; + } + return f ? pBase : NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::MacroDate(LPSTR t, SYSTEMTIME &now) +{ + switch(Log.m_LogSet.m_DateType){ + case 2: + case 3: + sprintf(t, "%02u-%s-%04u", now.wDay, MONT1[now.wMonth], now.wYear); + break; + case 4: + case 5: + sprintf(t, "%s-%02u-%04u", MONT1[now.wMonth], now.wDay, now.wYear); + break; + default: + sprintf(t, "%04u-%s-%02u", now.wYear, MONT1[now.wMonth], now.wDay); + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::MacroHisName(LPSTR t) +{ + strcpy(m_TextBuff, AnsiString(HisName->Text).c_str()); //JA7UDE 0428 + LPSTR pp; + LPSTR p = m_TextBuff; + while(*p){ + p = StrDlm(pp, p, -1); + BOOL f = m_RxSet[0].m_MBCS.IsLead((const unsigned char *)pp); + if( IsRTTY() ) f = f ? FALSE : TRUE; + if( *pp && f ){ + strcpy(t, pp); + return; + } + } + strcpy(m_TextBuff, AnsiString(HisName->Text).c_str()); //JA7UDE 0428 + p = m_TextBuff; + while(*p){ + p = StrDlm(pp, p, -1); + if( *pp ){ + strcpy(t, pp); + return; + } + } + *t = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::MacroGreeting(LPSTR t, LPCSTR pCall, int type) +{ + LPCSTR _tt[][3]={ + {"Hi", "Hello", "まいどです",}, + {"GM", "Good morning", "おはようございます",}, + {"GA", "Good afternoon", "こんにちは",}, + {"GE", "Good evening", "こんばんは",}, + }; + strcpy(t, _tt[0][type]); + if( !Cty.IsData() ) return; + LPCSTR p = ClipCC(pCall); + if( *p ){ + int n; + if( (n = Cty.GetNoP(p))!=0 ){ + CTL *cp = Cty.GetCTL(n-1); + if( cp->TD != NULL ){ + SYSTEMTIME now; + GetUTC(&now); + + WORD tim = WORD((now.wHour * 60 + now.wMinute) * 30 + now.wSecond/2); + tim = AdjustRolTimeUTC(tim, *cp->TD); + if( tim ){ + tim /= WORD(30); + if( tim < 12*60 ){ + n = 1; + } + else if( tim < 18*60 ){ + n = 2; + } + else { + n = 3; + } + strcpy(t, _tt[n][type]); + } + } + } + + } +} +//--------------------------------------------------------------------------- +static BOOL IsMMVARI(BYTE charset, int mode) +{ + BOOL r = FALSE; + + switch(mode){ + case MODE_GMSK: + case MODE_FSK: + case MODE_FSKW: + case MODE_BPSK: + switch(charset){ + case SHIFTJIS_CHARSET: + case HANGEUL_CHARSET: + case CHINESEBIG5_CHARSET: // + case 134: // 簡略 + r = TRUE; + break; + default: + break; + } + break; + default: + break; + } + return r; +} +//--------------------------------------------------------------------------- +static LPCSTR GetVariType(BYTE charset, int mode) +{ + if( (mode == MODE_RTTY) || (mode == MODE_U_RTTY) ){ + return "BAUDOT"; + } + else if( IsMFSK(mode) ){ + LPCSTR p; + switch(charset){ + case SHIFTJIS_CHARSET: + p = "VariMFSK/JA"; + break; + case HANGEUL_CHARSET: + case JOHAB_CHARSET: + p = "VariMFSK/HL"; + break; + case CHINESEBIG5_CHARSET: // + p = "VariMFSK/BV"; + break; + case 134: // 簡略 + p = "VariMFSK/BY"; + break; + default: + p = "VariMFSK"; + break; + } + return p; + } + BOOL f = (mode == ((MODE_N_BPSK)) || IsQPSK(mode)); + LPCSTR p = "VariSTD"; + switch(charset){ + case SHIFTJIS_CHARSET: + p = f ? "VariSTD/JA":"VariJA"; + break; + case HANGEUL_CHARSET: + case JOHAB_CHARSET: + p = f ? "VariSTD/HL":"VariHL"; + break; + case CHINESEBIG5_CHARSET: // + p = f ? "VariSTD/BV":"VariBV"; + break; + case 134: // 簡略 + p = f ? "VariSTD/BY":"VariBY"; + break; + default: + break; + } + return p; +} +//--------------------------------------------------------------------------- +static int GetOnOff(LPCSTR pKey) +{ + return FindStringTable(g_tOnOff, pKey, 3); +} +//--------------------------------------------------------------------------- +static int GetMacroOnOff(LPCSTR pKey) +{ + AnsiString as; + int f = FindStringTable(g_tOnOff, MainVARI->GetMacroStr(as, pKey), 3); + if( f < 0 ){ + f = MainVARI->GetMacroInt(pKey) != 0; + } + return f; +} +//--------------------------------------------------------------------------- +static BOOL __fastcall StrCond(LPCSTR p, LPCSTR v, int op) +{ + int f = strcmp(p, v); + switch(op){ + case 0: + return *p ? TRUE : FALSE; + case 1: + return !f; + case 2: + return f>=0; + case 3: + return f<=0; + case 4: + return f>0; + case 5: + return f<0; + case 6: + return f; + case 7: + return strstr(p, v)!=NULL; + default: + return FALSE; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall ValCond(double dd, double dv, int op) +{ + switch(op){ + case 0: + return dd ? TRUE : FALSE; + case 1: + return dd == dv; + case 2: + return dd >= dv; + case 3: + return dd <= dv; + case 4: + return dd > dv; + case 5: + return dd < dv; + case 6: + return dd != dv; + default: + return FALSE; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CheckCond(LPCSTR p, LPCSTR v, int type, int &op, double &d, AnsiString &as, AnsiString &vs) +{ + int l; + + if( v ){ + if( *p != *v ) return FALSE; + l = strlen(v); + if( strncmp(p, v, l) ){ + for( ; *v; v++, p++ ){ + if( *v == '*' ){ + vs = ""; + int f = 1; + for( ; *p; p++ ){ + if( *p == '(' ){ + f++; + } + else if( *p == ')' ){ + f--; + if( !f ) break; + } + vs += char(*p); + } + if( *p != ')' ) return FALSE; + p--; + } + else if( *p != *v ){ + return FALSE; + } + } + l = 0; + } + } + else { + int f = 0; + l = 0; + for( ; *p; p++ ){ + if( (*p == '<') && (*(p+1)=='%') ){ + f++; + vs += char(*p); + } + else if( *p == '>' ){ + if( f ){ + f--; + vs += char(*p); + } + else { + l = -1; + break; + } + } + else if( !f ){ + if( (*p == '=')||(*p == '<')||(*p == '!') ){ + l = -1; + break; + } + else { + vs += char(*p); + } + } + else { + vs += char(*p); + } + } + } + DelLastSpace(vs.c_str()); + + p += l; + p = SkipSpace(p); + if( !strncmp(p, "==", 2) ){ + op = 1; + p += 2; + } + else if( !strncmp(p, "!=", 2) ){ + op = 6; + p += 2; + } + else if( !strncmp(p, ">=", 2) ){ + op = 2; + p += 2; + } + else if( !strncmp(p, "<=", 2) ){ + op = 3; + p += 2; + } + else if( !strncmp(p, ">>", 2) ){ + op = 7; + p += 2; + } + else if( !strncmp(p, "=", 1) ){ + op = 1; + p++; + } + else if( !strncmp(p, ">", 1) ){ + op = 4; + p++; + } + else if( !strncmp(p, "<", 1) ){ + op = 5; + p++; + } + else if( !*p ){ + op = 0; + } + char bf[256]; + StrCopy(bf, SkipSpace(p), sizeof(bf)-1); + if( type ){ + if( bf[0] ){ + d = MainVARI->GetMacroDouble(bf); + } + else { + d = 0; + } + } + else { + if( (bf[0]=='<') && (bf[1] == '%') ){ + MainVARI->ConvMacro_(as, bf, NULL); + } + else { + as = bf; + } + } + return TRUE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::IsMBCSStr(LPCSTR p) +{ + while(*p){ + if( m_RxSet[0].m_MBCS.IsLead(*p) ) return TRUE; + p++; + } + return FALSE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::GetDataCond(LPCSTR p, int err, TSpeedButton *pButton) +{ + AnsiString vs = p; + p = DelLastSpace(vs.c_str()); + + int op; + AnsiString as, ms; + double d; + + BOOL r = FALSE; + BOOL fInv = FALSE; + p = SkipSpace(p); + if( *p == '!' ){ + p++; + fInv = TRUE; + } + if( !strcmp(p, "IsCall") ){ + r = !HisCall->Text.IsEmpty(); + } + else if( !strcmp(p, "IsName") ){ + r = !HisName->Text.IsEmpty(); + } + else if( !strcmp(p, "IsHisRST") ){ + r = !HisRST->Text.IsEmpty(); + } + else if( !strcmp(p, "IsMyRST") ){ + r = !MyRST->Text.IsEmpty(); + } + else if( !strcmp(p, "IsQTH") ){ + r = !HisQTH->Text.IsEmpty(); + } + else if( !strcmp(p, "IsNote") ){ + r = !EditNote->Text.IsEmpty(); + } + else if( !strcmp(p, "IsLocal") ){ + if( !HisCall->Text.IsEmpty() ){ + char bf[32]; + LPCSTR pCC = ClipCC(AnsiString(HisCall->Text).c_str()); //JA7UDE 0428 + strcpy(bf, Cty.GetCountry(pCC)); + pCC = ClipCC(sys.m_CallSign.c_str()); + r = !strcmp(bf, Cty.GetCountry(pCC)); + } + } + else if( !strcmp(p, "IsAFC") ){ + r = SBAFC->Down; + } + else if( !strcmp(p, "IsNET") ){ + r = SBNET->Down; + } + else if( !strcmp(p, "IsQSO") ){ + r = SBQSO->Enabled && SBQSO->Down; + } + else if( !strcmp(p, "IsTX") ){ + r = SBTX->Enabled && m_TX; + } + else if( !strcmp(p, "IsPTT") ){ + r = m_Wave.IsPTT(); + } + else if( !strcmp(p, "IsDupe") ){ + r = m_Dupe; + } + else if( !strcmp(p, "IsTone") ){ + r = SBTX->Enabled && m_TX && m_fTone; + } + else if( !strcmp(p, "IsTXEmpty") ){ + r = !m_Edit[m_CurrentEdit].GetCharCount(TRUE); + } + else if( !strcmp(p, "IsRXScroll") ){ + r = !m_Dump.IsCursorLast(); + } + else if( !strcmp(p, "IsSQ") ){ + r = m_RxSet[0].m_SQ; + } + else if( !strcmp(p, "IsIME") ){ + r = FALSE; + HWND hWnd = ActiveControl->Handle; + if( hWnd ){ + HIMC hIMC; + if( (hIMC = ::ImmGetContext(hWnd))!=NULL ){ + r = ::ImmGetOpenStatus(hIMC); + ::ImmReleaseContext(hWnd, hIMC); + } + } + } + else if( !strcmp(p, "IsUOS") ){ + r = m_RxSet[0].m_pDem->m_Decode.GetUOS(); + } + else if( !strcmp(p, "IsRadioLSB") ){ + r = m_pRadio && m_pRadio->IsRigLSB(); + } + else if( CheckCond(p, "IsCaptureText(*)", 1, op, d, as, ms) ){ + r = m_Dump.IsWindowText(GetMacroStr(as, ms.c_str())); + } + else if( !strcmp(p, "IsRepeat") ){ + r = m_fMacroRepeat; + } + else if( !strcmp(p, "IsOnTimer") ){ + r = m_pMacroOnTimer != NULL; + } + else if( !strcmp(p, "IsIdle") ){ + r = m_TX && m_ModFSK.m_Encode.m_Idle && !m_Edit[m_SendingEdit].GetCharCount(TRUE) && m_Edit[m_SendingEdit].IsCursorLast(); + } + else if( !strcmp(p, "IsFileSending") ){ + r = m_TX && (m_fpText != NULL); + } + else if( !strcmp(p, "IsPlaying") ){ + r = (m_WaveFile.m_mode == 1); + } + else if( !strcmp(p, "IsRecording") ){ + r = (m_WaveFile.m_mode == 2); + } + else if( !strcmp(p, "IsEnglish") ){ + r = sys.m_MsgEng; + } + else if( !strcmp(p, "IsMfskCenter") ){ + r = sys.m_MFSK_Center; + } + else if( !strcmp(p, "IsMfskMetricSq") ){ + r = sys.m_MFSK_SQ_Metric; + } + else if( !strcmp(p, "Is1stCR") ){ + r = KOAI->Checked; + } + else if( !strcmp(p, "IsPlayBack") ){ + r = m_PlayBack.IsActive(); + } + else if( !strcmp(p, "IsCodeMM") ){ + r = IsMMVARI(PCRX->Font->Charset, m_RxSet[0].m_Mode); + } + else if( CheckCond(p, "ValFreq", 1, op, d, as, ms) ){ + double dd; + sscanf(AnsiString(LogFreq->Text).c_str(), "%lf", &dd); //JA7UDE 0428 + r = ValCond(dd, d, op); + } + else if( CheckCond(p, "ValBaud", 1, op, d, as, ms) ){ + r = ValCond(m_RxSet[0].m_Speed, d, op); + } + else if( CheckCond(p, "ValCarrierRX", 1, op, d, as, ms) ){ + r = ValCond(UdRxCarrier->Position, d, op); + } + else if( CheckCond(p, "ValCarrierTX", 1, op, d, as, ms) ){ + r = ValCond(UdTxCarrier->Position, d, op); + } + else if( CheckCond(p, "ValPage", 1, op, d, as, ms) ){ + r = ValCond(m_CurrentEdit+1, d, op); + } + else if( CheckCond(p, "ValTimeLocal", 1, op, d, as, ms) ){ + ::GetLocal(&m_LocalTime); + r = ValCond(m_LocalTime.wHour*100 + m_LocalTime.wMinute, d, op); + } + else if( CheckCond(p, "ValTimeUTC", 1, op, d, as, ms) ){ + SYSTEMTIME now; + GetUTC(&now); + r = ValCond(now.wHour*100 + now.wMinute, d, op); + } + else if( CheckCond(p, "ValDateLocal", 1, op, d, as, ms) ){ + ::GetLocal(&m_LocalTime); + r = ValCond(m_LocalTime.wMonth*100 + m_LocalTime.wDay, d, op); + } + else if( CheckCond(p, "ValDateUTC", 1, op, d, as, ms) ){ + SYSTEMTIME now; + GetUTC(&now); + r = ValCond(now.wMonth*100 + now.wDay, d, op); + } + else if( CheckCond(p, "ValMenu", 1, op, d, as, ms) ){ + r = ValCond(m_MacroMenuNo, d, op); + } + else if( CheckCond(p, "ValScope", 1, op, d, as, ms) ){ + if( SBFFT->Down ){ + r = 0; + } + else if( SBWater->Down ){ + r = 1; + } + else { + r = 2; + } + r = ValCond(r, d, op); + } + else if( CheckCond(p, "StrCall", 0, op, d, as, ms) ){ + r = StrCond(AnsiString(HisCall->Text).c_str(), as.c_str(), op); + } + else if( CheckCond(p, "StrMode", 0, op, d, as, ms) ){ + r = StrCond(AnsiString(CBMode->Text).c_str(), as.c_str(), op); + } + else if( CheckCond(p, "StrBand", 0, op, d, as, ms) ){ + r = StrCond(_BandText[Log.m_sd.band], as.c_str(), op); + } + else if( CheckCond(p, "StrMyRST", 0, op, d, as, ms) ){ + r = StrCond(AnsiString(MyRST->Text).c_str(), as.c_str(), op); + } + else if( CheckCond(p, "StrHisRST", 0, op, d, as, ms) ){ + r = StrCond(AnsiString(HisRST->Text).c_str(), as.c_str(), op); + } + else if( CheckCond(p, "StrNote", 0, op, d, as, ms) ){ + r = StrCond(AnsiString(EditNote->Text).c_str(), as.c_str(), op); + } + else if( CheckCond(p, "StrEntity", 0, op, d, as, ms) ){ + LPCSTR pCC = ClipCC(AnsiString(HisCall->Text).c_str()); + r = StrCond(Cty.GetCountry(pCC), as.c_str(), op); + } + else if( CheckCond(p, "StrContinent", 0, op, d, as, ms) ){ + LPCSTR pCC = ClipCC(AnsiString(HisCall->Text).c_str()); + r = StrCond(Cty.GetCont(pCC), as.c_str(), op); + } + else if( CheckCond(p, "StrVARITYPE", 0, op, d, as, ms) ){ + if( IsRTTY() ){ + r = StrCond("BAUDOT", as.c_str(), op); + } + else { + r = StrCond(GetVariType(PCRX->Font->Charset, m_RxSet[0].m_Mode)+4, as.c_str(), op); + } + } + else if( CheckCond(p, "StrPLATFORM", 0, op, d, as, ms) ){ + char bf[128]; + StrWindowsVer(bf); + r = StrCond(bf, as.c_str(), op); + } + else if( CheckCond(p, "StrMacro(*)", 0, op, d, as, ms) ){ + AnsiString ts; + ConvMacro_(ts, ms.c_str(), pButton); + r = StrCond(ts.c_str(), as.c_str(), op); + } + else if( CheckCond(p, "ValMacro(*)", 1, op, d, as, ms) ){ + AnsiString ts; + ConvMacro_(ts, ms.c_str(), pButton); + double dd; + if( sscanf(ts.c_str(), "%lf", &dd) != 1 ) dd = 0; + r = ValCond(dd, d, op); + } + else if( CheckCond(p, "IsFile(*)", 0, op, d, as, ms) ){ + if( !op && !ms.IsEmpty() ){ + r = IsFile(GetMacroStr(as, ms.c_str())); + } + else { + r = FALSE; + } + } + else if( CheckCond(p, "IsDefined(*)", 1, op, d, as, ms) ){ + if( !op && !ms.IsEmpty() ){ + r = (m_MacroVal.FindName(ms.c_str(), _VAL_NORMAL|_VAL_INIFILE|_VAL_PROC) >= 0); + } + else { + r = FALSE; + } + } + else if( CheckCond(p, "IsMBCS(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = !as.IsEmpty() && IsMBCSStr(as.c_str()); + } + else if( CheckCond(p, "IsAlpha(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = !as.IsEmpty() && IsAlphaAll(as.c_str()); + } + else if( CheckCond(p, "IsNumber(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = !as.IsEmpty() && IsNumbAll(as.c_str()); + } + else if( CheckCond(p, "IsCall(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = !as.IsEmpty() && IsCall(as.c_str()); + } + else if( CheckCond(p, "IsRST(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = !as.IsEmpty() && IsRST(as.c_str()); + } + else if( CheckCond(p, "IsMenu(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TMenuItem *pMenu = GetMenuArg(ms, as.c_str(), FALSE); + r = pMenu != NULL; + } + else if( CheckCond(p, "IsMenuEnabled(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TMenuItem *pMenu = GetMenuArg(ms, as.c_str(), FALSE); + DoParentClick(pMenu); + r = pMenu && pMenu->Enabled; + } + else if( CheckCond(p, "IsMenuChecked(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TMenuItem *pMenu = GetMenuArg(ms, as.c_str(), FALSE); + DoParentClick(pMenu); + r = pMenu && pMenu->Checked; + } + else if( CheckCond(p, "IsMenuVisible(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TMenuItem *pMenu = GetMenuArg(ms, as.c_str(), FALSE); + DoParentClick(pMenu); + r = pMenu && pMenu->Visible; + } + else if( CheckCond(p, "IsButton(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + r = (FindButton(this, as.c_str(), NULL, FALSE) != NULL); + } + else if( CheckCond(p, "IsButtonEnabled(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TSpeedButton *pButton = FindButton(this, as.c_str(), NULL, TRUE); + r = pButton && pButton->Enabled; + } + else if( CheckCond(p, "IsButtonDown(*)", 1, op, d, as, ms) ){ + GetMacroStr(as, ms.c_str()); + TSpeedButton *pButton = FindButton(this, as.c_str(), NULL, TRUE); + r = pButton && pButton->Enabled && pButton->Down; + } + else if( CheckCond(p, NULL, 1, op, d, as, ms) ){ + r = ValCond(GetMacroDouble(ms.c_str()), d, op); + } + else { + r = GetMacroInt(p); + } + r = r ? TRUE : FALSE; + r = fInv ? !r : r; + return r; +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::GetDataConds(LPCSTR p, int err, TSpeedButton *pButton) +{ + BOOL r = TRUE; + int op = '&'; + LPSTR pBF = StrDupe(p); + BOOL f; + LPSTR s, t; + t = s = pBF; + for( ; *s; s++ ){ + if( ((*s=='&')&&(*(s+1)=='&')) || ((*s=='|')&&(*(s+1)=='|')) ){ + int c = *s; + *s = 0; + f = GetDataCond(t, err, pButton); + if( op == '|' ){ r = r || f; }else{ r = r && f; }; + op = c; + s++; + t = s + 1; + } + } + f = GetDataCond(t, err, pButton); + if( op == '|' ){ r = r || f; }else{ r = r && f; }; + delete pBF; + return r; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::Cond(LPCSTR p, TSpeedButton *pButton) +{ + sys.m_MacroError = FALSE; + BOOL f = FALSE; + LPCSTR sp = p; + for( ; *p; p++ ){ + if( *p == '#' ){ + if( !strncmp(p, "#if", 3) || + !strncmp(p, "#else", 5) || + !strncmp(p, "#endif", 6) || + !strncmp(p, "#define", 7) || + !strncmp(p, "#DEFINE", 7) || + !strncmp(p, "#DELETE", 7) || + !strncmp(p, "#macro", 6) || + !strncmp(p, "#exit", 5) || + !strncmp(p, "#repeat", 7) || + !strncmp(p, "#proc", 5) || + !strncmp(p, "#endp", 5) || + !strncmp(p, "#comment", 8) ){ + f = TRUE; + break; + } + } + } + if( !f ) return NULL; + + AnsiString asBuff; + CCond *pCond = new CCond(64); + TStringList *pString = new TStringList; + pString->Text = sp; + int count = pString->Count; + int cProc = 0; + AnsiString asProc, asName, asPara; + for( int i = 0; i < count; i++ ){ + LPCSTR pLine = AnsiString(pString->Strings[i]).c_str(); //JA7UDE 0428 + if( cProc ){ // procの登録 + LPCSTR p = SkipSpace(pLine); + if( !strncmp(p, "#endp", 5) ){ + if( cProc ) cProc--; + if( !cProc ){ + if( asName.IsEmpty() ){ // #repeatの実行 + int n; + CalcI(n, asPara.c_str()); + if( (n > 0) && !asProc.IsEmpty() ){ + LPSTR pBF = new char[sys.m_MacBuffSize]; + for( int i = 1; (i <= n) && !sys.m_MacroError; i++ ){ + sprintf(pBF, "%u,%u", n, i); + ConvDummy(asPara, asProc.c_str(), "$repeat,$counter", pBF); + DoMacroReturn(ConvMacro(pBF, asPara.c_str(), pButton)); + asBuff += pBF; + } + delete pBF; + } + } + else { // #procの登録 + m_MacroVal.RegisterString(asName.c_str(), asProc.c_str(), asPara.c_str(), _VAL_PROC); + } + } + else { + asProc += pLine; + asProc += "\r\n"; + } + } + else { + if( !strncmp(p, "#proc", 5) || !strncmp(p, "#repeat", 7) ) cProc++; + asProc += pLine; + asProc += "\r\n"; + } + } + else if( pCond->CondJob(pLine, pButton) ){ + LPCSTR p = SkipSpace(pLine); + if( !strncmp(p, "#proc", 5) ){ + pCond->SetCond(); + LPSTR pBF = StrDupe(SkipSpace(p+5)); + LPSTR pp = pBF; + for(; *pp; pp++ ){ + if( (*pp == ' ') || (*pp == '\t') ){ + *pp = 0; + pp++; + break; + } + } + if( pBF[0] && !isdigit(pBF[0]) ){ + asName = pBF; + asPara = SkipSpace(pp); + asProc = ""; + cProc++; + } + delete pBF; + } + else if( !strncmp(p, "#repeat", 7) ){ + pCond->SetCond(); + asName = ""; + asPara = SkipSpace(p+7); + asProc = ""; + cProc++; + } + else if( !strncmp(p, "#macro", 6) ){ + pCond->SetCond(); + p = SkipSpace(p+6); + LPSTR pBF = new char[sys.m_MacBuffSize]; + DoMacroReturn(ConvMacro_(pBF, p, pButton)); + asBuff += pBF; + delete pBF; + } + else if( !strncmp(p, "#define", 7) || !strncmp(p, "#DEFINE", 7) ){ + BYTE mtype = BYTE(*(p+1)=='D' ? _VAL_INIFILE : _VAL_NORMAL); + pCond->SetCond(); + LPSTR pBF = StrDupe(SkipSpace(p+7)); + LPSTR pp = pBF; + for(; *pp; pp++ ){ + if( (*pp == ' ') || (*pp == '\t') ){ + *pp = 0; + pp++; + break; + } + } + if( pBF[0] && !isdigit(pBF[0]) ){ + pp = SkipSpace(pp); + m_MacroVal.RegisterString(pBF, GetMacroStr(asProc, pp), NULL, mtype); + } + delete pBF; + } + else if( !strncmp(p, "#DELETEALL", 10) ){ + pCond->SetCond(); + m_MacroVal.Delete(_VAL_NORMAL|_VAL_INIFILE); + } + else if( !strncmp(p, "#DELETE", 7) ){ + pCond->SetCond(); + m_MacroVal.Delete(SkipSpace(p+7), _VAL_NORMAL|_VAL_INIFILE|_VAL_PROC); + } + else if( !strncmp(p, "#exit", 5) ){ + pCond->SetCond(); + pCond->ClearLevel(); + break; + } + else if( !strncmp(p, "#comment", 8) ){ + pCond->SetCond(); + } + else { + asBuff += pString->Strings[i]; + asBuff += '\r'; + } + } + } + delete pString; + f = pCond->IsCond(); + BOOL fLevel = pCond->GetLevel(); + delete pCond; + if( !f ){ + return NULL; + } + else if( !sys.m_MacroError ){ + if( fLevel ){ + sys.m_MacroError = TRUE; + InfoMB(sys.m_MsgEng ? "#if-#endif block is not closed..." : "#if〜#endifブロックを終了していません."); + } + else if( cProc ){ + sys.m_MacroError = TRUE; + InfoMB(sys.m_MsgEng ? "Procedure block is not closed... (#endp is necessary)":"プロシジャーブロックを終了していません (#endpが必要です)."); + } + } + return StrDupe(asBuff.c_str()); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::ConvMacro(LPSTR t, LPCSTR p, TSpeedButton *pButton) +{ + LPCSTR bp = Cond(p, pButton); + if( bp ) p = bp; + int r = ConvMacro_(t, p, pButton); + if( bp ) delete bp; + return r; +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::ConvMacro(AnsiString &as, LPCSTR p, TSpeedButton *pButton) +{ + LPCSTR bp = Cond(p, pButton); + if( bp ) p = bp; + int r = ConvMacro_(as, p, pButton); + if( bp ) delete bp; + return r; +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::ConvMacro_(AnsiString &as, LPCSTR p, TSpeedButton *pButton) +{ + LPSTR bp = new char[sys.m_MacBuffSize]; + int r = ConvMacro_(bp, p, pButton); + as = bp; + delete bp; + return r; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::GetMacroValue(LPCSTR pVal) +{ + pVal = SkipSpace(pVal); + int r = m_MacroVal.FindName(pVal, _VAL_NORMAL|_VAL_INIFILE); + if( r >= 0 ){ + pVal = m_MacroVal.GetString(r); + } + return pVal; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TMainVARI::GetMacroStr(AnsiString &as, LPCSTR pVal) +{ + pVal = GetMacroValue(pVal); + if( strstr(pVal, "<%") ){ + ConvMacro_(as, pVal, NULL); + } + else { + as = pVal; + } + return as.c_str(); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetMacroInt(LPCSTR pVal) +{ + if( !*pVal ) return 0; + + AnsiString as; + GetMacroStr(as, pVal); + int d; + if( sscanf(SkipToValue(as.c_str()), "%d", &d) != 1 ) d = 0; + return d; +} +//--------------------------------------------------------------------------- +double __fastcall TMainVARI::GetMacroDouble(LPCSTR pVal) +{ + if( !*pVal ) return 0; + + AnsiString as; + GetMacroStr(as, pVal); + double d; + if( sscanf(SkipToValue(as.c_str()), "%lf", &d) != 1 ) d = 0; + return d; +} +//--------------------------------------------------------------------------- +static LPCSTR __fastcall ClipRST(LPSTR bf, LPCSTR p) +{ + if( strlen(p) <= 3 ) return p; + StrCopy(bf, p, 3); bf[3] = 0; + return bf; +} +//--------------------------------------------------------------------------- +static LPCSTR __fastcall ClipNR(LPCSTR p) +{ + if( strlen(p) <= 3 ) return ""; + return p + 3; +} +//--------------------------------------------------------------------------- +static LPSTR __fastcall strchrl(LPSTR p, LPSTR v) +{ + LPSTR t; + while(*v){ + if( (t = strchr(p, *v++))!= NULL ) return t; + } + return NULL; +} +//--------------------------------------------------------------------------- +static void __fastcall EncodeColors(LPSTR t, UCOL *pColors, int max) +{ + int i; + for( i = 0; i < max; i++ ){ + if( i ) *t++ = ','; + sprintf(t, "%06X", pColors[i].d); t += strlen(t); + } +} +//--------------------------------------------------------------------------- +static BOOL __fastcall DecodeColors(LPCSTR p, UCOL *pColors, int max) +{ + AnsiString as; + LPSTR pBF = StrDupe(MainVARI->GetMacroStr(as, p)); + LPSTR pp, tt; + pp = SkipSpace(pBF); + int n = 0; + while(*pp && (n < max)){ + pp = SkipSpace(StrDlm(tt, pp)); + pColors[n].d = htoin(MainVARI->GetMacroStr(as, tt), -1); + n++; + } + delete pBF; + return n != 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnMacroMenuClick(TObject *Sender) +{ + TMenuItem *pMenu = (TMenuItem *)Sender; + m_MacroInput = pMenu->Caption; + + if( !m_pMacroPopup ) return; + int i, n; + for( i = n = 0; i < m_pMacroPopup->Items->Count; i++ ){ + TMenuItem *pRef = m_pMacroPopup->Items->Items[i]; + if( pRef->Caption != "-" ){ + if( pRef == pMenu ){ + m_MacroMenuNo = n + 1; + break; + } + n++; + } + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::ConvMacro_(LPSTR t, LPCSTR p, TSpeedButton *pButton) +{ + int r = 0; + int f; + AnsiString as, vs; + SYSTEMTIME now; + BOOL fKanji = FALSE; + LPCSTR pVal; + UINT cDisCR = 0; + BOOL fDisTAB = FALSE; + BOOL fDisSP = FALSE; + while(*p){ + if( fKanji ){ + fKanji = FALSE; + *t++ = *p++; + } + else if( m_RxSet[0].m_MBCS.IsLead(*p) ){ + fKanji = TRUE; + *t++ = *p++; + } + else if( (*p == '<') && (*(p+1) == '%') ){ + *t = 0; + AnsiString key; + int seq = 0; + for( p+=2; *p ; p++ ){ + key += char(*p); + if( (*p == '<') && (*(p+1) == '%') ){ + seq++; + } + else if( *p == '>' ){ + if( seq ){ + seq--; + } + else { + p++; + break; + } + } + } + LPCSTR pKey = key.c_str(); + InitCheckValKey(pKey, &vs); + if( CheckKey("TX>") ){ + r |= macTX; + } + else if( CheckKey("RX>") ){ + r |= macRX; + } + else if( CheckKey("TXRX>") ){ + r |= macTXRX; + } + else if( CheckKey("TXOFF>") ){ + r |= macTXOFF; + } + else if( CheckKey("TONE>") ){ + r |= macTONE; + } + else if( CheckKey("MyCall>") ){ + strcpy(t, sys.m_CallSign.c_str()); + } + else if( CheckKey("HisCall>") ){ + strcpy(t, AnsiString(HisCall->Text).c_str()); //JA7UDE 0428 + } + else if( CheckKey("HisName>") ){ + MacroHisName(t); + } + else if( CheckKey("DearName>") ){ + char bf[256]; + MacroHisName(bf); + if( bf[0] ){ + if( (PCRX->Font->Charset == SHIFTJIS_CHARSET) && m_RxSet[0].m_MBCS.IsLead(bf[0]) ){ + sprintf(t, "%sさん", bf); + } + else { + sprintf(t, "Dear %s", bf); + } + } + } + else if( CheckKey("HisRST>") ){ + char bf[MLRST+1]; + strcpy(t, ClipRST(bf, AnsiString(HisRST->Text).c_str())); //JA7UDE 0428 + } + else if( CheckKey("MyRST>") ){ + char bf[MLRST+1]; + strcpy(t, ClipRST(bf, AnsiString(MyRST->Text).c_str())); //JA7UDE 0428 + } + else if( CheckKey("HisNR>") ){ + strcpy(t, ClipNR(AnsiString(HisRST->Text).c_str())); //JA7UDE 0428 + } + else if( CheckKey("MyNR>") ){ + strcpy(t, ClipNR(AnsiString(MyRST->Text).c_str())); //JA7UDE 0428 + } + else if( CheckKey("HisQTH>") ){ + strcpy(t, AnsiString(HisQTH->Text).c_str()); //JA7UDE 0428 + } + else if( CheckKey("Note>") ){ + strcpy(t, AnsiString(EditNote->Text).c_str()); //JA7UDE 0428 + } + else if( CheckKey("AutoClear>") ){ + r |= macAUTOCLEAR; + } + else if( CheckKey("AutoReturn>") ){ + m_ReqAutoReturn = TRUE; + m_SaveEditPage = m_CurrentEdit; + } + else if( CheckKey("AutoNET>") ){ + m_ReqAutoNET = TRUE; + } + else if( CheckKey("ClearTXW>") ){ + KVCTClick(NULL); + } + else if( CheckKey("ClearRXW>") ){ + KVCRClick(NULL); + } + else if( CheckKey("MoveTop>") ){ + *t++ = button1ST; *t++ = button2ND; *t++ = buttonMOVETOP; *t = 0; + } + else if( CheckKey("MoveEnd>") ){ + *t++ = button1ST; *t++ = button2ND; *t++ = buttonMOVEEND; *t = 0; + } + else if( CheckKey("ResetScroll>") ){ + if( SBarRX->Enabled ){ + SBarRX->Position = SBarRX->Max; + SetTXFocus(); + } + } + else if( CheckKey("DupeText>") ){ + m_Edit[m_CurrentEdit].DupeText(1); + } + else if( CheckKey("PopupTXW>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + RECT rc; + ::GetWindowRect(PCTX->Handle, &rc); + int X, Y; + m_Edit[m_CurrentEdit].GetCursorPos(X, Y); + rc.left += X; rc.top += Y+8; + PupTX->Popup(rc.left, rc.top); + } + else if( CheckKey("NETON>") ){ + if( SBNET->Enabled ){ + SBNET->Down = TRUE; + SBNETClick(NULL); + } + } + else if( CheckKey("NETOFF>") ){ + if( SBNET->Enabled ){ + SBNET->Down = FALSE; + SBNETClick(NULL); + } + } + else if( CheckKey("AFCON>") ){ + if( SBAFC->Enabled ){ + SBAFC->Down = TRUE; + SBAFCClick(NULL); + } + } + else if( CheckKey("AFCOFF>") ){ + if( SBAFC->Enabled ){ + SBAFC->Down = FALSE; + SBAFCClick(NULL); + } + } + else if( CheckKey("ATCON>") ){ + if( SBATC->Enabled ){ + SBATC->Down = TRUE; + SBATCClick(NULL); + } + } + else if( CheckKey("ATCOFF>") ){ + if( SBATC->Enabled ){ + SBATC->Down = FALSE; + SBATCClick(NULL); + } + } + else if( CheckKey("FREQ>") ){ + strcpy(t, AnsiString(LogFreq->Text).c_str()); //JA7UDE 0428 + } + else if( CheckKey("BAND>") ){ + strcpy(t, _BandText[Log.m_sd.band]); + } + else if( CheckKey("UDATE>") ){ + GetUTC(&now); + MacroDate(t, now); + } + else if( CheckKey("LDATE>") ){ + GetLocal(&now); + MacroDate(t, now); + } + else if( CheckKey("UTIME>") ){ + GetUTC(&now); + sprintf(t, "%02u:%02u", now.wHour, now.wMinute); + } + else if( CheckKey("LTIME>") ){ + GetLocal(&now); + sprintf(t, "%02u:%02u", now.wHour, now.wMinute); + } + else if( CheckKey("UTIMES>") ){ + GetUTC(&now); + sprintf(t, "%02u:%02u:%02u", now.wHour, now.wMinute, now.wSecond); + } + else if( CheckKey("LTIMES>") ){ + GetLocal(&now); + sprintf(t, "%02u:%02u:%02u", now.wHour, now.wMinute, now.wSecond); + } + else if( CheckKey("QSOON>") ){ + if( SBQSO->Enabled && !SBQSO->Down ){ + SBQSO->Down = TRUE; + SBQSOClick(NULL); + } + } + else if( CheckKey("PTIME>") ){ + GetUTC(&now); + sprintf(t, "%u", SystemTime2GPS(&now)); + } + else if( CheckKey("LPTIME>") ){ + GetLocal(&now); + sprintf(t, "%u", SystemTime2GPS(&now)); + } + else if( CheckKey("QPTIME>") ){ + sprintf(t, "%u", m_QSOStart); + } + else if( CheckKey("ATCPPM>") ){ + sprintf(t, "%d", m_RxSet[0].m_pDem->GetClockError()); + } + else if( CheckKey("CPUBENCHMARK>") ){ + DoBench(t, 0); + } + else if( CheckKey("BENCHDECM>") ){ + DoBench(t, 1); + } + else if( CheckKey("RANDOM>") ){ + sprintf(t, "%d", rand()); + } + else if( CheckKey("QSOOFF>") ){ + if( SBQSO->Enabled && SBQSO->Down ){ + SBQSO->Down = FALSE; + SBQSOClick(NULL); + } + } + else if( CheckKey("MODE>") ){ + strcpy(t, g_tDispModeTable[m_RxSet[0].m_Mode]); + } + else if( CheckKey("VARITYPE>") ){ + strcpy(t, GetVariType(PCRX->Font->Charset, m_RxSet[0].m_Mode)); + } + else if( CheckKey("BAUD>") ){ + char bf[256]; + strcpy(t, StrDbl(bf, m_RxSet[0].IsMFSK() ? m_RxSet[0].m_pDem->m_MFSK_SPEED : m_RxSet[0].m_Speed)); + } + else if( CheckKey("SkipCR>") ){ + cDisCR++; + } + else if( CheckKey("DisableCR>") ){ + cDisCR = 0x7fffffff; + } + else if( CheckKey("EnableCR>") ){ + cDisCR = 0; + } + else if( CheckKey("DisableTAB>") ){ + fDisTAB = TRUE; + } + else if( CheckKey("EnableTAB>") ){ + fDisTAB = 0; + } + else if( CheckKey("DisableSP>") ){ + fDisSP = TRUE; + } + else if( CheckKey("EnableSP>") ){ + fDisSP = 0; + } + else if( CheckKey("SP>") ){ + *t++ = ' '; *t = 0; + } + else if( CheckKey("CR>") ){ + *t++ = '\r'; *t = 0; + } + else if( CheckKey("BS>") ){ + *t++ = '\b'; *t = 0; + } + else if( CheckKey("TAB>") ){ + *t++ = '\t'; *t = 0; + } + else if( CheckKey("IDLE>") ){ + *t++ = button1ST; *t++ = button2ND; *t++ = buttonIDLE; + *t = 0; + } + else if( CheckKey("SeekTop>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + f = UdMac->Max - UdMac->Position + 1; + if( f > UdMac->Max ) f = 0; + if( f ){ + ::PostMessage(Handle, WM_WAVE, waveSeekMacro, f); + r |= macSEEK; pButton = NULL; + } + } + else if( CheckKey("SeekNext>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + ::PostMessage(Handle, WM_WAVE, waveSeekMacro, 1); + r |= macSEEK; pButton = NULL; + } + else if( CheckKey("SeekPrev>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + ::PostMessage(Handle, WM_WAVE, waveSeekMacro, -1); + r |= macSEEK; pButton = NULL; + } + else if( CheckKey("Exit>") ){ + Close(); + } + else if( CheckKey("ShutDown>") ){ + ShutDown(); + } + else if( CheckKey("Suspend>") ){ + DoSuspend(TRUE); + } + else if( CheckKey("Resume>") ){ + DoResume(); + } + else if( CheckKey("PTTON>") ){ + SetPTT(TRUE); + } + else if( CheckKey("PTTOFF>") ){ + SetPTT(FALSE); + } + else if( CheckKey("VER>") ){ + strcpy(t, VERNO); + } + else if( CheckKey("VERMINOR>") ){ + strcpy(t, VERBETA); + } + else if( CheckKey("RxCarrier>") ){ + sprintf(t, "%u", UdRxCarrier->Position); + } + else if( CheckKey("TxCarrier>") ){ + sprintf(t, "%u", UdTxCarrier->Position); + } + else if( CheckKey("AFCFrequency>") ){ + double fq; + if( m_TX == txINTERNAL ){ + fq = m_ModFSK.m_CarrierFreq; + } + else { + fq = m_RxSet[0].m_pDem->m_RxFreq; + } + sprintf(t, (m_RxSet[0].Is170() || m_RxSet[0].IsMFSK()) ? "%.0lf":"%.1lf", fq); + } + else if( CheckKey("MouseFrequency>") ){ + sprintf(t, "%d", m_RightFreq); + } + else if( CheckKey("Input$>") ){ + strcpy(t, m_MacroInput.c_str()); + } + else if( CheckKey("Click$>") ){ + strcpy(t, m_StrSel.c_str()); + } + else if( CheckKey("CLICK$>") ){ + strcpy(t, m_UStrSel.c_str()); + } + else if( CheckKey("vvv>") ){ + strcpy(t, "the quick brown fox jumps over a lazy dog"); + } + else if( CheckKey("VVV>") ){ + strcpy(t, "天気晴朗なれど対馬の沖に波高し"); + } + else if( CheckKey("PLATFORM>") ){ + strcpy(t, "Windows "); t += strlen(t); + StrWindowsVer(t); + } + else if( CheckKey("OutputVolume>") ){ + KOVOClick(KOVO); + } + else if( CheckKey("InputVolume>") ){ + KOVOClick(KOVI); + } + else if( CheckKey("Setup>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + KOOClick(KOO); + } + else if( CheckKey("SetupLog>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + KOLClick(NULL); + } + else if( CheckKey("SetupRadio>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + KORClick(NULL); + } + else if( CheckKey("Calibration>") ){ +// if( pButton && pButton->Down ) pButton->Down = FALSE; + KOAClick(NULL); + } + else if( CheckKey("PlaySound>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + KFRSClick(NULL); + } + else if( CheckKey("RecordSound>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + KFWSClick(NULL); + } + else if( CheckKey("QuickRecordSound>") ){ + KFWSTClick(NULL); + } + else if( CheckKey("StopPlayRecord>") ){ + KFESClick(NULL); + } + else if( CheckKey("SoundTime>") ){ + sprintf(t, "%u", UINT(m_WaveFile.GetPos()*0.5/SAMPFREQ)); + } + else if( CheckKey("Level>") ){ + sprintf(t, "%d", m_RxSet[0].m_StgFFT.DispSig); + } + else if( CheckKey("PeakLevel>") ){ + sprintf(t, "%d", m_RxSet[0].m_PeakSig); + } + else if( CheckKey("AverageLevel>") ){ + sprintf(t, "%d", int(m_RxSet[0].m_AvgSig.GetAvg()+0.5)); + } + else if( CheckKey("CWID>") ){ + *t++ = button1ST; *t++ = button2ND; *t++ = buttonCWON; + strcpy(t, sys.m_CallSign.c_str()); t += strlen(t); + *t++ = button1ST; *t++ = button2ND; *t++ = buttonCWOFF; + *t = 0; + } + else if( (pVal = CheckValKey("CWID=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + *t++ = button1ST; *t++ = button2ND; *t++ = buttonCWON; + for( ; *pVal; pVal++ ) *t++ = *pVal; + *t++ = button1ST; *t++ = button2ND; *t++ = buttonCWOFF; + *t = 0; + } + else if( CheckKey("DigitalLevel>") ){ + sprintf(t, "%u", m_ModGain); + } + else if( (pVal = CheckValKey("DigitalLevel=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f >= 1024 ){ + if( f > 32768 ) f = 32768; + m_ModGain = f; + UpdateModGain(); + } + } + else if( (pVal = CheckValKey("ToLower=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + strcpy(t, (LPSTR)jstrlwr(LPUSTR(pBF))); + delete pBF; + } + else if( (pVal = CheckValKey("ToUpper=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + strcpy(t, (LPSTR)jstrupr(LPUSTR(pBF))); + delete pBF; + } + else if( (pVal = CheckValKey("Page=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= 4) ){ + f--; + SetEditPage(f); + } + } + else if( CheckKey("LogMODE>") ){ + strcpy(t, Log.GetModeString(Log.m_sd.mode)); + } + else if( (pVal = CheckValKey("LogMODE=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + m_strLogMode = pVal; + UpdateLogMode(); + } + else if( (pVal = CheckValKey("BAND=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + for(f = 0; _BandText[f]; f++ ){ + if( !strcmpi(pVal, _BandText[f]) ){ + LogFreq->Text = Log.GetFreqString(BYTE(f), 0); + OnLogFreq(FALSE); + break; + } + } + } + } + else if( (pVal = CheckValKey("FREQ=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + LogFreq->Text = pVal; + OnLogFreq(FALSE); + } + } + else if( (pVal = CheckValKey("HisCall=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + HisCall->Text = pVal; + FindCall(); + UpdateUI(); + SetTXFocus(); + } + } + else if( (pVal = CheckValKey("HisRST=*>"))!=NULL ){ + HisRST->Text = GetMacroStr(as, pVal); + } + else if( (pVal = CheckValKey("MyRST=*>"))!=NULL ){ + MyRST->Text = GetMacroStr(as, pVal); + } + else if( (pVal = CheckValKey("Note=*>"))!=NULL ){ + EditNote->Text = GetMacroStr(as, pVal); + } + else if( (pVal = CheckValKey("IME=*>"))!=NULL ){ + f = GetMacroOnOff(pVal); + if( f >= 0 ){ + HWND hWnd = ActiveControl->Handle; + if( hWnd ){ + HIMC hIMC; + if( (hIMC = ::ImmGetContext(hWnd))!=NULL ){ + if( f == 2 ){ + f = !::ImmGetOpenStatus(hIMC); + } + ::ImmSetOpenStatus(hIMC, f); + ::ImmReleaseContext(hWnd, hIMC); + } + } + } + } + else if( (pVal = CheckValKey("HisGreetings=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= 3) ){ + MacroGreeting(t, AnsiString(HisCall->Text).c_str(), f-1); //JA7UDE 0428 + } + } + else if( (pVal = CheckValKey("Entity=*>"))!=NULL ){ + strcpy(t, Cty.GetCountry(ClipCC(GetMacroStr(as, pVal)))); + } + else if( (pVal = CheckValKey("Continent=*>"))!=NULL ){ + strcpy(t, Cty.GetCont(ClipCC(GetMacroStr(as, pVal)))); + } + else if( (pVal = CheckValKey("EntityName=*>"))!=NULL ){ + if( (f = Cty.GetNoP(ClipCC(GetMacroStr(as, pVal))))!=0 ){ + CTL *cp = Cty.GetCTL(f-1); + strcpy(t, (cp->QTH!=NULL) ? cp->QTH : ""); + } + } + else if( (pVal = CheckValKey("RANDOM=*>"))!=NULL ){ + srand(GetMacroInt(pVal)); + } + else if( (pVal = CheckValKey("Wait=*>"))!=NULL ){ + f = GetMacroInt(pVal); + f /= 10; + CWaitCursor w; + for( ; f; f-- ){ + OnWave(); + ::Sleep(10); + } + } + else if( (pVal = CheckValKey("MacroText=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + AnsiString ts; + GetFullPathName(ts, pVal, sys.m_MacroDir); + FILE *fp = fopen(ts.c_str(), "rb"); + int len = sys.m_MacBuffSize; + if( fp ){ + LPSTR pBF = new char[len]; + int rlen = fread(pBF, 1, len-1, fp); + if( rlen > 0 ){ + pBF[rlen] = 0; + r |= ConvMacro(as, pBF, pButton); + StrCopy(t, as.c_str(), len/2); + } + delete pBF; + fclose(fp); + } + } + } + else if( (pVal = CheckValKey("SendFile=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + if( m_fpText ) fclose(m_fpText); + ::SetCurrentDirectory(sys.m_BgnDir); + if( (m_fpText = fopen(pVal, "rb")) != NULL ){ + r |= macTX; + } + } + } + else if( (pVal = CheckValKey("RefRXW>"))!=NULL ){ + AnsiString rs; + m_Dump.GetWindowText(rs); + if( !m_pEdit ){ + m_pEdit = new TFileEdit(this); + m_pEdit->SetEvent(Handle, WM_WAVE, 2); + } + m_pEdit->Execute(rs, "Received text", "Received.txt"); + } + else if( (pVal = CheckValKey("EditFile=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + pVal = GetMacroStr(as, tt); + if( *pVal ){ + if( !m_pEdit ){ + m_pEdit = new TFileEdit(this); + m_pEdit->SetEvent(Handle, WM_WAVE, 2); + } + f = GetMacroInt(pp); + m_pEdit->SetWordWrap(f & 2 ? FALSE : TRUE); + m_pEdit->Execute(pVal, f & 1); + } + delete pBF; + } + else if( (pVal = CheckValKey("SaveMacro=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + SaveMacro(pVal); + } + } + else if( (pVal = CheckValKey("LoadMacro=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + ::PostMessage(Handle, WM_WAVE, waveLoadMacro, DWORD(StrDupe(pVal))); + } + } + else if( (pVal = CheckValKey("PlaySound=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + AnsiString as; + GetFullPathName(as, pVal); + m_Wave.InClose(); + m_WaveFile.Play(as.c_str()); + ReOutOpen(); + if( !m_pPlayBox ){ + m_pPlayBox = new TPlayDlgBox(this); + } + m_pPlayBox->Execute(&m_WaveFile); + m_pPlayBox->Visible = TRUE; + m_pPlayBox->SetFocus(); + } + } + else if( (pVal = CheckValKey("RecordSound=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + AnsiString as; + GetFullPathName(as, pVal); + m_WaveFile.Rec(as.c_str()); + KFWST->Checked = FALSE; KFWS->Checked = TRUE; + } + } + else if( (pVal = CheckValKey("Slider=*>"))!=NULL ){ + CWaitCursor w; + if( pButton && pButton->Down ) pButton->Down = FALSE; + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + pVal = GetMacroStr(as, tt); + pp = StrDlm(tt, pp); + double d = GetMacroDouble(tt); + pp = StrDlm(tt, pp); + double dmin = GetMacroDouble(tt); + pp = StrDlm(tt, pp); + double dmax = GetMacroDouble(tt); + pp = StrDlm(tt, pp); + double per = GetMacroDouble(tt); + StrDlm(tt, pp); + int sc = GetMacroInt(tt); + m_MacroInput = ""; + DettachFocus(); + OnWave(); + TTrackDlgBox *pBox = new TTrackDlgBox(this); + f = pBox->Execute(pVal, d, dmin, dmax, sc, per); + delete pBox; + AttachFocus(); + if( f ){ + char bf[256]; + m_MacroInput = StrDbl(bf, d); + } + delete pBF; + } + else if( (pVal = CheckValKey("FileDialog=*>"))!=NULL ){ + CWaitCursor w; + if( pButton && pButton->Down ) pButton->Down = FALSE; + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + pVal = GetMacroStr(as, tt); + if( *pVal ) pBox->Title = pVal; + pp = StrDlm(tt, pp); + pBox->Filter = GetMacroStr(as, tt); + pp = StrDlm(tt, pp); + pBox->FileName = GetMacroStr(as, tt); + pp = StrDlm(tt, pp); + pBox->DefaultExt = GetMacroStr(as, tt); + StrDlm(tt, pp); + pVal = GetMacroStr(as, tt); + pBox->InitialDir = *pVal ? pVal : sys.m_BgnDir; + DettachFocus(); + OnWave(); + m_MacroInput = ""; + if( pBox->Execute() ){ + m_MacroInput = pBox->FileName.c_str(); + } + delete pBox; + delete pBF; + AttachFocus(); + } + else if( CheckKey("ListSpeed>") ){ + GetComboBox(as, CBSpeed); strcpy(t, as.c_str()); + } + else if( (pVal = CheckValKey("ListSpeed=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + m_ListBAUD = pVal; + if( !m_RxSet[0].IsMFSK() && !m_RxSet[0].IsRTTY() ){ + SetComboBox(CBSpeed, pVal); + } + } + } + else if( CheckKey("ListCarrier>") ){ + GetComboBox(as, CBRXCarrier); strcpy(t, as.c_str()); + } + else if( (pVal = CheckValKey("ListCarrier=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + SetComboBox(CBRXCarrier, pVal); + SetComboBox(CBTxCarrier, pVal); + } + } + else if( CheckKey("ListRST>") ){ + GetComboBox(as, HisRST); strcpy(t, as.c_str()); + } + else if( (pVal = CheckValKey("ListRST=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + SetComboBox(HisRST, pVal); + SetComboBox(MyRST, pVal); + } + } + else if( CheckKey("ListLogFreq>") ){ + GetComboBox(as, LogFreq); strcpy(t, as.c_str()); + } + else if( (pVal = CheckValKey("ListLogFreq=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + SetComboBox(LogFreq, pVal); + } + } + else if( CheckKey("CWSpeed>") ){ + sprintf(t, "%d", m_ModFSK.GetCWSpeed()); + } + else if( (pVal = CheckValKey("CWSpeed=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 10) && (f <= 60) ){ + m_ModFSK.SetCWSpeed(f); + } + } + else if( (pVal = CheckValKey("RxCarrier=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + SetRxFreq(f); + } + } + else if( (pVal = CheckValKey("TxCarrier=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + SetTxFreq(f); + } + } + else if( CheckKey("Clock>") ){ + sprintf(t, "%.2lf", SAMPFREQ); + } + else if( CheckKey("BaseClock>") ){ + sprintf(t, "%u", SAMPBASE); + } + else if( CheckKey("TxOffset>") ){ + sprintf(t, "%.2lf", SAMPTXOFFSET); + } + else if( CheckKey("DemodulatorClock>") ){ + sprintf(t, "%.2lf", DEMSAMPFREQ); + } + else if( CheckKey("FFTClock>") ){ + sprintf(t, "%.2lf", m_FFTSampFreq); + } + else if( CheckKey("FFTSize>") ){ + sprintf(t, "%u", FFT_SIZE); + } + else if( CheckKey("SoundName>") ){ + m_Wave.GetInDevName(as); + strcpy(t, as.c_str()); + } + else if( CheckKey("SoundOutName>") ){ + m_Wave.GetOutDevName(as); + strcpy(t, as.c_str()); + } + else if( CheckKey("SoundDevice>") ){ + LPCSTR pVal = g_tSoundCH[m_Wave.m_SoundStereo]; + if( m_Wave.m_SoundID == -2 ){ + sprintf(t, "%s,%s", pVal, sys.m_SoundMMW.c_str()); + } + else { + sprintf(t, "%s,%d", pVal, m_Wave.m_SoundID); + if( m_Wave.m_SoundID != m_Wave.m_SoundTxID ){ + t += strlen(t); + sprintf(t, ",%d", m_Wave.m_SoundTxID); + } + } + } + else if( (pVal = CheckValKey("SoundDevice=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + pVal = GetMacroStr(as, tt); + f = FindStringTable(g_tSoundCH, pVal, 3); + if( f < 0 ) f = m_Wave.m_SoundStereo; + pp = StrDlm(tt, pp); + pVal = GetMacroStr(as, tt); + { + AnsiString ts; + LPCSTR pVal2 = GetMacroStr(ts, pp); + SetSoundCard(f, *pVal ? pVal : NULL, *pVal2 ? pVal2 : pVal); + } + delete pBF; + } + else if( (pVal = CheckValKey("Clock=*>"))!=NULL ){ + double d = GetMacroDouble(pVal); + if( (d >= MIN_SAMP) && (d <= MAX_SAMP) ){ + SetSampleFreq(d, FALSE); + } + } + else if( (pVal = CheckValKey("TxOffset=*>"))!=NULL ){ + double d = GetMacroDouble(pVal); + if( fabs(d) <= 3000.0 ){ + SetTxOffset(d); + } + } + else if( CheckKey("FFTScale>") ){ + sprintf(t, "%d", m_FFTVType); + } + else if( (pVal = CheckValKey("FFTScale=*>"))!=NULL ){ + f = GetMacroInt(pVal); + switch(f){ + case 0: + KVF1Click(KVF1); + break; + case 1: + KVF1Click(KVF2); + break; + default: + KVF1Click(KVF3); + break; + } + } + else if( CheckKey("BPFTaps>") ){ + sprintf(t, "%d,%d,%d,%d", g_tBpfTaps[0], g_tBpfTaps[1], g_tBpfTaps[2], g_tBpfTaps[3]); + } + else if( (pVal = CheckValKey("BPFTaps=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = SkipSpace(pBF); + for( int n = 0; *pp && (n < 4); n++ ){ + pp = SkipSpace(StrDlm(tt, pp)); + if( *tt ){ + f = GetMacroInt(tt) & 0x0000fffe; + if( (f >= 8) && (f <= 512) ){ + g_tBpfTaps[n] = f; + } + } + } + delete pBF; + SBBPFWClick(GetBPF(GetBPFType())); + } + else if( (pVal = CheckValKey("BPF=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 0) && (f < 4) ){ + TSpeedButton *pButton = GetBPF(f); + pButton->Down = TRUE; + SBBPFWClick(pButton); + } + } + else if( CheckKey("NotchTaps>") ){ + sprintf(t, "%d", m_Notches.m_nBaseTaps); + } + else if( (pVal = CheckValKey("NotchTaps=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 16) && (f <= TAPMAX) ){ + m_Notches.m_nBaseTaps = f & 0x0ffe; + m_Notches.Create(); + } + } + else if( CheckKey("NotchWidth>") ){ + sprintf(t, "%d", m_Notches.m_NotchWidth); + } + else if( (pVal = CheckValKey("NotchWidth=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= 1000) ){ + m_Notches.m_NotchWidth = f; + m_Notches.Create(); + } + } + else if( CheckKey("Notch>") ){ + sprintf(t, "%d", m_Notches.m_Count ? m_Notches.m_pBase[0].Freq : 0); + } + else if( (pVal = CheckValKey("Notch=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + switch(GetOnOff(pVal)){ + case 0: + m_Notches.Delete(); + break; + case 1: + if( !m_Notches.m_Count ){ + m_Notches.Add(m_NotchFreq); + } + break; + case 2: + if( m_Notches.m_Count ){ + m_Notches.Delete(); + } + else { + m_Notches.Add(m_NotchFreq); + } + break; + default: + f = GetMacroInt(pVal); + if( f ){ + m_Notches.Add(f); + m_NotchFreq = f; + } + else { + m_Notches.Delete(); + } + break; + } + } + else if( (pVal = CheckValKey("BAUD=*>"))!=NULL ){ + double b = GetMacroDouble(pVal); + if( b > 0 ){ + if( m_RxSet[0].IsMFSK() || ((b >= MIN_SPEED) && (b <= MAX_SPEED)) ){ + UpdateSpeed(&m_RxSet[0], b); + } + } + } + else if( CheckKey("SquelchLevel>") ){ + sprintf(t, "%.1lf", double(m_RxSet[0].m_SQLevel * 0.01)); + } + else if( (pVal = CheckValKey("SquelchLevel=*>"))!=NULL ){ + if( *pVal ){ + f = GetMacroInt(pVal) * 100.0; + if( f < 0 ) f = 0; + if( f > 2048 ) f = 2048; + m_RxSet[0].m_SQLevel = f; + } + } + else if( CheckKey("AFCWidth>") ){ + sprintf(t, "%d", m_AFCWidth); + } + else if( (pVal = CheckValKey("AFCWidth=*>"))!=NULL ){ + if( *pVal ){ + f = GetMacroInt(pVal); + if( (f >= 0) && (f <= 2000) ){ + m_AFCWidth = f; + } + } + } + else if( CheckKey("AFCLevel>") ){ + sprintf(t, "%d", m_AFCLevel); + } + else if( (pVal = CheckValKey("AFCLevel=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 3) && (f < 20) ){ + m_AFCLevel = f; + } + } + else if( CheckKey("PTT>") ){ + strcpy(t, sys.m_PTTCOM.c_str()); + } + else if( CheckKey("Radio>") ){ + strcpy(t, RADIO.StrPort); + } + else if( (pVal = CheckValKey("PTT=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + if( strcmpi(sys.m_PTTCOM.c_str(), pVal) ){ + sys.m_PTTCOM = pVal; + OpenCom(); + } + } + } + else if( (pVal = CheckValKey("Radio=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + if( strcmpi(RADIO.StrPort, pVal) ){ + strcpy(RADIO.StrPort, pVal); + OpenRadio(); + } + } + } + else if( (pVal = CheckValKey("RadioOut=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( m_pRadio && *pVal ){ + WaitICOM(); + m_pRadio->SendCommand(pVal); + } + } + else if( CheckKey("RadioCarrierKHz>") ){ + if( m_pRadio ){ + sprintf(t, "%.3lf", double(m_pRadio->m_FreqHz)*0.001); + } + } + else if( CheckKey("RadioKHz>") ){ + if( m_pRadio ){ + sprintf(t, "%.3lf", double(m_pRadio->m_RigHz)*0.001); + } + } + else if( (pVal = CheckValKey("RadioKHz=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt; + pVal = StrDlm(tt, pBF); + LPCSTR pKey = GetMacroStr(as, tt); + double d; + Calc(d, pVal); + d *= 1000.0; // KHz -> Hz + if( m_pRadio && (d >= 50000.0) && (d <= 6.0e9) ){ + m_pRadio->CalcRigFreq(d*1.0e-6); + if( !strcmp(pKey, "YAESU-VU") ){ + OutYaesuVU(d); + } + else if( !strcmp(pKey, "YAESU-HF") ){ + OutYaesuHF(d); + } + else if( !strcmp(pKey, "CI-V") ){ + OutCIV(d); + } + else if( !strcmp(pKey, "CI-V4") ){ + OutCIV4(d); + } + else if( !strcmp(pKey, "KENWOOD") ){ + OutKENWOOD(d); + } + else if( !strcmp(pKey, "YAESU-NEW") ){ + OutKENWOOD(d); + } + else if( !strcmp(pKey, "JST245") ){ + OutJST245(d); + } + else { + strcpy(t, "Rig type = YAESU-HF/YAESU-VU/YAESU-NEW/CI-V/CI-V4/KENWOOD/JST245\r\n"); + } + } + delete pBF; + } + else if( CheckKey("RadioMode>") ){ + if( m_pRadio ){ + strcpy(t, g_tRadioMode[m_pRadio->m_RigMode]); + } + } + else if( (pVal = CheckValKey("RadioMode=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt; + pVal = StrDlm(tt, pBF); + LPCSTR pKey = GetMacroStr(as, tt); + AnsiString ts; + LPCSTR pMode = GetMacroStr(ts, pVal); + if( m_pRadio ){ + m_pRadio->SetInternalRigMode(pMode); + if( !strcmp(pKey, "YAESU-VU") ){ + OutModeYaesuVU(pMode); + } + else if( !strcmp(pKey, "YAESU-HF") ){ + OutModeYaesuHF(pMode); + } + else if( !strcmp(pKey, "CI-V") || !strcmp(pKey, "CI-V4") ){ + OutModeCIV(pMode); + } + else if( !strcmp(pKey, "KENWOOD") ){ + OutModeKENWOOD(pMode); + } + else if( !strcmp(pKey, "YAESU-NEW") ){ + OutModeKENWOOD(pMode); + } + else if( !strcmp(pKey, "JST245") ){ + OutModeJST245(pMode); + } + else { + strcpy(t, "Rig type = YAESU-HF/YAESU-VU/YAESU-NEW/CI-V/CI-V4/KENWOOD/JST245\r\n"); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("PlayBack=*>"))!=NULL ){ + f = GetOnOff(GetMacroStr(as, pVal)); + switch(f){ + case 0: // OFF + sys.m_fPlayBack = FALSE; + break; + case 1: // ON + sys.m_fPlayBack = TRUE; + break; + case 2: // ON-OFF + sys.m_fPlayBack = !sys.m_fPlayBack; + break; + default: + f = GetMacroInt(pVal); + LimitInt(&f, 0, 60); + DoPlayBack(f); + f = -1; + break; + } + if( f >= 0 ){ + if( sys.m_fPlayBack ){ + if( !m_PlayBack.IsActive() ) m_PlayBack.Init(m_BufferSize, SAMPBASE); + } + else { + m_PlayBack.Delete(); + } + UpdateUI(); + } + } + else if( CheckKey("PlayBackSpeed>") ){ + sprintf(t, "%d", sys.m_PlayBackSpeed); + } + else if( (pVal = CheckValKey("PlayBackSpeed=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + LimitInt(&f, 1, 20); + sys.m_PlayBackSpeed = f; + } + } + else if( CheckKey("PlayBackButtons>") ){ + sprintf(t, "%d,%d,%d", m_PlayBackTime[0], m_PlayBackTime[1], m_PlayBackTime[2]); + } + else if( (pVal = CheckValKey("PlayBackButtons=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); f = GetMacroInt(tt); + if( f ){ LimitInt(&f, 1, 60); m_PlayBackTime[0]=BYTE(f); } + pp = StrDlm(tt, pp); f = GetMacroInt(tt); + if( f ){ LimitInt(&f, 1, 60); m_PlayBackTime[1]=BYTE(f); } + StrDlm(tt, pp); f = GetMacroInt(tt); + if( f ){ LimitInt(&f, 1, 60); m_PlayBackTime[2]=BYTE(f); } + UpdatePlayBack(); + delete pBF; + } + else if( (pVal = CheckValKey("CODE=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( sscanf(pVal, "%X", &f) == 1 ){ + char c = char(f >> 8); + if( (f < 0x0100) || m_RxSet[0].m_MBCS.IsLead(c) ){ + if( c ) *t++ = c; + *t++ = char(f); + *t = 0; + } + } + } + else if( (pVal = CheckValKey("FFTWidth=*>"))!=NULL ){ + f = GetMacroInt(pVal); + SetFFTWidth(f); + } + else if( (pVal = CheckValKey("SyncWidth=*>"))!=NULL ){ + InitCollect(m_RxSet, GetMacroInt(pVal)); + } + else if( (pVal = CheckValKey("ShowCH=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( (f >= 1) && (f <= RXMAX) ){ + int sw = GetMacroOnOff(pp); + if( sw >= 0 ) ShowSubChannel(f, sw); + } + delete pBF; + } + else if( (pVal = CheckValKey("SetCHSpeed=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( (f >= 1) && (f <= RXMAX) ){ + CRxSet *pRxSet = &m_RxSet[f]; + double b = GetMacroDouble(pp); + if( pRxSet->IsMFSK() ){ + pRxSet->SetMFSKType(MFSK_Speed2Type(b)); + } + else { + pRxSet->SetSpeed(b); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("SetCHMode=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( (f >= 1) && (f <= RXMAX) ){ + pVal = GetMacroStr(as, pp); + CRxSet *pRxSet = &m_RxSet[f]; + f = GetModeIndex(pVal); + if( pRxSet->IsActive() && pRxSet->m_pView ){ + pRxSet->m_pView->SetMode(f); + } + else { + pRxSet->SetMode(f); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("ClearCHW=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= RXMAX) ){ + m_RxSet[f].ClearWindow(); + } + } + else if( (pVal = CheckValKey("RepeatTX=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + if( f < 100 ) f = 100; + m_ReqMacroTimer = f; + r |= macRX | macTX; + DrawHint(); + } + } + else if( (pVal = CheckValKey("Repeat=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + if( f < 100 ) f = 100; + m_ReqMacroTimer = f; + CreateMacroTimer(f); + DrawHint(); + } + } + else if( (pVal = CheckValKey("RepeatText=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( f > 0 ){ + if( f > 100 ) f = 100; + for( ; f; f-- ){ + ConvMacro_(t, pp, pButton); t += strlen(t); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("MODE=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + SetMode(GetModeIndex(pVal)); + } + else if( (pVal = CheckValKey("Execute=*>"))!=NULL ){ + CWaitCursor w; + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + if( (pVal[1] == ':')||(pVal[0]=='\\') ){ + char bf[256]; + SetDirName(bf, pVal); + if( bf[0] ){ + ::SetCurrentDirectory(bf); + } + } + else { + ::SetCurrentDirectory(sys.m_BgnDir); + } + ::WinExec(pVal, SW_SHOW); + } + } + else if( (pVal = CheckValKey("Shell=*>"))!=NULL ){ + CWaitCursor w; + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + LPCSTR pDoc = GetMacroStr(as, tt); + AnsiString ts; + pVal = GetMacroStr(ts, pp); + if( *pDoc ){ + char bf[256]; + LPSTR pDefDir = bf; + if( (pDoc[1] == ':')||(pDoc[0]=='\\') ){ + SetDirName(pDefDir, pDoc); + } + else { + pDefDir = NULL; + } + if( !*pVal ) pVal = NULL; + ::ShellExecute(Handle, "open", pDoc, pVal, pDefDir, SW_SHOWDEFAULT); + } + delete pBF; + } + else if( (pVal = CheckValKey("YesNo=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + f = YesNoMB(GetMacroStr(as, pVal)); + AttachFocus(); + sprintf(t, "%d", f); + } + else if( (pVal = CheckValKey("YesNoCancel=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + f = YesNoCancelMB(GetMacroStr(as, pVal)); + AttachFocus(); + sprintf(t, "%d", f); + } + else if( (pVal = CheckValKey("OkCancel=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + f = OkCancelMB(GetMacroStr(as, pVal)); + AttachFocus(); + sprintf(t, "%d", f); + } + else if( (pVal = CheckValKey("Error=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + ErrorMB(GetMacroStr(as, pVal)); + AttachFocus(); + } + else if( (pVal = CheckValKey("Warning=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + WarningMB(GetMacroStr(as, pVal)); + AttachFocus(); + } + else if( (pVal = CheckValKey("Message=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + InfoMB(GetMacroStr(as, pVal)); + AttachFocus(); + } + else if( (pVal = CheckValKey("WaterMsg=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = SkipSpace(StrDlm(tt, pBF)); + int pos = 4; + if( *pp ){ + sscanf(GetMacroStr(as, tt), "%d", &pos); + if( pos < 0 ) pos = 0; + if( pos > 4 ) pos = 4; + } + else { + pp = tt; + } + if( *pp ) SetInfoMsg(GetMacroStr(as, pp), pos); + delete pBF; + } + else if( (pVal = CheckValKey("RxStatus=*>"))!=NULL ){ + RxStatus(&m_RxSet[0], GetMacroStr(as, pVal)); + } + else if( CheckKey("SetFocus>") ){ + PCTX->SetFocus(); + } + else if( CheckKey("Menu>") ){ + sprintf(t, "%d", m_MacroMenuNo); + } + else if( (pVal = CheckValKey("Menu=*>"))!=NULL ){ + DoMacroMenu(pVal, pButton, FALSE); + } + else if( (pVal = CheckValKey("MenuB=*>"))!=NULL ){ + DoMacroMenu(pVal, pButton, TRUE); + } + else if( (pVal = CheckValKey("AddMenu=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = SkipSpace(StrDlm(tt, pBF)); + AnsiString Title = GetMacroStr(as, tt); + pp = SkipSpace(StrDlm(tt, pp)); + pVal = GetMacroStr(as, tt); +// if( !Title.IsEmpty() && *pVal && (*pp || !strcmp(pVal, "-")) ){ + if( !Title.IsEmpty() ){ + AddExtensionMenu(Title.c_str(), pVal, pp); + } + delete pBF; + } + else if( (pVal = CheckValKey("InsertMenu=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR pp, tt; + pp = SkipSpace(StrDlm(tt, pBF)); + AnsiString Title = GetMacroStr(as, tt); + pp = SkipSpace(StrDlm(tt, pp)); + AnsiString Pos = GetMacroStr(as, tt); + pp = SkipSpace(StrDlm(tt, pp)); + pVal = GetMacroStr(as, tt); + if( !Title.IsEmpty() && !Pos.IsEmpty() && *pVal && (*pp || !strcmp(pVal, "-")) ){ + InsExtensionMenu(Title.c_str(), Pos.c_str(), pVal, pp); + } + delete pBF; + } + else if( (pVal = CheckValKey("ShowMenu=*>"))!=NULL ){ + TMenuItem *pMenu = GetMenuArg(as, pVal, TRUE); + if( pMenu ){ + f = GetMacroOnOff(as.c_str()); + switch(f){ + case 0: + case 1: + pMenu->Visible = f; + break; + case 2: + pMenu->Visible = !pMenu->Visible; + break; + } + } + } + else if( (pVal = CheckValKey("EnableMenu=*>"))!=NULL ){ + TMenuItem *pMenu = GetMenuArg(as, pVal, TRUE); + if( pMenu ){ + f = GetMacroOnOff(as.c_str()); + switch(f){ + case 0: + case 1: + pMenu->Enabled = f; + break; + case 2: + pMenu->Enabled = !pMenu->Enabled; + break; + } + } + } + else if( (pVal = CheckValKey("ShortCut=*>"))!=NULL ){ + TMenuItem *pMenu = GetMenuArg(as, pVal, TRUE); + if( pMenu ) ShortCutExtensionMenu(pMenu, as.c_str()); + } + else if( (pVal = CheckValKey("CheckMenu=*>"))!=NULL ){ + TMenuItem *pMenu = GetMenuArg(as, pVal, TRUE); + if( pMenu ){ + f = GetMacroOnOff(as.c_str()); + switch(f){ + case 0: + case 1: + pMenu->Checked = f; + break; + case 2: + pMenu->Checked = !pMenu->Checked; + break; + } + } + } + else if( (pVal = CheckValKey("DeleteMenu=*>"))!=NULL ){ + TMenuItem *pMenu = GetMenuArg(as, pVal, FALSE); + if( pMenu ){ + TMenuItem *pMainMenu = pMenu->Parent; + if( pMainMenu ){ + if( (pMenu == KF)||(pMenu == KE)||(pMenu == KV)||(pMenu == KO)||(pMenu == KH) ){ + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + InfoMB("[%s] is not deleted...", pMenu->Caption.c_str()); + } + } + else { + pMainMenu->Delete(pMainMenu->IndexOf(pMenu)); + } + } + } + } + else if( (pVal = CheckValKey("TableCount=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, p; + int n = 0; + p = pBF; + while(*p){ + p = StrDlm(tt, SkipSpace(p)); + n++; + } + sprintf(t, "%d", n); + delete pBF; + } + else if( (pVal = CheckValKey("TableStr=*>"))!=NULL ){ + LPSTR pBF = new char[8192]; + StrCopy(pBF, GetMacroStr(as, pVal), 8191); + LPSTR tt, p; + p = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( f > 0 ){ + strcpy(p, GetMacroStr(as, p)); + int n = 1; + while(*p){ + p = StrDlm(tt, SkipSpace(p)); + if( n == f ){ + strcpy(t, GetMacroStr(as, tt)); + break; + } + n++; + } + } + delete pBF; + } + else if( CheckKey("Events>") ){ + for( f = 0; f < macOnEnd; f++ ){ + if( f ) *t++ = ','; + strcpy(t, g_tMacEvent[f]); t += strlen(t); + } + } + else if( (pVal = CheckValKey("Table=*>"))!=NULL ){ + LPSTR pBF = new char[8192]; + StrCopy(pBF, GetMacroStr(as, pVal), 8191); + LPSTR tt, p; + p = StrDlm(tt, pBF); + pVal = GetMacroStr(as, tt); + AnsiString ts; + strcpy(p, GetMacroStr(ts, p)); + int n = 1; + while(*p){ + p = StrDlm(tt, SkipSpace(p)); + if( !strcmpi(pVal, tt) ){ + sprintf(t, "%d", n); + n = -1; + break; + } + n++; + } + if( n >= 0 ) strcpy(t, "0"); + delete pBF; + } + else if( (pVal = CheckValKey("Input=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + DettachFocus(); + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = SkipSpace(StrDlm(tt, pBF)); + AnsiString rs = *pp ? GetMacroStr(as, pp) : ""; + if( InputMB("MMVARI", GetMacroStr(as, tt), rs) ){ + ConvMacro_(m_MacroInput, rs.c_str(), pButton); + strcpy(t, m_MacroInput.c_str()); + } + delete pBF; + AttachFocus(); + } + else if( (pVal = CheckValKey("ButtonContents=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt, p; + p = SkipSpace(StrDlm(tt, pBF)); + f = GetMacroInt(tt); + if( (f >= 1) && (f <= MACBUTTONALL) ){ + f--; + MACBUTTON *pList = &m_tMacButton[f]; + as = p; + Yen2CrLf(pList->Text, as); + if( pList->pButton ){ + pList->pButton->Font->Color = pList->Text.IsEmpty() ? clGrayText : pList->Color; + } + } + delete pBF; + } + else if( (pVal = CheckValKey("ButtonName=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt, p; + p = SkipSpace(StrDlm(tt, pBF)); + f = GetMacroInt(tt); + if( (f >= 1) && (f <= MACBUTTONALL) ){ + f--; + MACBUTTON *pList = &m_tMacButton[f]; + pList->Name = GetMacroStr(as, p); + if( pList->pButton ){ + pList->pButton->Caption = ConvAndChar(m_TextBuff, pList->Name.c_str()); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("EditMacro=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + LPCSTR pp = GetMacroStr(as, pVal); + if( !strcmpi(GetEXT(pp), "TXT") ){ + DettachFocus(); + TMacEditDlg *pBox = new TMacEditDlg(this); + pBox->Execute(pp); + delete pBox; + AttachFocus(); + } + else if( !strcmp(pp, "AS(CW)") ){ + DettachFocus(); + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(sys.m_AS, "AS(CW)") ){ + AdjustAS(&sys.m_AS); + } + delete pBox; + AttachFocus(); + } + else if( (f = FindStringTableStrictly(g_tMacEvent, pp, macOnEnd)) != 0 ){ + DettachFocus(); + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(sys.m_MacEvent[f], g_tMacEvent[f]) ){ + AdjustAS(&sys.m_MacEvent[f]); + } + delete pBox; + AttachFocus(); + } + else { + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= MACBUTTONALL) ){ + f--; + MACBUTTON *pList = &m_tMacButton[f]; + DettachFocus(); + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(pList, f) ){ + if( pList->pButton ){ + pList->pButton->Caption = ConvAndChar(m_TextBuff, pList->Name.c_str()); + pList->pButton->Font->Color = pList->Text.IsEmpty() ? clGrayText : pList->Color; + TFontStyles fs = Code2FontStyle(pList->Style); + pList->pButton->Font->Style = fs; + } + } + delete pBox; + AttachFocus(); + } + } + } + else if( (pVal = CheckValKey("DoMacro=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 1) && (f <= MACBUTTONALL) ){ + ::PostMessage(Handle, WM_WAVE, waveDoMacro, f-1); + } + } + else if( (pVal = CheckValKey("DoEvent=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + f = FindStringTable(g_tMacEvent, pVal, macOnEnd); + if( f >= 0 ) DoEvent(f); + } + else if( (pVal = CheckValKey("DoButton=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + ClickButton(FindButton(this, GetMacroStr(as, pVal), pButton, TRUE)); + } + else if( (pVal = CheckValKey("DoMenu=*>"))!=NULL ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + TMenuItem *pMenu = GetMenuArg(as, pVal, FALSE); + if( pMenu && pMenu->Enabled ) pMenu->Click(); + } + else if( (pVal = CheckValKey("HEX2DEC=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + sprintf(t, "%u", htoin(pVal, -1)); + } + } + else if( (pVal = CheckValKey("CHARX=*>"))!=NULL ){ + f = *pVal++; + if( m_RxSet[0].m_MBCS.IsLead(BYTE(f)) ){ + f = f << 8; + f |= *pVal; + } + sprintf(t, "%02X", f); t += strlen(t); + } + else if( (pVal = CheckValKey("CHAR=*>"))!=NULL ){ + f = *pVal++; + if( m_RxSet[0].m_MBCS.IsLead(BYTE(f)) ){ + f = f << 8; + f |= *pVal; + } + sprintf(t, "%u", f); t += strlen(t); + } + else if( (pVal = CheckValKey("KeyStroke=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + f = htoin(pVal, -1); + keybd_event(BYTE(f), 0, 0, 0); + keybd_event(BYTE(f), 0, KEYEVENTF_KEYUP, 0); + } + else if( (pVal = CheckValKey("KeyDown=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + f = htoin(pVal, -1); + keybd_event(BYTE(f), 0, 0, 0); + } + else if( (pVal = CheckValKey("KeyUp=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + f = htoin(pVal, -1); + keybd_event(BYTE(f), 0, KEYEVENTF_KEYUP, 0); + } + else if( (pVal = CheckValKey("Cond=*>"))!=NULL ){ + f = GetDataConds(SkipSpace(pVal), FALSE, pButton); + sprintf(t, "%d", f); + } + else if( (pVal = CheckValKey("ATCSpeed=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 0) && (f <= 6) ){ + SetATCSpeed(f); + } + } + else if( (pVal = CheckValKey("ATCLevel=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 3) && (f <= 40) ){ + m_ATCLevel = f; + } + } + else if( (pVal = CheckValKey("ATCLimit=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f > 1000) && (f <= 100000) ){ + SetATCLimit(f); + } + } + else if( CheckKey("TxShift>") ){ + StrDbl(t, m_ModFSK.m_RTTYShift); + } + else if( CheckKey("RxShift>") ){ + StrDbl(t, m_RxSet[0].m_pDem->m_RTTYShift); + } + else if( (pVal = CheckValKey("TxShift=*>"))!=NULL ){ + double d = GetMacroDouble(pVal); + if( (d >= 10.0) && (d <= 450.0) ){ + m_ModFSK.SetRTTYShift(d); +#if DEBUG + m_ModTest.SetRTTYShift(d); +#endif + } + } + else if( (pVal = CheckValKey("RxShift=*>"))!=NULL ){ + double d = GetMacroDouble(pVal); + if( (d >= 10.0) && (d <= 450.0) ){ + m_RxSet[0].m_pDem->SetRTTYShift(d); + } + } + else if( CheckKey("RTTYWaitC>") ){ + sprintf(t, "%d", m_ModFSK.m_Encode.GetWaitC()); + } + else if( CheckKey("RTTYWaitD>") ){ + sprintf(t, "%d", m_ModFSK.m_Encode.GetWaitD()); + } + else if( (pVal = CheckValKey("RTTYWaitC=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 0) && (f <= 100) ){ + m_ModFSK.m_Encode.SetWaitC(f); +#if DEBUG + m_ModTest.m_Encode.SetWaitC(f); +#endif + } + } + else if( (pVal = CheckValKey("RTTYWaitD=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 0) && (f <= 100) ){ + m_ModFSK.m_Encode.SetWaitD(f); +#if DEBUG + m_ModTest.m_Encode.SetWaitD(f); +#endif + } + } + else if( (pVal = CheckValKey("RTTYWordOut=*>"))!=NULL ){ + f = GetMacroOnOff(pVal); + switch(f){ + case 0: + case 1: + m_fRttyWordOut = f; + break; + case 2: + m_fRttyWordOut = !m_fRttyWordOut; + break; + } + } + else if( CheckKey("DIDDLE>") ){ + pVal = m_ModFSK.m_Encode.GetDiddle() == diddleLTR ? "LTR":"BLK"; + strcpy(t, pVal); + } + else if( (pVal = CheckValKey("DIDDLE=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( !strcmpi(pVal, "LTR") ){ + m_ModFSK.m_Encode.SetDiddle(diddleLTR); + } + else if( !strcmpi(pVal, "BLK") ){ + m_ModFSK.m_Encode.SetDiddle(diddleBLK); + } + } + else if( CheckKey("RTTYDEM>") ){ + pVal = m_RxSet[0].m_RTTYFFT ? "FFT":"IIR"; + strcpy(t, pVal); + } + else if( (pVal = CheckValKey("RTTYDEM=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( !strcmpi(pVal, "FFT") ){ + SetRTTYFFT(TRUE); + } + else if( !strcmpi(pVal, "IIR") ){ + SetRTTYFFT(FALSE); + } + } + else if( (pVal = CheckValKey("UOS=*>"))!=NULL ){ + f = GetMacroOnOff(pVal); + m_RxSet[0].m_pDem->m_Decode.SetUOS(f); + } + else if( CheckKey("MetricMFSK>") ){ + sprintf(t, "%d", m_RxSet[0].m_pDem->GetMFSKMetric(0)); + } + else if( (pVal = CheckValKey("MetricMFSK=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + f = 0; + if( !strcmpi(pVal, "EVEN") ){ + f = 1; + } + else if( !strcmpi(pVal, "ODD") ){ + f = 2; + } + sprintf(t, "%d", m_RxSet[0].m_pDem->GetMFSKMetric(f)); + } + else if( CheckKey("COMFSK>") ){ + sprintf(t, "%d", sys.m_bFSKOUT); + } + else if( (pVal = CheckValKey("COMFSK=*>"))!=NULL ){ + f = GetMacroOnOff(pVal); + sys.m_bFSKOUT = f; + if( m_pCom ) m_pCom->SetFSK(sys.m_bFSKOUT, sys.m_bINVFSK); + } + else if( CheckKey("COMFSKINV>") ){ + sprintf(t, "%d", sys.m_bINVFSK); + } + else if( (pVal = CheckValKey("COMFSKINV=*>"))!=NULL ){ + f = GetMacroOnOff(pVal); + sys.m_bINVFSK = f; + m_pCom->SetFSK(sys.m_bFSKOUT, sys.m_bINVFSK); + } + else if( (pVal = CheckValKey("String=*>"))!=NULL ){ + strcpy(t, GetMacroStr(as, pVal)); + } + else if( (pVal = CheckValKey("CallProc=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt; + pVal = GetMacroValue(StrDlm(tt, SkipSpace(pBF))); + tt = SkipSpace(tt); + if( *tt && !isdigit(*tt) ){ + f = m_MacroVal.FindName(tt, _VAL_PROC); + if( f >= 0 ){ + ConvDummy(as, m_MacroVal.GetString(f), m_MacroVal.GetPara(f), pVal); + r |= ConvMacro(t, as.c_str(), pButton); + } + else if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + InfoMB("Procedure [%s] is not found...", tt); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("DebugProc=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroValue(pVal)); + LPSTR tt; + pVal = GetMacroValue(StrDlm(tt, SkipSpace(pBF))); + tt = SkipSpace(tt); + if( *tt && !isdigit(*tt) ){ + f = m_MacroVal.FindName(tt, _VAL_PROC); + if( f >= 0 ){ + ConvDummy(as, m_MacroVal.GetString(f), m_MacroVal.GetPara(f), pVal); + strcpy(t, as.c_str()); + } + else if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + InfoMB("Procedure [%s] is not found...", tt); + } + } + delete pBF; + } + else if( (pVal = CheckValKey("VALTIME=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt; + pVal = StrDlm(tt, SkipSpace(pBF)); + CalcI(f, pVal); + GPS2SystemTime(f, &now); + if( !strcmpi(tt, "YEAR") ){ + sprintf(t, "%04u", now.wYear); + } + else if( !strcmpi(tt, "MONTH") ){ + sprintf(t, "%u", now.wMonth); + } + else if( !strcmpi(tt, "DAY") ){ + sprintf(t, "%u", now.wDay); + } + else if( !strcmpi(tt, "HOUR") ){ + sprintf(t, "%02u", now.wHour); + } + else if( !strcmpi(tt, "MINUTE") ){ + sprintf(t, "%02u", now.wMinute); + } + else if( !strcmpi(tt, "SECOND") ){ + sprintf(t, "%02u", now.wSecond); + } + else if( !strcmp(tt, "LMonth") ){ + strcpy(t, MONT2[now.wMonth]); + } + else if( !strcmp(tt, "LMONTH") ){ + strcpy(t, MONT1[now.wMonth]); + } + else if( !strcmpi(tt, "ALL") ){ + sprintf(t, "%04u,%02u,%02u,%02u,%02u,%02u,%s,%s", + now.wYear,now.wMonth,now.wDay, + now.wHour,now.wMinute,now.wSecond, + MONT2[now.wMonth],MONT1[now.wMonth] + ); + } + else { + strcpy(t, "<%VALTIME=...> year/month/day/hour/minute/second/LMonth/LMONTH/ALL"); + } + delete pBF; + } + else if( (pVal = CheckValKey("Inv=*>"))!=NULL ){ + sprintf(t, "%d", GetMacroInt(pVal)==0); + } + else if( (pVal = CheckValKey("Sin=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", sin(d)); + } + else if( (pVal = CheckValKey("Cos=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", cos(d)); + } + else if( (pVal = CheckValKey("Tan=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", tan(d)); + } + else if( (pVal = CheckValKey("ArcTan=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", atan(d)); + } + else if( (pVal = CheckValKey("Exp=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", exp(d)); + } + else if( (pVal = CheckValKey("Log=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", log(d)); + } + else if( (pVal = CheckValKey("Sqrt=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%.16lG", sqrt(d)); + } + else if( (pVal = CheckValKey("Pow=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + double x, y; + Calc(x, GetMacroStr(as, tt)); + Calc(y, GetMacroStr(as, pp)); + sprintf(t, "%.16lG", pow(x, y)); + delete pBF; + } + else if( (pVal = CheckValKey("Floor=*>"))!=NULL ){ + double d; + Calc(d, GetMacroStr(as, pVal)); + sprintf(t, "%d", int(floor(d))); + } + else if( (pVal = CheckValKey("Format=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt; + pVal = StrDlm(tt, SkipSpace(pBF)); + if( strchr(tt, 'c') ){ + pVal = GetMacroStr(as, pVal); + sprintf(t, tt, *pVal); + } + else if( strchrl(tt, "spn") ){ + pVal = GetMacroStr(as, pVal); + sprintf(t, tt, pVal); + } + else if( strchrl(tt, "eEfgG") ){ + double d; + Calc(d, pVal); + sprintf(t, tt, d); + } + else { + CalcI(f, pVal); + sprintf(t, tt, f); + } + delete pBF; + } + else if( (pVal = CheckValKey("Find$=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, pBF); + if( (pVal=strstr(GetMacroStr(as, pp), tt)) != NULL ){ + strcpy(t, pVal); + } + delete pBF; + } + else if( (pVal = CheckValKey("Skip$=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt; + pVal = GetMacroStr(as, StrDlm(tt, SkipSpace(pBF))); + f = GetMacroInt(tt); + int l; + for( l = 0; (l < f) && *pVal; l++, pVal++ ); + strcpy(t, pVal); + delete pBF; + } + else if( (pVal = CheckValKey("MSkip$=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt; + pVal = GetMacroStr(as, StrDlm(tt, SkipSpace(pBF))); + f = GetMacroInt(tt); + int l; + for( l = 0; (l < f) && *pVal; l++, pVal++ ){ + if( m_RxSet[0].m_MBCS.IsLead(*pVal) ){ + pVal++; + if( !*pVal ) break; + } + } + strcpy(t, pVal); + delete pBF; + } + else if( (pVal = CheckValKey("StrLen=*>"))!=NULL ){ + sprintf(t, "%d", strlen(GetMacroStr(as, pVal))); + } + else if( (pVal = CheckValKey("MStrLen=*>"))!=NULL ){ + sprintf(t, "%d", _mbslen((const unsigned char *)GetMacroStr(as, pVal))); + } + else if( CheckKey("CodePage>") ){ + sprintf(t, "%d", GetACP()); + } + else if( CheckKey("LanguageID>") ){ + sprintf(t, "%d", sys.m_wLang); + } + else if( CheckKey("Font>") ){ + sprintf(t, "%s,%d,%d", PCRX->Font->Name.c_str(), PCRX->Font->Size, PCRX->Font->Charset); + } + else if( (pVal = CheckValKey("Font=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, pp; + pp = StrDlm(tt, SkipSpace(pBF)); + pVal = GetMacroStr(as, tt); + if( *pVal ){ + PCRX->Font->Name = pVal; + } + pp = StrDlm(tt, pp); + tt = SkipSpace(tt); + if( *tt ){ + f = GetMacroInt(tt); + if( (f >= 1) && (f < 100) ){ + PCRX->Font->Size = f; + } + } + pp = StrDlm(tt, pp); + tt = SkipSpace(tt); + if( *tt ){ + PCRX->Font->Charset = BYTE(GetMacroInt(tt)); + } + DettachFocus(); + PCTX->Font->Name = PCRX->Font->Name; + PCTX->Font->Charset = PCRX->Font->Charset; + PCTX->Font->Size = PCRX->Font->Size; + OnFontChange(FALSE); + OnFontChange(TRUE); + UpdateUI(); + AttachFocus(); + delete pBF; + } + else if( CheckKey("WaterNoise>") ){ + double db = m_StgWater.Sum; + if( m_FFT.m_FFTGain ) db = SqrtToDB(db); + sprintf(t, "%.0lf", (db*0.01) + 5.0); + } + else if( (pVal = CheckValKey("WaterNoise=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + f = GetMacroInt(tt); + if( (f > 0) && (f <= 100) ) m_WaterNoiseL = f; + if( *pp ){ + f = GetMacroInt(pp); + if( (f > 0) && (f <= 100) ) m_WaterNoiseH = f; + } + InitWater(iniwLIMIT); + delete pBF; + } + else if( CheckKey("WaterLevels>") ){ + for( f = 0; f < AN(m_tWaterLevel); f++ ){ + if( f ) *t++ = ','; + sprintf(t, "%d", m_tWaterLevel[f]); t += strlen(t); + } + } + else if( (pVal = CheckValKey("WaterLevels=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = SkipSpace(pBF); + f = 0; + while(*pp && (f < AN(m_tWaterLevel))){ + pp = SkipSpace(StrDlm(tt, pp)); + int d = GetMacroInt(tt); + if( d < 0 ) d = 0; + if( d > 255 ) d = 255; + m_tWaterLevel[f] = d; + f++; + } + CreateWaterColors(); + delete pBF; + } + else if( CheckKey("WaterColors>") ){ + EncodeColors(t, m_tWaterColset, AN(m_tWaterColset)); + } + else if( (pVal = CheckValKey("WaterColors=*>"))!=NULL ){ + if( DecodeColors(pVal, m_tWaterColset, AN(m_tWaterColset)) ){ + CreateWaterColors(); + } + } + else if( CheckKey("SpectrumColors>") ){ + EncodeColors(t, m_tFFTColset, AN(m_tFFTColset)); + } + else if( (pVal = CheckValKey("SpectrumColors=*>"))!=NULL ){ + DecodeColors(pVal, m_tFFTColset, AN(m_tFFTColset)); + } + else if( CheckKey("RxColors>") ){ + EncodeColors(t, m_Dump.m_Color, AN(m_Dump.m_Color)); + } + else if( (pVal = CheckValKey("RxColors=*>"))!=NULL ){ + if( DecodeColors(pVal, m_Dump.m_Color, AN(m_Dump.m_Color)) ){ + PCRX->Color = m_Dump.m_Color[0].c; + } + } + else if( CheckKey("TxColors>") ){ + EncodeColors(t, m_Edit[0].m_Color, AN(m_Edit[0].m_Color)); + } + else if( (pVal = CheckValKey("TxColors=*>"))!=NULL ){ + if( DecodeColors(pVal, m_Edit[0].m_Color, AN(m_Edit[0].m_Color)) ){ + for( f = 1; f < AN(m_Edit); f++ ){ + for( int i = 0; i < AN(m_Edit[0].m_Color); i++ ){ + m_Edit[f].m_Color[i] = m_Edit[0].m_Color[i]; + } + } + PCTX->Color = m_Edit[0].m_Color[0].c; + } + } + else if( CheckKey("Capture>") ){ + if( m_Dump.GetWindowCallsign(as) ){ + strcpy(t, as.c_str()); + } + } + else if( CheckKey("SetCaptureLimit>") ){ + m_Dump.UpdateCaptureLimit(); + } + else if( CheckKey("ClearCaptureLimit>") ){ + m_Dump.ClearCaptureLimit(); + } + else if( (pVal = CheckValKey("SendMessage=*>"))!=NULL ){ + m_MacroInput = ""; + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + if( *tt ){ + HWND hWnd = HWND_BROADCAST; + UINT uMsg; + pVal = GetMacroStr(as, tt); + if( !strcmpi(pVal, "this") ){ + pp = StrDlm(tt, pp); + uMsg = GetMacroInt(tt); + hWnd = Handle; + } + else { + uMsg = ::RegisterWindowMessage(pVal); + } + pp = StrDlm(tt, pp); + DWORD wParam = GetMacroInt(tt); + StrDlm(tt, pp); + DWORD lParam = GetMacroInt(tt); + f = ::SendMessage(hWnd, uMsg, wParam, lParam); + char bf[32]; + sprintf(bf, "%d", f); + m_MacroInput = bf; + } + delete pBF; + } + else if( (pVal = CheckValKey("ShowHTML=*>"))!=NULL ){ + m_WebRef.ShowHTML(GetMacroStr(as, pVal)); + } + else if( (pVal = CheckValKey("CallDLL=*>"))!=NULL ){ + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR pp, tt; + pp = StrDlm(tt, pBF); + if( *tt ){ + pVal = GetMacroStr(as, tt); + HANDLE hLib = m_LibDLL.LoadLibrary(pVal); //ja7ude 0522 + if( hLib ){ + pp = StrDlm(tt, pp); + pVal = GetMacroStr(as, tt); + tmmMacro pFunc = (tmmMacro)::GetProcAddress((HINSTANCE)hLib, pVal); + if( pFunc ){ + pp = StrDlm(tt, pp); + pFunc(Handle, t, GetMacroStr(as, tt)); + } + } + } + delete pBF; + } + else if( CheckKey("OnTimerInterval>") ){ + sprintf(t, "%d", sys.m_OnTimerInterval); + } + else if( (pVal = CheckValKey("OnTimerInterval=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( f > 0 ){ + sys.m_OnTimerInterval = f; + if( m_pMacroOnTimer && (m_pMacroOnTimer->Interval != UINT(f)) ){ + m_pMacroOnTimer->Interval = f; + } + } + } + else if( (pVal = CheckValKey("ONOFF=*>"))!=NULL ){ + strcpy(t, GetMacroInt(pVal) ? "ON":"OFF"); + } + else if( CheckKey("BuffSize>") ){ + sprintf(t, "%d", sys.m_MacBuffSize); + } + else if( (pVal = CheckValKey("BuffSize=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f >= 512) && (f <= 65536) ){ + sys.m_MacBuffSize = f; + } + } + else if( CheckKey("Memory>") ){ + MEMORYSTATUS mem; + ::GlobalMemoryStatus(&mem); + sprintf(t, "%u,%.2lf,%.2lf", + mem.dwMemoryLoad, + double(mem.dwTotalPhys)/(1024*1024), + double(mem.dwAvailPhys)/(1024*1024) + ); + } + else if( CheckKey("Folder>") ){ + strcpy(t, sys.m_BgnDir); + } + else if( CheckKey("EOF>") ){ + break; + } +#if DEBUG + else if( CheckKey("Stack>") ){ + sprintf(t, "%08X", &f); + } + else if( CheckKey("ListDLL>") ){ + for( f = 0; f < m_LibDLL.m_Count; f++ ){ + sprintf(t, "%s\r\n", m_LibDLL.m_pBase[f].pName); + t += strlen(t); + } + } + else if( CheckKey("AFCCount>") ){ + if( m_RxSet[0].IsMFSK() ){ + f = m_RxSet[0].m_AFCTimerMFSK; + } + else { + f = m_RxSet[0].m_pDem->m_AFCCount; + } + sprintf(t, "%d", f); + } + else if( CheckKey("LostRX>") ){ + m_LostSoundRX = LOSTMSGTIME * int(SAMPFREQ) / m_BufferSize; + m_fShowMsg = TRUE; + } + else if( CheckKey("Repeat>") ){ + m_pDebugButton = pButton; + } + else if( CheckKey("StopRepeat>") ){ + m_pDebugButton = NULL; + } + else if( CheckKey("TestSignal>") ){ + if( pButton && pButton->Down ) pButton->Down = FALSE; + TestSignal(); + } + else if( CheckKey("TestMod>") ){ + CMODFSK *pMod = new CMODFSK; + pMod->SetSampleFreq(SAMPFREQ); + pMod->SetCarrierFreq(1900.0); + pMod->SetSpeed(m_RxSet[0].m_Speed); + pMod->SetType(CBMode->ItemIndex); + for( int i = 0; i < m_BufferSize; i++ ) pMod->Do(); + sprintf(t, "%08X : %d", pMod, pMod->m_DEBUG); + delete pMod; + } + else if( (pVal = CheckValKey("RandMem=*>"))!=NULL ){ + f = GetMacroInt(pVal); + if( (f > 1) && (f <= 1024*1024) ){ + BYTE *bp = new BYTE[f]; + BYTE *t = bp; + for( int i = 0; i < f; i++ ) *t++ = (BYTE)rand(); + delete bp; + } + } + else if( CheckKey("ShowTxBPF>") ){ + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(m_ModFSK.GetFIR(), 6000, SAMPFREQ); + delete pBox; + AttachFocus(); + } + else if( CheckKey("ShowDECM>") ){ + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); +#if DECFIR + pBox->Execute(m_Dec2.GetFIR(), 6000, SAMPFREQ); +#else + pBox->Execute(m_Dec2.GetIIR(), 6000, SAMPFREQ); +#endif + delete pBox; + AttachFocus(); + } + else if( CheckKey("ShowDemLPF>") ){ + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&m_RxSet[0].m_pDem->m_OutLPF, 300, SAMPFREQ); + delete pBox; + AttachFocus(); + } + else if( CheckKey("ShowNOTCH>") ){ + if( !m_Notches.m_Count ){ + m_Notches.Add(m_NotchFreq); + } + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&m_Notches.m_FIR, 3000, m_Notches.m_FIR.GetSampleFreq()); + delete pBox; + AttachFocus(); + } + else if( CheckKey("ShowMFSK>") ){ + CFIR2 *pH = m_RxSet[0].m_pDem->GetMFSKHIL(); + if( pH ){ + DettachFocus(); + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(pH, 3000, DEMSAMPFREQ); + delete pBox; + AttachFocus(); + } + } +/* + else if( CheckKey("ShowPHASEX>") ){ + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&m_RxSet[0].m_pDem->m_PhaseX.m_LPF, 400, DEMSAMPFREQ); + delete pBox; + } +*/ + else if( CheckKey("ShowQPSK1>") ){ + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&m_RxSet[0].m_pDem->m_DecPSK.m_LPF1, 400, DEMSAMPFREQ); + delete pBox; + } + else if( CheckKey("ShowQPSK2>") ){ + TFreqDispDlg *pBox = new TFreqDispDlg(this); + pBox->Execute(&m_RxSet[0].m_pDem->m_DecPSK.m_LPF2, 200, DEMSAMPFREQ/QPSK_SUBFACTOR); + delete pBox; + } + else if( (pVal = CheckValKey("RxFile=*>"))!=NULL ){ + pVal = GetMacroStr(as, pVal); + if( *pVal ){ + FILE *fp = fopen(pVal, "rb"); + if( fp ){ + while(1){ + int len = fread(m_TextBuff, 1, sizeof(m_TextBuff), fp); + if( len <= 0 ) break; + LPCSTR p = m_TextBuff; + while(len--){ + m_Dump.PutKey(*p++, 1); + } + } + fclose(fp); + } + } + } + else if( CheckKey("ShowTitle>") ){ + UpdateTitle(); + } + else if( (pVal = CheckValKey("SimBAUD=*>"))!=NULL ){ + double b = GetMacroDouble(pVal); + if( (b >= MIN_SPEED) && (b <= MAX_SPEED) ){ + m_ModTest.SetSpeed(b); + } + } +#endif + else { + BOOL f = FALSE; + for( int i = 0; i < macOnEnd; i++ ){ + char bf[256]; + sprintf(bf, "%s=*>", g_tMacEvent[i]); + if( (pVal = CheckValKey(bf))!=NULL ){ + f = TRUE; + as = pVal; + Yen2CrLf(sys.m_MacEvent[i], as); + UpdateMacroOnTimer(); + break; + } + else { + sprintf(bf, "%s>", g_tMacEvent[i]); + if( CheckKey(bf) ){ + f = TRUE; + DettachFocus(); + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(sys.m_MacEvent[i], g_tMacEvent[i]) ){ + AdjustAS(&sys.m_MacEvent[i]); + } + delete pBox; + AttachFocus(); + break; + } + } + } + if( !f ){ + *t++ = '<'; + *t++ = '%'; + strcpy(t, pKey); + } + } + t += strlen(t); + } + else { + if( *p != '\n' ){ + if( (*p == '\r') && cDisCR ){ + cDisCR--; + p++; + } + else if( (*p == '\t') && fDisTAB ){ + p++; + } + else if( (*p == ' ') && fDisSP ){ + p++; + } + else { + *t++ = *p++; + } + } + else { + p++; + } + } + } + *t = 0; + return r; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoMacroReturn(int f) +{ + if( f & macTX ){ + if( !m_TX || m_fTone ) ToTX(); + } + else if( f & macTXRX ){ + SBTX->Down = !SBTX->Down; + SBTXClick(NULL); + } + else if( f & macTONE ){ + if( !m_TX ) ToTone(); + } + if( f & macRX ){ + m_fReqRX = TRUE; + m_ModFSK.m_Encode.m_fReqRX = TRUE; + m_Edit[m_CurrentEdit].MoveCursor(dmpMoveLAST); + SetTXCaption(); + } + if( f & macTXOFF ){ + if( m_TX ) ToRX(); + } + if( f & macAUTOCLEAR ) m_ReqAutoClear = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoMacro(LPCSTR pMacro, TSpeedButton *pButton) +{ + int len = strlen(pMacro) + 1; + if( len < sys.m_MacBuffSize ) len = sys.m_MacBuffSize; + LPSTR bp = new char[len]; + int f = ConvMacro(bp, pMacro, pButton); + BOOL fCW = FALSE; + LPCSTR p = bp; + if( f & macRX ) m_Edit[m_CurrentEdit].MoveCursor(dmpMoveLAST); + for( f; *p; p++ ){ + if( (BYTE(*p) == button1ST) && (BYTE(*(p+1)) == button2ND) && (*(p+2)) ){ + p+=2; + switch(*p){ + case buttonCWON: + fCW = TRUE; + break; + case buttonCWOFF: + fCW = FALSE; + break; + case buttonMOVETOP: + m_Edit[m_CurrentEdit].MoveCursor(dmpMoveTOP); + break; + case buttonMOVEEND: + m_Edit[m_CurrentEdit].MoveCursor(dmpMoveLAST); + break; + case buttonIDLE: + m_Edit[m_CurrentEdit].PutChar(0x0200, 3); + break; + default: + m_Edit[m_CurrentEdit].PutKey(button1ST, 1); + m_Edit[m_CurrentEdit].PutKey(button2ND, 1); + m_Edit[m_CurrentEdit].PutKey(*p, 1); + break; + } + } + else if( fCW ){ + m_Edit[m_CurrentEdit].PutChar(*p+0x0100, 3); + } + else { + m_Edit[m_CurrentEdit].PutKey(*p, 1); + } + } + DoMacroReturn(f); + if( pButton && !(f & macSEEK) ){ + pButton->Down = m_ReqMacroTimer != 0; + } + delete bp; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SendButton(int n) +{ + if( (n < 0) || (n >= MACBUTTONALL) ) return; + + sys.m_MacroError = FALSE; + DeleteMacroTimer(); + m_CurrentMacro = n; + + MACBUTTON *pList = &m_tMacButton[n]; + if( pList->Text.IsEmpty() ){ + if( pList->pButton ) pList->pButton->Down = FALSE; + return; + } + DoMacro(pList->Text.c_str(), pList->pButton); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOAIClick(TObject *Sender) +{ + InvMenu(KOAI); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOAOClick(TObject *Sender) +{ + InvMenu(KOAO); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBInitClick(TObject *Sender) +{ + AnsiString strBand = LogFreq->Text; + if( Log.IsOpen() ){ + if( SBQSO->Down ){ + Log.DeleteLast(); + Log.m_Find.Clear(); + Log.InitCur(); + SBQSO->Down = FALSE; + UpdateTextData(); + } + else { + Log.InitCur(); + Log.m_sd.call[0] = 0; + Log.m_sd.name[0] = 0; + Log.m_sd.qth[0] = 0; + UpdateTextData(); + UpdateCallsign(); + } + if( !strBand.IsEmpty() ){ + LogFreq->Text = strBand; + Log.SetFreq(&Log.m_sd, strBand.c_str()); + } + HisCallChange(NULL); + LogLink.Clear(); + if( HisCall->CanFocus() ) HisCall->SetFocus(); + } + else { + HisCall->Text = ""; + HisName->Text = ""; + HisRST->Text = "599"; + MyRST->Text = "599"; + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KOClick(TObject *Sender) +{ + KOA->Enabled = !m_TX; + KORS->Visible = IsRTTY(); + KORSC->Checked = !m_fRttyWordOut; + KORSW->Checked = m_fRttyWordOut; + OnMenuProc(KO, "&Options"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KHAClick(TObject *Sender) +{ + char fname[256]; + + BOOL ww = TRUE; + LPCSTR pName; + if( Sender == KHA ){ + pName = "eproject.txt"; + if( !sys.m_MsgEng ) pName++; + } + else if( Sender == KHO ){ + pName = "emmvari.txt"; + if( !sys.m_MsgEng ) pName++; + } + else if( Sender == KHS ){ + pName = "samples.txt"; + ww = FALSE; + } + else { + pName = "ehistory.txt"; + if( !sys.m_MsgEng ) pName++; + } + + if( !m_pHelp ){ + m_pHelp = new TFileEdit(this); + m_pHelp->SetEvent(Handle, WM_WAVE, 2); + } + if( m_pHelp ){ + m_pHelp->SetWordWrap(ww); + sprintf(fname, "%s%s", sys.m_BgnDir, pName); +#if DEBUG + m_pHelp->Execute(fname, FALSE); +#else + m_pHelp->Execute(fname, TRUE); +#endif + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KHVClick(TObject *Sender) +{ + DettachFocus(); + TVerDspDlg *pBox = new TVerDspDlg(this); + pBox->ShowModal(); + delete pBox; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FormPaint(TObject *Sender) +{ + if( m_fInitFirst ){ + m_fInitFirst = FALSE; + Draw(FALSE); + if( sys.m_fShowLangMsg && !sys.m_fBaseMBCS ){ + AnsiString as = "This program was made for MBCS(JA/HL/BV/BY) languages. " + "SBCS languages are out of scope of this project, and there is no merit to run this program." + "\r\n\r\nDo you continue to run it?"; + if( YesNoMB(as.c_str()) != ID_YES ){ + Close(); + return; + } + sys.m_fShowLangMsg = FALSE; + } + OpenSound(FALSE); + int f1stInst = FALSE; + if( !strcmp(sys.m_CallSign.c_str(), "NOCALL") ){ + f1stInst = TRUE; + AnsiString as; + DettachFocus(); + if( InputMB("MMVARI", sys.m_MsgEng ? "Enter your callsign (for Macros)":"コールサインを入力して下さい", as) && !as.IsEmpty() ){ + strupr(as.c_str()); + sys.m_CallSign = as; + Log.MakePathName(ClipCall(as.c_str())); + } + } + sprintf(m_TextBuff, "%sARRL.DX", sys.m_BgnDir); + Cty.Load(m_TextBuff); + sprintf(m_TextBuff, "%sMMCG.DEF", sys.m_BgnDir); + mmcg.LoadDef(m_TextBuff); + if( !f1stInst ) Log.DoBackup(); + Log.Open(NULL, !f1stInst); + m_LogBand = Log.m_sd.band; + UpdateLogLink(); + UpdateTextData(); + if( Log.m_sd.btime ) SBQSO->Down = TRUE; + UpdateTitle(); +#if !DEBUG + srand(::GetTickCount()); +#endif + if( sys.m_fRestoreSubChannel ){ + for( int i = 1; i < RXMAX; i++ ){ + if( m_RxSet[i].m_fShowed ){ + ShowSubChannel(i, TRUE); + } + } + } + DoEvent(macOnStart); + AttachFocus(); + UpdateMacroOnTimer(); + } + else { + DoResume(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVCRClick(TObject *Sender) +{ + m_Dump.Clear(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVCTClick(TObject *Sender) +{ + m_ReqAutoClear = FALSE; + m_Edit[m_CurrentEdit].Clear(); + if( m_fReqRX ){ + m_fReqRX = FALSE; + m_ModFSK.m_Encode.m_fReqRX = FALSE; + SetTXCaption(); + } + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBATCMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + if( m_TX != txINTERNAL ){ + m_fDisEvent++; + EATC->Text = "0"; + m_RxSet[0].m_pDem->m_Decode.SetTmg(0); + m_RxSet[0].m_pDem->m_Decode.ClearLPF(); + m_fDisEvent--; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CreateWaterColors(void) +{ + int i, O, W; + UCOL c; + + W = m_tWaterLevel[0]; + for( i = 0; i < W; i++ ){ + c = GetGrade2(m_tWaterColset, i, W); + m_tWaterColors[i] = c.c; + } + UCOL col[2]; + W = m_tWaterLevel[1] - m_tWaterLevel[0]; + O = m_tWaterLevel[0]; + col[0].c = m_tWaterColset[1].c; + col[1].c = m_tWaterColset[6].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } + W = m_tWaterLevel[2] - m_tWaterLevel[1]; + O = m_tWaterLevel[1]; + col[0].c = m_tWaterColset[6].c; + col[1].c = m_tWaterColset[7].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } + W = m_tWaterLevel[3] - m_tWaterLevel[2]; + O = m_tWaterLevel[2]; + col[0].c = m_tWaterColset[7].c; + col[1].c = m_tWaterColset[8].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } + W = m_tWaterLevel[4] - m_tWaterLevel[3]; + O = m_tWaterLevel[3]; + col[0].c = m_tWaterColset[8].c; + col[1].c = m_tWaterColset[9].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } + W = m_tWaterLevel[5] - m_tWaterLevel[4]; + O = m_tWaterLevel[4]; + col[0].c = m_tWaterColset[9].c; + col[1].c = m_tWaterColset[10].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } + W = 256 - m_tWaterLevel[5]; + O = m_tWaterLevel[5]; + col[0].c = m_tWaterColset[10].c; + col[1].c = m_tWaterColset[11].c; + for( i = 0; i < W; i++ ){ + c = GetGrade2(col, i, W); + m_tWaterColors[i+O] = c.c; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawStatusBar(const TRect &Rect, LPCSTR pText, TColor col) //JA7UDE 0428 +{ + if( (WindowState != wsMinimized) && Rect.Right ){ + TCanvas *pCanvas = StatusBar->Canvas; + pCanvas->Brush->Color = col; + pCanvas->TextRect(Rect, Rect.Left+1, Rect.Top+1, pText); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawHint(void) +{ + DrawStatus(statusHint, GetHintStatus(m_HintKey.c_str())); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawStatus(int n, LPCSTR pText) +{ + if( strcmp(pText, m_strStatus[n].c_str()) ){ + m_strStatus[n] = pText; + DrawStatus(n); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawStatus(int n) +{ + const TRect &Rect = m_rcStatus[n]; //JA7UDE 0428 + switch(n){ + case statusCOM: + { + TColor col = clBtnFace; + if( strcmpi(sys.m_PTTCOM.c_str(), "NONE") && !m_pCom ){ + col = clRed; + } + DrawStatusBar(Rect, sys.m_PTTCOM.c_str(), col); + } + break; + default: + DrawStatusBar(Rect, m_strStatus[n].c_str(), clBtnFace); + if( (n == statusHint) && (WindowState == wsNormal) ){ + RECT rc; + rc.right = StatusBar->Width; + rc.bottom = StatusBar->Height; + rc.left = rc.right - 14; + rc.top = rc.bottom - 14; + ::DrawFrameControl(StatusBar->Canvas->Handle, &rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); + } + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::StatusBarDrawPanel(TStatusBar *StatusBar, + TStatusPanel *Panel, const TRect &Rect) +{ + for( int i = 0; i < statusEND; i++ ){ + if( Panel == StatusBar->Panels->Items[i] ){ + m_rcStatus[i] = Rect; + DrawStatus(i); + break; + } + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetStatusIndex(int x) +{ + int N = -1; + TRect *pRect = m_rcStatus; + for( int i = 0; i <= statusHint; i++, pRect++ ){ + if( (x > pRect->Left) && (x < pRect->Right) ){ + N = i; + break; + } + } + return N; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::StatusBarMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + switch(GetStatusIndex(X)){ + case statusPAGE: + PupPage->Popup(Left+X, Top+StatusBar->Top + Y); + break; + case statusSAMP: + if( Button == mbLeft ){ + KOOClick((TObject *)2); + } + else { + KOAClick(NULL); + } + break; + case statusCOM: + KOOClick((TObject *)1); + break; + case statusVARI: + PupCharset->PopupComponent = StatusBar; + PupCharset->Popup(Left+X, Top+StatusBar->Top + Y); + break; + case statusHint: + if( m_pPlayBox ) KVSPClick(NULL); + break; + default: + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::StatusBarMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + int N = GetStatusIndex(X); + if( (N >= statusPAGE) && (N <= statusHint) ){ + + const LPCSTR _tt[][2]={ + { "送信画面ページ", "Page of the TX window" }, + { "受信信号のS/N比", "S/N ratio of the RX signals" }, + { "サウンドカード Clock", "Sound card clock" }, + { "PTTポート", "PTT Port" }, + { "伝送言語", "Transmission language" }, + { "", "" }, + }; + DrawStatus(statusHint, _tt[N][sys.m_MsgEng]); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KANSIClick(TObject *Sender) +{ + TMenuItem *pMenu = (TMenuItem *)Sender; + if( pMenu->Checked ) return; + + WORD wLang; + if( pMenu == KANSI ){ + wLang = 0; + } + else if( pMenu == KJA ){ + wLang = 0x0411; + } + else if( pMenu == KHL ){ + wLang = 0x0412; + } + else if( pMenu == KBV ){ + wLang = 0x0404; + } + else if( pMenu == KBY ){ + wLang = 0x0804; + } + int n = GetPopupIndex(PupCharset->PopupComponent); + if( n ){ + TRxViewDlg *pView = m_RxSet[n].m_pView; + SetLangFont(pView->PC->Font, wLang); + pView->OnUpdateFont(); + } + else { + DettachFocus(); + SetLangFont(PCRX->Font, wLang); + PCTX->Font->Name = PCRX->Font->Name; + PCTX->Font->Charset = PCRX->Font->Charset; + OnFontChange(FALSE); + OnFontChange(TRUE); + UpdateUI(); + AttachFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KMISCClick(TObject *Sender) +{ + int n = GetPopupIndex(PupCharset->PopupComponent); + if( n ){ + m_RxSet[n].m_pView->ChangeFont(); + } + else { + TFontDialog *pBox = new TFontDialog(this); + DettachFocus(); + pBox->Font = PCRX->Font; + pBox->Font->Color = PCRX->Color; + OnWave(); + if( pBox->Execute() ){ + PCRX->Font = pBox->Font; + PCRX->Color = pBox->Font->Color; + PCTX->Font->Name = PCRX->Font->Name; + PCTX->Font->Charset = PCTX->Font->Charset; + OnFontChange(FALSE); + OnFontChange(TRUE); + } + delete pBox; + UpdateUI(); + AttachFocus(); + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetPopupIndex(TComponent *pComponent) +{ + if( (pComponent == StatusBar)||(pComponent == this) ){ + return 0; + } + else { + CRxSet *pRxSet = &m_RxSet[1]; + for( int i = 1; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() && pRxSet->m_pView ){ + if( (pComponent == pRxSet->m_pView->StatusBar)|| + (pComponent == pRxSet->m_pView) + ){ + return i; + } + } + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupCharsetPopup(TObject *Sender) +{ + CheckFontCharset(); + KJA->Enabled = sys.m_tFontFam[fmJA]; + KHL->Enabled = sys.m_tFontFam[fmHL] || sys.m_tFontFam[fmJOHAB]; + KBV->Enabled = sys.m_tFontFam[fmBV]; + KBY->Enabled = sys.m_tFontFam[fmBY]; + + int charset; + int n = GetPopupIndex(PupCharset->PopupComponent); + if( n ){ + charset = m_RxSet[n].m_pView->PC->Font->Charset; + } + else { + charset = PCRX->Font->Charset; + } + switch(charset){ + case SHIFTJIS_CHARSET: + KJA->Checked = TRUE; + break; + case JOHAB_CHARSET: + case HANGEUL_CHARSET: + KHL->Checked = TRUE; + break; + case CHINESEBIG5_CHARSET: // + KBV->Checked = TRUE; + break; + case 134: // 簡略 + KBY->Checked = TRUE; + break; + case ANSI_CHARSET: + KANSI->Checked = TRUE; + break; + case SYMBOL_CHARSET: + KMISC->Checked = TRUE; + break; + default: + KMISC->Checked = TRUE; + break; + } + OnMenuProc(PupCharset->Items, "PopCHARSET"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::HisRSTChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + if( m_fDrop ){ + m_fDrop = FALSE; + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnLogFreq(BOOL fLink) +{ + Log.SetFreq(&Log.m_sd, AnsiString(LogFreq->Text).c_str()); //JA7UDE 0428 + if( fLink ) LogLink.SetFreq(AnsiString(LogFreq->Text).c_str()); //JA7UDE 0428 + if( Log.m_sd.band != m_LogBand ){ + m_LogBand = Log.m_sd.band; + DoEvent(macOnBand); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::LogFreqChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + OnLogFreq(TRUE); + if( m_fDrop ){ + m_fDrop = FALSE; + if( (ActiveControl != PCTX) && PCTX->CanFocus() ) SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOVClick(TObject *Sender) +{ + char fname[256]; + + sprintf(fname, "%sVARICODE.TXT", sys.m_BgnDir); + g_VariCode.SaveTable(fname); + if( !m_pEdit ){ + m_pEdit = new TFileEdit(this); + m_pEdit->SetEvent(Handle, WM_WAVE, 2); + } + m_pEdit->SetDelFile(TRUE); + m_pEdit->Execute(fname, TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KECClick(TObject *Sender) +{ + DettachFocus(); + TCodeView *pBox = new TCodeView(this); + pBox->Execute(Handle, WM_WAVE, 3, PCRX->Font); + delete pBox; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFWSTClick(TObject *Sender) +{ + if( m_pPlayBox ){ + delete m_pPlayBox; + m_pPlayBox = NULL; + } + ::GetLocal(&m_LocalTime); + sprintf(m_TextBuff, "%s%02u%02u%02u%02u%02u%02u.mmv", + sys.m_SoundDir, + m_LocalTime.wYear % 100, + m_LocalTime.wMonth, + m_LocalTime.wDay, + m_LocalTime.wHour, + m_LocalTime.wMinute, + m_LocalTime.wSecond + ); + m_WaveFile.Rec(m_TextBuff); + KFWST->Checked = TRUE; KFWS->Checked = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFWSClick(TObject *Sender) +{ + TSaveDialog *pBox = new TSaveDialog(this); + pBox->Options << ofOverwritePrompt; + pBox->Options << ofNoReadOnlyReturn; + if( sys.m_MsgEng ){ + pBox->Title = "Recode sound"; + pBox->Filter = "MMV Files(*.mmv)|*.mmv|"; + } + else { + pBox->Title = "サウンドの記録"; + pBox->Filter = "MMV Files(*.mmv)|*.mmv|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "mmv"; + pBox->InitialDir = sys.m_SoundDir; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + SetDirName(sys.m_SoundDir, AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + OnWave(); + if( m_pPlayBox ){ + delete m_pPlayBox; + m_pPlayBox = NULL; + } + OnWave(); + m_WaveFile.Rec(AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + KFWST->Checked = FALSE; KFWS->Checked = TRUE; + } + delete pBox; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFRSClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Play sound"; + pBox->Filter = "MMV Files(*.mmv)|*.mmv|"; + } + else { + pBox->Title = "サウンドの再生"; + pBox->Filter = "MMV Files(*.mmv)|*.mmv|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "mmv"; + pBox->InitialDir = sys.m_SoundDir; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + SetDirName(sys.m_SoundDir, AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + OnWave(); + m_Wave.InClose(); + if( m_WaveFile.Play(AnsiString(pBox->FileName).c_str()) ){ //JA7UDE 0428 + ReOutOpen(); + if( !m_pPlayBox ){ + m_pPlayBox = new TPlayDlgBox(this); + } + m_pPlayBox->Execute(&m_WaveFile); + } + else { + OpenSound(FALSE); + } + } + delete pBox; + if( m_pPlayBox ){ + m_pPlayBox->Visible = TRUE; + m_pPlayBox->SetFocus(); + } + else { + AttachFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFESClick(TObject *Sender) +{ + if( m_pPlayBox ){ + delete m_pPlayBox; + m_pPlayBox = NULL; + } + int mode = m_WaveFile.m_mode; + m_WaveFile.FileClose(); + if( mode == 1 ){ + m_Wave.OutAbort(); + OpenSound(FALSE); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVSPClick(TObject *Sender) +{ + if( m_pPlayBox ){ + m_pPlayBox->Visible = TRUE; + m_pPlayBox->SetFocus(); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KVLClick(TObject *Sender) +{ + TLogListDlg *pBox = new TLogListDlg(this); + OnWave(); + pBox->Execute(); + delete pBox; + UpdateTitle(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateCallsign(void) +{ + if( HisCall->Text.IsEmpty() ){ + m_Dupe = 0; + SBQSO->Enabled = FALSE; + } + else { + SBQSO->Enabled = TRUE; + } + HisCall->Font->Color = m_Dupe ? clRed : clBlack; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateLogMode(void) +{ + LPCSTR pMode; + if( m_strLogMode.IsEmpty() ){ + pMode = g_tLogModeTable[CBMode->ItemIndex]; + } + else { + pMode = m_strLogMode.c_str(); + } + Log.SetMode(&Log.m_sd, pMode); + LogLink.SetMode(pMode); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateLogData(void) +{ + StrCopy(Log.m_sd.call, AnsiString(HisCall->Text).c_str(), MLCALL); //JA7UDE 0428 + clipsp(Log.m_sd.call); + jstrupr(Log.m_sd.call); + StrCopy(Log.m_sd.name, AnsiString(HisName->Text).c_str(), MLNAME); //JA7UDE 0428 + StrCopy(Log.m_sd.qth, AnsiString(HisQTH->Text).c_str(), MLQTH); //JA7UDE 0428 + StrCopy(Log.m_sd.my, AnsiString(MyRST->Text).c_str(), MLRST); //JA7UDE 0428 + jstrupr(Log.m_sd.my); + StrCopy(Log.m_sd.ur, AnsiString(HisRST->Text).c_str(), MLRST); //JA7UDE 0428 + jstrupr(Log.m_sd.ur); + StrCopy(Log.m_sd.rem, AnsiString(EditNote->Text).c_str(), MLREM); //JA7UDE 0428 + StrCopy(Log.m_sd.qsl, AnsiString(EditQSL->Text).c_str(), MLQSL); //JA7UDE 0428 + Log.SetFreq(&Log.m_sd, AnsiString(LogFreq->Text).c_str()); //JA7UDE 0428 +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateTextData(void) +{ + HisCall->Text = Log.m_sd.call; + HisName->Text = Log.m_sd.name; + HisQTH->Text = Log.m_sd.qth; + HisRST->Text = Log.m_sd.ur; + MyRST->Text = Log.m_sd.my; + EditNote->Text = Log.m_sd.rem; + EditQSL->Text = Log.m_sd.qsl; + LogFreq->Text = Log.GetFreqString(Log.m_sd.band, Log.m_sd.fq); + Log.m_CurChg = 0; + UpdateLogPanel(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::FindCall(void) +{ + CWaitCursor w; + UpdateLogMode(); + m_Dupe = 0; + StrCopy(Log.m_sd.call, AnsiString(HisCall->Text).c_str(), MLCALL); //JA7UDE 0428 + clipsp(Log.m_sd.call); + AddCall(Log.m_sd.call); +// if( IsCall(Log.m_sd.call) ) AddCall(Log.m_sd.call); + AnsiString strHis = HisRST->Text; + if( Log.FindSet(&Log.m_Find, Log.m_sd.call) ){ // 見つかった時 + OnWave(); + Log.SetFreq(&Log.m_sd, AnsiString(LogFreq->Text).c_str()); //JA7UDE 0428 + SDMMLOG sd; + Log.GetData(&sd, Log.m_Find.pFindTbl[0]); // 一番最新のデータ + if( SBQSO->Down ){ + if( (sd.btime == Log.m_sd.btime) && Log.m_Find.GetCount() ){ + Log.GetData(&sd, Log.m_Find.pFindTbl[1]); // 二番目のデータ + } + } + else { + Log.m_sd.btime = 0; + } + if( sd.btime != Log.m_sd.btime ){ + if( Log.m_Find.m_FindCmp1Max ){ + switch(Log.m_LogSet.m_CheckBand){ + case 1: + if( Log.FindSameBand(FALSE) ) m_Dupe = 1; + break; + case 2: + if( Log.FindSameBand(TRUE) ) m_Dupe = 1; + break; + default: + m_Dupe = 1; + break; + } + } + } + if( (!SBQSO->Down || !Log.m_sd.name[0] ) && Log.m_LogSet.m_CopyName ) strcpy(Log.m_sd.name, sd.name); + if( (!SBQSO->Down || !Log.m_sd.qth[0] ) && Log.m_LogSet.m_CopyQTH ) strcpy(Log.m_sd.qth, sd.qth); + if( (!SBQSO->Down || !Log.m_sd.rem[0] ) && Log.m_LogSet.m_CopyREM ) strcpy(Log.m_sd.rem, sd.rem); + if( (!SBQSO->Down || !Log.m_sd.qsl[0] ) && Log.m_LogSet.m_CopyQSL ) strcpy(Log.m_sd.qsl, sd.qsl); + UpdateTextData(); + if( SBQSO->Down ){ + Log.m_Find.Ins(Log.m_CurNo); + UpdateTextData(); + Log.PutData(&Log.m_sd, Log.m_CurNo); + } + } + else { // 見つからなかった時 + if( !SBQSO->Down && Log.m_LogSet.m_CopyName ) Log.m_sd.name[0] = 0; + if( !SBQSO->Down && Log.m_LogSet.m_CopyQTH ) Log.m_sd.qth[0] = 0; + if( !SBQSO->Down && Log.m_LogSet.m_CopyREM ) Log.m_sd.rem[0] = 0; + if( !SBQSO->Down && Log.m_LogSet.m_CopyQSL ) Log.m_sd.qsl[0] = 0; + UpdateTextData(); + } + LPCSTR pCC = ClipCC(Log.m_sd.call); + Log.SetOptStr(0, &Log.m_sd, Cty.GetCountry(pCC)); + Log.SetOptStr(1, &Log.m_sd, Cty.GetCont(pCC)); + if( !strHis.IsEmpty() ) HisRST->Text = strHis; + UpdateCallsign(); + UpdateLogPanel(); + if( !SBQSO->Down ){ + LogLink.SetFreq(AnsiString(LogFreq->Text).c_str()); + LogLink.SetMode(g_tLogModeTable[CBMode->ItemIndex]); + LogLink.FindCall(Log.m_sd.call); + } + else { + LogLink.Write(&Log.m_sd, 1); + } + DoEvent(macOnFind); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::AutoLogSave(void) +{ + if( Log.IsOpen() && Log.m_LogSet.m_AutoSave && Log.IsEdit() ) KFLFClick(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateLogLink(void) +{ + LogLink.UpdateLink(sys.m_LogLink); + UpdateTitle(); + if( sys.m_LogLink ){ + if( !m_pLogLinkTimer ){ + m_pLogLinkTimer = new TTimer(this); + m_pLogLinkTimer->OnTimer = LogLinkTimer; + m_pLogLinkTimer->Interval = LINKINTERVAL; + } + } + else if( m_pLogLinkTimer ){ + delete m_pLogLinkTimer; + m_pLogLinkTimer = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFLFClick(TObject *Sender) +{ + Log.Close(); + Log.Open(NULL, TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::HisCallChange(TObject *Sender) +{ + UpdateLogPanel(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::SBDataClick(TObject *Sender) +{ + SDMMLOG sd; + + UpdateLogData(); + if( strcmp(Log.m_Find.GetText(), Log.m_sd.call) ){ + CWaitCursor w; + Log.FindSet(&Log.m_Find, Log.m_sd.call); + } + TQSODlgBox *pBox = new TQSODlgBox(this); + OnWave(); + memcpy(&sd, &Log.m_sd, sizeof(sd)); + DettachFocus(); + if( pBox->Execute(&Log.m_Find, &Log.m_sd, Log.m_CurNo) == TRUE ){ + if( memcmp(&sd, &Log.m_sd, sizeof(sd)) ){ + UpdateTextData(); + HisCallChange(NULL); + LogLink.Write(&Log.m_sd, 0); + } + } + delete pBox; + AttachFocus(); + UpdateLogPanel(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBFindClick(TObject *Sender) +{ + AnsiString strName = HisName->Text; + AnsiString strMy = MyRST->Text; + if( !Log.IsOpen() ){ + if( Log.Open(NULL, TRUE) == FALSE ){ + UpdateLogPanel(); + return; + } + } + FindCall(); + DettachFocus(); + TQSODlgBox *pBox = new TQSODlgBox(this); + pBox->ShowFind(&Log.m_Find); + delete pBox; + if( HisName->Text.IsEmpty() ) HisName->Text = strName; + if( MyRST->Text.IsEmpty() ) MyRST->Text = strMy; + AutoLogSave(); + UpdateLogPanel(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOLClick(TObject *Sender) +{ + DettachFocus(); + TLogSetDlg *pBox = new TLogSetDlg(this); + pBox->Execute(); + delete pBox; + UpdateLogLink(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CheckLogLink(void) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFLOClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options >> ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Open LogData File"; + pBox->Filter = "MMLOG Data Files(*.mdt)|*.mdt|"; + } + else { + pBox->Title = "ログファイルのオープン"; + pBox->Filter = "MMLOGデータファイル(*.mdt)|*.mdt|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "mdt"; + pBox->InitialDir = sys.m_LogDir; + DettachFocus(); + if( pBox->Execute() == TRUE ){ + Log.Close(); + Log.DoBackup(); + Log.MakeName(AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + Log.Open(NULL, TRUE); + UpdateTextData(); + UpdateTitle(); + } + UpdateLogPanel(); + delete pBox; + if( Active ) AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBListClick(TObject *Sender) +{ + DettachFocus(); + TLogListDlg *pBox = new TLogListDlg(this); + OnWave(); + pBox->Execute(); + delete pBox; + AutoLogSave(); + UpdateLogLink(); + UpdateTitle(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CMMML(TMessage &Message) +{ + if( sys.m_LogLink != 2 ) return; + if( LogLink.m_pLink == NULL ) return; + + switch(Message.WParam){ + case MML_NOTIFYSESSION: + LogLink.NotifySession((LPCSTR)Message.LParam); + UpdateLogLink(); + break; + case MML_QRETURN: + if( !LogLink.IsLink() ) return; + if( LogLink.QReturn(&Log.m_sd, (const mmLOGDATA *)Message.LParam) ){ + UpdateTextData(); + } + break; + case MML_VFO: + if( !LogLink.IsLink() ) return; + if( Message.LParam ){ + LogFreq->Text = (LPCSTR)Message.LParam; + OnLogFreq(FALSE); + } + break; + } + Message.Result = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CMMMR(TMessage &Message) +{ + if( m_pRadio == NULL ) return; + + switch(Message.WParam){ + case MMR_DEFCOMMAND: + { + LPCSTR p; + switch(Message.LParam){ + case 1: + p = RADIO.CmdRx.c_str(); + break; + case 2: + p = RADIO.CmdTx.c_str(); + break; + default: + p = RADIO.CmdInit.c_str(); + break; + } + m_pRadio->SendCommand(p); + } + break; + case MMR_VFO: + m_pRadio->UpdateFreq(double(Message.LParam)/10000.0); + break; + } + Message.Result = TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVWAClick(TObject *Sender) +{ + InvMenu(KVWA); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitDefKey(void) +{ + sys.m_DefKey[kkTX] = VK_F12; + sys.m_DefKey[kkTXOFF] = VK_PAUSE; +} +//--------------------------------------------------------------------------- +// 初回の初期化 +__fastcall CRxSet::CRxSet() +{ + m_fShowed = FALSE; + m_Mode = sys.m_DefaultMode; + m_fTWO = 0; + m_fMBCS = 0; + m_fAFC = TRUE; + m_SQLevel = 300; + m_SQ = FALSE; + m_SQTimer = 0; + m_Speed = SPEED; + m_AFCTimerW = 0; + m_AFCTimerN = 0; + m_AFCTimerW2 = 0; + m_AFCFQ = 0; + m_AFCSQ = 0; + m_fATC = FALSE; + m_WaterW = 400; + m_pFFT = &MainVARI->m_FFT; + m_CarrierFreq = 1750; + m_MFSK_TYPE = typMFSK16; + m_AFCTimerPSK = m_AFCTimerMFSK = 0; + m_RTTYFFT = FALSE; + + memset(&m_StgFFT, 0, sizeof(m_StgFFT)); + m_StgFFT.VW = 100; + InitStgFFT(); + + m_FontData.m_Name = ""; + m_FontData.m_Charset = 0; + m_FontData.m_Height = 0; + m_FontData.m_Style = 0; + + m_cAutoTS1 = m_cAutoTS2 = 0; + m_AvgAFC.Create(8); + + m_pDem = NULL; + m_pView = NULL; +} +//--------------------------------------------------------------------------- +__fastcall CRxSet::~CRxSet() +{ + Delete(); +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::SetMFSKType(int type) +{ + m_MFSK_TYPE = type; + if( IsActive() ) m_pDem->SetMFSKType(type); +} +//--------------------------------------------------------------------------- +double __fastcall CRxSet::GetSpeed(void) +{ + if( IsMFSK() ){ + const double _tt[]={15.625,7.8125,31.25,10.767,21.533,32.0,62.5,3.9063}; + return _tt[m_MFSK_TYPE]; +// return IsActive() ? m_pDem->m_MFSK_SPEED : 15.625; + } + else { + return m_Speed; + } +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::SetSpeed(double b) +{ + if( b < MIN_SPEED ) return; + if( b > MAX_SPEED ) return; + if( m_Speed != b ){ + m_Speed = b; + if( IsActive() ) m_pDem->SetSpeed(b); + } +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::SetMode(int mode) +{ + int Offset = 0; + double Speed = 0.0; + if( m_Mode != mode ){ + if( ::IsRTTY(mode) ){ + if( !::IsRTTY(m_Mode) ){ + Speed = 45.45; + } + } + else if( ::IsMFSK(mode) ){ + if( !::IsMFSK(m_Mode) ){ + Speed = 15.625; + } + } + else { + if( ::IsRTTY(m_Mode) || ::IsMFSK(m_Mode) ){ + Speed = 31.25; + } + } + if( ::IsMFSK(mode) && ::IsMFSK(m_Mode) && !sys.m_MFSK_Center ){ + int bw = m_pDem ? m_pDem->m_MFSK_BW : 234.375; + Offset = (mode == MODE_mfsk_U) ? -bw : bw; + } + } + m_Mode = mode; + if( Speed > 1.0 ) MainVARI->UpdateSpeed(this, Speed); + MainVARI->InitCollect(this, ::IsRTTY(m_Mode) ? 7 : 14); + switch(m_Mode){ + case MODE_RTTY: + case MODE_U_RTTY: + case MODE_GMSK: + case MODE_FSK: + case MODE_FSKW: + case MODE_BPSK: + m_fTWO = FALSE; + break; + case MODE_N_BPSK: + case MODE_mfsk_L: + case MODE_mfsk_U: + case MODE_qpsk_L: + case MODE_qpsk_U: + m_fTWO = TRUE; + break; + } + m_fMBCS = FALSE; + m_AFCTimerPSK = m_AFCTimerMFSK = 0; + if( IsActive() ) m_pDem->SetType(m_Mode); + m_AvgAFC.Create(IsMFSK() ? 4 : 8); + m_AvgAFC.Reset(m_pDem->m_CarrierFreq); + MainVARI->UpdateMode(this, Offset); +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::SetCarrierFreq(double f) +{ + if( IsActive() ){ + m_pDem->SetCarrierFreq(f); + m_CarrierFreq = f; + } + m_AvgAFC.Reset(f); + m_AFCTimerPSK = 0; + m_AFCFQ = f; +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::Create(BOOL fView) +{ + m_SQLevel = 300; + m_SQ = FALSE; + m_SQTimer = 0; + m_AFCTimerW = 0; + m_AFCTimerN = 0; + m_AFCTimerW2 = 0; + m_AFCFQ = 0; + m_AFCSQ = 0; + m_fATC = FALSE; + m_pFFT = &MainVARI->m_FFT; + + m_StgFFT.dBSum = 0; + m_StgFFT.dBMax = 0; + m_StgFFT.dBWMax = 0; + m_StgFFT.VW = 100; + m_StgFFT.DispSig = 0; + m_StgFFT.Timer = 0; + InitStgFFT(); + + m_cAutoTS1 = m_cAutoTS2 = 0; + + m_PeakSig = 0; + m_AvgSig.Create(32); + LimitInt(&m_CarrierFreq, MIN_CARRIER, sys.m_MaxCarrier); + LimitInt(&m_SQLevel, 0, LEVELMAX); + LimitDbl(&m_Speed, MIN_SPEED, MAX_SPEED); + + if( IsRTTY() ) m_Speed = 45.45; + + EPHASE(P_SUBCREATE); + if( !m_pDem ){ + m_pDem = new CDEMFSK; + if( !m_pDem ){ + MainVARI->SetErrorMsg("Out of memory"); + return; + } + m_pDem->m_fRTTYFFT = m_RTTYFFT; + m_pDem->SetSampleFreq(DEMSAMPFREQ); + m_pDem->SetSpeed(m_Speed); + m_pDem->SetType(m_Mode); + m_pDem->SetMFSKType(m_MFSK_TYPE); + m_pDem->m_Decode.SetATCSpeed(MainVARI->m_ATCSpeed); + m_pDem->m_Decode.SetATCLimit(MainVARI->m_ATCLimit); + if( fView ){ // サブウインドウの場合 + m_pDem->m_Decode.m_fATC = TRUE; + m_pDem->m_fAFC = m_fAFC; + m_pDem->m_fEnableAFC = TRUE; + CDEMFSK *pDem = MainVARI->m_RxSet[0].m_pDem; + m_pDem->MakeBPF(pDem->m_PreBPFTaps); + m_pDem->m_pBPF = &pDem->m_inBPF; + SetCarrierFreq(m_CarrierFreq); +// m_fJA = MainVARI->m_RxSet[0].m_fJA; + } + InitStgFFT(); + m_StgFFT.Timer = 0; + } + EPHASE(P_SUBVIEW); + if( fView && !m_pView ){ + m_pView = new TRxViewDlg(MainVARI); + if( !m_pView ){ + delete m_pDem; m_pDem = NULL; + MainVARI->SetErrorMsg("Out of memory"); + return; + } + m_pView->m_pRxSet = this; + m_pView->SetBounds(m_rcView.left, m_rcView.top, m_rcView.right, m_rcView.bottom); + m_pView->UpdateWaterWidth(); + m_pView->m_Dump.SetRTTY(IsRTTY()); + m_pView->m_Dump.ShowCtrl(sys.m_fShowCtrlCode); + if( m_FontData.m_Height ){ + FontData2Font(m_pView->PC->Font, &m_FontData); + } + m_pView->OnUpdateFont(); + memcpy(m_pView->m_Dump.m_Color, MainVARI->m_Dump.m_Color, sizeof(MainVARI->m_Dump.m_Color)); +// ::SetWindowPos(m_pView->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); + } + EPHASE(P_NULL); + SetMode(m_Mode); +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::Delete(void) +{ + if( m_pDem ){ + m_CarrierFreq = m_pDem->m_CarrierFreq + 0.5; + delete m_pDem; + m_pDem = NULL; + } + if( m_pView ){ + MainVARI->CloseWheelTimer(&m_pView->m_Dump); + m_rcView.left = m_pView->Left; + m_rcView.top = m_pView->Top; + m_rcView.right = m_pView->Width; + m_rcView.bottom = m_pView->Height; + Font2FontData(&m_FontData, m_pView->PC->Font); + delete m_pView; + m_pView = NULL; + m_fShowed = TRUE; + } + else { + m_fShowed = FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::SetSampleFreq(double f) +{ + if( !IsActive() ) return; + m_pDem->SetSampleFreq(f); + if( m_pView ) m_pView->UpdateWaterWidth(); +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::InitStgFFT(void) +{ + if( m_pFFT->m_FFTGain ){ + m_StgFFT.Sum = 1024; + m_StgFFT.Max = 1024; + m_StgFFT.WMax = 1024; + } + else { + m_StgFFT.Sum = 5000; + m_StgFFT.Max = 5000; + m_StgFFT.WMax = 5000; + } + m_StgFFT.Sig = 0; +} +//--------------------------------------------------------------------------- +void __fastcall CRxSet::ClearWindow(void) +{ + if( !IsActive() ) return; + if( m_pView ) m_pView->m_Dump.Clear(); +} +//--------------------------------------------------------------------------- +double __fastcall CRxSet::GetBandWidth(void) +{ + switch(m_Mode){ + case MODE_GMSK: + case MODE_BPSK: + case MODE_N_BPSK: + case MODE_qpsk_L: + case MODE_qpsk_U: + return m_Speed; + case MODE_FSK: + return m_Speed*2; + case MODE_FSKW: + case MODE_RTTY: + case MODE_U_RTTY: + return m_pDem->m_RTTYShift; + case MODE_mfsk_L: + case MODE_mfsk_U: + if( m_pDem ){ + return m_pDem->m_MFSK_BW; + } + else { + return 234.375; + } + } + return 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateSubWindow(void) +{ + m_fSubWindow = FALSE; + int i; + for( i = 1; i < RXMAX; i++ ){ + if( m_RxSet[i].IsActive() ) m_fSubWindow = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ShowSubChannel(int n, int sw) +{ + DettachFocus(); + CRxSet *pRxSet = &m_RxSet[n]; + if( sw == 2 ){ + sw = !pRxSet->IsActive(); + } + if( sw ){ + if( !pRxSet->IsActive() ){ + pRxSet->Create(TRUE); + sprintf(m_TextBuff, sys.m_MsgEng ? "Channel - %u":"チャンネル - %u", n); + pRxSet->m_pView->Caption = m_TextBuff; + } + pRxSet->m_pView->Visible = TRUE; + } + else { + if( pRxSet->IsActive() ) pRxSet->Delete(); + } + UpdateSubWindow(); + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxFFTMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( SBWave->Down ) return; + + // FFTまたはWaterFallの場合 + if( m_MouseDown ){ + int fq = m_FFTB + X * m_FFTW / m_fftXW; + if( fq < MIN_CARRIER ) fq = MIN_CARRIER; + if( fq > sys.m_MaxCarrier ) fq = sys.m_MaxCarrier; + if( m_MouseNotch ){ + m_Notches.SetFreq(m_MouseNotch-1, fq); + if( m_MouseNotch == 1 ) m_NotchFreq = fq; + PBoxFFTPaint(NULL); + } + else if( m_MouseSubChannel ){ + CRxSet *pRxSet = &m_RxSet[m_MouseSubChannel]; + if( pRxSet->IsActive() ){ + pRxSet->m_pDem->m_Decode.Reset(); + pRxSet->m_pDem->ResetMeasMFSK(); + pRxSet->SetCarrierFreq(fq); + PBoxFFTPaint(NULL); + } + } + else { + m_RxSet[0].m_pDem->m_Decode.Reset(); + SetRxFreq(fq); + } + } + else if( m_fSubWindow || m_Notches.m_Count ){ + m_MouseNotch = FALSE; + m_MouseSubChannel = FALSE; + int i; + if( m_Notches.m_Count ){ + for( i = 0; i < m_Notches.m_Count; i++ ){ + int xx = X - m_Notches.m_pBase[i].m_MX; + int yy = Y - m_Notches.m_pBase[i].m_MY; + int d = (xx * xx + yy * yy); + if( d < 64 ){ + m_MouseNotch = i + 1; + } + } + } + if( !m_MouseNotch ){ + CRxSet *pRxSet = &m_RxSet[RXMAX-1]; + for( i = RXMAX-1; i > 0; i--, pRxSet-- ){ + if( pRxSet->IsActive() ){ + int xx = X - pRxSet->m_X; + int yy = Y - pRxSet->m_Y; + int d = (xx * xx + yy * yy); + if( d < 64 ){ + m_MouseSubChannel = i; + break; + } + } + } + } + PBoxFFT->Cursor = (m_MouseNotch || m_MouseSubChannel) ? crSizeWE : crDefault; + } + else { + m_MouseSubChannel = FALSE; + m_MouseNotch = 0; +// int XO = (UdRxCarrier->Position - m_FFTB) * m_fftXW / m_FFTW; +// XO -= X; XO *= XO; +// PBoxFFT->Cursor = (XO < 64) ? crSizeWE : crDefault; + PBoxFFT->Cursor = crDefault; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxFFTMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( m_MouseDown && !SBFFT500->Down ){ + int fq = m_FFTB + X * m_FFTW / m_fftXW; + if( fq < MIN_CARRIER ) fq = MIN_CARRIER; + if( fq > sys.m_MaxCarrier ) fq = sys.m_MaxCarrier; + if( m_MouseNotch ){ + m_Notches.SetFreq(m_MouseNotch-1, fq); + if( m_MouseNotch == 1 ) m_NotchFreq = fq; + PBoxFFTPaint(NULL); + } + else if( m_MouseSubChannel ){ + CRxSet *pRxSet = &m_RxSet[m_MouseSubChannel]; + if( pRxSet->IsActive() ){ + fq = GetSignalFreq(fq, SBFFT3K->Down ? 50 : 32, pRxSet); + pRxSet->m_pDem->m_Decode.Reset(); + pRxSet->m_pDem->ResetMeasMFSK(); + pRxSet->m_PeakSig = 0; + pRxSet->SetCarrierFreq(fq); + pRxSet->m_AFCTimerMFSK = (SBFFT500->Down || SBFFT1K->Down) ? MFSKAFC_MAX : 0; + PBoxFFTPaint(NULL); + } + } + else { + fq = GetSignalFreq(fq, SBFFT3K->Down ? 50 : 32, &m_RxSet[0]); + m_RxSet[0].m_pDem->m_Decode.Reset(); + SetRxFreq(fq); + m_RxSet[0].m_AFCTimerMFSK = (SBFFT500->Down || SBFFT1K->Down) ? MFSKAFC_MAX : 0; + m_RxSet[0].m_PeakSig = 0; + } + } + m_MouseDown = FALSE; + m_MouseSubChannel = FALSE; + m_MouseNotch = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KCallClick(TObject *Sender) +{ + TMenuItem *pm = (TMenuItem *)Sender; + if( strcmp(AnsiString(HisCall->Text).c_str(), (AnsiString(pm->Caption).c_str()+6)) ){ //JA7UDE 0428 + HisCall->Text = pm->Caption.c_str() + 6; + FindCall(); + UpdateUI(); + SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::AddCall(LPCSTR p) +{ + SYSTEMTIME now; + GetLocal(&now); + char bf[128]; + sprintf(bf, "%02u:%02u\t%s", now.wHour, now.wMinute, p); + + int i; + TMenuItem *pm; + for( i = 0; i < PupCalls->Items->Count; i++ ){ + pm = PupCalls->Items->Items[i]; + if( !strcmp(AnsiString(pm->Caption).c_str()+6, p) ){ //JA7UDE 0428 + if( !i ){ + pm->Caption = bf; + return; + } + else { + PupCalls->Items->Delete(i); + break; + } + } + } + pm = new TMenuItem (this); + pm->Caption = bf; + pm->RadioItem = FALSE; + pm->OnClick = KCallClick; + pm->Checked = FALSE; + pm->Enabled = TRUE; + if( (i >= PupCalls->Items->Count) && (PupCalls->Items->Count == STGCALLMAX) ){ + PupCalls->Items->Delete(STGCALLMAX-1); + } + PupCalls->Items->Insert(0, pm); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetTXFocus(void) +{ + if( PCTX->CanFocus() ) PCTX->SetFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBMClick(TObject *Sender) +{ + if( PupCalls->Items->Count ){ + RECT rc; + ::GetWindowRect(PLog->Handle, &rc); + PupCalls->Popup(rc.left+SBM->Left + SBM->Width/2, rc.top+SBM->Top+SBM->Height/2); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::DeleteMacroTimerS(void) +{ + BOOL r = FALSE; + if( m_ReqMacroTimer || m_pMacroTimer ){ + m_ReqMacroTimer = 0; + if( m_CurrentMacro >= 0 ){ + MACBUTTON *pList = &m_tMacButton[m_CurrentMacro]; + if( pList->pButton ) pList->pButton->Down = FALSE; + } + if( m_pMacroTimer ){ + m_pMacroTimer->Enabled = FALSE; + delete m_pMacroTimer; + m_pMacroTimer = NULL; + } + DrawHint(); + r = TRUE; + } + m_pCurrentMacroMenu = NULL; + return r; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DeleteMacroTimer(void) +{ + if( DeleteMacroTimerS() ){ + if( m_TX ) ToRX(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CreateMacroTimer(int n) +{ + if( n <= 100 ) n = 100; + if( m_pMacroTimer ){ + delete m_pMacroTimer; + m_pMacroTimer = NULL; + } + if( ((m_CurrentMacro >= 0) && (m_CurrentMacro < MACBUTTONALL)) || (m_CurrentMacro == -1) ){ + m_pMacroTimer = new TTimer(this); + m_pMacroTimer->Interval = n; + m_pMacroTimer->OnTimer = MacroTimer; + m_pMacroTimer->Enabled = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVLAClick(TObject *Sender) +{ + InvMenu(KVLA); + UpdateLogHeight(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateLogHeight(void) +{ + BOOL f = KVLA->Checked; + if( f ){ + PLog->Height = 52; + } + else { + PLog->Height = 26; + } + L16->Visible = f; + L17->Visible = f; + L18->Visible = f; + HisQTH->Visible = f; + EditNote->Visible = f; + EditQSL->Visible = f; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PLogMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ) KVLAClick(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateMacButtonVW(int n) +{ + if( n < 2 ) n = 2; + if( n > 4 ) n = 4; + + m_MacButtonVW = n; + n *= 16; + PCMac->SetBounds(0, StatusBar->Top - n, ClientWidth, n); + UdMac->Height = n; + SetMacButtonMax(); + CreateMacButton(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVM2Click(TObject *Sender) +{ + int n = 3; + if( Sender == KVM2 ){ + n = 2; + } + else if( Sender == KVM4 ){ + n = 4; + } + UpdateMacButtonVW(n); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::UdMacMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + UdMac->Position = 0; + CreateMacButton(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KOAClick(TObject *Sender) +{ + if( m_TX ) return; + + if( !m_pClockView ) m_pClockView = new TClockAdjDlg(this); + m_pClockView->Execute(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::SBDataMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + int n = Log.m_CurNo - 1; + if( n < 0 ){ + SBDataClick(NULL); + return; + } + + TQSODlgBox *pBox = new TQSODlgBox(this); + SDMMLOG sd; + Log.GetData(&sd, n); + CLogFind Find; + + Log.FindSet(&Find, sd.call); + + DettachFocus(); + pBox->Execute(&Find, &sd, n); + delete pBox; + AttachFocus(); + if( !SBQSO->Down && Log.m_CurNo && Log.IsEdit() ){ + Log.SetLastPos(); + UpdateTextData(); + } + AutoLogSave(); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::SBFindMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + AnsiString as; + if( InputMB("MMVARI", "Callsign", as) == TRUE ){ + jstrupr(as.c_str()); + CLogFind find; + Log.FindSet(&find, as.c_str() ); + TQSODlgBox *pBox = new TQSODlgBox(this); + DettachFocus(); + pBox->ShowFind(&find); + delete pBox; + AttachFocus(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFLClick(TObject *Sender) +{ + if( m_Dump.IsLogging() ){ + m_Dump.CloseLogFile(); + } + else { + ::SetCurrentDirectory(sys.m_BgnDir); + char bf[256]; + sprintf(bf, "%sRxLog", sys.m_BgnDir); + mkdir(bf); + ::GetLocal(&m_LocalTime); + sprintf(bf, "%sRxLog\\%04u%02u%02u.txt", + sys.m_BgnDir, + m_LocalTime.wYear, + m_LocalTime.wMonth, + m_LocalTime.wDay + ); + m_Dump.OpenLogFile(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFLRClick(TObject *Sender) +{ + char bf[256]; + sprintf(bf, "%sRxLog", sys.m_BgnDir); + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Load text file"; + pBox->Filter = "Text files(*.txt)|*.txt|"; + } + else { + pBox->Title = "テキストファイル参照"; + pBox->Filter = "テキストファイル(*.txt)|*.txt|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "txt"; + pBox->InitialDir = bf; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + m_Dump.FlushLogFile(); + OnWave(); + if( !m_pEdit ){ + m_pEdit = new TFileEdit(this); + m_pEdit->SetEvent(Handle, WM_WAVE, 2); + } + if( m_pEdit ){ + m_pEdit->Execute(AnsiString(pBox->FileName).c_str(), FALSE); //JA7UDE 0428 + } + } + else { + AttachFocus(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVSFTClick(TObject *Sender) +{ + if( (Sender == KVSFR) && (!m_pRadio || !RADIO.PollType) ){ + if( YesNoMB(sys.m_MsgEng ? "Radio command must be installed, do you open the setup window?":"リグコントロール(周波数取り込み)を設定する必要があります. 設定画面を開きますか?") == IDYES ){ + KORClick(NULL); + } +// if( (!m_pRadio || !RADIO.PollType) ) return; + if( !m_pRadio ) return; + } + m_ScaleAsRigFreq = (Sender == KVSFT) ? FALSE : TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KORClick(TObject *Sender) +{ + DettachFocus(); + TRADIOSetDlg *pBox = new TRADIOSetDlg(this); + RADIO.change = pBox->Execute(); + delete pBox; + AttachFocus(); + if( RADIO.change ) OpenRadio(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateSpeedList(int mode) +{ + if( IsMFSK(mode) ){ + SetComboBox(CBSpeed, "3.9063,7.8125,10.767,15.625,21.533,31.25,32.0,62.5"); + } + else if( ::IsRTTY(mode) ){ + SetComboBox(CBSpeed, "45.45,75.0,110.0"); + } + else { + SetComboBox(CBSpeed, m_ListBAUD.c_str()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetMode(int mode) +{ + if( m_RxSet[0].m_Mode != mode ){ + if( (::IsMFSK(mode) != ::IsMFSK(m_RxSet[0].m_Mode)) || + (::IsRTTY(mode) != ::IsRTTY(m_RxSet[0].m_Mode)) + ){ + UpdateSpeedList(mode); + } + m_RxSet[0].SetMode(mode); + m_ModFSK.SetType(mode); +#if DEBUG + m_ModTest.SetType(mode); +#endif + m_fDisEvent++; + CBMode->ItemIndex = mode; + m_fDisEvent--; + m_Dump.SetRTTY(IsRTTY()); + UpdateLogMode(); + UpdateUI(); + switch(mode){ + case MODE_GMSK: + SetInfoMsg(sys.m_MsgEng ? "GMSK : For MBCS language":"GMSK : MBCS伝送実験用(HF)"); + break; + case MODE_FSK: + SetInfoMsg(sys.m_MsgEng ? "FSK : For V/UHF":"FSK : V/UHF帯用モード"); + break; + case MODE_FSKW: + SetInfoMsg(sys.m_MsgEng ? "FSK-W : For V/UHF and satellite":"FSK-W : V/UHF帯/衛星通信用モード"); + break; + case MODE_BPSK: + SetInfoMsg(sys.m_MsgEng ? "BPSK : No compatible on MBCS":"BPSK : 従来方式と互換性なし(VariJAは使用注意)"); + break; + case MODE_N_BPSK: + SetInfoMsg(sys.m_MsgEng ? "bpsk : Compatible with conventionally VARICODE":"bpsk : 従来方式と互換性あり"); + break; + case MODE_RTTY: + SetInfoMsg("rtty(LSB) : BAUDOT"); + break; + case MODE_U_RTTY: + SetInfoMsg("rtty(USB) : BAUDOT"); + break; + case MODE_mfsk_L: + case MODE_mfsk_U: + sprintf(m_TextBuff, "mfsk%d (%s)", int((250.0/m_RxSet[0].m_pDem->m_MFSK_TONES)+0.5), mode == MODE_mfsk_L ? "LSB":"USB"); + SetInfoMsg(m_TextBuff); + break; + case MODE_qpsk_L: + case MODE_qpsk_U: + SetInfoMsg(sys.m_MsgEng ? "qpsk : Compatible with conventionally VARICODE":"qpsk : 従来方式と互換性あり"); + break; + } + UpdateLogMode(); + DoEvent(macOnMode); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CBModeChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + SetMode(CBMode->ItemIndex); + SetTXFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KECPClick(TObject *Sender) +{ + AnsiString as; + + if( m_Edit[m_CurrentEdit].GetSelText(as) ){ + Clipboard()->AsText = as; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KEXClick(TObject *Sender) +{ + AnsiString as; + + if( m_Edit[m_CurrentEdit].GetSelText(as) ){ + Clipboard()->AsText = as; + m_Edit[m_CurrentEdit].DeleteSelText(); + m_Edit[m_CurrentEdit].Paint(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxTXMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbLeft ){ + if( m_fpText ) return; + m_Edit[m_CurrentEdit].MoveCursor(X, Y, TRUE); + m_Edit[m_CurrentEdit].OpenSelect(); + m_MouseDown = TRUE; + } + else if( Button == mbRight ){ + RECT rc; + ::GetWindowRect(PCTX->Handle, &rc); + rc.left += X; rc.top += Y+8; + PupTX->Popup(rc.left, rc.top); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::PBoxTXMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_MouseDown ){ + m_Edit[m_CurrentEdit].MoveCursor(X, Y, FALSE); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxTXMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + m_Edit[m_CurrentEdit].CloseSelect(); + m_MouseDown = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoSuspend(BOOL fMinimize) +{ + if( !m_fSuspend ){ + DeleteMacroTimer(); + if( m_TX ) ToRX(); + m_Wave.InClose(); + m_Wave.OutAbort(); + if( m_pCom ){ + delete m_pCom; + m_pCom = NULL; + } + if( m_pRadio ){ + delete m_pRadio; + m_pRadio = NULL; + } + if( m_fpText ) fflush(m_fpText); + Log.Close(); + UpdateLogPanel(); + m_fSuspend = TRUE; + m_fShowMsg = TRUE; + } + if( fMinimize && (WindowState != wsMinimized) ) Application->Minimize(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoResume(void) +{ + if( m_fSuspend ){ + if( OpenSound(FALSE) ){ + OpenCom(); + OpenRadio(); + Log.Open(NULL, TRUE); + UpdateLogPanel(); + m_fSuspend = FALSE; + if( WindowState == wsMinimized ) Application->Restore(); + } + else { + Draw(FALSE); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KECallClick(TObject *Sender) +{ + SetTXFocus(); + TMenuItem *pItem = (TMenuItem *)Sender; + StrCopy(m_TextBuff, AnsiString(pItem->Caption).c_str(), sizeof(m_TextBuff)-1); //JA7UDE 0428 + LPSTR p = m_TextBuff; + for( ; *p; p++ ){ + if( *p == '\t' ){ + *p = 0; + break; + } + } + DoMacro(m_TextBuff, NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetEditPage(int cno) +{ + if( cno == m_CurrentEdit ) return; + + DettachFocus(); + CDump *pEdit = &m_Edit[cno]; + CDump *pOld = &m_Edit[m_CurrentEdit]; + m_CurrentEdit = cno; + if( !pEdit->IsCreate() ){ + pEdit->Create(PCTX->Handle, PCTX, PBoxTX, PCTX->Font, SBarTX, 512); + pEdit->SetCursorType(csCARET); + } + if( memcmp(pEdit->GetLogFontP(), pOld->GetLogFontP(), sizeof(LOGFONT)) || + pEdit->GetWindowSize() != pOld->GetWindowSize() + ){ + pEdit->SetFont(PCTX->Font); + pEdit->Resize(); + } + else { + pEdit->SetScrollBar(); + } + pEdit->SetMBCS(&m_RxSet[0].m_MBCS); + pEdit->m_fConvAlpha = m_fConvAlpha; + PBoxTX->Invalidate(); + AttachFocus(); + PageStatus(); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KPG1Click(TObject *Sender) +{ + int cno = 0; + if( Sender == KPG2 ){ + cno = 1; + } + else if( Sender == KPG3 ){ + cno = 2; + } + else if( Sender == KPG4 ){ + cno = 3; + } + SetEditPage(cno); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupPagePopup(TObject *Sender) +{ + switch(m_CurrentEdit){ + case 1: + KPG2->Checked = TRUE; + break; + case 2: + KPG3->Checked = TRUE; + break; + case 3: + KPG4->Checked = TRUE; + break; + default: + KPG1->Checked = TRUE; + break; + } + OnMenuProc(PupPage->Items, "PopPAGE"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitCollect(CRxSet *pRxSet, int n) +{ + if( pRxSet != &m_RxSet[0] ) return; + + if( n < 4 ) n = 4; + if( n > 24 ) n = 24; + m_WaveBitMax = n; + InitCollect(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InitCollect(void) +{ + double speed = m_RxSet[0].m_Speed; + if( m_RxSet[0].IsMFSK() ) speed = m_RxSet[0].m_pDem->m_MFSK_SPEED; + m_Collect1.Create(DEMSAMPFREQ*m_WaveBitMax/speed); + m_Collect2.Create(DEMSAMPFREQ*m_WaveBitMax/speed); + if( m_RxSet[0].IsActive() ){ + int n = m_WaveBitMax; + if( !(n & 1) ) n++; + m_RxSet[0].m_pDem->m_Decode.m_cBWave = n; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBWaveMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button == mbRight ){ + m_WaveType = m_WaveType ? 0 : 1; + UpdateWaveCaption(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSASClick(TObject *Sender) +{ + KSTXClick(NULL); + DoMacro(sys.m_AS.c_str(), NULL); +} +//--------------------------------------------------------------------------- +#if DEBUG +void __fastcall TMainVARI::TestSignal(void) +{ + DettachFocus(); + TTestDlg *pBox = new TTestDlg(this); + AnsiString fName = sys.m_testName.c_str(); + int r = pBox->Execute(); + delete pBox; + if( r ){ + double snr = sys.m_testSN-20.9; + if( snr >= (20.9-3.0) ){ + sys.m_testGain = (16384); + sys.m_testNoiseGain = (16384) / pow(10, snr/20.0); + } + else { + sys.m_testNoiseGain = 2369.5; + sys.m_testGain = 2369.5 * pow(10, snr/20.0); + } + sys.m_testGain2 = sys.m_testGain * pow(10, sys.m_testDB2/20.0); + m_TestHPF.Create(ffHPF, 700, SAMPFREQ+SAMPTXOFFSET, 3, 0, 0); + m_QSB.Create(sys.m_testGain / pow(10, sys.m_testQSBDB/20.0), sys.m_testGain, sys.m_testQSBTime, sys.m_testPhase); + double baud = m_RxSet[0].m_Speed - m_RxSet[0].m_Speed * sys.m_testClockErr * 1.0e-6; + m_ModTest.SetSpeed(baud); + if( sys.m_testCarrier1 ) m_ModTest.SetCarrierFreq(sys.m_testCarrier1); + if( sys.m_testCarrier2 ) m_VCOTest.SetFreeFreq(sys.m_testCarrier2); + if( sys.m_testCarrier1 ){ + int fq = sys.m_testCarrier1; + if( !sys.m_MFSK_Center ){ + switch( m_RxSet[0].m_Mode ){ + case MODE_mfsk_L: + fq -= 125; + break; + case MODE_mfsk_U: + fq += 125; + break; + } + } + int bw = (sys.m_test500 == 1) ? 250 : 135; + int tap = (sys.m_test500 == 1) ? 96 : 128; + m_BPF500.Create(tap, ffBPF, SAMPFREQ+SAMPTXOFFSET, fq-bw, fq+bw, 60.0, 1.0); + } + if( r == 2 ){ // 終了 + if( m_fpTest ){ + fclose(m_fpTest); + m_fpTest = NULL; + } + if( sys.m_test ){ + m_Wave.OutAbort(); + OpenSound(FALSE); + sys.m_test = FALSE; + } + } + else { // 開始 + if( m_fpTest && (fName != sys.m_testName) ){ + fclose(m_fpTest); + m_fpTest = NULL; + m_ModTest.m_Encode.Reset(FALSE); + } + ::SetCurrentDirectory(sys.m_BgnDir); + if( !m_fpTest ) m_fpTest = fopen(sys.m_testName.c_str(), "rb"); + if( !sys.m_test ){ + sys.m_test = TRUE; + m_ModTest.m_Encode.Reset(FALSE); + m_ModTest.Reset(); + m_TestTimer = 5 * SAMPFREQ / m_BufferSize; + if( m_TX ) ToRX(); + m_Wave.InClose(); + OpenSound(TRUE); + for( int i = 0; i < m_Wave.m_OutFifoSize; i++ ){ + DoDem(); + m_Wave.OutWrite(m_wBuffer); + } + } + } + } + AttachFocus(); +} +#endif +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OpenWheelTimer(CDump *pDump) +{ + if( m_pDump != pDump ){ + m_pDump = pDump; + } + if( !m_pWheelTimer ){ + m_pWheelTimer = new TTimer(this); + m_pWheelTimer->OnTimer = WheelTimer; + m_pWheelTimer->Interval = 500; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CloseWheelTimer(CDump *pDump) +{ + if( m_pDump == pDump ){ + m_pDump = NULL; + if( m_pWheelTimer ){ + delete m_pWheelTimer; + m_pWheelTimer = NULL; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnMouseWheel(TMessage &Message) +{ + if( !sys.m_EnableMouseWheel ) return; + if( m_Dump.OnMouseWheel(Message.WParam >> 16) ){ + OpenWheelTimer(&m_Dump); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetATCSpeed(int f) +{ + m_ATCSpeed = f; + CRxSet *pRxSet = m_RxSet; + for( int i = 0; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ) pRxSet->m_pDem->m_Decode.SetATCSpeed(f); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetATCLimit(int f) +{ + m_ATCLimit = f; + CRxSet *pRxSet = m_RxSet; + for( int i = 0; i < RXMAX; i++, pRxSet++ ){ + if( pRxSet->IsActive() ) pRxSet->m_pDem->m_Decode.SetATCLimit(f); + } +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetSignalFreq(int fo, int fm, CRxSet *pRxSet) +{ + return GetSignalFreq(fo, fm, pRxSet, 600); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetSignalFreq(int fo, int fm, CRxSet *pRxSet, int th) +{ + if( pRxSet->IsMFSK() ){ + return fo; + } + else if( pRxSet->Is170() ){ + if( (pRxSet != &m_RxSet[0]) || pRxSet->m_fAFC ){ + fm = pRxSet->m_pDem->m_RTTYShift + 30; + } + else { + return fo; + } + } + int xl = (fo - fm) * FFT_SIZE / m_FFTSampFreq; + int xh = (fo + fm) * FFT_SIZE / m_FFTSampFreq; + int x; + + if( xl < 0 ){ + x = xl; + xl = 0; + xh -= x; + } + + if( xl >= xh ) return fo; + + int d; + int avg = 0; + int max = 0; + for(x = xl; x < xh; x++ ){ + d = m_fftout[x]; + avg += d; + if( max < d ) max = d; + } + avg /= (xh - xl); + int maxdb, avgdb; + if( m_FFT.m_FFTGain ){ + avgdb = SqrtToDB(avg); + maxdb = SqrtToDB(max); + } + else { + double k = 100.0 / m_fftSC; + avgdb = avg * k; + maxdb = max * k; + } + if( (maxdb - avgdb) >= th ){ + max = (max + (avg * 2)) / 3; + int fl = 0; + int fh = 0; + for(x = xl; x <= xh; x++ ){ + if( m_fftout[x] >= max ){ + if( !fl ) fl = x; + fh = x; + } + } + if( pRxSet->Is170() ){ + xl = (pRxSet->m_pDem->m_RTTYShift - 20) * FFT_SIZE/m_FFTSampFreq; + xh = (pRxSet->m_pDem->m_RTTYShift + 30) * FFT_SIZE/m_FFTSampFreq; + } + else { + xl = 0; + xh = (pRxSet->m_Speed + 10) * FFT_SIZE/m_FFTSampFreq; + } + max = ABS(fh-fl); + if( ((max >= xl) && (max <= xh)) ){ + x = (fl + fh) / 2; + fo = x * m_FFTSampFreq / FFT_SIZE; + } + } + return fo; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::LoadMacro(LPCSTR pName) +{ + AnsiString as; + GetFullPathName(as, pName); + TMemIniFile *pIniFile = new TMemIniFile(as.c_str()); + LoadMacro(pIniFile); + delete pIniFile; + CreateMacButton(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SaveMacro(LPCSTR pName) +{ + AnsiString as; + GetFullPathName(as, pName); + TMemIniFile *pIniFile = new TMemIniFile(as.c_str()); + SaveMacro(pIniFile); + pIniFile->UpdateFile(); + delete pIniFile; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::LoadMacro(TMemIniFile *pIniFile) +{ + char bf[64]; + AnsiString as, ws; + MACBUTTON *pList = m_tMacButton; + for( int i = 0; i < MACBUTTONALL; i++, pList++ ){ + sprintf(bf, "MB%u", i+1); + pList->Name = pIniFile->ReadString(bf, "Name", pList->Name); + CrLf2Yen(as, pList->Text); + ws = pIniFile->ReadString(bf, "Text", as); + Yen2CrLf(pList->Text, ws); + pList->Color = (TColor)pIniFile->ReadInteger(bf, "Color", pList->Color); + pList->Style = pIniFile->ReadInteger(bf, "Style", pList->Style); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SaveMacro(TMemIniFile *pIniFile) +{ + char bf[64]; + AnsiString as; + MACBUTTON *pList = m_tMacButton; + for( int i = 0; i < MACBUTTONALL; i++, pList++ ){ + sprintf(bf, "MB%u", i+1); + pIniFile->WriteString(bf, "Name", pList->Name); + CrLf2Yen(as, pList->Text); + pIniFile->WriteString(bf, "Text", as); + pIniFile->WriteInteger(bf, "Color", pList->Color); + pIniFile->WriteInteger(bf, "Style", pList->Style); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFMSClick(TObject *Sender) +{ + TSaveDialog *pBox = new TSaveDialog(this); + pBox->Options << ofOverwritePrompt; + pBox->Options << ofNoReadOnlyReturn; + if( sys.m_MsgEng ){ + pBox->Title = "Save Macros"; + pBox->Filter = "Macro Files(*.mac)|*.mac|"; + } + else { + pBox->Title = "マクロのセーブ"; + pBox->Filter = "マクロファイル(*.mac)|*.mac|"; + } + pBox->FileName = "Macros"; + pBox->DefaultExt = "mac"; + pBox->InitialDir = sys.m_BgnDir; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + OnWave(); + SaveMacro(AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + } + delete pBox; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KFMLClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Load Macros"; + pBox->Filter = "Macro Files(*.mac)|*.mac|"; + } + else { + pBox->Title = "マクロのロード"; + pBox->Filter = "マクロファイル(*.mac)|*.mac|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "mac"; + pBox->InitialDir = sys.m_BgnDir; + DettachFocus(); + OnWave(); + if( pBox->Execute() == TRUE ){ + OnWave(); + LoadMacro(AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + } + delete pBox; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupRXWPopup(TObject *Sender) +{ + int n = GetPopupIndex(PupRXW->PopupComponent); + TScrollBar *pBar; + CDump *pDump; + if( n ){ + pBar = m_RxSet[n].m_pView->SBar; + pDump = &m_RxSet[n].m_pView->m_Dump; + } + else { + pBar = SBarRX; + pDump = &m_Dump; + } + BOOL f; + KRWC->Enabled = (f=pDump->IsPrinted()); + KRWE->Enabled = f; + KRWT->Enabled = (f=pBar->Enabled); + KRWB->Enabled = f; + KRSC->Checked = sys.m_fShowCtrlCode; + OnMenuProc(PupRXW->Items, "PopRXW"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRWCClick(TObject *Sender) +{ + int n = GetPopupIndex(PupRXW->PopupComponent); + if( n ){ + m_RxSet[n].m_pView->m_Dump.Clear(); + } + else { + m_Dump.Clear(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRWTClick(TObject *Sender) +{ + int n = GetPopupIndex(PupRXW->PopupComponent); + TScrollBar *pBar; + if( n ){ + pBar = m_RxSet[n].m_pView->SBar; + } + else { + pBar = SBarRX; + } + if( pBar->Enabled ){ + pBar->Position = (Sender == KRWT) ? 0 : pBar->Max; + if( Sender == KRWB ) SetTXFocus(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRWEClick(TObject *Sender) +{ + int n = GetPopupIndex(PupRXW->PopupComponent); + CDump *pDump; + if( n ){ + pDump = &m_RxSet[n].m_pView->m_Dump; + } + else { + pDump = &m_Dump; + } + AnsiString as; + pDump->GetWindowText(as); + if( !m_pEdit ){ + m_pEdit = new TFileEdit(this); + m_pEdit->SetEvent(Handle, WM_WAVE, 2); + } + m_pEdit->Execute(as, "Received text", "Received.txt"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupSpecPopup(TObject *Sender) +{ + BOOL fs = m_fSubWindow && m_MouseSubChannel; + BOOL f = fs || m_MouseNotch; + KSAS->Visible = !f; + KSTX->Visible = !f; + KSRX->Visible = !f; + KSN->Visible = !f; + KSNR->Visible = !fs && m_MouseNotch && m_Notches.m_Count; + KSNRA->Visible = !fs && m_Notches.m_Count; + KSS->Visible = !f; + N21->Visible = !f; + N23->Visible = !f; + KSW->Visible = fs; + KSSR->Visible = fs; + KSSM->Visible = fs; + if( fs ){ + sprintf(m_TextBuff, sys.m_MsgEng ? "CH.%d <=swap=> main channel":"CH.%d <=入れ替え=> メインチャンネル", m_MouseSubChannel); + KSW->Caption = m_TextBuff; + sprintf(m_TextBuff, sys.m_MsgEng ? "CH.%d Close window":"CH.%d ウインドウを閉じる", m_MouseSubChannel); + KSSR->Caption = m_TextBuff; + sprintf(m_TextBuff, sys.m_MsgEng ? "CH.%d Set mode":"CH.%d モードを設定", m_MouseSubChannel); + KSSM->Caption = m_TextBuff; + + BOOL fNew = !KSSM->Count; + TRxViewDlg *pView = m_RxSet[m_MouseSubChannel].m_pView; + pView->PupModePopup(NULL); + TMenuItem *pMenu = pView->PupMode->Items; + int i; + for( i = 0; i < pMenu->Count; i++ ){ + TMenuItem *pm; + if( fNew ){ + pm = new TMenuItem(KSSM); + } + else { + pm = KSSM->Items[i]; + } + pm->GroupIndex = pMenu->Items[i]->GroupIndex; + pm->RadioItem = pMenu->Items[i]->RadioItem; + pm->Caption = pMenu->Items[i]->Caption; + pm->OnClick = pMenu->Items[i]->OnClick; + pm->Visible = pMenu->Items[i]->Visible; + pm->Checked = pMenu->Items[i]->Checked; + if( fNew ) KSSM->Add(pm); + } + } + for( int i = 1; i < RXMAX; i++ ){ + TMenuItem *pm = KSS->Items[i-1]; + pm->Checked = m_RxSet[i].IsActive(); + } + OnMenuProc(PupSpec->Items, "PopWATER"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSWClick(TObject *Sender) +{ + ::PostMessage(Handle, WM_WAVE, waveSwapRxView, DWORD(m_RxSet[m_MouseSubChannel].m_pView)); +} +//--------------------------------------------------------------------------- +int __fastcall TMainVARI::GetOverlayTop(void) +{ + int y = 0; + int i; + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++, pRxSet ){ + if( pRxSet->IsActive() ){ + if( pRxSet->m_pView->Top < 32 ){ + int yy = pRxSet->m_pView->Top + pRxSet->m_pView->Height; + if( y < yy ) y = yy; + } + } + } + return y; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetConvAlpha(BOOL f) +{ + m_fConvAlpha = f; + m_Edit[m_CurrentEdit].m_fConvAlpha = f; +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KVSDClick(TObject *Sender) +{ + m_ScaleDetails = m_ScaleDetails ? FALSE : TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KORSCClick(TObject *Sender) +{ + m_fRttyWordOut = (Sender == KORSW); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSNClick(TObject *Sender) +{ + m_Notches.Add(m_RightFreq); + m_NotchFreq = m_RightFreq; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSTXClick(TObject *Sender) +{ + if( m_TX || !SBNET->Down ){ + SetTxFreq(m_RightFreq); + } + else if( SBNET->Down ){ + SBNET->Down = FALSE; + SetTxFreq(m_RightFreq); + } + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSRXClick(TObject *Sender) +{ + m_RxSet[0].m_pDem->m_Decode.Reset(); + SetRxFreq(m_RightFreq); + m_RxSet[0].m_AFCTimerMFSK = MFSKAFC_MAX; + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSNRClick(TObject *Sender) +{ + if( m_MouseNotch ){ + m_Notches.Delete(m_MouseNotch-1); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSNRAClick(TObject *Sender) +{ + m_Notches.Delete(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSSRClick(TObject *Sender) +{ + ShowSubChannel(m_MouseSubChannel, 0); +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::IsFreqErr(double d) +{ + if( IsBPSK() ){ + return fabs(d) > 0.30; // 0.15 X 2.0 + } + else { + return fabs(d) > 0.20; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DrawPF(BOOL fPaint) +{ + if( !m_PFTimer ){ + TCanvas *pCanvas = m_pBitmapPF->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; rc.Right = m_pfXW; rc.Bottom = m_pfYW; + pCanvas->Brush->Color = clBlack; + pCanvas->Pen->Color = clBlack; + pCanvas->Pen->Style = psSolid; + pCanvas->FillRect(rc); + + if( m_Wave.IsInOpen() || m_Wave.IsOutOpen() ){ + rc.Top ++; + rc.Bottom--; + BOOL fTX = (m_TX == txINTERNAL); + CRxSet *pRxSet = m_RxSet; + CDEMFSK *pDem = pRxSet->m_pDem; + double d = pDem->GetFreqErr(); + if( IsBPSK() ){ + if( m_AFCWidth && !fTX ){ + double f = double(pRxSet->m_AFCFQ - UdRxCarrier->Position)/pRxSet->GetBandWidth(); + if( fabs(f) >= 0.2 ) d = f; + } + d *= 2.0; + } + if( fTX ) d *= 0.05; + if( d > 0.0 ){ + rc.Left = m_pfXC + (d * m_pfXW); + rc.Right = m_pfXC; + } + else { + rc.Left = m_pfXC; + rc.Right = m_pfXC + (d * m_pfXW); + } + if( SBAFC->Down || fTX ){ + pCanvas->Brush->Color = TColor(RGB(144,144,144)); + } + else { + pCanvas->Brush->Color = IsFreqErr(d) ? clRed : clYellow; + } + pCanvas->FillRect(rc); + } + pCanvas->Pen->Color = SBAFC->Down ? TColor(RGB(0,255,0)) : clWhite; + pCanvas->MoveTo(m_pfXC, 0); + pCanvas->LineTo(m_pfXC, m_pfYW); + if( fPaint ) PBoxPFPaint(NULL); + } + else { + m_PFTimer--; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PBoxPFPaint(TObject *Sender) +{ + PBoxPF->Canvas->Draw(0, 0, m_pBitmapPF); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutYaesuVU(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + int hz1 = hz / 10000000; + hz = hz % 10000000; + int hz2 = hz / 100000; + hz = hz % 100000; + int hz3 = hz / 1000; + hz = hz % 1000; + sprintf(bf, "\\$%02u%02u%02u%02u01", hz1, hz2, hz3, hz/10); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutYaesuHF(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + int hz1 = hz / 10000000; + hz = hz % 10000000; + int hz2 = hz / 100000; + hz = hz % 100000; + int hz3 = hz / 1000; + hz = hz % 1000; + sprintf(bf, "\\$%02u%02u%02u%02u0A", hz/10, hz3, hz2, hz1); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutCIV(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + int hz1 = hz / 100000000; + hz = hz % 100000000; + int hz2 = hz / 1000000; + hz = hz % 1000000; + int hz3 = hz / 10000; + hz = hz % 10000; + int hz4 = hz / 100; + hz = hz % 100; + sprintf(bf, "\\$FEFExxE005%02u%02u%02u%02u%02uFD", hz, hz4, hz3, hz2, hz1); + WaitICOM(); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutCIV4(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + if( hz >= 100000000 ){ // 100MHz and up + int hz1 = hz / 100000000; + hz = hz % 100000000; + int hz2 = hz / 1000000; + hz = hz % 1000000; + int hz3 = hz / 10000; + hz = hz % 10000; + int hz4 = hz / 100; + hz = hz % 100; + sprintf(bf, "\\$FEFExxE005%02u%02u%02u%02u%02uFD", hz, hz4, hz3, hz2, hz1); + } + else { + int hz1 = hz / 1000000; + hz = hz % 1000000; + int hz2 = hz / 10000; + hz = hz % 10000; + int hz3 = hz / 100; + hz = hz % 100; + sprintf(bf, "\\$FEFExxE005%02u%02u%02u%02uFD", hz, hz3, hz2, hz1); + } + WaitICOM(); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutKENWOOD(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + sprintf(bf, "FA0%010lu;", hz); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutJST245(int hz) +{ + if( !m_pRadio ) return; + + char bf[256]; + sprintf(bf, "H1\\rF%08luA\\rH0\\rI1\\r", hz); + m_pRadio->SendCommand(bf); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutModeYaesuHF(LPCSTR pMode) +{ + if( !m_pRadio ) return; + + const BYTE _td[]={ + 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0a, + }; + int n = FindStringTable(g_tRadioMode, pMode, AN(_td)); + if( n >= 0 ){ + char bf[256]; + sprintf(bf, "\\$000000%02X0C", _td[n]); + m_pRadio->SendCommand(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutModeYaesuVU(LPCSTR pMode) +{ + if( !m_pRadio ) return; + + const BYTE _td[]={ + 0x00, 0x01, 0x82, 0x04, 0x08, + }; + int n = FindStringTable(g_tRadioMode, pMode, AN(_td)); + if( n >= 0 ){ + char bf[256]; + sprintf(bf, "\\$%02X00000007", _td[n]); + m_pRadio->SendCommand(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutModeCIV(LPCSTR pMode) +{ + if( !m_pRadio ) return; + + const BYTE _td[]={ + 0x00, 0x01, 0x03, 0x02, 0x05, 0x04, + }; + int n = FindStringTable(g_tRadioMode, pMode, AN(_td)); + if( n >= 0 ){ + char bf[256]; + sprintf(bf, "\\$FEFExxE006%02XFD", _td[n]); + WaitICOM(); + m_pRadio->SendCommand(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutModeKENWOOD(LPCSTR pMode) +{ + if( !m_pRadio ) return; + + const BYTE _td[]={ + 1, 2, 3, 5, 4, 6, + }; + int n = FindStringTable(g_tRadioMode, pMode, AN(_td)); + if( n >= 0 ){ + char bf[256]; + sprintf(bf, "MD%d;", int(_td[n])); + m_pRadio->SendCommand(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OutModeJST245(LPCSTR pMode) +{ + if( !m_pRadio ) return; + + const BYTE _td[]={ + 3, 2, 1, 4, 5, 0, + }; + int n = FindStringTable(g_tRadioMode, pMode, AN(_td)); + if( n >= 0 ){ + char bf[256]; + sprintf(bf, "H1\rD%d\rH0\rI1\r", int(_td[n])); + m_pRadio->SendCommand(bf); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::WaitICOM(void) +{ + if( m_pRadio && m_pRadioTimer ){ + m_pRadio->WaitICOM(m_pRadioTimer->Interval); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVMXClick(TObject *Sender) +{ + if( KVMX->Checked ){ + DeleteMacExButton(); + } + else { + CreateMacExButton(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DeleteMacExButton(void) +{ + KVMX->Checked = FALSE; + if( PBoxFFT->Align != alClient ){ + PBoxFFT->Align = alClient; + m_fftYW = PBoxFFT->Height; + m_pBitmapFFT->Canvas->Brush->Color = m_tWaterColset[0].c; + m_pBitmapFFT->Height = m_fftYW; + } + MACBUTTON *pList = &m_tMacButton[MACBUTTONMAX]; + for( int i = 0; i < MACEXBUTTONMAX; i++, pList++ ){ + TSpeedButton *pButton = pList->pButton; + if( pButton ){ + PFFT->RemoveControl(pList->pButton); + delete pList->pButton; + pList->pButton = NULL; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CreateMacExButton(void) +{ + KVMX->Checked = TRUE; + MACBUTTON *pList = &m_tMacButton[MACBUTTONMAX]; + if( PBoxFFT->Align == alClient ){ + PBoxFFT->Align = alTop; + PBoxFFT->Height = PFFT->Height - 24; + m_fftYW = PBoxFFT->Height; + m_pBitmapFFT->Height = m_fftYW; + } + int x = PBoxFFT->Left; + int max = (PBoxFFT->Width / 60); + if( max > MACEXBUTTONMAX ) max = MACEXBUTTONMAX; + int xw = PBoxFFT->Width / max; + int xx = PBoxFFT->Width % max; + int y = PBoxFFT->Top + PBoxFFT->Height+2; + int yw = 16; + int i; + for( i = 0; i < max; i++, pList++ ){ + TSpeedButton *pButton = pList->pButton; + if( !pButton ){ + pButton = new TSpeedButton(PFFT); + PFFT->InsertControl(pButton); + pButton->Parent = PFFT; + pButton->OnClick = OnMacButtonClick; + pButton->OnMouseDown = OnMacButtonDown; + pButton->GroupIndex = 1; + pButton->AllowAllUp = TRUE; + char bf[16]; + sprintf(bf, "%%M%u", i+MACBUTTONMAX); + pButton->Hint = bf; + pButton->Down = (i == m_CurrentMacro) && (m_ReqMacroTimer || m_pMacroTimer); + pList->pButton = pButton; + } + else { + pButton->Font->Name = sys.m_FontName; + pButton->Font->Charset = sys.m_FontCharset; + } + pButton->Caption = ConvAndChar(m_TextBuff, pList->Name.c_str()); + int xxw = xw; + if( xx ){ + xxw++; + xx--; + } + pButton->SetBounds(x, y, xxw, yw); + pButton->Font->Height = -(yw-4); + pButton->Font->Color = pList->Text.IsEmpty() ? clGrayText : pList->Color; + TFontStyles fs = Code2FontStyle(pList->Style); + pButton->Font->Style = fs; + x += xxw; + } + for( ; i < MACEXBUTTONMAX; i++, pList++ ){ + TSpeedButton *pButton = pList->pButton; + if( pButton ){ + PFFT->RemoveControl(pList->pButton); + delete pList->pButton; + pList->pButton = NULL; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoMacroMenu(LPCSTR pVal, TSpeedButton *pButton, BOOL fRadio) +{ + DettachFocus(); + AnsiString as; + LPSTR pBF = new char[8192]; + StrCopy(pBF, GetMacroStr(as, pVal), 8191); + LPSTR t, p; + p = pBF; + if( m_pMacroPopup ){ + delete m_pMacroPopup; + } + m_pMacroPopup = new TPopupMenu(this); + int nInit = -1; + if( fRadio ){ + p = StrDlm(t, SkipSpace(p)); + nInit = GetMacroInt(t); + } + strcpy(p, GetMacroStr(as, p)); + int n = 0; + BYTE gIndex = 1; + while(*p){ + p = StrDlm(t, SkipSpace(p)); + if( *t ){ + TMenuItem *pMenu = new TMenuItem(m_pMacroPopup); + pVal = GetMacroStr(as, t); + pMenu->Caption = pVal; + if( strcmp(pVal, "-") ){ + pMenu->OnClick = OnMacroMenuClick; + if( fRadio ){ + n++; + pMenu->GroupIndex = gIndex; + pMenu->RadioItem = TRUE; + pMenu->Checked = (n == nInit); + } + } + else { + gIndex++; + if( fRadio ){ + p = StrDlm(t, SkipSpace(p)); + nInit = GetMacroInt(t); + n = 0; + } + } + m_pMacroPopup->Items->Add(pMenu); + } + } + delete pBF; + BOOL fButton = pButton && pButton->Down; + if( fButton ) pButton->Down = FALSE; + RECT rc; + HWND hWnd; + if( fButton ){ + hWnd = GetMacButtonNo(pButton) >= MACBUTTONMAX ? PFFT->Handle : PCMac->Handle; + } + else { + hWnd = PCTX->Handle; + } + ::GetWindowRect(hWnd, &rc); + int X, Y; + if( fButton ){ + rc.left += pButton->Left + pButton->Width/2; + rc.top += pButton->Top + pButton->Height/2; + } + else { + m_Edit[m_CurrentEdit].GetCursorPos(X, Y); + rc.left += X; rc.top += Y+8; + } + m_MacroInput = ""; + m_MacroMenuNo = 0; + m_pMacroPopup->Popup(rc.left, rc.top); + Application->ProcessMessages(); + delete m_pMacroPopup; + m_pMacroPopup = NULL; + AttachFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SBP60Click(TObject *Sender) +{ + TSpeedButton *pButton = (TSpeedButton *)Sender; + + int s = m_PlayBackTime[0]; + if( Sender == SBP30 ){ + s = m_PlayBackTime[1]; + } + else if( Sender == SBP15 ){ + s = m_PlayBackTime[2]; + } + DoPlayBack(pButton->Down ? s : 0); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdatePlayBack(void) +{ + SBP15->Caption = m_PlayBackTime[2]; + SBP30->Caption = m_PlayBackTime[1]; + SBP60->Caption = m_PlayBackTime[0]; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoPlayBack(int s) +{ + if( !m_PlayBack.IsActive() || !SBP60->Enabled ) return; + + if( s ){ + if( !m_PlayBack.StartPlaying(s) ){ + StopPlayBack(); + } + else { + DrawWater(FALSE, TRUE); + if( s <= m_PlayBackTime[2] ){ + SBP15->Down = TRUE; + if( m_PlayBackTime[2] != s ) SBP15->Caption = s; + } + else if( s <= m_PlayBackTime[1] ){ + SBP30->Down = TRUE; + if( m_PlayBackTime[1] != s ) SBP30->Caption = s; + } + else { + SBP60->Down = TRUE; + if( m_PlayBackTime[0] != s ) SBP60->Caption = s; + } + } + } + else { + m_PlayBack.StopPlaying(); + UpdatePlayBack(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::StopPlayBack(void) +{ + if( m_PlayBack.IsActive() ){ + m_PlayBack.StopPlaying(); + SBP60->Down = FALSE; + SBP30->Down = FALSE; + SBP15->Down = FALSE; + UpdatePlayBack(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateShowCtrl(void) +{ + int i; + CRxSet *pRxSet = &m_RxSet[1]; + for( i = 1; i < RXMAX; i++ ){ + if( pRxSet->m_pView ){ + pRxSet->m_pView->m_Dump.ShowCtrl(sys.m_fShowCtrlCode); + } + } + m_Dump.ShowCtrl(sys.m_fShowCtrlCode); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRSCClick(TObject *Sender) +{ + sys.m_fShowCtrlCode = !sys.m_fShowCtrlCode; + UpdateShowCtrl(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupSQPopup(TObject *Sender) +{ + int n = GetPopupIndex(PupSQ->PopupComponent); + n = m_RxSet[n].m_SQLevel; + switch(n){ + case 100: + KS1->Checked = TRUE; + break; + case 200: + KS2->Checked = TRUE; + break; + case 300: + KS3->Checked = TRUE; + break; + case 400: + KS4->Checked = TRUE; + break; + default: + if( n < 50 ){ + KS0->Checked = TRUE; + } + else { + KS0->Checked = FALSE; + KS1->Checked = FALSE; + KS2->Checked = FALSE; + KS3->Checked = FALSE; + KS4->Checked = FALSE; + } + break; + } + OnMenuProc(PupSQ->Items, "PopSQ"); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KS0Click(TObject *Sender) +{ + int sq = 0; + if( Sender == KS1 ){ + sq = 100; + } + else if( Sender == KS2 ){ + sq = 200; + } + else if( Sender == KS3 ){ + sq = 300; + } + else if( Sender == KS4 ){ + sq = 400; + } + int n = GetPopupIndex(PupSQ->PopupComponent); + m_RxSet[n].m_SQLevel = sq; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KHJClick(TObject *Sender) +{ + AnsiString as = ((TMenuItem *)Sender)->Hint; + m_WebRef.ShowHTML(as.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoEvent(int n) +{ + if( !sys.m_MacEvent[n].IsEmpty() ) DoMacro(sys.m_MacEvent[n].c_str(), NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::MacroOnTimer(TObject *Sender) +{ + AnsiString as = sys.m_MacEvent[macOnTimer].c_str(); + if( !sys.m_MacroError ){ + DoMacro(as.c_str(), NULL); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateMacroOnTimer(void) +{ + if( sys.m_MacEvent[macOnTimer].IsEmpty() ){ + if( m_pMacroOnTimer ){ + delete m_pMacroOnTimer; + m_pMacroOnTimer = NULL; + } + } + else { + if( !m_pMacroOnTimer ){ + m_pMacroOnTimer = new TTimer(this); + m_pMacroOnTimer->Interval = sys.m_OnTimerInterval; + m_pMacroOnTimer->OnTimer = MacroOnTimer; + m_pMacroOnTimer->Enabled = TRUE; + } + } + sys.m_MacroError = FALSE; +} +//--------------------------------------------------------------------------- +// システムシャットダウン +void __fastcall TMainVARI::ShutDown(void) +{ + + DoSuspend(FALSE); + WriteRegister(); + + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + int WinNT = FALSE; + // アクセストークンをオープン + if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)){ + WinNT = TRUE; + + // 特権名のLUIDを取得する + LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); + + tkp.PrivilegeCount = 1; /* one privilege to set */ + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // アクセストークンの特権を得る + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); + } + ::ExitWindowsEx(sys.m_WinNT ? EWX_POWEROFF : EWX_SHUTDOWN, 0); + Close(); + if( WinNT == TRUE ){ + // アクセストークンの特権を放棄する + tkp.Privileges[0].Attributes = 0; + AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::UpdateModGain(void) +{ + m_ModGainR = m_ModGain; + if( m_ModGainR < 1024 ) m_ModGainR = 1024; + if( m_ModGainR > 31774 ) m_ModGainR = 31774; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoBench(LPSTR t, int type) +{ + CWaitCursor w; + if( m_CPUBENCHType != type ){ + m_CPUBENCHType = type; + m_CPUBENCH.Create(32); + } + LARGE_INTEGER ltFreq, ltOld; + if( ::QueryPerformanceFrequency(<Freq) && ::QueryPerformanceCounter(<Old) ){ + int i; + double d; + if( type ){ + CDECM2 dec; + CVCO vco; + vco.SetSampleFreq(SAMPFREQ); + vco.SetFreeFreq(1000.0); + dec.SetSampleFreq(m_fDec, SAMPFREQ); + for( i = 0; i < 65536; i++ ){ + dec.Do(vco.Do()); + } + } + else { + for( i = 0; i < 23400; i++ ){ + d = double(rand() % int(2 * PI * 1000)) / 1000.0; + sin(d*d); + } + } + LARGE_INTEGER ltNow; + ::QueryPerformanceCounter(<Now); + d = double(ltNow.QuadPart - ltOld.QuadPart)/double(ltFreq.QuadPart); + d = m_CPUBENCH.Do(d); + sprintf(t, "%.1lf", d * 1.0e6); + } +} +//--------------------------------------------------------------------------- +// インデックスからメニューを得る +TMenuItem* __fastcall TMainVARI::GetMenuItem(TMenuItem *pMainMenu, LPCSTR pTitle) +{ + int index; + if( IsNumbAll(pTitle) && ((index = GetMacroInt(pTitle)) <= pMainMenu->Count) && (index >= 1) ){ + int n = 1; + TMenuItem *pMenu; + for( int i = 0; i < pMainMenu->Count; i++ ){ + pMenu = pMainMenu->Items[i]; + if( pMenu->Visible && (pMenu->Caption != '-') ){ + if( n == index ) return pMenu; + n++; + } + } + } + return NULL; +} +//--------------------------------------------------------------------------- +TMenuItem* __fastcall TMainVARI::FindMenu(TMenuItem *pMainMenu, LPCSTR pTitle) +{ + AnsiString as; + int i; + BOOL fAcc = (*pTitle == '&') && (strlen(pTitle)==2); + TMenuItem *pMenu; + if( (pMenu = GetMenuItem(pMainMenu, pTitle)) != NULL ){ + return pMenu; + } + else { + for( i = pMainMenu->Count - 1; i >= 0; i-- ){ + pMenu = pMainMenu->Items[i]; + as = pMenu->Caption; + if( !strcmp(as.c_str(), pTitle) ){ + return pMenu; + } + else if( fAcc ){ + for( LPCSTR p = as.c_str(); *p; p++ ){ + if( *p == '&' ){ + if( *(p+1) == '&' ){ + p++; + } + else if( !strncmpi(p, pTitle, 2) ){ + return pMenu; + } + } + } + } + } + } + return NULL; +} +//--------------------------------------------------------------------------- +TMenuItem* __fastcall TMainVARI::GetMainMenu(LPCSTR pTitle, BOOL fNew) +{ + TMenuItem *pMenu = GetSubMenu(pTitle); + if( pMenu ) return pMenu; + + TMenuItem *pMainMenu = MainMenu->Items; + pMenu = FindMenu(pMainMenu, pTitle); + if( !pMenu ){ + if( fNew ){ + pMenu = new TMenuItem(pMainMenu); + pMenu->Caption = pTitle; + pMenu->OnClick = OnXmClick; + pMainMenu->Insert(pMainMenu->IndexOf(KH), pMenu); + } + else { + pMenu = NULL; + } + } + return pMenu; +} +//--------------------------------------------------------------------------- +TMenuItem* __fastcall TMainVARI::GetSubMenu(LPCSTR pTitle) +{ + if( !strcmp(pTitle, "PopWATER") ){ + return PupSpec->Items; + } + else if( !strcmp(pTitle, "PopPAGE") ){ + return PupPage->Items; + } + else if( !strcmp(pTitle, "PopRX") ){ + return PupRX->Items; + } + else if( !strcmp(pTitle, "PopRXW") ){ + return PupRXW->Items; + } + else if( !strcmp(pTitle, "PopSQ") ){ + return PupSQ->Items; + } + else if( !strcmp(pTitle, "PopTX") ){ + return PupTX->Items; + } + else if( !strcmp(pTitle, "PopCHARSET") ){ + return PupCharset->Items; + } + else if( !strcmp(pTitle, "PopCALLS") ){ + return PupCalls->Items; + } + return NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnXmClick(TObject *Sender) +{ + if( !m_MacroVal.IsHandleProc() ) return; + + TMenuItem *pMenu = (TMenuItem *)Sender; + AnsiString as = pMenu->Caption; + OnMenuProc(pMenu, as.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::AddExtensionMenu(LPCSTR pTitle, LPCSTR pCaption, LPCSTR pHint) +{ + TMenuItem *pMainMenu = GetMainMenu(pTitle, TRUE); + if( !*pCaption ) return; + + AnsiString as; + TMenuItem *pMenu = NULL; + if( strcmp(pCaption, "-") ){ + if( !*pHint ) return; + pMenu = FindMenu(pMainMenu, pCaption); + } + else if( pMainMenu->Count ){ + as = pMainMenu->Items[pMainMenu->Count - 1]->Caption; + if( !strcmp(as.c_str(), "-") ) return; + } + BOOL fAdd = FALSE; + if( !pMenu ){ + pMenu = new TMenuItem(pMainMenu); + pMenu->Caption = pCaption; + fAdd = TRUE; + } + else if( pMenu->Count ){ + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + as = pMenu->Caption; + InfoMB("[%s] is not overrode...", as.c_str()); + } + return; + } + pMenu->Hint = pHint; + pMenu->OnClick = OnXClick; + if( fAdd ){ + pMainMenu->Add(pMenu); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::InsExtensionMenu(LPCSTR pTitle, LPCSTR pPos, LPCSTR pCaption, LPCSTR pHint) +{ + TMenuItem *pMainMenu = GetMainMenu(pTitle, TRUE); + TMenuItem *pPosMenu = FindMenu(pMainMenu, pPos); + if( !pPosMenu ) return; + + BOOL fIns = FALSE; + TMenuItem *pMenu = NULL; + if( strcmp(pCaption, "-") ){ + pMenu = FindMenu(pMainMenu, pCaption); + } + if( !pMenu ){ + pMenu = new TMenuItem(pMainMenu); + pMenu->Caption = pCaption; + fIns = TRUE; + } + else if( pMenu->Count ){ + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + AnsiString as = pMenu->Caption; + InfoMB("[%s] is not overrode...", as.c_str()); + } + return; + } + pMenu->Hint = pHint; + pMenu->OnClick = OnXClick; + if( fIns ){ + pMainMenu->Insert(pMainMenu->IndexOf(pPosMenu), pMenu); + } +} +//--------------------------------------------------------------------------- +static void __fastcall DeleteShortCut(TMenuItem *pMain, TShortCut sKey) +{ + for( int i = 0; i < pMain->Count; i++ ){ + TMenuItem *pMenu = pMain->Items[i]; + if( pMenu->ShortCut == sKey ){ + pMenu->ShortCut = 0; + } + if( pMenu->Count ){ + DeleteShortCut(pMenu, sKey); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ShortCutExtensionMenu(TMenuItem *pMenu, LPCSTR pKey) +{ + if( pMenu ){ + AnsiString as; + GetMacroStr(as, pKey); + TShortCut sKey = 0; + if( strcmpi(as.c_str(), "NONE") ){ + sKey = TextToShortCut(as); + } + if( sKey ){ + DeleteShortCut(MainMenu->Items, sKey); + DeleteShortCut(PupTX->Items, sKey); + } + pMenu->ShortCut = sKey; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::IsXMenu(TMenuItem *pItem) +{ + if( !pItem ) return FALSE; + + TMenuItem *pMainMenu = MainMenu->Items; + for( int i = 0; i < pMainMenu->Count; i++ ){ + if( pMainMenu->Items[i]->IndexOf(pItem) >= 0 ) return TRUE; + } + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::OnXClick(TObject *Sender) +{ + TMenuItem *pMenu = (TMenuItem *)Sender; + AnsiString ps = pMenu->Hint.c_str(); + LPSTR tt, pp; + pp = StrDlm(tt, ps.c_str()); + if( !OnMenuProc(pMenu, tt, pp, TRUE) ){ + if( MainMenu->Items->IndexOf(pMenu) < 0 ){ + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + InfoMB("Procedure [%s] is not found...", tt); + } + } + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall TMainVARI::OnMenuProc(TMenuItem *pMenu, LPCSTR pProc, LPCSTR pPara, BOOL fStop) +{ + int r = m_MacroVal.FindName(pProc, _VAL_PROC); + if( r >= 0 ){ + if( fStop ){ + sys.m_MacroError = FALSE; + DeleteMacroTimer(); + m_pCurrentMacroMenu = pMenu; + m_CurrentMacro = -1; + } + m_MacroInput = pMenu->Caption; + AnsiString as; + ConvDummy(as, m_MacroVal.GetString(r), m_MacroVal.GetPara(r), pPara); + DoMacro(as.c_str(), NULL); + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +// メニューの更新ハンドラ +void __fastcall TMainVARI::OnMenuProc(TMenuItem *pMenu, LPCSTR pCaption) +{ + if( !m_MacroVal.IsHandleProc() ) return; + + m_ParentMenu = pMenu; + char bf[256]; + sprintf(bf, "On$%sClick", pCaption); + OnMenuProc(pMenu, bf, "", FALSE); + m_ParentMenu = NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::DoParentClick(TMenuItem *pMenu) +{ + TMenuItem *pMainMenu = pMenu->Parent; + if( pMainMenu ){ + DoParentClick(pMainMenu); + if( (pMainMenu != m_ParentMenu) && pMainMenu->OnClick ) pMainMenu->Click(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KHClick(TObject *Sender) +{ + OnMenuProc(KH, "&Help"); +} +//--------------------------------------------------------------------------- +TMenuItem* __fastcall TMainVARI::GetMenuArg(AnsiString &arg, LPCSTR pVal, BOOL fArg) +{ + BOOL f = !fArg; + AnsiString as; + LPSTR pBF = StrDupe(GetMacroStr(as, pVal)); + LPSTR tt, p; + p = StrDlm(tt, pBF); + TMenuItem *pMenu = FindMenu(MainMenu->Items, GetMacroStr(as, tt)); + while( *p && pMenu ){ + p = StrDlm(tt, SkipSpace(p)); + tt = SkipSpace(tt); + if( *p || (!fArg) ){ + if( *tt ){ + pMenu = FindMenu(pMenu, GetMacroStr(as, tt)); + } + } + else { + arg = tt; + f = TRUE; + } + } + delete pBF; + return f ? pMenu : NULL; +} +//--------------------------------------------------------------------------- +TSpeedButton* __fastcall TMainVARI::FindButton(TComponent *pMainControl, LPCSTR pCaption, TSpeedButton *pButton, BOOL fErrMsg) +{ + const LPCSTR _bt[]={"BPF1","BPF2","BPF3","BPF4"}; + int i = FindStringTable(_bt, pCaption, AN(_bt)); + if( i >= 0 ){ + TSpeedButton *_tt[]={SBBPFW, SBBPFM, SBBPFN, SBBPFS}; + return _tt[i]; + } + + TComponent *pComponent; + TControl *pControl; + for( i = 0; i < pMainControl->ComponentCount; i++ ){ + pComponent = pMainControl->Components[i]; + pControl = (TControl *)pComponent; + if( pControl && (pButton != pControl) ){ + if( pControl->ClassNameIs("TSpeedButton") ){ + TSpeedButton *pButton = (TSpeedButton *)pControl; + AnsiString as = pButton->Caption; + if( !strcmp(as.c_str(), pCaption) ){ + return pButton; + } + } + else if( pControl->ComponentCount ){ + pControl = FindButton(pControl, pCaption, pButton, FALSE); + if( pControl ) return (TSpeedButton *)pControl; + } + } + } + if( fErrMsg ){ + if( !sys.m_MacroError ){ + sys.m_MacroError = TRUE; + InfoMB("Button [%s] is not found...", pCaption); + } + } + return NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::ClickButton(TSpeedButton *pButton) +{ + if( !pButton ) return; + + if( pButton->Visible && pButton->Enabled ){ + pButton->Down = !pButton->Down; + pButton->Click(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::SetRTTYFFT(int f) +{ + m_RxSet[0].m_RTTYFFT = f; + m_RxSet[0].m_pDem->m_fRTTYFFT = f; +#if 0 + int i; + for( i = 1; i < RXMAX; i++ ){ + if( m_RxSet[i].m_pDem ){ + m_RxSet[i].m_pDem->m_fRTTYFFT = f; + } + } +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::CreateSubMenu(void) +{ + char bf[256]; + TMenuItem *pm; + for( int i = 1; i < RXMAX; i++ ){ + sprintf(bf, sys.m_MsgEng ? "CH &%d" : "チャンネル &%d", i); + if( (i - 1) >= KVS->Count ){ + pm = new TMenuItem(this); + KVS->Add(pm); + } + pm = KVS->Items[i-1]; + pm->OnClick = KVSClick; + pm->Caption = bf; + pm->Checked = m_RxSet[i].IsActive(); + + if( (i - 1) >= KSS->Count ){ + pm = new TMenuItem(this); + KSS->Add(pm); + } + pm = KSS->Items[i-1]; + pm->OnClick = KSSClick; + pm->Caption = bf; + pm->Checked = m_RxSet[i].IsActive(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KVSClick(TObject *Sender) +{ + int RN = KVS->IndexOf((TMenuItem *)Sender); + if( RN >= 0 ){ + RN++; + ShowSubChannel(RN, 2); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KSSClick(TObject *Sender) +{ + int RN = KSS->IndexOf((TMenuItem *)Sender); + if( RN >= 0 ){ + RN++; + ShowSubChannel(RN, 1); + + CRxSet *pRxSet = &m_RxSet[RN]; + double fq = GetSignalFreq(m_RightFreq, SBFFT3K->Down ? 50 : 32, pRxSet); + pRxSet->m_pDem->m_Decode.Reset(); + pRxSet->SetCarrierFreq(fq); + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::AdjustRadioMenu(void) +{ + int max = KR->IndexOf(NR); + TMenuItem *pm; + int i; + for( i = 0; i < m_nRadioMenu; i++ ){ + if( i >= max ){ + TMenuItem *pm = new TMenuItem(this); + KR->Insert(i, pm); + max++; + } + pm = KR->Items[i]; + if( pm->Caption != m_RadioMenu[i].strTTL ){ + pm->Caption = m_RadioMenu[i].strTTL; + } + pm->OnClick = KRadioCmdClick; + pm->Enabled = m_pRadio != NULL; + } + int N = i; + for( ; i < max; i++ ){ + KR->Delete(N); + } + + max = KRM->IndexOf(NRE); + for( i = 0; i < m_nRadioMenu; i++ ){ + if( i >= max ){ + TMenuItem *pm = new TMenuItem (this); + KRM->Insert(i, pm); + max++; + } + pm = KRM->Items[i]; + if( pm->Caption != m_RadioMenu[i].strTTL ){ + pm->Caption = m_RadioMenu[i].strTTL; + } + pm->OnClick = KRadioEditClick; + } + N = i; + for( ; i < max; i++ ){ + KRM->Delete(N); + } + BOOL f = m_nRadioMenu != 0; + NR->Visible = f; + NRE->Visible = f; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRadioCmdClick(TObject *Sender) +{ + if( !m_pRadio ) return; + + int n = KR->IndexOf((TMenuItem *)Sender); + if( (n >= 0) && (n < RADIOMENUMAX) ){ + LPCSTR p = m_RadioMenu[n].strCMD.c_str(); + if( CheckEXT(p, "RCM") && IsFile(p) ){ + LoadRadioDef(p); + } + else { + m_pRadio->SendCommand(p); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRadioEditClick(TObject *Sender) +{ + int n = KRM->IndexOf((TMenuItem *)Sender); + if( (n >= 0) && (n < RADIOMENUMAX) ){ + AnsiString strTTL = m_RadioMenu[n].strTTL; + AnsiString strCMD = m_RadioMenu[n].strCMD; + + TRMenuDialog *pBox = new TRMenuDialog(this); + int r = pBox->Execute(strTTL, strCMD); + BOOL fNull = strTTL.IsEmpty() && strCMD.IsEmpty(); + if( (r == IDOK) && !fNull ){ + if( !strCMD.IsEmpty() ){ + if( strTTL.IsEmpty() ){ + char bf[64]; + sprintf(bf, "Radio command #d", n + 1); + strTTL = bf; + } + m_RadioMenu[n].strTTL = strTTL; + m_RadioMenu[n].strCMD = strCMD; + AdjustRadioMenu(); + } + } + else if( (r == 1024) || fNull ){ + for( int i = n; i < (m_nRadioMenu - 1); i++ ){ + m_RadioMenu[i].strTTL = m_RadioMenu[i+1].strTTL; + m_RadioMenu[i].strCMD = m_RadioMenu[i+1].strCMD; + } + m_nRadioMenu--; + AdjustRadioMenu(); + } + else if( r == 1025 ){ + if( m_nRadioMenu < RADIOMENUMAX ){ + for( int i = m_nRadioMenu; i > n; i-- ){ + m_RadioMenu[i].strTTL = m_RadioMenu[i-1].strTTL; + m_RadioMenu[i].strCMD = m_RadioMenu[i-1].strCMD; + } + m_RadioMenu[n].strTTL = strTTL; + m_RadioMenu[n].strCMD = strCMD; + m_nRadioMenu++; + AdjustRadioMenu(); + } + } + delete pBox; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRClick(TObject *Sender) +{ + AdjustRadioMenu(); + KRADD->Enabled = m_nRadioMenu < RADIOMENUMAX; + OnMenuProc(KR, "Radio&Command"); +} +//--------------------------------------------------------------------------- + +void __fastcall TMainVARI::KRADDClick(TObject *Sender) +{ + if( m_nRadioMenu >= RADIOMENUMAX ) return; + + AnsiString strTTL, strCMD; + + TRMenuDialog *pBox = new TRMenuDialog(this); + if( pBox->Execute(strTTL, strCMD, TRUE) ){ + if( !strCMD.IsEmpty() ){ + if( strTTL.IsEmpty() ){ + char bf[64]; + sprintf(bf, "Radio command #d", m_nRadioMenu + 1); + strTTL = bf; + } + m_RadioMenu[m_nRadioMenu].strTTL = strTTL; + m_RadioMenu[m_nRadioMenu].strCMD = strCMD; + m_nRadioMenu++; + AdjustRadioMenu(); + } + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::LoadRadioDef(LPCSTR pName) +{ + try { + CWaitCursor w; + TMemIniFile *pIniFile = new TMemIniFile(pName); + RADIO.CmdInit = pIniFile->ReadString("RADIO", "CmdInit", RADIO.CmdInit); + RADIO.CmdRx = pIniFile->ReadString("RADIO", "CmdRx", RADIO.CmdRx); + RADIO.CmdTx = pIniFile->ReadString("RADIO", "CmdTx", RADIO.CmdTx); + char bf[32]; + sprintf( bf, "%02X", RADIO.Cmdxx); + AnsiString as = pIniFile->ReadString("RADIO", "Cmdxx", bf); + int d; + sscanf(as.c_str(), "%X", &d); + RADIO.Cmdxx = d; + RADIO.PollType = pIniFile->ReadInteger("RADIO", "PollType", 0); + RADIO.PollInterval = pIniFile->ReadInteger("RADIO", "PollInterval", 0); + delete pIniFile; + OpenRadio(); + } + catch(...){ + } +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KRLClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Open command file"; + pBox->Filter = "Command files(*.rcm)|*.rcm|"; + } + else { + pBox->Title = "コマンド定義ファイルを開く"; + pBox->Filter = "コマンド定義ファイル(*.rcm)|*.rcm|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "rcm"; + pBox->InitialDir = sys.m_BgnDir; + if( pBox->Execute() == TRUE ){ + LoadRadioDef(AnsiString(pBox->FileName).c_str()); //JA7UDE 0428 + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::KROClick(TObject *Sender) +{ + TRADIOSetDlg *pBox = new TRADIOSetDlg(this); + + if( (sys.m_PTTCOM != "NONE") && !strcmp(sys.m_PTTCOM.c_str(), RADIO.StrPort) ){ + strcpy(RADIO.StrPort, "NONE"); + RADIO.change = 1; + } + if( pBox->Execute() == TRUE ){ + if( (sys.m_PTTCOM != "NONE") && !strcmp(sys.m_PTTCOM.c_str(), RADIO.StrPort) ){ + sys.m_PTTCOM = "NONE"; + COMM.change = 1; + } + } + delete pBox; + if( COMM.change ) OpenCom(); + if( RADIO.change ) OpenRadio(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainVARI::PupCallsPopup(TObject *Sender) +{ + OnMenuProc(PupCalls->Items, "PopPAGE"); +} +//--------------------------------------------------------------------------- + diff --git a/Main.dfm b/Main.dfm new file mode 100644 index 0000000..91dd163 Binary files /dev/null and b/Main.dfm differ diff --git a/Main.h b/Main.h new file mode 100644 index 0000000..4164083 --- /dev/null +++ b/Main.h @@ -0,0 +1,1118 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef MainH +#define MainH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "ComLib.h" +#include "wave.h" +#include "fft.h" +#include "dsp.h" +#include "dump.h" +#include "comm.h" +#include "fedit.h" +#include "PlayDlg.h" +#include "cradio.h" +#include "RxView.h" +#include "ClockAdj.h" +#include "RMenuDlg.h" +//--------------------------------------------------------------------------- +#define KEY_DIRECT TRUE // WM_CHARで処理 +//--------------------------------------------------------------------------- +#define POINT TPoint +//--------------------------------------------------------------------------- +#define MODGAIN 16384.0 +#define LEVELMAX 2048 +//--------------------------------------------------------------------------- +#define STGCALLMAX 16 +#define LOSTMSGTIME 3 +//--------------------------------------------------------------------------- +enum { + statusPAGE, + statusSN, + statusSAMP, + statusCOM, + statusVARI, + statusHint, + statusEND, +}; +//--------------------------------------------------------------------------- +#define MACBUTTONMAX 144 +#define MACBUTTONWIDTH 60 +#define MACBUTTONVW 3 +#define MACBUTTONXW 12 + +#define MACEXBUTTONMAX 16 +#define MACBUTTONALL (MACBUTTONMAX+MACEXBUTTONMAX) + +#define button1ST 0x02 // Seq 1st +#define button2ND 0xaa // Seq 2nd +enum { + buttonCWON = 1, + buttonCWOFF, + buttonMOVETOP, + buttonMOVEEND, + buttonIDLE, +}; +#define macTX 1 +#define macRX 2 +#define macTXOFF 4 +#define macAUTOCLEAR 8 +#define macTONE 16 +#define macSEEK 32 +#define macTXRX 64 +typedef struct { + TSpeedButton *pButton; + AnsiString Name; + AnsiString Text; + TColor Color; + DWORD Style; +}MACBUTTON; + +enum { + loopINTERNAL, + loopEXTERNAL, +}; +enum { + txRX, + txINTERNAL, + txEXTERNAL, +}; + +#define RADIOMENUMAX 128 +typedef struct { + AnsiString strTTL; + AnsiString strCMD; +}RADIOMENU; + +#define iniwMETRIC 1 +#define iniwLIMIT 2 +#define iniwBOTH 3 +//--------------------------------------------------------------------------- +#define RXMAX 9 +//--------------------------------------------------------------------------- +class CRxSet { +public: + int m_Mode; + BOOL m_fJA; + BOOL m_fTWO; + int m_fMBCS; + int m_CarrierFreq; + RECT m_rcView; + FONTDATA m_FontData; + CMBCS m_MBCS; + + BOOL m_fAFC; + BOOL m_SQ; // スケルチの状態 + int m_SQLevel; + int m_SQTimer; + double m_Speed; + + int m_AFCTimerW; // 広帯域AFCのガード時間 + int m_AFCTimerN; // 高精度AFCのガード時間 + int m_AFCTimerW2; + UINT m_AFCTimerPSK; + int m_AFCFQ; + BOOL m_AFCSQ; + + CFAVG m_AvgAFC; + + BOOL m_fATC; + + int m_PeakSig; + CFAVG m_AvgSig; + FFTSTG m_StgFFT; + CDEMFSK *m_pDem; + CFFT *m_pFFT; + TRxViewDlg *m_pView; + + int m_X; + int m_Y; + int m_WaterW; // for the sub channel + + int m_cAutoTS1; // 自動タイムスタンプカウンタ + int m_cAutoTS2; // 自動タイムスタンプカウンタ + + int m_MFSK_TYPE; + UINT m_AFCTimerMFSK; + + int m_RTTYFFT; + int m_fShowed; +public: + __fastcall CRxSet(); + __fastcall ~CRxSet(); + void __fastcall SetMFSKType(int type); + void __fastcall SetSpeed(double b); + void __fastcall SetMode(int mode); + void __fastcall SetCarrierFreq(double f); + void __fastcall Create(BOOL fView); + void __fastcall Delete(void); + void __fastcall InitStgFFT(void); + void __fastcall SetSampleFreq(double f); + void __fastcall ClearWindow(void); + double __fastcall GetBandWidth(void); + double __fastcall GetSpeed(void); + inline BOOL __fastcall IsActive(void){return m_pDem != NULL;}; + inline BOOL __fastcall IsRTTY(void){return ::IsRTTY(m_Mode);}; + inline BOOL __fastcall Is170(void){return ::Is170(m_Mode);}; + inline BOOL __fastcall IsBPSK(void){return ::IsBPSK(m_Mode);}; + inline BOOL __fastcall IsFSK(void){return ::IsFSK(m_Mode);}; + inline BOOL __fastcall IsMFSK(void){return ::IsMFSK(m_Mode);}; + inline BOOL __fastcall IsQPSK(void){return ::IsQPSK(m_Mode);}; + inline BOOL __fastcall IsPSK(void){return ::IsPSK(m_Mode);}; +}; + +//--------------------------------------------------------------------------- +class TMainVARI : public TForm +{ +__published: // IDE 管理のコンポーネント + TMainMenu *MainMenu; + TMenuItem *KF; + TPanel *PCont; + TPanel *PLog; + TPanel *PCRXB; + TSplitter *Splitter; + TPanel *PCTXB; + TPanel *PCMac; + TStatusBar *StatusBar; + TPanel *PCRX; + TScrollBar *SBarRX; + TPanel *PCTX; + TScrollBar *SBarTX; + TPaintBox *PBoxRX; + TPaintBox *PBoxTX; + TSpeedButton *SBTX; + TSpeedButton *SBTXOFF; + TGroupBox *GBBPF; + TSpeedButton *SBBPFW; + TSpeedButton *SBBPFM; + TSpeedButton *SBBPFS; + TGroupBox *GBCarrier; + TLabel *L1; + TLabel *L2; + TComboBox *CBRXCarrier; + TComboBox *CBTxCarrier; + TSpeedButton *SBAFC; + TSpeedButton *SBNET; + TPanel *PCLevel; + TGroupBox *GBBaud; + TPanel *PFFT; + TSpeedButton *SBFFT; + TSpeedButton *SBWater; + TSpeedButton *SBWave; + TSpeedButton *SBFFT500; + TSpeedButton *SBFFT1K; + TSpeedButton *SBFFT2K; + TSpeedButton *SBFFT3K; + TUpDown *UdRxCarrier; + TUpDown *UdTxCarrier; + TComboBox *CBSpeed; + TGroupBox *GBTiming; + TEdit *EATC; + TUpDown *UdATC; + TSpeedButton *SBBPFN; + TPaintBox *PBoxFFT; + TPaintBox *PBoxLevel; + TMenuItem *KFS; + TSpeedButton *SBATC; + TLabel *L3; + TEdit *HisCall; + TMenuItem *KE; + TUpDown *UdMac; + TMenuItem *KV; + TMenuItem *KVF; + TMenuItem *KVF1; + TMenuItem *KVF3; + TMenuItem *KVFS; + TMenuItem *KVFS2; + TMenuItem *KVFS4; + TMenuItem *N1; + TMenuItem *KFX; + TMenuItem *KO; + TMenuItem *KEP; + TMenuItem *NOT; + TMenuItem *KOVO; + TMenuItem *KOVI; + TMenuItem *N3; + TMenuItem *KOO; + TMenuItem *N4; + TMenuItem *KOAI; + TMenuItem *KOAO; + TLabel *L4; + TEdit *HisName; + TLabel *L5; + TComboBox *HisRST; + TLabel *L6; + TComboBox *MyRST; + TSpeedButton *SBInit; + TMenuItem *KH; + TMenuItem *KHA; + TMenuItem *KHV; + TMenuItem *N5; + TMenuItem *KVFS3; + TMenuItem *KVF2; + TMenuItem *N6; + TMenuItem *KVCR; + TMenuItem *KVCT; + TPopupMenu *PupCharset; + TMenuItem *KANSI; + TMenuItem *KJA; + TMenuItem *KHL; + TMenuItem *KBV; + TMenuItem *KBY; + TMenuItem *KMISC; + TMenuItem *KOV; + TMenuItem *KHH; + TMenuItem *KEC; + TMenuItem *N2; + TMenuItem *KFWS; + TMenuItem *KFRS; + TMenuItem *KFES; + TMenuItem *N7; + TMenuItem *KVSP; + TMenuItem *KFWST; + TMenuItem *N8; + TMenuItem *KVL; + TSpeedButton *SBQSO; + TComboBox *LogFreq; + TMenuItem *N9; + TMenuItem *KFLF; + TSpeedButton *SBData; + TSpeedButton *SBFind; + TMenuItem *KOL; + TMenuItem *KFLO; + TSpeedButton *SBList; + TPopupMenu *PupRX; + TMenuItem *KRXQTH; + TMenuItem *KRXMY; + TMenuItem *KRXNAME; + TMenuItem *KRXNOTE; + TMenuItem *KRXCALL; + TMenuItem *N10; + TMenuItem *KVWA; + TMenuItem *N11; + TMenuItem *KVS; + TPopupMenu *PupCalls; + TSpeedButton *SBM; + TMenuItem *KHO; + TMenuItem *N12; + TMenuItem *KRXCopy; + TLabel *L16; + TEdit *HisQTH; + TLabel *L17; + TEdit *EditNote; + TLabel *L18; + TEdit *EditQSL; + TMenuItem *KVLA; + TMenuItem *KVM; + TMenuItem *KVM2; + TMenuItem *KVM3; + TMenuItem *KVM4; + TMenuItem *N13; + TMenuItem *KRXADDNAME; + TMenuItem *KRXADDNOTE; + TMenuItem *KOA; + TMenuItem *N14; + TMenuItem *KFL; + TMenuItem *KVSF; + TMenuItem *KVSFT; + TMenuItem *KVSFR; + TMenuItem *KOR; + TComboBox *CBMode; + TMenuItem *KFLR; + TMenuItem *KECP; + TMenuItem *KEX; + TPopupMenu *PupTX; + TMenuItem *N15; + TMenuItem *KRXADDQSL; + TMenuItem *N16; + TMenuItem *KECall; + TMenuItem *KEName; + TMenuItem *KERST; + TMenuItem *KEMyCall; + TMenuItem *KEDear; + TMenuItem *KESeq; + TMenuItem *KEFinal; + TPopupMenu *PupPage; + TMenuItem *KPG1; + TMenuItem *KPG2; + TMenuItem *KPG3; + TMenuItem *KPG4; + TPopupMenu *PupSpec; + TMenuItem *KSAS; + TMenuItem *N17; + TMenuItem *KSCan; + TMenuItem *N18; + TMenuItem *KFMS; + TMenuItem *KFML; + TPopupMenu *PupRXW; + TMenuItem *KRWC; + TMenuItem *N19; + TMenuItem *KRWT; + TMenuItem *KRWB; + TMenuItem *KRWE; + TMenuItem *KSW; + TMenuItem *N20; + TMenuItem *KVSD; + TMenuItem *KRXADDMY; + TMenuItem *KRXINV; + TMenuItem *KRXN; + TMenuItem *KORS; + TMenuItem *KORSC; + TMenuItem *KORSW; + TMenuItem *KSN; + TMenuItem *N21; + TMenuItem *KSTX; + TMenuItem *KSNRA; + TMenuItem *KSS; + TMenuItem *N23; + TMenuItem *KSRX; + TMenuItem *KSSR; + TMenuItem *KSSM; + TPanel *PF; + TPaintBox *PBoxPF; + TMenuItem *KVMX; + TMenuItem *N22; + TSpeedButton *SBP60; + TSpeedButton *SBP30; + TSpeedButton *SBP15; + TMenuItem *KRSC; + TMenuItem *N24; + TPopupMenu *PupSQ; + TMenuItem *KS0; + TMenuItem *KS1; + TMenuItem *KS2; + TMenuItem *KS3; + TMenuItem *KS4; + TMenuItem *N25; + TMenuItem *KHJ; + TMenuItem *KHN; + TMenuItem *KHS; + TMenuItem *KSNR; + TMenuItem *KR; + TMenuItem *NR; + TMenuItem *KRM; + TMenuItem *N26; + TMenuItem *KRL; + TMenuItem *KRO; + TMenuItem *NRE; + TMenuItem *KRADD; + TMenuItem *KHM; + void __fastcall FormDestroy(TObject *Sender); + void __fastcall PBoxFFTPaint(TObject *Sender); + void __fastcall PBoxLevelPaint(TObject *Sender); + void __fastcall PBoxRXPaint(TObject *Sender); + void __fastcall PBoxTXPaint(TObject *Sender); + void __fastcall PCTXEnter(TObject *Sender); + void __fastcall PCTXExit(TObject *Sender); + void __fastcall PBoxTXClick(TObject *Sender); + void __fastcall FormKeyPress(TObject *Sender, char &Key); + + void __fastcall SBTXClick(TObject *Sender); + void __fastcall PCRXResize(TObject *Sender); + void __fastcall PCTXResize(TObject *Sender); + void __fastcall SBFFTClick(TObject *Sender); + void __fastcall SBBPFWClick(TObject *Sender); + void __fastcall UdTxCarrierClick(TObject *Sender, TUDBtnType Button); + void __fastcall UdRxCarrierClick(TObject *Sender, TUDBtnType Button); + void __fastcall CBSpeedChange(TObject *Sender); + void __fastcall KFSClick(TObject *Sender); + + void __fastcall SBFFT500Click(TObject *Sender); + void __fastcall UdATCClick(TObject *Sender, TUDBtnType Button); + void __fastcall SBAFCClick(TObject *Sender); + void __fastcall SBATCClick(TObject *Sender); + void __fastcall PBoxFFTMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall PBoxLevelMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall SBTXOFFClick(TObject *Sender); + void __fastcall CBTxCarrierChange(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall KFClick(TObject *Sender); + void __fastcall CBRXCarrierChange(TObject *Sender); + void __fastcall CBRXCarrierDropDown(TObject *Sender); + void __fastcall CBRXCarrierKeyPress(TObject *Sender, char &Key); + void __fastcall UdMacClick(TObject *Sender, TUDBtnType Button); + + void __fastcall PBoxRXMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall FormKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + + void __fastcall SBQSOClick(TObject *Sender); + void __fastcall KVClick(TObject *Sender); + void __fastcall KVF1Click(TObject *Sender); + void __fastcall SBNETClick(TObject *Sender); + void __fastcall KVFS2Click(TObject *Sender); + void __fastcall KVFS4Click(TObject *Sender); + void __fastcall KFXClick(TObject *Sender); + void __fastcall FormActivate(TObject *Sender); + void __fastcall FormDeactivate(TObject *Sender); + void __fastcall KEClick(TObject *Sender); + void __fastcall KEPClick(TObject *Sender); + void __fastcall SBarRXChange(TObject *Sender); + void __fastcall SBarTXChange(TObject *Sender); + void __fastcall SBBPFWMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KOVOClick(TObject *Sender); + void __fastcall KOOClick(TObject *Sender); + void __fastcall KOAIClick(TObject *Sender); + void __fastcall KOAOClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall SBInitClick(TObject *Sender); + void __fastcall KOClick(TObject *Sender); + void __fastcall KHAClick(TObject *Sender); + void __fastcall KHVClick(TObject *Sender); + + void __fastcall FormPaint(TObject *Sender); + void __fastcall KVFS3Click(TObject *Sender); + void __fastcall KVCRClick(TObject *Sender); + void __fastcall KVCTClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall SBATCMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + + void __fastcall StatusBarMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KANSIClick(TObject *Sender); + void __fastcall KMISCClick(TObject *Sender); + void __fastcall PupCharsetPopup(TObject *Sender); + void __fastcall HisRSTChange(TObject *Sender); + void __fastcall KOVClick(TObject *Sender); + void __fastcall KECClick(TObject *Sender); + void __fastcall KFWSClick(TObject *Sender); + void __fastcall KFRSClick(TObject *Sender); + void __fastcall KFESClick(TObject *Sender); + void __fastcall KVSPClick(TObject *Sender); + void __fastcall KFWSTClick(TObject *Sender); + + void __fastcall KVLClick(TObject *Sender); + void __fastcall KFLFClick(TObject *Sender); + void __fastcall HisCallChange(TObject *Sender); + void __fastcall SBDataClick(TObject *Sender); + void __fastcall SBFindClick(TObject *Sender); + void __fastcall KOLClick(TObject *Sender); + void __fastcall KFLOClick(TObject *Sender); + void __fastcall LogFreqChange(TObject *Sender); + void __fastcall SBListClick(TObject *Sender); + + void __fastcall KRXMYClick(TObject *Sender); + void __fastcall KRXQTHClick(TObject *Sender); + void __fastcall KRXNAMEClick(TObject *Sender); + void __fastcall KRXNOTEClick(TObject *Sender); + void __fastcall KRXCALLClick(TObject *Sender); + void __fastcall KVWAClick(TObject *Sender); + void __fastcall PBoxFFTMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall PBoxFFTMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall PBoxLevelMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall PBoxLevelMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall SBMClick(TObject *Sender); + void __fastcall KRXCopyClick(TObject *Sender); + void __fastcall KVLAClick(TObject *Sender); + void __fastcall PLogMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KVM2Click(TObject *Sender); + void __fastcall UdMacMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KRXADDNAMEClick(TObject *Sender); + void __fastcall KRXADDNOTEClick(TObject *Sender); + void __fastcall KOAClick(TObject *Sender); + void __fastcall SBDataMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall SBFindMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + void __fastcall KFLClick(TObject *Sender); + + void __fastcall KVSFTClick(TObject *Sender); + void __fastcall KORClick(TObject *Sender); + void __fastcall CBModeChange(TObject *Sender); + void __fastcall KFLRClick(TObject *Sender); + void __fastcall PBoxTXMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KECPClick(TObject *Sender); + void __fastcall KEXClick(TObject *Sender); + void __fastcall PupTXPopup(TObject *Sender); + void __fastcall PBoxTXMouseMove(TObject *Sender, TShiftState Shift, int X, + int Y); + void __fastcall PBoxTXMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + + void __fastcall KRXADDQSLClick(TObject *Sender); + void __fastcall KECallClick(TObject *Sender); + void __fastcall SBTXMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall KPG1Click(TObject *Sender); + void __fastcall PupPagePopup(TObject *Sender); + + void __fastcall SBWaveMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + + void __fastcall KSASClick(TObject *Sender); + void __fastcall KFMSClick(TObject *Sender); + void __fastcall KFMLClick(TObject *Sender); + void __fastcall KRWCClick(TObject *Sender); + void __fastcall KRWTClick(TObject *Sender); + void __fastcall PupRXWPopup(TObject *Sender); + void __fastcall KRWEClick(TObject *Sender); + void __fastcall PupSpecPopup(TObject *Sender); + void __fastcall KSWClick(TObject *Sender); + void __fastcall KVSDClick(TObject *Sender); + void __fastcall StatusBarDrawPanel(TStatusBar *StatusBar, + TStatusPanel *Panel, const TRect &Rect); + void __fastcall StatusBarMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall KRXADDMYClick(TObject *Sender); + void __fastcall KRXINVClick(TObject *Sender); + void __fastcall PupRXPopup(TObject *Sender); + void __fastcall KORSCClick(TObject *Sender); + void __fastcall KSNClick(TObject *Sender); + + void __fastcall KSTXClick(TObject *Sender); + void __fastcall KSNRAClick(TObject *Sender); + void __fastcall KSRXClick(TObject *Sender); + void __fastcall KSSRClick(TObject *Sender); + + void __fastcall PBoxPFPaint(TObject *Sender); + + void __fastcall KVMXClick(TObject *Sender); + void __fastcall SBP60Click(TObject *Sender); + void __fastcall KRSCClick(TObject *Sender); + void __fastcall PupSQPopup(TObject *Sender); + void __fastcall KS0Click(TObject *Sender); + void __fastcall KHJClick(TObject *Sender); + + + void __fastcall KHClick(TObject *Sender); + void __fastcall KSNRClick(TObject *Sender); + void __fastcall KRClick(TObject *Sender); + void __fastcall KRADDClick(TObject *Sender); + void __fastcall KRLClick(TObject *Sender); + void __fastcall KROClick(TObject *Sender); + void __fastcall PupCallsPopup(TObject *Sender); +private: // ユーザー宣言 + BOOL m_fInitFirst; + BOOL m_fDisEvent; + int m_AppErr; +public: + TTimer *m_pSoundTimer; + TTimer *m_pLogLinkTimer; + TTimer *m_pRadioTimer; + TTimer *m_pMacroTimer; + TTimer *m_pPlayBackTimer; + TTimer *m_pMacroOnTimer; + int m_BufferSize; + SHORT m_wBuffer[8192]; + WAVEFORMATEX m_WFX; + CWave m_Wave; + CWaveFile m_WaveFile; + + int m_SoundMsgTimer; + int m_RecoverSoundMode; + int m_LostSoundRX; + int m_LostSoundTX; + int m_fShowMsg; + int m_cInfoMsg[5]; + int m_InfoMsgFlag; + AnsiString m_InfoMsg[5]; + int m_cErrorMsg; + AnsiString m_ErrorMsg; + + TPlayDlgBox *m_pPlayBox; + + int m_TX; + BOOL m_fHPF; + CIIR m_HPF; + + int m_NotchFreq; + CNotches m_Notches; + int m_MouseNotch; + + CRxSet m_RxSet[RXMAX]; // 受信管理データ + CMODFSK m_ModFSK; + int m_ModGain; + double m_ModGainR; +// double m_Speed; + +#if DEBUG + CMODFSK m_ModTest; // For test + CVCO m_VCOTest; // For test + CIIR m_TestHPF; + CFIR2 m_BPF500; +#endif + + BOOL m_StatusUTC; + CDump m_Dump; + CDump m_Edit[4]; + int m_SendingEdit; + int m_CurrentEdit; + int m_SaveEditPage; + BOOL m_fSendChar; + + int m_WaveBitMax; + int m_WaveType; + CCOLLECT m_Collect1; + CCOLLECT m_Collect2; +// CFAVG m_AVGWave; + +#if DEBUG + CQSB m_QSB; + CNoise m_Noise; +#endif + + double m_DecFactor; + int m_fDec; + CDECM2 m_Dec2; + + int m_RadioScaleCounter; + int m_ScaleAsRigFreq; + int m_ScaleDetails; + int m_FFTVType; + int m_FFTSmooth; + int m_FFTW; + int m_FFTB; + int m_FFTU; + int m_FFTWindow; + double m_FFTFactor; + double m_FFTSampFreq; + double m_fftbuf[FFT_BUFSIZE*2]; + int m_fftout[FFT_BUFSIZE]; + CFFT m_FFT; + + int m_WaterNoiseL; + int m_WaterNoiseH; + + int m_AFCWidth; + int m_AFCLevel; + int m_ATCLevel; + int m_ATCSpeed; + int m_ATCLimit; + int m_AFCKeyTimer; + + int m_SkipTmg; + BOOL m_Lock; + BOOL m_fReqRX; + BOOL m_fDrop; + + DWORD m_QSOStart; + SYSTEMTIME m_LocalTime; + + BOOL m_fSubWindow; + + int m_fftSC; + int m_fftMX; + int m_fftXW, m_fftYW; + Graphics::TBitmap *m_pBitmapFFT; + int m_levelXW, m_levelYW; + Graphics::TBitmap *m_pBitmapLevel; + + int m_PFTimer; + int m_pfXW, m_pfYW, m_pfXC; + Graphics::TBitmap *m_pBitmapPF; + + int m_tWaterLevel[6]; + UCOL m_tWaterColset[12]; + TColor m_tWaterColors[256]; + + UCOL m_tFFTColset[6]; + + FFTSTG m_StgWater; + + int m_TestTimer; + FILE *m_fpText; + FILE *m_fpTest; + + int m_MacButtonVW; + MACBUTTON m_tMacButton[MACBUTTONALL]; + + CComm *m_pCom; + CCradio *m_pRadio; + TFileEdit *m_pHelp; + TFileEdit *m_pEdit; + + char m_HintText[256]; // ヒント用のバッファ + char m_TextBuff[256]; // 汎用のバッファ + + LPCSTR m_pCheckKey; + AnsiString *m_pCheckBuff; + + BOOL m_fHintUpdate; + AnsiString m_HintKey; + + BOOL m_MouseDown; + int m_MouseSubChannel; + + int m_Priority; + int m_Dupe; + + AnsiString m_StrSel; + AnsiString m_UStrSel; + + int m_MacroMenuNo; + TPopupMenu *m_pMacroPopup; + TMenuItem *m_pCurrentMacroMenu; + int m_CurrentMacro; + BOOL m_fMacroRepeat; + int m_ReqMacroTimer; + int m_ReqAutoClear; + int m_ReqAutoReturn; + int m_ReqAutoNET; + TMenuItem *m_ParentMenu; + + TClockAdjDlg *m_pClockView; + + BOOL m_fKeyShift; + BOOL m_fSuspend; + BOOL m_fTone; + + int m_RightX; + int m_RightFreq; + + AnsiString m_MacroInput; + CVal m_MacroVal; + + BOOL m_fMBCS; + BOOL m_fConvAlpha; + BOOL m_fRttyWordOut; + + AnsiString m_strStatus[statusEND]; + TRect m_rcStatus[statusEND]; + + + TTimer *m_pWheelTimer; + CDump *m_pDump; + + int m_CPUBENCHType; + CFAVG m_CPUBENCH; + + BYTE m_PlayBackTime[3]; + CPlayBack m_PlayBack; + CWebRef m_WebRef; + CLIBL m_LibDLL; + + int m_LogBand; + + AnsiString m_ListBAUD; + AnsiString m_strLogMode; + +public: + int m_nRadioMenu; +private: + RADIOMENU m_RadioMenu[RADIOMENUMAX]; + +#if DEBUG + TSpeedButton *m_pDebugButton; +#endif + +private: + void __fastcall OnAppMessage(tagMSG &Msg, bool &Handled); + void __fastcall OnActiveFormChange(TObject *Sender); + void __fastcall SetSystemFont(void); + void __fastcall SoundTimer(TObject *Sender); + void __fastcall LogLinkTimer(TObject *Sender); + void __fastcall RadioTimer(TObject *Sender); + void __fastcall MacroTimer(TObject *Sender); + void __fastcall WheelTimer(TObject *Sender); + void __fastcall MacroOnTimer(TObject *Sender); + + LPCSTR __fastcall GetHintStatus(LPCSTR pHint); + //void __fastcall DrawStatusBar(const Windows::TRect &Rect, LPCSTR pText, TColor col); + void __fastcall DrawStatusBar(const TRect &Rect, LPCSTR pText, TColor col); //JA7UDE 0428 + void __fastcall DrawHint(void); + void __fastcall DrawStatus(int n, LPCSTR pText); + void __fastcall DrawStatus(int n); + int __fastcall GetStatusIndex(int x); + int __fastcall GetPopupIndex(TComponent *pComponent); + void __fastcall UpdateCharset(void); + void __fastcall UpdateTitle(void); + void __fastcall ReadRegister(void); + void __fastcall WriteRegister(void); + void __fastcall SampleStatus(void); + void __fastcall PageStatus(void); + BOOL __fastcall SampleFreq(double f); + void __fastcall FFTSampleFreq(double f); + BOOL __fastcall OpenSound(BOOL fTX); + BOOL __fastcall ReOutOpen(void); + void __fastcall OpenCom(void); + void __fastcall OpenRadio(void); + void __fastcall SetCBSpeed(void); + void __fastcall UpdateUI(void); + void __fastcall UpdateLogPanel(void); + void __fastcall OnWaveIn(void); + void __fastcall OnWaveOut(void); + void __fastcall RemoveUselessMessage(UINT wParam); + void __fastcall InitWFX(void); + void __fastcall Draw(BOOL fPaint); + void __fastcall DrawFFT(BOOL fPaint); + void __fastcall DrawWater(BOOL fPaint, BOOL fClear); + void __fastcall DrawWave(BOOL fPaint); + void __fastcall DrawPF(BOOL fPaint); + void __fastcall CalcFFTCenter(int fo); + void __fastcall CalcFFTFreq(void); + void __fastcall SetFFTWidth(int fw); + void __fastcall InitStgFFT(FFTSTG *pStg); + void __fastcall InitWater(int sw); + double __fastcall SqrtToDB(double d); + double __fastcall DBToSqrt(double d); + double __fastcall AdjDB(double d); + void __fastcall CalcStgFFT(CRxSet *pRxSet); + void __fastcall DoAFCMFSK(CRxSet *pRxSet, int fo, BOOL fUpdate); + void __fastcall CreateWaterColors(void); + + void __fastcall DrawLevel(BOOL fPaint); + void __fastcall DoMod(void); + void __fastcall PutDumpChar(int d, CRxSet *pRxSet, CDump *pDump); + void __fastcall DoDem(double d); + void __fastcall DoDem(void); + void __fastcall UpdateWaveCaption(void); + void __fastcall SetTXCaption(void); + void __fastcall SetPTT(BOOL fTX); + void __fastcall RxStatus(CRxSet *pRxSet, LPCSTR p); + void __fastcall SetTXInternal(void); + void __fastcall ToTone(void); + void __fastcall ToTX(void); + void __fastcall ToRX(void); + void __fastcall DeleteSoundTimer(void); + void __fastcall SetRxFreq(int fq); + void __fastcall SetTxFreq(int fq); + void __fastcall SetMacButtonMax(void); + void __fastcall CreateMacButton(void); + int __fastcall GetMacButtonNo(TSpeedButton *pButton); + void __fastcall OnMacButtonClick(TObject *Sender); + void __fastcall OnMacButtonDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y); + void __fastcall CreateMacExButton(void); + void __fastcall DeleteMacExButton(void); + void __fastcall AttachFocus(void); + void __fastcall DettachFocus(void); + TSpeedButton *__fastcall GetDraw(int n); + int __fastcall GetDrawType(void); + void __fastcall SetDrawType(int n); + TSpeedButton *__fastcall GetBPF(int n); + int __fastcall GetBPFType(void); + void __fastcall SetBPFType(int n); + int __fastcall GetBPFTaps(TObject *Sender); + + void __fastcall InitCheckValKey(LPCSTR pKey, AnsiString *pAS); + BOOL __fastcall CheckKey(LPCSTR pTemplate); + LPCSTR __fastcall CheckValKey(LPCSTR pTemplate); + LPCSTR __fastcall CheckValKey(LPCSTR pKey, LPCSTR pTemplate); + void __fastcall MacroDate(LPSTR t, SYSTEMTIME &now); + void __fastcall MacroHisName(LPSTR t); +// BOOL __fastcall CheckCond(LPCSTR p, LPCSTR v, int type, int &op, double &d, AnsiString &as); + LPCSTR __fastcall Cond(LPCSTR p, TSpeedButton *pButton); + BOOL __fastcall IsMBCSStr(LPCSTR p); + BOOL __fastcall GetDataCond(LPCSTR p, int err, TSpeedButton *pButton); + int __fastcall ConvMacro(LPSTR t, LPCSTR p, TSpeedButton *pButton); + void __fastcall DoMacroReturn(int f); + void __fastcall DoMacro(LPCSTR pMacro, TSpeedButton *pButton); + void __fastcall SendButton(int n); + + void __fastcall UpdateCallsign(void); + void __fastcall UpdateLogMode(void); + void __fastcall UpdateLogData(void); + void __fastcall UpdateTextData(void); + void __fastcall FindCall(void); + void __fastcall UpdateLogLink(void); + void __fastcall AutoLogSave(void); + void __fastcall WndCopyData(TMessage &Message); + void __fastcall CheckLogLink(void); + void __fastcall InitDefKey(void); + void __fastcall UpdateSubWindow(void); + void __fastcall DrawSubChannel(TPaintBox *pBox); + void __fastcall AppException(TObject *Sender, Exception *E); + void __fastcall ShowSubChannel(int n, int sw); + void __fastcall MacroGreeting(LPSTR t, LPCSTR pCall, int type); + + void __fastcall KCallClick(TObject *Sender); + void __fastcall AddCall(LPCSTR p); + void __fastcall SetTXFocus(void); + + BOOL __fastcall DeleteMacroTimerS(void); + void __fastcall DeleteMacroTimer(void); + void __fastcall CreateMacroTimer(int n); + + void __fastcall UpdateLogHeight(void); + void __fastcall UpdateMacButtonVW(int n); + void __fastcall UpdateSpeedList(int mode); + void __fastcall SetMode(int mode); + void __fastcall DoSuspend(BOOL fMinimize); + void __fastcall DoResume(void); + void __fastcall SetEditPage(int cno); + void __fastcall InitCollect(void); + void __fastcall LoadMacro(LPCSTR pName); + void __fastcall SaveMacro(LPCSTR pName); + void __fastcall LoadMacro(TMemIniFile *pIniFile); + void __fastcall SaveMacro(TMemIniFile *pIniFile); + void __fastcall SetSpeedInfo(double b); + BOOL __fastcall IsFreqErr(double d); + int __fastcall GetMsgCount(void); + + inline BOOL __fastcall IsRTTY(void){return m_RxSet[0].IsRTTY();}; + inline BOOL __fastcall Is170(void){return m_RxSet[0].Is170();}; + inline BOOL __fastcall IsBPSK(void){return m_RxSet[0].IsBPSK();}; + inline BOOL __fastcall IsPSK(void){return m_RxSet[0].IsPSK();}; + + void __fastcall OutYaesuVU(int hz); + void __fastcall OutYaesuHF(int hz); + void __fastcall OutCIV(int hz); + void __fastcall OutCIV4(int hz); + void __fastcall OutKENWOOD(int hz); + void __fastcall OutJST245(int hz); + + void __fastcall OutModeYaesuHF(LPCSTR pMode); + void __fastcall OutModeYaesuVU(LPCSTR pMode); + void __fastcall OutModeCIV(LPCSTR pMode); + void __fastcall OutModeKENWOOD(LPCSTR pMode); + void __fastcall OutModeJST245(LPCSTR pMode); + + void __fastcall OnMacroMenuClick(TObject *Sender); + void __fastcall WaitICOM(void); + void __fastcall DoMacroMenu(LPCSTR pVal, TSpeedButton *pButton, BOOL fRadio); + + void __fastcall UpdatePlayBack(void); + void __fastcall DoPlayBack(int s); + void __fastcall StopPlayBack(void); + + void __fastcall UpdateShowCtrl(void); + void __fastcall DoEvent(int n); + void __fastcall UpdateMacroOnTimer(void); + void __fastcall OnLogFreq(BOOL fLink); + void __fastcall ShutDown(void); + void __fastcall DoBench(LPSTR t, int type); + void __fastcall OnXmClick(TObject *Sender); + void __fastcall OnXClick(TObject *Sender); + TMenuItem* __fastcall FindMenu(TMenuItem *pMainMenu, LPCSTR pTitle); + TMenuItem* __fastcall GetMenuItem(TMenuItem *pMenu, LPCSTR pTitle); + TMenuItem* __fastcall GetMainMenu(LPCSTR pTitle, BOOL fNew); + TMenuItem* __fastcall GetSubMenu(LPCSTR pTitle); + void __fastcall AddExtensionMenu(LPCSTR pMain, LPCSTR pCaption, LPCSTR pHint); + void __fastcall InsExtensionMenu(LPCSTR pTitle, LPCSTR pPos, LPCSTR pCaption, LPCSTR pHint); + void __fastcall ShortCutExtensionMenu(TMenuItem *pMenu, LPCSTR pKey); + BOOL __fastcall IsXMenu(TMenuItem *pItem); + BOOL __fastcall OnMenuProc(TMenuItem *pMenu, LPCSTR pProc, LPCSTR pPara, BOOL fStop); + void __fastcall OnMenuProc(TMenuItem *pMenu, LPCSTR pCaption); + void __fastcall DoParentClick(TMenuItem *pMenu); + TMenuItem* __fastcall GetMenuArg(AnsiString &arg, LPCSTR pVal, BOOL fArg); + void __fastcall SetRadioMenu(TMenuItem *pMenu); + + TSpeedButton* __fastcall FindButton(TComponent *pMainControl, LPCSTR pTitle, TSpeedButton *pButton, BOOL fErrMsg); + void __fastcall ClickButton(TSpeedButton *pButton); + + void __fastcall CreateSubMenu(void); + void __fastcall KVSClick(TObject *Sender); + void __fastcall KSSClick(TObject *Sender); + + void __fastcall LoadRadioDef(LPCSTR pName); + void __fastcall AdjustRadioMenu(void); + void __fastcall KRadioCmdClick(TObject *Sender); + void __fastcall KRadioEditClick(TObject *Sender); + +#if DEBUG + void __fastcall TestSignal(void); +#endif + +public: // ユーザー宣言 + __fastcall TMainVARI(TComponent* Owner); + + void __fastcall WndProc(TMessage &Message); + void __fastcall DisplayHint(TObject *Sender); + void __fastcall OnWave(void); + void __fastcall SetSoundCard(int ch, LPCSTR pID, LPCSTR pIDTX); + void __fastcall SetSampleFreq(double f, BOOL fForce); + void __fastcall SetTxOffset(double f); + void __fastcall SetRXFifo(int d); + void __fastcall SetTXFifo(int d); + void __fastcall UpdatePriority(int Priority); + void __fastcall OnFontChange(BOOL fTX); + void __fastcall DrawFreqScale(TCanvas *pCanvas, int XW, int YW, int fftb, int fftw, int fh, BOOL fRadio); + void __fastcall DrawErrorMsg(TCanvas *pCanvas, int XW, int YW, BOOL fReset); + void __fastcall SetInfoMsg(LPCSTR pStr); + void __fastcall SetInfoMsg(LPCSTR pStr, int pos); + void __fastcall SetErrorMsg(LPCSTR pStr); + int __fastcall GetOverlayTop(void); + void __fastcall SetConvAlpha(BOOL f); + + void __fastcall SpeedChange(double b); + void __fastcall UpdateSpeed(CRxSet *pRxSet, double b); + void __fastcall UpdateMode(CRxSet *pRxSet, int offset); + void __fastcall SetATCSpeed(int f); + void __fastcall SetATCLimit(int f); + BOOL __fastcall GetDataConds(LPCSTR p, int err, TSpeedButton *pButton); + + LPCSTR __fastcall GetMacroValue(LPCSTR pVal); + LPCSTR __fastcall GetMacroStr(AnsiString &as, LPCSTR pVal); + int __fastcall GetMacroInt(LPCSTR pVal); + double __fastcall GetMacroDouble(LPCSTR pVal); + int __fastcall ConvMacro(AnsiString &as, LPCSTR p, TSpeedButton *pButton); + int __fastcall ConvMacro_(AnsiString &as, LPCSTR p, TSpeedButton *pButton); + int __fastcall ConvMacro_(LPSTR t, LPCSTR p, TSpeedButton *pButton); + + int __fastcall GetSignalFreq(int freq, int fm, CRxSet *pRxSet); + int __fastcall TMainVARI::GetSignalFreq(int fo, int fm, CRxSet *pRxSet, int th); + void __fastcall OnChar(int Key); + void __fastcall OpenWheelTimer(CDump *pDump); + void __fastcall CloseWheelTimer(CDump *pDump); + void __fastcall UpdateModGain(void); + + void __fastcall InitCollect(CRxSet *pRxSet, int n); + inline void __fastcall ShowMacroSample(void){KHS->Click();}; + inline void __fastcall ShowManual(void){KHO->Click();}; + + void __fastcall ExtFskIt(int r); + void __fastcall SetRTTYFFT(int f); + + friend int __fastcall OnGetChar(void); + +protected: + void __fastcall OnWaveEvent(TMessage &Message); + void __fastcall CMMML(TMessage &Message); + void __fastcall CMMMR(TMessage &Message); + void __fastcall OnActiveApp(TMessage &Message); + void __fastcall OnMouseWheel(TMessage &Message); +BEGIN_MESSAGE_MAP + MESSAGE_HANDLER(WM_WAVE, TMessage, OnWaveEvent) + MESSAGE_HANDLER(CM_CMML, TMessage, CMMML) + MESSAGE_HANDLER(CM_CMMR, TMessage, CMMMR) + MESSAGE_HANDLER(WM_ACTIVATEAPP, TMessage, OnActiveApp) + MESSAGE_HANDLER(WM_MOUSEWHEEL, TMessage, OnMouseWheel) +END_MESSAGE_MAP(TForm) +}; +//--------------------------------------------------------------------------- +extern PACKAGE TMainVARI *MainVARI; +//--------------------------------------------------------------------------- +#endif diff --git a/Mmcg.cpp b/Mmcg.cpp new file mode 100644 index 0000000..a4c064b --- /dev/null +++ b/Mmcg.cpp @@ -0,0 +1,1521 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +/************************************************************************ + MMCG + + Copyright (C) JE3HHT 1993. + Modifed on 2000 for MMTTY by JE3HHT +************************************************************************/ +#include //JA7UDE 0428 +#pragma hdrstop + +#include "ComLib.h" +#include "Mmcg.h" +#include "string.h" +#include "stdlib.h" +#include "Country.h" + +CMMCG mmcg; + +static LPCSTR ptbl[]={ + "", + "北海道", "青森県","岩手県","秋田県","山形県","宮城県","福島県","新潟県", + "長野県", "東京都","神奈川県","千葉県","埼玉県","茨城県","栃木県","群馬県", + "山梨県","静岡県","岐阜県","愛知県","三重県","京都府","滋賀県","奈良県", + "大阪府","和歌山県","兵庫県","富山県","福井県","石川県","岡山県","島根県", + "山口県","鳥取県","広島県","香川県","徳島県","愛媛県","高知県","福岡県", + "佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県" +}; + +static LPCSTR ptbleng[]={ + "", + "Hokkaido", "Aomori","Iwate","Akita","Yamagata","Miyazaki","Fukushima","Nigata", + "Nagano", "Tokyo","Kanagawa","Chiba","Saitama","Ibaragi","Tochigi","Gunma", + "Yamanashi","Shizuoka","Gifu","Aichi","Mie","Kyoto","Shiga","Nara", + "Osaka","Wakayama","Hyogo","Toyama","Fukui","Ishikawa","Okayama","Shimane", + "Yamaguchi","Tottri","Hiroshima","Kagawa","Tokushima","Ehime","Kochi","Fukuoka", + "Saga","Nagasaki","Kumamoto","Oita","Miyazaki","Kagoshima","Okinawa" +}; + +__fastcall CMMCG::CMMCG() +{ + m_bp = NULL; + m_Max = 0; + m_Cnt = 0; + m_sinc = 0; + m_mask = -1; +} + +__fastcall CMMCG::~CMMCG() +{ + Free(); +} + +void __fastcall CMMCG::Free(void) +{ + if( m_bp != NULL ){ + int i; + MMCG *mp; + + for( mp = m_bp, i = 0; i < m_Cnt; i++, mp++ ){ + if( mp->Code != NULL ) delete mp->Code; + if( mp->QTH != NULL ) delete mp->QTH; + if( mp->Key != NULL ) delete mp->Key; + } + m_bp = NULL; + } + if( m_fp != NULL ){ + delete m_fp; + m_fp = NULL; + } + m_Max = m_Cnt = m_FindCnt = 0; +} + +void __fastcall CMMCG::Alloc(int n) +{ + if( n >= m_Max ){ + int max = m_Max ? m_Max * 2 : 256; + MMCG *np = (MMCG *)new BYTE[sizeof(MMCG) * max]; + if( m_bp != NULL ){ + memcpy(np, m_bp, sizeof(MMCG) * m_Cnt); + delete m_bp; + } + m_bp = np; + m_Max = max; + } +} + +/*#$% +====================================================== + ローマ綴りを調整する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +LPSTR __fastcall CMMCG::adjspl(LPSTR p) +{ + static char bf[50]; + LPCSTR tp[]={ + "TSU","TU", + "CHA","CYA", + "CHI","CI", + "CHU","CYU", + "CHO","CYO", + "JYA","JA", + "JYU","JU", + "JYO","JO", + "SHA","SYA", + "SHI","SI", + "SHU","SYU", + "SHE","SYE", + "SHO","SYO", + }; + int i, f; + char *t; + + for( t = bf; *p;){ + for( f = 0, i = 0; i < AN(tp); i+=2 ){ + if( !strncmp(p, tp[i], strlen(tp[i])) ){ + strcpy(t, tp[i+1]); + t += strlen(t); + p += strlen(tp[i]); + f++; + break; + } + } + if( !f ){ + *t++ = *p++; + } + } + *t = 0; + return(bf); +} + +/*#$% +====================================================== + 最後のローマ綴りで検索起動を断念する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::chkspl(LPCSTR p) +{ + static char *tp[]={ + "TS","CH","JY","SH", + }; + int i; + + i = strlen(p); + if( i >= 2 ){ + p += (i-2); + for( i = 0; i < AN(tp); i++ ){ + if( !strcmp(tp[i], p) ) return 0; + } + } + return 1; +} + +/*#$% +====================================================== + 文字列の最後の一致を調べる +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::LastMatch(LPSTR t, LPSTR s) +{ + t = lastp(t) - strlen(s) + 1; + return !strcmp(t, s); +} + +/*#$% +====================================================== + 入力されたQTHを正規化する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::NormQth(LPSTR p) +{ + int i; + LPCSTR *cp; + + for( i = 1, cp = &ptbl[1]; i < AN(ptbl); i++, cp++ ){ + if( !strncmp(p, *cp, strlen(*cp)) ){ + if( *(p + strlen(*cp)) ){ + strcpy(p, p + strlen(*cp)); + return 1; + } + } + } + return 0; +} + +/*#$% +====================================================== + エリアマスクを設定する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::SetMask(void) +{ + LPCSTR p; + + m_mask = -1; + if( m_Call[0] ){ /* エリアマスク */ + p = m_Call; + if( (m_Call[0] == '7') && (m_Call[1] != 'J') ){ + m_mask = 1; + p += 3; + } + for( ; *p; p++ ){ + if( isdigit(*(LPUSTR)p) ) m_mask = ((*p) & 0x0f); + } + } +} + +/*#$% +====================================================== + コードから検索対象にするかどうか調べる +------------------------------------------------------ + p : コードのポインタ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::isfind(LPCSTR p) +{ + const char _tt[]={ + -1, + 8, /* 01 */ + 7, 7, 7, 7, 7, 7, /* 02-07 */ + 0, 0, /* 08-09 */ + 1, 1, 1, 1, 1, 1, 1, 1, /* 10-17 */ + 2, 2, 2, 2, /* 18-21 */ + 3, 3, 3, 3, 3, 3, /* 22-27 */ + 9, 9, 9, /* 28-30 */ + 4, 4, 4, 4, 4, /* 31-35 */ + 5, 5, 5, 5, /* 36-39 */ + 6, 6, 6, 6, 6, 6, 6, 6, /* 40-47 */ + }; + + if( m_mask == -1 ){ + return 1; + } + else { + return( (_tt[atoin(p, 2)] == m_mask) ? 1 : 0 ); + } +} + + +/*#$% +====================================================== + 指定位置の文字の種類を得る +------------------------------------------------------ + p : バッファのポインタ + x : 位置 +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::_ischrtyp(char *p, int x) +{ + int xx, jis; + + for( jis = xx = 0; xx < x; xx++, p++ ){ + if( jis ){ + jis = 0; + } + else if( _mbsbtype((unsigned char *)p, 0) == _MBC_LEAD ){ + jis = 1; + } + } + if( jis ){ /* KANJI2 */ + return 2; + } + else if( _mbsbtype((unsigned char *)p, 0) == _MBC_LEAD ){ /* KANJI1 */ + return 1; + } + else { /* ANK */ + return 0; + } +} + +/*#$% +====================================================== + データファイルを読み込む +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::LoadDef(LPCSTR pFileName) +{ + FILE *fp; + char hbf[512]; + LPSTR t, p; + + Free(); + if( (fp = fopen(pFileName, "rt"))!=NULL ){ + while( !feof(fp) ){ + if( fgets(hbf, 512, fp)!=NULL ){ + if( hbf[0] == '$' ) break; + ClipLF(hbf); + if( hbf[0] != '!' ){ + p = StrDlm(t, hbf, TAB); + clipsp(t); + Alloc(m_Cnt); + m_bp[m_Cnt].Code = StrDupe(t); + if( p != NULL ){ + p = StrDlm(t, p, TAB); + if( *t == '%' ) *t = 0; + clipsp(t); + m_bp[m_Cnt].QTH = StrDupe(SkipSpace(t)); + } + else { + m_bp[m_Cnt].QTH = StrDupe(""); + } + if( p != NULL ){ + clipsp(p); + m_bp[m_Cnt].Key = StrDupe(SkipSpace(p)); + } + else { + m_bp[m_Cnt].Key = StrDupe(""); + } + m_Cnt++; + } + } + } + fclose(fp); + m_fp = (MMCG **)new BYTE[sizeof(MMCG*)*m_Cnt]; + } + else { + WarningMB(sys.m_MsgEng ? "'%s' was not found.\r\n\r\nYou cannot use a JCC/JCG list function.\r\nThis is not a problem if you do not need it":"'%s'が見つかりません.", pFileName); + } +} + +/*#$% +====================================================== + コードから県名を得る +------------------------------------------------------ + code : コードのポインタ +------------------------------------------------------ + 県名のポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall CMMCG::getprf(LPCSTR pCode) +{ + int n; + + n = atoin(pCode, 2); + return(sys.m_MsgEng ? ptbleng[n] : ptbl[n]); +} + +/*#$% +====================================================== + 郡名を得る +------------------------------------------------------ + p : 町村コードのポインタ +------------------------------------------------------ + QTHのポインタ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::GetGun(LPSTR t, LPCSTR pCode) +{ + strcpy(wbf, pCode); + wbf[5] = 0; + MMCG *mp = m_bp; + int i; + for( i = 0; i < m_Cnt; i++, mp++ ){ + if( !strcmp(mp->Code, wbf) ){ + strcpy(t, mp->QTH); + return; + } + } + *t = 0; +} + +/*#$% +====================================================== + QTHの文字列を得る +------------------------------------------------------ + cp : データのポインタ +------------------------------------------------------ + QTHのポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall CMMCG::GetQTH(MMCG *mp) +{ + char bf[512]; + + if( sys.m_MsgEng ){ + char qth[128]; + strcpy(qth, mp->Key); + LPSTR t; + LPSTR p = qth; + while(*p){ + p = StrDlm(t, p, ','); + } + if( strlen(mp->Code) == 6 ){ + if( isalpha((unsigned char)LastC(mp->Code)) ){ /* 町村コード */ + strcpy(bf, t); + strcat(bf, ","); + GetGun(qth, mp->Code); + strcat(bf, qth); + } + else { /* 政令指定都市 */ + strcpy(bf, t); + } + } + else { /* 都道府県を追加 */ + if( *t ){ + sprintf( bf, "%s,%s", t, getprf(mp->Code)); + } + else { + sprintf( bf, "%s", getprf(mp->Code)); + } + } + } + else { + if( strlen(mp->Code) == 6 ){ + if( isalpha((unsigned char)LastC(mp->Code)) ){ /* 町村コード */ + GetGun(bf, mp->Code); + strcat(bf, mp->QTH); + } + else { /* 政令指定都市 */ + strcpy(bf, mp->QTH); + } + } + else { /* 都道府県を追加 */ + sprintf( bf, "%s%s", getprf(mp->Code), mp->QTH); + } + } + bf[MLQTH] = 0; + m_QTH = bf; + return m_QTH.c_str(); + + +} + + +/*#$% +====================================================== + データの検索を行う(すべて) +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::FindAll(void) +{ + MMCG *mp; + int i; + + m_FindCnt = 0; + mp = m_bp; + for( i = 0; i < m_Cnt; i++, mp++ ){ + if( isfind(mp->Code) ){ + m_fp[m_FindCnt] = mp; + m_FindCnt++; + } + } +} + +/*#$% +====================================================== + 同一データが存在するか調べる +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CMMCG::isEnt(MMCG *mp) +{ + int i; + + for( i = 0; i < m_FindCnt; i++ ){ + if( m_fp[i] == mp ) return 1; + } + return 0; +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::FindQTH(LPSTR pKey) +{ + MMCG *mp; + int i; + int len, kj; + LPSTR t, p; + + kj = _mbsbtype((unsigned char *)pKey, 0) == _MBC_LEAD ? 1 : 0; + if( kj ) NormQth(pKey); + len = strlen(pKey); + m_FindCnt = 0; + mp = m_bp; + char bf[256]; + for( i = 0; i < m_Cnt; i++, mp++ ){ + if( isfind(mp->Code) ){ + if( kj ){ + if( strstr(mp->QTH, pKey) != NULL ){ + m_fp[m_FindCnt] = mp; + m_FindCnt++; + goto _nx; + } + } + strcpy(bf, mp->Key); + for( p = bf; *p; ){ + p = StrDlm(t, p, ','); + if( (!strncmp(t, pKey, len)) || (m_sinc && (strstr(t, pKey)!=NULL)) ){ + m_fp[m_FindCnt] = mp; + m_FindCnt++; + break; + } + } +_nx:; + } + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::FindNumb(LPSTR pKey) +{ + MMCG *mp; + int i; + int len; + + m_FindCnt = 0; + len = strlen(pKey); + mp = m_bp; + for( i = 0; i < m_Cnt; i++, mp++ ){ + if( (!strncmp(mp->Code, pKey, len)) || (m_sinc && (strstr(mp->Code, pKey)!=NULL)) ){ + m_fp[m_FindCnt] = mp; + m_FindCnt++; + } + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CMMCG::Find(LPSTR p) +{ + if( *p ){ + if( isdigit(*(LPUSTR)p) ){ + FindNumb(p); + } + else { + jstrupr(p); + if( chkspl(p) ) FindQTH(adjspl(p)); + } + } + else { + FindAll(); + } +} + +#if 0 +/*#$% +====================================================== + 定義領域を確保する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall allocdef(int blk) +{ + if( cseg == 0 ){ + if( (cseg=__malloc(blk))!=0 ){ /* メモリの確保 */ + return(NOERR); + } + return(ERR); + } + return(NOERR); +} + +/*#$% +====================================================== + 定義領域を開放する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall freedef(void) +{ + if( cseg ){ + __free(cseg); + cseg = 0; + } +} + +#define XW 60 +#define YW 16 +/*#$% +====================================================== + 検索データのメニュー表示をオープンする +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +VEWP *__fastcall opencc(void) +{ + cc.xw = XW-1; + cc.yw = YW-1; + cc.x = (crt.hmax-cc.xw+2)/2; + cc.y = (crt.vmax-cc.yw+2)/2; + cc.yt = cc.y; + cc.ye = cc.y + cc.yw; + cc.tb = cc.cy = 0; + cc.xe = cc.x + cc.xw - 1; + if( (cc.vp=openvew(cc.x, cc.y, cc.x+cc.xw, cc.ye, _menuwcol))!=NULL ){ + _dprintf( cc.x, cc.yt, " 検索>" ); + cc.x++; + cc.y++; +/* _dprintf( cc.x, cc.ye, "中止, 決定, <↓><↑>選択, クリア, エリア/ALL" );*/ + _dprintf( cc.x, cc.ye, "中止,決定,クリア,検索方法,エリア/ALL" ); + } + return(cc.vp); +} + +/*#$% +====================================================== + 検索データのメニュー表示をクローズする +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall closecc(void) +{ + if( cc.vp ){ + closevew(cc.vp); + cc.vp = NULL; + } +} + +/*#$% +====================================================== + 1行の表示を行う +------------------------------------------------------ + y : 表示位置 + tp: テーブル番号 +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall dspone(int y, int tp) +{ + CD cd; + int l; + uchar bf[60]; + +/*0123456789012345678901234567890123456789012345678901234567*/ +/*250119__ 大阪府__ 大阪市阿倍野区______ ABENO______________*/ +/*12345678 12345678 12345678901234567890 1234567890123456789*/ + + _fills(cc.x, y, cc.xe, y); + if( tp < cc.fn ){ + getdat(cc.ctbl[tp], &cd); + l = strlen(cd.code); + _dprintf(cc.x, y, "%-.8s", cd.code ); + _dprintf(cc.x+9, y, "%-.8s", getprf(cd.code)); + if( l == 6 ){ + if( isalpha(lastc(cd.code)) ){ /* 町村 */ + GetGun(bf, cd.code); + } + else { /* 制令 */ + bf[0] = 0; + } + strcat(bf, cd.qth); + _dprintf(cc.x+18, y, "%-.20s", bf ); + } + else { + _dprintf(cc.x+18, y, "%-.20s", cd.qth ); + } + _dprintf(cc.x+39, y, "%-.19s", cd.key ); + } +} + +/*#$% +====================================================== + 検索データの表示をする +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall dspcc(void) +{ + int y, cp; + CD cd; + + for( cp = cc.tb, y = cc.y; y < cc.ye; y++, cp++ ){ + dspone(y, cp); + } +} + +/*#$% +====================================================== + カーソルの表示 +------------------------------------------------------ + sw : 0-OFF, 1-ON +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall ecursor(int sw) +{ + int at; + + at = sw ? _menuccol : CRT_ATTR_NORMAL; + _afill(cc.x, cc.y + cc.cy, cc.xe, cc.y + cc.cy, at ); +} + +/*#$% +====================================================== + カーソルのアップ +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall cup(void) +{ + if( cc.cy ){ + cc.cy--; + } + else if( cc.tb ){ + cc.tb--; + _scrdwn(cc.x, cc.y, cc.xe, cc.ye-1); + dspone(cc.y, cc.tb); + } +} + +/*#$% +====================================================== + カーソルのダウン +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall cdown(void) +{ + if( (cc.tb + cc.cy) < (cc.fn - 1) ){ + if( cc.cy < (cc.yw - 2) ){ + cc.cy++; + } + else { + cc.tb++; + _scrup(cc.x, cc.y, cc.xe, cc.ye-1); + dspone(cc.ye-1, cc.tb+cc.cy); + } + } +} + +/*#$% +====================================================== + 指定位置へのSEEK +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall cdseek(int tp) +{ + if( tp >= cc.fn ) tp = cc.fn - 1; + if( tp < 0 ) tp = 0; + cc.tb = tp; + cc.cy = 0; + dspcc(); +} + +/*#$% +====================================================== + ページアップ +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall pup(void) +{ + CD cd; + int tp, m; + + tp = cc.tb + cc.cy; + getdat(cc.ctbl[tp], &cd); + m = atoin(cd.code, 2); + for( tp--; tp >= 0; tp-- ){ + getdat(cc.ctbl[tp], &cd); + if( m != atoin(cd.code, 2) ){ + cdseek(tp); + return; + } + } + cdseek(0); +} + +/*#$% +====================================================== + ページダウン +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall pdown(void) +{ + CD cd; + int tp, m; + + tp = cc.tb + cc.cy; + getdat(cc.ctbl[tp], &cd); + m = atoin(cd.code, 2); + for( tp++; tp < cc.fn; tp++ ){ + getdat(cc.ctbl[tp], &cd); + if( m != atoin(cd.code, 2) ){ + cdseek(tp); + return; + } + } + cdseek(32767); +} + +/*#$% +====================================================== + バッファ内容の表示 +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static void __fastcall dspbf(void) +{ + _dprintf(cc.x+5, cc.yt, "%-40s", kbf ); + _dprintf(cc.xe - 15, cc.yt, sinc ? "含み":"先頭"); + _dprintf(cc.xe - 10, cc.yt, (m_mask != -1) ? "%uエリア" : "ALL ", m_mask ); + _dprintf(cc.xe-4, cc.yt, "%4u", cc.fn ); +} + +/*#$% +====================================================== + MMCGの処理を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall mmcg(void) +{ + int c; + int xx; + + loaddat(); + if( nosel == 1 ){ + strcpy(kbf, _dspopt(optnmb, &cc.sd)); + findnosel(jstrupr(kbf)); + setdat(); + return; + } + if( opencc() == NULL ) return; + find1st(); + if( nosel == 2 ){ + if( cc.fn == 1 ) setdat(); + closecc(); + return; + } + dspcc(); + xx = strlen(kbf); + _cursor(ON); + while(1){ + dspbf(); + _locate(cc.x+5 + xx, cc.yt); + ecursor(ON); + c = _bgetch(); + ecursor(OFF); + switch(c){ + case K_RU: + pdown(); + break; + case K_RD: + pup(); + break; + case K_UP: + cup(); + break; + case K_DOWN: + cdown(); + break; + case ESC: + goto _ex; + case K_CR: + setdat(); + goto _ex; + case K_BS: + if( xx ){ + xx--; + if( xx && (_ischrtyp(kbf, xx)==2) ) xx--; + kbf[xx] = 0; + find(kbf); + dspcc(); + } + break; + case ' ': + kbf[0] = 0; + xx = 0; + findall(); + dspcc(); + break; + case K_F1: + sinc = sinc ? 0 : 1; + find(kbf); + dspcc(); + break; + case K_F2: + case K_HOME: + if( mask == -1 ){ + setmask(); + } + else { + mask = -1; + } + find(kbf); + dspcc(); + break; + default: + if( (c > 0x0020) && (c <= 0x00ff) ){ + if( xx < 40 ){ + kbf[xx] = c; + xx++; + kbf[xx] = 0; + if( _ischrtyp(kbf, xx-1) != 1 ){ + finds(kbf); + } + dspcc(); + } + } + break; + } + } +_ex:; + closecc(); +} + +/*#$% +====================================================== + データの検索を行う(すべて) +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findall(void) +{ + CD cd; + int cp, np; + + cc.tb = cc.cy = cc.fn = 0; + for( cp = 0; cp < cc.cwp; cp = np){ + np = getdat(cp, &cd); + if( isfind(cd.code) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + if( cc.fn >= CTMAX ) break; + } + } +} + +/*#$% +====================================================== + 同一データが存在するか調べる +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +int __fastcall isEnt(int n) +{ + int i; + + for( i = 0; i < cc.fn; i++ ){ + if( cc.ctbl[i] == n ){ + return(ON); + } + } + return(OFF); +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findqth(uchar *key) +{ + CD cd; + int cp, np; + int len, kj; + uchar *t, *p; + + if( (kj = iskanji(*key))!=0 ) NormQth(key); + len = strlen(key); + cc.tb = cc.cy = cc.fn = 0; + for( cp = 0; cp < cc.cwp; cp = np){ + np = getdat(cp, &cd); + if( isfind(cd.code) ){ + if( kj ){ + if( jstrstr(cd.qth, key) != NULL ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + goto _nx; + } + } + for( p = cd.key; *p; ){ + p = strdm(&t, p); + if( (!strncmp(t, key, len)) || (sinc && (strstr(t, key)!=NULL)) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + break; + } + } +_nx:; + if( cc.fn >= CTMAX ) break; + } + if( _bkbhit() ) break; + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findqths(uchar *key) +{ + CD cd; + int cp; + int len, fn, nn, f, kj; + uchar *t, *p; + + if( (kj = iskanji(*key))!=0 ){ + if( NormQth(key) ){ + findqth(key); + return; + } + } + len = strlen(key); + fn = cc.fn; + cc.tb = cc.cy = cc.fn = 0; + f = OFF; + if( lastc(key) == '\\' ){ + f = ON; + *lastp(key) = 0; + } + for( nn = 0; nn < fn; nn++){ + cp = cc.ctbl[nn]; + getdat(cp, &cd); + if( kj ){ + if( jstrstr(cd.qth, key) != NULL ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + goto _nx; + } + } + for( p = cd.key; *p; ){ + p = strdm(&t, p); + if( f ){ + if( (!strcmp(t, key)) || (sinc && (LastMatch(t,key))) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + break; + } + } + else { + if( (!strncmp(t, key, len)) || (sinc && (strstr(t, key)!=NULL)) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + break; + } + } + } +_nx:; + if( cc.fn >= CTMAX ) break; + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findnmb(uchar *key) +{ + CD cd; + int cp, np; + int len; + + cc.tb = cc.cy = cc.fn = 0; + len = strlen(key); + for( cp = 0; cp < cc.cwp; cp = np){ + np = getdat(cp, &cd); + if( (!strncmp(cd.code, key, len)) || (sinc && (strstr(cd.code, key)!=NULL)) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + if( cc.fn >= CTMAX ) break; + } + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findnmbs(uchar *key) +{ + CD cd; + int cp; + int len, fn, nn, f; + + fn = cc.fn; + cc.tb = cc.cy = cc.fn = 0; + f = OFF; + if( lastc(key) == '\\' ){ + f = ON; + *lastp(key) = 0; + } + len = strlen(key); + for( nn = 0; nn < fn; nn++){ + cp = cc.ctbl[nn]; + getdat(cp, &cd); + if( f ){ + if( (!strcmp(cd.code, key)) || (sinc && LastMatch(cd.code, key)) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + } + } + else { + if( (!strncmp(cd.code, key, len)) || (sinc && (strstr(cd.code, key)!=NULL)) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + } + } + } + if( f ) strcat(key, "\\"); +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall findnosel(uchar *key) +{ + CD cd; + int cp, np; + + cc.tb = cc.cy = cc.fn = 0; + for( cp = 0; cp < cc.cwp; cp = np){ + np = getdat(cp, &cd); + if( !strcmp(cd.code, key) ){ + cc.ctbl[cc.fn] = cp; + cc.fn++; + break; + } + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall find(uchar *p) +{ + dspbf(); + if( *p ){ + if( isdigit(*p) ){ + findnmb(p); + } + else { + jstrupr(p); + if( chkspl(p) ) findqth(adjspl(p)); + } + } + else { + findall(); + } +} + +/*#$% +====================================================== + データの検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall finds(uchar *p) +{ + dspbf(); + if( *p ){ + if( isdigit(*p) ){ + findnmbs(p); + if( !cc.fn ) findnmb(p); + } + else { + jstrupr(p); + if( chkspl(p) ) findqths(adjspl(p)); + } + } + else { + findall(); + } +} + +/*#$% +====================================================== + 最初の検索を行う +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall find1st(void) +{ + uchar *p; + uchar far *s; + + setmask(); + kbf[0] = 0; + if( setmac ){ + if( dtname[0] && (ishex(dtname)==NOERR) ){ + s = (uchar far *)htoln(dtname, -1); + for( p = kbf; *s; s++, p++ ){ + *p = *s; + } + *p = 0; + } + } + else { + p = _dspopt(optnmb, &cc.sd); + if( *p && isdigit(*p) ){ + strcpy(kbf, p); + } + else if( cc.sd.qth[0] ){ + strcpy(kbf, cc.sd.qth); + } + } + find(jstrupr(kbf)); +} + +/*#$% +====================================================== + データをセットする +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall setdat(void) +{ + CD cd; + uchar far *t; + uchar *p; + + if( cc.fn ){ + if( !dtname[0] ) return; + getdat(cc.ctbl[cc.tb+cc.cy], &cd); + if( setmac ){ + if( ishex(dtname)!=NOERR ) return; + t = (uchar far *)htoln(dtname,-1); + if( ocpy ){ + for( p = cd.code; *p; p++, t++ ){ + *t = *p; + } + *t = 0; + } + if( qcpy ){ + for( p = getqth(&cd); *p; p++, t++ ){ + *t = *p; + } + *t = 0; + } + } + else { + if( ocpy ) strcpy(_ptropt(optnmb, &cc.sd), cd.code); + if( qcpy ) strcpy(cc.sd.qth, getqth(&cd)); + savedat(); + } + } +} + +/*#$% +================================================================ + 1行のアスキーセーブの処理を行う +---------------------------------------------------------------- + fp : ファイルポインタ + sp : データのポインタ +---------------------------------------------------------------- + ERR +---------------------------------------------------------------- +================================================================ +*/ +void __fastcall _sputdat(uchar *bf, SD *sp) +{ + sinit(bf); + sputf("\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,", + _strydate(sp->year, sp->date), _strtimes(sp->btime), sp->call, sp->ur, sp->my, _strband(sp->band, sp->fq)); + sputf("\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,\042%s\042,", + _strmode(sp->mode), sp->pow, sp->name, sp->qth, sp->rem, sp->qsl ); + sputf("\042%s\042,\042%.1s\042,\042%.1s\042,\042%.1s\042,\042%u\042,", _strtime(sp->etime), &sp->send, &sp->recv, &sp->cq, sp->env); + sputf("\042%s\042,\042%s\042,", sp->opt1, sp->opt2 ); + sputf("\042%s\042,", _dspopt(2, sp)); + sputf("\042%s\042", _dspopt(3, sp)); +} + +/*#$% +================================================================ + 1行のアスキーセーブの処理を行う +---------------------------------------------------------------- + fp : ファイルポインタ + sp : データのポインタ +---------------------------------------------------------------- + ERR +---------------------------------------------------------------- +================================================================ +*/ +int __fastcall _fputdat(FILE *fp, SD *sp) +{ + _sputdat(hbf, sp); + fputs(hbf, fp); + fputs("\r\n", fp); + return(ferror(fp)); +} + +/*#$% +================================================================ + アスキーデータを登録する +---------------------------------------------------------------- + p : バッファのポインタ +---------------------------------------------------------------- + ERR +---------------------------------------------------------------- +================================================================ +*/ +int __fastcall _aputdat(uchar *p, SD *sp) +{ + uchar *t; + int y, m, d; + + _fillmem(sp, sizeof(SD), 0); + p = strdm(&t, p); /* DATE */ + if( sscanf(t, "%u.%u.%u", &y, &m, &d )!=3 ) return(ERR); + sp->year = y; + sp->date = (m * 100) + d; + p = strdm(&t, p); /* BGN */ + if( sscanf(t, "%u.%u", &d, &y) != 2 ){ + d = atoin(t, -1); + y = 0; + } + m = d / 100; + d = d % 100; + y /= 2; + sp->btime = (((m * 60) + d) * 30) + y; + p = strdm(&t, p); /* CALL */ + strcpy(sp->call, t); + p = strdm(&t, p); /* UR */ + strcpy(sp->ur, t); + p = strdm(&t, p); /* MY */ + strcpy(sp->my, t); + p = strdm(&t, p); /* BAND */ + sp->band = _bandno(&sp->fq, t); + p = strdm(&t, p); /* MODE */ + sp->mode = _modeno(t); + p = strdm(&t, p); /* POW */ + strcpy(sp->pow, t); + p = strdm(&t, p); /* NAME */ + strcpy(sp->name, t); + p = strdm(&t, p); /* QTH */ + strcpy(sp->qth, t); + p = strdm(&t, p); /* REM */ + strcpy(sp->rem, t); + p = strdm(&t, p); /* QSL */ + strcpy(sp->qsl, t); + p = strdm(&t, p); /* ETIME*/ + d = atoin(t, -1); + m = d / 100; + d = d % 100; + sp->etime = ((m * 60) + d) * 30; + p = strdm(&t, p); /* S */ + sp->send = *t; + p = strdm(&t, p); /* R */ + sp->recv = *t; + p = strdm(&t, p); /* M */ + sp->cq = *t; + p = strdm(&t, p); /* ENV */ + sp->env = atoin(t, -1); + p = strdm(&t, p); /* OPT1 */ + strcpy(sp->opt1, t); + p = strdm(&t, p); /* OPT2 */ + strcpy(sp->opt2, t); + p = strdm(&t, p); /* USR1 */ + if( *t ) strcpy(_ptropt(2,sp), t); + p = strdm(&t, p); /* USR2 */ + if( *t ) strcpy(_ptropt(3,sp), t); + return(NOERR); +} + +/*#$% +================================================================ + 引渡データを読み込む +---------------------------------------------------------------- +---------------------------------------------------------------- +---------------------------------------------------------------- +================================================================ +*/ +int __fastcall loaddat(void) +{ + int r; + FILE *fp; + + r = ERR; + _fillmem(&cc.sd, sizeof(SD), 0); + if( !dtname[0] ) return(NOERR); + if( setmac ) return(NOERR); + if( (fp = fopen(dtname, "rt"))!=NULL ){ + if( (fgets(hbf, 256, fp))!=NULL ){ + cliplf(hbf); + _aputdat(hbf, &cc.sd); + r = NOERR; + } + fclose(fp); + } + return(r); +} + +/*#$% +================================================================ + 指定のデータを書き込む +---------------------------------------------------------------- +---------------------------------------------------------------- +---------------------------------------------------------------- +================================================================ +*/ +void __fastcall savedat(void) +{ + FILE *fp; + + if( (fp = fopen(dtname, "wb"))!=NULL ){ + _fputdat(fp, &cc.sd); + fclose(fp); + } +} +#endif + diff --git a/Mmcg.h b/Mmcg.h new file mode 100644 index 0000000..eda5ca8 --- /dev/null +++ b/Mmcg.h @@ -0,0 +1,81 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef MmcgH +#define MmcgH +#include "LogFile.h" + +#ifndef LPCUSTR +typedef const unsigned char * LPCUSTR; +typedef unsigned char * LPUSTR; +#endif + +typedef struct { + LPSTR Code; + LPSTR QTH; + LPSTR Key; +}MMCG; + +class CMMCG +{ +private: + int m_Max; // 現在確保しているスロット数 + int m_Cnt; // 現在記憶しているスロット数 + MMCG *m_bp; // MMCGの配列 + + + char wbf[512]; + +public: + int m_mask; + int m_sinc; + int m_FindCnt; + MMCG **m_fp; + + AnsiString m_QTH; + char m_Call[MLCALL+1]; +private: + void __fastcall Free(void); + void __fastcall Alloc(int n); + LPSTR __fastcall adjspl(LPSTR p); + int __fastcall chkspl(LPCSTR p); + int __fastcall LastMatch(LPSTR t, LPSTR s); + int __fastcall NormQth(LPSTR p); + int __fastcall isfind(LPCSTR p); + int __fastcall _ischrtyp(char *p, int x); + LPCSTR __fastcall getprf(LPCSTR pCode); + void __fastcall GetGun(LPSTR t, LPCSTR pCode); + int __fastcall isEnt(MMCG *mp); + +public: + __fastcall CMMCG(); + __fastcall ~CMMCG(); + + void __fastcall LoadDef(LPCSTR pFileName); + void __fastcall FindAll(void); + void __fastcall FindQTH(LPSTR pKey); + void __fastcall FindNumb(LPSTR pKey); + void __fastcall Find(LPSTR p); + void __fastcall SetMask(void); + + LPCSTR __fastcall GetQTH(MMCG *mp); +}; + +extern CMMCG mmcg; +#endif diff --git a/MmcgDlg.cpp b/MmcgDlg.cpp new file mode 100644 index 0000000..f5dd8f0 --- /dev/null +++ b/MmcgDlg.cpp @@ -0,0 +1,245 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "MmcgDlg.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TMmcgDlgBox *MmcgDlgBox; +//--------------------------------------------------------------------- +__fastcall TMmcgDlgBox::TMmcgDlgBox(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + + if( sys.m_MsgEng ){ + SBInc->Caption = "String"; + SBMask->Caption = "Area"; + CancelBtn->Caption = "Cancel"; + } + + m_DisEvent = 0; +} +//--------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::UpdateCaption(void) +{ + char bf[256]; + + if( sys.m_MsgEng ){ + if( mmcg.m_Call[0] ){ + sprintf(bf, "MMCG [%s] Find: %d", mmcg.m_Call, mmcg.m_FindCnt); + } + else { + sprintf(bf, "MMCG Find: %d", mmcg.m_FindCnt); + } + } + else { + if( mmcg.m_Call[0] ){ + sprintf(bf, "MMCG [%s] 候補 : %d", mmcg.m_Call, mmcg.m_FindCnt); + } + else { + sprintf(bf, "MMCG 候補: %d", mmcg.m_FindCnt); + } + } + Caption = bf; +} + +//--------------------------------------------------------------------- +int __fastcall TMmcgDlgBox::Execute(AnsiString &call, AnsiString &qth, AnsiString &op) +{ + StrCopy(mmcg.m_Call, call.c_str(), MLCALL); + mmcg.SetMask(); + SBMask->Down = TRUE; + if( mmcg.m_mask == -1 ) SBMask->Enabled = FALSE; + + char bf[256]; + + bf[0] = 0; + if( isdigit(*op.c_str()) ){ + strcpy(bf, op.c_str()); + } + else if( !qth.IsEmpty() ){ + strcpy(bf, qth.c_str()); + } + m_DisEvent++; + EditYomi->Text = bf; + mmcg.Find(bf); + UpdateCaption(); + m_DisEvent--; + Grid->RowCount = mmcg.m_FindCnt ? mmcg.m_FindCnt + 1 : 2; + if( ShowModal() == IDOK ){ + int n = Grid->Row - 1; + if( (n >= 0)&&(n < mmcg.m_FindCnt) ){ + qth = mmcg.GetQTH(mmcg.m_fp[n]); + op = mmcg.m_fp[n]->Code; + return TRUE; + } + } + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::GridDrawCell(TObject *Sender, int Col, + int Row, TRect &Rect, TGridDrawState State) +{ + char bf[256]; + MMCG *mp; + + Grid->Canvas->FillRect(Rect); + int X = Rect.Left + 4; + int Y = Rect.Top + 2; + + if( Row ){ + Row--; + bf[0] = 0; + if( Row < mmcg.m_FindCnt ){ + mp = mmcg.m_fp[Row]; + } + else { + mp = NULL; + } + switch(Col){ + case 0: // Code + if( mp != NULL ) strcpy(bf, mp->Code); + break; + case 1: // QTH + if( mp != NULL ) strcpy(bf, mmcg.GetQTH(mp)); + break; + case 2: // Key + if( mp != NULL ) strcpy(bf, mp->Key); + break; + } + Grid->Canvas->TextOut(X, Y, bf); + } + else { // タイトル + LPCSTR _tt[]={ + "Code","QTH","Key", + }; + Grid->Canvas->TextOut(X, Y, _tt[Col]); + } + +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::EditYomiChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + char bf[256]; + + strcpy(bf, AnsiString(EditYomi->Text).c_str()); //JA7UDE 0428 + mmcg.Find(bf); + UpdateCaption(); + Grid->RowCount = mmcg.m_FindCnt ? mmcg.m_FindCnt + 1 : 2; + Grid->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::EditYomiKeyPress(TObject *Sender, char &Key) +{ + if( Key == 0x20 ){ + EditYomi->Text = ""; + Key = 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::EditYomiKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + switch(Key){ + case VK_UP: + if( Grid->Row >= 2 ) Grid->Row--; + Key = 0; + break; + case VK_DOWN: + if( Grid->Row < Grid->RowCount - 1 ) Grid->Row++; + Key = 0; + break; + case VK_HOME: + Grid->Row = 1; + Key = 0; + break; + case VK_END: + Grid->Row = Grid->RowCount - 1; + Key = 0; + break; + case VK_F1: + SBInc->Down = SBInc->Down ? 0 : 1; + SBIncClick(NULL); + Key = 0; + break; + case VK_F2: + SBMask->Down = SBMask->Down ? 0 : 1; + SBMaskClick(NULL); + Key = 0; + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::EditYomiKeyUp(TObject *Sender, WORD &Key, + TShiftState Shift) +{ + switch(Key){ + case VK_UP: + Key = 0; + break; + case VK_DOWN: + Key = 0; + break; + case VK_HOME: + Key = 0; + break; + case VK_END: + Key = 0; + break; + case VK_F1: + Key = 0; + break; + case VK_F2: + Key = 0; + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::SBMaskClick(TObject *Sender) +{ + if( SBMask->Down ){ + mmcg.SetMask(); + } + else { + mmcg.m_mask = -1; + } + EditYomiChange(NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TMmcgDlgBox::SBIncClick(TObject *Sender) +{ + if( SBInc->Down ){ + mmcg.m_sinc = 1; + } + else { + mmcg.m_sinc = 0; + } + EditYomiChange(NULL); +} +//--------------------------------------------------------------------------- + + diff --git a/MmcgDlg.dfm b/MmcgDlg.dfm new file mode 100644 index 0000000..ef39597 Binary files /dev/null and b/MmcgDlg.dfm differ diff --git a/MmcgDlg.h b/MmcgDlg.h new file mode 100644 index 0000000..30adaab --- /dev/null +++ b/MmcgDlg.h @@ -0,0 +1,76 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef MmcgDlgH +#define MmcgDlgH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +#include +//---------------------------------------------------------------------------- +#include "Mmcg.h" +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TMmcgDlgBox : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TStringGrid *Grid; + TEdit *EditYomi; + TSpeedButton *SBMask; + TSpeedButton *SBInc;void __fastcall EditYomiChange(TObject *Sender); + + + + + void __fastcall EditYomiKeyDown(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall EditYomiKeyUp(TObject *Sender, WORD &Key, TShiftState Shift); + void __fastcall SBMaskClick(TObject *Sender); + void __fastcall SBIncClick(TObject *Sender); + void __fastcall EditYomiKeyPress(TObject *Sender, char &Key); + void __fastcall GridDrawCell(TObject *Sender, int Col, int Row, + TRect &Rect, TGridDrawState State); +private: + int m_DisEvent; + + void __fastcall UpdateCaption(void); +public: + virtual __fastcall TMmcgDlgBox(TComponent* AOwner); + + int __fastcall Execute(AnsiString &call, AnsiString &qth, AnsiString &op); +}; +//---------------------------------------------------------------------------- +//extern TMmcgDlgBox *MmcgDlgBox; +//---------------------------------------------------------------------------- +#endif diff --git a/Mmvari English.ini b/Mmvari English.ini new file mode 100644 index 0000000..ff27ebe --- /dev/null +++ b/Mmvari English.ini @@ -0,0 +1,1341 @@ +[SoundCard] +Clock=11025.00 +TxOffset=0.00 +RxFIFO=12 +TxFIFO=6 +Source=0 +ID=SPDIF インターフェイス (USB Aud +IDTX=SPDIF インターフェイス (USB Aud + +[System] +Schema=3 +Priority=1 +FontName=Arial +FontCharset=0 + +[Window] +Fixed=0 +Left=227 +Top=261 +Width=1898 +Height=1154 +WindowState=0 +LogExtension=0 +RestoreSubChannels=0 + +[Folder] +Sound= +Log= +ExtLog= +Text= + +[PTT] +Name=COM1 +Lock=1 +OUTFSK=0 +INVFSK=0 + +[TX] +LoopBack=0 +AutoCR=1 +Carrier=1662 +NET=1 +Mode=bpsk +Speed=31.25 +ModGain=16384 +ConvAlpha=1 +RttyWordOut=1 +MFSK_TYPE=0 +MFSK_CENTER=0 +SendSingleTone=1 + +[FFT] +Width=3000 +Smooth=2 +Type=2 + +[Spec] +Col1=0 +Col2=65280 +Col3=16777215 +Col4=8421504 +Col5=16776960 +Col6=16711680 + +[WF] +Col1=0 +Lvl1=28 +Col2=16776960 +Lvl2=100 +Col3=16777215 +Lvl3=168 +Col4=255 +Lvl4=192 +Col5=16776960 +Lvl5=220 +Col6=16711680 +Lvl6=240 +Col7=65535 +Col8=33023 +Col9=8388863 +Col10=255 +Col11=255 +Col12=255 + +[View] +DrawType=0 +WaveForm=0 +RigFreqScale=0 +ScaleDetails=1 +WaterAGC=0 + +[RXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +Color5=14737632 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +StatusUTC=0 +MouseWheel=1 +ShowCtrl=0 + +[TXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 + +[RX] +Carrier=1662 +BPF=0 +AFC=1 +ATC=1 +SQLevel=300 +AFCWidth=50 +AFCLevel=12 +HPF=0 +ATCLevel=15 +ATCSpeed=0 +ATCLimit=25000 +SWL_TS=0 +NotchFreq=1750 +PlayBack=1 +PlayBackSpeed=5 +MFSK_SQ_METRIC=0 +RTTY_FFT=0 + +[Log] +Name= + +[LogSet] +TimeZone=73 +DateType=0 +UpperName=0 +UpperQTH=0 +UpperREM=0 +UpperQSL=0 +DefMyRST=0 +CopyFreq=1 +CopyHis=0 +CopyName=1 +CopyQTH=1 +CopyREM=0 +CopyQSL=0 +CopyREMB4=0 +CheckBand=1 +AutoSave=1 +THRTTY=RTY +THSSTV=STV +THGMSK=MSK +THTZ=0 +ClipRSTADIF=1 +Backup=1 +TH5Fields=3,3,7,4,12,28,54 +LogLink=1 +LinkPoll=0 +LinkPTT=0 + +[MMLink] +Name= + +[RADIO] +PortName=NONE +BaudRate=4800 +BitLen=1 +Stop=1 +Parity=0 +flwXON=0 +flwCTS=0 +usePTT=0 +ByteWait=0 +Cmdxx=0 +CmdInit= +CmdRx=\$000000000F +CmdTx=\$000000010F\w10 +FileGNR= +OpenGNR=0 +PollType=0 +PollInterval=8 +PollOffset=3 + +[Macro] +CallSign= +ButtonRow=3 +ButtonPos=0 +CWAS="<%DisableCR>\r\n#if !IsTX\r\n<%AutoNET><%AutoReturn>\r\n#if ValPage!=4\r\n<%Page=4>\r\n#else\r\n<%Page=3>\r\n#endif\r\n<%ClearTXW>\r\n#endif\r\n<%TX><%CWID=@><%RX><%EOF>\r\n" +OnTimer="" +OnPTT="" +OnQSO="" +OnFind="" +OnBand="" +OnStart="" +OnExit="" +OnMode="" +OnSpeed="" +OnClick="" +OnFFTScale="" +Expand=0 + +[MB1] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB2] +Name=CQ +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB3] +Name=CQ2 +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB4] +Name=1x1 +Text="<%NETON><%TX><%HisCall> de <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB5] +Name=2x2 +Text="<%NETON><%TX><%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB6] +Name=RRR +Text="\r\nRRR <%HisCall> de <%MyCall>\r\n--- <%VARITYPE> ---\r\n" +Color=0 +Style=0 + +[MB7] +Name=BTU +Text="BTU <%HisCall> de <%MyCall> KN\r\n<%RX>" +Color=0 +Style=0 + +[MB8] +Name=M8 +Text="" +Color=0 +Style=0 + +[MB9] +Name=M9 +Text="" +Color=0 +Style=0 + +[MB10] +Name=M10 +Text="" +Color=0 +Style=0 + +[MB11] +Name=M11 +Text="" +Color=0 +Style=0 + +[MB12] +Name=M12 +Text="" +Color=0 +Style=0 + +[MB13] +Name=CWID +Text="<%TX><%CWID=DE <%MyCall>><%RX><%EOF>" +Color=0 +Style=4 + +[MB14] +Name=TU SK +Text="<%TX><%CWID=TU:><%RX><%EOF>" +Color=0 +Style=4 + +[MB15] +Name=M15 +Text="" +Color=0 +Style=0 + +[MB16] +Name=0x2 - 2x4 +Text="<%DisableCR>\r\n#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4>\r\n#if ValMenu\r\n#define\t_His\t<%Format=%c,<%Input$>>\r\n#define\t_My\t<%Format=%d,<%Find$=x,<%Input$>>>\r\n<%TX><%RX>\r\n#if !Is1stCR\r\n<%CR>\r\n#endif\r\n#if IsCall\r\n<%RepeatText=_His,<%HisCall> >\r\n#endif\r\nde\r\n<%RepeatText=_My, <%MyCall>>\r\n pse K<%CR>\r\n#endif\r\n<%EOF>" +Color=0 +Style=0 + +[MB17] +Name=M17 +Text="" +Color=0 +Style=0 + +[MB18] +Name=M18 +Text="" +Color=0 +Style=0 + +[MB19] +Name=M19 +Text="" +Color=0 +Style=0 + +[MB20] +Name=M20 +Text="" +Color=0 +Style=0 + +[MB21] +Name=M21 +Text="" +Color=0 +Style=0 + +[MB22] +Name=M22 +Text="" +Color=0 +Style=0 + +[MB23] +Name=M23 +Text="" +Color=0 +Style=0 + +[MB24] +Name=M24 +Text="" +Color=0 +Style=0 + +[MB25] +Name=M25 +Text="" +Color=0 +Style=0 + +[MB26] +Name=M26 +Text="" +Color=0 +Style=0 + +[MB27] +Name=M27 +Text="" +Color=0 +Style=0 + +[MB28] +Name=M28 +Text="" +Color=0 +Style=0 + +[MB29] +Name=M29 +Text="" +Color=0 +Style=0 + +[MB30] +Name=M30 +Text="" +Color=0 +Style=0 + +[MB31] +Name=M31 +Text="" +Color=0 +Style=0 + +[MB32] +Name=M32 +Text="" +Color=0 +Style=0 + +[MB33] +Name=M33 +Text="" +Color=0 +Style=0 + +[MB34] +Name=M34 +Text="" +Color=0 +Style=0 + +[MB35] +Name=M35 +Text="" +Color=0 +Style=0 + +[MB36] +Name=M36 +Text="" +Color=0 +Style=0 + +[MB37] +Name=M37 +Text="" +Color=0 +Style=0 + +[MB38] +Name=M38 +Text="" +Color=0 +Style=0 + +[MB39] +Name=M39 +Text="" +Color=0 +Style=0 + +[MB40] +Name=M40 +Text="" +Color=0 +Style=0 + +[MB41] +Name=M41 +Text="" +Color=0 +Style=0 + +[MB42] +Name=M42 +Text="" +Color=0 +Style=0 + +[MB43] +Name=M43 +Text="" +Color=0 +Style=0 + +[MB44] +Name=M44 +Text="" +Color=0 +Style=0 + +[MB45] +Name=M45 +Text="" +Color=0 +Style=0 + +[MB46] +Name=M46 +Text="" +Color=0 +Style=0 + +[MB47] +Name=M47 +Text="" +Color=0 +Style=0 + +[MB48] +Name=M48 +Text="" +Color=0 +Style=0 + +[MB49] +Name=M49 +Text="" +Color=0 +Style=0 + +[MB50] +Name=M50 +Text="" +Color=0 +Style=0 + +[MB51] +Name=M51 +Text="" +Color=0 +Style=0 + +[MB52] +Name=M52 +Text="" +Color=0 +Style=0 + +[MB53] +Name=M53 +Text="" +Color=0 +Style=0 + +[MB54] +Name=M54 +Text="" +Color=0 +Style=0 + +[MB55] +Name=M55 +Text="" +Color=0 +Style=0 + +[MB56] +Name=M56 +Text="" +Color=0 +Style=0 + +[MB57] +Name=M57 +Text="" +Color=0 +Style=0 + +[MB58] +Name=M58 +Text="" +Color=0 +Style=0 + +[MB59] +Name=M59 +Text="" +Color=0 +Style=0 + +[MB60] +Name=M60 +Text="" +Color=0 +Style=0 + +[MB61] +Name=M61 +Text="" +Color=0 +Style=0 + +[MB62] +Name=M62 +Text="" +Color=0 +Style=0 + +[MB63] +Name=M63 +Text="" +Color=0 +Style=0 + +[MB64] +Name=M64 +Text="" +Color=0 +Style=0 + +[MB65] +Name=M65 +Text="" +Color=0 +Style=0 + +[MB66] +Name=M66 +Text="" +Color=0 +Style=0 + +[MB67] +Name=M67 +Text="" +Color=0 +Style=0 + +[MB68] +Name=M68 +Text="" +Color=0 +Style=0 + +[MB69] +Name=M69 +Text="" +Color=0 +Style=0 + +[MB70] +Name=M70 +Text="" +Color=0 +Style=0 + +[MB71] +Name=M71 +Text="" +Color=0 +Style=0 + +[MB72] +Name=M72 +Text="" +Color=0 +Style=0 + +[MB73] +Name=M73 +Text="" +Color=0 +Style=0 + +[MB74] +Name=M74 +Text="" +Color=0 +Style=0 + +[MB75] +Name=M75 +Text="" +Color=0 +Style=0 + +[MB76] +Name=M76 +Text="" +Color=0 +Style=0 + +[MB77] +Name=M77 +Text="" +Color=0 +Style=0 + +[MB78] +Name=M78 +Text="" +Color=0 +Style=0 + +[MB79] +Name=M79 +Text="" +Color=0 +Style=0 + +[MB80] +Name=M80 +Text="" +Color=0 +Style=0 + +[MB81] +Name=M81 +Text="" +Color=0 +Style=0 + +[MB82] +Name=M82 +Text="" +Color=0 +Style=0 + +[MB83] +Name=M83 +Text="" +Color=0 +Style=0 + +[MB84] +Name=M84 +Text="" +Color=0 +Style=0 + +[MB85] +Name=M85 +Text="" +Color=0 +Style=0 + +[MB86] +Name=M86 +Text="" +Color=0 +Style=0 + +[MB87] +Name=M87 +Text="" +Color=0 +Style=0 + +[MB88] +Name=M88 +Text="" +Color=0 +Style=0 + +[MB89] +Name=M89 +Text="" +Color=0 +Style=0 + +[MB90] +Name=M90 +Text="" +Color=0 +Style=0 + +[MB91] +Name=M91 +Text="" +Color=0 +Style=0 + +[MB92] +Name=M92 +Text="" +Color=0 +Style=0 + +[MB93] +Name=M93 +Text="" +Color=0 +Style=0 + +[MB94] +Name=M94 +Text="" +Color=0 +Style=0 + +[MB95] +Name=M95 +Text="" +Color=0 +Style=0 + +[MB96] +Name=M96 +Text="" +Color=0 +Style=0 + +[MB97] +Name=M97 +Text="" +Color=0 +Style=0 + +[MB98] +Name=M98 +Text="" +Color=0 +Style=0 + +[MB99] +Name=M99 +Text="" +Color=0 +Style=0 + +[MB100] +Name=M100 +Text="" +Color=0 +Style=0 + +[MB101] +Name=M101 +Text="" +Color=0 +Style=0 + +[MB102] +Name=M102 +Text="" +Color=0 +Style=0 + +[MB103] +Name=M103 +Text="" +Color=0 +Style=0 + +[MB104] +Name=M104 +Text="" +Color=0 +Style=0 + +[MB105] +Name=M105 +Text="" +Color=0 +Style=0 + +[MB106] +Name=M106 +Text="" +Color=0 +Style=0 + +[MB107] +Name=M107 +Text="" +Color=0 +Style=0 + +[MB108] +Name=M108 +Text="" +Color=0 +Style=0 + +[MB109] +Name=M109 +Text="" +Color=0 +Style=0 + +[MB110] +Name=M110 +Text="" +Color=0 +Style=0 + +[MB111] +Name=M111 +Text="" +Color=0 +Style=0 + +[MB112] +Name=M112 +Text="" +Color=0 +Style=0 + +[MB113] +Name=M113 +Text="" +Color=0 +Style=0 + +[MB114] +Name=M114 +Text="" +Color=0 +Style=0 + +[MB115] +Name=M115 +Text="" +Color=0 +Style=0 + +[MB116] +Name=M116 +Text="" +Color=0 +Style=0 + +[MB117] +Name=M117 +Text="" +Color=0 +Style=0 + +[MB118] +Name=M118 +Text="" +Color=0 +Style=0 + +[MB119] +Name=M119 +Text="" +Color=0 +Style=0 + +[MB120] +Name=M120 +Text="" +Color=0 +Style=0 + +[MB121] +Name=M121 +Text="" +Color=0 +Style=0 + +[MB122] +Name=M122 +Text="" +Color=0 +Style=0 + +[MB123] +Name=M123 +Text="" +Color=0 +Style=0 + +[MB124] +Name=M124 +Text="" +Color=0 +Style=0 + +[MB125] +Name=M125 +Text="" +Color=0 +Style=0 + +[MB126] +Name=M126 +Text="" +Color=0 +Style=0 + +[MB127] +Name=M127 +Text="" +Color=0 +Style=0 + +[MB128] +Name=M128 +Text="" +Color=0 +Style=0 + +[MB129] +Name=M129 +Text="" +Color=0 +Style=0 + +[MB130] +Name=M130 +Text="" +Color=0 +Style=0 + +[MB131] +Name=M131 +Text="" +Color=0 +Style=0 + +[MB132] +Name=M132 +Text="" +Color=0 +Style=0 + +[MB133] +Name=M133 +Text="" +Color=0 +Style=0 + +[MB134] +Name=M134 +Text="" +Color=0 +Style=0 + +[MB135] +Name=M135 +Text="" +Color=0 +Style=0 + +[MB136] +Name=M136 +Text="" +Color=0 +Style=0 + +[MB137] +Name=M137 +Text="" +Color=0 +Style=0 + +[MB138] +Name=M138 +Text="" +Color=0 +Style=0 + +[MB139] +Name=M139 +Text="" +Color=0 +Style=0 + +[MB140] +Name=M140 +Text="" +Color=0 +Style=0 + +[MB141] +Name=M141 +Text="" +Color=0 +Style=0 + +[MB142] +Name=M142 +Text="" +Color=0 +Style=0 + +[MB143] +Name=M143 +Text="" +Color=0 +Style=0 + +[MB144] +Name=M144 +Text="" +Color=0 +Style=0 + +[MB145] +Name=M145 +Text="" +Color=0 +Style=0 + +[MB146] +Name=M146 +Text="" +Color=0 +Style=0 + +[MB147] +Name=M147 +Text="" +Color=0 +Style=0 + +[MB148] +Name=M148 +Text="" +Color=0 +Style=0 + +[MB149] +Name=M149 +Text="" +Color=0 +Style=0 + +[MB150] +Name=M150 +Text="" +Color=0 +Style=0 + +[MB151] +Name=M151 +Text="" +Color=0 +Style=0 + +[MB152] +Name=M152 +Text="" +Color=0 +Style=0 + +[MB153] +Name=M153 +Text="" +Color=0 +Style=0 + +[MB154] +Name=M154 +Text="" +Color=0 +Style=0 + +[MB155] +Name=M155 +Text="" +Color=0 +Style=0 + +[MB156] +Name=M156 +Text="" +Color=0 +Style=0 + +[MB157] +Name=M157 +Text="" +Color=0 +Style=0 + +[MB158] +Name=M158 +Text="" +Color=0 +Style=0 + +[MB159] +Name=M159 +Text="" +Color=0 +Style=0 + +[MB160] +Name=M160 +Text="" +Color=0 +Style=0 + +[DefKey] +K1=123 +K2=19 + +[Channel1] +Show=0 +Mode=rtty-L +Carrier=943 +WaterWidth=400 +Left=2495 +Top=890 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel2] +Show=0 +Mode=rtty-L +Carrier=2479 +WaterWidth=400 +Left=1967 +Top=888 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel3] +Show=0 +Mode=GMSK +Carrier=1450 +WaterWidth=400 +Left=58 +Top=58 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel4] +Show=0 +Mode=GMSK +Carrier=2050 +WaterWidth=400 +Left=74 +Top=74 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel5] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=90 +Top=90 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel6] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=106 +Top=106 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel7] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=122 +Top=122 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel8] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=138 +Top=138 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Misc] +ShowLangMsg=0 + +[DEBUG] +testSN=13 +testName=eproject.txt +testGain=0 +testCarrier1=1750 +testCarrier2=0 +testDB2=0 +testQSBTime=8000 +testQSBDB=0 +test500=0 +testPhase=0 +testClockErr=0 + +[RadioMenu] +Menus=4 +Cap1=7.030 LSB (FT847) +Cmd1=\$0070300001\w10\$0000000007\w10 +Cap2=14.073 LSB (FT847) +Cmd2=\$0140730001\w10\$0000000007\w10 +Cap3=21.073 LSB (FT847) +Cmd3=\$0210730001\w10\$0000000007\w10 +Cap4=28.073 LSB (FT847) +Cmd4=\$0280730001\w10\$0000000007\w10 + diff --git a/Mmvari Japanese.ini b/Mmvari Japanese.ini new file mode 100644 index 0000000..8180e4f --- /dev/null +++ b/Mmvari Japanese.ini @@ -0,0 +1,1341 @@ +[SoundCard] +Clock=11025.00 +TxOffset=0.00 +RxFIFO=12 +TxFIFO=6 +Source=0 +ID=SPDIF インターフェイス (USB Aud +IDTX=SPDIF インターフェイス (USB Aud + +[System] +Schema=3 +Priority=1 +FontName=MS Pゴシック +FontCharset=128 + +[Window] +Fixed=0 +Left=227 +Top=261 +Width=1898 +Height=1154 +WindowState=0 +LogExtension=0 +RestoreSubChannels=0 + +[Folder] +Sound= +Log= +ExtLog= +Text= + +[PTT] +Name=COM1 +Lock=1 +OUTFSK=0 +INVFSK=0 + +[TX] +LoopBack=0 +AutoCR=1 +Carrier=1662 +NET=1 +Mode=bpsk +Speed=31.25 +ModGain=16384 +ConvAlpha=1 +RttyWordOut=1 +MFSK_TYPE=0 +MFSK_CENTER=0 +SendSingleTone=1 + +[FFT] +Width=3000 +Smooth=2 +Type=2 + +[Spec] +Col1=0 +Col2=65280 +Col3=16777215 +Col4=8421504 +Col5=16776960 +Col6=16711680 + +[WF] +Col1=0 +Lvl1=28 +Col2=16776960 +Lvl2=100 +Col3=16777215 +Lvl3=168 +Col4=255 +Lvl4=192 +Col5=16776960 +Lvl5=220 +Col6=16711680 +Lvl6=240 +Col7=65535 +Col8=33023 +Col9=8388863 +Col10=255 +Col11=255 +Col12=255 + +[View] +DrawType=0 +WaveForm=0 +RigFreqScale=0 +ScaleDetails=1 +WaterAGC=0 + +[RXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +Color5=14737632 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +StatusUTC=0 +MouseWheel=1 +ShowCtrl=0 + +[TXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 + +[RX] +Carrier=1662 +BPF=0 +AFC=1 +ATC=1 +SQLevel=300 +AFCWidth=50 +AFCLevel=12 +HPF=0 +ATCLevel=15 +ATCSpeed=0 +ATCLimit=25000 +SWL_TS=0 +NotchFreq=1750 +PlayBack=1 +PlayBackSpeed=5 +MFSK_SQ_METRIC=0 +RTTY_FFT=0 + +[Log] +Name= + +[LogSet] +TimeZone=73 +DateType=0 +UpperName=0 +UpperQTH=0 +UpperREM=0 +UpperQSL=0 +DefMyRST=0 +CopyFreq=1 +CopyHis=0 +CopyName=1 +CopyQTH=1 +CopyREM=0 +CopyQSL=0 +CopyREMB4=0 +CheckBand=1 +AutoSave=1 +THRTTY=RTY +THSSTV=STV +THGMSK=MSK +THTZ=0 +ClipRSTADIF=1 +Backup=1 +TH5Fields=3,3,7,4,12,28,54 +LogLink=1 +LinkPoll=0 +LinkPTT=0 + +[MMLink] +Name= + +[RADIO] +PortName=NONE +BaudRate=4800 +BitLen=1 +Stop=1 +Parity=0 +flwXON=0 +flwCTS=0 +usePTT=0 +ByteWait=0 +Cmdxx=0 +CmdInit= +CmdRx=\$000000000F +CmdTx=\$000000010F\w10 +FileGNR= +OpenGNR=0 +PollType=0 +PollInterval=8 +PollOffset=3 + +[Macro] +CallSign= +ButtonRow=3 +ButtonPos=0 +CWAS="<%DisableCR>\r\n#if !IsTX\r\n<%AutoNET><%AutoReturn>\r\n#if ValPage!=4\r\n<%Page=4>\r\n#else\r\n<%Page=3>\r\n#endif\r\n<%ClearTXW>\r\n#endif\r\n<%TX><%CWID=@><%RX><%EOF>\r\n" +OnTimer="" +OnPTT="" +OnQSO="" +OnFind="" +OnBand="" +OnStart="" +OnExit="" +OnMode="" +OnSpeed="" +OnClick="" +OnFFTScale="" +Expand=0 + +[MB1] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB2] +Name=CQ +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB3] +Name=CQ2 +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB4] +Name=1x1 +Text="<%NETON><%TX><%HisCall> de <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB5] +Name=2x2 +Text="<%NETON><%TX><%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB6] +Name=RRR +Text="\r\nRRR <%HisCall> de <%MyCall>\r\n--- <%VARITYPE> ---\r\n" +Color=0 +Style=0 + +[MB7] +Name=BTU +Text="BTU <%HisCall> de <%MyCall> KN\r\n<%RX>" +Color=0 +Style=0 + +[MB8] +Name=M8 +Text="" +Color=0 +Style=0 + +[MB9] +Name=M9 +Text="" +Color=0 +Style=0 + +[MB10] +Name=M10 +Text="" +Color=0 +Style=0 + +[MB11] +Name=M11 +Text="" +Color=0 +Style=0 + +[MB12] +Name=M12 +Text="" +Color=0 +Style=0 + +[MB13] +Name=CWID +Text="<%TX><%CWID=DE <%MyCall>><%RX><%EOF>" +Color=0 +Style=4 + +[MB14] +Name=TU SK +Text="<%TX><%CWID=TU:><%RX><%EOF>" +Color=0 +Style=4 + +[MB15] +Name=M15 +Text="" +Color=0 +Style=0 + +[MB16] +Name=0x2 - 2x4 +Text="<%DisableCR>\r\n#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4>\r\n#if ValMenu\r\n#define\t_His\t<%Format=%c,<%Input$>>\r\n#define\t_My\t<%Format=%d,<%Find$=x,<%Input$>>>\r\n<%TX><%RX>\r\n#if !Is1stCR\r\n<%CR>\r\n#endif\r\n#if IsCall\r\n<%RepeatText=_His,<%HisCall> >\r\n#endif\r\nde\r\n<%RepeatText=_My, <%MyCall>>\r\n pse K<%CR>\r\n#endif\r\n<%EOF>" +Color=0 +Style=0 + +[MB17] +Name=M17 +Text="" +Color=0 +Style=0 + +[MB18] +Name=M18 +Text="" +Color=0 +Style=0 + +[MB19] +Name=M19 +Text="" +Color=0 +Style=0 + +[MB20] +Name=M20 +Text="" +Color=0 +Style=0 + +[MB21] +Name=M21 +Text="" +Color=0 +Style=0 + +[MB22] +Name=M22 +Text="" +Color=0 +Style=0 + +[MB23] +Name=M23 +Text="" +Color=0 +Style=0 + +[MB24] +Name=M24 +Text="" +Color=0 +Style=0 + +[MB25] +Name=M25 +Text="" +Color=0 +Style=0 + +[MB26] +Name=M26 +Text="" +Color=0 +Style=0 + +[MB27] +Name=M27 +Text="" +Color=0 +Style=0 + +[MB28] +Name=M28 +Text="" +Color=0 +Style=0 + +[MB29] +Name=M29 +Text="" +Color=0 +Style=0 + +[MB30] +Name=M30 +Text="" +Color=0 +Style=0 + +[MB31] +Name=M31 +Text="" +Color=0 +Style=0 + +[MB32] +Name=M32 +Text="" +Color=0 +Style=0 + +[MB33] +Name=M33 +Text="" +Color=0 +Style=0 + +[MB34] +Name=M34 +Text="" +Color=0 +Style=0 + +[MB35] +Name=M35 +Text="" +Color=0 +Style=0 + +[MB36] +Name=M36 +Text="" +Color=0 +Style=0 + +[MB37] +Name=M37 +Text="" +Color=0 +Style=0 + +[MB38] +Name=M38 +Text="" +Color=0 +Style=0 + +[MB39] +Name=M39 +Text="" +Color=0 +Style=0 + +[MB40] +Name=M40 +Text="" +Color=0 +Style=0 + +[MB41] +Name=M41 +Text="" +Color=0 +Style=0 + +[MB42] +Name=M42 +Text="" +Color=0 +Style=0 + +[MB43] +Name=M43 +Text="" +Color=0 +Style=0 + +[MB44] +Name=M44 +Text="" +Color=0 +Style=0 + +[MB45] +Name=M45 +Text="" +Color=0 +Style=0 + +[MB46] +Name=M46 +Text="" +Color=0 +Style=0 + +[MB47] +Name=M47 +Text="" +Color=0 +Style=0 + +[MB48] +Name=M48 +Text="" +Color=0 +Style=0 + +[MB49] +Name=M49 +Text="" +Color=0 +Style=0 + +[MB50] +Name=M50 +Text="" +Color=0 +Style=0 + +[MB51] +Name=M51 +Text="" +Color=0 +Style=0 + +[MB52] +Name=M52 +Text="" +Color=0 +Style=0 + +[MB53] +Name=M53 +Text="" +Color=0 +Style=0 + +[MB54] +Name=M54 +Text="" +Color=0 +Style=0 + +[MB55] +Name=M55 +Text="" +Color=0 +Style=0 + +[MB56] +Name=M56 +Text="" +Color=0 +Style=0 + +[MB57] +Name=M57 +Text="" +Color=0 +Style=0 + +[MB58] +Name=M58 +Text="" +Color=0 +Style=0 + +[MB59] +Name=M59 +Text="" +Color=0 +Style=0 + +[MB60] +Name=M60 +Text="" +Color=0 +Style=0 + +[MB61] +Name=M61 +Text="" +Color=0 +Style=0 + +[MB62] +Name=M62 +Text="" +Color=0 +Style=0 + +[MB63] +Name=M63 +Text="" +Color=0 +Style=0 + +[MB64] +Name=M64 +Text="" +Color=0 +Style=0 + +[MB65] +Name=M65 +Text="" +Color=0 +Style=0 + +[MB66] +Name=M66 +Text="" +Color=0 +Style=0 + +[MB67] +Name=M67 +Text="" +Color=0 +Style=0 + +[MB68] +Name=M68 +Text="" +Color=0 +Style=0 + +[MB69] +Name=M69 +Text="" +Color=0 +Style=0 + +[MB70] +Name=M70 +Text="" +Color=0 +Style=0 + +[MB71] +Name=M71 +Text="" +Color=0 +Style=0 + +[MB72] +Name=M72 +Text="" +Color=0 +Style=0 + +[MB73] +Name=M73 +Text="" +Color=0 +Style=0 + +[MB74] +Name=M74 +Text="" +Color=0 +Style=0 + +[MB75] +Name=M75 +Text="" +Color=0 +Style=0 + +[MB76] +Name=M76 +Text="" +Color=0 +Style=0 + +[MB77] +Name=M77 +Text="" +Color=0 +Style=0 + +[MB78] +Name=M78 +Text="" +Color=0 +Style=0 + +[MB79] +Name=M79 +Text="" +Color=0 +Style=0 + +[MB80] +Name=M80 +Text="" +Color=0 +Style=0 + +[MB81] +Name=M81 +Text="" +Color=0 +Style=0 + +[MB82] +Name=M82 +Text="" +Color=0 +Style=0 + +[MB83] +Name=M83 +Text="" +Color=0 +Style=0 + +[MB84] +Name=M84 +Text="" +Color=0 +Style=0 + +[MB85] +Name=M85 +Text="" +Color=0 +Style=0 + +[MB86] +Name=M86 +Text="" +Color=0 +Style=0 + +[MB87] +Name=M87 +Text="" +Color=0 +Style=0 + +[MB88] +Name=M88 +Text="" +Color=0 +Style=0 + +[MB89] +Name=M89 +Text="" +Color=0 +Style=0 + +[MB90] +Name=M90 +Text="" +Color=0 +Style=0 + +[MB91] +Name=M91 +Text="" +Color=0 +Style=0 + +[MB92] +Name=M92 +Text="" +Color=0 +Style=0 + +[MB93] +Name=M93 +Text="" +Color=0 +Style=0 + +[MB94] +Name=M94 +Text="" +Color=0 +Style=0 + +[MB95] +Name=M95 +Text="" +Color=0 +Style=0 + +[MB96] +Name=M96 +Text="" +Color=0 +Style=0 + +[MB97] +Name=M97 +Text="" +Color=0 +Style=0 + +[MB98] +Name=M98 +Text="" +Color=0 +Style=0 + +[MB99] +Name=M99 +Text="" +Color=0 +Style=0 + +[MB100] +Name=M100 +Text="" +Color=0 +Style=0 + +[MB101] +Name=M101 +Text="" +Color=0 +Style=0 + +[MB102] +Name=M102 +Text="" +Color=0 +Style=0 + +[MB103] +Name=M103 +Text="" +Color=0 +Style=0 + +[MB104] +Name=M104 +Text="" +Color=0 +Style=0 + +[MB105] +Name=M105 +Text="" +Color=0 +Style=0 + +[MB106] +Name=M106 +Text="" +Color=0 +Style=0 + +[MB107] +Name=M107 +Text="" +Color=0 +Style=0 + +[MB108] +Name=M108 +Text="" +Color=0 +Style=0 + +[MB109] +Name=M109 +Text="" +Color=0 +Style=0 + +[MB110] +Name=M110 +Text="" +Color=0 +Style=0 + +[MB111] +Name=M111 +Text="" +Color=0 +Style=0 + +[MB112] +Name=M112 +Text="" +Color=0 +Style=0 + +[MB113] +Name=M113 +Text="" +Color=0 +Style=0 + +[MB114] +Name=M114 +Text="" +Color=0 +Style=0 + +[MB115] +Name=M115 +Text="" +Color=0 +Style=0 + +[MB116] +Name=M116 +Text="" +Color=0 +Style=0 + +[MB117] +Name=M117 +Text="" +Color=0 +Style=0 + +[MB118] +Name=M118 +Text="" +Color=0 +Style=0 + +[MB119] +Name=M119 +Text="" +Color=0 +Style=0 + +[MB120] +Name=M120 +Text="" +Color=0 +Style=0 + +[MB121] +Name=M121 +Text="" +Color=0 +Style=0 + +[MB122] +Name=M122 +Text="" +Color=0 +Style=0 + +[MB123] +Name=M123 +Text="" +Color=0 +Style=0 + +[MB124] +Name=M124 +Text="" +Color=0 +Style=0 + +[MB125] +Name=M125 +Text="" +Color=0 +Style=0 + +[MB126] +Name=M126 +Text="" +Color=0 +Style=0 + +[MB127] +Name=M127 +Text="" +Color=0 +Style=0 + +[MB128] +Name=M128 +Text="" +Color=0 +Style=0 + +[MB129] +Name=M129 +Text="" +Color=0 +Style=0 + +[MB130] +Name=M130 +Text="" +Color=0 +Style=0 + +[MB131] +Name=M131 +Text="" +Color=0 +Style=0 + +[MB132] +Name=M132 +Text="" +Color=0 +Style=0 + +[MB133] +Name=M133 +Text="" +Color=0 +Style=0 + +[MB134] +Name=M134 +Text="" +Color=0 +Style=0 + +[MB135] +Name=M135 +Text="" +Color=0 +Style=0 + +[MB136] +Name=M136 +Text="" +Color=0 +Style=0 + +[MB137] +Name=M137 +Text="" +Color=0 +Style=0 + +[MB138] +Name=M138 +Text="" +Color=0 +Style=0 + +[MB139] +Name=M139 +Text="" +Color=0 +Style=0 + +[MB140] +Name=M140 +Text="" +Color=0 +Style=0 + +[MB141] +Name=M141 +Text="" +Color=0 +Style=0 + +[MB142] +Name=M142 +Text="" +Color=0 +Style=0 + +[MB143] +Name=M143 +Text="" +Color=0 +Style=0 + +[MB144] +Name=M144 +Text="" +Color=0 +Style=0 + +[MB145] +Name=M145 +Text="" +Color=0 +Style=0 + +[MB146] +Name=M146 +Text="" +Color=0 +Style=0 + +[MB147] +Name=M147 +Text="" +Color=0 +Style=0 + +[MB148] +Name=M148 +Text="" +Color=0 +Style=0 + +[MB149] +Name=M149 +Text="" +Color=0 +Style=0 + +[MB150] +Name=M150 +Text="" +Color=0 +Style=0 + +[MB151] +Name=M151 +Text="" +Color=0 +Style=0 + +[MB152] +Name=M152 +Text="" +Color=0 +Style=0 + +[MB153] +Name=M153 +Text="" +Color=0 +Style=0 + +[MB154] +Name=M154 +Text="" +Color=0 +Style=0 + +[MB155] +Name=M155 +Text="" +Color=0 +Style=0 + +[MB156] +Name=M156 +Text="" +Color=0 +Style=0 + +[MB157] +Name=M157 +Text="" +Color=0 +Style=0 + +[MB158] +Name=M158 +Text="" +Color=0 +Style=0 + +[MB159] +Name=M159 +Text="" +Color=0 +Style=0 + +[MB160] +Name=M160 +Text="" +Color=0 +Style=0 + +[DefKey] +K1=123 +K2=19 + +[Channel1] +Show=0 +Mode=rtty-L +Carrier=943 +WaterWidth=400 +Left=2495 +Top=890 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel2] +Show=0 +Mode=rtty-L +Carrier=2479 +WaterWidth=400 +Left=1967 +Top=888 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel3] +Show=0 +Mode=GMSK +Carrier=1450 +WaterWidth=400 +Left=58 +Top=58 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel4] +Show=0 +Mode=GMSK +Carrier=2050 +WaterWidth=400 +Left=74 +Top=74 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel5] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=90 +Top=90 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel6] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=106 +Top=106 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel7] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=122 +Top=122 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel8] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=138 +Top=138 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Misc] +ShowLangMsg=0 + +[DEBUG] +testSN=13 +testName=eproject.txt +testGain=0 +testCarrier1=1750 +testCarrier2=0 +testDB2=0 +testQSBTime=8000 +testQSBDB=0 +test500=0 +testPhase=0 +testClockErr=0 + +[RadioMenu] +Menus=4 +Cap1=7.030 LSB (FT847) +Cmd1=\$0070300001\w10\$0000000007\w10 +Cap2=14.073 LSB (FT847) +Cmd2=\$0140730001\w10\$0000000007\w10 +Cap3=21.073 LSB (FT847) +Cmd3=\$0210730001\w10\$0000000007\w10 +Cap4=28.073 LSB (FT847) +Cmd4=\$0280730001\w10\$0000000007\w10 + diff --git a/Mmvari.ini b/Mmvari.ini new file mode 100644 index 0000000..74082ed --- /dev/null +++ b/Mmvari.ini @@ -0,0 +1,1341 @@ +[SoundCard] +Clock=11025.00 +TxOffset=0.00 +RxFIFO=12 +TxFIFO=6 +Source=0 +ID=Sound Blaster +IDTX=Sound Blaster + +[System] +Schema=3 +Priority=1 +FontName=Arial +FontCharset=0 + +[Window] +Fixed=0 +Left=117 +Top=116 +Width=1898 +Height=1154 +WindowState=0 +LogExtension=0 +RestoreSubChannels=0 + +[Folder] +Sound= +Log= +ExtLog= +Text= + +[PTT] +Name=COM1 +Lock=1 +OUTFSK=0 +INVFSK=0 + +[TX] +LoopBack=0 +AutoCR=1 +Carrier=446 +NET=1 +Mode=bpsk +Speed=31.25 +ModGain=16384 +ConvAlpha=1 +RttyWordOut=1 +MFSK_TYPE=0 +MFSK_CENTER=0 +SendSingleTone=1 + +[FFT] +Width=3000 +Smooth=2 +Type=2 + +[Spec] +Col1=0 +Col2=65280 +Col3=16777215 +Col4=8421504 +Col5=16776960 +Col6=16711680 + +[WF] +Col1=0 +Lvl1=28 +Col2=16776960 +Lvl2=100 +Col3=16777215 +Lvl3=168 +Col4=255 +Lvl4=192 +Col5=16776960 +Lvl5=220 +Col6=16711680 +Lvl6=240 +Col7=65535 +Col8=33023 +Col9=8388863 +Col10=255 +Col11=255 +Col12=255 + +[View] +DrawType=0 +WaveForm=0 +RigFreqScale=0 +ScaleDetails=1 +WaterAGC=0 + +[RXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +Color5=14737632 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +StatusUTC=0 +MouseWheel=1 +ShowCtrl=0 + +[TXW] +Color1=16777215 +Color2=0 +Color3=16711680 +Color4=255 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 + +[RX] +Carrier=447 +BPF=0 +AFC=1 +ATC=1 +SQLevel=300 +AFCWidth=50 +AFCLevel=12 +HPF=0 +ATCLevel=15 +ATCSpeed=0 +ATCLimit=25000 +SWL_TS=0 +NotchFreq=1750 +PlayBack=1 +PlayBackSpeed=5 +MFSK_SQ_METRIC=0 +RTTY_FFT=0 + +[Log] +Name= + +[LogSet] +TimeZone=73 +DateType=0 +UpperName=0 +UpperQTH=0 +UpperREM=0 +UpperQSL=0 +DefMyRST=0 +CopyFreq=1 +CopyHis=0 +CopyName=1 +CopyQTH=1 +CopyREM=0 +CopyQSL=0 +CopyREMB4=0 +CheckBand=1 +AutoSave=1 +THRTTY=RTY +THSSTV=STV +THGMSK=MSK +THTZ=0 +ClipRSTADIF=1 +Backup=1 +TH5Fields=3,3,7,4,12,28,54 +LogLink=1 +LinkPoll=0 +LinkPTT=0 + +[MMLink] +Name= + +[RADIO] +PortName=NONE +BaudRate=4800 +BitLen=1 +Stop=1 +Parity=0 +flwXON=0 +flwCTS=0 +usePTT=0 +ByteWait=0 +Cmdxx=0 +CmdInit= +CmdRx=\$000000000F +CmdTx=\$000000010F\w10 +FileGNR= +OpenGNR=0 +PollType=0 +PollInterval=8 +PollOffset=3 + +[Macro] +CallSign= +ButtonRow=3 +ButtonPos=0 +CWAS="<%DisableCR>\r\n#if !IsTX\r\n<%AutoNET><%AutoReturn>\r\n#if ValPage!=4\r\n<%Page=4>\r\n#else\r\n<%Page=3>\r\n#endif\r\n<%ClearTXW>\r\n#endif\r\n<%TX><%CWID=@><%RX><%EOF>\r\n" +OnTimer="" +OnPTT="" +OnQSO="" +OnFind="" +OnBand="" +OnStart="" +OnExit="" +OnMode="" +OnSpeed="" +OnClick="" +OnFFTScale="" +Expand=0 + +[MB1] +Name=Clear +Text="<%ClearTXW>" +Color=0 +Style=0 + +[MB2] +Name=CQ +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB3] +Name=CQ2 +Text="<%ClearTXW><%TX>CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall>\r\nCQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K\r\n<%RX>" +Color=0 +Style=0 + +[MB4] +Name=1x1 +Text="<%NETON><%TX><%HisCall> de <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB5] +Name=2x2 +Text="<%NETON><%TX><%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse K\r\n<%RX>" +Color=0 +Style=0 + +[MB6] +Name=RRR +Text="\r\nRRR <%HisCall> de <%MyCall>\r\n--- <%VARITYPE> ---\r\n" +Color=0 +Style=0 + +[MB7] +Name=BTU +Text="BTU <%HisCall> de <%MyCall> KN\r\n<%RX>" +Color=0 +Style=0 + +[MB8] +Name=M8 +Text="" +Color=0 +Style=0 + +[MB9] +Name=M9 +Text="" +Color=0 +Style=0 + +[MB10] +Name=M10 +Text="" +Color=0 +Style=0 + +[MB11] +Name=M11 +Text="" +Color=0 +Style=0 + +[MB12] +Name=M12 +Text="" +Color=0 +Style=0 + +[MB13] +Name=CWID +Text="<%TX><%CWID=DE <%MyCall>><%RX><%EOF>" +Color=0 +Style=4 + +[MB14] +Name=TU SK +Text="<%TX><%CWID=TU:><%RX><%EOF>" +Color=0 +Style=4 + +[MB15] +Name=M15 +Text="" +Color=0 +Style=0 + +[MB16] +Name=0x2 - 2x4 +Text="<%DisableCR>\r\n#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4>\r\n#if ValMenu\r\n#define\t_His\t<%Format=%c,<%Input$>>\r\n#define\t_My\t<%Format=%d,<%Find$=x,<%Input$>>>\r\n<%TX><%RX>\r\n#if !Is1stCR\r\n<%CR>\r\n#endif\r\n#if IsCall\r\n<%RepeatText=_His,<%HisCall> >\r\n#endif\r\nde\r\n<%RepeatText=_My, <%MyCall>>\r\n pse K<%CR>\r\n#endif\r\n<%EOF>" +Color=0 +Style=0 + +[MB17] +Name=M17 +Text="" +Color=0 +Style=0 + +[MB18] +Name=M18 +Text="" +Color=0 +Style=0 + +[MB19] +Name=M19 +Text="" +Color=0 +Style=0 + +[MB20] +Name=M20 +Text="" +Color=0 +Style=0 + +[MB21] +Name=M21 +Text="" +Color=0 +Style=0 + +[MB22] +Name=M22 +Text="" +Color=0 +Style=0 + +[MB23] +Name=M23 +Text="" +Color=0 +Style=0 + +[MB24] +Name=M24 +Text="" +Color=0 +Style=0 + +[MB25] +Name=M25 +Text="" +Color=0 +Style=0 + +[MB26] +Name=M26 +Text="" +Color=0 +Style=0 + +[MB27] +Name=M27 +Text="" +Color=0 +Style=0 + +[MB28] +Name=M28 +Text="" +Color=0 +Style=0 + +[MB29] +Name=M29 +Text="" +Color=0 +Style=0 + +[MB30] +Name=M30 +Text="" +Color=0 +Style=0 + +[MB31] +Name=M31 +Text="" +Color=0 +Style=0 + +[MB32] +Name=M32 +Text="" +Color=0 +Style=0 + +[MB33] +Name=M33 +Text="" +Color=0 +Style=0 + +[MB34] +Name=M34 +Text="" +Color=0 +Style=0 + +[MB35] +Name=M35 +Text="" +Color=0 +Style=0 + +[MB36] +Name=M36 +Text="" +Color=0 +Style=0 + +[MB37] +Name=M37 +Text="" +Color=0 +Style=0 + +[MB38] +Name=M38 +Text="" +Color=0 +Style=0 + +[MB39] +Name=M39 +Text="" +Color=0 +Style=0 + +[MB40] +Name=M40 +Text="" +Color=0 +Style=0 + +[MB41] +Name=M41 +Text="" +Color=0 +Style=0 + +[MB42] +Name=M42 +Text="" +Color=0 +Style=0 + +[MB43] +Name=M43 +Text="" +Color=0 +Style=0 + +[MB44] +Name=M44 +Text="" +Color=0 +Style=0 + +[MB45] +Name=M45 +Text="" +Color=0 +Style=0 + +[MB46] +Name=M46 +Text="" +Color=0 +Style=0 + +[MB47] +Name=M47 +Text="" +Color=0 +Style=0 + +[MB48] +Name=M48 +Text="" +Color=0 +Style=0 + +[MB49] +Name=M49 +Text="" +Color=0 +Style=0 + +[MB50] +Name=M50 +Text="" +Color=0 +Style=0 + +[MB51] +Name=M51 +Text="" +Color=0 +Style=0 + +[MB52] +Name=M52 +Text="" +Color=0 +Style=0 + +[MB53] +Name=M53 +Text="" +Color=0 +Style=0 + +[MB54] +Name=M54 +Text="" +Color=0 +Style=0 + +[MB55] +Name=M55 +Text="" +Color=0 +Style=0 + +[MB56] +Name=M56 +Text="" +Color=0 +Style=0 + +[MB57] +Name=M57 +Text="" +Color=0 +Style=0 + +[MB58] +Name=M58 +Text="" +Color=0 +Style=0 + +[MB59] +Name=M59 +Text="" +Color=0 +Style=0 + +[MB60] +Name=M60 +Text="" +Color=0 +Style=0 + +[MB61] +Name=M61 +Text="" +Color=0 +Style=0 + +[MB62] +Name=M62 +Text="" +Color=0 +Style=0 + +[MB63] +Name=M63 +Text="" +Color=0 +Style=0 + +[MB64] +Name=M64 +Text="" +Color=0 +Style=0 + +[MB65] +Name=M65 +Text="" +Color=0 +Style=0 + +[MB66] +Name=M66 +Text="" +Color=0 +Style=0 + +[MB67] +Name=M67 +Text="" +Color=0 +Style=0 + +[MB68] +Name=M68 +Text="" +Color=0 +Style=0 + +[MB69] +Name=M69 +Text="" +Color=0 +Style=0 + +[MB70] +Name=M70 +Text="" +Color=0 +Style=0 + +[MB71] +Name=M71 +Text="" +Color=0 +Style=0 + +[MB72] +Name=M72 +Text="" +Color=0 +Style=0 + +[MB73] +Name=M73 +Text="" +Color=0 +Style=0 + +[MB74] +Name=M74 +Text="" +Color=0 +Style=0 + +[MB75] +Name=M75 +Text="" +Color=0 +Style=0 + +[MB76] +Name=M76 +Text="" +Color=0 +Style=0 + +[MB77] +Name=M77 +Text="" +Color=0 +Style=0 + +[MB78] +Name=M78 +Text="" +Color=0 +Style=0 + +[MB79] +Name=M79 +Text="" +Color=0 +Style=0 + +[MB80] +Name=M80 +Text="" +Color=0 +Style=0 + +[MB81] +Name=M81 +Text="" +Color=0 +Style=0 + +[MB82] +Name=M82 +Text="" +Color=0 +Style=0 + +[MB83] +Name=M83 +Text="" +Color=0 +Style=0 + +[MB84] +Name=M84 +Text="" +Color=0 +Style=0 + +[MB85] +Name=M85 +Text="" +Color=0 +Style=0 + +[MB86] +Name=M86 +Text="" +Color=0 +Style=0 + +[MB87] +Name=M87 +Text="" +Color=0 +Style=0 + +[MB88] +Name=M88 +Text="" +Color=0 +Style=0 + +[MB89] +Name=M89 +Text="" +Color=0 +Style=0 + +[MB90] +Name=M90 +Text="" +Color=0 +Style=0 + +[MB91] +Name=M91 +Text="" +Color=0 +Style=0 + +[MB92] +Name=M92 +Text="" +Color=0 +Style=0 + +[MB93] +Name=M93 +Text="" +Color=0 +Style=0 + +[MB94] +Name=M94 +Text="" +Color=0 +Style=0 + +[MB95] +Name=M95 +Text="" +Color=0 +Style=0 + +[MB96] +Name=M96 +Text="" +Color=0 +Style=0 + +[MB97] +Name=M97 +Text="" +Color=0 +Style=0 + +[MB98] +Name=M98 +Text="" +Color=0 +Style=0 + +[MB99] +Name=M99 +Text="" +Color=0 +Style=0 + +[MB100] +Name=M100 +Text="" +Color=0 +Style=0 + +[MB101] +Name=M101 +Text="" +Color=0 +Style=0 + +[MB102] +Name=M102 +Text="" +Color=0 +Style=0 + +[MB103] +Name=M103 +Text="" +Color=0 +Style=0 + +[MB104] +Name=M104 +Text="" +Color=0 +Style=0 + +[MB105] +Name=M105 +Text="" +Color=0 +Style=0 + +[MB106] +Name=M106 +Text="" +Color=0 +Style=0 + +[MB107] +Name=M107 +Text="" +Color=0 +Style=0 + +[MB108] +Name=M108 +Text="" +Color=0 +Style=0 + +[MB109] +Name=M109 +Text="" +Color=0 +Style=0 + +[MB110] +Name=M110 +Text="" +Color=0 +Style=0 + +[MB111] +Name=M111 +Text="" +Color=0 +Style=0 + +[MB112] +Name=M112 +Text="" +Color=0 +Style=0 + +[MB113] +Name=M113 +Text="" +Color=0 +Style=0 + +[MB114] +Name=M114 +Text="" +Color=0 +Style=0 + +[MB115] +Name=M115 +Text="" +Color=0 +Style=0 + +[MB116] +Name=M116 +Text="" +Color=0 +Style=0 + +[MB117] +Name=M117 +Text="" +Color=0 +Style=0 + +[MB118] +Name=M118 +Text="" +Color=0 +Style=0 + +[MB119] +Name=M119 +Text="" +Color=0 +Style=0 + +[MB120] +Name=M120 +Text="" +Color=0 +Style=0 + +[MB121] +Name=M121 +Text="" +Color=0 +Style=0 + +[MB122] +Name=M122 +Text="" +Color=0 +Style=0 + +[MB123] +Name=M123 +Text="" +Color=0 +Style=0 + +[MB124] +Name=M124 +Text="" +Color=0 +Style=0 + +[MB125] +Name=M125 +Text="" +Color=0 +Style=0 + +[MB126] +Name=M126 +Text="" +Color=0 +Style=0 + +[MB127] +Name=M127 +Text="" +Color=0 +Style=0 + +[MB128] +Name=M128 +Text="" +Color=0 +Style=0 + +[MB129] +Name=M129 +Text="" +Color=0 +Style=0 + +[MB130] +Name=M130 +Text="" +Color=0 +Style=0 + +[MB131] +Name=M131 +Text="" +Color=0 +Style=0 + +[MB132] +Name=M132 +Text="" +Color=0 +Style=0 + +[MB133] +Name=M133 +Text="" +Color=0 +Style=0 + +[MB134] +Name=M134 +Text="" +Color=0 +Style=0 + +[MB135] +Name=M135 +Text="" +Color=0 +Style=0 + +[MB136] +Name=M136 +Text="" +Color=0 +Style=0 + +[MB137] +Name=M137 +Text="" +Color=0 +Style=0 + +[MB138] +Name=M138 +Text="" +Color=0 +Style=0 + +[MB139] +Name=M139 +Text="" +Color=0 +Style=0 + +[MB140] +Name=M140 +Text="" +Color=0 +Style=0 + +[MB141] +Name=M141 +Text="" +Color=0 +Style=0 + +[MB142] +Name=M142 +Text="" +Color=0 +Style=0 + +[MB143] +Name=M143 +Text="" +Color=0 +Style=0 + +[MB144] +Name=M144 +Text="" +Color=0 +Style=0 + +[MB145] +Name=M145 +Text="" +Color=0 +Style=0 + +[MB146] +Name=M146 +Text="" +Color=0 +Style=0 + +[MB147] +Name=M147 +Text="" +Color=0 +Style=0 + +[MB148] +Name=M148 +Text="" +Color=0 +Style=0 + +[MB149] +Name=M149 +Text="" +Color=0 +Style=0 + +[MB150] +Name=M150 +Text="" +Color=0 +Style=0 + +[MB151] +Name=M151 +Text="" +Color=0 +Style=0 + +[MB152] +Name=M152 +Text="" +Color=0 +Style=0 + +[MB153] +Name=M153 +Text="" +Color=0 +Style=0 + +[MB154] +Name=M154 +Text="" +Color=0 +Style=0 + +[MB155] +Name=M155 +Text="" +Color=0 +Style=0 + +[MB156] +Name=M156 +Text="" +Color=0 +Style=0 + +[MB157] +Name=M157 +Text="" +Color=0 +Style=0 + +[MB158] +Name=M158 +Text="" +Color=0 +Style=0 + +[MB159] +Name=M159 +Text="" +Color=0 +Style=0 + +[MB160] +Name=M160 +Text="" +Color=0 +Style=0 + +[DefKey] +K1=123 +K2=19 + +[Channel1] +Show=0 +Mode=rtty-L +Carrier=943 +WaterWidth=400 +Left=2495 +Top=890 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel2] +Show=0 +Mode=rtty-L +Carrier=2479 +WaterWidth=400 +Left=1967 +Top=888 +Width=500 +Height=124 +FontName=MS Pゴシック +FontSet=128 +FontSize=-13 +FontStyle=0 +RTTYFFT=0 +Speed=45.45 +MFSK_TYPE=0 +AFC=1 + +[Channel3] +Show=0 +Mode=GMSK +Carrier=1450 +WaterWidth=400 +Left=58 +Top=58 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel4] +Show=0 +Mode=GMSK +Carrier=2050 +WaterWidth=400 +Left=74 +Top=74 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel5] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=90 +Top=90 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel6] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=106 +Top=106 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel7] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=122 +Top=122 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Channel8] +Show=0 +Mode=GMSK +Carrier=2210 +WaterWidth=400 +Left=138 +Top=138 +Width=500 +Height=124 +FontName= +FontSet=0 +FontSize=0 +FontStyle=0 +RTTYFFT=0 +Speed=31.25 +MFSK_TYPE=0 +AFC=1 + +[Misc] +ShowLangMsg=0 + +[DEBUG] +testSN=13 +testName=eproject.txt +testGain=0 +testCarrier1=1750 +testCarrier2=0 +testDB2=0 +testQSBTime=8000 +testQSBDB=0 +test500=0 +testPhase=0 +testClockErr=0 + +[RadioMenu] +Menus=4 +Cap1=7.030 LSB (FT847) +Cmd1=\$0070300001\w10\$0000000007\w10 +Cap2=14.073 LSB (FT847) +Cmd2=\$0140730001\w10\$0000000007\w10 +Cap3=21.073 LSB (FT847) +Cmd3=\$0210730001\w10\$0000000007\w10 +Cap4=28.073 LSB (FT847) +Cmd4=\$0280730001\w10\$0000000007\w10 + diff --git a/Option.cpp b/Option.cpp new file mode 100644 index 0000000..e8c8633 --- /dev/null +++ b/Option.cpp @@ -0,0 +1,938 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Option.h" +#include "ComLib.h" +#include "Main.h" +#include "dsp.h" +#include "CodeVw.h" +#include "RadioSet.h" +#include "cradio.h" +#include "MacEdit.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TOptDlgBox *OptDlgBox; +//--------------------------------------------------------------------- +__fastcall TOptDlgBox::TOptDlgBox(TComponent* AOwner) + : TForm(AOwner) +{ + m_fDisEvent = TRUE; + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + Caption = "Setup MMVARI"; + CancelBtn->Caption = "Cancel"; + + TabRX->Caption = "RX"; + TabTX->Caption = "TX"; + TabMisc->Caption = "Misc"; + + // RX + GB10->Caption = "HPF (DC ingredients cutter)"; + GB10->Hint = "It is unnecessary with most sound cards"; + CBHPF->Caption = "Use HPF"; + L10->Caption = "FREQ width +/-"; + L13->Caption = "Sense level(S/N)"; + GB6->Hint = "Narrow (less than 50Hz) is FB in HF"; + GB15->Hint = "You do not need to change the value"; + L20->Caption = "Speed"; + L21->Caption = "Slow ---- Fast"; + L22->Caption = "Sense level(S/N)"; + L23->Caption = "Max range +/-"; + CBMC->Caption = "Handling center frequency"; + CBMM->Caption = "Use metric level squelch"; + CBMM->Hint = "It may be FB, when you use narrow filter in the Rig"; + GB17->Caption = "Misc"; + CBSWL->Caption = "Show Time stamp for SWL"; + CBPB->Caption = "Enabled Sound Playback"; + LPB->Caption = "Playback speed\r\nx1 -------------- x20"; + RGRTTY->Caption = "RTTY Demodulator"; + + // TX + CBComLock->Caption = "Exclusive lock"; + CBFSK->Caption = "Output"; + CBFSK->Hint = "Use multi-media timer function"; + CBFSKINV->Caption = "Invert logic"; + CBFSKINV->Hint = "Invert mark and space"; + + SBRadio->Caption = "Radio command"; + GB8->Caption = "Digital output level"; + RGLoopBack->Caption = "LoopBack"; + RGLoopBack->Items->Strings[0] = "Internal"; + RGLoopBack->Items->Strings[1] = "External (full-duplex)"; + GBKey->Caption = "Key assign"; + GB5->Caption = "Macro"; + GB16->Caption = "Misc"; + CBCA->Caption = "Convert MBCS alphabet to ASCII"; + SBAS->Caption = "Edit AS(CW)"; + SBAS->Hint = "Edit AS(CW) macro - Right click on the Spectrum scope"; + GB33->Caption = "Event macro"; + L33->Caption = "Name"; + SBEvent->Caption = "Edit"; + SBEventC->Caption = "Clear"; + CBEvent->Hint = "Choose event to edit"; + SBEvent->Hint = "Edit this event"; + SBEventC->Hint = "Clear this event"; + CBST->Caption = "Output single tone when the TX ends (PSK)"; + + // Misc + GB2->Caption = "Soundcard"; + RGSoundIn->Caption = "Input channel"; + RGSoundIn->Items->Strings[0] = "Mono"; + RGSoundIn->Items->Strings[1] = "Left"; + RGSoundIn->Items->Strings[2] = "Right"; + RGPriority->Caption = "Priority"; + RGPriority->Items->Strings[0] = "Normal"; + RGPriority->Items->Strings[1] = "Higher"; + RGPriority->Items->Strings[2] = "Highest"; + GB11->Caption = "RX window"; + SBRxFont->Caption = "Font"; + SBRxChar->Caption = "Code list"; + SBRxChar->Hint = "Character code list"; + CBRxUTC->Caption = "Time stamp = UTC"; + CBMW->Caption = "Scroll with mouse wheel"; + CBShowCtrl->Caption = "Show CTRL code"; + GB12->Caption = "TX window"; + SBTxFont->Caption = "Font"; + GBWindow->Caption = "Size and position"; + RBW1->Caption = "Windows default"; + RBW2->Caption = "Save size && pos."; + CBRestoreSub->Caption = "Restore sub channels"; + GB13->Caption = "Spectrum scope"; + GB14->Caption = "Waterfall scope"; + L30->Caption = "Level"; + L31->Caption = "Sigs"; + + SBJA->Caption = "Japanese"; + SBEng->Caption = "English"; + GB9->Caption = "Message-Language"; + + OKBtn->Hint = "Save all update && close this window"; + CancelBtn->Hint = "Unsave all update && close this window"; + EATCL->Hint = "Default = 15dB"; + TBATC->Hint = "Default = Slow"; + CBATCM->Hint = "Default = 25000ppm"; + CBComPTT->Hint = ""; + CBComLock->Hint = "Uncheck this, when the port shares with other software"; + RGLoopBack->Hint = "Choose 'Internal' for usually operation"; + ECallSign->Hint = "Your callsign"; + GB8->Hint = "The signal may be a warp, when it is high (It depend on soundcard)"; + CBKTX->Hint = "Switch TX/RX"; + CBKTXOFF->Hint = "Abort TX"; + CBCA->Hint = "Some transmission efficiency will be improved when does this conv."; + CBFifoRX->Hint = "Enlarge the value if you often break the sound in RX"; + CBFifoTX->Hint = "Enlarge the value if you often break the sound in TX"; + CBClock->Hint = "RX sampling FREQ (Put the same value of MMSSTV)"; + CBTxOffset->Hint = "TX (offset) sampling FREQ (Put the same value of MMSSTV)"; + CBSoundID->Hint = "Input sound device (device name or number)"; + CBSoundIDTX->Hint = "Output sound device (device name or number)"; + PCRx1->Hint = "Back color"; + PCRx2->Hint = "Character color (RX)"; + PCRx3->Hint = "Character color (TX)"; + PCRx4->Hint = "Status color"; + PCRx5->Hint = "Back color with scrolling"; + PCTx1->Hint = "Back color"; + PCTx2->Hint = "Character color"; + PCTx3->Hint = "Character color (TX)"; + PCTx4->Hint = "CWID/Control code color"; + PS1->Hint = "Back color"; + PS2->Hint = "Signal color"; + PS3->Hint = "Text color"; + PS4->Hint = "Scale"; + PS5->Hint = "RX Marker"; + PS6->Hint = "TX Marker"; + PW1->Hint = "Back color"; + PW2->Hint = "Level1"; + PW3->Hint = "Text color"; + PW4->Hint = "Marker frame"; + PW5->Hint = "RX Marker"; + PW6->Hint = "TX Marker"; + PW7->Hint = "Level2"; + PW8->Hint = "Level3"; + PW9->Hint = "Level4"; + PW10->Hint = "Level5"; + PW11->Hint = "Level6"; + PW12->Hint = "Level7"; + PL->Hint = "Set level (Drag && drop)"; + SBWLCD->Hint = "Return to the LCD's default (Level and Colors)"; + SBWCRT->Hint = "Return to the CRT's default (Level and Colors)"; + GBWindow->Hint = "Window size and position (when program will be invoked)."; + SBFont->Hint = "Choose your favorite font for the program except TX/RX window"; + } + else { + LPB->Caption = "プレーバック速度\r\nx1 <---------> x20"; + } + SBJA->Hint = "All menu messages are displayed in Japanese"; + SBEng->Hint = "All menu messages are displayed in English"; + + double mb = 120.0 * SAMPBASE / (1024*1024); + char bf[256]; + sprintf(bf, sys.m_MsgEng ? "To use memory of %.1lfMB for the function":"この機能は%.1lfMBのメモリを使います.", mb); + CBPB->Hint = bf; + + UdATCL->Hint = EATCL->Hint; + m_fComChange = FALSE; + m_fLangChange = FALSE; + + UdClock->Hint = CBClock->Hint; + UdTxOffset->Hint = CBTxOffset->Hint; + OnWave(); + const DEFKEYTBL *pKey = KEYTBL; + for( ; pKey->Key; pKey++ ){ + CBKTX->Items->Add(pKey->pName); + } + CBEvent->DropDownCount = macOnEnd; + for( int i = 0; i < macOnEnd; i++ ){ + CBEvent->Items->Add(g_tMacEvent[i]); + } + CBEvent->ItemIndex = sys.m_EventIndex; + OnWave(); + CBKTXOFF->Items->Assign(CBKTX->Items); + FormCenter(this); + m_MouseDown = 0; + m_MouseWLN = -1; + CWave *pw = &MainVARI->m_Wave; + pw->GetDeviceList(); + for( int i = 0; i < pw->m_InDevs; i++ ){ + if( !pw->m_tInDevName[i].IsEmpty() ){ + CBSoundID->Items->Add(pw->m_tInDevName[i]); + } + } + for( int i = 0; i < pw->m_OutDevs; i++ ){ + if( !pw->m_tOutDevName[i].IsEmpty() ){ + CBSoundIDTX->Items->Add(pw->m_tOutDevName[i]); + } + } + CBSoundID->DropDownCount = CBSoundID->Items->Count; + CBSoundIDTX->DropDownCount = CBSoundIDTX->Items->Count; +} +//--------------------------------------------------------------------- +void __fastcall TOptDlgBox::UpdateButton(void) +{ + if( m_FontCharset == SHIFTJIS_CHARSET ){ + SBJA->Down = TRUE; + } + else { + SBEng->Down = TRUE; + } +} +//--------------------------------------------------------------------- +void __fastcall TOptDlgBox::UpdateHint(void) +{ + AnsiString as = PCRx2->Font->Name; + TFontStyles fs = PCRx2->Font->Style; + AddStyle(as, PCRx2->Font->Charset, FontStyle2Code(fs)); + as += sys.m_MsgEng ? " (VariCode type is decided by this font)":" (このフォントでVariCodeタイプが決まります)"; + SBRxFont->Hint = as; + as = PCTx2->Font->Name; + fs = PCTx2->Font->Style; + AddStyle(as, PCTx2->Font->Charset, FontStyle2Code(fs)); + SBTxFont->Hint = as; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::DisplayHint(TObject *Sender) +{ + LH->Caption = GetLongHint(Application->Hint); +} +//--------------------------------------------------------------------- +void __fastcall TOptDlgBox::UpdateUI(void) +{ + int dd; + BOOL f = (sscanf(AnsiString(CBSoundID->Text).c_str(), "%d", &dd) == 1 ); //JA7UDE 0428 + if( !f ){ + if( !strcmpi(AnsiString(CBSoundID->Text).c_str(), "Default") ){ //JA7UDE 0428 + f = TRUE; + } + else { + CWave *pw = &MainVARI->m_Wave; + for(int i = 0; i < pw->m_InDevs; i++ ){ + if( !strcmp(AnsiString(CBSoundID->Text).c_str(), AnsiString(pw->m_tInDevName[i]).c_str()) ){ //JA7UDE 0428 + f = TRUE; + break; + } + } + } + } + LO->Enabled = f; + CBSoundIDTX->Enabled = f; + + GB3->Enabled = f; + SetGroupEnabled(GB3); + RGSoundIn->Enabled = f; + + f = CBPB->Checked; + TBPB->Visible = f; + LPB->Visible = f; + SBEventC->Enabled = !m_MacEvent[CBEvent->ItemIndex].IsEmpty(); + + AnsiString as = CBComPTT->Text; + f = strncmpi(as.c_str(), "COM", 3); + if( f ){ // COMxx + f = strcmp(as.c_str(), "NONE"); + } + else { + LPCSTR p = as.c_str(); + f = isdigit(p[3]) ? 0 : 1; + } + CBFSKINV->Enabled = f ? 0 : 1; +} +//--------------------------------------------------------------------- +int __fastcall TOptDlgBox::Execute(DWORD dwPage) +{ + m_fDisEvent = TRUE; + int i; + char bf[256]; + // RX + CBAFCW->Text = MainVARI->m_AFCWidth; + UdAFCL->Position = short(MainVARI->m_AFCLevel); + CBHPF->Checked = MainVARI->m_fHPF; + TBATC->Position = short(MainVARI->m_ATCSpeed); + UdATCL->Position = short(MainVARI->m_ATCLevel); + CBATCM->Text = MainVARI->m_ATCLimit; + CBSWL->Checked = sys.m_fAutoTS; + CBPB->Checked = sys.m_fPlayBack; + TBPB->Position = sys.m_PlayBackSpeed; + RGRTTY->ItemIndex = MainVARI->m_RxSet[0].m_RTTYFFT; + // TX + CBComPTT->Text = sys.m_PTTCOM; + CBFSK->Checked = sys.m_bFSKOUT; + CBFSKINV->Checked = sys.m_bINVFSK; + + CBComLock->Checked = sys.m_PTTLock; + RGLoopBack->ItemIndex = sys.m_LoopBack; + + ECallSign->Text = sys.m_CallSign; + m_AS = sys.m_AS.c_str(); + for( i = 0; i < macOnEnd; i++ ) m_MacEvent[i] = sys.m_MacEvent[i]; + TBModGain->Position = MainVARI->m_ModGain; + + CBKTX->ItemIndex = CBKTX->Items->IndexOf(GetKeyName(sys.m_DefKey[kkTX])); + CBKTXOFF->ItemIndex = CBKTXOFF->Items->IndexOf(GetKeyName(sys.m_DefKey[kkTXOFF])); + CBCA->Checked = MainVARI->m_fConvAlpha; + CBMC->Checked = sys.m_MFSK_Center; + CBMM->Checked = sys.m_MFSK_SQ_Metric; + CBST->Checked = sys.m_fSendSingleTone; + + //Misc + CBFifoRX->Text = MainVARI->m_Wave.m_InFifoSize; + CBFifoTX->Text = MainVARI->m_Wave.m_OutFifoSize; + RGSoundIn->ItemIndex = MainVARI->m_Wave.m_SoundStereo; + + int d; + if( MainVARI->m_Wave.m_SoundID == -2 ){ + CBSoundID->Text = sys.m_SoundMMW; + } + else { + if( (sscanf(sys.m_SoundIDRX.c_str(), "%d", &d ) == 1) && (d == -1) ){ + CBSoundID->Text = "Default"; + } + else { + CBSoundID->Text = sys.m_SoundIDRX; + } + } + if( (sscanf(sys.m_SoundIDTX.c_str(), "%d", &d ) == 1) && (d == -1) ){ + CBSoundIDTX->Text = "Default"; + } + else { + CBSoundIDTX->Text = sys.m_SoundIDTX; + } + sprintf(bf, "%.2lf", SAMPFREQ); + CBClock->Text = bf; + sprintf(bf, "%.2lf", SAMPTXOFFSET); + CBTxOffset->Text = bf; + UdTxOffset->Position = 0; + RGPriority->ItemIndex = MainVARI->m_Priority; + + PCRx2->Font = MainVARI->PCRX->Font; + long cz; + cz = MainVARI->m_Dump.m_Color[0].d; + PCRx1->Color = cz; + cz = MainVARI->m_Dump.m_Color[1].d; + PCRx2->Color = cz; + cz = MainVARI->m_Dump.m_Color[2].d; + PCRx3->Color = cz; + cz = MainVARI->m_Dump.m_Color[3].d; + PCRx4->Color = cz; + cz = MainVARI->m_Dump.m_Color[4].d; + PCRx5->Color = cz; + + //PCRx1->Color = MainVARI->m_Dump.m_Color[0].c; + //PCRx2->Color = MainVARI->m_Dump.m_Color[1].c; + //PCRx3->Color = MainVARI->m_Dump.m_Color[2].c; + //PCRx4->Color = MainVARI->m_Dump.m_Color[3].c; + //PCRx5->Color = MainVARI->m_Dump.m_Color[4].c; + + CBRxUTC->Checked = MainVARI->m_StatusUTC; + CBMW->Checked = sys.m_EnableMouseWheel; + CBShowCtrl->Checked = sys.m_fShowCtrlCode; + + PCTx2->Font = MainVARI->PCTX->Font; + cz = MainVARI->m_Edit[0].m_Color[0].c; + PCTx1->Color = cz; + cz = MainVARI->m_Edit[0].m_Color[1].c; + PCTx2->Color = cz; + cz = MainVARI->m_Edit[0].m_Color[2].c; + PCTx3->Color = cz; + cz = MainVARI->m_Edit[0].m_Color[3].c; + PCTx4->Color = cz; + + //PCTx1->Color = MainVARI->m_Edit[0].m_Color[0].c; + //PCTx2->Color = MainVARI->m_Edit[0].m_Color[1].c; + //PCTx3->Color = MainVARI->m_Edit[0].m_Color[2].c; + //PCTx4->Color = MainVARI->m_Edit[0].m_Color[3].c; + + PS1->Color = MainVARI->m_tFFTColset[0].c; + PS2->Color = MainVARI->m_tFFTColset[1].c; + PS3->Color = MainVARI->m_tFFTColset[2].c; + PS4->Color = MainVARI->m_tFFTColset[3].c; + PS5->Color = MainVARI->m_tFFTColset[4].c; + PS6->Color = MainVARI->m_tFFTColset[5].c; + + PW1->Color = MainVARI->m_tWaterColset[0].c; + PW2->Color = MainVARI->m_tWaterColset[1].c; + PW3->Color = MainVARI->m_tWaterColset[2].c; + PW4->Color = MainVARI->m_tWaterColset[3].c; + PW5->Color = MainVARI->m_tWaterColset[4].c; + PW6->Color = MainVARI->m_tWaterColset[5].c; + PW7->Color = MainVARI->m_tWaterColset[6].c; + PW8->Color = MainVARI->m_tWaterColset[7].c; + PW9->Color = MainVARI->m_tWaterColset[8].c; + PW10->Color = MainVARI->m_tWaterColset[9].c; + PW11->Color = MainVARI->m_tWaterColset[10].c; + PW12->Color = MainVARI->m_tWaterColset[11].c; + PL->Color = PW1->Color; + for( i = 0; i < 6; i++ ){ + m_tWaterLevel[i] = MainVARI->m_tWaterLevel[i]; + } + + RBW1->Checked = !sys.m_fFixWindow; + RBW2->Checked = sys.m_fFixWindow; + CBRestoreSub->Checked = sys.m_fRestoreSubChannel; + + m_FontName = sys.m_FontName; + m_FontCharset = sys.m_FontCharset; + + UpdateButton(); + UpdateHint(); + UpdateUI(); + OnWave(); + m_fDisEvent = FALSE; + + if( (dwPage >= 0) && (dwPage <= 2) ){ + sys.m_OptionPage = dwPage; + } + SetActiveIndex(Page, sys.m_OptionPage); + m_fnHintProc = Application->OnHint; + Application->OnHint = DisplayHint; + int r = ShowModal(); + Application->OnHint = m_fnHintProc; + sys.m_OptionPage = GetActiveIndex(Page); + sys.m_EventIndex = CBEvent->ItemIndex; + if( r == IDOK ){ + int di; + double dd; + // RX + sscanf(AnsiString(CBAFCW->Text).c_str(), "%u", &di); //JA7UDE 0428 + if( (di >= 0) && (di <= 2000) ){ + MainVARI->m_AFCWidth = di; + } + MainVARI->m_AFCLevel = UdAFCL->Position; + MainVARI->m_fHPF = CBHPF->Checked; + MainVARI->SetATCSpeed(TBATC->Position); + MainVARI->m_ATCLevel = UdATCL->Position; + sscanf(AnsiString(CBATCM->Text).c_str(), "%u", &di); //JA7UDE 0428 + if( (di >= 1000) && (di <= 100000) ){ + MainVARI->SetATCLimit(di); + } + sys.m_fAutoTS = CBSWL->Checked; + sys.m_fPlayBack = CBPB->Checked; + sys.m_PlayBackSpeed = TBPB->Position; + + // TX + sys.m_PTTCOM = CBComPTT->Text; + sys.m_bFSKOUT = CBFSK->Checked; + sys.m_bINVFSK = CBFSKINV->Checked; + if( MainVARI->m_pCom ) MainVARI->m_pCom->SetFSK(sys.m_bFSKOUT, sys.m_bINVFSK); + + sys.m_PTTLock = CBComLock->Checked; + sys.m_LoopBack = RGLoopBack->ItemIndex; + sys.m_CallSign = ECallSign->Text; + sys.m_AS = m_AS.c_str(); + for( i = 0; i < macOnEnd; i++ ) sys.m_MacEvent[i] = m_MacEvent[i]; + MainVARI->m_ModGain = TBModGain->Position; + MainVARI->UpdateModGain(); + + sys.m_DefKey[kkTX] = GetKeyCode(AnsiString(CBKTX->Text).c_str()); //JA7UDE 0428 + sys.m_DefKey[kkTXOFF] = GetKeyCode(AnsiString(CBKTXOFF->Text).c_str()); //JA7UDE 0428 + MainVARI->SetConvAlpha(CBCA->Checked); + sys.m_fSendSingleTone = CBST->Checked; + + PCTx2->Font->Charset = PCRx2->Font->Charset; + LOGFONT l1; + LOGFONT l2; + GetLogFont(&l1, PCRx2->Font); + GetLogFont(&l2, MainVARI->PCRX->Font); + if( memcmp(&l1, &l2, sizeof(l1)) ){ + MainVARI->PCRX->Font = PCRx2->Font; + MainVARI->OnFontChange(FALSE); + } + MainVARI->m_Dump.m_Color[0].c = PCRx1->Color; + MainVARI->m_Dump.m_Color[1].c = PCRx2->Color; + MainVARI->m_Dump.m_Color[2].c = PCRx3->Color; + MainVARI->m_Dump.m_Color[3].c = PCRx4->Color; + MainVARI->m_Dump.m_Color[4].c = PCRx5->Color; + MainVARI->m_StatusUTC = CBRxUTC->Checked; + sys.m_EnableMouseWheel = CBMW->Checked; + sys.m_fShowCtrlCode = CBShowCtrl->Checked; + + GetLogFont(&l1, PCTx2->Font); + GetLogFont(&l2, MainVARI->PCTX->Font); + if( memcmp(&l1, &l2, sizeof(l1)) ){ + MainVARI->PCTX->Font = PCTx2->Font; + MainVARI->OnFontChange(TRUE); + } + for( int i = 0; i < 4; i++ ){ + MainVARI->m_Edit[i].m_Color[0].c = PCTx1->Color; + MainVARI->m_Edit[i].m_Color[1].c = PCTx2->Color; + MainVARI->m_Edit[i].m_Color[2].c = PCTx3->Color; + MainVARI->m_Edit[i].m_Color[3].c = PCTx4->Color; + MainVARI->m_Edit[i].m_Color[4].c = PCTx1->Color; + } + MainVARI->m_tFFTColset[0].c = PS1->Color; + MainVARI->m_tFFTColset[1].c = PS2->Color; + MainVARI->m_tFFTColset[2].c = PS3->Color; + MainVARI->m_tFFTColset[3].c = PS4->Color; + MainVARI->m_tFFTColset[4].c = PS5->Color; + MainVARI->m_tFFTColset[5].c = PS6->Color; + + MainVARI->m_tWaterColset[0].c = PW1->Color; + MainVARI->m_tWaterColset[1].c = PW2->Color; + MainVARI->m_tWaterColset[2].c = PW3->Color; + MainVARI->m_tWaterColset[3].c = PW4->Color; + MainVARI->m_tWaterColset[4].c = PW5->Color; + MainVARI->m_tWaterColset[5].c = PW6->Color; + MainVARI->m_tWaterColset[6].c = PW7->Color; + MainVARI->m_tWaterColset[7].c = PW8->Color; + MainVARI->m_tWaterColset[8].c = PW9->Color; + MainVARI->m_tWaterColset[9].c = PW10->Color; + MainVARI->m_tWaterColset[10].c = PW11->Color; + MainVARI->m_tWaterColset[11].c = PW12->Color; + for( i = 0; i < 6; i++ ){ + MainVARI->m_tWaterLevel[i] = m_tWaterLevel[i]; + } + + sys.m_fFixWindow = RBW2->Checked; + sys.m_fRestoreSubChannel = CBRestoreSub->Checked; + + if( RGRTTY->ItemIndex != MainVARI->m_RxSet[0].m_RTTYFFT ){ + MainVARI->SetRTTYFFT(RGRTTY->ItemIndex); + } + + sys.m_MFSK_SQ_Metric = CBMM->Checked; + sscanf(AnsiString(CBClock->Text).c_str(), "%lf", &dd); //JA7UDE 0428 + di = CBMC->Checked != sys.m_MFSK_Center; + if( (dd != SAMPFREQ) || di ){ + sys.m_MFSK_Center = CBMC->Checked; + MainVARI->SetSampleFreq(dd, di); + } + sscanf(AnsiString(CBTxOffset->Text).c_str(), "%lf", &dd); //JA7UDE 0428 + if( dd != SAMPTXOFFSET ){ + MainVARI->SetTxOffset(dd); + } + sscanf(AnsiString(CBFifoRX->Text).c_str(), "%u", &di); //JA7UDE 0428 + if( (di >= 4) && (di <= 32) ){ + MainVARI->SetRXFifo(di); + } + sscanf(AnsiString(CBFifoTX->Text).c_str(), "%u", &di); //JA7UDE 0428 + if( (di >= 4) && (di <= 32) ){ + MainVARI->SetTXFifo(di); + } + MainVARI->SetSoundCard(RGSoundIn->ItemIndex, AnsiString(CBSoundID->Text).c_str(), AnsiString(CBSoundIDTX->Text).c_str()); //JA7UDE 0428 + MainVARI->UpdatePriority(RGPriority->ItemIndex); + + if( (m_FontCharset != sys.m_FontCharset) || (m_FontName != sys.m_FontName) ){ + m_fLangChange = TRUE; + sys.m_FontCharset = m_FontCharset; + sys.m_FontName = m_FontName; + } + return TRUE; + } + OnWave(); + return FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::UdTxOffsetClick(TObject *Sender, + TUDBtnType Button) +{ + if( m_fDisEvent ) return; + + double f; + sscanf(AnsiString(CBTxOffset->Text).c_str(), "%lf", &f); //JA7UDE 0428 + if( Button == Comctrls::btNext ){ + f += 0.02; + } + else { + f -= 0.02; + } + char bf[128]; + sprintf(bf, "%.2lf", f); + m_fDisEvent++; + CBTxOffset->Text = bf; + m_fDisEvent--; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBTxOffsetChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + double fq; + sscanf(AnsiString(CBTxOffset->Text).c_str(), "%lf", &fq); //JA7UDE 0428 + if( (fq >= -300.0) && (fq <= 300.0) ){ + m_fDisEvent++; + UdTxOffset->Position = short(fq * 100.0); + m_fDisEvent--; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBRxFontClick(TObject *Sender) +{ + TFontDialog *pBox = new TFontDialog(this); + TPanel *pPanel = Sender == SBRxFont ? PCRx2 : PCTx2; + pBox->Font = pPanel->Font; + pBox->Font->Color = pPanel->Color; + OnWave(); + if( pBox->Execute() ){ + pPanel->Font = pBox->Font; + pPanel->Color = pBox->Font->Color; + if( pPanel == PCRx2 ){ + PCTx2->Font->Name = PCRx2->Font->Name; + PCTx2->Font->Charset = PCRx2->Font->Charset; + } + UpdateHint(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBRxCharClick(TObject *Sender) +{ + LOGFONT l1; + GetLogFont(&l1, PCRx2->Font); + TCodeView *pBox = new TCodeView(this); + Application->OnHint = m_fnHintProc; + pBox->Execute(NULL, 0, 0, PCRx2->Font); + Application->OnHint = DisplayHint; + LOGFONT l2; + GetLogFont(&l2, PCRx2->Font); + if( memcmp(&l1, &l2, sizeof(l1)) ){ + PCTx2->Font->Name = PCRx2->Font->Name; + PCTx2->Font->Charset = PCRx2->Font->Charset; + UpdateHint(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::PCRx1Click(TObject *Sender) +{ + TColorDialog *pBox = new TColorDialog(this); + pBox->Options << cdFullOpen; + TPanel *pPanel = (TPanel *)Sender; + pBox->Color = pPanel->Color; + OnWave(); + if( pBox->Execute() ){ + pPanel->Color = pBox->Color; + if( pPanel == PW1 ) PL->Color = PW1->Color; + PBL->Invalidate(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::UdClockClick(TObject *Sender, + TUDBtnType Button) +{ + if( m_fDisEvent ) return; + + double f; + sscanf(AnsiString(CBClock->Text).c_str(), "%lf", &f); //JA7UDE 0428 + if( Button == Comctrls::btNext ){ + f += 0.02; + } + else { + f -= 0.02; + } + char bf[128]; + sprintf(bf, "%.2lf", f); + m_fDisEvent++; + CBClock->Text = bf; + m_fDisEvent--; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBComPTTChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + + m_fComChange = TRUE; + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBRadioClick(TObject *Sender) +{ + TRADIOSetDlg *pBox = new TRADIOSetDlg(this); + RADIO.change = pBox->Execute(); + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBEngClick(TObject *Sender) +{ + if( SBJA->Down ){ + m_FontName = "MS Pゴシック"; + m_FontCharset = SHIFTJIS_CHARSET; + if( sys.m_MsgEng ){ + Application->MessageBox(L"MMVARIを再起動すると日本語モードになります.\r\n(Please restart MMVARI for Japanese mode)", L"MMVARI", MB_ICONINFORMATION|MB_OK); + } + } + else { + m_FontName = "Arial"; + m_FontCharset = ANSI_CHARSET; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBFontClick(TObject *Sender) +{ + TFontDialog *pBox = new TFontDialog(this); + pBox->Font->Name = m_FontName; + pBox->Font->Charset = m_FontCharset; + OnWave(); + if( pBox->Execute() ){ + m_FontName = pBox->Font->Name; + m_FontCharset = pBox->Font->Charset; + UpdateButton(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::PBLPaint(TObject *Sender) +{ + int xw = PBL->Width; + int yw = PBL->Height; + int x; + + TCanvas *pCanvas = PBL->Canvas; + + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = xw; rc.Bottom = yw; + pCanvas->Brush->Color = PW1->Color; + pCanvas->FillRect(rc); + + pCanvas->Pen->Width = 2; + TColor col[6]; + col[0] = PW2->Color; + col[1] = PW7->Color; + col[2] = PW8->Color; + col[3] = PW9->Color; + col[4] = PW10->Color; + col[5] = PW11->Color; + + for( int i = 0; i < 6; i++ ){ + x = m_tWaterLevel[i] * xw / 256; + pCanvas->Pen->Color = col[i]; + pCanvas->MoveTo(x, 0); + pCanvas->LineTo(x, yw); + } +} +//--------------------------------------------------------------------------- +int __fastcall TOptDlgBox::GetWLNo(int x) +{ + int i; + int *ip = m_tWaterLevel; + for( i = 0; i < 6; i++, ip++ ){ + int X = *ip * PBL->Width / 256; + if( (x > (X-3)) && (x < (X+3)) ){ + return i; + } + } + return -1; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::PBLMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( Button != mbLeft ) return; + + if( m_MouseWLN >= 0 ){ + m_MouseDown = TRUE; + switch(m_MouseWLN){ + case 0: + m_MinWL = 0; + m_MaxWL = m_tWaterLevel[1]; + break; + case 1: + case 2: + case 3: + case 4: + m_MinWL = m_tWaterLevel[m_MouseWLN-1]; + m_MaxWL = m_tWaterLevel[m_MouseWLN+1]; + break; + case 5: + m_MinWL = m_tWaterLevel[4]; + m_MaxWL = 256; + break; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::PBLMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_MouseDown ){ + int x = X * 256 / PBL->Width; + if( (x > m_MinWL) && (x < m_MaxWL) ){ + m_tWaterLevel[m_MouseWLN] = x; + PBLPaint(NULL); + } + } + else { + m_MouseWLN = GetWLNo(X); + PBL->Cursor = m_MouseWLN >= 0 ? crSizeWE : crDefault; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::PBLMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + m_MouseDown = FALSE; +} +//--------------------------------------------------------------------------- + +void __fastcall TOptDlgBox::SBWLCDClick(TObject *Sender) +{ + PW1->Color = clBlack; // back + PW3->Color = clWhite; // char + PW4->Color = clRed; // WAKU + PW5->Color = TColor(RGB(0,255,255)); // RX + PW6->Color = clBlue; // TX + + if( Sender == SBWLCD ){ + m_tWaterLevel[0] = 28; + m_tWaterLevel[1] = 100; + m_tWaterLevel[2] = 168; + m_tWaterLevel[3] = 192; + m_tWaterLevel[4] = 220; + m_tWaterLevel[5] = 240; + + PW2->Color = TColor(RGB(0,255,255)); // low + PW7->Color = clYellow; // mid-low + PW8->Color = TColor(RGB(255,128,0)); // mid + PW9->Color = TColor(RGB(255,0,128)); // mid-high + PW10->Color = clRed; // Peak + PW11->Color = clRed; // Peak + PW12->Color = clRed; // Peak + } + else { + m_tWaterLevel[0] = 10; + m_tWaterLevel[1] = 60; + m_tWaterLevel[2] = 134; + m_tWaterLevel[3] = 192; + m_tWaterLevel[4] = 220; + m_tWaterLevel[5] = 240; + + PW2->Color = TColor(16711680); // low + PW7->Color = TColor(16776960); // mid-low + PW8->Color = TColor(65535); // mid + PW9->Color = TColor(33023); // mid-high + PW10->Color = clRed; // Peak + PW11->Color = clRed; // Peak + PW12->Color = clRed; // Peak + } + PBL->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBSoundIDDropDown(TObject *Sender) +{ + if( m_fDisEvent ) return; + + if( !m_MMListW.IsQuery() ){ + m_MMListW.QueryList("MMW"); + for( int i = 0; i < m_MMListW.GetCount(); i++ ){ + CBSoundID->Items->Add(m_MMListW.GetItemName(i)); + } + CBSoundID->DropDownCount = CBSoundID->Items->Count; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBSoundIDChange(TObject *Sender) +{ + if( m_fDisEvent ) return; + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBComPTTDropDown(TObject *Sender) +{ + if( m_fDisEvent ) return; + + if( !m_MMListF.IsQuery() ){ + m_MMListF.QueryList("FSK"); + for( int i = 0; i < m_MMListF.GetCount(); i++ ){ + CBComPTT->Items->Add(m_MMListF.GetItemName(i)); + } + CBComPTT->DropDownCount = CBComPTT->Items->Count; + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBASClick(TObject *Sender) +{ + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(m_AS, "AS(CW)") ){ + AdjustAS(&m_AS); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBEventClick(TObject *Sender) +{ + int n = CBEvent->ItemIndex; + TMacEditDlg *pBox = new TMacEditDlg(this); + if( pBox->Execute(m_MacEvent[n], g_tMacEvent[n]) ){ + AdjustAS(&m_MacEvent[n]); + } + delete pBox; + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::SBEventCClick(TObject *Sender) +{ + int n = CBEvent->ItemIndex; + if( YesNoMB(sys.m_MsgEng ? "Clear contents of %s, and stop executing this event macro.":"%sの定義内容をクリアし、このイベントマクロを停止します.", g_tMacEvent[n]) == IDYES ){ + m_MacEvent[n] = ""; + UpdateUI(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TOptDlgBox::CBPBClick(TObject *Sender) +{ + UpdateUI(); +} +//--------------------------------------------------------------------------- + + + diff --git a/Option.dfm b/Option.dfm new file mode 100644 index 0000000..ec5fc8d Binary files /dev/null and b/Option.dfm differ diff --git a/Option.h b/Option.h new file mode 100644 index 0000000..673e49f --- /dev/null +++ b/Option.h @@ -0,0 +1,246 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef OptionH +#define OptionH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +#include "ComLib.h" +#include "MMLink.h" +//---------------------------------------------------------------------------- +class TOptDlgBox : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TPageControl *Page; + TTabSheet *TabRX; + TTabSheet *TabTX; + TTabSheet *TabMisc; + TGroupBox *GB1; + TComboBox *CBComPTT; + TCheckBox *CBComLock; + TGroupBox *GB2; + TGroupBox *GB3; + TLabel *L2; + TComboBox *CBFifoRX; + TLabel *Label1; + TComboBox *CBFifoTX; + TGroupBox *GB4; + TLabel *L4; + TComboBox *CBClock; + TLabel *L5; + TLabel *L6; + TUpDown *UdTxOffset; + TLabel *L7; + TRadioGroup *RGLoopBack; + TGroupBox *GB5; + TLabel *L9; + TEdit *ECallSign; + TGroupBox *GB6; + TLabel *L10; + TComboBox *CBAFCW; + TLabel *L11; + TRadioGroup *RGSoundIn; + TGroupBox *GB8; + TTrackBar *TBModGain; + TGroupBox *GB10; + TCheckBox *CBHPF; + TRadioGroup *RGPriority; + TGroupBox *GB11; + TSpeedButton *SBRxFont; + TSpeedButton *SBRxChar; + TPanel *PCRx1; + TPanel *PCRx2; + TPanel *PCRx3; + TPanel *PCRx4; + TGroupBox *GB12; + TSpeedButton *SBTxFont; + TPanel *PCTx1; + TPanel *PCTx2; + TPanel *PCTx3; + TGroupBox *GB13; + TPanel *PS1; + TPanel *PS2; + TPanel *PS3; + TPanel *PS4; + TPanel *PS5; + TPanel *PS6; + TGroupBox *GB14; + TPanel *PW1; + TPanel *PW2; + TPanel *PW3; + TPanel *PW4; + TPanel *PW5; + TPanel *PW6; + TComboBox *CBTxOffset; + TUpDown *UdClock; + TLabel *L13; + TEdit *EAFCL; + TUpDown *UdAFCL; + TLabel *L14; + TLabel *LH; + TSpeedButton *SBRadio; + TGroupBox *GBKey; + TComboBox *CBKTX; + TLabel *L15; + TComboBox *CBKTXOFF; + TLabel *L16; + TPanel *PCTx4; + TLabel *L17; + TLabel *L18; + TGroupBox *GB9; + TSpeedButton *SBJA; + TSpeedButton *SBEng; + TSpeedButton *SBFont; + TPanel *PW7; + TGroupBox *GB15; + TLabel *L20; + TTrackBar *TBATC; + TLabel *L21; + TLabel *L22; + TEdit *EATCL; + TUpDown *UdATCL; + TLabel *Label2; + TPanel *PCRx5; + TLabel *L23; + TComboBox *CBATCM; + TLabel *L24; + TGroupBox *GB16; + TCheckBox *CBCA; + TGroupBox *GB17; + TCheckBox *CBSWL; + TPanel *PW8; + TPanel *PW9; + TPanel *PL; + TPaintBox *PBL; + TLabel *L30; + TLabel *L31; + TPanel *PW10; + TPanel *PW11; + TPanel *PW12; + TCheckBox *CBRxUTC; + TCheckBox *CBMW; + TSpeedButton *SBAS; + TCheckBox *CBPB; + TCheckBox *CBShowCtrl; + TTrackBar *TBPB; + TLabel *LPB; + TGroupBox *GB18; + TCheckBox *CBMC; + TCheckBox *CBMM; + TSpeedButton *SBWLCD; + TSpeedButton *SBWCRT; + TGroupBox *GB33; + TLabel *L33; + TComboBox *CBEvent; + TSpeedButton *SBEvent; + TSpeedButton *SBEventC; + TRadioGroup *RGRTTY; + TComboBox *CBSoundID; + TLabel *LI; + TLabel *LO; + TComboBox *CBSoundIDTX; + TGroupBox *GB30; + TCheckBox *CBFSK; + TCheckBox *CBFSKINV; + TCheckBox *CBST; + TGroupBox *GBWindow; + TRadioButton *RBW1; + TRadioButton *RBW2; + TCheckBox *CBRestoreSub; + void __fastcall UdTxOffsetClick(TObject *Sender, TUDBtnType Button); + void __fastcall SBRxFontClick(TObject *Sender); + void __fastcall SBRxCharClick(TObject *Sender); + void __fastcall PCRx1Click(TObject *Sender); + void __fastcall CBTxOffsetChange(TObject *Sender); + void __fastcall UdClockClick(TObject *Sender, TUDBtnType Button); + + void __fastcall CBComPTTChange(TObject *Sender); + + void __fastcall SBRadioClick(TObject *Sender); + void __fastcall SBEngClick(TObject *Sender); + void __fastcall SBFontClick(TObject *Sender); + + void __fastcall PBLPaint(TObject *Sender); + void __fastcall PBLMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall PBLMouseMove(TObject *Sender, TShiftState Shift, int X, + int Y); + void __fastcall PBLMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + + void __fastcall SBWLCDClick(TObject *Sender); + void __fastcall CBSoundIDDropDown(TObject *Sender); + void __fastcall CBSoundIDChange(TObject *Sender); + void __fastcall CBComPTTDropDown(TObject *Sender); + void __fastcall SBASClick(TObject *Sender); + void __fastcall CBPBClick(TObject *Sender); + void __fastcall SBEventClick(TObject *Sender); + void __fastcall SBEventCClick(TObject *Sender); + +private: + BOOL m_fDisEvent; + TNotifyEvent m_fnHintProc; + + AnsiString m_FontName; + BYTE m_FontCharset; + + int m_MouseDown; + int m_MouseWLN; + int m_MinWL, m_MaxWL; + int m_tWaterLevel[6]; + + CMMList m_MMListF; + CMMList m_MMListW; + + AnsiString m_AS; + AnsiString m_MacEvent[macOnEnd]; +public: + BOOL m_fComChange; + BOOL m_fLangChange; +private: + void __fastcall UpdateButton(void); + void __fastcall UpdateHint(void); + void __fastcall UpdateUI(void); + int __fastcall GetWLNo(int x); + +public: + virtual __fastcall TOptDlgBox(TComponent* AOwner); + void __fastcall DisplayHint(TObject *Sender); + int __fastcall Execute(DWORD dwPage); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TOptDlgBox *OptDlgBox; +//---------------------------------------------------------------------------- +#endif + diff --git a/PlayDlg.cpp b/PlayDlg.cpp new file mode 100644 index 0000000..2b65c83 --- /dev/null +++ b/PlayDlg.cpp @@ -0,0 +1,131 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "PlayDlg.h" +#include "ComLib.h" +#include "dsp.h" +#include "Main.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TPlayDlgBox *PlayDlgBox; +//--------------------------------------------------------------------- +__fastcall TPlayDlgBox::TPlayDlgBox(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + + pWave = NULL; + m_DisEvent = 0; + + if( sys.m_MsgEng ){ + Caption = "Adjust Play position"; + CloseBtn->Caption = "Hide"; + StopBtn->Caption = "Stop"; + LRec->Caption = "RecTime"; + LNow->Caption = "NowTime"; + } + FormCenter(this); +} +//--------------------------------------------------------------------- +void __fastcall TPlayDlgBox::UpdateItem(void) +{ + char bf[32]; + + int h = int(pWave->m_length * 0.5 / SAMPFREQ); + int s = h % 60; + h /= 60; + int m = h % 60; + h /= 60; + sprintf(bf, "%u:%02u:%02u", h, m, s); + LTime->Caption = bf; + h = int(pWave->GetPos() * 0.5 / SAMPFREQ); + s = h % 60; + h /= 60; + m = h % 60; + h /= 60; + sprintf(bf, "%u:%02u:%02u", h, m, s); + LPos->Caption = bf; + m_DisEvent++; + ScrollBar->Max = int(pWave->m_length * 0.5 / SAMPFREQ); + ScrollBar->Position = int(pWave->GetPos() * 0.5 / SAMPFREQ); + CheckPause->Checked = pWave->m_pause; + m_DisEvent--; +} +//--------------------------------------------------------------------- +void __fastcall TPlayDlgBox::Execute(CWaveFile *wp) +{ + pWave = wp; + pWave->m_autopause = 1; + LName->Caption = pWave->m_FileName; + UpdateItem(); +// pWave->m_autopause = 0; + Visible = TRUE; +} +//--------------------------------------------------------------------- +void __fastcall TPlayDlgBox::ScrollBarChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + int pos = ScrollBar->Position; + pWave->Seek(pos * SAMPFREQ*2); + if( !CheckPause->Checked ) pWave->m_pause = 0; + + char bf[128]; + int h = pos; + int s = h % 60; + h /= 60; + int m = h % 60; + h /= 60; + sprintf(bf, "%u:%02u:%02u", h, m, s); + LPos->Caption = bf; +} +//--------------------------------------------------------------------------- +void __fastcall TPlayDlgBox::CheckPauseClick(TObject *Sender) +{ + if( m_DisEvent ) return; + + pWave->m_pause = CheckPause->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TPlayDlgBox::StopBtnClick(TObject *Sender) +{ + ::PostMessage(MainVARI->Handle, WM_WAVE, wavePlayDlg, DWORD(this)); +} +//--------------------------------------------------------------------------- +void __fastcall TPlayDlgBox::CloseBtnClick(TObject *Sender) +{ + Visible = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TPlayDlgBox::FormClose(TObject *Sender, + TCloseAction &Action) +{ + if( Action == caHide ){ + if( !pWave->m_mode ){ + StopBtnClick(NULL); + } + } +} +//--------------------------------------------------------------------------- diff --git a/PlayDlg.dfm b/PlayDlg.dfm new file mode 100644 index 0000000..357f1c7 Binary files /dev/null and b/PlayDlg.dfm differ diff --git a/PlayDlg.h b/PlayDlg.h new file mode 100644 index 0000000..420d199 --- /dev/null +++ b/PlayDlg.h @@ -0,0 +1,71 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef PlayDlgH +#define PlayDlgH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ + +#include "Wave.h" +//---------------------------------------------------------------------------- +class TPlayDlgBox : public TForm +{ +__published: + TButton *CloseBtn; + TScrollBar *ScrollBar; + TLabel *LRec; + TLabel *LNow; + TLabel *LTime; + TLabel *LPos; + TLabel *LName; + TCheckBox *CheckPause; + TButton *StopBtn;void __fastcall ScrollBarChange(TObject *Sender); + void __fastcall CheckPauseClick(TObject *Sender); + void __fastcall StopBtnClick(TObject *Sender); + + + void __fastcall CloseBtnClick(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); +private: + CWaveFile *pWave; + + int m_DisEvent; +public: + virtual __fastcall TPlayDlgBox(TComponent* AOwner); + + void __fastcall Execute(CWaveFile *wp); + void __fastcall UpdateItem(void); + +}; +//---------------------------------------------------------------------------- +//extern TPlayDlgBox *PlayDlgBox; +//---------------------------------------------------------------------------- +#endif diff --git a/Qsodlg.cpp b/Qsodlg.cpp new file mode 100644 index 0000000..1b9393f --- /dev/null +++ b/Qsodlg.cpp @@ -0,0 +1,526 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "QsoDlg.h" +#include "Country.h" +#include "MmcgDlg.h" +#include "Main.h" +//#include "TextEdit.h" +//#include "LogPic.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TQSODlgBox *QSODlgBox; +//--------------------------------------------------------------------- +__fastcall TQSODlgBox::TQSODlgBox(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + LStat->Font->Name = ((TForm *)AOwner)->Font->Name; + LStat->Font->Charset = ((TForm *)AOwner)->Font->Charset; + m_fp = NULL; + + EditHis->Items->Assign(MainVARI->HisRST->Items); + EditMy->Items->Assign(MainVARI->MyRST->Items); + if( sys.m_MsgEng ){ + Grid->Font->Name = ((TForm *)AOwner)->Font->Name; + Grid->Font->Charset = ((TForm *)AOwner)->Font->Charset; + Caption = "QSO Data"; + CancelBtn->Caption = "Close"; + OKBtn->Caption = "Write"; + } + switch(Log.m_LogSet.m_TimeZone){ + case 'I': + if( sys.m_LCID == 0x0412 ){ + LTimeZone->Caption = "KST"; + } + else { + LTimeZone->Caption = "JST"; + } + break; + default: + LTimeZone->Caption = "UTC"; + break; + } + if( Log.m_LogSet.m_DateType & 1 ){ + Grid->ColWidths[0] = (Grid->ColWidths[0] * 10) / 8; + } + m_EditFlag = 0; + m_fSelect = FALSE; + FormCenter(this); +} + +void __fastcall TQSODlgBox::UpdateBtn(void) +{ + OKBtn->Enabled = m_EditFlag; +} + +void __fastcall TQSODlgBox::SetCountry(void) +{ + m_Country = ""; + + if( !Cty.IsData() ) return; + LPCSTR p = ClipCC(m_fp->GetText()); + if( !(*p) ) return; + + SYSTEMTIME now; + GetUTC(&now); + + WORD tim = WORD((now.wHour * 60 + now.wMinute) * 30 + now.wSecond/2); + + int n; + if( (n = Cty.GetNoP(p))!=0 ){ + CTL *cp = Cty.GetCTL(n-1); + char bf[256]; + char tbf[5]; + tbf[0] = 0; + if( cp->TD != NULL ){ + tim = AdjustRolTimeUTC(tim, *cp->TD); + if( tim ){ + tim /= WORD(30); + sprintf(tbf, "%02u%02u%c", tim / 60, tim % 60, *cp->TD); + } + } + sprintf(bf, " %s/%s %s %s", + (cp->Name!=NULL) ? cp->Name : "", + (cp->Cont!=NULL) ? cp->Cont : "", + tbf, + (cp->QTH!=NULL) ? cp->QTH : "" + ); + m_Country = bf; + } +} + +int __fastcall TQSODlgBox::Execute(CLogFind *fp, SDMMLOG *sp, int n) +{ + m_fp = fp; + UpdateTextData(sp, n); + Grid->RowCount = fp->GetCount() ? fp->GetCount() + 1 : 2; +// Grid->TopRow = 1; + Grid->Row = 1; +// Grid->Enabled = FALSE; + m_fSelect = FALSE; + for( int i = 0; i < fp->GetCount(); i++ ){ + if( n == fp->pFindTbl[i] ){ + m_fSelect = TRUE; +// Grid->Enabled = TRUE; + Grid->Row = i + 1; + Grid->TopRow = (i > 4) ? Grid->Row - 4 : 1; + break; + } + } + SetCountry(); + char bf[512]; + strcpy(bf, sys.m_MsgEng ? "Initial Data":"QSOデータ初期値"); + if( m_fSelect ){ + if( sp->btime ){ + sprintf(bf, "[%s]", fp->GetText()); + strcat(bf, m_Country.c_str()); + } + else if( *fp->GetText() ){ + sprintf(bf, "[%s]", fp->GetText()); + strcat(bf, m_Country.c_str()); + } + } + Caption = bf; + UpdateStat(); + m_EditFlag = 0; + UpdateBtn(); + m_CurNo = n; + if( ShowModal() == IDOK ){ + if( m_EditFlag ){ + UpdateCurData(&m_sd); + Log.PutData(&m_sd, m_CurNo); + } + } + if( m_CurNo == n ){ + memcpy(sp, &m_sd, sizeof(SDMMLOG)); + } + else { + Log.GetData(sp, n); + } + return TRUE; +} + +int __fastcall TQSODlgBox::ShowFind(CLogFind *fp) +{ + m_fp = fp; + if( fp->GetCount() ){ + Log.GetData(&m_sd, fp->pFindTbl[0]); + m_CurNo = fp->pFindTbl[0]; + } + else { + memset(&m_sd, 0, sizeof(SDMMLOG)); + OKBtn->Enabled = FALSE; + } + SetCountry(); + char bf[512]; + UpdateTextData(&m_sd, fp->pFindTbl[0]); + Grid->RowCount = fp->GetCount() ? fp->GetCount() + 1 : 2; + Grid->TopRow = 1; + Grid->Row = 1; + sprintf(bf, "[%s]", fp->GetText()); + strcat(bf, m_Country.c_str()); + Caption = bf; + UpdateStat(); + m_EditFlag = 0; + m_fSelect = TRUE; + UpdateBtn(); + if( ShowModal() == IDOK ){ + if( m_EditFlag ){ + UpdateCurData(&m_sd); + Log.PutData(&m_sd, m_CurNo); + } + return TRUE; + } + else { + return FALSE; + } +} + +void __fastcall TQSODlgBox::UpdateTextData(SDMMLOG *sp, int n) +{ + m_CurNo = n; + memcpy(&m_sd, sp, sizeof(SDMMLOG)); + UpdateTextData(&m_sd); +} + +void __fastcall TQSODlgBox::UpdateTextData(SDMMLOG *sp) +{ + SDMMLOG sd; + memcpy(&sd, sp, sizeof(SDMMLOG)); + if( Log.m_LogSet.m_TimeZone != 'I' ){ + JSTtoUTC(&sd); + } + EditDate->Text = Log.GetDateString(&sd); + EditBgn->Text = Log.GetTimeString(sd.btime); + EditEnd->Text = Log.GetTimeString(sd.etime); + EditCall->Text = sp->call; + EditName->Text = sp->name; + EditQTH->Text = sp->qth; + EditHis->Text = sp->ur; + EditMy->Text = sp->my; + EditBand->Text = Log.GetFreqString(sp->band, sp->fq); + EditMode->Text = Log.GetModeString(sp->mode); + EditRem->Text = sp->rem; + EditQSL->Text = sp->qsl; + if( sp->env ){ + EditEnv->Text = sp->env; + } + else { + EditEnv->Text = ""; + } + EditOpt1->Text = Log.GetOptStr(0, sp); + EditOpt2->Text = Log.GetOptStr(1, sp); + EditUsr1->Text = Log.GetOptStr(2, sp); + EditUsr2->Text = Log.GetOptStr(3, sp); + EditS->Text = sp->send; + EditR->Text = sp->recv; + EditM->Text = sp->cq; + EditPow->Text = sp->pow; + m_EditFlag = 0; + UpdateBtn(); +} + +void __fastcall TQSODlgBox::UpdateCurData(SDMMLOG *sp) +{ + int y, m, d, h; + + switch(Log.m_LogSet.m_DateType){ + case 2: // dd-mm-yy + case 3: // dd-mm-yyyy + if( sscanf(AnsiString(EditDate->Text).c_str(), "%u.%u.%u", &d, &m, &y) == 3 ){ //JA7UDE 0428 + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + break; + case 4: // mm-dd-yy + case 5: // mm-dd-yyyy + if( sscanf(AnsiString(EditDate->Text).c_str(), "%u.%u.%u", &m, &d, &y) == 3 ){ //JA7UDE 0428 + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + break; + default: // yy-mm-dd, yyyy-mm-dd + if( sscanf(AnsiString(EditDate->Text).c_str(), "%u.%u.%u", &y, &m, &d) == 3 ){ //JA7UDE 0428 + sp->year = BYTE(y % 100); + sp->date = WORD(m * 100 + d); + } + break; + } + if( !EditBgn->Text.IsEmpty() ){ + if( sscanf(AnsiString(EditBgn->Text).c_str(), "%u", &d) == 1){ //JA7UDE 0428 + h = d / 100; + m = d % 100; + if( (sp->btime / 30) != (h * 60 + m) ){ + sp->btime = WORD((h * 60 + m) * 30 + 1); + } + } + } + if( !EditEnd->Text.IsEmpty() ){ + if( sscanf(AnsiString(EditEnd->Text).c_str(), "%u", &d) == 1){ //JA7UDE 0428 + h = d / 100; + m = d % 100; + if( (sp->etime / 30) != (h * 60 + m) ){ + sp->etime = WORD((h * 60 + m) * 30 + 1); + } + } + } + StrCopy(sp->call, AnsiString(EditCall->Text).c_str(), MLCALL); //JA7UDE 0428 + jstrupr(sp->call); + StrCopy(sp->name, AnsiString(EditName->Text).c_str(), MLNAME); //JA7UDE 0428 + if( Log.m_LogSet.m_UpperName ) jstrupr(sp->name); + StrCopy(sp->qth, AnsiString(EditQTH->Text).c_str(), MLQTH); //JA7UDE 0428 + if( Log.m_LogSet.m_UpperQTH ) jstrupr(sp->qth); + StrCopy(sp->ur, AnsiString(EditHis->Text).c_str(), MLRST); //JA7UDE 0428 + jstrupr(sp->ur); + StrCopy(sp->my, AnsiString(EditMy->Text).c_str(), MLRST); //JA7UDE 0428 + jstrupr(sp->my); + Log.SetFreq(sp, AnsiString(EditBand->Text).c_str()); //JA7UDE 0428 + Log.SetMode(sp, AnsiString(EditMode->Text).c_str()); //JA7UDE 0428 + StrCopy(sp->rem, AnsiString(EditRem->Text).c_str(), MLREM); //JA7UDE 0428 + if( Log.m_LogSet.m_UpperREM ) jstrupr(sp->rem); + StrCopy(sp->qsl, AnsiString(EditQSL->Text).c_str(), MLQSL); //JA7UDE 0428 + if( Log.m_LogSet.m_UpperQSL ) jstrupr(sp->qsl); + if( sscanf(AnsiString(EditEnv->Text).c_str(), "%u", &d) == 1){ //JA7UDE 0428 + sp->env = WORD(d); + } + else { + sp->env = 0; + } + Log.SetOptStr(0, sp, AnsiString(EditOpt1->Text).c_str()); //JA7UDE 0428 + Log.SetOptStr(1, sp, AnsiString(EditOpt2->Text).c_str()); //JA7UDE 0428 + Log.SetOptStr(2, sp, AnsiString(EditUsr1->Text).c_str()); //JA7UDE 0428 + Log.SetOptStr(3, sp, AnsiString(EditUsr2->Text).c_str()); //JA7UDE 0428 + sp->send = *EditS->Text.c_str(); + sp->recv = *EditR->Text.c_str(); + sp->cq = *EditM->Text.c_str(); + sp->cq = char(toupper(sp->cq)); + StrCopy(sp->pow, AnsiString(EditPow->Text).c_str(), MLPOW); //JA7UDE 0428 + jstrupr(sp->pow); + if( Log.m_LogSet.m_TimeZone != 'I' ){ + UTCtoJST(sp); + } +} +//--------------------------------------------------------------------- +void __fastcall TQSODlgBox::UpdateStat(void) +{ + char bf[256]; + + int cmp1max = m_fp->m_FindCmp1Max; + int cmp2max = m_fp->m_FindCmp2Max; + if( cmp2max && (m_fp->pFindTbl[0] == Log.m_CurNo) ){ + cmp1max--; + cmp2max--; + } + if( sys.m_MsgEng ){ + if( !cmp2max ){ + strcpy(bf, "No Data"); + } + else if( cmp1max != cmp2max ){ + sprintf(bf, "Perfect: %u SameCall: %u", cmp1max, cmp2max - cmp1max); + } + else { + sprintf(bf, "Perfect: %u", cmp1max ); + } + } + else { + if( !cmp2max ){ + strcpy(bf, "一致なし"); + } + else if( cmp1max != cmp2max ){ + sprintf(bf, "完全一致: %u件 同一コール: %u件", cmp1max, cmp2max - cmp1max); + } + else { + sprintf(bf, "完全一致: %u件", cmp1max ); + } + } + LStat->Caption = bf; +} +//---------------------------------------------------------------------#if 0 +void __fastcall TQSODlgBox::GridDrawCell(TObject *Sender, int Col, int Row, + TRect &Rect, TGridDrawState State) +{ + char bf[256]; + SDMMLOG sd; + + Grid->Canvas->FillRect(Rect); + int X = Rect.Left + 4; + int Y = Rect.Top + 2; + + if( Row ){ + Row--; + bf[0] = 0; + if( Row < m_fp->GetCount() ){ + Log.GetData(&sd, m_fp->pFindTbl[Row]); + if( ((Row+1) != Grid->Row)||(Col != Grid->Col) ){ + if( m_fp->pFindTbl[Row] == Log.m_CurNo ){ + Grid->Canvas->Font->Color = clLtGray; + } + else if( Row < m_fp->m_FindCmp1Max ){ + Grid->Canvas->Font->Color = clRed; + } + else if( Row < m_fp->m_FindCmp2Max ){ + Grid->Canvas->Font->Color = clGreen; + } + } + if( Log.m_LogSet.m_TimeZone != 'I' ){ + JSTtoUTC(&sd); + } + } + else { + memset(&sd, 0, sizeof(SDMMLOG)); + } + switch(Col){ + case 0: // Date + strcpy(bf, Log.GetDateString(&sd)); + break; + case 1: // Time + strcpy(bf, Log.GetTimeString(sd.btime)); + break; + case 2: // Call + strcpy(bf, sd.call); + break; + case 3: // M + bf[0] = sd.cq; + bf[1] = 0; + break; + case 4: // HisRST + strcpy(bf, sd.ur); + break; + case 5: // MyRST + strcpy(bf, sd.my); + break; + case 6: // Band + strcpy(bf, Log.GetFreqString(sd.band, sd.fq)); + break; + case 7: // Mode + strcpy(bf, Log.GetModeString(sd.mode)); + break; + case 8: // Pow + strcpy(bf, sd.pow); + break; + case 9: // Name + strcpy(bf, sd.name); + break; + case 10: // QTH + strcpy(bf, sd.qth); + break; + case 11: // S + bf[0] = sd.send; + bf[1] = 0; + break; + case 12: // R + bf[0] = sd.recv; + bf[1] = 0; + break; + case 13: // REM + strcpy(bf, sd.rem); + break; + case 14: // QSL + strcpy(bf, sd.qsl); + break; + case 15: // etime; + strcpy(bf, Log.GetTimeString(sd.etime)); + break; + case 16: // Env + if( sd.env ) sprintf(bf, "%u", sd.env); + break; + case 17: // Opt1 + strcpy(bf, sd.opt1); + break; + case 18: // Opt2 + strcpy(bf, sd.opt2); + break; + case 19: // Usr1 + break; + case 20: // Usr2 + break; + } + Grid->Canvas->TextRect(Rect, X, Y, bf); + } + else { // タイトル + LPCSTR _tt[]={ + "Date","JST","Call","M", "His","My","Band","Mode","Pow","Name","QTH","S","R", + "Note","QSL", "End", "Env", "Opt1", "Opt2", "Usr1", "Usr2", + }; + if( Col == 1 ){ + Grid->Canvas->TextRect(Rect, X, Y, LTimeZone->Caption); + } + else { + Grid->Canvas->TextRect(Rect, X, Y, _tt[Col]); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TQSODlgBox::GridSelectCell(TObject *Sender, int Col, + int Row, bool &CanSelect) +{ + if( !m_fSelect ) return; + + int n = Row - 1; + if( n < m_fp->GetCount() ){ + if( m_CurNo != m_fp->pFindTbl[n] ){ + if( m_EditFlag ){ + UpdateCurData(&m_sd); + Log.PutData(&m_sd, m_CurNo); + m_EditFlag = 0; + } + m_CurNo = m_fp->pFindTbl[n]; + Log.GetData(&m_sd, m_CurNo); + UpdateTextData(&m_sd, m_CurNo); + Grid->Invalidate(); + UpdateBtn(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TQSODlgBox::SBMMCGClick(TObject *Sender) +{ + TMmcgDlgBox *pBox = new TMmcgDlgBox(this); + + AnsiString qth = EditQTH->Text; + AnsiString opt = EditOpt1->Text; + AnsiString cal = EditCall->Text; //JA7UDE 0428 + if( pBox->Execute(cal, qth, opt) == TRUE ){ //JA7UDE 0428 + EditQTH->Text = qth; + EditOpt1->Text = opt; + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TQSODlgBox::EditDateChange(TObject *Sender) +{ + m_EditFlag = 1; + UpdateBtn(); +} +//--------------------------------------------------------------------------- +void __fastcall TQSODlgBox::GridClick(TObject *Sender) +{ + if( !m_fSelect ){ + Grid->Row = 1; + return; + } +} +//--------------------------------------------------------------------------- diff --git a/Qsodlg.dfm b/Qsodlg.dfm new file mode 100644 index 0000000..4f4dfbd Binary files /dev/null and b/Qsodlg.dfm differ diff --git a/Qsodlg.h b/Qsodlg.h new file mode 100644 index 0000000..30eac25 --- /dev/null +++ b/Qsodlg.h @@ -0,0 +1,133 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef QsoDlgH +#define QsoDlgH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +//---------------------------------------------------------------------------- +#include "LogFile.h" +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TQSODlgBox : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TGroupBox *GB1; + TStringGrid *Grid; + TLabel *Label1; + TEdit *EditDate; + TLabel *LTimeZone; + TEdit *EditBgn; + TLabel *Label3; + TEdit *EditEnd; + TLabel *Label4; + TEdit *EditCall; + TLabel *Label5; + TEdit *EditName; + TLabel *Label6; + TEdit *EditQTH; + TLabel *Label7; + TComboBox *EditMy; + TLabel *Label8; + TComboBox *EditHis; + TLabel *Label9; + TComboBox *EditBand; + TLabel *Label10; + TComboBox *EditMode; + TLabel *Label11; + TEdit *EditRem; + TLabel *Label12; + TEdit *EditQSL; + TLabel *Label13; + TLabel *Label14; + TLabel *Label15; + TEdit *EditEnv; + TLabel *Label16; + TEdit *EditOpt1; + TLabel *Label17; + TEdit *EditOpt2; + TLabel *Label18; + TComboBox *EditM; + TComboBox *EditS; + TComboBox *EditR; + TLabel *Label19; + TComboBox *EditPow; + TLabel *LStat; + TLabel *Label20; + TEdit *EditUsr1; + TLabel *Label21; + TEdit *EditUsr2; + TSpeedButton *SBMMCG; + void __fastcall SBMMCGClick(TObject *Sender); + void __fastcall EditDateChange(TObject *Sender); + void __fastcall GridSelectCell(TObject *Sender, int Col, int Row, + bool &CanSelect); + void __fastcall GridDrawCell(TObject *Sender, int Col, int Row, + TRect &Rect, TGridDrawState State); + + + + void __fastcall GridClick(TObject *Sender); +private: + CLogFind *m_fp; + int m_EditFlag; + + int m_CurNo; + SDMMLOG m_sd; + + BOOL m_fSelect; + AnsiString m_Country; + void __fastcall UpdateBtn(void); + void __fastcall SetCountry(void); + +// CAlignList AlignList; +// void __fastcall EntryAlignControl(void); + void __fastcall UpdateStat(void); + + void __fastcall UpdateTextData(SDMMLOG *sp, int n); + void __fastcall UpdateTextData(SDMMLOG *sp); + void __fastcall UpdateCurData(SDMMLOG *sp); +public: + virtual __fastcall TQSODlgBox(TComponent* AOwner); + int __fastcall Execute(CLogFind *fp, SDMMLOG *sp, int n); + int __fastcall ShowFind(CLogFind *fp); +}; +//---------------------------------------------------------------------------- +//extern TQSODlgBox *QSODlgBox; +//---------------------------------------------------------------------------- +#endif diff --git a/RMenuDlg.cpp b/RMenuDlg.cpp new file mode 100644 index 0000000..02510a3 --- /dev/null +++ b/RMenuDlg.cpp @@ -0,0 +1,145 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "RMenuDlg.h" +#include "Main.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TRMenuDialog *RMenuDialog; +static LPCSTR g_help={ +"コマンド\r\n" +"\r\n" +"\\$##... ##=00-FF, 送信する複数バイトを16進数で定義する\r\n" +" (例:\\$FE55AA -> FEh,55h,AAh)\r\n" +"\\x## ##=00-FF, 送信する1バイトを16進数で定義する\r\n" +" (例:\\xFE\\x55\\xAA -> FEh, 55h, AAh)\r\n" +"\\w## ##=00-99, ディレイ時間を10ms単位の10進数で定義する\r\n" +" (例:\\w05 -> wait 50ms)\r\n" +"\\r キャリッジリターンを送信する\r\n" +"\\n ラインフィードを送信する\r\n" +"\\c.... 以降はすべてコメント\r\n" +"\\\\ '\\'文字を送信する\r\n" +"その他 その文字列を送信する\r\n" +"\r\n" +"##の代わりにxxを記述すると、その部分はxx入力ボックスで定義した16進数に置き換わります。\r\n" +"この変換はICOMの機種アドレスを指定する場合に使用します。\r\n" +" 例:\\$FEFExxE01C0001FD (xxの部分が定義内容に置き換わる)" +}; +static LPCSTR g_helpeng={ +" This command sends a radio command to the rig. It will work for any rig. Use the following keyword to specify byte data in hexadecimal number.\r\n" +"\r\n" +"\\$##... ##=00-FF, Specify the byte data string in the hexadecimal format\r\n" +" (Example: \\$FE55AA -> $FE,$55,$AA)\r\n" +" ICOM CI-V address can be expressed by xx\r\n" +"\\x## ##=00-FF, Specify one byte in the hexadecimal format\r\n" +" (Example: \\xFE\\x55\\xAA -> $FE, $55, $AA)\r\n" +"\\w## ##=00-99, Specify the delay time\r\n" +" (Example: \\w05 -> wait 50ms)\r\n" +"\\r Send a carriage return\r\n" +"\\n Send a line feed\r\n" +"\\c.... Comment\r\n" +"\\\\ '\\' send character\r\n" +"Others Send the character as is" +}; + +//--------------------------------------------------------------------- +__fastcall TRMenuDialog::TRMenuDialog(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + + if( sys.m_MsgEng ){ + LH->Font->Name = "Arial"; + LH->Font->Charset = ((TForm *)AOwner)->Font->Charset; + + L1->Caption = "Caption"; + L2->Caption = "Command"; + Caption = "Edit menu"; + SBDel->Caption = "Delete this menu"; + SBIns->Caption = "Insert this menu"; + CancelBtn->Caption = "Cancel"; + LH->Caption = g_helpeng; + } + else { + LH->Caption = g_help; + } +} +//--------------------------------------------------------------------- +void __fastcall TRMenuDialog::UpdateUI(void) +{ + if( SBIns->Visible ){ + SBIns->Enabled = MainVARI->m_nRadioMenu < RADIOMENUMAX; + } +} +//--------------------------------------------------------------------- +int __fastcall TRMenuDialog::Execute(AnsiString &strTTL, AnsiString &strCMD, int fAdd) +{ + if( fAdd ){ + Caption = sys.m_MsgEng ? "Add menu" : "メニューの追加"; + SBDel->Visible = FALSE; + SBIns->Visible = FALSE; + } + ETTL->Text = strTTL; + ECMD->Text = strCMD; + UpdateUI(); + int r = ShowModal(); + strTTL = ETTL->Text; + strCMD = ECMD->Text; + return r; +} +//--------------------------------------------------------------------- +void __fastcall TRMenuDialog::SBDelClick(TObject *Sender) +{ + ModalResult = 1024; +} +//--------------------------------------------------------------------------- +void __fastcall TRMenuDialog::SBInsClick(TObject *Sender) +{ + ModalResult = 1025; +} +//--------------------------------------------------------------------------- +void __fastcall TRMenuDialog::SBRefClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Open command file"; + pBox->Filter = "Command files(*.rcm)|*.rcm|"; + } + else { + pBox->Title = "コマンド定義ファイルを開く"; + pBox->Filter = "コマンド定義ファイル(*.rcm)|*.rcm|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "rcm"; + pBox->InitialDir = sys.m_BgnDir; + if( pBox->Execute() == TRUE ){ + ECMD->Text = pBox->FileName.c_str(); + } + delete pBox; +} +//--------------------------------------------------------------------------- + diff --git a/RMenuDlg.dfm b/RMenuDlg.dfm new file mode 100644 index 0000000..a9440d8 Binary files /dev/null and b/RMenuDlg.dfm differ diff --git a/RMenuDlg.h b/RMenuDlg.h new file mode 100644 index 0000000..b4fbe7f --- /dev/null +++ b/RMenuDlg.h @@ -0,0 +1,64 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef RMenuDlgH +#define RMenuDlgH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +#include "ComLib.h" +//---------------------------------------------------------------------------- +class TRMenuDialog : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TLabel *L1; + TLabel *L2; + TEdit *ETTL; + TEdit *ECMD; + TSpeedButton *SBDel; + TLabel *LH; + TSpeedButton *SBIns; + TSpeedButton *SBRef; + void __fastcall SBDelClick(TObject *Sender); + void __fastcall SBInsClick(TObject *Sender); + + void __fastcall SBRefClick(TObject *Sender); +private: + void __fastcall UpdateUI(void); +public: + virtual __fastcall TRMenuDialog(TComponent* AOwner); + + int __fastcall Execute(AnsiString &strTTL, AnsiString &strCMD, int fAdd = FALSE); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TRMenuDialog *RMenuDialog; +//---------------------------------------------------------------------------- +#endif diff --git a/RadioSet.cpp b/RadioSet.cpp new file mode 100644 index 0000000..5e6dfc6 --- /dev/null +++ b/RadioSet.cpp @@ -0,0 +1,593 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "RadioSet.h" +#include "Main.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +LPCSTR __MK[]={ + "YAESU FT-1000D, 1000MP, 920", //AA6YQ 1.66 cosmetic, MakerIndex=0 + "YAESU FT-9000, 2000, 950, 450", //AA6YQ 1.66 , MakerIndex=1 + "YAESU FT-736, 817, 847, 857, 897", //AA6YQ 1.66 cosmetic, MakerIndex=2 + "Icom xx=addr 01-7F", // , MakerIndex=3 + "Ten-Tec Omni VI xx=addr 00-64", // , MakerIndex=4 + "Kenwood, Elecraft ", // , MakerIndex=5 + "JRC JST-245", // , MakerIndex=6 + "Clear", // , MakerIndex=6 + NULL, // , MakerIndex=8 +}; +LPCSTR __MT[][3]={ + {"", "\\$000000000F", "\\$000000010F\\w10" }, + {"", "TX0;", "TX1;\\w10" }, //AA6YQ 1.66 + {"\\$0000000000", "\\$0000000088", "\\$0000000008\\w10" }, + {"", "\\$FEFExxE01C0000FD", "\\$FEFExxE01C0001FD\\w10" }, + {"", "\\$FEFExxE01602FD", "\\$FEFExxE01601FD\\w10" }, + {"", "RX;", "TX;\\w10" }, + {"", "H1\\rX0\\rH0\\r", "H1\\rX1\\rH0\\r\\w10" }, + {"", "", "" }, +}; + +#define MAKER_UNKNOWN 7 + +typedef struct { + LPCSTR pKey; + int r; +}POLLDEF; + +const POLLDEF __VT0[]={ + { "NONE", 0 }, + { "FT-1000MP", RADIO_POLLYAESUHF }, + { "FT-1000D", RADIO_POLLFT1000D }, + { "FT-920", RADIO_POLLFT920 }, + { NULL, 0 }, +}; +const POLLDEF __VT1[]={ + { "NONE", 0 }, + { "FT-9000", RADIO_POLLFT9000 }, //1.66B AA6YQ + { "FT-2000", RADIO_POLLFT2000 }, //1.66B AA6YQ + { "FT-950", RADIO_POLLFT950 }, //1.66B AA6YQ + { "FT-450", RADIO_POLLFT450 }, //1.66B AA6YQ + { NULL, 0 }, +}; +const POLLDEF __VT2[]={ + { "NONE", 0 }, + { "FT-817, 847, 857, 897", RADIO_POLLYAESUVU }, + { NULL, 0 }, +}; +const POLLDEF __VT3[]={ + { "NONE", 0 }, + { "ICOM CI-V", RADIO_POLLICOM }, + { "ICOM CI-V (no inquiry)", RADIO_POLLICOMN }, + { NULL, 0 }, +}; +const POLLDEF __VT4[]={ + { "NONE", 0 }, + { "Ten-Tec Omni VI", RADIO_POLLOMNIVI }, + { "Ten-Tec Omni VI (no inquiry)", RADIO_POLLOMNIVIN }, + { NULL, 0 }, +}; +const POLLDEF __VT5[]={ + { "NONE", 0 }, + { "KENWOOD", RADIO_POLLKENWOOD }, + { "KENWOOD (use auto info)", RADIO_POLLKENWOODN }, + { NULL, 0 }, +}; +const POLLDEF __VT6[]={ + { "NONE", 0 }, + { "JST245", RADIO_POLLJST245 }, + { "JST245 (use auto info)", RADIO_POLLJST245N }, + { NULL, 0 }, +}; +const POLLDEF __VTUNKNOWN[]={ + { "NONE", 0 }, + { "YAESU FT-1000MP", RADIO_POLLYAESUHF }, + { "YAESU FT-1000D", RADIO_POLLFT1000D }, + { "YAESU FT-920", RADIO_POLLFT920 }, + { "YAESU FT-817, 847, 857, 897", RADIO_POLLYAESUVU }, + { "YAESU FT-9000", RADIO_POLLFT9000 }, //1.66B AA6YQ + { "YAESU FT-2000", RADIO_POLLFT2000 }, //1.66B AA6YQ + { "YAESU FT-950", RADIO_POLLFT950 }, //1.66B AA6YQ + { "YAESU FT-450", RADIO_POLLFT450 }, //1.66B AA6YQ + { "ICOM CI-V", RADIO_POLLICOM }, + { "ICOM CI-V (no inquiry)", RADIO_POLLICOMN }, + { "Ten-Tec Omni VI", RADIO_POLLOMNIVI }, + { "Ten-Tec Omni VI (no inquiry)", RADIO_POLLOMNIVIN }, + { "KENWOOD", RADIO_POLLKENWOOD }, + { "KENWOOD (use auto info)", RADIO_POLLKENWOODN }, + { "JST245", RADIO_POLLJST245 }, + { "JST245 (use auto info)", RADIO_POLLJST245N }, + { NULL, 0 }, +}; +const POLLDEF *__VL[]={ + __VT0, __VT1, __VT2, __VT3, __VT4, __VT5, __VT6, __VTUNKNOWN, NULL, +}; +//--------------------------------------------------------------------- +__fastcall TRADIOSetDlg::TRADIOSetDlg(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + Caption = "Radio command"; + CancelBtn->Caption = "Cancel"; + + GB1->Caption = "Port definition"; + GCmd->Caption = "Rig and commands"; + LVFO->Caption = "VFO polling"; + LInt->Caption = "Polling interval"; + RGFS->Caption = "Frequency offset"; + AddrScan->Caption = "Scan addr."; + + BitLen->Hint = "Choose 8Bits"; + Parity->Hint = "Choose None"; + GB3->Hint = "Uncheck both boxes (It might be FB)"; + GB2->Hint = "Check this, if you control PTT with the signal line"; + + PortName->Hint = "Put the port name"; + Baud->Hint = "4800bps is normal"; + ByteWait->Hint = "Choose 0ms with recent Rig"; + Maker->Hint = "Rig type"; + AddrScan->Hint = "Check this, if you don't know Rig-address"; + Cmdxx->Hint = "Rig-address (It depends on the Rig)"; + CmdInit->Hint = "Initialization command (FT847 is required)"; + CmdRx->Hint = "PTT to RX command"; + CmdTx->Hint = "PTT to TX command"; + VFOType->Hint = "Rig name of VFO polling"; + PollInt->Hint = "Choose long time if the frequency is disguised"; + RGFS->Hint = "Frequency correction by the mode"; + } + int i; + for( i = 0; __MK[i] != NULL; i++ ){ + Maker->Items->Add(__MK[i]); + } + m_InitWidth = CmdInit->Width; + m_PollType = 0; + m_Maker = 0; + m_MMList.QueryList("MMR"); + for( int i = 0; i < m_MMList.GetCount(); i++ ){ + PortName->Items->Insert(1, m_MMList.GetItemName(i)); + } + PortName->DropDownCount = PortName->Items->Count; + FormCenter(this); + m_DisEvent = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::DisplayHint(TObject *Sender) +{ + LH->Caption = GetLongHint(Application->Hint); +} +//--------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::UpdateUI(void) +{ + int f; + if( !strcmpi(AnsiString(PortName->Text).c_str(), "PSKGNR")|| //JA7UDE 0428 + !strcmpi(AnsiString(PortName->Text).c_str(), "WD5GNR")|| + !strcmpi(AnsiString(PortName->Text).c_str(), "LOGGER") ){ + GCmd->Visible = FALSE; + if( !strcmpi(AnsiString(PortName->Text).c_str(), "LOGGER") ){ //JA7UDE 0428 + GGNR->Visible = FALSE; +// LTNX->Caption = "Thanks to Bob Furzer (K4CY) who is releasing the fine programs."; + } + else { + GGNR->Visible = TRUE; +// LTNX->Caption = "Thanks to Al Williams (WD5GNR) who is releasing the fine programs."; + } + LGNR->Visible = OpenGNR->Checked; + CmdGNR->Visible = OpenGNR->Checked; + RefBtn->Visible = OpenGNR->Checked; + LPTT->Visible = OpenGNR->Checked; + Maker->Visible = FALSE; + LoadBtn->Visible = FALSE; + SaveBtn->Visible = FALSE; + f = FALSE; + } + else { + GGNR->Visible = FALSE; + GCmd->Visible = TRUE; + Maker->Visible = TRUE; + LoadBtn->Visible = TRUE; + SaveBtn->Visible = TRUE; + f = IsXX(); + Lxx->Visible = f; + Cmdxx->Visible = f; + AddrScan->Enabled = f && m_PollType; + if( f ){ + CmdInit->Width = m_InitWidth; + } + else { + CmdInit->Width = CmdRx->Width; + } + RGFS->Enabled = m_PollType; + LInt->Enabled = m_PollType; + LInts->Enabled = m_PollType; + PollInt->Enabled = m_PollType; + f = (m_MMList.IndexOf(AnsiString(PortName->Text).c_str()) < 0) ? TRUE : FALSE; //JA7UDE 0428 + } + Label2->Enabled = f; + Baud->Enabled = f; + BitLen->Enabled = f; + Stop->Enabled = f; + Parity->Enabled = f; + GB3->Enabled = f; + flwXON->Enabled = f; + flwCTS->Enabled = f && !CBPTT->Checked; + CBPTT->Enabled = f; + Label3->Enabled = f; + ByteWait->Enabled = f; + Label8->Enabled = f; + f = TRUE; + LVFO->Visible = f; + VFOType->Visible = f; + LInt->Visible = f; + LInts->Visible = f; + PollInt->Visible = f; + LVFO->Enabled = f; + VFOType->Enabled = f; + if( !f ){ + LInt->Enabled = f; + LInts->Enabled = f; + PollInt->Enabled = f; + } +} +//--------------------------------------------------------------------- +int __fastcall TRADIOSetDlg::Execute(void) +{ + PortName->Text = RADIO.StrPort; + Baud->Text = RADIO.BaudRate; + BitLen->ItemIndex = RADIO.BitLen; + Parity->ItemIndex = RADIO.Parity; + Stop->ItemIndex = RADIO.Stop; + flwXON->Checked = RADIO.flwXON; + flwCTS->Checked = RADIO.flwCTS; + CBPTT->Checked = RADIO.usePTT; + + ByteWait->Text = int(RADIO.ByteWait); + + char bf[32]; + sprintf( bf, "%02X", RADIO.Cmdxx); + Cmdxx->Text = bf; + CmdInit->Text = RADIO.CmdInit; + CmdRx->Text = RADIO.CmdRx; + CmdTx->Text = RADIO.CmdTx; + + CmdGNR->Text = RADIO.cmdGNR; + OpenGNR->Checked = RADIO.openGNR; + m_PollType = RADIO.PollType; + RGFS->ItemIndex = RADIO.PollOffset; + PollInt->Text = (RADIO.PollInterval + 2)/10.0; + AddrScan->Checked = RADIO.PollScan; + SetMaker(); + UpdateUI(); + m_fnHintProc = Application->OnHint; + Application->OnHint = DisplayHint; + int r = ShowModal(); + Application->OnHint = m_fnHintProc; + if( r == IDOK ){ + StrCopy(RADIO.StrPort, AnsiString(PortName->Text).c_str(), 31); //JA7UDE 0428 + int dd; + if( sscanf(AnsiString(Baud->Text).c_str(), "%u", &dd) == 1 ){ //JA7UDE 0428 + RADIO.BaudRate = dd; + } + RADIO.BitLen = BitLen->ItemIndex; + RADIO.Parity = Parity->ItemIndex; + RADIO.Stop = Stop->ItemIndex; + RADIO.flwXON = flwXON->Checked; + RADIO.flwCTS = flwCTS->Checked; + RADIO.usePTT = CBPTT->Checked; + + if( sscanf(AnsiString(ByteWait->Text).c_str(), "%u", &dd) == 1 ){ //JA7UDE 0428 + if( (dd >= 0) && (dd <= 1000) ){ + RADIO.ByteWait = dd; + } + } + if( sscanf(AnsiString(Cmdxx->Text).c_str(), "%X", &dd) == 1 ){ //JA7UDE 0428 + RADIO.Cmdxx = dd & 0x000000ff; + } + RADIO.CmdInit = CmdInit->Text; + RADIO.CmdRx = CmdRx->Text; + RADIO.CmdTx = CmdTx->Text; + + RADIO.cmdGNR = CmdGNR->Text; + RADIO.openGNR = OpenGNR->Checked; + + RADIO.PollType = m_PollType; + RADIO.PollOffset = RGFS->ItemIndex; + double d; + if( sscanf(AnsiString(PollInt->Text).c_str(), "%lf", &d) == 1 ){ //JA7UDE 0428 + if( d < 0.2 ) d = 0.2; + RADIO.PollInterval = int((d * 10.0) - 2); + if( RADIO.PollInterval < 0 ) RADIO.PollInterval = 0; + } + RADIO.PollScan = AddrScan->Checked; + RADIO.change = 1; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::LoadBtnClick(TObject *Sender) +{ +// + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Open command file"; + pBox->Filter = "Command files(*.rcm)|*.rcm|"; + } + else { + pBox->Title = "コマンド定義ファイルを開く"; + pBox->Filter = "コマンド定義ファイル(*.rcm)|*.rcm|"; + } + pBox->FileName = ""; + pBox->DefaultExt = "rcm"; + pBox->InitialDir = sys.m_BgnDir; + if( pBox->Execute() == TRUE ){ + CWaitCursor w; + TMemIniFile *pIniFile = new TMemIniFile(pBox->FileName); + CmdInit->Text = pIniFile->ReadString("RADIO", "CmdInit", CmdInit->Text); + CmdRx->Text = pIniFile->ReadString("RADIO", "CmdRx", CmdRx->Text); + CmdTx->Text = pIniFile->ReadString("RADIO", "CmdTx", CmdTx->Text); + Cmdxx->Text = pIniFile->ReadString("RADIO", "Cmdxx", Cmdxx->Text); + m_PollType = pIniFile->ReadInteger("RADIO", "PollType", 0); + RGFS->ItemIndex = pIniFile->ReadInteger("RADIO", "Offset", 0); + PollInt->Text = (pIniFile->ReadInteger("RADIO", "PollInterval", 0) + 2)/10.0; + AddrScan->Checked = 0; + delete pIniFile; + SetMaker(); + UpdateUI(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::SaveBtnClick(TObject *Sender) +{ + TSaveDialog *pBox = new TSaveDialog(this); + if( sys.m_MsgEng ){ + pBox->Title = "Save command file"; + pBox->Filter = "Command files(*.rcm)|*.rcm|"; + } + else { + pBox->Title = "コマンド定義ファイルの作成"; + pBox->Filter = "コマンド定義ファイル(*.rcm)|*.rcm|"; + } + pBox->FileName = "MyRIG.rcm"; + pBox->DefaultExt = "rcm"; + pBox->InitialDir = sys.m_BgnDir; + if( pBox->Execute() == TRUE ){ + CWaitCursor w; + TMemIniFile *pIniFile = new TMemIniFile(pBox->FileName); + pIniFile->WriteString("RADIO", "CmdInit", CmdInit->Text); + pIniFile->WriteString("RADIO", "CmdRx", CmdRx->Text); + pIniFile->WriteString("RADIO", "CmdTx", CmdTx->Text); + pIniFile->WriteString("RADIO", "Cmdxx", Cmdxx->Text); + pIniFile->WriteInteger("RADIO", "PollType", m_PollType); + pIniFile->ReadInteger("RADIO", "Offset", RGFS->ItemIndex); + double d; + int dd = 5; + if( sscanf(AnsiString(PollInt->Text).c_str(), "%lf", &d) == 1 ){ //JA7UDE 0428 + if( d >= 0.2 ){ + dd = int((d * 10.0) - 2); + if( dd < 0 ) dd = 0; + } + } + pIniFile->WriteInteger("RADIO", "PollInterval", dd); + pIniFile->UpdateFile(); + delete pIniFile; + } + delete pBox; +} +//--------------------------------------------------------------------------- +int __fastcall TRADIOSetDlg::IsXX(void) +{ + if( strstr(AnsiString(Maker->Text).c_str(), "xx") != NULL ) return 1; //JA7UDE 0428 + if( m_PollType == RADIO_POLLICOM ) return 1; + if( m_PollType == RADIO_POLLICOMN ) return 1; + if( m_PollType == RADIO_POLLOMNIVI ) return 1; + if( m_PollType == RADIO_POLLOMNIVIN ) return 1; + return 0; +} +//--------------------------------------------------------------------------- +int __fastcall TRADIOSetDlg::IsCompatible(int PollType, int MakerIndex) +{ + + if (MakerIndex == 5) { //MakerIndex 5 is Kenwood + if (PollType == 0){ + return 1; + } + else if (PollType == RADIO_POLLKENWOOD) { + return 1; + } + else if (PollType == RADIO_POLLKENWOODN) { + return 1; + } + else { + return 0; + } + } + else if (MakerIndex == 1) { //MakerIndex 1 is Yaesu FT-9000 et al + if (PollType == 0){ + return 1; + } + else if (PollType == RADIO_POLLFT9000) { + return 1; + } + else if (PollType == RADIO_POLLFT2000) { + return 1; + } + else if (PollType == RADIO_POLLFT950) { + return 1; + } + else if (PollType == RADIO_POLLFT450) { + return 1; + } + else { + return 0; + } + + } + else { + return 1; + } +} +//--------------------------------------------------------------------------- +int __fastcall TRADIOSetDlg::IsSame(LPCSTR t, LPCSTR v) +{ + for( ; *v && *t; v++, t++ ){ + if( (*v=='x')&&(*(v+1)=='x') ){ + t++; + v++; + } + else if( (*t == '\\')&&(*(t+1) == 'w') ){ + return 1; + } + else if( (*v == '\\')&&(*(v+1) == 'w') ){ + return 1; + } + else if( *t != *v ){ + return 0; + } + } + return *t != *v ? 0 : 1; +} +//--------------------------------------------------------------------------- +int __fastcall TRADIOSetDlg::GetVFOType(LPCSTR pKey) +{ + for( int i = 0; __VL[i] != NULL; i++ ){ + const POLLDEF *p = __VL[i]; + for( ; p->pKey != NULL; p++ ){ + if( !strcmp(p->pKey, pKey) ) return p->r; + } + } + return 0; +} +//--------------------------------------------------------------------------- +LPCSTR __fastcall TRADIOSetDlg::GetVFOName(int r) +{ + for( int i = 0; __VL[i] != NULL; i++ ){ + const POLLDEF *p = __VL[i]; + for( ; p->pKey != NULL; p++ ){ + if( p->r == r ) return p->pKey; + } + } + return "NONE"; +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::SetVFOList(void) +{ + m_DisEvent++; + const POLLDEF *p = __VL[m_Maker]; + VFOType->Items->Clear(); + for( ; p->pKey != NULL; p++ ){ + VFOType->Items->Add(p->pKey); + } + VFOType->Text = GetVFOName(m_PollType); + m_DisEvent--; +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::SetMaker(void) +{ + int i; + for( i = 0; __MK[i] != NULL; i++ ){ + if( IsSame(AnsiString(CmdRx->Text).c_str(), __MT[i][1]) && IsSame(AnsiString(CmdTx->Text).c_str(), __MT[i][2]) && IsCompatible (m_PollType,i)){ //AA6YQ 1.66 JA7UDE 0428 + m_DisEvent++; + Maker->Text = __MK[i]; + m_DisEvent--; + m_Maker = i; + SetVFOList(); + return; + } + } + m_Maker = MAKER_UNKNOWN; + m_DisEvent++; + Maker->Text = "Unknown"; + SetVFOList(); + m_DisEvent--; +} + +void __fastcall TRADIOSetDlg::MakerChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + m_PollType = 0; + VFOType->Text = "NONE"; + PollInt->Text = "1"; + AddrScan->Checked = 0; + for( int i = 0; __MK[i] != NULL; i++ ){ + if( Maker->Text == __MK[i] ){ + CmdInit->Text = __MT[i][0]; + CmdRx->Text = __MT[i][1]; + CmdTx->Text = __MT[i][2]; + m_Maker = i; + if( m_Maker == 3 ){ // Ten-Tec Omni-VI + Cmdxx->Text = "04"; + } + SetVFOList(); + break; + } + } + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::PortNameChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + UpdateUI(); +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::RefBtnClick(TObject *Sender) +{ + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "Program file"; + pBox->Filter = "Program files(*.exe;*.lnk)|*.exe;*.lnk|"; + } + else { + pBox->Title = "プログラムファイル"; + pBox->Filter = "プログラムファイル(*.exe;*.lnk)|*.exe;*.lnk|"; + } + pBox->FileName = CmdGNR->Text.c_str(); + pBox->DefaultExt = "exe"; + char bf[256]; + SetDirName(bf, AnsiString(CmdGNR->Text).c_str()); //JA7UDE 0428 + pBox->InitialDir = bf; + if( pBox->Execute() == TRUE ){ + CmdGNR->Text = AnsiString(pBox->FileName).c_str(); //JA7UDE 0428 + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TRADIOSetDlg::VFOTypeChange(TObject *Sender) +{ + if( m_DisEvent ) return; + + m_PollType = GetVFOType(AnsiString(VFOType->Text).c_str()); //JA7UDE 0428 + UpdateUI(); +} +//--------------------------------------------------------------------------- diff --git a/RadioSet.dfm b/RadioSet.dfm new file mode 100644 index 0000000..28a3846 Binary files /dev/null and b/RadioSet.dfm differ diff --git a/RadioSet.h b/RadioSet.h new file mode 100644 index 0000000..daf6bb5 --- /dev/null +++ b/RadioSet.h @@ -0,0 +1,128 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef RadioSetH +#define RadioSetH +//---------------------------------------------------------------------------- +/* JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +*/ +//---------------------------------------------------------------------------- +#include "Cradio.h" +#include +#include +#include +#include +/* JA7UDE 0428 +#include +#include +*/ +//---------------------------------------------------------------------------- +class TRADIOSetDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TGroupBox *GB1; + TComboBox *PortName; + TLabel *Label1; + TLabel *Label2; + TComboBox *Baud; + TRadioGroup *BitLen; + TRadioGroup *Stop; + TRadioGroup *Parity; + TGroupBox *GB3; + TCheckBox *flwXON; + TCheckBox *flwCTS; + TLabel *Label3; + TComboBox *ByteWait; + TLabel *Label8; + TButton *LoadBtn; + TButton *SaveBtn; + TGroupBox *GGNR; + TLabel *LGNR; + TEdit *CmdGNR; + TButton *RefBtn; + TCheckBox *OpenGNR; + TLabel *LPTT; + TGroupBox *GCmd; + TLabel *Label4; + TLabel *Label5; + TLabel *Label6; + TLabel *Lxx; + TLabel *LVFO; + TEdit *CmdInit; + TEdit *CmdRx; + TEdit *CmdTx; + TEdit *Cmdxx; + TComboBox *VFOType; + TComboBox *PollInt; + TLabel *LInt; + TLabel *LInts; + TCheckBox *AddrScan; + TGroupBox *GB2; + TCheckBox *CBPTT; + TRadioGroup *RGFS; + TComboBox *Maker; + TLabel *L1; + TLabel *LH; + void __fastcall LoadBtnClick(TObject *Sender); + void __fastcall SaveBtnClick(TObject *Sender); + void __fastcall MakerChange(TObject *Sender); + void __fastcall PortNameChange(TObject *Sender); + void __fastcall RefBtnClick(TObject *Sender); + + void __fastcall VFOTypeChange(TObject *Sender); + + +private: + int m_DisEvent; + TNotifyEvent m_fnHintProc; + + int __fastcall IsXX(void); + int __fastcall IsSame(LPCSTR v, LPCSTR t); + int __fastcall IsCompatible(int PollType, int MakerIndex); //AA6YQ 1.6.6 + void __fastcall SetMaker(void); + void __fastcall UpdateUI(void); + void __fastcall SetVFOList(void); + int __fastcall GetVFOType(LPCSTR pKey); + LPCSTR __fastcall GetVFOName(int r); + int m_Maker; + int m_PollType; + int m_InitWidth; + CMMList m_MMList; +public: + virtual __fastcall TRADIOSetDlg(TComponent* AOwner); + int __fastcall Execute(void); + + void __fastcall DisplayHint(TObject *Sender); +}; +//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- +#endif diff --git a/RxView.cpp b/RxView.cpp new file mode 100644 index 0000000..e71f917 --- /dev/null +++ b/RxView.cpp @@ -0,0 +1,967 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "RxView.h" +#include "Main.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//TRxViewDlg *RxViewDlg; +LPCSTR g_tm[]={ +"GMSK\tMMVARI code", +"FSK(fm=1.0)\tMMVARI code", +"FSK-W(170Hz)\tMMVARI code", +"BPSK\tMMVARI code", +"bpsk\tStandard code", +"rtty-LSB\tBAUDOT code", +"rtty-USB\tBAUDOT code", +"mfsk-LSB\tMFSK standard code", +"mfsk-USB\tMFSK standard code", +"qpsk-LSB\tStandard code", +"qpsk-USB\tStandard code", +}; +//--------------------------------------------------------------------------- +__fastcall TRxViewDlg::TRxViewDlg(TComponent* Owner) + : TForm(Owner) +{ + Font->Name = ((TForm *)Owner)->Font->Name; + Font->Charset = ((TForm *)Owner)->Font->Charset; + if( sys.m_MsgEng ){ + KFQSW->Caption = "Exchange with Main channel"; + KRIIR->Caption = "IIR demodulator"; + KRFFT->Caption = "FFT demodulator"; + } + m_pRxSet = NULL; + m_pBitmapLevel = NULL; + m_pBitmapFFT = NULL; + m_levelXW = m_levelYW = 0; + m_WaterWidth = 400; + m_FFTWindow = (m_WaterWidth-1) * FFT_SIZE / MainVARI->m_FFTSampFreq; + m_WaterLowFQ = 1750 - (m_WaterWidth/2); + m_WaterHighFQ = 1750 + (m_WaterWidth/2); + m_fDisEvent = TRUE; + PC->Font->Assign(MainVARI->PCRX->Font); + m_Dump.Create(PC->Handle, PC, PBox, PC->Font, SBar, 256); + m_Dump.SetCursorType(csSTATIC); + m_fDisEvent = FALSE; + m_MouseDown = FALSE; + m_ShowTiming = FALSE; + AddModeMenu(); + AddToneMenu(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::OnUpdateFont(void) +{ + if( !m_pRxSet ) return; + + m_Dump.SetFont(PC->Font); + m_pRxSet->m_fJA = (PC->Font->Charset == SHIFTJIS_CHARSET); + m_pRxSet->m_MBCS.Create(PC->Font->Charset); + + if( m_fDisEvent ) return; + StatusBar->Invalidate(); + +// m_Dump.SetFont(PC->Font); +// m_pRxSet->m_fJA = (PC->Font->Charset == SHIFTJIS_CHARSET); +// StatusBar->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::PBoxPaint(TObject *Sender) +{ + if( m_fDisEvent ) return; + + m_Dump.Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::FormClose(TObject *Sender, + TCloseAction &Action) +{ + if( Action == caHide ){ + ::PostMessage(MainVARI->Handle, WM_WAVE, waveCloseRxView, DWORD(this)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawMode(void) +{ + int sync = (m_pRxSet->m_SQ && m_pRxSet->m_pDem->GetSyncState() && m_pRxSet->m_pDem->m_Lock); + TCanvas *pCanvas = StatusBar->Canvas; + pCanvas->Brush->Color = sync ? TColor(RGB(0,255,0)) : clBtnFace; +// pCanvas->FillRect(m_rcBar[sbMODE]); + pCanvas->TextRect(m_rcBar[sbMODE], m_rcBar[sbMODE].Left+1, m_rcBar[sbMODE].Top+1, g_tDispModeTable[m_pRxSet->m_Mode]); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawSN(void) +{ + TCanvas *pCanvas = StatusBar->Canvas; + pCanvas->Brush->Color = clBtnFace; +// pCanvas->FillRect(m_rcBar[sbSN]); + char bf[256]; + if( m_ShowTiming ){ + if( m_pRxSet->IsRTTY() ){ + if( m_pRxSet->m_pDem->m_Decode.IsRTTYTmg() ){ + sprintf(bf, "%.2lfms", m_pRxSet->m_pDem->m_Decode.GetRTTYTmg()); + } + else { + strcpy(bf, "***"); + } + } + else { + sprintf(bf, "%dppm", m_pRxSet->m_pDem->GetClockError()); + } + } + else { + sprintf(bf, "S/N=%ddB", m_pRxSet->m_StgFFT.DispSig); + } + pCanvas->TextRect(m_rcBar[sbSN], m_rcBar[sbSN].Left+1, m_rcBar[sbSN].Top+1, bf); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawFREQ(void) +{ + TCanvas *pCanvas = StatusBar->Canvas; + pCanvas->Brush->Color = m_pRxSet->m_fAFC ? clBtnFace : clBlue; + if( !m_pRxSet->m_fAFC ) pCanvas->Font->Color = clYellow; +// pCanvas->FillRect(m_rcBar[sbFREQ]); + char bf[256]; + sprintf(bf, "%uHz", int(m_pRxSet->m_pDem->m_CarrierFreq + 0.5)); + pCanvas->TextRect(m_rcBar[sbFREQ], m_rcBar[sbFREQ].Left+1, m_rcBar[sbFREQ].Top+1, bf); + if( !m_pRxSet->m_fAFC ) pCanvas->Font->Color = clBlack; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::CalcWaterCenter(void) +{ + if( !m_pRxSet ) return; + int fo = m_pRxSet->m_pDem->m_CarrierFreq; + int fw = (m_WaterWidth - m_pRxSet->m_pDem->m_MFSK_BW)/2; + if( fw < 30 ) fw = 30; + if( !sys.m_MFSK_Center && m_pRxSet->IsMFSK() ){ + if( m_pRxSet->m_Mode == MODE_mfsk_U ){ + m_WaterLowFQ = fo - fw; + m_WaterHighFQ = m_WaterLowFQ + m_WaterWidth; + } + else { + m_WaterHighFQ = fo + fw; + m_WaterLowFQ = m_WaterHighFQ - m_WaterWidth; + } + } + else { + m_WaterLowFQ = fo - m_WaterWidth/2; + m_WaterHighFQ = fo + m_WaterWidth/2; + } + if( m_WaterLowFQ < 0 ){ + m_WaterLowFQ = 0; + m_WaterHighFQ = m_WaterLowFQ + m_WaterWidth; + } + else if( m_WaterHighFQ > 3000 ){ + m_WaterHighFQ = 3000; + m_WaterLowFQ = m_WaterHighFQ - m_WaterWidth; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::UpdateWaterWidth(void) +{ + if( !m_pRxSet ) return; + + m_WaterWidth = m_pRxSet->m_WaterW; + m_FFTWindow = (m_WaterWidth-1) * FFT_SIZE / MainVARI->m_FFTSampFreq; + CalcWaterCenter(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::UpdateStatus(void) +{ + if( !m_pRxSet ) return; + + DrawMode(); + DrawSN(); + DrawFREQ(); + if( m_pBitmapLevel ){ + DrawLevel(); + StatusBar->Canvas->Draw(m_rcBar[sbLEVEL].Left, m_rcBar[sbLEVEL].Top, m_pBitmapLevel); + } + if( m_pBitmapFFT ){ + DrawWater(FALSE); + StatusBar->Canvas->Draw(m_rcBar[sbWATER].Left, m_rcBar[sbWATER].Top, m_pBitmapFFT); + DrawWaterCursor(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::FormResize(TObject *Sender) +{ + if( m_fDisEvent ) return; + + m_Dump.Resize(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawLevel(void) +{ + if( m_pRxSet == NULL ) return; + if( !m_pBitmapLevel ) return; + + TCanvas *pCanvas = m_pBitmapLevel->Canvas; + TRect rc; + rc.Left = 0; rc.Top = 0; + rc.Right = m_levelXW; rc.Bottom = m_levelYW; + pCanvas->Brush->Color = clBlack; + pCanvas->Pen->Color = clBlack; + pCanvas->FillRect(rc); + +// pCanvas->Pen->Color = clYellow; + int d = m_pRxSet->m_StgFFT.Sig - 500; + if( m_pRxSet->IsMFSK() && sys.m_MFSK_SQ_Metric ){ + d = m_pRxSet->m_pDem->GetMFSKMetric(0); + } + if( d > LEVELMAX ) d = LEVELMAX; + + if( m_pRxSet->m_pDem->m_AGC.GetOver() && !MainVARI->m_TX ){ + pCanvas->Brush->Color = clRed; + } + else if( !m_pRxSet->m_pDem->m_Lock ){ + pCanvas->Brush->Color = m_pRxSet->m_SQ ? clBlue : clGray; + } + else { + pCanvas->Brush->Color = m_pRxSet->m_SQ ? TColor(RGB(0,255,0)) : clGray; + } + rc.Right = (d * m_levelXW / LEVELMAX); + pCanvas->FillRect(rc); + pCanvas->Pen->Color = m_pRxSet->m_SQ ? clBlack : clWhite; + d = (m_pRxSet->m_SQLevel * m_levelXW / LEVELMAX); + pCanvas->MoveTo(d, 0); pCanvas->LineTo(d, m_levelYW); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::InitWater(void) +{ + if( !m_pRxSet ) return; + + if( m_pRxSet->m_pFFT->m_FFTGain ){ + m_StgWater.Sum = 0; + m_StgWater.Max = 5120; + m_StgWater.VW = 4800; + } + else { + m_StgWater.Sum = 4800; + m_StgWater.Max = 8000; + m_StgWater.VW = 4800; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawWater(BOOL fClear) +{ + if( m_pRxSet == NULL ) return; + if( !m_pBitmapFFT ) return; + + TCanvas *pCanvas = m_pBitmapFFT->Canvas; + + int fo = m_pRxSet->m_pDem->m_CarrierFreq; + if( !m_MouseDown ){ + int ww = m_WaterWidth / ((m_pRxSet->Is170()||m_pRxSet->IsMFSK()) ? 4 : 8); + int cfo = fo; + if( m_pRxSet->IsMFSK() ){ + int off = m_pRxSet->m_pDem->m_MFSK_BW/2; + if( m_pRxSet->m_Mode == MODE_mfsk_L ){ + cfo -= off; + } + else { + cfo += off; + } + } + if( (cfo < (m_WaterLowFQ+ww)) || (cfo > (m_WaterHighFQ-ww)) ){ + CalcWaterCenter(); + } + } + + TRect rc; + rc.Left = 0; rc.Top = 0; rc.Right = m_fftXW; rc.Bottom = m_fftYW; + if( fClear ){ + pCanvas->Brush->Color = MainVARI->m_tWaterColset[0].c; + pCanvas->Pen->Color = MainVARI->m_tWaterColset[0].c; + pCanvas->FillRect(rc); + InitWater(); + } + + TRect trc = rc; + rc.Bottom--; + trc.Top++; + pCanvas->CopyRect(trc, pCanvas, rc); + int xo = ((m_WaterLowFQ+(MainVARI->m_FFTSampFreq/FFT_SIZE))*FFT_SIZE/MainVARI->m_FFTSampFreq) + 0.5; + int xl = 0.5 + (fo - m_pRxSet->m_Speed - m_WaterLowFQ) * m_fftXW / m_WaterWidth; + int xh = 0.5 + (fo + m_pRxSet->m_Speed - m_WaterLowFQ) * m_fftXW / m_WaterWidth; + int x, y, xx; + int sum = 0; + int max = 0; + int wmax = 0; + double k = 256.0 / m_StgWater.VW; + for( x = 0; x < m_fftXW; x++ ){ + xx = xo + (x * m_FFTWindow / m_fftXW); + y = MainVARI->m_fftout[xx]; + if( max < y ) max = y; + if( (x >= xl) && (x <= xh) ){ + if( wmax < y ) wmax = y; + } + sum += y; + + y = (y - m_StgWater.Sum) * k; + if( y < 0 ) y = 0; + if( y >= 256 ) y = 255; + + pCanvas->Pixels[x][0] = MainVARI->m_tWaterColors[y]; + } + sum /= m_fftXW; + if( (wmax-sum) >= 320 ){ + max = wmax; + } + m_StgWater.Sum = (m_StgWater.Sum + sum) / 2; + m_StgWater.Max = (m_StgWater.Max + max) / 2; + m_StgWater.VW = m_StgWater.Max - m_StgWater.Sum; + int low, high; + if( m_pRxSet->m_pFFT->m_FFTGain ){ + low = 5120; high = 7000; + } + else { + low = 6000; high = 6000; + } + if( MainVARI->m_TX == txINTERNAL ) high = 100000; + if( m_StgWater.VW < low ) m_StgWater.VW = low; + if( m_StgWater.VW > high ) m_StgWater.VW = high; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::DrawWaterCursor(void) +{ + if( !m_pRxSet ) return; + + int fo = m_pRxSet->m_pDem->m_CarrierFreq; + int xx = m_rcBar[sbWATER].Left + 0.5 + (fo - m_WaterLowFQ) * m_fftXW / m_WaterWidth; + if( xx < m_rcBar[sbWATER].Left + 4 ) return; + if( xx > m_rcBar[sbWATER].Right - 4 ) return; + TCanvas *pCanvas = StatusBar->Canvas; + int fb = m_rcBar[sbWATER].Bottom - 1; +#if 0 + if( (m_pRxSet->m_Mode == MODE_RTTY) || (m_pRxSet->m_Mode == MODE_U_RTTY) ){ + pCanvas->Pen->Width = 3; + pCanvas->Pen->Color = MainVARI->m_tWaterColset[4].c; + int x = m_rcBar[sbWATER].Left + 0.5 + (fo - m_WaterLowFQ - 85.5) * m_fftXW / m_WaterWidth; + pCanvas->MoveTo(x, fb-4); + pCanvas->LineTo(x, fb-1); + x = m_rcBar[sbWATER].Left + 0.5 + (fo - m_WaterLowFQ + 85.5) * m_fftXW / m_WaterWidth; + pCanvas->LineTo(x, fb-1); + pCanvas->LineTo(x, fb-5); + pCanvas->Pen->Width = 1; + } +#endif + POINT pt[3]; + pt[0].x = xx - 4; pt[0].y = fb; + pt[1].x = xx + 4; pt[1].y = fb; + pt[2].x = xx; pt[2].y = fb - 6; + + pCanvas->Pen->Color = MainVARI->m_tWaterColset[3].c; + pCanvas->Brush->Color = MainVARI->m_tWaterColset[4].c; + pCanvas->Polygon(pt, 2); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::StatusBarDrawPanel(TStatusBar *StatusBar, + TStatusPanel *Panel, const TRect &Rect) +{ + if( !m_pRxSet ) return; + + if( Panel == StatusBar->Panels->Items[sbMODE] ){ + m_rcBar[sbMODE] = Rect; + DrawMode(); + } + else if( Panel == StatusBar->Panels->Items[sbSN] ){ + m_rcBar[sbSN] = Rect; + DrawSN(); + } + else if( Panel == StatusBar->Panels->Items[sbFREQ] ){ + m_rcBar[sbFREQ] = Rect; + DrawFREQ(); + } + else if( Panel == StatusBar->Panels->Items[sbLEVEL] ){ + if( !m_pBitmapLevel || ((Rect.Right-Rect.Left) != m_pBitmapLevel->Width) ){ + m_rcBar[sbLEVEL] = Rect; + m_levelXW = Rect.Right - Rect.Left; + m_levelYW = Rect.Bottom - Rect.Top; + if( !m_pBitmapLevel ){ + m_pBitmapLevel = new Graphics::TBitmap; + } + m_pBitmapLevel->Width = m_levelXW; + m_pBitmapLevel->Height = m_levelYW; + } + StatusBar->Canvas->Draw(m_rcBar[sbLEVEL].Left, m_rcBar[sbLEVEL].Top, m_pBitmapLevel); + } + else if( Panel == StatusBar->Panels->Items[sbWATER] ){ + if( !m_pBitmapFFT || ((Rect.Right-Rect.Left) != m_pBitmapFFT->Width) ){ + m_rcBar[sbWATER] = Rect; + m_fftXW = Rect.Right - Rect.Left; + m_fftYW = Rect.Bottom - Rect.Top; + if( !m_pBitmapFFT ){ + m_pBitmapFFT = new Graphics::TBitmap; + } + m_pBitmapFFT->Width = m_fftXW; + m_pBitmapFFT->Height = m_fftYW; + DrawWater(TRUE); + } + StatusBar->Canvas->Draw(m_rcBar[sbWATER].Left, m_rcBar[sbWATER].Top, m_pBitmapFFT); + DrawWaterCursor(); + } + else if( Panel == StatusBar->Panels->Items[sbEND] ){ + AnsiString as = PC->Font->Name; +// TFontStyles fs = PC->Font->Style; +// AddStyle(as, PC->Font->Charset, FontStyle2Code(fs)); + AddStyle(as, PC->Font->Charset, 0); + StatusBar->Canvas->TextRect(Rect, Rect.Left + 1, Rect.Top + 1, as.c_str()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::FormDestroy(TObject *Sender) +{ + if( m_pBitmapLevel ){ + delete m_pBitmapLevel; + m_pBitmapLevel = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::StatusBarMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + m_MouseDown = FALSE; + if( !m_pRxSet ) return; + if( (Button != mbLeft) && (Button != mbRight) ) return; + + int N = -1; + int xl = 0; + int xr = 0; + for( int i = 0; i <= sbEND; i++ ){ + xr += StatusBar->Panels->Items[i]->Width; + if( i == sbEND ) xr += StatusBar->Width; + if( (X > (xl+4)) && (X < (xr-4)) ){ + N = i; + break; + } + xl = xr; + } + switch(N){ + case sbMODE: + PupMode->Popup(Left+X, Top+StatusBar->Top + Y); + break; + case sbSN: + PupS->Popup(Left+X, Top+StatusBar->Top + Y); + break; + case sbFREQ: + Pup->Popup(Left+X, Top+StatusBar->Top + Y); + break; + case sbLEVEL: + if( Button == mbLeft ){ + int x = X - m_rcBar[sbLEVEL].Left; + x = (x * LEVELMAX) / m_levelXW; + m_pRxSet->m_SQLevel = ((x + 5) / 10) * 10; + m_MouseDown = sbLEVEL; + } + else if( Button == mbRight ){ + MainVARI->PupSQ->PopupComponent = this; + MainVARI->PupSQ->Popup(Left+X, Top+StatusBar->Top + Y); + } + break; + case sbWATER: + if( Button == mbLeft ){ + int x = X - m_rcBar[sbWATER].Left; + int fo = m_WaterLowFQ + x * m_WaterWidth / m_fftXW; + if( m_WaterWidth >= 400 ){ + fo = MainVARI->GetSignalFreq(fo, m_WaterWidth >= 800 ? 50 : 32, m_pRxSet); + } + m_pRxSet->m_pDem->m_Decode.Reset(); + m_pRxSet->m_pDem->ResetMeasMFSK(); + m_pRxSet->m_AFCTimerMFSK = 0; + m_pRxSet->SetCarrierFreq(fo); + m_pRxSet->m_pDem->m_fAFC = m_pRxSet->m_fAFC; + m_pRxSet->m_SQTimer = 0; + m_MouseDown = sbWATER; + } + else if( Button == mbRight ){ + PupW->Popup(Left+X, Top+StatusBar->Top + Y); + } + break; + case sbEND: + if( Button == mbRight ){ + MainVARI->PupCharset->PopupComponent = StatusBar; + MainVARI->PupCharset->Popup(Left+X, Top+StatusBar->Top + Y); + } + else { + ChangeFont(); + } + break; + default: + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::ChangeFont(void) +{ + TFontDialog *pBox = new TFontDialog(this); + pBox->Font = PC->Font; + if( pBox->Execute() ){ + PC->Font = pBox->Font; + OnUpdateFont(); + } + delete pBox; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::SBarChange(TObject *Sender) +{ + m_Dump.OnScrollBarChange(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KFQSWClick(TObject *Sender) +{ + ::PostMessage(MainVARI->Handle, WM_WAVE, waveSwapRxView, DWORD(this)); +// +} +//--------------------------------------------------------------------------- + +void __fastcall TRxViewDlg::PBoxMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + BOOL f = m_Dump.ClearAllSelect(FALSE); + int r = m_Dump.GetWindowText(MainVARI->m_StrSel, X, Y); + if( f || r ) m_Dump.Paint(); + if( r ){ + MainVARI->m_UStrSel = jstrupr(MainVARI->m_StrSel.c_str()); + if( (Button == mbLeft)||(Button == mbRight) ){ + RECT rc; + ::GetWindowRect(PC->Handle, &rc); + MainVARI->PupRX->PopupComponent = this; + MainVARI->PupRX->Popup(rc.left+X, rc.top+Y); + } + } + else if( Button == mbRight ){ + RECT rc; + ::GetWindowRect(PC->Handle, &rc); + MainVARI->PupRXW->PopupComponent = StatusBar; + MainVARI->PupRXW->Popup(rc.left+X, rc.top+Y); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::StatusBarMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if( m_MouseDown == sbLEVEL ){ + int x = X - m_rcBar[sbLEVEL].Left; + x = (x * LEVELMAX) / m_levelXW; + if( (x >= 0) && (x <= LEVELMAX) ){ + m_pRxSet->m_SQLevel = x; + } + } + else if( m_MouseDown == sbWATER ){ + int x = X - m_rcBar[sbWATER].Left; + int fo = m_WaterLowFQ + x * m_WaterWidth / m_fftXW; + if( fo < MIN_CARRIER ) fo = MIN_CARRIER; + if( fo > sys.m_MaxCarrier ) fo = sys.m_MaxCarrier; + m_pRxSet->m_pDem->m_Decode.Reset(); + m_pRxSet->m_pDem->ResetMeasMFSK(); + m_pRxSet->SetCarrierFreq(fo); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TRxViewDlg::StatusBarMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if( m_MouseDown == sbWATER ){ + if( m_WaterWidth >= 400 ){ + int fo = MainVARI->GetSignalFreq(m_pRxSet->m_pDem->m_CarrierFreq, m_WaterWidth >= 800 ? 50 : 32, m_pRxSet); + m_pRxSet->m_pDem->m_Decode.Reset(); + m_pRxSet->m_pDem->ResetMeasMFSK(); + m_pRxSet->SetCarrierFreq(fo); + } + } + m_MouseDown = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::SetMode(int mode) +{ + if( m_pRxSet->m_Mode != mode ){ + double bw = m_pRxSet->GetBandWidth(); + m_pRxSet->SetMode(mode); + m_Dump.SetRTTY(m_pRxSet->IsRTTY()); + if( bw != m_pRxSet->GetBandWidth() ){ + CalcWaterCenter(); + StatusBar->Invalidate(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::SetSpeed(double spd) +{ + if( m_pRxSet->IsMFSK() ){ + m_pRxSet->SetMFSKType(MFSK_Speed2Type(spd)); + } + else if( m_pRxSet->m_Speed != spd ){ + m_pRxSet->SetSpeed(spd); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::PupModePopup(TObject *Sender) +{ + PupMode->Items->Items[m_pRxSet->m_pDem->m_Type]->Checked = TRUE; + BOOL f = m_pRxSet->Is170(); + NR->Visible = f; + KRFFT->Visible = f; + KRIIR->Visible = f; + if( f ){ + if( m_pRxSet->m_RTTYFFT ){ + KRFFT->Checked = TRUE; + } + else { + KRIIR->Checked = TRUE; + } + } + int spd = (m_pRxSet->m_Speed * 1000) + 0.5; + f = FALSE; + if( m_pRxSet->IsMFSK() ){ + switch(m_pRxSet->m_MFSK_TYPE){ + case typMFSK4: + KS0->Checked = TRUE; + break; + case typMFSK8: + KS1->Checked = TRUE; + break; + case typMFSK11: + KS2->Checked = TRUE; + break; + case typMFSK16: + KS3->Checked = TRUE; + break; + case typMFSK22: + KS4->Checked = TRUE; + break; + case typMFSK31: + KS5->Checked = TRUE; + break; + case typMFSK32: + KS6->Checked = TRUE; + break; + case typMFSK64: + KS7->Checked = TRUE; + break; + } + } + else if( m_pRxSet->IsRTTY() ){ + switch(spd){ + case 45450: + KS0->Checked = TRUE; + break; + case 75000: + KS1->Checked = TRUE; + break; + case 110000: + KS2->Checked = TRUE; + break; + } + } + else { + switch(spd){ + case 15625: + KS0->Checked = TRUE; + break; + case 20000: + KS1->Checked = TRUE; + break; + case 31250: + KS2->Checked = TRUE; + break; + case 62500: + KS3->Checked = TRUE; + break; + case 93750: + KS4->Checked = TRUE; + break; + case 125000: + KS5->Checked = TRUE; + break; + case 250000: + KS6->Checked = TRUE; + break; + default: + char bf[256]; + StrDbl(bf, m_pRxSet->m_Speed); + strcat(bf, " bps"); + KS7->Caption = bf; + KS7->Checked = TRUE; + f = TRUE; + break; + } + } + if( m_pRxSet->IsMFSK() ){ + KS0->Caption = "3.9063 baud, 32tones\tmfsk4"; + KS1->Caption = "7.8125 baud, 32tones\tmfsk8"; + KS2->Caption = "10.767 baud, 16tones\tmfsk11"; + KS3->Caption = "15.625 baud, 16tones\tmfsk16 (Standard)"; + KS4->Caption = "21.533 baud, 16tones\tmfsk22"; + KS5->Caption = "31.25 baud, 8tones\tmfsk31"; + KS6->Caption = "31.25 baud, 16tones\tmfsk32"; + KS7->Caption = "62.5 baud, 16tones\tmfsk64"; + KS3->Visible = TRUE; + KS4->Visible = TRUE; + KS5->Visible = TRUE; + KS6->Visible = TRUE; + KS7->Visible = TRUE; + } + else if( m_pRxSet->IsRTTY() ){ + KS0->Caption = "45.45 baud\tStandard RTTY"; + KS1->Caption = "75.0 baud"; + KS2->Caption = "110.0 baud"; + KS3->Visible = FALSE; + KS4->Visible = FALSE; + KS5->Visible = FALSE; + KS6->Visible = FALSE; + KS7->Visible = f; + } + else { + KS0->Caption = "15.625 bps"; + KS1->Caption = "20.0 bps"; + KS2->Caption = "31.25 bps"; + KS3->Caption = "62.5 bps"; + KS4->Caption = "93.75 bps"; + KS5->Caption = "125.0 bps"; + KS6->Caption = "250.0 bps"; + KS3->Visible = TRUE; + KS4->Visible = TRUE; + KS5->Visible = TRUE; + KS6->Visible = TRUE; + KS7->Visible = f; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::OnMouseWheel(TMessage Message) +{ + if( !sys.m_EnableMouseWheel ) return; + if( m_Dump.OnMouseWheel(Message.WParam >> 16) ){ + MainVARI->OpenWheelTimer(&m_Dump); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::PupWPopup(TObject *Sender) +{ + switch(m_WaterWidth){ + case 200: + KW1->Checked = TRUE; + break; + case 400: + KW2->Checked = TRUE; + break; + default: + KW3->Checked = TRUE; + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KW1Click(TObject *Sender) +{ + int fw = 800; + if( Sender == KW1 ){ + fw = 200; + } + else if( Sender == KW2 ){ + fw = 400; + } + if( !m_pRxSet ) return; + m_pRxSet->m_WaterW = fw; + UpdateWaterWidth(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS0Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(3.90625); + } + else if( m_pRxSet->IsRTTY() ){ + SetSpeed(45.45); + } + else { + SetSpeed(15.625); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS1Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(7.8125); + } + else if( m_pRxSet->IsRTTY() ){ + SetSpeed(75.0); + } + else { + SetSpeed(20.0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS2Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(10.767); + } + else if( m_pRxSet->IsRTTY() ){ + SetSpeed(110.0); + } + else { + SetSpeed(31.25); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS3Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(15.625); + } + else { + SetSpeed(62.5); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS4Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(21.533); + } + else { + SetSpeed(93.75); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS5Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(31.25); + } + else { + SetSpeed(125.0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS6Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(32.0); + } + else { + SetSpeed(250.0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KS7Click(TObject *Sender) +{ + if( m_pRxSet->IsMFSK() ){ + SetSpeed(62.5); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::PupSPopup(TObject *Sender) +{ + KSTM->Caption = m_pRxSet->IsRTTY() ? "Timing (ms)" : "Timing (ppm)"; + if( m_ShowTiming ){ + KSTM->Checked = TRUE; + } + else { + KSSN->Checked = TRUE; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KSSNClick(TObject *Sender) +{ + m_ShowTiming = (Sender != KSSN); + StatusBar->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KFAFCClick(TObject *Sender) +{ + if( !m_pRxSet ) return; + + InvMenu(KFAFC); + m_pRxSet->m_pDem->m_fAFC = m_pRxSet->m_fAFC = KFAFC->Checked; + StatusBar->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::PupPopup(TObject *Sender) +{ + if( !m_pRxSet ) return; + + KFAFC->Checked = m_pRxSet->m_fAFC; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KRIIRClick(TObject *Sender) +{ + if( !m_pRxSet ) return; + + m_pRxSet->m_RTTYFFT = FALSE; + m_pRxSet->m_pDem->m_fRTTYFFT = FALSE; +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KRFFTClick(TObject *Sender) +{ + if( !m_pRxSet ) return; + + m_pRxSet->m_RTTYFFT = TRUE; + m_pRxSet->m_pDem->m_fRTTYFFT = TRUE; +} +void __fastcall TRxViewDlg::AddModeMenu(void) +{ + for( int i = 0; i < AN(g_tm); i++ ){ + TMenuItem *pm = new TMenuItem(this); + pm->Caption = g_tm[i]; + pm->GroupIndex = 1; + pm->RadioItem = TRUE; + pm->OnClick = KMClick; + PupMode->Items->Insert(i, pm); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KMClick(TObject *Sender) +{ + int N = PupMode->Items->IndexOf((TMenuItem *)Sender); + if( (N >= 0) && (N < MODE_END) ){ + SetMode(N); + } +} +//--------------------------------------------------------------------------- +static int g_tf[]={1000, 1200, 1500, 1750, 2000, 2210}; +void __fastcall TRxViewDlg::AddToneMenu(void) +{ + for( int i = 0; i < AN(g_tf); i++ ){ + char bf[32]; + sprintf(bf, "%d", g_tf[i]); + TMenuItem *pm = new TMenuItem(this); + pm->Caption = bf; + pm->OnClick = KFQClick; + Pup->Items->Insert(i, pm); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRxViewDlg::KFQClick(TObject *Sender) +{ + if( !m_pRxSet ) return; + for( int i = 0; i < AN(g_tf); i++ ){ + if( Sender == (TObject *)Pup->Items->Items[i] ){ + m_pRxSet->SetCarrierFreq(g_tf[i]); + break; + } + } +} +//--------------------------------------------------------------------------- + diff --git a/RxView.dfm b/RxView.dfm new file mode 100644 index 0000000..e6243bd Binary files /dev/null and b/RxView.dfm differ diff --git a/RxView.h b/RxView.h new file mode 100644 index 0000000..7682495 --- /dev/null +++ b/RxView.h @@ -0,0 +1,173 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef RxViewH +#define RxViewH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "Dump.h" +#include "ComLib.h" +#include +class CRxSet; +enum { + sbMODE, + sbSN, + sbFREQ, + sbWATER, + sbLEVEL, + sbEND, +}; +//--------------------------------------------------------------------------- +class TRxViewDlg : public TForm +{ +__published: // IDE 管理のコンポーネント + TStatusBar *StatusBar; + TPanel *PC; + TPaintBox *PBox; + TScrollBar *SBar; + TPopupMenu *Pup; + TMenuItem *KFQSW; + TPopupMenu *PupMode; + TPopupMenu *PupW; + TMenuItem *KW1; + TMenuItem *KW2; + TMenuItem *KW3; + TMenuItem *KS1; + TMenuItem *KS2; + TMenuItem *KS3; + TMenuItem *KS4; + TMenuItem *KS5; + TMenuItem *KS6; + TMenuItem *NS; + TMenuItem *KS7; + TPopupMenu *PupS; + TMenuItem *KSSN; + TMenuItem *KSTM; + TMenuItem *N2; + TMenuItem *KFAFC; + TMenuItem *NF; + TMenuItem *KS0; + TMenuItem *NR; + TMenuItem *KRIIR; + TMenuItem *KRFFT; + void __fastcall PBoxPaint(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormResize(TObject *Sender); + void __fastcall StatusBarDrawPanel(TStatusBar *StatusBar, + TStatusPanel *Panel, const TRect &Rect); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall StatusBarMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall SBarChange(TObject *Sender); + void __fastcall KFQSWClick(TObject *Sender); + void __fastcall PBoxMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall StatusBarMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall StatusBarMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall PupModePopup(TObject *Sender); + void __fastcall PupWPopup(TObject *Sender); + void __fastcall KW1Click(TObject *Sender); + void __fastcall KS1Click(TObject *Sender); + void __fastcall KS2Click(TObject *Sender); + void __fastcall KS3Click(TObject *Sender); + void __fastcall KS4Click(TObject *Sender); + void __fastcall KS5Click(TObject *Sender); + void __fastcall KS6Click(TObject *Sender); + void __fastcall PupSPopup(TObject *Sender); + void __fastcall KSSNClick(TObject *Sender); + void __fastcall KFAFCClick(TObject *Sender); + void __fastcall PupPopup(TObject *Sender); + + void __fastcall KRIIRClick(TObject *Sender); + void __fastcall KRFFTClick(TObject *Sender); + + + void __fastcall KS0Click(TObject *Sender); + void __fastcall KS7Click(TObject *Sender); +private: // ユーザー宣言 + BOOL m_fDisEvent; + int m_MouseDown; + + TRect m_rcBar[sbEND]; + int m_levelXW, m_levelYW; + Graphics::TBitmap *m_pBitmapLevel; + + int m_fftXW, m_fftYW; + Graphics::TBitmap *m_pBitmapFFT; + FFTSTG m_StgWater; + int m_WaterLowFQ; + int m_WaterHighFQ; + int m_FFTWindow; + BOOL m_ShowTiming; +private: + void __fastcall DrawMode(void); + void __fastcall DrawSN(void); + void __fastcall DrawFREQ(void); + + void __fastcall DrawLevel(void); + void __fastcall DrawWater(BOOL fClear); + void __fastcall InitWater(void); + void __fastcall DrawWaterCursor(void); + void __fastcall CalcWaterCenter(void); + + void __fastcall AddModeMenu(void); + void __fastcall KMClick(TObject *Sender); + void __fastcall AddToneMenu(void); + void __fastcall KFQClick(TObject *Sender); + + void __fastcall UpdateSpeedMenu(void); + +public: + CRxSet *m_pRxSet; + CDump m_Dump; + int m_WaterWidth; +public: // ユーザー宣言 + __fastcall TRxViewDlg(TComponent* Owner); + + void __fastcall UpdateStatus(void); + void __fastcall OnUpdateFont(void); + void __fastcall SetMode(int mode); + void __fastcall SetSpeed(double spd); + void __fastcall UpdateWaterWidth(void); + void __fastcall ChangeFont(void); + inline __fastcall PopupMode(int x, int y){ + PupMode->Popup(x, y); + }; + +protected: + void __fastcall OnMouseWheel(TMessage Message); +BEGIN_MESSAGE_MAP + MESSAGE_HANDLER(WM_MOUSEWHEEL, TMessage, OnMouseWheel) +END_MESSAGE_MAP(TForm) + +}; +//--------------------------------------------------------------------------- +//extern PACKAGE TRxViewDlg *RxViewDlg; +//--------------------------------------------------------------------------- +#endif + diff --git a/Samples.txt b/Samples.txt new file mode 100644 index 0000000..97de912 --- /dev/null +++ b/Samples.txt @@ -0,0 +1,418 @@ +[Macro samples] + +===================== CQ menu ====================== +<%DisableCR> +#macro <%Menu=CQ1, CQ2, CQ3> +#if ValMenu +#define _cLine <%Format=%d,<%Input$>> +<%ClearTXW><%AutoClear><%TX><%RX> +<%RepeatText=_cLine,<%RepeatText=3,CQ<%SP>>de<%RepeatText=3,<%SP><%MyCall>><%CR>> +<%BS><%SP>pse +#if IsCodeMM +<%SP>(<%VARITYPE>) +#endif +<%SP>k...<%CR> +#endif +<%EOF> +===================== Call menu ====================== +<%DisableCR> +#macro <%Menu= 0x2, 0x3, 0x4, -, 1x2, 1x3, 1x4, -, 2x3, 2x4> +#if ValMenu +#define _His <%Format=%c,<%Input$>> +#define _My <%Format=%d,<%Find$=x,<%Input$>>> +<%TX><%RX> +#if !Is1stCR +<%CR> +#endif +#if IsCall +<%RepeatText=_His,<%HisCall><%SP>> +#endif +de +<%RepeatText=_My,<%SP><%MyCall>> +<%SP>pse K<%CR> +#endif +<%EOF> +===================== CW speed ====================== +<%DisableCR> +#macro <%Slider=CW speed,<%CWSpeed>,10,30,1,10> +#if StrMacro(<%Input$>) +<%CWSpeed=<%Input$>> +#endif +<%EOF> +===================== CW menu ====================== +<%DisableCR><%DisableTAB> +#define _tCode 73CU:, TU:EE, TU:, SU, EE, QRL?, QSY TU, CL: +#macro <%Menu=&73 CU SK, &TU SK EE, T&U SK, &SU, &EE, -, QR&L? (before CQ), QS&Y, QRT, -, &Input..., -, Speed...> +#if ValMenu + #define _strCode <%TableStr=<%Menu>,_tCode> + #if StrMacro(<%String=_strCode>) + <%TX><%RX><%CWID=_strCode><%EOF> + #elseif StrMacro(<%Input$>) >> Input... + #if StrMacro(<%Input=CW text (@ AS : SK ; AR = BT ] KN), <%MyCall>>) + <%TX><%RX><%CWID=<%Input$>><%EOF> + #endif + #elseif StrMacro(<%Input$>) >> Speed... + <%Slider=CW speed, <%CWSpeed>,10,40><%CWSpeed=<%Input$>> + #endif +#endif +<%EOF> +===================== How to use <%CallProc=...> ====================== +<%DisableCR><%DisableTAB> +#define _tTitle AFC width (Hz), AFC level (dB), CW speed, Digital output level, Play back speed, Minimum size of the macro buffer +#define _tCommand AFCWidth, AFCLevel, CWSpeed, DigitalLevel, PlayBackSpeed, BuffSize +#define _tRange "0,200,5", "6,20", "10,40", "1024,32768,1024", "1,20", "1024,16384,1024" +#macro <%Menu=_tTitle> +#if ValMenu + #define _strArg <%TableStr=<%Menu>,_tTitle>,<%TableStr=<%Menu>,_tCommand>,<%TableStr=<%Menu>,_tRange> + <%CallProc=Slider, _strArg> +#endif + +#proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales +<%DisableCR> +#macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> +#if StrMacro(<%Input$>) +<%@Command=<%Input$>> +#endif +#endp +===================== How to use <%VALTIME> ====================== +<%DisableCR><%CallProc=DateTime, <%LPTIME>> + +#proc DateTime @Passing +<%DisableCR> +#define _Now @Passing +#define _tMonth January, February, March, April, May, June, July, August, September, October, November, December +#define _tWeek Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday +#define _iDay <%Floor=_Now / (24*60*60)> +#define _iWeek <%Format=%d, _iDay % 7 + 1> +<%VALTIME=year, _Now><%SP><%TableStr=<%VALTIME=month, _Now>, _tMonth><%SP> +<%VALTIME=day, _Now><%SP><%SP><%VALTIME=hour, _Now>:<%VALTIME=minute, _Now>: +<%VALTIME=second, _Now><%SP>(<%TableStr=_iWeek, _tWeek>) +#endp +===================== To capture callsign ====================== +<%DisableCR><%DisableTAB> +#if IsCall + <%WaterMsg=3,<%EntityName=<%HisCall>>/<%Continent=<%HisCall>>> + <%ClearTXW>RRR, <%HisCall> <%HisCall> de <%MyCall> <%MyCall><%CR> + #if IsCodeMM + --- (<%VARITYPE>) ---<%CR> + #endif + <%HisGreetings=2> <%DearName>, Thank you for your call...<%CR> +#else + <%WaterMsg=3,Waiting...> + <%HisCall=<%Capture>><%Repeat=1000> +#endif +===================== CQ repeating with auto stop ====================== +#define _tCQ CQ1, CQ2, CQ3 +#define _tTime 3sec, 4sec, 5sec +<%DisableCR><%DisableTAB> +#if !IsRepeat + #if IsCall + #macro <%Message=Callsign already exists in the Call box..., Clear the callsign and run this macro again> + #exit + #endif + #if !IsDefined(_Interval) + #define _Interval 3 + #endif + #define _iTemp <%Table=<%String=_Interval>sec, _tTime> + #define _strMenu 0, <%String=_tCQ>, -, _iTemp, <%String=_tTime> + #macro <%MenuB=_strMenu> +#endif +#if !IsCall + #if StrMacro(<%Input$>) >> CQ + #define _cLine <%Format=%d,<%Input$>> + #if !IsSQ + <%ClearTXW><%AutoClear><%TX><%RX> + <%RepeatText=_cLine,<%RepeatText=3,CQ<%SP>>de<%RepeatText=3,<%SP><%MyCall>><%CR>> + <%BS><%SP>pse + #if IsCodeMM + <%SP>(<%VARITYPE>) + #endif + <%SP>k...<%CR> + <%RepeatTX=<%Format=%d,_Interval*1000>> + #else + <%HisCall=<%Capture>><%Repeat=1000> + #endif + #elseif StrMacro(<%Input$>) >> sec + #define _Interval <%Format=%d,<%Input$>> + #endif +#else + #macro <%WaterMsg=3,<%EntityName=<%HisCall>>/<%Continent=<%HisCall>>> + <%ClearTXW>RRR, <%HisCall> <%HisCall> de <%MyCall> <%MyCall><%CR> + #if IsCodeMM + --- (<%VARITYPE>) ---<%CR> + #endif + <%HisGreetings=2> <%DearName>, Thank you for your call...<%CR> +#endif +<%EOF> +===================== Sound channel menu ====================== +<%DisableCR> +#define _tCH MONO,LEFT,RIGHT +#define _strCH <%TableStr=1,<%SoundDevice>> +#define _iCH <%Table=_strCH,_tCH> +#macro <%MenuB=_iCH,_tCH> +#if ValMenu +<%SoundDevice=<%Input$>> +#endif +<%EOF> +===================== Digtal output level ====================== +<%DisableCR> +#define _tLevel 8192,16384,24576,32768 +#define _tLabel Low, Mid(Default), High, Maximum +#define _iLevel <%Table=<%DigitalLevel>,_tLevel> +#macro <%MenuB=_iLevel,_tLabel> +#if ValMenu +<%DigitalLevel=<%TableStr=<%Menu>,_tLevel>> +#endif +<%EOF> +===================== Digital output level ====================== +<%DisableCR> +#macro <%Slider=Digital output level, <%DigitalLevel>,1024,32768,1024> +#if StrMacro(<%Input$>) +<%DigitalLevel=<%Input$>> +#endif +<%EOF> +===================== Windows shut down ====================== +<%DisableCR> +#if <%YesNo=Windows will be shut down, are you sure?> == 6 +<%ShutDown> +#endif +<%EOF> +===================== Play back menu ====================== +<%DisableCR><%DisableTAB> +#define _tButtons "60-30-15<%TAB>(Default)","60-20-10","60-40-15" +#define _tReplays Replay latest 10sec, Replay latest 15sec, Replay latest 20sec, Replay latest 30sec +#define _strMenu OFF, ON, -, 0, <%String=_tButtons>, -, 0, <%String=_tReplays> +#define _iSwitch <%Format=%d,<%Cond=IsPlayBack>+1> +#if IsPlayBack +#macro <%MenuB=_iSwitch, _strMenu> +#else +#macro <%MenuB=_iSwitch, OFF, ON> +#endif +#if ValMenu + #if StrMacro(<%Input$>) >> - + #define _strButtons <%Format=%.2s,<%Input$>>,<%Format=%.2s,<%Skip$=3,<%Input$>>>,<%Format=%.2s,<%Skip$=6,<%Input$>>> + #macro <%PlayBackButtons=_strButtons> + #elseif StrMacro(<%Input$>) >> Replay + #define _strTime <%Format=%d,<%Input$>> + #macro <%PlayBack=_strTime> + #else + #macro <%PlayBack=<%Input$>> + #endif +#endif +<%EOF> +===================== RYRYRY ====================== +<%RepeatText=2,<%RepeatText=33,RY><%CR><%vvv><%CR>> +===================== rtty UOS ====================== +<%DisableCR> +#define _iMenu <%Format=%d,<%Cond=IsUOS>+1> +#macro <%MenuB=_iMenu, OFF, ON> +#if ValMenu +<%UOS=<%Input$>> +#endif +===================== rtty Diddle ====================== +<%DisableCR> +#define _tDiddle BLK,LTR +#define _iMenu <%Table=<%DIDDLE>,_tDiddle> +#macro <%MenuB=_iMenu, _tDiddle> +#if ValMenu +<%DIDDLE=<%Input$>> +#endif +===================== rtty wait ====================== +<%DisableCR> +#macro <%Slider=RTTY Wait,<%RTTYWaitC>,0,100> +#if StrMacro(<%Input$>) +<%RTTYWaitC=<%Input$>><%RTTYWaitD=<%Input$>> +#endif +<%EOF> +===================== Rig control (Rig selection) ====================== +<%DisableCR> +#define _tRigs YAESU-VU, YAESU-HF, CI-V, CI-V4, KENWOOD, JST245 +#define _iRig <%Table=_Rig, _tRigs> +#macro <%MenuB=_iRig, _tRigs> +#if ValMenu +#DEFINE _Rig <%Format=%s,<%Input$>> +#endif +<%EOF> +===================== Rig control (FREQ menu) ====================== +<%DisableCR> +#if !IsDefined(_Rig) +#define _Rig CI-V +#endif +#macro <%Menu=7028.5,10141.5,14072.5,18102.5,21072.5,28072.5> +#if ValMenu +#if IsRadioLSB +#macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001> +#else +#macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001> +#endif +#endif +<%EOF> +===================== Rig control (Mode menu) ====================== +<%DisableCR> +#if !IsDefined(_Rig) +#define _Rig CI-V +#endif +#define _t_Mode LSB,USB,CW,AM,FM,RTTY,PACKET +#macro <%MenuB="<%Table=<%RadioMode>,_t_Mode>",_t_Mode> +#if ValMenu +#macro <%RadioMode=_Rig,<%Input$>> +#endif +<%EOF> +===================== Rig control (Tone menu) ====================== +<%DisableCR> +#if !IsDefined(_Rig) +#define _Rig CI-V +#endif +#macro <%Menu=1000,1200,1500,1750,2000> +#if ValMenu +#define _Tone <%Input$> +#define _OffKHz <%Format=%f,(<%RxCarrier>-_Tone)*0.001> +#if IsRadioLSB +#macro <%RadioKHz=_Rig,<%RadioKHz>-_OffKHz> +#else +#macro <%RadioKHz=_Rig,<%RadioKHz>+_OffKHz> +#endif +#macro <%RxCarrier=_Tone> +#endif +<%EOF> +===================== Edit event macro ====================== +<%DisableCR> +#macro <%Menu=<%Events>> +#if ValMenu +#define _strArg <%Input$> +<%CallProc=EditEvent, _strArg> +#endif + +#proc EditEvent @Event +<%DisableCR> +<%@Event> +#endp +===================== Setup OnTimer menu ====================== +<%DisableCR> +#macro <%Menu=AFC frequency, Metric(MFSK), RadioMode, WaterNoise, S/N (Average and Peak), UTC time, Local time, QSO time, Memory free, -, Stop> +#if ValMenu == 1 +#macro <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>> +#elseif ValMenu == 2 +#macro <%OnTimer=<%WaterMsg=4,<%MetricMFSK>>> +#elseif ValMenu == 3 +#macro <%OnTimer=<%WaterMsg=4,<%RadioMode>>> +#elseif ValMenu == 4 +#macro <%OnTimer=<%WaterMsg=4,<%WaterNoise>dB>> +#elseif ValMenu == 5 +#macro <%OnTimer=<%WaterMsg=4,S/N=<%AverageLevel>/<%PeakLevel>dB>> +#elseif ValMenu == 6 +#macro <%OnTimer=<%WaterMsg=4,<%UTIME>z>> +#elseif ValMenu == 7 +#macro <%OnTimer=<%WaterMsg=4,<%LTIME>>> +#elseif ValMenu == 8 +#macro <%OnTimer=<%DisableCR>\r\n#if IsQSO\r\n#define\t_QT\t<%Format=%u,<%PTIME>-<%QPTIME>>\r\n<%WaterMsg=3,<%VALTIME=hour,_QT>:<%VALTIME=minute,_QT>:<%VALTIME=second,_QT>>\r\n#endif> +#elseif ValMenu == 9 +#macro <%OnTimer=<%WaterMsg=4,<%Format=%d,100-<%TableStr=1,<%Memory>>>% (<%TableStr=3,<%Memory>>MB)>> +#elseif ValMenu == 10 +#macro <%OnTimer=> +#endif +<%EOF> +===================== Create extension menu (Write to OnStart) ====================== +<%DisableCR> +#define _Name E&X +<%AddMenu=_Name, &CW speed..., Slider, CW speed, CWSpeed, 10, 40> +<%AddMenu=_Name, &Digital output level..., Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> +<%AddMenu=_Name, -> +<%AddMenu=_Name, CQ DX(&1), OnCQDXClick, 1, 3, 3> +<%AddMenu=_Name, CQ DX(&3), OnCQDXClick, 3, 3, 3> + +#proc OnCQDXClick @NLINE, @NCQ, @NCALL +<%DisableCR><%ClearTXW><%AutoClear><%TX><%RX> +<%RepeatText=@NLINE,<%RepeatText=@NCQ,CQ DX<%SP>>de<%RepeatText=@NCALL,<%SP><%MyCall>><%CR>> +<%BS><%SP>pse DX k<%CR> +#endp + +#proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales +<%DisableCR> +#macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> +#if StrMacro(<%Input$>) +<%@Command=<%Input$>> +#endif +#endp +===================== Override builtin menus (Write to OnStart) ====================== +<%DisableCR> +#if !IsDefined(_fShellHelp) +#define _fShellHelp 0 +#endif +<%AddMenu=&E, -> +<%AddMenu=&E, Edit &AS(CW) macro..., OnCommand, <%EditMacro=AS(CW)>> +<%AddMenu=&E, Edit &OnStart event..., OnCommand, <%OnStart>> +<%InsertMenu=&O, &B, &Digital output level..., Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> +<%InsertMenu=&O, &B, -> +<%AddMenu=&H, &P, OnShellEdit, project.txt, e, 1> +<%AddMenu=&H, &O, OnShellEdit, mmvari.txt, e, 1> +<%AddMenu=&H, &S, OnShellEdit, Samples.txt, , 3> +<%AddMenu=&H, &H, OnShellEdit, history.txt, e, 1> +<%InsertMenu=&H, &D, &Use Shell-standard editor, InvRegVal, _fShellHelp> +<%InsertMenu=&H, &D, -> + +#proc On$&HelpClick +<%DisableCR><%CheckMenu=&H, &U, _fShellHelp> +#endp + +#proc OnCommand @Command +<%DisableCR>@Command +#endp + +#proc OnInvVal @Value +<%DisableCR> +#DEFINE @Value <%Inv=@Value> +#endp + +#proc OnShellEdit @File, @Prifix, @Flag +<%DisableCR> +#if IsEnglish +#define _FileName <%Folder>@Prifix@File +#else +#define _FileName <%Folder>@File +#endif +#if _fShellHelp +<%Shell=_FileName> +#else +<%EditFile=_FileName, @Flag> +#endif +#endp + +#proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales +<%DisableCR> +#macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> +#if StrMacro(<%Input$>) +<%@Command=<%Input$>> +#endif +#endp +===================== Set shortcut keys (Write to OnStart) ====================== +<%DisableCR> +<%ShortCut=&V, &C, &1, Ctrl+1> +<%ShortCut=&V, &C, &2, Ctrl+2> +<%ShortCut=&V, &C, &3, Ctrl+3> +<%ShortCut=&V, &C, &4, Ctrl+4> +<%ShortCut=&V, &C, &5, Ctrl+5> +<%ShortCut=&V, &C, &6, Ctrl+6> +<%ShortCut=&V, &C, &7, Ctrl+7> +<%ShortCut=&V, &C, &8, Ctrl+8> +<%ShortCut=&O, &M, Ctrl+S> +===================== Create hid menu for shortcut keys (Write to OnStart) ====================== +<%DisableCR> +#define _NameHide Hide +<%AddMenu=_NameHide, &RefRXW, OnCommand, <%RefRXW>> +<%AddMenu=_NameHide, &QSO button, OnCommand, <%DoButton=QSO>> +<%AddMenu=_NameHide, &Data button, OnCommand, <%DoButton=Data>> +<%AddMenu=_NameHide, &Find button, OnCommand, <%DoButton=Find>> +<%ShortCut=_NameHide, &R, Ctrl+R> +<%ShortCut=_NameHide, &Q, Ctrl+Q> +<%ShortCut=_NameHide, &D, Ctrl+D> +<%ShortCut=_NameHide, &F, Ctrl+F> +<%ShowMenu=_NameHide, OFF> + +#proc OnCommand @Command +<%DisableCR>@Command +#endp +===================== Hide builtin menus ====================== +<%DisableCR> +<%ShowMenu=&F, ONOFF><%ShowMenu=&E, ONOFF><%ShowMenu=&V, ONOFF> +<%ShowMenu=&O, ONOFF><%ShowMenu=&H, ONOFF> diff --git a/TH5Len.cpp b/TH5Len.cpp new file mode 100644 index 0000000..4798c99 --- /dev/null +++ b/TH5Len.cpp @@ -0,0 +1,62 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "TH5Len.h" +#include "ComLib.h" +#include "Hamlog5.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TTH5LenDlg *TH5LenDlg; +//--------------------------------------------------------------------- +__fastcall TTH5LenDlg::TTH5LenDlg(TComponent* AOwner) + : TForm(AOwner) +{ + Caption = sys.m_MsgEng ? "Set fields length" : "フィールド長の設定"; +} +//--------------------------------------------------------------------- +int __fastcall TTH5LenDlg::Execute(void) +{ + UHis->Position = Log.m_LogSet.m_Hamlog5Len[8]; + UMy->Position = Log.m_LogSet.m_Hamlog5Len[9]; + UFreq->Position = Log.m_LogSet.m_Hamlog5Len[10]; + UMode->Position = Log.m_LogSet.m_Hamlog5Len[11]; + UName->Position = Log.m_LogSet.m_Hamlog5Len[12]; + UQTH->Position = Log.m_LogSet.m_Hamlog5Len[13]; + URem->Position = Log.m_LogSet.m_Hamlog5Len[14]; + if( ShowModal() == IDOK ){ + Log.m_LogSet.m_Hamlog5Len[8] = UHis->Position; + Log.m_LogSet.m_Hamlog5Len[9] = UMy->Position; + Log.m_LogSet.m_Hamlog5Len[10] = UFreq->Position; + Log.m_LogSet.m_Hamlog5Len[11] = UMode->Position; + Log.m_LogSet.m_Hamlog5Len[12] = UName->Position; + Log.m_LogSet.m_Hamlog5Len[13] = UQTH->Position; + Log.m_LogSet.m_Hamlog5Len[14] = URem->Position; + Log.m_LogSet.m_Hamlog5Len[15] = Log.m_LogSet.m_Hamlog5Len[14]; + return TRUE; + } + else { + return FALSE; + } +} +//--------------------------------------------------------------------- + diff --git a/TH5Len.dfm b/TH5Len.dfm new file mode 100644 index 0000000..6457467 Binary files /dev/null and b/TH5Len.dfm differ diff --git a/TH5Len.h b/TH5Len.h new file mode 100644 index 0000000..c5fc1ed --- /dev/null +++ b/TH5Len.h @@ -0,0 +1,71 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef OCBH +#define OCBH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TTH5LenDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TLabel *L1; + TLabel *L2; + TLabel *L3; + TLabel *L4; + TLabel *L5; + TLabel *L6; + TLabel *L7; + TEdit *EHis; + TEdit *EMy; + TEdit *EFreq; + TEdit *EMode; + TEdit *EName; + TEdit *EQTH; + TEdit *ERem; + TUpDown *UHis; + TUpDown *UMy; + TUpDown *UFreq; + TUpDown *UMode; + TUpDown *UName; + TUpDown *UQTH; + TUpDown *URem; +private: +public: + virtual __fastcall TTH5LenDlg(TComponent* AOwner); + + int __fastcall Execute(void); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TTH5LenDlg *TH5LenDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/Term.cpp b/Term.cpp new file mode 100644 index 0000000..8bb4adc --- /dev/null +++ b/Term.cpp @@ -0,0 +1,131 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +//#include "Main.h" +#include "Term.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +//TTermView *TermView; +//--------------------------------------------------------------------------- +__fastcall TTermView::TTermView(TComponent* Owner) + : TForm(Owner) +{ + m_Dump.Create(PC->Handle, PB, PC->Font, SBar, 20); + m_Dump.SetCursorType(csSTATIC); + + m_Edit.Create(PCE->Handle, PBE, PCE->Font, SBarE, 20); + m_Edit.SetCursorType(csCARET); + +} +//--------------------------------------------------------------------------- +void TTermView::PutChar(int c) +{ + m_Dump.PutChar(c, 1); +// Caption = m_Dump.Debug(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::FormKeyPress(TObject *Sender, char &Key) +{ + if( Key == '\b' ){ +// if( m_Edit.GetSendCharCount() ){ +// DPLLWnd->SendChar('\b'); +// } + } + m_Edit.PutKey(Key, 1); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PBPaint(TObject *Sender) +{ + m_Dump.Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCResize(TObject *Sender) +{ + m_Dump.Resize(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::SBarChange(TObject *Sender) +{ + m_Dump.OnScrollBarChange(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PBClick(TObject *Sender) +{ + PCE->SetFocus(); +// m_Dump.Cursor(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCEnter(TObject *Sender) +{ + m_Dump.CreateCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCExit(TObject *Sender) +{ + m_Dump.DestroyCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PBEPaint(TObject *Sender) +{ + m_Edit.Paint(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCEEnter(TObject *Sender) +{ + m_Edit.CreateCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCEExit(TObject *Sender) +{ + m_Edit.DestroyCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::SBarEChange(TObject *Sender) +{ + m_Edit.OnScrollBarChange(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PBEClick(TObject *Sender) +{ + PCE->SetFocus(); + m_Edit.Cursor(TRUE); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::PCEResize(TObject *Sender) +{ + m_Edit.Resize(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::FormActivate(TObject *Sender) +{ + PCE->SetFocus(); + m_Edit.CreateCaret(); +} +//--------------------------------------------------------------------------- +void __fastcall TTermView::FormDeactivate(TObject *Sender) +{ + m_Edit.DestroyCaret(); +} +//--------------------------------------------------------------------------- diff --git a/Term.dfm b/Term.dfm new file mode 100644 index 0000000..7f3c4bf Binary files /dev/null and b/Term.dfm differ diff --git a/Term.h b/Term.h new file mode 100644 index 0000000..08642f6 --- /dev/null +++ b/Term.h @@ -0,0 +1,78 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#ifndef TermH +#define TermH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "Dump.h" +//--------------------------------------------------------------------------- +class TTermView : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *PCB; + TScrollBar *SBar; + TPanel *PC; + TPaintBox *PB; + TSplitter *Splitter1; + TPanel *PCEB; + TPanel *PCE; + TScrollBar *SBarE; + TPaintBox *PBE; + void __fastcall FormKeyPress(TObject *Sender, char &Key); + void __fastcall PBPaint(TObject *Sender); + + + void __fastcall PCResize(TObject *Sender); + void __fastcall SBarChange(TObject *Sender); + void __fastcall PBClick(TObject *Sender); + void __fastcall PCEnter(TObject *Sender); + void __fastcall PCExit(TObject *Sender); + + void __fastcall PBEPaint(TObject *Sender); + void __fastcall PCEEnter(TObject *Sender); + void __fastcall PCEExit(TObject *Sender); + void __fastcall SBarEChange(TObject *Sender); + void __fastcall PBEClick(TObject *Sender); + void __fastcall PCEResize(TObject *Sender); + void __fastcall FormActivate(TObject *Sender); + void __fastcall FormDeactivate(TObject *Sender); +private: // ユーザー宣言 +public: + CDump m_Dump; + CDump m_Edit; +private: + void __fastcall SetCompositionWindowPos(); + +public: // ユーザー宣言 + __fastcall TTermView(TComponent* Owner); + + void PutChar(int c); + +}; +//--------------------------------------------------------------------------- +//extern PACKAGE TTermView *TermView; +//--------------------------------------------------------------------------- +#endif diff --git a/Test.cpp b/Test.cpp new file mode 100644 index 0000000..add14b4 --- /dev/null +++ b/Test.cpp @@ -0,0 +1,113 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Test.h" +#include "ComLib.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TTestDlg *TestDlg; +//--------------------------------------------------------------------- +__fastcall TTestDlg::TTestDlg(TComponent* AOwner) + : TForm(AOwner) +{ + UdCarrier1->Max = short(sys.m_MaxCarrier); +#if DEBUG + OnWave(); +#endif +} +//--------------------------------------------------------------------- +int __fastcall TTestDlg::Execute(void) +{ +#if DEBUG + UdSN->Position = (short)sys.m_testSN; + EFile->Text = sys.m_testName; + SBDo->Down = sys.m_test; + UdCarrier1->Position = short(sys.m_testCarrier1); + UdCarrier2->Position = short(sys.m_testCarrier2); + UdDB2->Position = short(sys.m_testDB2); + CBQSBTime->Text = sys.m_testQSBTime; + UdQSBDB->Position = short(sys.m_testQSBDB); + RG500->ItemIndex = sys.m_test500; + CBPhase->Checked = sys.m_testPhase; + UDClockErr->Position = short(sys.m_testClockErr); + OnWave(); + int r = ShowModal(); + if( (r == IDOK) || (r == IDYES) ){ + sys.m_testSN = UdSN->Position; + sys.m_testName = EFile->Text; + sys.m_testCarrier1 = UdCarrier1->Position; + sys.m_testCarrier2 = UdCarrier2->Position; + sys.m_testDB2 = UdDB2->Position; + sscanf(AnsiString(CBQSBTime->Text).c_str(), "%u", &sys.m_testQSBTime); //JA7UDE 0428 + sys.m_testQSBDB = UdQSBDB->Position; + sys.m_test500 = RG500->ItemIndex; + sys.m_testPhase = CBPhase->Checked; + sys.m_testClockErr = UDClockErr->Position; + if( r == IDYES ){ + return 2 + SBDo->Down; + } + else { + return 1; + } + } +#endif + return 0; +} +//--------------------------------------------------------------------- +void __fastcall TTestDlg::SBFClick(TObject *Sender) +{ +#if DEBUG + TOpenDialog *pBox = new TOpenDialog(this); + pBox->Options >> ofCreatePrompt; + pBox->Options << ofFileMustExist; + if( sys.m_MsgEng ){ + pBox->Title = "text file"; + pBox->Filter = "Text Files(*.txt)|*.txt|"; + } + else { + pBox->Title = "擬似受信テキスト"; + pBox->Filter = "テキストファイル(*.txt)|*.txt|"; + } + pBox->FileName = EFile->Text; + pBox->DefaultExt = "txt"; + pBox->InitialDir = sys.m_BgnDir; + OnWave(); + if( pBox->Execute() == TRUE ){ + EFile->Text = pBox->FileName; + } + delete pBox; +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TTestDlg::SBDoClick(TObject *Sender) +{ + ModalResult = mrYes; +} +//--------------------------------------------------------------------------- + +void __fastcall TTestDlg::SBClrClick(TObject *Sender) +{ + EFile->Text = ""; +} +//--------------------------------------------------------------------------- + diff --git a/Test.dfm b/Test.dfm new file mode 100644 index 0000000..06e0eb6 Binary files /dev/null and b/Test.dfm differ diff --git a/Test.h b/Test.h new file mode 100644 index 0000000..fe30e08 --- /dev/null +++ b/Test.h @@ -0,0 +1,81 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef OCBH +#define OCBH +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TTestDlg : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TLabel *L1; + TComboBox *CBSigSN; + TLabel *L2; + TLabel *L3; + TEdit *EFile; + TSpeedButton *SBF; + TSpeedButton *SBDo; + TUpDown *UdSN; + TComboBox *CBCarrier1; + TComboBox *CBCarrier2; + TUpDown *UdCarrier1; + TUpDown *UdCarrier2; + TEdit *EDB2; + TUpDown *UdDB2; + TComboBox *CBQSBTime; + TLabel *L5; + TComboBox *CBQSBDB; + TUpDown *UdQSBDB; + TLabel *L6; + TLabel *L7; + TSpeedButton *SBClr; + TCheckBox *CBPhase; + TRadioGroup *RG500; + TLabel *Label1; + TComboBox *CBClockErr; + TUpDown *UDClockErr; + void __fastcall SBFClick(TObject *Sender); + + void __fastcall SBDoClick(TObject *Sender); + void __fastcall SBClrClick(TObject *Sender); +private: +public: + virtual __fastcall TTestDlg(TComponent* AOwner); + + int __fastcall Execute(void); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TTestDlg *TestDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/TrackDlg.cpp b/TrackDlg.cpp new file mode 100644 index 0000000..235e194 --- /dev/null +++ b/TrackDlg.cpp @@ -0,0 +1,110 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Main.h" +#include "TrackDlg.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TTrackDlgBox *TrackDlgBox; +static int g_DlgCount=0; +//--------------------------------------------------------------------- +__fastcall TTrackDlgBox::TTrackDlgBox(TComponent* AOwner) + : TForm(AOwner) +{ + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + CancelBtn->Caption = "Cancel"; + } + FormCenter(this); + m_Changed = FALSE; +} +//--------------------------------------------------------------------- +BOOL __fastcall TTrackDlgBox::Execute(LPCSTR pTitle, double &d, double min, double max, int sc, double per) +{ + if( g_DlgCount ) return FALSE; + + g_DlgCount++; + if( pTitle && *pTitle ) Caption = pTitle; + if( min > max ){ + double d = min; + min = max; + max = d; + } + else if( min == max ){ + max = min + 10.0; + } + m_Min = min; + m_Max = max; + char bf[256], bff[128]; + sprintf(bf, "Min(%s)", StrDbl(bff, min)); + LMin->Caption = bf; + sprintf(bf, "Max(%s)", StrDbl(bff, max)); + LMax->Caption = bf; + if( per < 0.0 ) per = -per; + if( per < 1e-64 ) per = 1.0; + m_K = per; + int mw = ((max - min)/per) + 0.5; + TB->Min = 0; + TB->Max = mw; + TB->Position = ((d - m_Min) / m_K)+0.5; + if( sc < 2 ){ + sc = (max - min) / per; + if( sc > 20 ) sc = 20; + } + TB->Frequency = (mw/sc)+0.5; + ShowLV(); + m_Changed = FALSE; + int r = ShowModal(); + if( r == IDOK ){ + if( m_Changed ) d = (TB->Position * m_K) + m_Min; + r = TRUE; + } + else { + r = FALSE; + } + g_DlgCount--; + return r; +} +//--------------------------------------------------------------------- +void __fastcall TTrackDlgBox::ShowLV(void) +{ + char bf[256], bff[128]; + double d = (TB->Position * m_K) + m_Min; + AnsiString as = StrDbl(bff, m_K); + if( sys.m_MsgEng ){ + sprintf(bf, "Value= %s (Step=%s)", StrDbl(bff, d), as.c_str()); + } + else { + sprintf(bf, "値= %s (ステップ=%s)", StrDbl(bff, d), as.c_str()); + } + LV->Caption = bf; +} +//--------------------------------------------------------------------- +void __fastcall TTrackDlgBox::TBChange(TObject *Sender) +{ + m_Changed = TRUE; + ShowLV(); +} +//--------------------------------------------------------------------------- diff --git a/TrackDlg.dfm b/TrackDlg.dfm new file mode 100644 index 0000000..df0372b Binary files /dev/null and b/TrackDlg.dfm differ diff --git a/TrackDlg.h b/TrackDlg.h new file mode 100644 index 0000000..7024fb4 --- /dev/null +++ b/TrackDlg.h @@ -0,0 +1,65 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef TrackDlgBox_H +#define TrackDlgBox_H +//---------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------- +#include "ComLib.h" +//---------------------------------------------------------------------------- +class TTrackDlgBox : public TForm +{ +__published: + TButton *OKBtn; + TButton *CancelBtn; + TTrackBar *TB; + TLabel *LMin; + TLabel *LMax; + TLabel *LV; + void __fastcall TBChange(TObject *Sender); +private: + BOOL m_Changed; + + double m_K; + double m_Min, m_Max; + + void __fastcall ShowLV(void); +public: + virtual __fastcall TTrackDlgBox(TComponent* AOwner); + + BOOL __fastcall Execute(LPCSTR pTitle, double &d, double min, double max, int sc, double per); +}; +//---------------------------------------------------------------------------- +//extern PACKAGE TTrackDlgBox *TrackDlgBox; +//---------------------------------------------------------------------------- +#endif + diff --git a/VariCode.tbl b/VariCode.tbl new file mode 100644 index 0000000..a1e145d Binary files /dev/null and b/VariCode.tbl differ diff --git a/VerDsp.cpp b/VerDsp.cpp new file mode 100644 index 0000000..f302a1e --- /dev/null +++ b/VerDsp.cpp @@ -0,0 +1,57 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "VerDsp.h" +#include "ComLib.h" +//--------------------------------------------------------------------- +#pragma resource "*.dfm" +//TVerDspDlg *VerDspDlg; +//--------------------------------------------------------------------- +__fastcall TVerDspDlg::TVerDspDlg(TComponent* AOwner) + : TForm(AOwner) +{ + IconImage->Picture->Assign(Application->Icon); + FormStyle = ((TForm *)AOwner)->FormStyle; + Font->Name = ((TForm *)AOwner)->Font->Name; + Font->Charset = ((TForm *)AOwner)->Font->Charset; + LFree->Font->Name = ((TForm *)AOwner)->Font->Name; + LFree->Font->Charset = ((TForm *)AOwner)->Font->Charset; + if( sys.m_MsgEng ){ + Caption = "Version Information"; + LFree->Caption = "Free Software"; + } + Version->Caption = VERTTL; + OnWave(); +#if 0 + LInfo->Caption = + "I would like to thank my friends in both groups\r\n\r\n" + " MM-SSTV@yahoogroups.com\r\n" + " mmhamsoft@egroups.co.jp\r\n\r\n" + "I do not list all those names, for fear that I would forget one.\r\n" + "And too small space in the window for writing all the name..." + ; +#endif + FormCenter(this); +} +//--------------------------------------------------------------------- + diff --git a/VerDsp.dfm b/VerDsp.dfm new file mode 100644 index 0000000..bc41a92 Binary files /dev/null and b/VerDsp.dfm differ diff --git a/VerDsp.h b/VerDsp.h new file mode 100644 index 0000000..84f2086 --- /dev/null +++ b/VerDsp.h @@ -0,0 +1,50 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//---------------------------------------------------------------------------- +#ifndef VerDspH +#define VerDspH +//---------------------------------------------------------------------------- +//JA7UDE 0428 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//---------------------------------------------------------------------------- +class TVerDspDlg : public TForm +{ +__published: + TButton *OKBtn; + TLabel *Version; + TImage *IconImage; + TLabel *LFree; +private: +public: + virtual __fastcall TVerDspDlg(TComponent* AOwner); +}; +//---------------------------------------------------------------------------- +//extern TVerDspDlg *VerDspDlg; +//---------------------------------------------------------------------------- +#endif diff --git a/Wave.cpp b/Wave.cpp new file mode 100644 index 0000000..e09d029 --- /dev/null +++ b/Wave.cpp @@ -0,0 +1,1242 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#include +#pragma hdrstop + +#include +#include "Wave.h" +#include "dsp.h" +#include "ComLib.h" + +//--------------------------------------------------------------------------- +// 初期化 +__fastcall CWave::CWave(void) +{ + m_Error = 0; + m_InOpen = m_OutOpen = FALSE; + m_hin = NULL; + m_hout = NULL; + m_InEvent = NULL; + m_OutEvent = NULL; + for( int i = 0; i < WAVE_FIFO_MAX; i++ ){ + m_pInBuff[i] = m_pOutBuff[i] = NULL; + } + m_pOutBase = m_pInBase = NULL; + m_SoundTxID = m_SoundID = -1; + m_InBuffSize = 1024; + m_OutBuffSize = 1024; + m_OutFirst = FALSE; + m_InFifoSize = 12; + m_OutFifoSize = 6; + m_SoundStereo = 0; + m_pDLL = NULL; + m_fPTT = FALSE; + ::InitializeCriticalSection(&m_InCS); + ::InitializeCriticalSection(&m_OutCS); +} + +//--------------------------------------------------------------------------- +// 終了時実行ルーチン +__fastcall CWave::~CWave() +{ + ::DeleteCriticalSection(&m_InCS); + ::DeleteCriticalSection(&m_OutCS); + if( m_pDLL ){ + delete m_pDLL; + m_pDLL = NULL; + } +} +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +void __fastcall CWave::GetInDevName(AnsiString &as) +{ + int id = m_SoundID; + if( id == -2 ){ + as = sys.m_SoundMMW + " (MM Custom sound)"; + return; + } + GetDeviceList(); + if( (id < 0) || (id >= AN(m_tInDevName)) ) id = 0; + as = m_tInDevName[id]; +} +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +void __fastcall CWave::GetOutDevName(AnsiString &as) +{ + int id = m_SoundID; + if( id == -2 ){ + as = sys.m_SoundMMW + " (MM Custom sound)"; + return; + } + GetDeviceList(); + id = m_SoundTxID; + if( (id < 0) || (id >= AN(m_tOutDevName)) ) id = 0; + as = m_tOutDevName[id]; +} +#if 0 +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +BOOL __fastcall CWave::IsFormatSupported(LPWAVEFORMATEX pWFX, UINT IDDevice) +{ + return (::waveOutOpen( + NULL, // ptr can be NULL for query + IDDevice, // the device identifier + pWFX, // defines requested format + NULL, // no callback + NULL, // no instance data + WAVE_FORMAT_QUERY // query only, do not open device + ) ? FALSE : TRUE); +} +#endif +//--------------------------------------------------------------------------- +// サウンドカードの入力でのオープン +// WFX.wFormatTag = WAVE_FORMAT_PCM; +// WFX.nChannels = 1; +// WFX.wBitsPerSample = 16; +// WFX.nSamplesPerSec = 11025; +// WFX.nBlockAlign = WORD(WFX.nChannels *(WFX.wBitsPerSample/8)); +// WFX.nAvgBytesPerSec = WFX.nBlockAlign * WFX.nSamplesPerSec; +// WFX.cbSize = 0; +BOOL __fastcall CWave::InOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size) +{ + if( m_pDLL ){ + m_InOpen = m_pDLL->InOpen(pWFX->nSamplesPerSec, Size); + if( !m_InOpen ) PumpMessages(); + return m_InOpen; + } + int i; + + if( m_InOpen ) InClose(); + m_Error = 0; + m_InWait = m_InOver = FALSE; + m_InWP = m_InRP = m_InBC = 0; + m_IWFX = *pWFX; + m_InLen = Size; + m_InBuffSize = Size * (m_IWFX.wBitsPerSample/8) * m_IWFX.nChannels; + m_InMemSize = sizeof(WAVEHDR) + m_InBuffSize; + if( m_InMemSize & 3 ) m_InMemSize += 4 - (m_InMemSize & 3); + m_InAllocSize = m_InMemSize * m_InFifoSize; + m_InEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + // サウンドカードのオープン + if( (m_Error = ::waveInOpen( &m_hin, IDDevice, pWFX, (DWORD)WaveInProc, (DWORD)this, CALLBACK_FUNCTION ) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + // バッファの準備 + m_pInBase = new char[m_InAllocSize]; + ::VirtualLock(m_pInBase, m_InAllocSize); + memset(m_pInBase, 0, m_InAllocSize); + LPSTR p = m_pInBase; + for( i=0; i < m_InFifoSize; i++, p += m_InMemSize ){ + m_pInBuff[i] = (WAVEHDR *)p; + ((WAVEHDR *)p)->dwBufferLength = m_InBuffSize; + ((WAVEHDR *)p)->dwFlags = 0; + ((WAVEHDR *)p)->dwUser = NULL; + ((WAVEHDR *)p)->dwBytesRecorded = NULL; + ((WAVEHDR *)p)->lpData = p + sizeof(WAVEHDR); + if( (m_Error = ::waveInPrepareHeader(m_hin, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + if( (m_Error = ::waveInAddBuffer(m_hin, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + } + // 取りこみの開始 + if( (m_Error = ::waveInStart(m_hin) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + m_InOpen = TRUE; + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CWave::InClose() +{ + if( m_pDLL ){ + m_pDLL->InClose(); + m_InOpen = FALSE; + PumpMessages(); + return; + } + int i; + + if(NULL != m_hin){ + ::waveInReset(m_hin); + if( m_pInBase != NULL ){ + for( i=0; i < m_InFifoSize; i++ ){ + if( m_pInBuff[i] != NULL ){ + if( m_pInBuff[i]->dwFlags & WHDR_PREPARED ){ + ::waveInUnprepareHeader(m_hin, m_pInBuff[i], sizeof(WAVEHDR)); + } + } + } + } + ::waveInClose(m_hin); + m_hin = NULL; + if( m_pInBase != NULL ){ + ::VirtualUnlock(m_pInBase, m_InAllocSize); + delete m_pInBase; + m_pInBase = NULL; + } + } + if(m_InEvent != NULL){ + ::CloseHandle(m_InEvent); + m_InEvent = NULL; + } + m_InOpen = FALSE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::InRead(SHORT *pData) +{ + if( m_pDLL ){ + return m_pDLL->InRead(pData); + } + int Len = m_InLen; + int i; + + if( !m_InOpen ){ + m_Error = 1; + return FALSE; + } + if( m_InOver ){ + m_Error = 1; + InClose(); + return FALSE; + } + + ::EnterCriticalSection(&m_InCS); + if( !m_InBC ){ // まだデータが存在しない時 + m_InWait++; + ::LeaveCriticalSection(&m_InCS); + // バッファにデータが溜まるまで待つ + if( ::WaitForSingleObject( m_InEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 1; + InClose(); + return FALSE; + } + } + else { + ::LeaveCriticalSection(&m_InCS); + } + // データを浮動少数点に変換 + LPWAVEHDR hp = m_pInBuff[m_InRP]; + SHORT *rp = (SHORT *)hp->lpData; + if( m_IWFX.nChannels == 2 ){ + if( m_SoundStereo == 1 ){ // Left + for( i = 0; i < Len; i++ ){ + *pData++ = *rp++; + rp++; + } + } + else { // Right + for( i = 0; i < Len; i++ ){ + rp++; + *pData++ = *rp++; + } + } + } + else { + memcpy(pData, rp, sizeof(SHORT) * Len); + } + hp->dwBytesRecorded = NULL; + ::waveInAddBuffer(m_hin, hp, sizeof(WAVEHDR)); + m_InBC--; // 1命令で展開されるので CriticalSection は不要 + m_InRP++; + if( m_InRP >= m_InFifoSize){ + m_InRP = 0; + } + return TRUE; +} +//--------------------------------------------------------------------------- +//void CALLBACK WaveProc(hWave, uMsg, dwInstance, dwParam1, dwParam2) +// +//HWAVE hWave; /* ウェーブフォーム デバイスのハンドル */ +//UINT uMsg; /* 送るメッセージ */ +//DWORD dwInstance; /* インスタンス データ */ +//DWORD dwParam1; /* アプリケーション定義のパラメータ */ +//DWORD dwParam2; /* アプリケーション定義のパラメータ */ +void CALLBACK WaveInProc(HWAVE m_hin, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ) +{ + if( uMsg == MM_WIM_DATA ){ + ::EnterCriticalSection(&pWave->m_InCS); + pWave->m_InBC++; + pWave->m_InWP++; + if( pWave->m_InWP >= pWave->m_InFifoSize ) pWave->m_InWP = 0; + if( pWave->m_InBC > pWave->m_InFifoSize ) pWave->m_InOver = TRUE; + if(pWave->m_InWait){ + pWave->m_InWait--; + ::SetEvent(pWave->m_InEvent); + } + ::LeaveCriticalSection(&pWave->m_InCS); + ::PostMessage(pWave->m_hWnd, WM_WAVE, waveIN, 0); + } +} +//--------------------------------------------------------------------------- +// サウンドカードの出力でのオープン +// WFX.wFormatTag = WAVE_FORMAT_PCM; +// WFX.nChannels = 1; +// WFX.wBitsPerSample = 16; +// WFX.nSamplesPerSec = 11025; +// WFX.nBlockAlign = WORD(WFX.nChannels *(WFX.wBitsPerSample/8)); +// WFX.nAvgBytesPerSec = WFX.nBlockAlign * WFX.nSamplesPerSec; +// WFX.cbSize = 0; +BOOL __fastcall CWave::OutOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size) +{ + if( m_pDLL ){ + m_OutOpen = m_pDLL->OutOpen(pWFX->nSamplesPerSec, Size); + if( !m_OutOpen ) PumpMessages(); + return m_OutOpen; + } + if( m_OutOpen ) OutAbort(); + m_Error = 0; + m_OutBCC = 0x7fffffff; + m_OutWait = FALSE; + m_OutUnder = FALSE; + m_OutWP = m_OutRP = m_OutBC = 0; + m_OWFX = *pWFX; + m_OutLen = Size; + m_OutBuffSize = Size * (m_OWFX.wBitsPerSample/8) * m_OWFX.nChannels; + m_OutMemSize = sizeof(WAVEHDR) + m_OutBuffSize; + if( m_OutMemSize & 3 ) m_OutMemSize += 4 - (m_OutMemSize & 3); + m_OutAllocSize = m_OutMemSize * m_OutFifoSize; + m_OutEvent = ::CreateEvent(NULL, FALSE,FALSE,NULL); + if( (m_Error = ::waveOutOpen( &m_hout, IDDevice , pWFX, (DWORD)WaveOutProc, (DWORD)this, CALLBACK_FUNCTION ) ) != MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + if( (m_Error = ::waveOutPause(m_hout))!= MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + // バッファーの準備 + m_pOutBase = new char[m_OutAllocSize]; + ::VirtualLock(m_pOutBase, m_OutAllocSize); + memset(m_pOutBase, 0, m_OutAllocSize); + LPSTR p = m_pOutBase; + for(int i = 0; i < m_OutFifoSize; i++, p += m_OutMemSize ){ + m_pOutBuff[i] = (WAVEHDR *)p; + ((WAVEHDR *)p)->dwBufferLength = m_OutBuffSize; + ((WAVEHDR *)p)->dwFlags = 0; + ((WAVEHDR *)p)->dwUser = NULL; + ((WAVEHDR *)p)->dwLoops = NULL; + ((WAVEHDR *)p)->lpData = p + sizeof(WAVEHDR); + if( (m_Error = ::waveOutPrepareHeader(m_hout, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + } + m_OutOpen = TRUE; + m_OutFirst = TRUE; + return TRUE; +} +#if 0 +//--------------------------------------------------------------------------- +DWORD __fastcall CWave::GetOutVolume(void) +{ + if( !m_OutOpen ){ + return 0x8000; + } + DWORD vol; + ::waveOutGetVolume(m_hout, &vol); + return vol; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::SetOutVolume(DWORD vol) +{ + if( !m_OutOpen ){ + return FALSE; + } + ::waveOutSetVolume(m_hout, vol); + return TRUE; +} +#endif +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::OutWrite(const SHORT *pData) +{ + if( m_pDLL ){ + return m_pDLL->OutWrite(pData); + } + int Len = m_OutLen; + int i; + if( !m_OutOpen ){ + m_Error = 1; + return FALSE; + } + if( m_OutUnder ){ + m_Error = 1; + OutClose(); + return FALSE; + } + + // 送信バッファ空き待ち + EnterCriticalSection(&m_OutCS); + if( m_OutBC >= m_OutFifoSize ){ + m_OutWait++; + ::LeaveCriticalSection(&m_OutCS); + if( ::WaitForSingleObject( m_OutEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 2; + OutAbort(); + return FALSE; + } + } + else { + ::LeaveCriticalSection(&m_OutCS); + } + + // データの変換 + LPWAVEHDR hp = m_pOutBuff[m_OutWP]; + SHORT *wp = (SHORT *)hp->lpData; + if( m_OWFX.nChannels == 2 ){ + for( i = 0; i < Len; i++ ){ + *wp++ = *pData; + *wp++ = *pData++; + } + } + else { + memcpy(wp, pData, sizeof(SHORT)*Len); + } + ::waveOutWrite(m_hout, hp, sizeof(WAVEHDR) ); + m_OutBC++; // 1命令で展開されるので CriticalSection は不要 + if( m_OutFirst ){ + if( (m_OutBC >= 8) || (m_OutBC >= (m_OutFifoSize-1)) ){ + m_OutFirst = FALSE; + ::waveOutRestart( m_hout ); + } + } + m_OutWP++; + if( m_OutWP >= m_OutFifoSize){ + m_OutWP = 0; + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CWave::OutFlush() +{ + if( m_pDLL ){ + m_pDLL->OutFlush(); + return; + } + if(m_hout != NULL){ + // バッファ送信待ち + while(1){ + ::EnterCriticalSection(&m_OutCS); + if( m_OutBC > 0 ){ // 未送出データが存在する場合 + m_OutWait++; + ::LeaveCriticalSection(&m_OutCS); + if( ::WaitForSingleObject( m_OutEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 2; + break; + } + } + else { + ::LeaveCriticalSection(&m_OutCS); + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::OutAbort() +{ + if( m_pDLL ){ + m_pDLL->OutAbort(); + m_OutOpen = FALSE; + PumpMessages(); + return; + } + if(m_hout != NULL){ + ::waveOutReset(m_hout); + ::Sleep(1); // for the timing + // バッファの解放 + if( m_pOutBase != NULL ){ + for(int i = 0; i < m_OutFifoSize; i++ ){ + if( m_pOutBuff[i] != NULL ){ + if( m_pOutBuff[i]->dwFlags & WHDR_PREPARED ){ + ::waveOutUnprepareHeader(m_hout, m_pOutBuff[i], sizeof(WAVEHDR)); + } + } + } + } + ::waveOutClose(m_hout); + m_hout = NULL; + if( m_pOutBase != NULL ){ + ::VirtualUnlock(m_pOutBase, m_OutAllocSize); + delete m_pOutBase; + m_pOutBase = NULL; + } + } + if(m_OutEvent != NULL){ + ::CloseHandle(m_OutEvent); + m_OutEvent = NULL; + } + m_OutOpen = FALSE; +} +//--------------------------------------------------------------------------- +//void CALLBACK WaveProc(hWave, uMsg, dwInstance, dwParam1, dwParam2) +// +//HWAVE hWave; /* ウェーブフォーム デバイスのハンドル */ +//UINT uMsg; /* 送るメッセージ */ +//DWORD dwInstance; /* インスタンス データ */ +//DWORD dwParam1; /* アプリケーション定義のパラメータ */ +//DWORD dwParam2; /* アプリケーション定義のパラメータ */ +void CALLBACK WaveOutProc(HWAVE m_hout, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ) +{ + if( uMsg == WOM_DONE ){ + EnterCriticalSection(&pWave->m_OutCS); + pWave->m_OutBCC--; + pWave->m_OutBC--; + pWave->m_OutRP++; + if( pWave->m_OutRP >= pWave->m_OutFifoSize) pWave->m_OutRP = 0; + if( !pWave->m_OutBC ) pWave->m_OutUnder = TRUE; + if(pWave->m_OutWait){ + pWave->m_OutWait--; + SetEvent(pWave->m_OutEvent); + } + LeaveCriticalSection(&pWave->m_OutCS); + ::PostMessage(pWave->m_hWnd, WM_WAVE, waveOUT, 0); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::IsOutFirst(void) +{ + if( m_pDLL ){ + return FALSE; + } + else { + return m_OutFirst; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetInBC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetInBC(); + } + else { + return m_InBC; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetOutBC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetOutBC(); + } + else { + return m_OutBC; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetOutBCC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetOutBCC(); + } + else { + return m_OutBCC; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetOutBCC(int count) +{ + if( m_pDLL ){ + m_pDLL->SetOutBCC(count); + } + else { + m_OutBCC = count; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsInBufCritical(void) +{ + if( m_pDLL ){ + return m_pDLL->IsInBufCritical(); + } + else { + return ( m_InBC >= (m_InFifoSize/2) ) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsOutBufCritical(void) +{ + if( m_pDLL ){ + return m_pDLL->IsOutBufCritical(); + } + else { + return (m_OutBC <= (m_OutFifoSize/2)) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsOutBufFull(void) +{ + if( m_pDLL ){ + return m_pDLL->IsOutBufFull(); + } + else { + return (m_OutBC >= m_OutFifoSize) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetPTT(LONG tx) +{ + m_fPTT = tx; + if( m_pDLL ) m_pDLL->SetPTT(tx); +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetTimeout(void) +{ + if( m_pDLL ){ + return m_pDLL->GetTimeout(); + } + else { + return 5000; + } +} +//--------------------------------------------------------------------------- +// サウンドカードの名前を得る +void __fastcall CWave::GetDeviceList(void) +{ + m_InDevs = 0; + m_OutDevs = 0; + WAVEINCAPS incaps; + for( int i = 0; i < AN(m_tInDevName); i++ ){ + if( !waveInGetDevCaps(i, &incaps, sizeof(incaps)) ){ + m_tInDevName[i] = incaps.szPname; + m_InDevs = i + 1; + } + else { + m_tInDevName[i] = ""; + } + } + WAVEOUTCAPS outcaps; + for( int i = 0; i < AN(m_tOutDevName); i++ ){ + if( !waveOutGetDevCaps(i, &outcaps, sizeof(outcaps)) ){ + m_tOutDevName[i] = outcaps.szPname; + m_OutDevs = i + 1; + } + else { + m_tOutDevName[i] = ""; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetSoundID(int &rxID, int &txID) +{ + BOOL fList = FALSE; + int d; + if( sscanf(sys.m_SoundIDRX.c_str(), "%d", &d ) == 1 ){ + rxID = d; + } + else { + rxID = -2; + GetDeviceList(); fList = TRUE; + for( int i = 0; i < m_InDevs; i++ ){ + if( !strcmp(m_tInDevName[i].c_str(), sys.m_SoundIDRX.c_str()) ){ + rxID = i; + break; + } + } + if( rxID == -2 ){ + sys.m_SoundMMW = sys.m_SoundIDRX; + } + } + if( sscanf(sys.m_SoundIDTX.c_str(), "%d", &d ) == 1 ){ + txID = d; + } + else { + txID = -1; + if( !fList ) GetDeviceList(); + for( int i = 0; i < m_OutDevs; i++ ){ + if( !strcmp(m_tOutDevName[i].c_str(), sys.m_SoundIDTX.c_str()) ){ + txID = i; + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::UpdateDevice(int ID) +{ + if( ID == -2 ){ + if( (m_pDLL == NULL) || m_pDLL->IsNameChange() ){ + if( m_pDLL ) delete m_pDLL; + m_pDLL = new CXWave(sys.m_SoundMMW.c_str()); + } + } + else if( m_pDLL != NULL ){ + delete m_pDLL; + m_pDLL = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::PumpMessages(void) +{ +#if 0 + if( m_pDLL ){ + m_pDLL->PumpMessages(); + } +#endif +} + +//*************************************************************************** +// CXWave class +//--------------------------------------------------------------------------- +void CALLBACK TimeProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) +{ + OnWave(); +} +//--------------------------------------------------------------------------- +__fastcall CXWave::CXWave(LPCSTR pName) +{ + m_ItemName = pName; + m_nTimerID = 0; + + char Name[MAX_PATH]; + if( !*GetEXT(pName) ){ + wsprintf(Name, "%s.mmw", pName); + pName = Name; + } + + m_hLib = ::LoadLibrary(pName); + if( m_hLib ){ + + fmmwPumpMessages = PROC(mmwPumpMessages); + fmmwSetPTT = PROC(mmwSetPTT); + fmmwGetTimeout = PROC(mmwGetTimeout); + + fmmwInOpen = PROC(mmwInOpen); + fmmwInClose = PROC(mmwInClose); + fmmwInRead = PROC(mmwInRead); + + fmmwGetInExist = PROC(mmwGetInExist); + fmmwIsInCritical = PROC(mmwIsInCritical); + + fmmwOutOpen = PROC(mmwOutOpen); + fmmwOutAbort = PROC(mmwOutAbort); + fmmwOutFlush = PROC(mmwOutFlush); + fmmwOutWrite = PROC(mmwOutWrite); + + fmmwIsOutCritical = PROC(mmwIsOutCritical); + fmmwIsOutFull = PROC(mmwIsOutFull); + fmmwGetOutRemaining = PROC(mmwGetOutRemaining); + fmmwGetOutCounter = PROC(mmwGetOutCounter); + fmmwSetOutCounter = PROC(mmwSetOutCounter); + + + if( !m_hLib ){ + FreeLib(); + } + else { + //m_nTimerID = ::SetTimer(NULL, 0, 50, (int (__stdcall *)())TimeProc); //$$$ + m_nTimerID = SetTimer(NULL, 0, 50, TimeProc); + } + } +} +//--------------------------------------------------------------------------- +__fastcall CXWave::~CXWave(void) +{ + if( m_nTimerID ){ + ::KillTimer(NULL, m_nTimerID); + } + if( m_hLib ){ + fmmwOutAbort(); + fmmwInClose(); + } + FreeLib(); +} +//--------------------------------------------------------------------------- +FARPROC __fastcall CXWave::GetProc(LPCSTR pName) +{ + if( !m_hLib ) return NULL; + + FARPROC fn = ::GetProcAddress(m_hLib, pName+1); + if( fn == NULL ){ + fn = ::GetProcAddress(m_hLib, pName); + if( fn == NULL ) FreeLib(); + } + return fn; +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::FreeLib(void) +{ + if( m_hLib ){ + FreeLibrary(m_hLib); + m_hLib = NULL; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::IsNameChange(void) +{ + return strcmpi(m_ItemName.c_str(), sys.m_SoundMMW.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::PumpMessages(void) +{ + if( !IsLib() ) return; + + fmmwPumpMessages(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::InOpen(int sampfreq, int size) +{ + if( !IsLib() ) return FALSE; + + return fmmwInOpen(sampfreq, size); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::InClose(void) +{ + if( !IsLib() ) return; + + fmmwInClose(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::InRead(SHORT *p) +{ + if( !IsLib() ) return FALSE; + + return fmmwInRead(p); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetInBC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetInExist(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsInBufCritical(void) +{ + if( !IsLib() ) return 0; + return fmmwIsInCritical(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::OutOpen(int sampfreq, int size) +{ + if( !IsLib() ) return FALSE; + return fmmwOutOpen(sampfreq, size); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::OutFlush(void) +{ + if( !IsLib() ) return; + fmmwOutFlush(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::OutAbort(void) +{ + if( !IsLib() ) return; + fmmwOutAbort(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::OutWrite(const SHORT *p) +{ + if( !IsLib() ) return FALSE; + return fmmwOutWrite(p); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetOutBC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetOutRemaining(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetOutBCC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetOutCounter(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::SetOutBCC(int count) +{ + if( !IsLib() ) return; + fmmwSetOutCounter(count); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsOutBufCritical(void) +{ + if( !IsLib() ) return 0; + return fmmwIsOutCritical(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsOutBufFull(void) +{ + if( !IsLib() ) return 0; + return fmmwIsOutFull(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::SetPTT(int tx) +{ + if( !IsLib() ) return; + fmmwSetPTT(tx); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetTimeout(void) +{ + if( !IsLib() ) return 200; + return fmmwGetTimeout(); +} +//--------------------------------------------------------------------------- +// +//*************************************************************************** +// CWaveFileクラス +// +const int g_tSampTable[]={11025, 8000, 6000, 12000, 16000, 18000, 22050, 24000, 44100, 48000, 50000}; +//--------------------------------------------------------------------------- +// CWaveFileクラス +__fastcall CWaveFile::CWaveFile() +{ + m_mode = 0; + m_pause = 0; + m_Handle = NULL; + m_dis = 0; + m_autopause = TRUE; +} + +__fastcall CWaveFile::~CWaveFile() +{ + FileClose(); +} + +void __fastcall CWaveFile::FileClose(void) +{ + m_mode = 0; + m_pause = 0; + if( m_Handle != NULL ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + } +} + +void __fastcall CWaveFile::ReadWrite(short *s, int size) +{ + int csize = size * sizeof(short); + + if( m_Handle != NULL ){ + if( m_mode == 2 ){ // 書きこみ + if( !m_pause ){ + if( mmioWrite(m_Handle, (const char*)s, csize) != csize ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + m_mode = 0; + } + else { + m_pos += csize; + } + } + } + else { // 読み出し + if( m_pause || m_dis ){ + memset(s, 0, csize); + } + else { + if( mmioRead(m_Handle, (char *)s, csize) == csize ){ + m_pos += csize; + } + else if( m_autopause ){ +// Rewind(); + m_pause = 1; + } + else { + mmioClose(m_Handle, 0); + m_Handle = 0; + m_mode = 0; + } + } + } + } +} + +void __fastcall CWaveFile::Rec(LPCSTR pName) +{ + FileClose(); + m_FileName = pName; + GetFileName(m_Name, pName); + m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_CREATE|MMIO_WRITE|MMIO_ALLOCBUF); + if( m_Handle == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'を作成できません.", pName); + return; + } + m_Head[0] = 0x55; + m_Head[1] = 0xaa; + m_Head[2] = char(SAMPTYPE); + m_Head[3] = 0; + mmioWrite(m_Handle, (const char *)m_Head, 4); + m_pos = 4; + m_mode = 2; + m_pause = 0; + m_dis = 0; +} + +BOOL __fastcall CWaveFile::Play(LPCSTR pName) +{ + FileClose(); + FILE *fp = fopen(pName, "rb"); + if( fp == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'をオープンできません.", pName); + return FALSE; + } + m_length = filelength(fileno(fp)); + m_FileName = pName; + GetFileName(m_Name, pName); + + fclose(fp); + m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_READ|MMIO_ALLOCBUF); + if( m_Handle == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'をオープンできません.", pName); + return FALSE; + } + m_pos = 0; + if( mmioRead(m_Handle, (char *)m_Head, 4) == 4 ){ + int type = 0; + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + type = m_Head[2]; + m_pos = 4; + m_length -= 4; + } + if( type > 10 ) type = 0; + if( type != SAMPTYPE ){ + if( YesNoMB( + sys.m_MsgEng + ? "%s\r\n\r\nThis file has been recorded based on %uHz, play it with sampling conversion?\r\n\r\nThis conversion needs long time..." + : "%s\r\n\r\nこのファイルは %uHz ベースで記録されています. 周波数変換して再生しますか?\r\n\r\nこの変換は時間がかかる場合があります...", + m_FileName.c_str(), g_tSampTable[type] ) == IDNO ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + return FALSE; + } + else { + mmioClose(m_Handle, 0); + m_Handle = 0; + char bf[1024]; + strcpy(bf, pName); + SetEXT(bf, ""); + char wName[1024]; + sprintf(wName, "%s_%u.MMV", bf, int(SAMPBASE)); + if( ChangeSampFreq(wName, pName, g_tSampTable[type]) == TRUE ){ + Play(wName); + } + } + } + } + m_mode = 1; + m_pause = 0; + m_dis = 0; + return TRUE; +} + +int __fastcall CWaveFile::ChangeSampFreq(LPCSTR tName, LPCSTR pName, int sSamp) +{ + int rr = FALSE; + FILE *fp = fopen(pName, "rb"); + if( fp != NULL ){ + CWaitCursor w; + BYTE head[4]; + memset(head, 0, sizeof(head)); + head[0] = 0x55; + head[1] = 0xaa; + head[2] = char(SAMPTYPE); + head[3] = 0; + FILE *wfp = fopen(tName, "wb"); + if( wfp != NULL ){ + fwrite(head, 1, 4, wfp); + + int rsize = 16384; + int wsize = rsize * SAMPBASE/double(sSamp); + short *rp = new short[rsize]; + short *wp = new short[wsize]; + short *ip = new short[rsize*4]; + CIIR riir; + riir.Create(ffLPF, 2800, sSamp*4, 10, 1, 0.3); + CIIR wiir; + wiir.Create(ffLPF, 2800, SAMPBASE, 10, 1, 0.3); + int rlen, wlen; + short *tp, *sp; + int i, r; + double k; + while(1){ + rlen = fread(rp, 1, rsize * 2, fp); + if( !rlen ) break; + rlen /= 2; + if( SAMPBASE < sSamp ){ // デシメーション + sp = rp; + tp = ip; + for( i = 0; i < rlen; i++, sp++ ){ // 一旦4倍にする + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + } + k = double(sSamp*4) / double(SAMPBASE); + tp = wp; + wlen = rlen * SAMPBASE / sSamp; + if( wlen > wsize ) wlen = wsize; + for( i = 0; i < wlen; i++ ){ + r = int((double(i) * k) + 0.5); + if( r >= (rlen*4) ) r = (rlen*4) - 1; + *tp++ = wiir.Do(ip[r]); + } + } + else { // インターポーレーション + k = double(sSamp) / double(SAMPBASE); + tp = wp; + wlen = rlen * SAMPBASE / sSamp; + if( wlen > wsize ) wlen = wsize; + for( i = 0; i < wlen; i++ ){ + r = int((double(i) * k) + 0.5); + if( r >= rlen ) r = rlen - 1; + *tp++ = wiir.Do(rp[r]); + } + } + if( fwrite(wp, 1, wlen * 2, wfp) != size_t(wlen * 2) ) break; + } + if( !fclose(wfp) ) rr = TRUE; + delete ip; + delete rp; + delete wp; + } + fclose(fp); + } + return rr; +} + +void __fastcall CWaveFile::Rewind(void) +{ + if( m_Handle != NULL ){ + m_dis++; + if( m_mode == 2 ){ + mmioSeek(m_Handle, 4, SEEK_SET); + m_pos = 4; + } + else { + mmioSeek(m_Handle, 0, SEEK_SET); + m_pos = 0; + } + m_dis--; + } +} + +void __fastcall CWaveFile::Seek(int n) +{ + if( m_Handle != NULL ){ + n &= 0xfffffffe; + m_dis++; + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + mmioSeek(m_Handle, n + 4, SEEK_SET); + m_pos = n + 4; + } + else { + mmioSeek(m_Handle, n, SEEK_SET); + m_pos = n; + } + m_dis--; + } +} + +long __fastcall CWaveFile::GetPos(void) +{ + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + long n = m_pos - 4; + if( n < 0 ) n = 0; + return n; + } + else { + return m_pos; + } +} + +//--------------------------------------------------------------------------- +// CWaveStrageクラス + +__fastcall CWaveStrage::CWaveStrage() +{ + m_Handle = NULL; + + m_pos = m_rpos = m_wpos = 0; + pData = pSync = NULL; +} + +void __fastcall CWaveStrage::Close(void) +{ + if( m_Handle != NULL ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + unlink(m_FileName.c_str()); + } + if( pData != NULL ){ + delete pData; + pData = NULL; + } + if( pSync != NULL ){ + delete pSync; + pSync = NULL; + } +} + +void __fastcall CWaveStrage::Open(void) +{ + Close(); + char bf[256]; + sprintf(bf, "%sSound.tmp", sys.m_BgnDir); + m_FileName = bf; + m_Handle = mmioOpen(bf, NULL, MMIO_READWRITE|MMIO_CREATE|MMIO_ALLOCBUF); + m_wpos = m_rpos = m_pos = 0; + pData = new short[1400*SAMPFREQ/1000]; + pSync = new short[1400*SAMPFREQ/1000]; +} + +void __fastcall CWaveStrage::RInit(void) +{ + m_rpos = 0; +} + +void __fastcall CWaveStrage::WInit(void) +{ + m_wpos = 0; +} + +void __fastcall CWaveStrage::Seek(int n) +{ + mmioSeek(m_Handle, n, SEEK_SET); + m_pos = n; +} + +void __fastcall CWaveStrage::Read(short *sp, int size) +{ + if( m_pos != m_rpos ){ + Seek(m_rpos); + } + mmioRead(m_Handle, (char *)sp, size); + m_rpos += size; + m_pos = m_rpos; +} + +void __fastcall CWaveStrage::Write(short *sp, int size) +{ + if( m_pos != m_wpos ){ + Seek(m_wpos); + } + mmioWrite(m_Handle, (char *)sp, size); + m_wpos += size; + m_pos = m_wpos; +} + + diff --git a/Wave.h b/Wave.h new file mode 100644 index 0000000..a283a21 --- /dev/null +++ b/Wave.h @@ -0,0 +1,287 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef WAVE_H +#define WAVE_H +//--------------------------------------------------------------------------- +#include +#include "mmw.h" +#include "ComLib.h" +//--------------------------------------------------------------------------- +#ifndef PROC +#define PROC(Key) ((t##Key)GetProc("_" #Key)) +#endif +//--------------------------------------------------------------------------- +class CXWave +{ +private: + AnsiString m_ItemName; + //HANDLE m_hLib; //ja7ude 0522 + HINSTANCE m_hLib; + UINT m_nTimerID; + + tmmwPumpMessages fmmwPumpMessages; + tmmwGetTimeout fmmwGetTimeout; + tmmwSetPTT fmmwSetPTT; + + tmmwInOpen fmmwInOpen; + tmmwInClose fmmwInClose; + tmmwInRead fmmwInRead; + + tmmwGetInExist fmmwGetInExist; + tmmwIsInCritical fmmwIsInCritical; + + tmmwOutOpen fmmwOutOpen; + tmmwOutAbort fmmwOutAbort; + tmmwOutFlush fmmwOutFlush; + tmmwOutWrite fmmwOutWrite; + + tmmwIsOutCritical fmmwIsOutCritical; + tmmwIsOutFull fmmwIsOutFull; + tmmwGetOutRemaining fmmwGetOutRemaining; + tmmwGetOutCounter fmmwGetOutCounter; + tmmwSetOutCounter fmmwSetOutCounter; + +private: + FARPROC __fastcall GetProc(LPCSTR pName); + void __fastcall FreeLib(void); + +public: + __fastcall CXWave(LPCSTR pName); + __fastcall ~CXWave(void); + inline BOOL __fastcall IsLib(void){return m_hLib != NULL;}; + BOOL __fastcall IsNameChange(void); +public: + BOOL __fastcall InOpen(int sampfreq, int size); + void __fastcall InClose(void); + BOOL __fastcall InRead(SHORT *p); + + int __fastcall GetInBC(void); + int __fastcall IsInBufCritical(void); + + BOOL __fastcall OutOpen(int sampfreq, int size); + void __fastcall OutFlush(void); + void __fastcall OutAbort(void); + BOOL __fastcall OutWrite(const SHORT *p); +// inline void __fastcall OutClose(void){OutFlush(); OutAbort();}; + + int __fastcall GetOutBC(void); + int __fastcall GetOutBCC(void); + void __fastcall SetOutBCC(int count); + int __fastcall IsOutBufCritical(void); + int __fastcall IsOutBufFull(void); + + void __fastcall SetPTT(int tx); + int __fastcall GetTimeout(void); + void __fastcall PumpMessages(void); +}; +//--------------------------------------------------------------------------- +//#define WM_WAVE WM_USER+400 +#define WAVE_TIMEOUT_EVENT 2000 // バッファリクエストのタイムアウト +#define WAVE_FIFO_MAX 32 // 循環バッファの最大個数 +//--------------------------------------------------------------------------- +class CWave +{ + friend void CALLBACK WaveInProc(HWAVE m_hin, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ); + friend void CALLBACK WaveOutProc(HWAVE m_hout, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ); + +public: + HWND m_hWnd; + + int m_InFifoSize; + int m_OutFifoSize; + int m_SoundStereo; + int m_SoundID; + int m_SoundTxID; + + int m_InDevs; + int m_OutDevs; + AnsiString m_tInDevName[16]; + AnsiString m_tOutDevName[16]; + +private: + volatile int m_InBC; + volatile int m_OutBC; + volatile int m_OutBCC; + +private: + LPWAVEHDR m_pInBuff[WAVE_FIFO_MAX]; // 入力バッファ + LPWAVEHDR m_pOutBuff[WAVE_FIFO_MAX]; // 出力バッファ + WAVEFORMATEX m_OWFX; // 出力フォーマット + WAVEFORMATEX m_IWFX; // 入力フォーマット + + CRITICAL_SECTION m_InCS; + CRITICAL_SECTION m_OutCS; + + HANDLE m_InEvent; + HANDLE m_OutEvent; + BOOL m_InWait; + BOOL m_InOver; + BOOL m_OutWait; + BOOL m_OutUnder; + + int m_InWP; + int m_InRP; + + int m_OutWP; + int m_OutRP; + + int m_Error; + BOOL m_InOpen; + BOOL m_OutOpen; + + LPSTR m_pInBase; + LPSTR m_pOutBase; + int m_InLen; + int m_InBuffSize; + int m_InMemSize; + int m_InAllocSize; + int m_OutLen; + int m_OutBuffSize; + int m_OutMemSize; + int m_OutAllocSize; + BOOL m_OutFirst; + //HWAVE m_hin; + //HWAVE m_hout; //ja7ude 0522 + HWAVEIN m_hin; + HWAVEOUT m_hout; + + BOOL m_fPTT; + CXWave *m_pDLL; +private: + +public: + __fastcall CWave(void); + __fastcall ~CWave(); +// BOOL __fastcall IsFormatSupported(LPWAVEFORMATEX pWFX, UINT IDDevice); + BOOL __fastcall InOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size); + inline __fastcall BOOL IsInOpen(){return m_InOpen;}; + BOOL __fastcall InRead(SHORT *pData); + void __fastcall InClose(); + BOOL __fastcall OutOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size); + inline __fastcall BOOL IsOutOpen(){return m_OutOpen;}; + BOOL __fastcall OutWrite(const SHORT *pData); + void __fastcall OutFlush(); + void __fastcall OutAbort(); + void __fastcall OutClose(){OutFlush();OutAbort();}; +// DWORD __fastcall GetOutVolume(void); +// BOOL __fastcall SetOutVolume(DWORD vol); +#if 0 + inline int __fastcall IsInBufCritical(void){ + return ( m_InBC >= (m_InFifoSize/2) ) ? 1 : 0; + } + inline int __fastcall IsOutBufCritical(void){ + return (m_OutBC <= (m_OutFifoSize/2)) ? 1 : 0; + } + inline int __fastcall IsOutBufFull(void){ + return (m_OutBC >= m_OutFifoSize) ? 1 : 0; + }; + inline void __fastcall SetOutBCC(int count){ + m_OutBCC = count; + }; + inline int __fastcall GetOutBCC(void){ + return m_OutBCC; + }; + inline int __fastcall GetOutBC(void){ + return m_OutBC; + }; +#else + BOOL __fastcall IsOutFirst(void); + inline int __fastcall IsInBufNull(void){return !GetInBC();}; + int __fastcall GetInBC(void); + int __fastcall GetOutBC(void); + int __fastcall GetOutBCC(void); + void __fastcall SetOutBCC(int count); + int __fastcall IsInBufCritical(void); + int __fastcall IsOutBufCritical(void); + int __fastcall IsOutBufFull(void); + void __fastcall SetPTT(LONG tx); + int __fastcall GetTimeout(void); + void __fastcall GetDeviceList(void); + void __fastcall SetSoundID(int &rxID, int &txID); + void __fastcall SetSoundID(void){ + SetSoundID(m_SoundID, m_SoundTxID); + } + void __fastcall UpdateDevice(int ID); + void __fastcall PumpMessages(void); +#endif + inline BOOL __fastcall IsPTT(void){return m_fPTT;}; + void __fastcall GetInDevName(AnsiString &as); + void __fastcall GetOutDevName(AnsiString &as); +}; + +//--------------------------------------------------------------------------- +class CWaveFile +{ +private: + HMMIO m_Handle; + int m_dis; + BYTE m_Head[4]; +private: + void __fastcall SetName(void); + +public: + long m_length; + long m_pos; + int m_mode; + int m_pause; + int m_autopause; + AnsiString m_FileName; + AnsiString m_Name; + int m_SampType; +public: + __fastcall CWaveFile(); + __fastcall ~CWaveFile(); + void __fastcall FileClose(void); + void __fastcall Rec(LPCSTR pName); + BOOL __fastcall Play(LPCSTR pName); + void __fastcall Rewind(void); + void __fastcall ReadWrite(short *s, int size); + long __fastcall GetPos(void); + void __fastcall Seek(int n); + int __fastcall ChangeSampFreq(LPCSTR tName, LPCSTR pName, int sSamp); +}; +//--------------------------------------------------------------------------- +class CWaveStrage +{ +private: + HMMIO m_Handle; + AnsiString m_FileName; + +public: + long m_pos; + long m_wpos; + long m_rpos; + short *pData; + short *pSync; + + __fastcall CWaveStrage(); + __fastcall ~CWaveStrage(){Close();}; + void __fastcall Close(void); + void __fastcall Open(void); + void __fastcall RInit(void); + void __fastcall WInit(void); + int __fastcall IsOpen(void){return m_Handle != NULL ? TRUE : FALSE;}; + void __fastcall Read(short *sp, int size); + void __fastcall Write(short *sp, int size); + void __fastcall Seek(int n); +}; +//--------------------------------------------------------------------------- +#endif + diff --git a/_BAK.MDT b/_BAK.MDT new file mode 100644 index 0000000..e8d15f3 Binary files /dev/null and b/_BAK.MDT differ diff --git a/country.cpp b/country.cpp new file mode 100644 index 0000000..13812ca --- /dev/null +++ b/country.cpp @@ -0,0 +1,351 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +/************************************************************************ + カントリ識別処理モジュール + + Copyright (C) JE3HHT 1993-2000. +************************************************************************/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ComLib.h" +#include "Country.h" +#include "string.h" +#include "stdlib.h" + +CCountry Cty; +/*#$% +======================================================== + 文字列から指定の文字をクリップする +-------------------------------------------------------- + s : 文字列のポインタ +-------------------------------------------------------- +-------------------------------------------------------- +======================================================== +*/ +static char *__fastcall _delchr(char *s, char c) +{ + char *p; + + for( p = s; *p; p++ ){ + if( *p == c ){ + strcpy(p, p+1); + p--; + } + } + return(s); +} + +/*#$% +====================================================== + 異なる文字列のポインタを返す +------------------------------------------------------ + n : 範囲数の格納位置のポインタ + t : プリフィックスのポインタ + p : プリフィックスのポインタ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static LPSTR __fastcall lcmpp(int *n, LPSTR s, LPSTR p) +{ + LPSTR t; + + for( t = s; *p && *t; p++, t++ ){ + if( *p != *t ){ + *n = (*p - *t) + 1; + if( *n > 26 ) *n = 26; + return(t); + } + } + *n = 0; + return(s); +} + +/*#$% +====================================================== + 文字列の比較を行う +------------------------------------------------------ + t : 対象文字列 + s : 基準文字列 +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +static int __fastcall strcmpv(LPCSTR t, LPCSTR s) +{ + for( ; *s; s++, t++ ){ + if( *t != *s ) return(1); + } + return(0); +} + +static int svf; /* 完全一致フラグ */ +/*#$% +================================================================ + プリフィックス検索用文字列比較 +---------------------------------------------------------------- +---------------------------------------------------------------- +---------------------------------------------------------------- +================================================================ +*/ +static int __fastcall _strcmp(LPCSTR t, LPCSTR v) +{ +/* printf( "<%s>-<%s>\n", v, t ); */ + for( ; *v; v++, t++ ){ + if( *v == '*' ){ + for( v++; *t && strcmpv(t, v); t++ ); + if( !*t ) return(1); + } + else if( *v == '\\' ){ + if( *t ) return(1); + } + else if( (*v!='?') && (*v != *t) ){ + return(1); + } + } + if( svf && *t ) return(1); + return(0); +} + +/*#$% +====================================================== + コンストラクター +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +__fastcall CCountry::CCountry() +{ + Init(); +} + +__fastcall CCountry::~CCountry(void) +{ + Free(); +} + +/*#$% +====================================================== + DXCC定義領域を開放する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CCountry::Init(void) +{ + cmax = 0; + memset(ctl, 0, sizeof(ctl)); +} + +/*#$% +====================================================== + DXCC定義領域を開放する +------------------------------------------------------ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CCountry::Free(void) +{ + int i; + CTL *cp; + + for( cp = ctl, i = 0; i < cmax; i++, cp++ ){ + if( cp->Name != NULL ) delete cp->Name; + if( cp->Code != NULL ) delete cp->Code; + if( cp->QTH != NULL ) delete cp->QTH; + if( cp->Cont != NULL ) delete cp->Cont; + if( cp->TD != NULL ) delete cp->TD; + } + Init(); +} + + +/*#$% +====================================================== + プリフィックスからカントリコードを得る +------------------------------------------------------ + p : プリフィックスのポインタ +------------------------------------------------------ + カントリコード +------------------------------------------------------ +====================================================== +*/ +int __fastcall CCountry::GetNo(LPCSTR s) +{ + LPSTR p, pb, t, pp; + int i; + int j; + + if( !*s ) return(0); + for( i = 0; i < cmax; i++ ){ + strcpy(wbf, ctl[i].Code); + for( p = wbf; *p; ){ + p = StrDlm(pb, p, ','); + if( (t = strchr(pb, '-')) != NULL ){ + *t = 0; + t++; + if( (*pb == *s) || (*pb != *t) ){ + for( pp = lcmpp(&j, pb, t); j; (*pp)++, j-- ){ + if( !_strcmp(s, pb) ) return(i+1); + } + } + } + else { + if( !_strcmp(s, pb) ) return(i+1); + } + } + } + return(0); +} + +/*#$% +====================================================== + コールサインからポインタを得る +------------------------------------------------------ + p : コールサインのポインタ +------------------------------------------------------ + ポインタ +------------------------------------------------------ +====================================================== +*/ +int __fastcall CCountry::GetNoP(LPCSTR p) +{ + int n; + + svf = 1; + if( (n = GetNo(p))!=0 ) return(n); + svf = 0; + if( (n = GetNo(p))!=0 ) return(n); + return(0); +} + +/*#$% +====================================================== + コールサインからカントリ名を得る +------------------------------------------------------ + p : コールサインのポインタ +------------------------------------------------------ + カントリ名のポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall CCountry::GetCountry(LPCSTR p) +{ + if( !cmax ) return ""; + int n; + + if( !(*p) ) return("?"); + if( ((n = GetNoP(p))!=0) && (ctl[n-1].Name != NULL) ){ + strcpy(wbf, ctl[n-1].Name); + return(wbf); + } + else { + return("?"); + } +} + +/*#$% +====================================================== + コールサインから大陸名を得る +------------------------------------------------------ + p : コールサインのポインタ +------------------------------------------------------ + カントリ名のポインタ +------------------------------------------------------ +====================================================== +*/ +LPCSTR __fastcall CCountry::GetCont(LPCSTR p) +{ + if( !cmax ) return ""; + int n; + + if( !(*p) ) return("?"); + if( ((n = GetNoP(p))!=0) && (ctl[n-1].Cont != NULL) ){ + strcpy(wbf, ctl[n-1].Cont); + return(wbf); + } + else { + return("?"); + } +} + +/*#$% +====================================================== + DXCC定義ファイルを読み込む +------------------------------------------------------ + fm : ファイル名のポインタ +------------------------------------------------------ +------------------------------------------------------ +====================================================== +*/ +void __fastcall CCountry::Load(LPCSTR fm) +{ + FILE *fp; + LPCSTR p; + char hbf[512]; + + Free(); + if( (fp = fopen(fm, "rt"))!=NULL ){ + while( !feof(fp) ){ + if( fgets(hbf, 512, fp)!=NULL ){ + if( hbf[0] == '$' ) break; + ClipLF(hbf); + _delchr(hbf, TAB); + if( hbf[0] != '!' ){ + p = StrDlmCpy(wbf, hbf, ';', 512); + clipsp(wbf); + ctl[cmax].Name = StrDupe(wbf); + if( p != NULL ){ + p = StrDlmCpy(wbf, p, ';', 512); + clipsp(wbf); + ctl[cmax].Code = StrDupe(wbf); + } + if( p != NULL ){ + p = StrDlmCpy(wbf, p, ';', 512); + clipsp(wbf); + ctl[cmax].QTH = StrDupe(wbf); + } + if( p != NULL ){ + p = StrDlmCpy(wbf, p, ';', 512); + clipsp(wbf); + ctl[cmax].Cont = StrDupe(wbf); + } + if( p != NULL ){ + StrDlmCpy(wbf, p, ';', 512); + clipsp(wbf); + ctl[cmax].TD = StrDupe(wbf); + } + cmax++; + if( cmax >= CTMAX ) break; + } + } + } + fclose(fp); + } + else { + WarningMB(sys.m_MsgEng ? "'ARRL.DX' was not found.\r\n\r\nYou cannot use a DXCC function.\r\nThis is not a problem if you do not need it":"'ARRL.DX'が見つかりません.\r\n\r\nDXエンティティの自動判定機能は使用できません."); + } +} + diff --git a/country.h b/country.h new file mode 100644 index 0000000..53f43a2 --- /dev/null +++ b/country.h @@ -0,0 +1,60 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef CountryH +#define CountryH + +extern LPSTR __fastcall StrDupe(LPCSTR s); + +#define CTMAX 512 +typedef struct { + LPSTR Name; + LPSTR Code; + LPSTR QTH; + LPSTR Cont; + LPSTR TD; +}CTL; + +class CCountry +{ +private: + int cmax; + CTL ctl[CTMAX]; + + char wbf[512]; +public: + __fastcall CCountry(); + __fastcall ~CCountry(void); + + inline CTL *__fastcall GetCTL(int n){ return &ctl[n];}; + void __fastcall Init(void); + void __fastcall Free(void); + int __fastcall GetNo(LPCSTR s); + int __fastcall GetNoP(LPCSTR p); + LPCSTR __fastcall GetCountry(LPCSTR p); + LPCSTR __fastcall GetCont(LPCSTR p); + void __fastcall Load(LPCSTR fm); + inline int __fastcall IsData(void){ + return cmax; + }; +}; + +extern CCountry Cty; +#endif + diff --git a/cradio.cpp b/cradio.cpp new file mode 100644 index 0000000..a24c8f2 --- /dev/null +++ b/cradio.cpp @@ -0,0 +1,1451 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "Cradio.h" +#include "ComLib.h" + +#define WAITSTAT 0 + +const LPCSTR g_tRadioMode[]={ + "LSB", "USB", "CW", "AM", "FM", "RTTY", "PACKET", "UNKNOWN" +}; + +CRADIOPARA RADIO; +void __fastcall InitRADIOPara(void) +{ + RADIO.change = 1; + strcpy(RADIO.StrPort, "NONE"); // ポートの名前 + RADIO.BaudRate = 4800; // ボーレート + RADIO.BitLen = 1; // 0-7Bit, 1-8Bit + RADIO.Stop = 1; // 0-1Bit, 1-2Bit + RADIO.Parity = 0; // 0-PN, 1-PE, 2-PO + RADIO.flwXON = 0; // Xon/Xoff ON + RADIO.flwCTS = 0; // CTS-RTS ON + RADIO.usePTT = 0; + RADIO.Cmdxx = 0; + RADIO.CmdInit = ""; + RADIO.CmdRx = "\\$000000000F"; + RADIO.CmdTx = "\\$000000010F\\w10"; + RADIO.ByteWait = 0; + RADIO.cmdGNR = ""; + RADIO.openGNR = 0; + + RADIO.PollType = 0; + RADIO.PollInterval = 8; + RADIO.PollOffset = 3; + RADIO.PollScan = 0; +} + +void __fastcall LoadRADIOSetup(TMemIniFile *pIniFile) +{ + AnsiString as = RADIO.StrPort; + as = pIniFile->ReadString("RADIO", "PortName", as); + StrCopy(RADIO.StrPort, as.c_str(), 31); + RADIO.BaudRate = pIniFile->ReadInteger("RADIO", "BaudRate", RADIO.BaudRate); + RADIO.BitLen = pIniFile->ReadInteger("RADIO", "BitLen", RADIO.BitLen); + RADIO.Stop = pIniFile->ReadInteger("RADIO", "Stop", RADIO.Stop); + RADIO.Parity = pIniFile->ReadInteger("RADIO", "Parity", RADIO.Parity); + RADIO.flwXON = pIniFile->ReadInteger("RADIO", "flwXON", RADIO.flwXON); + RADIO.flwCTS = pIniFile->ReadInteger("RADIO", "flwCTS", RADIO.flwCTS); + RADIO.usePTT = pIniFile->ReadInteger("RADIO", "usePTT", RADIO.usePTT); + + RADIO.ByteWait = pIniFile->ReadInteger("RADIO", "ByteWait", RADIO.ByteWait); + + RADIO.Cmdxx = pIniFile->ReadInteger("RADIO", "Cmdxx", RADIO.Cmdxx); + RADIO.CmdInit = pIniFile->ReadString("RADIO", "CmdInit", RADIO.CmdInit); + RADIO.CmdRx = pIniFile->ReadString("RADIO", "CmdRx", RADIO.CmdRx); + RADIO.CmdTx = pIniFile->ReadString("RADIO", "CmdTx", RADIO.CmdTx); + + RADIO.cmdGNR = pIniFile->ReadString("RADIO", "FileGNR", RADIO.cmdGNR); + RADIO.openGNR = pIniFile->ReadInteger("RADIO", "OpenGNR", RADIO.openGNR); + + RADIO.PollType = pIniFile->ReadInteger("RADIO", "PollType", RADIO.PollType); + RADIO.PollInterval = pIniFile->ReadInteger("RADIO", "PollInterval", RADIO.PollInterval); + RADIO.PollOffset = pIniFile->ReadInteger("RADIO", "PollOffset", RADIO.PollOffset); +} +void __fastcall SaveRADIOSetup(TMemIniFile *pIniFile) +{ + pIniFile->WriteString("RADIO", "PortName", RADIO.StrPort); + pIniFile->WriteInteger("RADIO", "BaudRate", RADIO.BaudRate); + pIniFile->WriteInteger("RADIO", "BitLen", RADIO.BitLen); + pIniFile->WriteInteger("RADIO", "Stop", RADIO.Stop); + pIniFile->WriteInteger("RADIO", "Parity", RADIO.Parity); + pIniFile->WriteInteger("RADIO", "flwXON", RADIO.flwXON); + pIniFile->WriteInteger("RADIO", "flwCTS", RADIO.flwCTS); + pIniFile->WriteInteger("RADIO", "usePTT", RADIO.usePTT); + + pIniFile->WriteInteger("RADIO", "ByteWait", RADIO.ByteWait); + + pIniFile->WriteInteger("RADIO", "Cmdxx", RADIO.Cmdxx); + pIniFile->WriteString("RADIO", "CmdInit", RADIO.CmdInit); + pIniFile->WriteString("RADIO", "CmdRx", RADIO.CmdRx); + pIniFile->WriteString("RADIO", "CmdTx", RADIO.CmdTx); + + pIniFile->WriteString("RADIO", "FileGNR", RADIO.cmdGNR); + pIniFile->WriteInteger("RADIO", "OpenGNR", RADIO.openGNR); + + pIniFile->WriteInteger("RADIO", "PollType", RADIO.PollType); + pIniFile->WriteInteger("RADIO", "PollInterval", RADIO.PollInterval); + pIniFile->WriteInteger("RADIO", "PollOffset", RADIO.PollOffset); +} +//--------------------------------------------------------------------------- +// 注意: VCL オブジェクトのメソッドとプロパティを使用するには, Synchronize +// を使ったメソッド呼び出しでなければなりません。次に例を示します。 +// +// Synchronize(UpdateCaption); +// +// ここで, UpdateCaption は次のように記述できます。 +// +// void __fastcall CCradio::UpdateCaption() +// { +// Form1->Caption = "スレッドから書き換えました"; +// } +//--------------------------------------------------------------------------- +__fastcall CCradio::CCradio(bool CreateSuspended) + : TThread(CreateSuspended) +{ + m_RigHz = m_FreqHz = 0; + if( RADIO.PollOffset < 3 ){ + m_LSB = RADIO.PollOffset; + } + else { + m_LSB = 1; + } + m_RigMode = rmUNKNOWN; + m_CreateON = FALSE; // クリエイトフラグ + m_fHnd = NULL; // ファイルハンドル + m_wHnd = NULL; // 親のウインドウハンドル + m_uMsg = WM_USER; + m_ID = 0; // メッセージのID番号 + m_Command = 0; // スレッドへのコマンド + m_TxAbort = 0; // 送信中止フラグ + m_txwp = m_txrp = m_txcnt = 0; + m_PSKGNRId = 0; + m_OpenGNR = 0; + + m_PollCnt = 0; + m_PollCntHalf = -1; + m_PollInhibit = 0; + m_rxcnt = 0; + m_FreqEvent = 0; + m_Freq[0] = 0; + + m_ScanAddr = 0; + m_pRadio = NULL; + m_CarrierFreq = 0; +} + +//--------------------------------------------------------------------------- +void __fastcall CCradio::Execute() +{ + //---- スレッドのコードをここに記述 ---- +// Priority = tpLower; + while(1){ + if( Terminated == TRUE ){ + return; + } + if( m_Command == CRADIO_CLOSE ){ + m_Command = 0; + return; + } + if( m_CreateON == TRUE ){ + if( m_txcnt ){ + if( m_pRadio != NULL ){ + if( !(m_pRadio->GetStatus() & mmrpstatusTXBUSY) ){ + m_pRadio->PutChar(m_txbuf[m_txrp]); + m_txrp++; + if( m_txrp >= RADIO_TXBUFSIZE ){ + m_txrp = 0; + } + m_txcnt--; + } + } + else if( !TxBusy() ){ + DWORD size=0; + ::WriteFile( m_fHnd, &m_txbuf[m_txrp], 1, &size, NULL ); + if( size ){ + m_txrp++; + if( m_txrp >= RADIO_TXBUFSIZE ){ + m_txrp = 0; + } + m_txcnt--; + } + if( RADIO.ByteWait ) ::Sleep(RADIO.ByteWait); + } + ::Sleep(1); + } + else if( m_pRadio != NULL ){ + if( m_pRadio->GetStatus() & mmrpstatusFREQ ){ + long fq = m_pRadio->GetFreq(); + if( fq ) UpdateFreq(double(fq)/1e4); + } + while(m_pRadio->GetStatus() & mmrpstatusRX){ + CatchPoll(m_pRadio->GetChar()); + } + ::Sleep(10); + } + else { + BYTE dmy[256]; + while(1){ + int len = RecvLen(); + if( !len ) break; + if( len >= sizeof(dmy) ) len = sizeof(dmy); + Read(dmy, len); + if( RADIO.PollType ){ + BYTE *p = dmy; + for( ; len; p++, len-- ){ + CatchPoll(*p); + } + } + } + ::Sleep(10); + } + } + else { + ::Sleep(10); + } + } +} +//--------------------------------------------------------------------------- +/*#$% +============================================================== + 通信回線をオープンしスレッドをアクティブにする +-------------------------------------------------------------- +PortName : 回線の名前 +pCP : COMMPARAのポインタ(ヌルの時はデフォルトで初期化) +pWnd : メッセージ送信先のウインドウクラスのポインタ(ヌルの時はメインフレームウインドウ) +nID : データ受信時のメッセージID +RBufSize : 受信バッファのサイズ(default=2048) +TBufSize : 送信バッファのサイズ(default=2048) +-------------------------------------------------------------- +TRUE/FALSE +-------------------------------------------------------------- +============================================================== +*/ +BOOL __fastcall CCradio::Open(CRADIOPARA *cp, HWND hwnd, UINT uMsg, UINT nID) +{ + if( m_CreateON == TRUE ) Close(); + m_RigHz = m_FreqHz = 0; + m_TxAbort = FALSE; + m_PSKGNRId = 0; + m_OpenGNR = 0; + if( !strcmpi(cp->StrPort, "PSKGNR") || !strcmpi(cp->StrPort, "WD5GNR") || !strcmpi(cp->StrPort, "LOGGER")){ + m_PSKGNRId = ::RegisterWindowMessage("PSKGNRFUNC"); + m_CreateON = TRUE; + if( RADIO.openGNR && (!RADIO.cmdGNR.IsEmpty()) && (strcmpi(cp->StrPort, "LOGGER")) ){ + if( FindWindow("ThunderRT6Main", NULL) == NULL ){ + ::WinExec(RADIO.cmdGNR.c_str(), SW_HIDE); + m_OpenGNR = 1; + } + } + return m_CreateON; + } + m_fHnd = ::CreateFile(cp->StrPort, GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if( m_fHnd == INVALID_HANDLE_VALUE ){ + AnsiString as = "\\\\.\\"; + as += cp->StrPort; + m_fHnd = ::CreateFile(as.c_str(), GENERIC_READ | GENERIC_WRITE, + 0, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + } + m_wHnd = hwnd; + m_uMsg = uMsg; + m_ID = nID; + if( m_fHnd == INVALID_HANDLE_VALUE ) goto _mmr; + // setup device buffers + if( ::SetupComm( m_fHnd, DWORD(RADIO_COMBUFSIZE), DWORD(RADIO_COMBUFSIZE) ) == FALSE ){ + ::CloseHandle(m_fHnd); +_mmr:; + m_pRadio = new CMMRadio(hwnd, uMsg); + if( m_pRadio->Open(cp->StrPort) ){ + m_CreateON = TRUE; + Priority = tpLower; + Resume(); // スレッドの実行 + return TRUE; + } + else { + delete m_pRadio; + m_pRadio = NULL; + return FALSE; + } + } + + // purge any information in the buffer + ::PurgeComm( m_fHnd, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR ); + + // set up for overlapped I/O + COMMTIMEOUTS TimeOut; + + TimeOut.ReadIntervalTimeout = 0xffffffff; + TimeOut.ReadTotalTimeoutMultiplier = 0; + TimeOut.ReadTotalTimeoutConstant = 0; + TimeOut.WriteTotalTimeoutMultiplier = 0; + TimeOut.WriteTotalTimeoutConstant = 20000; +// TimeOut.WriteTotalTimeoutConstant = 1; + if( !::SetCommTimeouts( m_fHnd, &TimeOut ) ){ + ::CloseHandle( m_fHnd ); + return FALSE; + } + ::GetCommState( m_fHnd, &m_dcb ); + m_dcb.BaudRate = cp->BaudRate; + m_dcb.fBinary = TRUE; + m_dcb.ByteSize = USHORT(cp->BitLen ? 8 : 7); + const UCHAR _tp[]={NOPARITY, EVENPARITY, ODDPARITY}; + m_dcb.Parity = _tp[cp->Parity]; + const UCHAR _ts[]={ONESTOPBIT,TWOSTOPBITS}; + m_dcb.StopBits = _ts[cp->Stop]; + if( cp->usePTT ){ + m_dcb.fRtsControl = RTS_CONTROL_DISABLE; // 送信禁止 + m_dcb.fDtrControl = DTR_CONTROL_DISABLE; // 送信禁止 + } + else { + m_dcb.fRtsControl = RTS_CONTROL_ENABLE; + } + m_dcb.fOutxCtsFlow = (cp->flwCTS && !cp->usePTT) ? TRUE : FALSE; + m_dcb.fInX = m_dcb.fOutX = cp->flwXON ? TRUE : FALSE; + m_dcb.XonChar = 0x11; + m_dcb.XoffChar = 0x13; + m_dcb.fParity = FALSE; + m_dcb.EvtChar = 0x0d; // dummy setting +// m_dcb.fTXContinueOnXoff = TRUE; + m_dcb.XonLim = USHORT(RADIO_COMBUFSIZE/4); // 1/4 of RBufSize + m_dcb.XoffLim = USHORT(RADIO_COMBUFSIZE*3/4); // 3/4 of RBufSize + m_dcb.DCBlength = sizeof( DCB ); + if( !::SetCommState( m_fHnd, &m_dcb ) ){ + ::CloseHandle( m_fHnd ); + return FALSE; + } + // get any early notifications + if( !::SetCommMask( m_fHnd, EV_RXFLAG ) ){ + ::CloseHandle(m_fHnd); + return FALSE; + } + m_CreateON = TRUE; + Priority = tpLower; + Resume(); // スレッドの実行 + return TRUE; +} +/*#$% +============================================================== + 通信回線をクローズする +-------------------------------------------------------------- +-------------------------------------------------------------- +-------------------------------------------------------------- + スレッドが終了するまで待つ +============================================================== +*/ +void __fastcall CCradio::Close(void) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ){ + if( (m_OpenGNR || RADIO.change) && RADIO.openGNR ) ::SendMessage(HWND_BROADCAST, m_PSKGNRId, 1 , 0); + m_PSKGNRId = 0; + } + else { + if( m_ID ){ + m_Command = CRADIO_CLOSE; // スレッド終了コマンド + Priority = tpNormal; //スレッドは通常の優先度である + WaitFor(); + } + if( m_pRadio != NULL ){ + delete m_pRadio; + m_pRadio = NULL; + } + else { + ::CloseHandle(m_fHnd); + } + } + } + m_CreateON = FALSE; + m_TxAbort = TRUE; +} +void __fastcall CCradio::ReqClose(void) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ){ + return; + } + else { + if( m_ID ){ + m_Command = CRADIO_CLOSE; // スレッド終了コマンド + Priority = tpNormal; //スレッドは通常の優先度である + } + } + } +} +void __fastcall CCradio::WaitClose(void) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ){ + if( (m_OpenGNR || RADIO.change) && RADIO.openGNR ) ::SendMessage(HWND_BROADCAST, m_PSKGNRId, 1 , 0); + m_PSKGNRId = 0; + } + else { + if( m_ID && m_Command ){ + WaitFor(); + } + if( m_pRadio != NULL ){ + delete m_pRadio; + m_pRadio = NULL; + } + else { + ::CloseHandle(m_fHnd); + } + } + m_CreateON = FALSE; + } + m_TxAbort = TRUE; +} +/*#$% +============================================================== + 受信バッファ内の格納データ長を得る +-------------------------------------------------------------- +-------------------------------------------------------------- + データの長さ +-------------------------------------------------------------- +============================================================== +*/ +DWORD __fastcall CCradio::RecvLen(void) +{ + COMSTAT ComStat; + DWORD dwErrorFlags; + + ::ClearCommError( m_fHnd, &dwErrorFlags, &ComStat ); + return ComStat.cbInQue; +} + +/*#$% +============================================================== + 送信ビジーかどうか調べる +-------------------------------------------------------------- +-------------------------------------------------------------- + : 送信ビジー状態 +-------------------------------------------------------------- +============================================================== +*/ +int __fastcall CCradio::TxBusy(void) +{ +#if 0 + COMSTAT ComStat; + DWORD dwErrorFlags; + + if( m_TxAbort ) return FALSE; + ClearCommError( m_fHnd, &dwErrorFlags, &ComStat ); + int f = ComStat.fRlsdHold; + if( f ) return TRUE; + if( m_dcb.fOutxCtsFlow ){ + f |= ComStat.fCtsHold; + } + if( m_dcb.fOutX ){ + f |= ComStat.fXoffHold; + } + return f ? TRUE : FALSE; +#else + COMSTAT ComStat; + DWORD dwErrorFlags; + + ::ClearCommError( m_fHnd, &dwErrorFlags, &ComStat ); + return ComStat.cbOutQue; +#endif +} + +/*#$% +============================================================== + 通信回線からデータを取り出す +-------------------------------------------------------------- +p : バッファのポインタ +len : バッファのサイズ +-------------------------------------------------------------- +実際に受信したサイズ +-------------------------------------------------------------- +============================================================== +*/ +DWORD __fastcall CCradio::Read(BYTE *p, DWORD len) +{ + DWORD size=0; + + if( m_CreateON == TRUE ){ + ::ReadFile( m_fHnd, p, len, &size, NULL ); + } + return size; +} + +/*#$% +============================================================== + 通信回線にデータを送信する +-------------------------------------------------------------- +-------------------------------------------------------------- +-------------------------------------------------------------- +============================================================== +*/ +void __fastcall CCradio::PutChar(char c) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ) return; + if( m_txcnt < RADIO_TXBUFSIZE ){ + m_txbuf[m_txwp] = c; + m_txwp++; + if( m_txwp >= RADIO_TXBUFSIZE ) m_txwp = 0; + m_txcnt++; + } + } +} + +/*#$% +============================================================== + 通信回線にデータを送信する +-------------------------------------------------------------- +p : バッファのポインタ +len : 送信するサイズ +-------------------------------------------------------------- +実際に送信したサイズ +-------------------------------------------------------------- +============================================================== +*/ +void __fastcall CCradio::Write(void *s, DWORD len) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ) return; + char *p; + for( p = (char *)s; len; len--, p++ ){ + PutChar(*p); + } + } +} + +/*#$% +============================================================== + 通信回線にデータを送信する +-------------------------------------------------------------- +p : バッファのポインタ +len : 送信するサイズ +-------------------------------------------------------------- +実際に送信したサイズ +-------------------------------------------------------------- +============================================================== +*/ +void CCradio::OutStr(LPCSTR fmt, ...) +{ + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + Write(bf, strlen(bf)); +} + +void CCradio::OutLine(LPCSTR fmt, ...) +{ + va_list pp; + char bf[1024]; + + va_start(pp, fmt); + vsprintf( bf, fmt, pp ); + va_end(pp); + Write(bf, strlen(bf)); + char r[] = "\r"; //JA7UDE 0428 + Write(r, 1); //JA7UDE 0428 +} + +void __fastcall CCradio::SendCommand(LPCSTR p) +{ + int c; + int f; + + for(f = 0; *p; p++){ + if( *p == '\\' ){ + f = 0; + p++; + switch(*p){ + case '$': + f = 1; + continue; + case 'x': + case 'X': + p++; + if( *p == 'x' ){ + c = RADIO.Cmdxx; + } + else { + c = htoin(p, 2); + } + p++; + break; + case 'r': + c = CR; + break; + case 'n': + c = LF; + break; + case 'w': + p++; + c = atoin(p, 2); + if( (c < 0) || (c >= 100) ) c = 100; + if( c ) ::Sleep(c * 10); + p++; + continue; + case '\\': + c = '\\'; + break; + case 'c': // comment + return; + } + } + else if( f ){ + p = SkipSpace(p); + if( *p == 'x' ){ + c = RADIO.Cmdxx; + } + else { + c = htoin(p, 2); + } + p++; + } + else { + c = *p; + } + PutChar(BYTE(c)); + } +} + +void __fastcall CCradio::SetPTT(int sw) +{ + if( m_PSKGNRId ){ + ::SendMessage(HWND_BROADCAST, m_PSKGNRId, 0 , sw ? 1 : 0); + if( sw ) ::Sleep(50); + } + else { + if( sw ){ + if( m_pRadio != NULL ){ + m_pRadio->SetPTT(sw); + } + else if( RADIO.usePTT ){ + ::EscapeCommFunction(m_fHnd, SETRTS); + ::EscapeCommFunction(m_fHnd, SETDTR); + } + SendCommand(RADIO.CmdTx.c_str()); + } + else { + if( m_pRadio != NULL ){ + m_pRadio->SetPTT(sw); + } + else if( RADIO.usePTT ){ + ::EscapeCommFunction(m_fHnd, CLRRTS); + ::EscapeCommFunction(m_fHnd, CLRDTR); + } + SendCommand(RADIO.CmdRx.c_str()); + } + } +} + +//-------------------------------------------------------- +// 周波数が変化しているかどうか調べる +int __fastcall CCradio::IsFreqChange(LPCSTR pFreq) +{ + if( RADIO.PollType ){ + if( m_FreqEvent ) return 1; + if( m_Freq[0] ){ + if( strcmp(m_Freq, pFreq) ) return 1; + } + } + return 0; +} + +//-------------------------------------------------------- +void __fastcall CCradio::WaitICOM(int interval) +{ + if( interval ){ + switch(RADIO.PollType){ + case RADIO_POLLICOM: + case RADIO_POLLOMNIVI: + m_PollInhibit = 500 / interval; + ::Sleep(100); + break; + } + } +} +//-------------------------------------------------------- +// タイマー処理 +void __fastcall CCradio::Timer(int tx, int interval) +{ + if( m_CreateON == TRUE ){ + if( m_PSKGNRId ) return; + if( m_pRadio != NULL ){ + if( m_pRadio->GetStatus() & mmrpstatusDEFCMD ){ + LPCSTR p; + switch(m_pRadio->GetDefCommand()){ + case 1: + p = RADIO.CmdTx.c_str(); + break; + case 2: + p = RADIO.CmdRx.c_str(); + break; + default: + p = RADIO.CmdInit.c_str(); + break; + } + SendCommand(p); + m_PollCnt = (2 + RADIO.PollInterval); + if( interval ){ + m_PollCnt = m_PollCnt * 100 / interval; + if( !m_PollCnt ) m_PollCnt++; + } + } + } + if( (!tx) && RADIO.PollType && (!m_PollInhibit) ){ + if( (m_PollCnt == m_PollCntHalf) && (RADIO.PollOffset == 3) ){ + switch(RADIO.PollType){ + case RADIO_POLLICOM: + case RADIO_POLLOMNIVI: + if( !m_ScanAddr ){ + m_rxcnt = 0; + SendCommand("\\$FEFExxE004FD"); + } + break; + case RADIO_POLLICOMN: + case RADIO_POLLOMNIVIN: + if( (m_RigMode == rmUNKNOWN) && !m_ScanAddr ){ + m_rxcnt = 0; + SendCommand("\\$FEFExxE004FD"); + } + break; + } + } + if( !m_PollCnt ){ + if( m_pRadio != NULL ) m_pRadio->Polling(); + if( m_ScanAddr ){ // アドレススキャン + m_PollCnt = 4; + if( m_ScanAddr <= 3 ){ + m_ScanAddr++; + } + else { + RADIO.Cmdxx++; + if( RADIO.Cmdxx >= 0x80 ){ + RADIO.Cmdxx = 0; + } + } + } + else { + m_PollCnt = (2 + RADIO.PollInterval); + } + if( interval ){ + m_PollCnt = m_PollCnt * 100 / interval; + m_PollCntHalf = m_PollCnt / 2; + if( !m_PollCnt ) m_PollCnt++; + } + switch(RADIO.PollType){ + case RADIO_POLLYAESUHF: + case RADIO_POLLFT1000D: + case RADIO_POLLFT920: + m_rxcnt = 0; + SendCommand("\\$0000000210"); + break; + case RADIO_POLLYAESUVU: + m_rxcnt = 0; + SendCommand("\\$0000000003"); + break; + //1.66B AA6YQ + case RADIO_POLLFT9000: + case RADIO_POLLFT2000: + case RADIO_POLLFT950: + case RADIO_POLLFT450: + m_rxcnt = 0; + SendCommand("IF;"); + break; + + case RADIO_POLLICOM: + case RADIO_POLLOMNIVI: + m_rxcnt = 0; + SendCommand("\\$FEFExxE003FD"); + break; + case RADIO_POLLICOMN: + case RADIO_POLLOMNIVIN: + if( !m_Freq[0] || m_ScanAddr ){ + m_rxcnt = 0; + SendCommand("\\$FEFExxE003FD"); + } + break; + case RADIO_POLLKENWOOD: + m_rxcnt = 0; + SendCommand("IF;"); + break; + case RADIO_POLLKENWOODN: + if( !m_Freq[0] ){ + m_rxcnt = 0; + SendCommand("AI1;"); + } + break; + case RADIO_POLLJST245: + m_rxcnt = 0; + SendCommand("I\r\n"); + break; + case RADIO_POLLJST245N: + if( !m_Freq[0] ){ + m_rxcnt = 0; + SendCommand("I1\r\nL\r\n"); + } + break; + default: + break; + } + } + m_PollCnt--; + } + if( m_PollInhibit ) m_PollInhibit--; + } +} + +//-------------------------------------------------------- +// 周波数ポーリングデータの受信 +void __fastcall CCradio::CatchPoll(BYTE c) +{ + switch(RADIO.PollType){ + case RADIO_POLLYAESUHF: + case RADIO_POLLFT1000D: + case RADIO_POLLFT920: + if( m_rxcnt < 8 ){ + m_rxbuf[m_rxcnt] = c; + m_rxcnt++; + if( m_rxcnt == 8 ){ + FreqYaesuHF(); + } + } + break; + case RADIO_POLLYAESUVU: + if( m_rxcnt < 5 ){ + m_rxbuf[m_rxcnt] = c; + m_rxcnt++; + if( m_rxcnt == 5 ){ + FreqYaesuVU(); + } + } + break; + //1.66B AA6YQ + case RADIO_POLLFT9000: + case RADIO_POLLFT2000: + case RADIO_POLLFT950: + case RADIO_POLLFT450: + if( m_rxcnt < sizeof(m_rxbuf) ){ + if( (c != 0x0d) && (c != 0x0f) ){ + if( (c != ' ') || m_rxcnt ){ + m_rxbuf[m_rxcnt] = c; // Data + m_rxcnt++; + if( c == ';' ){ + if( (m_rxbuf[0] == 'I') && (m_rxbuf[1]=='F') ){ + if( m_rxcnt >= 13 ) FreqYaesu9K2K(); + } + m_rxcnt = 0; + } + } + } + } + else { + m_rxcnt = 0; + } + break; + case RADIO_POLLICOM: + case RADIO_POLLICOMN: + case RADIO_POLLOMNIVI: + case RADIO_POLLOMNIVIN: + switch(m_rxcnt){ + case 0: + if( c == 0xfe ){ + m_rxbuf[m_rxcnt] = c; // プリアンブル + m_rxcnt++; + } + break; + case 1: + if( c != 0xfe ){ + if( (c >= 0x80) || (!m_ScanAddr&&(c == 0x00)&&((RADIO.PollType == RADIO_POLLICOMN)||(RADIO.PollType == RADIO_POLLOMNIVIN))) ){ + m_rxbuf[m_rxcnt] = c; // PC-Addr + m_rxcnt++; + } + else { + m_rxcnt = 0; + } + } +// if( (c != 0xfe) && (c >= 0x80) ){ +// m_rxbuf[m_rxcnt] = c; // PC-Addr +// m_rxcnt++; +// } + break; + case 2: + if( (c == RADIO.Cmdxx) || (!RADIO.Cmdxx) || + (m_ScanAddr && c) ){ + m_rxbuf[m_rxcnt] = c; // Radio-Addr + m_rxcnt++; + } + else { + m_rxcnt = 0; + } + break; + case 3: +// if( (c == 0x03) || ((c == 0x00)&&((RADIO.PollType == RADIO_POLLICOMN)||(RADIO.PollType == RADIO_POLLOMNIVIN))) ){ + if( (c == 0x03) || (c == 0x04) ){ + m_rxbuf[m_rxcnt] = c; // Respons-command + m_rxcnt++; + } + else if( ((c == 0x00)||(c == 0x01)) && ((RADIO.PollType == RADIO_POLLICOMN)||(RADIO.PollType == RADIO_POLLOMNIVIN)) ){ + m_rxbuf[m_rxcnt] = c; // Respons-command + m_rxcnt++; + } + else { + m_rxcnt = 0; + } + break; + default: + if( m_rxcnt < sizeof(m_rxbuf) ){ + m_rxbuf[m_rxcnt] = c; // Data + m_rxcnt++; + if( c == 0xfd ){ + if( m_rxcnt >= 5 ){ + FreqICOM(); +// if( (m_ScanAddr && m_rxbuf[2]) || (!RADIO.Cmdxx) ){ + if( (m_ScanAddr && m_rxbuf[2]) ){ + RADIO.Cmdxx = m_rxbuf[2]; + RADIO.PollScan = 0; + m_ScanAddr = 0; + } + } + m_rxcnt = 0; + } + } + else { + m_rxcnt = 0; + } + break; + } + break; + case RADIO_POLLKENWOOD: + case RADIO_POLLKENWOODN: + if( m_rxcnt < sizeof(m_rxbuf) ){ + if( (c != 0x0d) && (c != 0x0a) ){ + if( (c != ' ') || m_rxcnt ){ + m_rxbuf[m_rxcnt] = c; // Data + m_rxcnt++; + if( c == ';' ){ + if( (m_rxbuf[0] == 'I') && (m_rxbuf[1]=='F') ){ + if( m_rxcnt >= 13 ) FreqKenwood(); + } + m_rxcnt = 0; + } + } + } + } + else { + m_rxcnt = 0; + } + break; + case RADIO_POLLJST245: + case RADIO_POLLJST245N: + if( m_rxcnt < sizeof(m_rxbuf) ){ + if( (c == 'I') || m_rxcnt ){ + m_rxbuf[m_rxcnt] = c; // Data + m_rxcnt++; + if( (c == 0x0d) || (c == 0x0a) ){ + if( m_rxcnt >= 12 ) FreqJST245(); + m_rxcnt = 0; + } + } + } + else { + m_rxcnt = 0; + } + break; + default: + break; + } +} +//---------------------------------------------------------- +void __fastcall CCradio::SetCarrierFreq(int fq) +{ + int offset = fq - m_CarrierFreq; + m_CarrierFreq = fq; + if( m_FreqHz ){ + if( RADIO.PollOffset < 3 ) m_LSB = RADIO.PollOffset; + switch(m_LSB){ + case 1: + case 3: + m_FreqHz -= offset; + break; + default: + m_FreqHz += offset; + break; + } + } +} +//---------------------------------------------------------- +BOOL __fastcall CCradio::IsRigLSB(void) +{ + return m_LSB == 1; +} +//---------------------------------------------------------- +// モードの更新 +// +void __fastcall CCradio::SetInternalRigMode(LPCSTR pMode) +{ + int mode = 0; + int oldmode = m_RigMode; + m_RigMode = FindStringTable(g_tRadioMode, pMode, AN(g_tRadioMode)); + if( m_RigMode < 0 ) m_RigMode = rmUNKNOWN; + switch(m_RigMode){ + case rmLSB: + case rmRTTY: + case rmPACKET: + mode = 1; + break; + case rmUSB: + mode = 2; + break; + } + m_LSB = mode; + if( mode ){ + if( RADIO.PollOffset < 3 ) RADIO.PollOffset = mode; + if( oldmode != m_RigMode ){ + CalcRigFreq(m_RigHz*1.0e-6); + } + } +} +//---------------------------------------------------------- +// 周波数の更新 (freq=MHz) +// +double __fastcall CCradio::CalcRigFreq(double freq) +{ + m_RigHz = (freq * 1.0e6) + 0.5; + switch(m_LSB){ + case 1: // LSB + freq -= m_CarrierFreq/1000000.0; + break; + case 2: // USB + freq += m_CarrierFreq/1000000.0; + break; + case 3: // CW-LSB + freq -= (m_CarrierFreq-700)/1000000.0; + break; + case 4: // CW-USB + freq += (m_CarrierFreq-700)/1000000.0; + break; + default: + break; + } + m_FreqHz = (freq * 1.0e6) + 0.5; + return freq; +} +//---------------------------------------------------------- +// 周波数の更新 (freq=MHz) +// +void __fastcall CCradio::UpdateFreq(double freq) +{ + if( freq < 0.001 ) return; + + if( RADIO.PollOffset < 3 ) m_LSB = RADIO.PollOffset; +#if 1 + freq = CalcRigFreq(freq); +#else + m_RigHz = (freq * 1.0e6) + 0.5; + switch(m_LSB){ + case 1: // LSB + freq -= m_CarrierFreq/1000000.0; + break; + case 2: // USB + freq += m_CarrierFreq/1000000.0; + break; + case 3: // CW-LSB + freq -= (m_CarrierFreq-700)/1000000.0; + break; + case 4: // CW-USB + freq += (m_CarrierFreq-700)/1000000.0; + break; + default: + break; + } + m_FreqHz = (freq * 1.0e6) + 0.5; +#endif + char bf[32]; + sprintf(bf, "%.3lf", freq); + if( strcmp(m_Freq, bf) ){ + strcpy(m_Freq, bf); + m_FreqEvent = 1; + } +} + +void __fastcall CCradio::FreqYaesuHF(void) +{ + ULONG fq; + fq = m_rxbuf[1]; + fq = fq << 8; + fq |= m_rxbuf[2]; + fq = fq << 8; + fq |= m_rxbuf[3]; + fq = fq << 8; + fq |= m_rxbuf[4]; + + double f; + switch(RADIO.PollType){ + case RADIO_POLLFT1000D: // FT1000D + f = 25600000.0; + break; + case RADIO_POLLFT920: // FT920 + f = 1000000.0; + break; + default: // FT1000MP + f = 1600000.0; + break; + } + + UpdateFreq(double(fq)/f); + + if( RADIO.PollOffset < 3 ) return; + switch(m_rxbuf[7]){ + case 0: // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case 1: // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case 2: // CW + m_LSB = 0; + m_RigMode = rmCW; + break; + case 3: // AM + m_LSB = 0; + m_RigMode = rmAM; + break; + case 4: // FM + m_LSB = 0; + m_RigMode = rmFM; + break; + case 5: // RTTY + m_LSB = 1; + m_RigMode = rmRTTY; + break; + case 6: // PACKET + m_LSB = 1; + m_RigMode = rmPACKET; + break; + default: // Other + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } +} + +void __fastcall CCradio::FreqYaesuVU(void) +{ + ULONG fq; + fq = m_rxbuf[0] >> 4; + fq *= 10; + fq += m_rxbuf[0] & 0x0f; + fq *= 10; + fq += m_rxbuf[1] >> 4; + fq *= 10; + fq += m_rxbuf[1] & 0x0f; + fq *= 10; + fq += m_rxbuf[2] >> 4; + fq *= 10; + fq += m_rxbuf[2] & 0x0f; + fq *= 10; + fq += m_rxbuf[3] >> 4; + fq *= 10; + fq += m_rxbuf[3] & 0x0f; + + UpdateFreq( double(fq) / 100000.0 ); + + if( RADIO.PollOffset < 3 ) return; + switch(m_rxbuf[4]){ + case 0x00: // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case 0x01: // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case 0x03: // CW-LSB + case 0x83: + m_LSB = 3; + m_RigMode = rmCW; + break; + case 0x02: // CW-USB + case 0x82: + m_LSB = 4; + m_RigMode = rmCW; + break; + case 0x04: // AM + case 0x84: + m_LSB = 0; + m_RigMode = rmAM; + break; + case 0x08: // FM + case 0x88: + m_LSB = 0; + m_RigMode = rmFM; + break; + default: // Other + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } +} + +//AA6YQ 1.66B +void __fastcall CCradio::FreqYaesu9K2K(void) +{ +//0 1 2 3 +//01234567890123456789012345678901234567890 +//IF00021155000 +001000 0002000008 ; +//abcdefghijklmnopqrstuvwxyz1234567890 <---- 桁位置 +//c - m 周波数 21.155000MHz +//x 0 = RIT off 1 = RIT on +//z 0 = XIT off 1 = XIT on +//12 M.CH +//4 モード 1=LSB 2=USB 3=CW 4=FM 5=AM 6=RTTY +//567 000=RX:A TX:A 001=RX:A TX=B 100=RX:B TX:B 101=RX:B TX=A + ULONG fq = 0; + + m_rxbuf[13] = 0; + if( sscanf((LPCSTR)&m_rxbuf[5], "%lu", &fq) == 1 ){ + if( fq ) UpdateFreq(double(fq)/1e6); + } + if( RADIO.PollOffset < 3 ) return; + switch(m_rxbuf[29]){ + case '1': // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case '2': // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case '3': // CW + m_LSB = 0; + m_RigMode = rmCW; + break; + case '4': // FM + m_LSB = 0; + m_RigMode = rmFM; + break; + case '5': // AM + m_LSB = 0; + m_RigMode = rmAM; + break; + case '6': // RTTY + m_LSB = 1; + m_RigMode = rmRTTY; + break; + default: // Other + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } +} + +void __fastcall CCradio::FreqICOM(void) +{ +// 0 1 2 3 4 5 6 7 8 9 +// fe e0 40 03 90 09 02 07 00 fd 0007020990 +// fe e0 40 03 90 09 02 07 fd 07020990 +// fe e0 40 04 xx fd + + if( (m_rxbuf[3] == 0x03) || (m_rxbuf[3] == 0x00) ){ // Freq + ULONG fq = 0; + if( m_rxbuf[8] != 0xfd ){ + fq = (m_rxbuf[8] >> 4); + fq *= 10; + fq += (m_rxbuf[8] & 0x0f); + } + fq *= 10; + fq += m_rxbuf[7] >> 4; + fq *= 10; + fq += m_rxbuf[7] & 0x0f; + fq *= 10; + fq += m_rxbuf[6] >> 4; + fq *= 10; + fq += m_rxbuf[6] & 0x0f; + fq *= 10; + fq += m_rxbuf[5] >> 4; + fq *= 10; + fq += m_rxbuf[5] & 0x0f; + fq *= 10; + fq += m_rxbuf[4] >> 4; + fq *= 10; + fq += m_rxbuf[4] & 0x0f; + + UpdateFreq(double(fq)/1e6); + } + else if( (m_rxbuf[3] == 0x04) || (m_rxbuf[3] == 0x01) ){ // Mode + if( RADIO.PollOffset < 3 ) return; + int oldmode = m_RigMode; + switch(m_rxbuf[4]){ + case 0x00: // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case 0x01: // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case 0x02: // AM + m_LSB = 0; + m_RigMode = rmAM; + break; + case 0x03: // CW + m_LSB = 0; + m_RigMode = rmCW; + break; + case 0x04: // RTTY + m_LSB = 1; + m_RigMode = rmRTTY; + break; + case 0x05: // FM + m_LSB = 0; + m_RigMode = rmFM; + break; + default: // Other + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } + if( oldmode != m_RigMode ){ + CalcRigFreq(m_RigHz*1.0e-6); + } + } +} + +void __fastcall CCradio::FreqKenwood(void) +{ +//0 1 2 3 +//01234567890123456789012345678901234567890 +//IF00021155000 +001000 0002000008 ; +//abcdefghijklmnopqrstuvwxyz1234567890 <---- 桁位置 +//c - m 周波数 21.155000MHz +//x 0 = RIT off 1 = RIT on +//z 0 = XIT off 1 = XIT on +//12 M.CH +//4 モード 1=LSB 2=USB 3=CW 4=FM 5=AM 6=RTTY +//567 000=RX:A TX:A 001=RX:A TX=B 100=RX:B TX:B 101=RX:B TX=A + + + ULONG fq = 0; + + m_rxbuf[13] = 0; + if( sscanf((LPCSTR)&m_rxbuf[2], "%lu", &fq) == 1 ){ + if( fq ) UpdateFreq(double(fq)/1e6); + } + if( RADIO.PollOffset < 3 ) return; + switch(m_rxbuf[29]){ + case '1': // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case '2': // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case '3': // CW + m_LSB = 0; + m_RigMode = rmCW; + break; + case '4': // FM + m_LSB = 0; + m_RigMode = rmFM; + break; + case '5': // AM + m_LSB = 0; + m_RigMode = rmAM; + break; + case '6': // RTTY + m_LSB = 1; + m_RigMode = rmRTTY; + break; + default: // Other + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } +} + +void __fastcall CCradio::FreqJST245(void) +{ +// 0 1 2 3 4 5 6 7 8 9 10 11 12 +// ”Iabdffffffffg” +//  I:ヘッダー記号 +//  a:使用アンテナ1桁(1〜3) +//  b:バンド幅1桁(0〜2) +//  d:モード1桁(0〜5) +//  f:送受信周波数8桁(00100000〜53999998) +//  g:AGC1桁(0〜2) + + ULONG fq = 0; + + m_rxbuf[12] = 0; + LPCSTR p = (LPCSTR)&m_rxbuf[4]; + for( ; *p; p++ ) if( !isdigit(*p) ) return; + if( sscanf((LPCSTR)&m_rxbuf[4], "%lu", &fq) == 1 ){ + if( fq ) UpdateFreq(double(fq)/1e6); + } + if( RADIO.PollOffset < 3 ) return; + //char JST_Mode[] = {"F1","A1","USB","LSB","A3", "F3"}; + switch(m_rxbuf[3]){ + case '0': // RTTY + m_LSB = 1; + m_RigMode = rmRTTY; + break; + case '1': // CW + m_LSB = 0; + m_RigMode = rmCW; + break; + case '2': // USB + m_LSB = 2; + m_RigMode = rmUSB; + break; + case '3': // LSB + m_LSB = 1; + m_RigMode = rmLSB; + break; + case '4': // AM + m_LSB = 0; + m_RigMode = rmAM; + break; + case '5': // FM + m_LSB = 0; + m_RigMode = rmFM; + break; + default: + m_LSB = 0; + m_RigMode = rmUNKNOWN; + break; + } +} + diff --git a/cradio.h b/cradio.h new file mode 100644 index 0000000..2cd2fb3 --- /dev/null +++ b/cradio.h @@ -0,0 +1,196 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +///---------------------------------------------------------- +/// Radioコミニュケーションクラス +/// +/// (C) JE3HHT Makoto.Mori +/// +//--------------------------------------------------------------------------- +#ifndef CradioH +#define CradioH +#include "ComLib.h" +#include "MMlink.h" +//--------------------------------------------------------------------------- +#include + +typedef enum { + rmLSB, + rmUSB, + rmCW, + rmAM, + rmFM, + rmRTTY, + rmPACKET, + rmUNKNOWN, +}RIGMODE; + +extern const LPCSTR g_tRadioMode[]; + +typedef struct { + int change; + + char StrPort[32]; // ポートの名前 + int BaudRate; // ボーレート + int BitLen; // 0-7Bit, 1-8Bit + int Stop; // 0-1Bit, 1-2Bit + int Parity; // 0-PN, 1-PE, 2-PO + int flwXON; // Xon/Xoff ON + int flwCTS; // CTS-RTS ON + int usePTT; // PTT control + + long ByteWait; // バイト間の送信ウエイト + + int Cmdxx; + + AnsiString CmdInit; + AnsiString CmdRx; + AnsiString CmdTx; + + AnsiString cmdGNR; + int openGNR; + + int PollType; + int PollInterval; + int PollOffset; + + int PollScan; +}CRADIOPARA; +extern CRADIOPARA RADIO; +//--------------------------------------------------------------------------- +void __fastcall LoadRADIOSetup(TMemIniFile *pIniFile); +void __fastcall SaveRADIOSetup(TMemIniFile *pIniFile); +//#define CR 0x0d +//#define LF 0x0a +#define CRADIO_CLOSE 1 +#define RADIO_COMBUFSIZE 4096 +#define RADIO_TXBUFSIZE 256 +#define RADIO_RXBUFSIZE 256 + +enum { + RADIO_POLLNULL, + RADIO_POLLYAESUHF, + RADIO_POLLYAESUVU, + RADIO_POLLICOM, + RADIO_POLLICOMN, + RADIO_POLLOMNIVI, + RADIO_POLLOMNIVIN, + RADIO_POLLKENWOOD, + RADIO_POLLKENWOODN, + RADIO_POLLFT1000D, + RADIO_POLLFT920, + RADIO_POLLJST245, + RADIO_POLLJST245N, + RADIO_POLLFT9000, //1.66B AA6YQ add new radios at end of list as this value is stored in mmtty.ini + RADIO_POLLFT2000, //1.66B AA6YQ + RADIO_POLLFT950, //1.66B AA6YQ + RADIO_POLLFT450, //1.66B AA6YQ +}; + +class CCradio : public TThread +{ +public: + BOOL m_CreateON; // クリエイトフラグ + DCB m_dcb; // DCB + HANDLE m_fHnd; // ファイルハンドル + HWND m_wHnd; // 親のウインドウハンドル + UINT m_uMsg; + UINT m_ID; // メッセージのID番号 + volatile int m_Command; // スレッドへのコマンド + BOOL m_TxAbort; // 送信中止フラグ + AnsiString Name; + CMMRadio *m_pRadio; + + int m_PSKGNRId; + int m_OpenGNR; + + char m_txbuf[RADIO_TXBUFSIZE]; + int m_txcnt; + int m_txwp; + int m_txrp; + + int m_PollCnt; + int m_PollCntHalf; + int m_PollTimer; + int m_PollInhibit; + unsigned char m_rxbuf[RADIO_RXBUFSIZE]; + int m_rxcnt; + int m_FreqEvent; + char m_Freq[32]; + UINT m_FreqHz; // [Hz] + UINT m_RigHz; + + int m_ScanAddr; + int m_CarrierFreq; + int m_LSB; + int m_RigMode; +protected: + void virtual __fastcall Execute(); + BOOL __fastcall OpenPipe(CRADIOPARA *cp, HWND hwnd, UINT nID); + void __fastcall CatchPoll(BYTE c); + void __fastcall FreqYaesuHF(void); + void __fastcall FreqYaesuVU(void); + void __fastcall FreqYaesu9K2K(void); + void __fastcall FreqICOM(void); + void __fastcall FreqKenwood(void); + void __fastcall FreqJST245(void); + +public: + __fastcall CCradio(bool CreateSuspended); + __fastcall ~CCradio(){ + Close(); + }; + inline BOOL __fastcall IsOpen(void){ + return m_CreateON; + }; + inline void __fastcall UpdateHandle(HWND hwnd, UINT uMsg){ + m_wHnd = hwnd; m_uMsg = uMsg; + }; + BOOL __fastcall Open(CRADIOPARA *cp, HWND hwnd, UINT uMsg, UINT nID); + void __fastcall Close(void); + void __fastcall ReqClose(void); + void __fastcall WaitClose(void); + DWORD __fastcall RecvLen(void); + int __fastcall TxBusy(void); + DWORD __fastcall Read(BYTE *p, DWORD len); + void __fastcall Write(void *p, DWORD len); + void __fastcall PutChar(char c); + void OutStr(LPCSTR fmt, ...); + void OutLine(LPCSTR fmt, ...); + void __fastcall SendCommand(LPCSTR p); + void __fastcall SetPTT(int sw); + void __fastcall Timer(int tx, int interval); + + inline LPCSTR __fastcall GetFreq(void){ + m_FreqEvent = 0; + return m_Freq; + }; + int __fastcall IsFreqChange(LPCSTR p); + void __fastcall UpdateFreq(double freq); + void __fastcall SetCarrierFreq(int fq); + + void __fastcall SetInternalRigMode(LPCSTR pMode); + BOOL __fastcall IsRigLSB(void); + double __fastcall CalcRigFreq(double freq); + void __fastcall WaitICOM(int intval); +}; + +void __fastcall InitRADIOPara(void); +#endif + diff --git a/extfsk.dll b/extfsk.dll new file mode 100644 index 0000000..6850ce1 Binary files /dev/null and b/extfsk.dll differ diff --git a/fsk8250.fsk b/fsk8250.fsk new file mode 100644 index 0000000..02533d3 Binary files /dev/null and b/fsk8250.fsk differ diff --git a/mfsk.cpp b/mfsk.cpp new file mode 100644 index 0000000..a3ec85a --- /dev/null +++ b/mfsk.cpp @@ -0,0 +1,547 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +/*============================================================================= + MFSK16の実装 2004/JUL/28に作成開始 by Mako JE3HHT +=============================================================================*/ +#include +#pragma hdrstop +#include +#include +#include + +#include "mfsk.h" +#include "dsp.h" + +#if DEBUG && 0 // InterLeaverのデバッグ +#define TEST_BITS 5 // MFSK8 = 5, MFSK16 = 4, MFSK31 = 3 +//-------------------------------------------------------------------------- +int IVTest(void) +{ + + CInterLeaver IVE, IVD; + + BYTE syms[256]; + + LPCSTR p = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz" + "--------------------------------------------------------------" + "--------------------------------------------------------------" + "--------------------------------------------------------------"; + FILE *fp = fopen("TEST.TXT", "wt"); + + int i; + IVE.Init(TEST_BITS); + IVD.Init(TEST_BITS); + int stage = 1; + while(*p){ + LPCSTR pp = p; + fprintf(fp, "%2u ", stage++); + for( i = 0; i < TEST_BITS; i++ ){ + fprintf(fp, "%c", *pp); + if( *pp ) pp++; + } + fprintf(fp, "\t"); + for( i = 0; i < TEST_BITS; i++ ){ + if( *p ){ + syms[i] = *p++; + } + else { + syms[i] = '-'; + } + } + IVE.EncodeSyms(syms); + for( i = 0; i < TEST_BITS; i++ ){ + fprintf(fp, "%c", syms[i] ? syms[i] : ' '); + } + IVD.DecodeSyms(syms); + fprintf(fp, "\t"); + for( i = 0; i < TEST_BITS; i++ ){ + fprintf(fp, "%c", syms[i] ? syms[i] : ' '); + } + fprintf(fp, "\n"); + } + fclose(fp); + return 0; +} +int n = IVTest(); +#endif + + +#if DEBUG && 0 // g_tGray2Bin[], g_tBin2Gray, g_tParityOddの生成 +/*============================================================================= + g_tGray2Bin[], g_tBin2Gray, g_tParity +=============================================================================*/ +//--------------------------------------------------------------------------- +static int __fastcall GetParity(UINT c) +{ + int i, n; + for( i = n = 0; i < 32; i++, c = c >> 1 ){ + if( c & 1 ) n++; + } + return n; +} +static int CreateTable(void) +{ + int tbl[32]; + int i; + + FILE *fp = fopen("test.txt", "wt"); + fprintf(fp, "const BYTE g_tBin2Gray[]={\t//Decode"); + for( i = 0; i < MFSK_MAXTONES; i++ ){ + tbl[i] = (i >> 1) ^ i; // グレーコードに変換 + if( !(i % 8) ) fprintf(fp, "\n\t"); + fprintf(fp, "0x%02X,", tbl[i]); + } + fprintf(fp, "\n};\nconst BYTE g_tGray2Bin[]={\t//Encode"); + for( i = 0; i < MFSK_MAXTONES; i++ ){ + if( !(i % 8) ) fprintf(fp, "\n\t"); + for( int j = 0; j < 32; j++ ){ + if( i == tbl[j] ) fprintf(fp, "0x%02X,", j); + } + } + fprintf(fp, "\n};\n"); + // パリティテーブルを作成 + fprintf(fp, "const BYTE g_tParityOdd[]={\t//Odd parity"); + for( i = 0; i < 256; i++ ){ + if( !(i % 32) ) fprintf(fp, "\n\t"); + fprintf(fp, "%d,", GetParity(i) & 1); + } + fprintf(fp, "\n};\n"); + fclose(fp); + return 0; +} +int n = CreateTable(); +#endif + +/* +const BYTE g_tBin2Gray[]={ //Decode + 0x00,0x01,0x03,0x02,0x06,0x07,0x05,0x04, + 0x0C,0x0D,0x0F,0x0E,0x0A,0x0B,0x09,0x08, + 0x18,0x19,0x1B,0x1A,0x1E,0x1F,0x1D,0x1C, + 0x14,0x15,0x17,0x16,0x12,0x13,0x11,0x10, +}; +const BYTE g_tGray2Bin[]={ //Encode + 0x00,0x01,0x03,0x02,0x07,0x06,0x04,0x05, + 0x0F,0x0E,0x0C,0x0D,0x08,0x09,0x0B,0x0A, + 0x1F,0x1E,0x1C,0x1D,0x18,0x19,0x1B,0x1A, + 0x10,0x11,0x13,0x12,0x17,0x16,0x14,0x15, +}; +*/ + + +/*============================================================================= + MFSK type ヘルパ関数 +=============================================================================*/ +//-------------------------------------------------------------------------- +int __fastcall MFSK_Speed2Type(double speed) +{ + if( speed < 5.0 ){ + return typMFSK4; + } + else if( speed < 10.0 ){ + return typMFSK8; + } + else if( speed < 13.0 ){ + return typMFSK11; + } + else if( speed < 20.0 ){ + return typMFSK16; + } + else if( speed < 28.0 ){ + return typMFSK22; + } + else if( speed < 32.0 ){ + return typMFSK31; + } + else if( speed < 50.0 ){ + return typMFSK32; + } + else { + return typMFSK64; + } +} +//-------------------------------------------------------------------------- +void __fastcall MFSK_SetPara(int type, int *pTones, double *pSpeed, int *pBits) +{ + switch(type){ + case typMFSK16: + if( pTones ) *pTones = 16; + if( pSpeed ) *pSpeed = 15.625; + if( pBits ) *pBits = 4; + break; + case typMFSK8: + if( pTones ) *pTones = 32; + if( pSpeed ) *pSpeed = 7.8125; + if( pBits ) *pBits = 5; + break; + case typMFSK31: + if( pTones ) *pTones = 8; + if( pSpeed ) *pSpeed = 31.25; + if( pBits ) *pBits = 3; + break; + case typMFSK11: + if( pTones ) *pTones = 16; + if( pSpeed ) *pSpeed = 11025.0/1024.0; + if( pBits ) *pBits = 4; + break; + case typMFSK22: + if( pTones ) *pTones = 16; + if( pSpeed ) *pSpeed = 11025.0/512.0; + if( pBits ) *pBits = 4; + break; + case typMFSK32: + if( pTones ) *pTones = 16; + if( pSpeed ) *pSpeed = 31.25; + if( pBits ) *pBits = 4; + break; + case typMFSK64: + if( pTones ) *pTones = 16; + if( pSpeed ) *pSpeed = 62.5; + if( pBits ) *pBits = 4; + break; + case typMFSK4: + if( pTones ) *pTones = 32; + if( pSpeed ) *pSpeed = 3.90625; + if( pBits ) *pBits = 5; + break; + } +} +/*============================================================================= + CViterbiEncodeクラス +=============================================================================*/ +const BYTE g_tParityOdd[]={ //Odd parity + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, + 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, +}; +#define POLY2(d,p1,p2) ((g_tParityOdd[d&p1]<<1)|g_tParityOdd[d&p2]) + +//-------------------------------------------------------------------------- +__fastcall CViterbiEncode::CViterbiEncode(void) +{ + Init(MFSK_VITERBI_K, MFSK_VITERBI_POLY1, MFSK_VITERBI_POLY2); +} +//-------------------------------------------------------------------------- +void __fastcall CViterbiEncode::Init(int k, int poly1, int poly2) +{ + m_K = k; + m_Poly1 = poly1; m_Poly2 = poly2; + Reset(); +} +//-------------------------------------------------------------------------- +// b1 = 1st, b0 = 2nd +BYTE __fastcall CViterbiEncode::Do(BOOL bit) +{ + m_EncData = m_EncData << 1; + if( bit ) m_EncData |= 1; + return BYTE(POLY2(m_EncData, m_Poly1, m_Poly2)); +} + +/*============================================================================= + CViterbiクラス +=============================================================================*/ +//-------------------------------------------------------------------------- +__fastcall CViterbi::CViterbi(void) +{ + m_BlockSize = 1; + m_TraceBack = 45; + m_States = 0; + + m_pPoly = NULL; + + memset(m_pMetrics, 0, sizeof(m_pMetrics)); + memset(m_pHistory, 0, sizeof(m_pHistory)); + memset(m_tSeq, 0, sizeof(m_tSeq)); + memset(m_tMetrics, 0, sizeof(m_tMetrics)); + + m_CurPtr = NULL; +} +//-------------------------------------------------------------------------- +void __fastcall CViterbi::Free(void) +{ + if( m_pPoly ){ + delete m_pPoly; m_pPoly = NULL; + } + for( int i = 0; i < VITERBI_PATHMAX; i++ ){ + delete m_pMetrics[i]; m_pMetrics[i] = NULL; + delete m_pHistory[i]; m_pHistory[i] = NULL; + } +} +//-------------------------------------------------------------------------- +void __fastcall CViterbi::Init(int k, int poly1, int poly2) +{ + int i; + + if( m_pPoly ){ +#if DEBUG + Application->MainForm->Caption = "Init duplication in CViterbi"; +#endif + Free(); + } + int size = _tBitData[k] * 2; +#if DEBUG + if( size > 256 ){ + Application->MainForm->Caption = "Over size in CViterbi"; + size = 256; + } +#endif + m_States = size / 2; + // 高速化のために展開データをあらかじめ作成しておく + m_pPoly = new int[size]; + for( i = 0; i < size; i++ ){ + m_pPoly[i] = POLY2(i, poly1, poly2); + } + for( i = 0; i < VITERBI_PATHMAX; i++ ){ + m_pMetrics[i] = new int[m_States]; + m_pHistory[i] = new int[m_States]; + } + for( i = 0; i < 256; i++ ){ // s = 0 to 255 + m_tMetrics[0][i] = 128 - i; // 128 to -127 + m_tMetrics[1][i] = i - 128; // -128 to 127 + } + m_CurPtr = 0; + Reset(); +} +//-------------------------------------------------------------------------- +BOOL __fastcall CViterbi::SetTraceBack(int traceback) + +{ + if( (traceback < 0) || (traceback > (VITERBI_PATHMAX - 1)) ) return FALSE; + m_TraceBack = traceback; + return TRUE; +} +//-------------------------------------------------------------------------- +BOOL __fastcall CViterbi::SetBlockSize(int blocksize) +{ + if( (blocksize < 1) || (blocksize > m_TraceBack) ) return FALSE; + m_BlockSize = blocksize; + return TRUE; +} +//-------------------------------------------------------------------------- +void __fastcall CViterbi::Reset(void) +{ + if( !m_pMetrics[0] ) return; + + memset(m_tSeq, 0, sizeof(m_tSeq)); + int i; + for( i = 0; i < VITERBI_PATHMAX; i++) { + memset(m_pMetrics[i], 0, m_States * sizeof(int)); + memset(m_pHistory[i], 0, m_States * sizeof(int)); + } + m_CurPtr = 0; +} +//-------------------------------------------------------------------------- +int __fastcall CViterbi::TraceBack(int *pMetric) +{ + int i; + + UINT pn = CIRCULATE(m_CurPtr - 1, VITERBI_PATHMAX); + int *ip = m_pMetrics[pn]; + int MaxMetric = INT_MIN; + int MaxState = 0; + for( i = 0; i < m_States; i++, ip++ ){ + if( *ip > MaxMetric ){ + MaxState = i; + MaxMetric = *ip; + } + } + + m_tSeq[pn] = MaxState; + for( i = 0; i < m_TraceBack; i++ ){ + UINT prev = CIRCULATE(pn - 1, VITERBI_PATHMAX); + m_tSeq[prev] = m_pHistory[pn][m_tSeq[pn]]; + pn = prev; + } + if( pMetric ) *pMetric = m_pMetrics[pn][m_tSeq[pn]]; + + UINT c = 0; + for( i = 0; i < m_BlockSize; i++ ){ + c = (c << 1) | (m_tSeq[pn] & 1); + pn = CIRCULATE(pn + 1, VITERBI_PATHMAX); + } + if( pMetric ) *pMetric = m_pMetrics[pn][m_tSeq[pn]] - *pMetric; + + return c; +} +//-------------------------------------------------------------------------- +// s[0] = 1st, s[1] = 2nd +int __fastcall CViterbi::Decode(int *pMetric, BYTE s[2]) +{ + int i, j, m[4], n; + + UINT curp = m_CurPtr; + UINT prevp = CIRCULATE(curp - 1, VITERBI_PATHMAX); + + m[0] = m_tMetrics[0][s[0]] + m_tMetrics[0][s[1]]; + m[1] = m_tMetrics[0][s[0]] + m_tMetrics[1][s[1]]; + m[2] = m_tMetrics[1][s[0]] + m_tMetrics[0][s[1]]; + m[3] = m_tMetrics[1][s[0]] + m_tMetrics[1][s[1]]; + + int *mp = m_pMetrics[curp]; + int *hp = m_pHistory[curp]; + for( n = 0; n < m_States; n++ ){ + int p0, p1, s0, s1, m0, m1; + + s0 = n; s1 = n + m_States; + p0 = s0 >> 1; p1 = s1 >> 1; + m0 = m_pMetrics[prevp][p0] + m[m_pPoly[s0]]; + m1 = m_pMetrics[prevp][p1] + m[m_pPoly[s1]]; + if( m0 > m1 ){ + *mp++ = m0; + *hp++ = p0; + } + else { + *mp++ = m1; + *hp++ = p1; + } + } + m_CurPtr = CIRCULATE(m_CurPtr + 1, VITERBI_PATHMAX); + if( !(m_CurPtr % m_BlockSize) ) return TraceBack(pMetric); + + if( m_pMetrics[curp][0] > (INT_MAX / 2) ){ + for( i = 0; i < VITERBI_PATHMAX; i++ ){ + mp = m_pMetrics[i]; + for( j = 0; j < m_States; j++ ){ + *mp++ -= INT_MAX / 2; + } + } + } + if( m_pMetrics[curp][0] < (INT_MIN / 2) ){ + for( i = 0; i < VITERBI_PATHMAX; i++){ + mp = m_pMetrics[i]; + for( j = 0; j < m_States; j++){ + *mp++ += INT_MIN / 2; + } + } + } + return -1; +} + +/*============================================================================= + CInterLeaverクラス + + 1 2 3 4 5 6 7 8 9 0 1 2 3 4 +To encode: ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz-------------------------------------------------------------------------------------- +Encoded: A E I M Q U Y 2 6 a eB iF mJ qN uR yV -Z -3 -7 -b -fC -jG -nK -rO -vS -zW --0 --4 --8 --c --gD--kH--oL--sP--wT---X---1 + +1234567890 12 +------------- +AEIMQUY26a ei +BFJNRVZ37b fj +CGKOSW048c gk +DHLPTX159d hl + +=============================================================================*/ +//-------------------------------------------------------------------------- +__fastcall CInterLeaver::CInterLeaver(void) +{ + Init(4); +} +//-------------------------------------------------------------------------- +void __fastcall CInterLeaver::Init(int bitsize) +{ +#if DEBUG + if( bitsize > MFSK_MAXBITS ){ + Application->MainForm->Caption = "Over BitSize in InterLeaver"; + return; + } +#endif + m_Stages = 10; + m_BitSize = bitsize; + m_BitSizeM = bitsize - 1; + if( bitsize == 5 ){ // for comminucate with Stream on MFSK8 + m_Stages = 5; + } + Reset(); +} +//-------------------------------------------------------------------------- +void __fastcall CInterLeaver::Reset(void) +{ + memset(m_tTable, 0, sizeof(m_tTable)); +} +//-------------------------------------------------------------------------- +void __fastcall CInterLeaver::Bits2Syms(BYTE *pSyms, int b) +{ + for( int i = 0; i < m_BitSize; i++ ){ + *pSyms++ = BYTE(b & _tBitData[m_BitSizeM-i]); + } +} +//-------------------------------------------------------------------------- +int __fastcall CInterLeaver::Syms2Bits(BYTE *pSyms) +{ + int b = 0; + for( int i = 0; i < m_BitSize; i++ ){ + b = b << 1; + if( *pSyms++ ) b |= 1; + } + return b; +} +//-------------------------------------------------------------------------- +// MFSK16 = pSyms[4], MFSK8 = pSyms[5], MFSK31 = pSym[3] +void __fastcall CInterLeaver::DecodeSyms(BYTE *pSyms) +{ + for( int N = 0; N < m_Stages; N++ ){ + int i; + for( i = 0; i < m_BitSize; i++ ){ + for( int j = 0; j < m_BitSizeM; j++ ) m_tTable[N][i][j] = m_tTable[N][i][j+1]; + } + for(i = 0; i < m_BitSize; i++) m_tTable[N][i][m_BitSizeM] = pSyms[i]; + for(i = 0; i < m_BitSize; i++) pSyms[i] = m_tTable[N][i][i]; + } +} +//-------------------------------------------------------------------------- +// MFSK16 = pSyms[4], MFSK8 = pSyms[5], MFSK31 = pSym[3] +void __fastcall CInterLeaver::EncodeSyms(BYTE *pSyms) +{ + for( int N = 0; N < m_Stages; N++ ){ + int i; + for( i = 0; i < m_BitSize; i++ ){ + for( int j = 0; j < m_BitSizeM; j++ ) m_tTable[N][i][j] = m_tTable[N][i][j+1]; + } + for(i = 0; i < m_BitSize; i++) m_tTable[N][i][m_BitSizeM] = pSyms[i]; + for(i = 0; i < m_BitSize; i++) pSyms[i] = m_tTable[N][i][m_BitSizeM-i]; + } +} +//-------------------------------------------------------------------------- +// MFSK8 = b4 to b0, MFSK16 = b3 to b0 +int __fastcall CInterLeaver::DecodeBits(int b) +{ + BYTE tSyms[MFSK_MAXBITS]; + + Bits2Syms(tSyms, b); + DecodeSyms(tSyms); + return Syms2Bits(tSyms); +} +//-------------------------------------------------------------------------- +// MFSK8 = b4 to b0, MFSK16 = b3 to b0 +int __fastcall CInterLeaver::EncodeBits(int b) +{ + BYTE tSyms[MFSK_MAXBITS]; + + Bits2Syms(tSyms, b); + EncodeSyms(tSyms); + return Syms2Bits(tSyms); +} +//-------------------------------------------------------------------------- + diff --git a/mfsk.h b/mfsk.h new file mode 100644 index 0000000..9ed8400 --- /dev/null +++ b/mfsk.h @@ -0,0 +1,127 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +/*============================================================================= + MFSK16の実装 2004/JUL/28に作成開始 by Mako JE3HHT +=============================================================================*/ +#ifndef _MFSK_H +#define _MFSK_H + +#include "CLX.h" +#include "ComLib.h" + +#define MFSK_MAXBITS 5 // MFSK4 +#define MFSK_MAXTONES 32 // MFSK4 +#define MFSK_MINSPEED 3.90625 // MFSK4 + +#define MFSK_VITERBI_K 7 // Length = 7 +#define MFSK_VITERBI_POLY1 0x006D // 01101101 (O1 + O3 + O4 + O6 + O7) +#define MFSK_VITERBI_POLY2 0x004F // 01001111 (O1 + O2 + O3 + O4 + O7) + +typedef enum { + typMFSK16, + typMFSK8, + typMFSK31, + typMFSK11, + typMFSK22, + typMFSK32, + typMFSK64, + typMFSK4, +}MFSKTYPE; + +int __fastcall MFSK_Speed2Type(double speed); +void __fastcall MFSK_SetPara(int type, int *pTones, double *pSpeed, int *pBits); + +/*============================================================================= + CViterbiEncodeクラス +=============================================================================*/ +class CViterbiEncode +{ +private: + UINT m_EncData; + + int m_K; + int m_Poly1; + int m_Poly2; +public: + __fastcall CViterbiEncode(void); + void __fastcall Init(int k, int poly1, int poly2); + inline void __fastcall Reset(void){m_EncData = 0;}; + + BYTE __fastcall Do(BOOL bit); +}; + +/*============================================================================= + CViterbiクラス +=============================================================================*/ +#define VITERBI_PATHMAX 64 +class CViterbi +{ +private: + int m_TraceBack; + int m_BlockSize; + int m_States; + UINT m_CurPtr; + + int *m_pPoly; + int *m_pMetrics[VITERBI_PATHMAX]; + int *m_pHistory[VITERBI_PATHMAX]; + int m_tSeq[VITERBI_PATHMAX]; + int m_tMetrics[2][256]; +private: + int __fastcall TraceBack(int *pMetric); + +public: + __fastcall CViterbi(void); + __fastcall ~CViterbi(){Free();}; + void __fastcall Free(void); + void __fastcall Init(int k, int poly1, int poly2); + + BOOL __fastcall SetTraceBack(int traceback); + BOOL __fastcall SetBlockSize(int blocksize); + void __fastcall Reset(void); + int __fastcall Decode(int *pMetric, BYTE s[2]); +}; + +/*============================================================================= + CInterLeaverクラス +=============================================================================*/ +#define INTERLEAVER_STAGES 10 +class CInterLeaver{ +private: + int m_Stages; + int m_BitSize; + int m_BitSizeM; + BYTE m_tTable[INTERLEAVER_STAGES][MFSK_MAXBITS][MFSK_MAXBITS]; +private: + void __fastcall Bits2Syms(BYTE *pSyms, int b); + int __fastcall Syms2Bits(BYTE *pSyms); + +public: + __fastcall CInterLeaver(void); + + void __fastcall Reset(void); + void __fastcall Init(int bitsize); + + void __fastcall DecodeSyms(BYTE *pSyms); + void __fastcall EncodeSyms(BYTE *pSyms); + int __fastcall DecodeBits(int b); + int __fastcall EncodeBits(int b); +}; +#endif diff --git a/mml.h b/mml.h new file mode 100644 index 0000000..2db53a3 --- /dev/null +++ b/mml.h @@ -0,0 +1,67 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef MML_H +#define MML_H + +#define capNOTIFYSESSION 0x0001 +#define capWMCOPYDATA 0x0002 + +enum { + MML_NOTIFYSESSION, + MML_QRETURN, + MML_VFO, +}; + +#pragma pack(push, 1) +typedef struct { + SYSTEMTIME m_TimeLogON; + SYSTEMTIME m_TimeLogOFF; + char m_Call[16+1]; + char m_Mode[6+1]; // Name of the mode (eg. "RTTY", "SSTV") + char m_Freq[16+1]; // MHz (eg. "14.080") + char m_His[20+1]; // His/Her RST(V) and contest number. + char m_My[20+1]; + char m_Name[16+1]; // His/Her name + char m_QTH[28+1]; // His/Her QTH + char m_Pow[4+1]; + char m_Note[56+1]; // Note + char m_QSL[54+1]; // Note or QSL information + BYTE m_QSLS; // QSL sent + BYTE m_QSLR; // QSL rcvd + char m_DXCC[8+1]; // DXCC keyword (eg. JA, W, VK, etc...) + char m_Cont[8+1]; // The continental keyword (AS/OC/NA/SA/EU/AF) +}mmLOGDATA; +#pragma pack(pop) + + +typedef BOOL (__stdcall *tmmlOpen)(HWND hWnd, UINT uMsg); +typedef void (__stdcall *tmmlClose)(void); +typedef void (__stdcall *tmmlSetHandle)(HWND hWnd, UINT uMsg); +typedef DWORD (__stdcall *tmmlIsCap)(void); +typedef BOOL (__stdcall *tmmlIsConnected)(void); +typedef LPCSTR (__stdcall *tmmlGetSessionName)(void); +typedef void (__stdcall *tmmlQuery)(LPCSTR pCall); +typedef void (__stdcall *tmmlSetFreq)(LPCSTR pFreq); +typedef void (__stdcall *tmmlLog)(const mmLOGDATA *pLog, int sw); +typedef void (__stdcall *tmmlLogClear)(void); +typedef void (__stdcall *tmmlSetPTT)(LONG sw); +typedef LONG (__stdcall *tmmlOnCopyData)(HWND hSender, const COPYDATASTRUCT *pcds); +typedef void (__stdcall *tmmlEventVFO)(void); +#endif diff --git a/mmrp.h b/mmrp.h new file mode 100644 index 0000000..8b20165 --- /dev/null +++ b/mmrp.h @@ -0,0 +1,43 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef MMRP_H +#define MMRP_H + +enum { + MMR_DEFCOMMAND, + MMR_VFO, +}; +#define mmrpstatusRX 0x0001 +#define mmrpstatusTXBUSY 0x0002 +#define mmrpstatusFREQ 0x0004 +#define mmrpstatusDEFCMD 0x0008 + +typedef void (__stdcall *tmmrpSetHandle)(HWND hWnd, UINT uMsg); +typedef LONG (__stdcall *tmmrpOpen)(HWND hWnd, UINT uMsg); +typedef void (__stdcall *tmmrpClose)(void); +typedef DWORD (__stdcall *tmmrpGetStatus)(void); +typedef void (__stdcall *tmmrpSetPTT)(LONG tx); +typedef void (__stdcall *tmmrpPutChar)(BYTE c); +typedef BYTE (__stdcall *tmmrpGetChar)(void); +typedef void (__stdcall *tmmrpPolling)(void); +typedef LONG (__stdcall *tmmrpGetFreq)(void); +typedef LONG (__stdcall *tmmrpGetDefCommand)(void); + +#endif diff --git a/mmvari.txt b/mmvari.txt new file mode 100644 index 0000000..aa8b9d8 --- /dev/null +++ b/mmvari.txt @@ -0,0 +1,1021 @@ +「MMVARI操作マニュアル」 + 初版 2004/JAN/18 JE3HHT 森 誠 + 改定 2010/OCT/01 JE3HHT 森 誠 + +========== +◎はじめに +========== + まず「プロジェクトについて」をお読みください。このプログラムの目的について記載してあります。 + + このドキュメントは未だメモのようなものですが、このプログラムはマウスを移動するだけで最下段ステータスバーに簡単な解説が表示されますので、そちらのほうも参照して頂ければと思います。 + +========== +◎変調方式 +========== + MMVARIで利用できる変調方式を以下に示します。メイン画面左上のTXOFFボタンのすぐ下に選択する場所があります。 + - GMSK 通常はこれを使います。 + - FSK V/UHF用(Rigのドリフトや送受のfズレが大きい場合これを使う) + - BPSK MBCS文字に関してWINPSK/Jと互換性がありません。VariJAは注意して下さい。 + - bpsk HALPSK, WINPSK/Jと互換性がありますが、従来のSTD-VARICODE + なので、このプロジェクトの実験はできません。 + - qpsk HALPSK, WINPSK/Jと互換性がありますが、従来のSTD-VARICODE + なので、このプロジェクトの実験はできません。 + - rtty このモードはおまけです。標準のBAUDOTコード(5単位コード) + だけ実装してあり、伝送文字はアルファベット(大文字)と数字、 + 一部の記号に限られます。 + - mfsk MFSK16を実装してあります。伝送コードはMFSK-VARICODEです。 + +※PSKは帯域を抑えるために振幅成分があります。オーバードライブに注意して下さい。 + (スピーチプロセッサは使用しないように) + +※PSKでは伝送速度(Speed)によって以下の名称が一般的に使われています。 + PSK31 31.25Bps + PSK63 62.5Bps + PSK125 125.0Bps + PSK250 250.0Bps + +※MMVARIに搭載されているRTTYの仕様を以下に示します。 + - シフト幅は170Hz (±85Hz) + (マクロコマンド<%TxShift=...>, <%RxShift=...>で変更可) + - キャリア周波数は中心周波数 + - RTTY-LはLSB用(標準)、RTTY-UはUSB用(リバース) + - 伝送コードはBAUDOT(5単位,S-BELL)のみ + - UOS(受信側)はデフォルトでON + (マクロコマンド<%UOS=ON/OFF/ONOFF>で変更可) + - TxUOS(送信側)は常にON + - Diddleは常にON (デフォルトはLTR) + (マクロコマンド<%DIDDLE=BLK/LTR>でコード変更可) + - 送信はAFSK(サウンド出力)のみ + +※MMVARIでのmfsk実装仕様 + mfsk16 mfsk8 mfsk31 mfsk32 mfsk64 mfsk11 mfsk22 +Symbol baudrate 15.625 7.8125 31.25 31.25 62.5 10.767 21.533 +Tones 16 32 8 16 16 16 16 +Tone space(Hz) 15.625 7.8125 31.25 31.25 62.5 10.767 21.533 +MAX FREQ shift(Hz) 234.375 242.1875 218.75 468.75 937.5 161.499 322.988 +Transmission speed(bps) 31.25 19.53125 46.875 62.5 125.0 21.533 43.066 +Viterbi NASA K=7, R=1/2 +Interleaver Diagonal interleaver +VARICODE MFSK standard + +type Speed 実際の変調速度 +mfsk4 3.9063 (3.90625 baud, 32 tones) +mfsk8 7.8125 (7.8125 baud, 32 tones) +mfsk11 10.767 (10.7666015625 baud, 16 tones) +mfsk16 15.625 (15.625 baud, 16 tones) +mfsk22 21.533 (21.533203125 baud, 16 tones) +mfsk31 31.25 (31.25 baud, 8 tones) +mfsk32 32.0 (31.25 baud, 16 tones) +mfsk64 62.5 (62.5 baud, 16 tones) + +====================== +◎周波数を合わせる方法 +====================== + スペクトラムまたはウォータフォールを見て、受信したい信号の中心の部分をクリックすると、その周波数が受信キャリア周波数に設定されます。この時、スペクトラムまたはウォータフォールのレンジは1Kまたは2Kにしておくと合わせ易いと思います。受信機のダイアルで合わせることもできますが、この方法は慣れるまで少し難しいかも知れません。 + + GMSK, FSK, BPSK, bpskは、無線機のヘテロダイン(LSBまたはUSB)はいずれで運用しても構いません。rttyの場合はrtty-L(=LSB)またはrtty-U(=USB)で無線機のヘテロダインと合わして運用して下さい。 + +※mfskはデフォルトでは信号の帯の端(mfskのベーストーン周波数, LSB=右端, USB=左端)をクリックします。「MMVARI設定画面」の「受信」タブで「MFSKを中心周波数で取り扱う」のチェックを付けている場合は信号の帯の中心をクリックします。いずれの場合でも、mfsk-LはLSB用、mfsk-UはUSB用です。rttyと同様、無線機のヘテロダインと合わせて運用して下さい。 + +===== +◎BPF +===== + 可能ならば(お使いのPCの速度が許すなら)最も狭い帯域を選択しておきます。特に40mで運用する場合はQRMが激しいので、できるだけ狭くしておいたほうがFBです。 + +===== +◎ATC +===== + ATCは(Automatic Timing Control)の略で、受信した信号のタイミングから受信同期タイミングを生成する際に、そのタイミング周期を自動的に調整(計測)する機能です。通常はONにしておきます。この機能についてはクロック補正の項も参照して下さい。 + +※MMTTYのATC(Automatic Threshold Control)とは性質がまったく異なります。混乱しないように... + +※MMVARIではATCで同期が取れない場合でも、文字のデコードに関してはかなり頑張ります。しかしbpskモードの場合は、タイミングズレに厳しいソフトもありますので、自局の送信信号のタイミングを正確に合わせることは重要です。相手局からタイミングズレによる文字化けを指摘された場合は、クロック補正の項を参照して下さい。 + +================ +◎受信画面の操作 +================ + 受信画面に表示された文字をマウスでクリックすると、ログに取り込むことができます。左クリックの場合、コールサイン、RSTは自動判定で取り込まれますが、それ以外はポップアップメニューを表示し、ログのいずれの項目に取り込むかを選択する動作になります。右クリックの場合、すべての場合にポップアップメニューを表示します。 + + 右側のスクロールバーで受信画面は自由にスクロールできます。記憶しているテキストは最新の1024行です。 + +================ +◎送信画面の操作 +================ + 送信画面には、次に送信する文章をあからじめ準備しておくことができます。送信中はカーソル位置までの文字が送信されます。 + +================== +◎送受信の切り替え +================== + メイン画面左上の「TX」(またはF12キー)ボタンを押すと送信状態になります。もう一度「TX」ボタンを押すと受信状態に戻ります(この場合、送信画面に存在する未送出の文字はすべて送出される)。 + + 「TXOFF」(またはPAUSEキー)ボタンは強制的な受信への切り替えです。送信画面に未送出の文字が存在するかどうかに関係なく、ただちに受信に切り替えます。いわゆるスクランブル機能ですので、通常のQSO中には使う必要はないと思います。 + +※デフォルトで「TXOFF」にはPAUSEキーが割り当てられています。IME操作でPAUSEキーを使う場合、「MMVARI設定画面」送信タブで、別のキーを割り当てると良いでしょう。 + +============== +◎マクロボタン +============== + MMVARIには144個のマクロボタンが存在し、メインウインドウの下側にカレントページのボタンが表示されています。カレントページはマクロボタンの右端にある上下矢印ボタンで変更できます。一度に表示するボタンの数(段数)は表示メニューで変更できます。 + 個々のマクロボタンは左クリックで「呼び出し」操作、右クリックで「登録(編集)」操作を行います。またファンクションキーによっても呼び出すことができます。 + + MMVARIのマクロ文は、文字列の置換、動作の制御、条件展開などの機能が実装されています。右クリック-ボタン編集画面の「マクロ」ボタンを押すと利用可能なマクロコマンドの一覧が表示されます。また「条件文」ボタンを押すと利用可能な条件命令の一覧が表示されます。 + +以下にマクロ文についてヒントを示します。 + +1.予備知識 +~~~~~~~~~~ + ボタン編集画面で登録(編集)した内容をマクロ文と呼びます。そのマクロを実行した結果の送信文を展開文と呼びます。したがって展開文には<%TX>などのマクロコマンドは含まれません。 + MMVARIでは常にボタンを押したときに展開文が作成され、MMTTYのような遅延展開(変調時に展開)はサポートしません。例えば<%HisRST>コマンド含むマクロを実行する場合、先にログパネルのHisを確定させておく必要があります。 + + マクロコマンドはおおまかに次の2種類に分類できます。 + 文字展開コマンド <%HisCall>, <%HisRST>など文字列を展開するもの + 制御コマンド <%TX>, <%NETON>など動作を制御するもの + +2.コマンドの配置位置と効果 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + 展開した文字列が実際に送信されるのは伝送速度によって遅れますので、常に制御コマンドが先に実行されます。 + ただし<%RX>コマンドや<%TX>コマンドは、マクロ文内のどこに配置しても同じように実行されます。例えば、以下の3つのマクロ文はいずれも同じ実行結果になります(送信に切り替えた後、VVV123を送信して受信に戻る)。 + <%TX>VVV<%RX>123 + <%TX><%RX>VVV123 + VVV<%TX><%RX>123 + + また<%MoveTop>、<%MoveEnd>コマンドは制御コマンドですが、展開文との順序関係を維持する特別なコマンドです。例えば以下のマクロ文は、現在のカーソル位置に関係なく常に未送信文字の先頭に展開文を挿入した後カーソルを最後に移動します。 + + <%MoveTop><%HisCall> de <%MyCall> 途中でQRMがありました + <%MoveEnd> + +※マクロコマンドよりも条件展開が先に実行されます。条件が偽になるブロックに記述されているすべてのマクロコマンドや文字列は存在しないのと同じです。条件展開については本項の(8)を参照して下さい。 + +3.展開文の挿入位置 +~~~~~~~~~~~~~~~~~~ + 基本的にはマクロボタンを押した時のカーソル位置に展開文が挿入されます。ただしマクロ文に<%RX>コマンドを含む場合は、<%MoveEnd>コマンドが存在しなくても、自動的に送信画面の最後の位置にカーソルを移動してから、その展開文が追加されます。 + +4.CWID +~~~~~~ + 展開文がCWIDだけの場合、CWIDのみが送信されます。CWIDとテキストが混在する場合、その順序でCWIDと変調信号がそれぞれ送信されます。したがって変調信号を送信後、CWIDを送信してそのまま受信に戻りたい場合、CWIDの後ろにキャリッジリターンを入れないようにします。編集画面ではキャリッジリターンの有無が判りにくいので、例えば以下のように<%EOF>を定義するのが確実な方法です。 + + <%TX>TNX AGN 73, SK...<%CWID><%RX><%EOF> + + 以下に<%CWID=...>内に記述する特殊の文字とCW符号の関係を示します。 + @ AS + : SK (VA) + ; AR + = BT + ] KN + +5.送信画面の自動消去 +~~~~~~~~~~~~~~~~~~~~ + 受信に戻った際に送信画面を自動的に消去したい場合、以下のように、<%AutoClear>コマンドをマクロ文に含めてください。 + + BTU <%HisCall> de <%MyCall> KN + <%RX><%AutoClear> + +※TXOFFで送信をキャンセルした場合、送信画面の自動消去は働きません。 + +6.繰り返し送信 +~~~~~~~~~~~~~~ + マクロ文内に<%RepeatTX=...>コマンドが存在すると、その展開文を自動的に繰り返し送信することができます。<%RepeatTX=...>コマンドには<%TX>、<%RX>コマンドの動作が含まれているので、これらのコマンドを定義する必要はありません(定義しても結果は変わらない)。 + 設定する時間は繰り返しの際の受信時間で単位はmsです。例えば5秒間受信したい場合は、<%RepeatTX=5000>を定義します。 + +※繰り返し送信中はそのボタンが押し込まれた状態になります。そのボタンをもう一度押すか、または別のマクロボタンを押すと繰り返し送信はキャンセルされます。 + +※スペクトラム、ウォーターフォール、受信画面、送信画面、TXOFFボタンをクリックしても、繰り返し送信はキャンセルされます。 + +※スケルチを監視して繰り返し送信を自動的に停止させるには、以下のようなマクロ文を使います。 + #define ReceiveTime 5000 + #if !IsSQ + <%RepeatTX=ReceiveTime><%ClearTXW> + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) K + #endif + + +※送信を行わずにマクロを繰り返し実行したい場合は、<%Repeat=...>コマンドを使います。例えば次のマクロ文は文字列"CQ"を受信するとメッセージボックスを表示します。 + + #define _CaptureString CQ + #if !IsRepeat + #macro <%SetCaptureLimit> + #endif + #if IsCaptureText(<%String=_CaptureString>) + #macro <%Message="<%String=_CaptureString>" was detected> + #else + #macro <%Repeat=1000> + #endif + + +7.プログラムの実行 +~~~~~~~~~~~~~~~~~~ + <%Execute=...>コマンドを実行すると、任意のプログラムを実行することができます。パラメータの部分は、プログラム名とそのアーギュメントで構成される文字列です。 + + 別のサウンドカードプログラムを実行する場合、先に<%Suspend>コマンドを実行してMMVARIが占有しているサウンドカードとCOMポートを解放しておきます。以下のマクロ文は私のシステムにインストールされているMMSSTVを起動する例です。 + + <%Suspend><%Execute=C:\MMSSTV\MMSSTV.exe> + + MMVARIを終了させてMMSSTVに切り替えるには、 + + <%Suspend><%Execute=C:\MMSSTV\MMSSTV.exe><%Exit> + +と記述します。 + +※プログラム名にフォルダ名を含むフルパス名を指定するとWindowsのPATH設定に関係なくそのプログラムを実行できます。 +※MMVARIをアクティブにするとサスペンドの解除を試みます。 + +8.条件展開 +~~~~~~~~~~ + マクロ文では条件展開を使うこともできます。条件展開とマクロコマンドを組み合わせると状況判断を伴うプログラムを作成することができます。条件展開の構文を以下に示します。 + + #if test1 条件ブロックを開始 + | <-- test1が真の時にここが展開 + #elseif test2 別の条件をテスト + | <-- test1が偽でtest2が真の時にここが展開 + #else 残りすべての条件で真 + | <-- 上記以外の時にここが展開 + #endif 条件ブロックを終了 + + 条件展開は次の規則に従います。 + + 1)条件ブロックは#ifで開始し#endifで終了しなければならない。 + 2)条件命令(#ifなど)とそのアーギュメント(test1など)は1行に記述し + 他のマクロコマンド等は同じ行に記述してはいけない。 + 3)#elseifおよび#elseは省略できる。 + 4)条件ブロック内の条件ブロックは64レベルまでネスト(入れ子に)できる。 + 5)アーギュメントの先頭にを記述してテスト結果の真偽を反転できる。 + 例: #if !IsCall Callボックスに文字が存在しない時に真 + 6)アーギュメントは次の3種類に分類できる。 + Is... 単項条件 + Str... 文字列条件 + Val... 数値条件 + + 7)単項条件(Is...)は、それだけで真偽を得ることができる。 + + 8)文字列条件(Str...)および数値条件(Val...)は、次の演算子を記述して + 値の大小関係により真偽を得る。 + == 等しい時に真 < 小さい時に真 + != 異なる時に真 >= 以上の時に真 + > 大きい時に真 <= 以下の時に真 + >> 文字列を含む場合に真(文字列条件の場合のみ) + 例:#if ValFreq >= 144 144MHz以上の時に真 + #if StrMacro(<%HisQTH>) >> 大阪 + QTHに「大阪」を含む場合に真 + 9)条件は<&&>または<||>を記述して複合できる。 + 例:#if IsNET && IsAFC NETとAFCが両方ONの時に真 + #if IsNET || IsAFC NETとAFCのいずれかがONの時に真 + + 例えば次のマクロ文では、ログパネルのCallボックスに文字が存在する時だけ相手局を呼び出します。 + + #if IsCall + <%TX><%RX> + <%HisCall> <%HisCall> de <%MyCall> <%MyCall> pse k + #endif + + 次のマクロ文は、相手局と自分のエンティティを比較して異なる言語のメッセージを送信します。 + + <%TX> + #if IsLocal + まいどです。コール有難うございます。 + #else + Hello, Thanks for your call. + #endif + + 次のマクロ文は、運用周波数によって変調方式を選択しCQを送信します。 + + #if ValFreq >= 144 + <%MODE=FSK><%SkipCR> + #else + <%MODE=GMSK><%SkipCR> + #endif + <%TX> + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> pse (<%VARITYPE>) k + <%RX> + + 次のマクロ文は文字列入力ウインドウをオープンし、そこで入力された文字列をCWで送信する例です。 + + #macro <%IME=OFF> + #if StrMacro(<%Input=Input CW text>) + <%TX><%RX><%CWID=<%Input$>><%EOF> + #endif + + スペクトラムまたはウォータフォールを右クリックすると表示されるポップアップメニューの「AS(CW)を送信」には、次のマクロ文がそのまま実装されています。このマクロ文では送信画面ページを切り替えることにより、送信画面で現在編集中の文書を失わないでASを送信できるようにプログラムされています。 + + <%DisableCR> + #if !IsTX + <%AutoNET><%AutoReturn> + #if ValPage!=4 + <%Page=4> + #else + <%Page=3> + #endif + <%ClearTXW> + #endif + <%TX><%CWID=@><%RX><%EOF> + +9.文字列変数 +~~~~~~~~~~~~ + マクロ文では文字列変数を使うこともできます。文字列変数は#defineで定義し、<%String=名前>コマンドで参照できます。また条件文のアーギュメントやマクロコマンドのパラメータとしても使用できます。 + + #define命令の構文を以下に示します。 + #define Name String + + Nameは先頭の文字が数字以外の文字で始まる任意の名前です。Stringは任意の文字列で、マクロコマンドや他の文字列変数を記述しても構いません。 + + 例 : #define Greetings まいどです... + #define NowSpeed <%BAUD> + #define ImaSpeed NowSpeed + +※#define命令で定義できる変数の個数に制限はありません。同じ名前に再定義する場合は、新しい文字列に置き換わります。 +※変数はマクロ間でグローバルです。したがって別のマクロボタンで定義した変数を参照することができます。 +※プログラムを終了するとすべての変数の内容は失われます。 +※#define命令はパス1で実行されます。 + + 次のマクロ文はWX情報を展開する例です。この例では最初に一度WXの文字列を入力すれば、次からはその文字列が(入力ウインドウを表示せずに)展開されます。 + + #if !IsDefined(TodayWX) || !StrMacro(<%String=TodayWX>) + #define TodayWX <%Input=WXを入力> + #endif + #if StrMacro(<%String=TodayWX>) + 本日のお天気は、<%String=TodayWX>です。 + #endif + + 次のマクロ文はマクロ文内でよく変更する箇所を、先頭に集めて定義した例です。 + + #define Boundary 14 + #define MyRIG FT1000MP(50W) + #define MyLANT Vertical(7m) + #define MyHANT Magnetic loop(90cm) + #if ValFreq < Boundary + #define MyANT MyLANT + #else + #define MyANT MyHANT + #endif + 私のリグは<%String=MyRIG>、アンテナは<%String=MyANT>です。 + + 次のマクロ文はNoteに記録しているJCC番号から運用場所のQTHを展開する例です。 + + #define QTH_HOME 大阪府高槻市 + #define QTH_25006 大阪府三島郡 + #define QTH_2701 兵庫県神戸市 + #if StrNote >> 25006 + #define MyQTH QTH_25006 + #elseif StrNote >> 2701 + #define MyQTH QTH_2701 + #else + #define MyQTH QTH_HOME + #endif + 私の現在のQTHは、<%String=MyQTH>です。 + +10.書式変換と計算式 +~~~~~~~~~~~~~~~~~~~ + <%Format=...>コマンドは書式指定による文字列変換と計算式の演算を同時に行うことができるマクロコマンドです。以下に構文を示します。 + <%Format=書式,演算式> + +--- 書式 ---- + C言語のprintf(...)の書式変換を完全に模倣します。書式変換の形式は次の通りです。[]内の記号は省略することができます。 + + %[-][#][0][w][.p]TYP + + - 左詰めを指定します。 + 0 フィールド幅を埋めるだけの0が出力値に付けられます。 + w 指定された最小文字数を出力バッファにコピーします。 + .p 指定された最小桁数を出力バッファにコピーします。 + TYP 以下の特別な文字で展開方法を指定します。 + + TYP 変数の型 展開 + c 文字 1文字 + s 文字列 指定された文字数の文字列 + d 整数 符号付き10進整数 + i 整数 符号付き10進整数 + o 整数 符号なし8進整数 + u 整数 符号なし10進整数 + x 整数 符号なし16進整数(a,b,c,d,e,f を使用) + X 整数 符号なし16進整数(A,B,C,D,E,F を使用) + f 浮動小数点数 符号付きの [-]dddd.dddd 形式の値 + e 浮動小数点数 符号付きの [-]d.dddd または e[+/-]ddd の値 + g 浮動小数点数 符号付きの e または f 形式の値 + E 浮動小数点数 e と同じで指数部を表す記号はEになる + G 浮動小数点数 g と同じで指数部を表す記号はEになる + +--- 演算式 --- + 演算式の変数として、数値、マクロコマンド、文字列変数が指定できます。マクロコマンドおよび文字列変数を演算する場合は、その展開結果を数値化します。利用できる演算子は次の通りです。 + + 加算 + - 減算 + * 乗算 + / 除算 + % 剰余算 + & AND + | OR + 演算の優先順位は一般的な数学の規則が適用され、また括弧記号()で演算の優先順位を変更できます。 + 10 + 20 * 30 = 610 + (10 + 20) * 30 = 900 + +--- 例 --- +<%BAUD=<%Format=%f,<%BAUD>*2>> + ボーレートを現在の倍の値に設定します。 +<%Format=%c,<%Skip$=1,<%HisRST>>> + HisRSTの2文字目の文字を展開します。(579 -> 7) +<%TxCarrier=<%Format=%d,<%RxCarrier>+100>> + 送信キャリア周波数を受信キャリア周波数より100Hz高く設定します。 + +11.ポップアップメニュー +~~~~~~~~~~~~~~~~~~~~~~~ + マクロ文では任意のポップアップメニューを作成することもできます。ポップアップメニューを使うと使用するマクロボタンの数を少なくできます。 + + ポップアップメニューは<%Menu=....>または、<%MenuB=...>コマンドで表示されます。選択されたメニューの文字列を得るには<%Input$>コマンドを使います。また選択されたメニューのインデクッス番号を条件子ValMenuでテストすることもできます。 + + メニュー項目はカンマ(,)で区切ります。1つの項目の文字列内にカンマが存在する場合はその文字列をダブル(")で括ります。文字列にはマクロを記述することもできます。メニュー項目の数に制限はありません。 + <%Menu=Menu1, Menu2, Menu3, Menu4, ...> + <%MenuB=Index, Menu1, Menu2, Menu3, Menu4, ...> + +※<%MenuB=...>コマンドはマーク付きメニューを表示し、指定したIndex(1〜)の項目の左側に黒丸が表示されます。 + + メニュー内にセパレータを記述する場合は、マイナス(-)だけをその項目の文字列として記述します。アクセスキーを設定する場合は、その文字の前にアンパサンド(&)を前置します。 + <%Menu=Menu&1, Menu&2, -, Menu&3, Menu&4, ...> + <%MenuB=Index1, Menu&1, Menu&2, -, Index2, Menu&3, Menu&4, ...> + + 次のマクロ文はファイナルメッセージのメニューを表示し、選択された文字列を送信ウインドウに展開します。 + <%Menu=<%DearName>まいどおおきに..., ほなさいなら..., "TNX AGN <%DearName>, 73..."><%Input$> + + メニューのインデックス番号(1〜)で動作を選択する場合、次のマクロ文のように条件子ValMenuを使います。この際、条件展開がパス1で実行されるので、<%Menu=...>も同じパスで実行されるように#macroを前置します。 + + #macro <%Menu=&73 CU SK, &TU SK EE, &SU, &EE> + #if ValMenu==1 + <%TX><%RX><%CWID=73CU:><%EOF> + #elseif ValMenu==2 + <%TX><%RX><%CWID=TU:EE><%EOF> + #elseif ValMenu==3 + <%TX><%RX><%CWID=SU><%EOF> + #elseif ValMenu==4 + <%TX><%RX><%CWID=EE><%EOF> + #endif + +※ポップアップメニューの選択がキャンセルされた場合、<%Input$>にはヌル文字列が入り、ValMenuは0を返します。 +※メニュー内にセパレータを定義しても、セパレータが選択されることはありません。またValMenuのインデックス番号はそのセパレータを含みません。 + + +12.マクロでのリグコントロール +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + MMVARIはマクロコマンドでのリグコントロールをサポートします。リグコントロールで使用する主なマクロコマンドを以下に示します。 + <%RadioKHz> VFOポーリングの周波数を得ます。 + <%RadioKHz=...> VFOの周波数を設定します。 + <%RadioMode> Rigのモードを得ます。 + <%RadioMode=...> Rigのモードを設定します。 + <%RadioOut=...> Rigに任意のコマンドを送信します。 + #if IsRadioLSB Rigのヘテロダインをテストします。 + + これらのコマンドは主にLAN経由でのリモート運用のために実装してありますが、Rig直結の場合でも便利な場合があります。 + +※これらのマクロを使用するには、少なくともリグコントロールのポート設定が完了していなければなりません。リグコントロールのポート設定がされていない場合、これらのマクロコマンドは無視されます。 +※および<%RadioMode>でVFO周波数やモードを得るには、通常はVFOポーリングも設定している必要があります。しかし<%RadioKHz=...>および<%RadioMode=...>でRigに周波数やモードを設定すると、VFOポーリングを設定していなくても、その設定した値を返します。 + +<%RadioKHz=RigType,RigFreq(KHz)> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + このコマンドは、RigのVFO周波数を設定します。サポートするRigTypeは以下の7種類です。 + RigType Rigの種類 + YAESU-VU FT847, FT736, ...etc + YAESU-HF FT1000MP, FT920,...etc + YAESU-NEW FT9000, FT2000, etc. + CI-V ICOM + CI-V4 ICOM (4 byte command) + KENWOOD KENWOOD + JST245 JRC JST245 + +※RigTypeがCI-Vの周波数設定は100MHz未満でも5バイトコマンドを送信します。もし旨く制御できない場合はRigTypeにCI-V4を使用して下さい。この場合4バイトコマンドを送信します。 + + 次のマクロ文は、入力ウインドウを表示し、Rigの周波数を設定します。 + #define _Rig YAESU-HF + #macro <%IME=OFF> + #if StrMacro(<%Input=Input VFO FREQ(KHz)>) + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001> + #else + #macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001> + #endif + #endif + + 次のマクロ文は、メニューを表示し、Rigの周波数を設定します。 + #define _Rig YAESU-VU + #macro <%Menu=7028.5,10141.5,14072.5,18102.5,21072.5,28072.5> + #if ValMenu + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%Input$>+<%RxCarrier>*0.001> + #else + #macro <%RadioKHz=_Rig,<%Input$>-<%RxCarrier>*0.001> + #endif + #endif + + 次のマクロ文は、RigのVFOを500Hzアップします。 + #define _Rig JST245 + #macro <%RadioKHz=_Rig,<%RadioKHz>+0.5> + + 次のマクロ文は現在の受信キャリア周波数を強制的に1750Hzにし、RigのVFO周波数をそこに合わせます(低いトーン周波数で運用するのを防止するために使います)。 + #define _Tone 1750 + #define _Rig CI-V + #define _OffKHz <%Format=%f,(<%RxCarrier>-_Tone)*0.001> + #if IsRadioLSB + #macro <%RadioKHz=_Rig,<%RadioKHz>-_OffKHz> + #else + #macro <%RadioKHz=_Rig,<%RadioKHz>+_OffKHz> + #endif + #macro <%RxCarrier=_Tone> + +<%RadioMode=RigType,RigMode> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + このコマンドは、Rigのモードを設定します。サポートするRigTypeは<%RadioKHz=...>と同じです。RigModeは以下の名前を受け付けます。 + LSB, USB, CW, AM, FM, RTTY, PACKET + + 例: <%RadioMode=KENWOOD,LSB> + +※Rigによって使用できないモードがあります。また特殊なモードを設定する場合は<%RadioOut=...>でラジオコマンドを直接出力して下さい。 + + 次のマクロ文は、選択メニューを表示し、Rigのモードを設定します。 + #define _Rig YAESU-VU + #define _t_Mode LSB,USB,CW,AM,FM,RTTY,PACKET + #macro <%MenuB="<%Table=<%RadioMode>,_t_Mode>",_t_Mode> + #if ValMenu + #macro <%RadioMode=_Rig,<%Input$>> + #endif + +<%RadioOut=文字列> +~~~~~~~~~~~~~~~~~~ + このコマンドは、Rigに任意のラジオコマンドを送信します。あらゆるRigに対して有効です。文字列には以下の特別なキーワードを使って$00〜$FFのすべてのデータを送信できます。 + \$##... ##=00-FF, 送信する複数バイトを16進数で定義する + (例:\$FE55AA -> $FE,$55,$AA) + xxを表記してICOM CI-VのRigアドレスに変換できます。 + \x## ##=00-FF, 送信する1バイトを16進数で定義する + (例:\xFE\x55\xAA -> $FE, $55, $AA) + \w## ##=00-99, ディレイ時間を10ms単位の10進数で定義する + (例:\w05 -> wait 50ms) + \r キャリッジリターンを送信する + \n ラインフィードを送信する + \c.... 以降はすべてコメント + \\ '\'文字を送信する + その他 その文字列をそのまま送信する + +※ラジオコマンドはRigによって異なります。Rigのマニュアルを参照して下さい。 + +[例] +YAESU FT1000MPのVFO-Aのフィルタを500Hzにします。 + <%RadioOut=\$020000008C> +ICOM IC-706のVFO A-Bを切り替えます。 + <%RadioOut=\$FEFExxE007BOFD> +KENWOODのVFO-Bの周波数を14.073MHzに設定します。 + <%RadioOut=FB00014073000;> +YAESU FT847のモードをCW(W)にします。 +(<%RadioMode=YAESU-VU,CW>ではCW(N)が設定されます) + <%RadioOut=\$0200000007> + +#if IsRadioLSB +~~~~~~~~~~~~~~ + リグのヘテロダイン状態をテストします。周波数オフセット計算を行う場合に使用します。MMVARIはすべてのRigで次のように判定します。 + 真偽 Rigのモード + TRUE LSB,RTTY,PACKET + FALSE その他のモード + + 通常この条件命令を使う場合は、リグコントロールでVFOポーリングを設定し、「モードによる周波数補正」を設定しておかなければなりません。しかしVFOポーリングを設定していない場合でも、<%RadioMode=...>でモードを設定すれば、その設定したモードで真偽を返します。 + +※RigのモードがLSB/USB以外の場合、Rigによってはヘテロダインを正しく認識できない場合があります。 +※Rigの本来のモードを得るには<%RadioMode>マクロを使います。 + + +13.イベントマクロ +~~~~~~~~~~~~~~~~~ + イベントマクロは、特定のイベントを検出した時に実行される特別なマクロです。以下のようなイベントが準備されています。 + OnTimer 約1秒間隔で繰り返し実行されます。 + OnPTT PTT状態が変化した時に実行されます。 + OnQSO QSOボタン状態が変化した時に実行されます。 + OnFind HisCallがセットされた時に実行されます。 + OnBand ログパネルのバンドが変更された時に実行されます。 + OnStart MMVARIの起動時に1回だけ実行されます。 + OnExit MMVARIの終了時に1回だけ実行されます。 + OnMode 変調方式が変更された時に実行されます。 + OnSpeed 伝送速度が変更された時に実行されます。 + OnClick 受信画面の文字列をクリックした時に実行されます。 + OnFFTScale FFTスケール(縦軸)を変更した時に実行されます。 + +[イベントマクロの設定] +~~~~~~~~~~~~~~~~~~~~~~ + イベントマクロは、「MMVARI設定画面」の「送信」タブのイベントマクロで編集することができます(編集するイベントを選択し、「編集」ボタンを押します)。またすべてのイベントマクロは、そのマクロ文をクリアすることにより、実行を停止することができます。 + + 次のマクロ文はOnTimerイベントマクロに記述し、AFC検出周波数をウォータフォールに表示します。 + <%WaterMsg=4,<%AFCFrequency>Hz> + + 次のマクロ文はOnQSOイベントマクロに記述し、QSOボタンを押した時に受信画面にステータスを表示する例です(受信画面のステータスは受信ログにも記録されます)。 + #if IsQSO + #macro <%RxStatus=LogON <%HisCall> on <%BAND>/<%MODE>> + #else + #macro <%RxStatus=LogOFF <%HisCall>> + #endif + + 次のマクロ文はOnModeイベントマクロに記述し、変調方式を変更した時に自動的にマクロボタンページを切り替えます。 + #if StrMode>>rtty + #macro <%SeekTop><%SeekNext> + #else + #macro <%SeekTop> + #endif + +[マクロコマンドによるイベントマクロの設定] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + すべてのイベントマクロは、次のようなマクロコマンドで他のマクロからその本文を設定することもできます。 + <%OnTimer=...> + <%OnPTT=...> + <%OnQSO=...> + <%OnFind=...> + <%OnBand=...> + <%OnStart=...> + <%OnExit=...> + <%OnMode=...> + <%OnSpeed=...> + <%OnClick=...> + <%OnFFTScale=...> + + 次のマクロ文は別のマクロボタンに記述し、OnTimerイベントマクロにマクロ文を設定する例です。 + <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>> + + 複数行のマクロ文を設定するには、次のように文の改行を\r\nで記述します。 + <%OnTimer=#if IsSQ\r\n#macro <%WaterMsg=4,<%AFCFrequency>Hz>\r\n#endif> + + 次のマクロ文はメニュー選択によりOnTimerイベントマクロの動作を切り替えます(このマクロ文はマクロボタンに定義します)。 + + #macro <%Menu=AFC, Metric(MFSK), RadioMode, WaterNoise, UTC, Local, -, Stop> + #if ValMenu == 1 + #macro <%OnTimer=<%WaterMsg=4,<%AFCFrequency>Hz>> + #elseif ValMenu == 2 + #macro <%OnTimer=<%WaterMsg=4,<%MetricMFSK>>> + #elseif ValMenu == 3 + #macro <%OnTimer=<%WaterMsg=4,<%RadioMode>>> + #elseif ValMenu == 4 + #macro <%OnTimer=<%WaterMsg=4,<%WaterNoise>dB>> + #elseif ValMenu == 5 + #macro <%OnTimer=<%WaterMsg=4,<%UTIME>z>> + #elseif ValMenu == 6 + #macro <%OnTimer=<%WaterMsg=4,<%LTIME>>> + #elseif ValMenu == 7 + #macro <%OnTimer=> + #endif + + 次のマクロ文はイベントマクロの編集メニューを作成した例です(このマクロ文はマクロボタンに定義します)。 + + #macro <%Menu=<%Events>> + #if ValMenu + #macro <%EditMacro=<%Input$>> + #endif + + +14.プロシジャー +~~~~~~~~~~~~~~~ + MMVARIはプロシジャー呼び出し機能を備えています。マクロ文内の頻繁にコーディングする部分をあらかじめプロシジャーに定義し、マクロ文内の任意の場所で何回でも呼び出して実行することができます。定義するプロシジャーの数に制限はありません。プロシジャーは拡張メニューのハンドラとしても使うことができます。 + +[プロシジャーの定義] +~~~~~~~~~~~~~~~~~~~~ + #proc 〜 #endpまでの行がプロシジャーとして定義されます。 + + #proc Name Dummy1, Dummy2... + | + #endp + + Nameは先頭が数字以外で始まるプロシジャーの名前です。 + Dummy1、Dummy2...は、ダミーと呼ばれるプロシジャー内だけで有効なシンボルです。プロシジャー内のダミーと同じ文字列は、呼び出し時に指定するアーギュメントに置き換えられます。ダミーは省略することができます。1つのプロシジャーに定義できるダミーは最大64個です。 + + プロシジャーの定義の例 + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +※ プロシジャーの定義中には、そのブロック内のすべての行は評価されません。それらが評価されるのは、そのプロシジャーが呼び出された時です。 + +※ ダミーは単純な文字列の置き換えです。したがってダミーの名前を長くするか、または@記号を名前に前置するなどして、予想外の文字列の置き換えを防止するのは良いアイデアです。 + +※ 定義したプロシジャーはMMVARIを終了するまで有効です。したがってOnStartイベントマクロ内にプロシジャーを定義しておくと、すべてのマクロ文内からそのプロシジャーを呼び出すことができます。また同じ名前のプロシジャーを再定義した場合は後で定義した内容が有効になります。 + + +[プロシジャーの呼び出し] +~~~~~~~~~~~~~~~~~~~~~~~~ + <%CallProc=Name,Arg1,Arg2...>マクロコマンドで呼び出します。 + Nameは#procで定義した名前です。 + Arg1、Arg2...は、#procで定義されているダミーを、これらのアーギュメントで置き換えます。ダミーとアーギュメントの数が一致しない場合、余分なダミーはすべてヌル文字列に置き換えられ、余分なアーギュメントはすべて無視されます。 + + プロシジャーの呼び出しの例 + <%CallProc=Slider, CW speed, CWSpeed, 10, 40> + <%CallProc=Slider, Digital output level, DigitalLevel, 1024, 32768, 1024> + <%CallProc=Slider, Play back speed, PlayBackSpeed, 1, 20> + +※ プロシジャーはパス1で定義されます。プロシジャーの呼び出し<%CallProc=...>は通常はパス2で実行されるため、マクロ文内でプロシジャーの定義が後に記述されていても構いません。しかし#macro命令で<%CallProc=...>を実行する場合(パス1で実行される)は、そのプロシジャーの定義を先に記述しておかなければなりません。 + +※ プロシジャーの再帰呼び出し(リカーシブコール)は許されますが、ネスト数が多くなるとスタックオーバーフローになります。無限ループに注意して下さい。以下に再帰呼び出しの簡単な例を示します。 + + <%DisableCR> + <%CallProc=Repeat, 3, CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall><%CR>> + <%BS> pse k...<%CR> + + #proc Repeat @N, @Text + <%DisableCR> + #define _RepCount <%Format=%d,@N-1> + #if _RepCount >= 0 + @Text + <%CallProc=Repeat, _RepCount, @Text> + #endif + #endp + +※ <%CallProc=...>を<%DebugProc=...>に置き換えると、送信画面にプロシジャーをそのまま展開します。これによってダミーの文字列の置き換えが正しく行われているかどうかを確認することができます。 + +[拡張メニューハンドラ] +~~~~~~~~~~~~~~~~~~~~~~ + 実はプロシジャーは拡張メニューのハンドラとして利用する場合にその真価を発揮します。拡張メニューを使うと、MMVARIのメインメニューやポップアップメニューを自分の好みで自由に拡張できます。拡張メニューは<%AddMenu=...>や<%InsertMenu=...>マクロコマンドで作成します。 + + <%AddMenu=Name, Caption, Procedure, Arg1, Arg2...> + <%InsertMenu=Name, InsPos, Caption, Procedure, Arg1, Arg2...> + + Name: メニューの名前, アクセスキー(&x)またはインデックス(1〜) + InsPos: 挿入位置のキャプション, アクセスキー(&x)またはインデックス(1〜) + Caption: メニューのキャプション, アクセスキー(&x)またはインデックス(1〜) + Procedure: ハンドラプロシジャーの名前 + Arg: ハンドラプロシジャーに渡すアーギュメント(省略可) + + 以下に簡単な拡張メニューの作成とそのハンドラプロシジャーの例を示します。通常このようなマクロ文はOnStartイベントマクロ内に記述しておきます。 + + <%DisableCR> + #define _Name 拡張(&X) + <%AddMenu=_Name, CWの速度(&C)..., Slider, CWの速度, CWSpeed, 10, 40> + <%AddMenu=_Name, デジタル出力レベル(&D)..., Slider, デジタル出力レベル, DigitalLevel, 1024, 32768, 1024> + <%AddMenu=_Name, -> + <%AddMenu=_Name, CQ DX(&1) (リピート), OnCQDXClick, 1, 3, 3, 4000> + <%AddMenu=_Name, CQ DX(&3) (リピート), OnCQDXClick, 3, 3, 3, 5000> + + #proc OnCQDXClick @Nline, @Ncq, @Ncall, @Interval + <%DisableCR><%ClearTXW><%AutoClear><%TX><%RX> + <%RepeatText=@Nline,<%RepeatText=@Ncq,CQ DX<%SP>>de<%RepeatText=@Ncall,<%SP><%MyCall>><%CR>> + <%BS><%SP>pse DX k<%CR><%RepeatTX=@Interval> + #endp + + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +※ 追加した拡張メニューのタイトルをクリックした場合、暗黙で以下のハンドラプロシジャーが呼び出されます(このハンドラプロシジャーの定義は必須ではありません)。 + On$xxxClick xxx = メニューの名前 (例: On$拡張(&X)Click) +※ メニューにアクセスキーを設定すると、すべてのメニューコマンド(<%DoMenu=...>, <%DeleteMenu=...>, <%AddMenu=...>など)でアクセスキーでメニューを特定できるようになります。同一メニュー内でアクセスキーが重複しないように注意して下さい。 + + <%AddMenu=...>や<%InsertMenu=...>は既存のメニューに項目を追加したり、既存のメニュー項目の動作をオーバーライドすることもできます。既存のメニューは名前やキャプションで指定するよりは、アクセスキーやインデックスで指定するほうが簡単です。以下に例を示します。 + + <%DisableCR> + #if !IsDefined(_fShellHelp) + #define _fShellHelp 0 + #endif + <%AddMenu=&E, -> + <%AddMenu=&E, AS(CW)マクロの編集(&A)..., OnCommand, <%EditMacro=AS(CW)>> + <%AddMenu=&E, OnStart イベントの編集(&O)..., OnCommand, <%OnStart>> + <%InsertMenu=&O, &B, デジタル出力レベル(&D)..., Slider, デジタル出力レベル, DigitalLevel, 1024, 32768, 1024> + <%InsertMenu=&O, &B, -> + <%AddMenu=&H, &P, OnShellEdit, project.txt, e, 1> + <%AddMenu=&H, &O, OnShellEdit, mmvari.txt, e, 1> + <%AddMenu=&H, &S, OnShellEdit, Samples.txt, , 3> + <%AddMenu=&H, &H, OnShellEdit, history.txt, e, 1> + <%InsertMenu=&H, &D, シェルの標準エディタを使う(&U), InvRegVal, _fShellHelp> + <%InsertMenu=&H, &D, -> + + #proc On$&HelpClick + <%DisableCR><%CheckMenu=&H, &U, _fShellHelp> + #endp + + #proc OnCommand @Command + <%DisableCR>@Command + #endp + + #proc OnInvVal @Value + <%DisableCR> + #DEFINE @Value <%Inv=@Value> + #endp + + #proc OnShellEdit @File, @Prifix, @Flag + <%DisableCR> + #if IsEnglish + #define _FileName <%Folder>@Prifix@File + #else + #define _FileName <%Folder>@File + #endif + #if _fShellHelp + <%Shell=_FileName> + #else + <%EditFile=_FileName, @Flag> + #endif + #endp + + #proc Slider @Title, @Command, @Min, @Max, @Step, @NumScales + <%DisableCR> + #macro <%Slider=@Title, <%@Command>, @Min, @Max, @Step, @NumScales> + #if StrMacro(<%Input$>) + <%@Command=<%Input$>> + #endif + #endp + +※ 既存のポップアップメニューは以下の名前で定義されています。 + + PopWATER スペクトラム、ウォーターフォールで右クリックした時のメニュー + PopSQ レベルインディケータ上で右クリックした時のメニュー + PopRXW 受信画面で右クリックした時のメニュー + PopRX 受信画面の文字上で右クリックした時のメニュー + PopTX 送信画面で右クリックした時のメニュー + PopPAGE ステータスバーのPage枠で右クリックした時のメニュー + PopCHARSET ステータスバーの言語種別欄で右クリックした時のメニュー + PopCALLS CallBox右横のボタンを押した時のメニュー + +※ サブメニューを持つメニュー項目はオーバーライドできません。 +※ メニューを挿入するとインデックス番号は変化します。既存のメニューはアクセスキーで指定するほうが良いでしょう。 +※ 既存のメニューのタイトルをクリックした場合、暗黙で以下のハンドラプロシジャーが呼び出されます(これらのハンドラプロシジャーの定義は必須ではありません)。 + On$&FileClick, On$&EditClick, On$&ViewClick, On$&OptionsClick, + OnRadio&CommandClick, On$&HelpClick +※ 既存のポップアップメニューがポップアップした場合、暗黙で以下のハンドラプロシジャーが呼び出されます(これらのハンドラプロシジャーの定義は必須ではありません)。 + On$PopWATERClick, On$PopSQClick, On$PopRXWClick, On$PopRXClick, + On$PopTXClick, On$PopPAGEClick, On$PopCHARASETClick, On$PopCALLSClick, + + +[反復ブロック] +~~~~~~~~~~~~~~ + #repeat〜#endpまでを反復ブロックと呼びます。反復ブロックは特別なプロシジャーとして定義されます。そして#endp命令をデコードした直後にそのプロシジャーを式の回数だけ繰り返し呼び出します(反復ブロック内のマクロ文はパス1で実行されます)。式の結果が0の場合反復ブロックは実行されません。 + #repeat 式 + | + #endp + +※ 反復ブロック内では、反復回数=$repeatと、カウンタ(1〜)=$counterという2つのダミーが暗黙に定義されます。 + + #repeat 3 + CQ CQ CQ de <%MyCall> <%MyCall> <%MyCall> (<%Format=%d, 1 + $repeat - $counter>) + #endp + +※ 反復ブロックがネストしている場合、$repeatと$counterは、ブロックの内側と外側で区別されます。 + + #repeat 3 + <%DisableCR>Outside=($counter/$repeat)[ + #repeat 2 + <%DisableCR> + #if $counter > 1 + , + #endif + Inside=($counter/$repeat) + #endp + ]<%CR> + #endp + + +====================== +◎サウンドプレーバック +====================== + 「MMARI設定画面」の「受信」タブの「サウンドプレーバックを有効にする」をONにすると、メイン画面左上に60/30/15のボタンが表示されます。これらのボタンを押すと、サウンドプレーバックを実行します。 + + 60 60秒前からプレーバック + 30 30秒前からプレーバック + 15 15秒前からプレーバック + + サウンドプレーバックは次のような場合に使います。 + - 誰かに呼ばれたが、AFCが間に合わずコールサインが判らない + - 誰かが出ていたが、モード切り替えが間に合わずコールサインが判らない + + サウンドプレーバックを使うと、同じ信号を何度も受信しなおす事ができます。例えばmfskのようなAFCの応答が遅いモードでは、fズレしている局の短いコールを受信しても復調できない場合があります。しかしサウンドプレーバックをそのまま1回または2回実行することにより、AFCが継続的に働き復調できるようになります。 + + 「サウンドプレーバックを有効にする」の右側に表示されるスライダを使って、サウンドプレーバックの速度をx1〜x20の範囲で設定できます。CPUパワーが不足している場合は速くしてもその通りの再生速度が得られず、プレーバックが終了するまで他の操作ができなくなる場合があります。デフォルトはx5(15秒のサウンドを3秒で再生)です。 + + サウンドプレーバックは常に最新の受信サウンド60秒分をPCM形式でメモリに保存しています。例えばサウンドカードクロック11025Hzの場合は約1.3MBのメモリを使います。 + + +================ +◎サウンドカード +================ + サウンドカードについては、「設定画面」その他タブに設定項目があります。 + +(1)Fifo - RX +~~~~~~~~~~~~ + 受信サウンドが頻繁に途切れる場合、数値を大きくして下さい。 + +(2)Fifo - TX +~~~~~~~~~~~~ + 送信サウンドが頻繁に途切れる場合、数値を大きくして下さい。しかしあまり大きくするとキー操作に対して送信音の遅れが大きくなります。 + +(3)DeviceID +~~~~~~~~~~~ + 複数のサウンドカードがインストールされている場合、そのDeviceID(0から順番で割り当てられている)を設定して下さい。-1はデフォルトのカードを使うことを意味しています。 + サウンドデバイスとしてMMTTY、MMSSTV用のカスタムサウンドを選択することもできます。カスタムサウンドを利用する場合はmmwファイルをMMVARIがインストールされているフォルダ内にコピーして下さい(DeviceIDの一覧にその名前が表示されるのでそれを選択します)。 + +※送受で異なるカードを使用する場合は、0,1のように受信、送信の順でDeviceIDをカンマで区切って設定します。 + +※カスタムサウンドの詳細はMMTTY/MMSSTV用のカスタムサウンドのサンプル「MM-WaveLink」パッケージ内の「JReadme.txt」および「JMMW.txt」を参照して下さい。 + +(4)処理の優先順位 +~~~~~~~~~~~~~~~~~ + 送受信サウンドが途切れがちな場合、優先順位を高くすると改善する場合があります。 + +(5)入力チャンネル +~~~~~~~~~~~~~~~~~ + サウンドカード入力をモノラル、またはステレオのどのチャンネルから行うかを設定します。出力はステレオが選択されていても、常に左右両方に出力されます。 + +(6)Clock - RX +~~~~~~~~~~~~~ + 受信サンプリング周波数を設定します。現状のMMVARIは次のクロック系をサポートします。デフォルトは11025Hz系です。 + + 11025Hz系 サウンドカード標準周波数の1つ。すべてのカードで動作する。 + 12000Hz系 すべてのカードで動作する訳ではないが、 + TxOffset(送受での周波数ズレ)が発生しない可能性が高い。 + 6000Hz系 すべてのカードで動作する訳ではないがCPU負荷は軽い。 + 8000Hz系 特にメリットなし。 + 18000Hz系 特にメリットなし。 + 22050Hz系 サウンドカード標準周波数の1つ。特にメリットなし。 + 24000Hz系 特にメリットなし。 + 44100Hz系 サウンドカード標準周波数の1つ。特にメリットなし。 + 48000Hz系 光デジタルI/F用。 + +※11100Hzの選択が一覧に存在しますが、この周波数は11025Hz系クロックのクロックズレを補正した(代表的な...)値の1つで、サウンドカードは11025Hz系で動作します。 + +※遅いパソコンで動作させる場合は、6000Hz系クロックを選択されると良いかも知れません。 + +※8000Hz系はFFT点数の関係で、スペクトラムおよびウォータフォールの表示が少し遅くなります。 + +(7)Clock - TxOffset +~~~~~~~~~~~~~~~~~~~ + 送信サンプリング周波数を、RX値に対するオフセット値で設定します。送受で周波数がズレる場合にこの値を設定する必要があります。詳細は「クロック補正」を参照して下さい。 + + 送信サンプリング周波数 = RX + TxOffset [Hz] + +============== +◎クロック補正 +============== + サウンドカードのクロックズレについてはSSTVのように神経を使う必要はありません。しかし送受で大きくズレている場合、送信キャリア周波数と受信キャリア周波数が一致しなくなり不便ですし、タイミング(ボーレート)のズレも発生してしまいます。 + +※MMVARIのクロック補正とは、「設定画面」その他タブの左下部分にあるClock-RX値とTxOffset値の2つの値を設定する操作です。この2つの値さえ正しく設定すれば、あらゆるサウンドカードのクロックズレに完全に対応することができます。 + +1.MMSSTVを利用する場合 +~~~~~~~~~~~~~~~~~~~~~~ + MMSSTVのクロック値およびTxOffset値は、MMVARIにそのまま適用できます。したがって正しい方法で校正したMMSSTVの値をそのままMMVARIに設定するのが最も簡単で正確な方法です。この場合、これ以降の操作は一切必要ありません。 + +※MMSSTVの「自動傾き調整」をOFFにし、送受信の画像がいずれも傾かない状態になっている場合に限り、MMSSTVは正しく校正されていると言えます。 + +2.まず受信クロックを合わせる +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + オプションメニューの「サウンドカードのクロック校正」を選択すると、「サウンドカードの受信クロック値の校正」画面が表示されますので、その画面に表示されている手順を実行します。この校正操作には現在、東アジア地域全般で受信可能なBPM標準電波放送を利用します。 + + この画面では受信クロック(Clock-RX)値しか校正できません。TxOffset値の校正については次の項(3)を参照して下さい。 + +3.TxOffsetの校正 +~~~~~~~~~~~~~~~~ + 「設定画面」送信タブを開き、「外部ループバック(衛星通信用)」を選択し、サウンドカードの入力と出力を線で接続します。要は自分が送信した信号をサウンドカードを経由して自分で受信できるようにすれば良いので、線で接続しなくてもサウンド入力ボリュームの調整画面を開き、入力を「ライン」から「ステレオミキサー」または「モノラルミキサー」に変更しても構いません。 + + MMVARIメイン画面で、以下の操作を行います。 + + 1) NET=OFF, AFC=ON, ATC=ON + 2) 送信画面をクリア(アイドル信号が最も計測条件が良いため) + 3) TXボタンを押し送信状態にする(Rigの電源は切っておくこと) + 4) スペクトラムで受信周波数を合わせる + (サウンドカードにTxOffsetが存在する場合、必ず送受で周波数がズレます) + + この状態で十分に時間が経過すると、ATCタイミングの値の変化が落ち着きますので、ATCタイミングの枠の部分にマウスを移動し、そのとき最下段ステータスバーに表示されるRxOffset[Hz]を現在のTxOffset[Hz]から減算します。 + + 新しいTxOffset = 現在のTxOffset - RxOffset [Hz] + + 例えば、現在のTxOffsetが0で、RxOffsetが-74.40と表示された場合は、74.40を新しいTxOffset値にします。 + + TxOffsetを設定した後、もう一度送信してみて、送受での周波数のズレや、ATCタイミングの大きなズレがない事を確認しておくと良いでしょう。SSTVでは精度を得るために上記の操作を2回繰り返しますが、MMVARIではその必要はありません。 + + 以上で校正操作は終了です。最後に「設定画面」送信タブを開き、「内部ループバック」に戻しておきます。 + +4.TxOffsetの簡易校正 +~~~~~~~~~~~~~~~~~~~~ + (3)をやるのがメンドウな場合は、とりあえずTxOffsetを0にして送信し、相手局から十分に時間が経過した後のATCタイミングのズレ(RxOffset[Hz])を教えてもらって、その符号を逆にした値を自分のTxOffsetに設定しても構いません。もちろんこの場合、相手局の受信クロックが概ね正確である事が確認されている必要があります。 + +================ +◎VARICODEの名称 +================ + MMVARIでは便宜上以下のようにVARICODEの名称を定義しており、<%VARITYPE>マクロコマンドでは以下の表記が自動的に展開されます。 + + VariSTD 標準(PSK31)のVARICODE(256種類) + VariMFSK 標準(MFSK)のVARICODE(256種類) + VariJA 日本語用VARICODE(12160種類) + VariHL 韓国語用VARICODE(24448種類) + VariBV 中国語(BV)用VARICODE(24448種類) + VariBY 中国語(BY)用VARICODE(24448種類) + + 従来方式---標準VARICODEでMBCSを2文字連結で伝送する方式---の場合、受信画面で選択されている言語に従って、"VariSTD/JA", "VariSTD/HL"のように表記します。以下に変調方式と<%VARITYPE>の関係を示します。 + + GMSK VariJA, VariHL, VariBV, VariBY + FSK VariJA, VariHL, VariBV, VariBY + BPSK VariJA, VariHL, VariBV, VariBY + bpsk VariSTD/JA, VariSTD/HL, VariSTD/BV, VariSTD/BY + mfsk VariMFSK/JA, VariMFSK/HL, VariMFSK/BV, VariMFSK/BY + +※受信画面で選択されている言語によって<%VARITYPE>は異なります。またSBCS言語が選択されている場合、いずれの変調方式でも"VariSTD"または"VariMFSK"になります。 + +※bpskの場合の"VariSTD/JA"という表記は一般的ではありませんので、たとえば以下のマクロ文のように単に"Japanese"と展開すると良いかも知れません。 + + RRR <%HisCall> de <%MyCall> + #if IsLocal + #if StrVARITYPE == STD/JA + --- Japanese --- + #else + --- <%VARITYPE> --- + #endif + #endif + +73, Mako JE3HHT diff --git a/mmw.h b/mmw.h new file mode 100644 index 0000000..9a39cbf --- /dev/null +++ b/mmw.h @@ -0,0 +1,46 @@ +//Copyright+LGPL + +//----------------------------------------------------------------------------------------------------------------------------------------------- +// Copyright 2000-2013 Makoto Mori, Nobuyuki Oba +//----------------------------------------------------------------------------------------------------------------------------------------------- +// This file is part of MMVARI. + +// MMVARI is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License +// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +// MMVARI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + +// You should have received a copy of the GNU Lesser General Public License along with MMTTY. If not, see +// . +//----------------------------------------------------------------------------------------------------------------------------------------------- + + + +#ifndef MMW_H +#define MMW_H + +typedef void (__stdcall *tmmwPumpMessages)(void); +typedef LONG (__stdcall *tmmwGetTimeout)(void); +typedef void (__stdcall *tmmwSetPTT)(LONG tx); + +typedef LONG (__stdcall *tmmwInOpen)(DWORD sampfreq, DWORD size); +typedef void (__stdcall *tmmwInClose)(void); +typedef BOOL (__stdcall *tmmwInRead)(SHORT *buf); + +typedef LONG (__stdcall *tmmwGetInExist)(void); +typedef BOOL (__stdcall *tmmwIsInCritical)(void); + +typedef LONG (__stdcall *tmmwOutOpen)(DWORD sampfreq, DWORD size); +typedef void (__stdcall *tmmwOutAbort)(void); +typedef void (__stdcall *tmmwOutFlush)(void); +typedef BOOL (__stdcall *tmmwOutWrite)(const SHORT *buf); + +typedef BOOL (__stdcall *tmmwIsOutCritical)(void); +typedef BOOL (__stdcall *tmmwIsOutFull)(void); +typedef LONG (__stdcall *tmmwGetOutRemaining)(void); +typedef LONG (__stdcall *tmmwGetOutCounter)(void); +typedef void (__stdcall *tmmwSetOutCounter)(LONG count); + +#endif + diff --git a/res/App.ico b/res/App.ico new file mode 100644 index 0000000..9f8ccd8 Binary files /dev/null and b/res/App.ico differ diff --git a/res/SBBPFM.bmp b/res/SBBPFM.bmp new file mode 100644 index 0000000..b2b9ec1 Binary files /dev/null and b/res/SBBPFM.bmp differ diff --git a/res/SBBPFN.bmp b/res/SBBPFN.bmp new file mode 100644 index 0000000..4f907ab Binary files /dev/null and b/res/SBBPFN.bmp differ diff --git a/res/SBBPFS.bmp b/res/SBBPFS.bmp new file mode 100644 index 0000000..1564983 Binary files /dev/null and b/res/SBBPFS.bmp differ diff --git a/res/SBBPFW.bmp b/res/SBBPFW.bmp new file mode 100644 index 0000000..1a18881 Binary files /dev/null and b/res/SBBPFW.bmp differ diff --git a/temp.txt b/temp.txt new file mode 100644 index 0000000..6c2c73b --- /dev/null +++ b/temp.txt @@ -0,0 +1,1220 @@ +#include +#pragma hdrstop + +#include +#include "Wave.h" +#include "dsp.h" +#include "ComLib.h" + +//--------------------------------------------------------------------------- +// 初期化 +__fastcall CWave::CWave(void) +{ + m_Error = 0; + m_InOpen = m_OutOpen = FALSE; + m_hin = NULL; + m_hout = NULL; + m_InEvent = NULL; + m_OutEvent = NULL; + for( int i = 0; i < WAVE_FIFO_MAX; i++ ){ + m_pInBuff[i] = m_pOutBuff[i] = NULL; + } + m_pOutBase = m_pInBase = NULL; + m_SoundTxID = m_SoundID = -1; + m_InBuffSize = 1024; + m_OutBuffSize = 1024; + m_OutFirst = FALSE; + m_InFifoSize = 12; + m_OutFifoSize = 6; + m_SoundStereo = 0; + m_pDLL = NULL; + m_fPTT = FALSE; + ::InitializeCriticalSection(&m_InCS); + ::InitializeCriticalSection(&m_OutCS); +} + +//--------------------------------------------------------------------------- +// 終了時実行ルーチン +__fastcall CWave::~CWave() +{ + ::DeleteCriticalSection(&m_InCS); + ::DeleteCriticalSection(&m_OutCS); + if( m_pDLL ){ + delete m_pDLL; + m_pDLL = NULL; + } +} +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +void __fastcall CWave::GetInDevName(AnsiString &as) +{ + int id = m_SoundID; + if( id == -2 ){ + as = sys.m_SoundMMW + " (MM Custom sound)"; + return; + } + GetDeviceList(); + if( (id < 0) || (id >= AN(m_tInDevName)) ) id = 0; + as = m_tInDevName[id]; +} +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +void __fastcall CWave::GetOutDevName(AnsiString &as) +{ + int id = m_SoundID; + if( id == -2 ){ + as = sys.m_SoundMMW + " (MM Custom sound)"; + return; + } + GetDeviceList(); + id = m_SoundTxID; + if( (id < 0) || (id >= AN(m_tOutDevName)) ) id = 0; + as = m_tOutDevName[id]; +} +#if 0 +//--------------------------------------------------------------------------- +// サウンドカードの問い合わせ +BOOL __fastcall CWave::IsFormatSupported(LPWAVEFORMATEX pWFX, UINT IDDevice) +{ + return (::waveOutOpen( + NULL, // ptr can be NULL for query + IDDevice, // the device identifier + pWFX, // defines requested format + NULL, // no callback + NULL, // no instance data + WAVE_FORMAT_QUERY // query only, do not open device + ) ? FALSE : TRUE); +} +#endif +//--------------------------------------------------------------------------- +// サウンドカードの入力でのオープン +// WFX.wFormatTag = WAVE_FORMAT_PCM; +// WFX.nChannels = 1; +// WFX.wBitsPerSample = 16; +// WFX.nSamplesPerSec = 11025; +// WFX.nBlockAlign = WORD(WFX.nChannels *(WFX.wBitsPerSample/8)); +// WFX.nAvgBytesPerSec = WFX.nBlockAlign * WFX.nSamplesPerSec; +// WFX.cbSize = 0; +BOOL __fastcall CWave::InOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size) +{ + if( m_pDLL ){ + m_InOpen = m_pDLL->InOpen(pWFX->nSamplesPerSec, Size); + if( !m_InOpen ) PumpMessages(); + return m_InOpen; + } + int i; + + if( m_InOpen ) InClose(); + m_Error = 0; + m_InWait = m_InOver = FALSE; + m_InWP = m_InRP = m_InBC = 0; + m_IWFX = *pWFX; + m_InLen = Size; + m_InBuffSize = Size * (m_IWFX.wBitsPerSample/8) * m_IWFX.nChannels; + m_InMemSize = sizeof(WAVEHDR) + m_InBuffSize; + if( m_InMemSize & 3 ) m_InMemSize += 4 - (m_InMemSize & 3); + m_InAllocSize = m_InMemSize * m_InFifoSize; + m_InEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + // サウンドカードのオープン + if( (m_Error = ::waveInOpen( &m_hin, IDDevice, pWFX, (DWORD)WaveInProc, (DWORD)this, CALLBACK_FUNCTION ) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + // バッファの準備 + m_pInBase = new char[m_InAllocSize]; + ::VirtualLock(m_pInBase, m_InAllocSize); + memset(m_pInBase, 0, m_InAllocSize); + LPSTR p = m_pInBase; + for( i=0; i < m_InFifoSize; i++, p += m_InMemSize ){ + m_pInBuff[i] = (WAVEHDR *)p; + ((WAVEHDR *)p)->dwBufferLength = m_InBuffSize; + ((WAVEHDR *)p)->dwFlags = 0; + ((WAVEHDR *)p)->dwUser = NULL; + ((WAVEHDR *)p)->dwBytesRecorded = NULL; + ((WAVEHDR *)p)->lpData = p + sizeof(WAVEHDR); + if( (m_Error = ::waveInPrepareHeader(m_hin, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + if( (m_Error = ::waveInAddBuffer(m_hin, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + } + // 取りこみの開始 + if( (m_Error = ::waveInStart(m_hin) ) != MMSYSERR_NOERROR ){ + InClose(); + return FALSE; + } + m_InOpen = TRUE; + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CWave::InClose() +{ + if( m_pDLL ){ + m_pDLL->InClose(); + m_InOpen = FALSE; + PumpMessages(); + return; + } + int i; + + if(NULL != m_hin){ + ::waveInReset(m_hin); + if( m_pInBase != NULL ){ + for( i=0; i < m_InFifoSize; i++ ){ + if( m_pInBuff[i] != NULL ){ + if( m_pInBuff[i]->dwFlags & WHDR_PREPARED ){ + ::waveInUnprepareHeader(m_hin, m_pInBuff[i], sizeof(WAVEHDR)); + } + } + } + } + ::waveInClose(m_hin); + m_hin = NULL; + if( m_pInBase != NULL ){ + ::VirtualUnlock(m_pInBase, m_InAllocSize); + delete m_pInBase; + m_pInBase = NULL; + } + } + if(m_InEvent != NULL){ + ::CloseHandle(m_InEvent); + m_InEvent = NULL; + } + m_InOpen = FALSE; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::InRead(SHORT *pData) +{ + if( m_pDLL ){ + return m_pDLL->InRead(pData); + } + int Len = m_InLen; + int i; + + if( !m_InOpen ){ + m_Error = 1; + return FALSE; + } + if( m_InOver ){ + m_Error = 1; + InClose(); + return FALSE; + } + + ::EnterCriticalSection(&m_InCS); + if( !m_InBC ){ // まだデータが存在しない時 + m_InWait++; + ::LeaveCriticalSection(&m_InCS); + // バッファにデータが溜まるまで待つ + if( ::WaitForSingleObject( m_InEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 1; + InClose(); + return FALSE; + } + } + else { + ::LeaveCriticalSection(&m_InCS); + } + // データを浮動少数点に変換 + LPWAVEHDR hp = m_pInBuff[m_InRP]; + SHORT *rp = (SHORT *)hp->lpData; + if( m_IWFX.nChannels == 2 ){ + if( m_SoundStereo == 1 ){ // Left + for( i = 0; i < Len; i++ ){ + *pData++ = *rp++; + rp++; + } + } + else { // Right + for( i = 0; i < Len; i++ ){ + rp++; + *pData++ = *rp++; + } + } + } + else { + memcpy(pData, rp, sizeof(SHORT) * Len); + } + hp->dwBytesRecorded = NULL; + ::waveInAddBuffer(m_hin, hp, sizeof(WAVEHDR)); + m_InBC--; // 1命令で展開されるので CriticalSection は不要 + m_InRP++; + if( m_InRP >= m_InFifoSize){ + m_InRP = 0; + } + return TRUE; +} +//--------------------------------------------------------------------------- +//void CALLBACK WaveProc(hWave, uMsg, dwInstance, dwParam1, dwParam2) +// +//HWAVE hWave; /* ウェーブフォーム デバイスのハンドル */ +//UINT uMsg; /* 送るメッセージ */ +//DWORD dwInstance; /* インスタンス データ */ +//DWORD dwParam1; /* アプリケーション定義のパラメータ */ +//DWORD dwParam2; /* アプリケーション定義のパラメータ */ +void CALLBACK WaveInProc(HWAVE m_hin, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ) +{ + if( uMsg == MM_WIM_DATA ){ + ::EnterCriticalSection(&pWave->m_InCS); + pWave->m_InBC++; + pWave->m_InWP++; + if( pWave->m_InWP >= pWave->m_InFifoSize ) pWave->m_InWP = 0; + if( pWave->m_InBC > pWave->m_InFifoSize ) pWave->m_InOver = TRUE; + if(pWave->m_InWait){ + pWave->m_InWait--; + ::SetEvent(pWave->m_InEvent); + } + ::LeaveCriticalSection(&pWave->m_InCS); + ::PostMessage(pWave->m_hWnd, WM_WAVE, waveIN, 0); + } +} +//--------------------------------------------------------------------------- +// サウンドカードの出力でのオープン +// WFX.wFormatTag = WAVE_FORMAT_PCM; +// WFX.nChannels = 1; +// WFX.wBitsPerSample = 16; +// WFX.nSamplesPerSec = 11025; +// WFX.nBlockAlign = WORD(WFX.nChannels *(WFX.wBitsPerSample/8)); +// WFX.nAvgBytesPerSec = WFX.nBlockAlign * WFX.nSamplesPerSec; +// WFX.cbSize = 0; +BOOL __fastcall CWave::OutOpen(LPWAVEFORMATEX pWFX, UINT IDDevice, DWORD Size) +{ + if( m_pDLL ){ + m_OutOpen = m_pDLL->OutOpen(pWFX->nSamplesPerSec, Size); + if( !m_OutOpen ) PumpMessages(); + return m_OutOpen; + } + if( m_OutOpen ) OutAbort(); + m_Error = 0; + m_OutBCC = 0x7fffffff; + m_OutWait = FALSE; + m_OutUnder = FALSE; + m_OutWP = m_OutRP = m_OutBC = 0; + m_OWFX = *pWFX; + m_OutLen = Size; + m_OutBuffSize = Size * (m_OWFX.wBitsPerSample/8) * m_OWFX.nChannels; + m_OutMemSize = sizeof(WAVEHDR) + m_OutBuffSize; + if( m_OutMemSize & 3 ) m_OutMemSize += 4 - (m_OutMemSize & 3); + m_OutAllocSize = m_OutMemSize * m_OutFifoSize; + m_OutEvent = ::CreateEvent(NULL, FALSE,FALSE,NULL); + if( (m_Error = ::waveOutOpen( &m_hout, IDDevice , pWFX, (DWORD)WaveOutProc, (DWORD)this, CALLBACK_FUNCTION ) ) != MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + if( (m_Error = ::waveOutPause(m_hout))!= MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + // バッファーの準備 + m_pOutBase = new char[m_OutAllocSize]; + ::VirtualLock(m_pOutBase, m_OutAllocSize); + memset(m_pOutBase, 0, m_OutAllocSize); + LPSTR p = m_pOutBase; + for(int i = 0; i < m_OutFifoSize; i++, p += m_OutMemSize ){ + m_pOutBuff[i] = (WAVEHDR *)p; + ((WAVEHDR *)p)->dwBufferLength = m_OutBuffSize; + ((WAVEHDR *)p)->dwFlags = 0; + ((WAVEHDR *)p)->dwUser = NULL; + ((WAVEHDR *)p)->dwLoops = NULL; + ((WAVEHDR *)p)->lpData = p + sizeof(WAVEHDR); + if( (m_Error = ::waveOutPrepareHeader(m_hout, (WAVEHDR *)p, sizeof(WAVEHDR)) ) != MMSYSERR_NOERROR ){ + OutAbort(); + return FALSE; + } + } + m_OutOpen = TRUE; + m_OutFirst = TRUE; + return TRUE; +} +#if 0 +//--------------------------------------------------------------------------- +DWORD __fastcall CWave::GetOutVolume(void) +{ + if( !m_OutOpen ){ + return 0x8000; + } + DWORD vol; + ::waveOutGetVolume(m_hout, &vol); + return vol; +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::SetOutVolume(DWORD vol) +{ + if( !m_OutOpen ){ + return FALSE; + } + ::waveOutSetVolume(m_hout, vol); + return TRUE; +} +#endif +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::OutWrite(const SHORT *pData) +{ + if( m_pDLL ){ + return m_pDLL->OutWrite(pData); + } + int Len = m_OutLen; + int i; + if( !m_OutOpen ){ + m_Error = 1; + return FALSE; + } + if( m_OutUnder ){ + m_Error = 1; + OutClose(); + return FALSE; + } + + // 送信バッファ空き待ち + EnterCriticalSection(&m_OutCS); + if( m_OutBC >= m_OutFifoSize ){ + m_OutWait++; + ::LeaveCriticalSection(&m_OutCS); + if( ::WaitForSingleObject( m_OutEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 2; + OutAbort(); + return FALSE; + } + } + else { + ::LeaveCriticalSection(&m_OutCS); + } + + // データの変換 + LPWAVEHDR hp = m_pOutBuff[m_OutWP]; + SHORT *wp = (SHORT *)hp->lpData; + if( m_OWFX.nChannels == 2 ){ + for( i = 0; i < Len; i++ ){ + *wp++ = *pData; + *wp++ = *pData++; + } + } + else { + memcpy(wp, pData, sizeof(SHORT)*Len); + } + ::waveOutWrite(m_hout, hp, sizeof(WAVEHDR) ); + m_OutBC++; // 1命令で展開されるので CriticalSection は不要 + if( m_OutFirst ){ + if( (m_OutBC >= 8) || (m_OutBC >= (m_OutFifoSize-1)) ){ + m_OutFirst = FALSE; + ::waveOutRestart( m_hout ); + } + } + m_OutWP++; + if( m_OutWP >= m_OutFifoSize){ + m_OutWP = 0; + } + return TRUE; +} +//--------------------------------------------------------------------------- +void __fastcall CWave::OutFlush() +{ + if( m_pDLL ){ + m_pDLL->OutFlush(); + return; + } + if(m_hout != NULL){ + // バッファ送信待ち + while(1){ + ::EnterCriticalSection(&m_OutCS); + if( m_OutBC > 0 ){ // 未送出データが存在する場合 + m_OutWait++; + ::LeaveCriticalSection(&m_OutCS); + if( ::WaitForSingleObject( m_OutEvent, WAVE_TIMEOUT_EVENT ) != WAIT_OBJECT_0 ){ + m_Error = 2; + break; + } + } + else { + ::LeaveCriticalSection(&m_OutCS); + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::OutAbort() +{ + if( m_pDLL ){ + m_pDLL->OutAbort(); + m_OutOpen = FALSE; + PumpMessages(); + return; + } + if(m_hout != NULL){ + ::waveOutReset(m_hout); + ::Sleep(1); // for the timing + // バッファの解放 + if( m_pOutBase != NULL ){ + for(int i = 0; i < m_OutFifoSize; i++ ){ + if( m_pOutBuff[i] != NULL ){ + if( m_pOutBuff[i]->dwFlags & WHDR_PREPARED ){ + ::waveOutUnprepareHeader(m_hout, m_pOutBuff[i], sizeof(WAVEHDR)); + } + } + } + } + ::waveOutClose(m_hout); + m_hout = NULL; + if( m_pOutBase != NULL ){ + ::VirtualUnlock(m_pOutBase, m_OutAllocSize); + delete m_pOutBase; + m_pOutBase = NULL; + } + } + if(m_OutEvent != NULL){ + ::CloseHandle(m_OutEvent); + m_OutEvent = NULL; + } + m_OutOpen = FALSE; +} +//--------------------------------------------------------------------------- +//void CALLBACK WaveProc(hWave, uMsg, dwInstance, dwParam1, dwParam2) +// +//HWAVE hWave; /* ウェーブフォーム デバイスのハンドル */ +//UINT uMsg; /* 送るメッセージ */ +//DWORD dwInstance; /* インスタンス データ */ +//DWORD dwParam1; /* アプリケーション定義のパラメータ */ +//DWORD dwParam2; /* アプリケーション定義のパラメータ */ +void CALLBACK WaveOutProc(HWAVE m_hout, UINT uMsg, CWave* pWave, DWORD dwParam1, DWORD dwParam2 ) +{ + if( uMsg == WOM_DONE ){ + EnterCriticalSection(&pWave->m_OutCS); + pWave->m_OutBCC--; + pWave->m_OutBC--; + pWave->m_OutRP++; + if( pWave->m_OutRP >= pWave->m_OutFifoSize) pWave->m_OutRP = 0; + if( !pWave->m_OutBC ) pWave->m_OutUnder = TRUE; + if(pWave->m_OutWait){ + pWave->m_OutWait--; + SetEvent(pWave->m_OutEvent); + } + LeaveCriticalSection(&pWave->m_OutCS); + ::PostMessage(pWave->m_hWnd, WM_WAVE, waveOUT, 0); + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CWave::IsOutFirst(void) +{ + if( m_pDLL ){ + return FALSE; + } + else { + return m_OutFirst; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetInBC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetInBC(); + } + else { + return m_InBC; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetOutBC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetOutBC(); + } + else { + return m_OutBC; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetOutBCC(void) +{ + if( m_pDLL ){ + return m_pDLL->GetOutBCC(); + } + else { + return m_OutBCC; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetOutBCC(int count) +{ + if( m_pDLL ){ + m_pDLL->SetOutBCC(count); + } + else { + m_OutBCC = count; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsInBufCritical(void) +{ + if( m_pDLL ){ + return m_pDLL->IsInBufCritical(); + } + else { + return ( m_InBC >= (m_InFifoSize/2) ) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsOutBufCritical(void) +{ + if( m_pDLL ){ + return m_pDLL->IsOutBufCritical(); + } + else { + return (m_OutBC <= (m_OutFifoSize/2)) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +int __fastcall CWave::IsOutBufFull(void) +{ + if( m_pDLL ){ + return m_pDLL->IsOutBufFull(); + } + else { + return (m_OutBC >= m_OutFifoSize) ? 1 : 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetPTT(LONG tx) +{ + m_fPTT = tx; + if( m_pDLL ) m_pDLL->SetPTT(tx); +} +//--------------------------------------------------------------------------- +int __fastcall CWave::GetTimeout(void) +{ + if( m_pDLL ){ + return m_pDLL->GetTimeout(); + } + else { + return 5000; + } +} +//--------------------------------------------------------------------------- +// サウンドカードの名前を得る +void __fastcall CWave::GetDeviceList(void) +{ + m_InDevs = 0; + m_OutDevs = 0; + WAVEINCAPS incaps; + for( int i = 0; i < AN(m_tInDevName); i++ ){ + if( !waveInGetDevCaps(i, &incaps, sizeof(incaps)) ){ + m_tInDevName[i] = incaps.szPname; + m_InDevs = i + 1; + } + else { + m_tInDevName[i] = ""; + } + } + WAVEOUTCAPS outcaps; + for( int i = 0; i < AN(m_tOutDevName); i++ ){ + if( !waveOutGetDevCaps(i, &outcaps, sizeof(outcaps)) ){ + m_tOutDevName[i] = outcaps.szPname; + m_OutDevs = i + 1; + } + else { + m_tOutDevName[i] = ""; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::SetSoundID(int &rxID, int &txID) +{ + BOOL fList = FALSE; + int d; + if( sscanf(sys.m_SoundIDRX.c_str(), "%d", &d ) == 1 ){ + rxID = d; + } + else { + rxID = -2; + GetDeviceList(); fList = TRUE; + for( int i = 0; i < m_InDevs; i++ ){ + if( !strcmp(m_tInDevName[i].c_str(), sys.m_SoundIDRX.c_str()) ){ + rxID = i; + break; + } + } + if( rxID == -2 ){ + sys.m_SoundMMW = sys.m_SoundIDRX; + } + } + if( sscanf(sys.m_SoundIDTX.c_str(), "%d", &d ) == 1 ){ + txID = d; + } + else { + txID = -1; + if( !fList ) GetDeviceList(); + for( int i = 0; i < m_OutDevs; i++ ){ + if( !strcmp(m_tOutDevName[i].c_str(), sys.m_SoundIDTX.c_str()) ){ + txID = i; + break; + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::UpdateDevice(int ID) +{ + if( ID == -2 ){ + if( (m_pDLL == NULL) || m_pDLL->IsNameChange() ){ + if( m_pDLL ) delete m_pDLL; + m_pDLL = new CXWave(sys.m_SoundMMW.c_str()); + } + } + else if( m_pDLL != NULL ){ + delete m_pDLL; + m_pDLL = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall CWave::PumpMessages(void) +{ +#if 0 + if( m_pDLL ){ + m_pDLL->PumpMessages(); + } +#endif +} + +//*************************************************************************** +// CXWave class +//--------------------------------------------------------------------------- +void CALLBACK TimeProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) +{ OnWave(); } //--------------------------------------------------------------------------- +__fastcall CXWave::CXWave(LPCSTR pName) +{ + m_ItemName = pName; + m_nTimerID = 0; + + char Name[MAX_PATH]; + if( !*GetEXT(pName) ){ + wsprintf(Name, "%s.mmw", pName); + pName = Name; + } + + m_hLib = ::LoadLibrary(pName); + if( m_hLib ){ + + fmmwPumpMessages = PROC(mmwPumpMessages); + fmmwSetPTT = PROC(mmwSetPTT); + fmmwGetTimeout = PROC(mmwGetTimeout); + + fmmwInOpen = PROC(mmwInOpen); + fmmwInClose = PROC(mmwInClose); + fmmwInRead = PROC(mmwInRead); + + fmmwGetInExist = PROC(mmwGetInExist); + fmmwIsInCritical = PROC(mmwIsInCritical); + + fmmwOutOpen = PROC(mmwOutOpen); + fmmwOutAbort = PROC(mmwOutAbort); + fmmwOutFlush = PROC(mmwOutFlush); + fmmwOutWrite = PROC(mmwOutWrite); + + fmmwIsOutCritical = PROC(mmwIsOutCritical); + fmmwIsOutFull = PROC(mmwIsOutFull); + fmmwGetOutRemaining = PROC(mmwGetOutRemaining); + fmmwGetOutCounter = PROC(mmwGetOutCounter); + fmmwSetOutCounter = PROC(mmwSetOutCounter); + + + if( !m_hLib ){ + FreeLib(); + } + else { + //m_nTimerID = ::SetTimer(NULL, 0, 50, (int (__stdcall *)())TimeProc); //$$$ + m_nTimerID = SetTimer(NULL, 0, 50, TimeProc); + } + } +} +//--------------------------------------------------------------------------- +__fastcall CXWave::~CXWave(void) +{ + if( m_nTimerID ){ + ::KillTimer(NULL, m_nTimerID); + } + if( m_hLib ){ + fmmwOutAbort(); + fmmwInClose(); + } + FreeLib(); +} +//--------------------------------------------------------------------------- +FARPROC __fastcall CXWave::GetProc(LPCSTR pName) +{ + if( !m_hLib ) return NULL; + + FARPROC fn = ::GetProcAddress(m_hLib, pName+1); + if( fn == NULL ){ + fn = ::GetProcAddress(m_hLib, pName); + if( fn == NULL ) FreeLib(); + } + return fn; +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::FreeLib(void) +{ + if( m_hLib ){ + FreeLibrary(m_hLib); + m_hLib = NULL; + } +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::IsNameChange(void) +{ + return strcmpi(m_ItemName.c_str(), sys.m_SoundMMW.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::PumpMessages(void) +{ + if( !IsLib() ) return; + + fmmwPumpMessages(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::InOpen(int sampfreq, int size) +{ + if( !IsLib() ) return FALSE; + + return fmmwInOpen(sampfreq, size); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::InClose(void) +{ + if( !IsLib() ) return; + + fmmwInClose(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::InRead(SHORT *p) +{ + if( !IsLib() ) return FALSE; + + return fmmwInRead(p); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetInBC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetInExist(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsInBufCritical(void) +{ + if( !IsLib() ) return 0; + return fmmwIsInCritical(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::OutOpen(int sampfreq, int size) +{ + if( !IsLib() ) return FALSE; + return fmmwOutOpen(sampfreq, size); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::OutFlush(void) +{ + if( !IsLib() ) return; + fmmwOutFlush(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::OutAbort(void) +{ + if( !IsLib() ) return; + fmmwOutAbort(); +} +//--------------------------------------------------------------------------- +BOOL __fastcall CXWave::OutWrite(const SHORT *p) +{ + if( !IsLib() ) return FALSE; + return fmmwOutWrite(p); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetOutBC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetOutRemaining(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetOutBCC(void) +{ + if( !IsLib() ) return 0; + return fmmwGetOutCounter(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::SetOutBCC(int count) +{ + if( !IsLib() ) return; + fmmwSetOutCounter(count); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsOutBufCritical(void) +{ + if( !IsLib() ) return 0; + return fmmwIsOutCritical(); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::IsOutBufFull(void) +{ + if( !IsLib() ) return 0; + return fmmwIsOutFull(); +} +//--------------------------------------------------------------------------- +void __fastcall CXWave::SetPTT(int tx) +{ + if( !IsLib() ) return; + fmmwSetPTT(tx); +} +//--------------------------------------------------------------------------- +int __fastcall CXWave::GetTimeout(void) +{ + if( !IsLib() ) return 200; + return fmmwGetTimeout(); +} +//--------------------------------------------------------------------------- +// +//*************************************************************************** +// CWaveFileクラス +// +const int g_tSampTable[]={11025, 8000, 6000, 12000, 16000, 18000, 22050, 24000, 44100, 48000, 50000}; +//--------------------------------------------------------------------------- +// CWaveFileクラス +__fastcall CWaveFile::CWaveFile() +{ + m_mode = 0; + m_pause = 0; + m_Handle = NULL; + m_dis = 0; + m_autopause = TRUE; +} + +__fastcall CWaveFile::~CWaveFile() +{ + FileClose(); +} + +void __fastcall CWaveFile::FileClose(void) +{ + m_mode = 0; + m_pause = 0; + if( m_Handle != NULL ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + } +} + +void __fastcall CWaveFile::ReadWrite(short *s, int size) +{ + int csize = size * sizeof(short); + + if( m_Handle != NULL ){ + if( m_mode == 2 ){ // 書きこみ + if( !m_pause ){ + if( mmioWrite(m_Handle, (const char*)s, csize) != csize ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + m_mode = 0; + } + else { + m_pos += csize; + } + } + } + else { // 読み出し + if( m_pause || m_dis ){ + memset(s, 0, csize); + } + else { + if( mmioRead(m_Handle, (char *)s, csize) == csize ){ + m_pos += csize; + } + else if( m_autopause ){ +// Rewind(); + m_pause = 1; + } + else { + mmioClose(m_Handle, 0); + m_Handle = 0; + m_mode = 0; + } + } + } + } +} + +void __fastcall CWaveFile::Rec(LPCSTR pName) +{ + FileClose(); + m_FileName = pName; + GetFileName(m_Name, pName); + m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_CREATE|MMIO_WRITE|MMIO_ALLOCBUF); + if( m_Handle == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'を作成できません.", pName); + return; + } + m_Head[0] = 0x55; + m_Head[1] = 0xaa; + m_Head[2] = char(SAMPTYPE); + m_Head[3] = 0; + mmioWrite(m_Handle, (const char *)m_Head, 4); + m_pos = 4; + m_mode = 2; + m_pause = 0; + m_dis = 0; +} + +BOOL __fastcall CWaveFile::Play(LPCSTR pName) +{ + FileClose(); + FILE *fp = fopen(pName, "rb"); + if( fp == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'をオープンできません.", pName); + return FALSE; + } + m_length = filelength(fileno(fp)); + m_FileName = pName; + GetFileName(m_Name, pName); + + fclose(fp); + m_Handle = mmioOpen(m_FileName.c_str(), NULL, MMIO_READ|MMIO_ALLOCBUF); + if( m_Handle == NULL ){ + ErrorMB( sys.m_MsgEng?"Can't open '%s'":"'%s'をオープンできません.", pName); + return FALSE; + } + m_pos = 0; + if( mmioRead(m_Handle, (char *)m_Head, 4) == 4 ){ + int type = 0; + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + type = m_Head[2]; + m_pos = 4; + m_length -= 4; + } + if( type > 10 ) type = 0; + if( type != SAMPTYPE ){ + if( YesNoMB( + sys.m_MsgEng + ? "%s\r\n\r\nThis file has been recorded based on %uHz, play it with sampling conversion?\r\n\r\nThis conversion needs long time..." + : "%s\r\n\r\nこのファイルは %uHz ベースで記録されています. 周波数変換して再生しますか?\r\n\r\nこの変換は時間がかかる場合があります...", + m_FileName.c_str(), g_tSampTable[type] ) == IDNO ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + return FALSE; + } + else { + mmioClose(m_Handle, 0); + m_Handle = 0; + char bf[1024]; + strcpy(bf, pName); + SetEXT(bf, ""); + char wName[1024]; + sprintf(wName, "%s_%u.MMV", bf, int(SAMPBASE)); + if( ChangeSampFreq(wName, pName, g_tSampTable[type]) == TRUE ){ + Play(wName); + } + } + } + } + m_mode = 1; + m_pause = 0; + m_dis = 0; + return TRUE; +} + +int __fastcall CWaveFile::ChangeSampFreq(LPCSTR tName, LPCSTR pName, int sSamp) +{ + int rr = FALSE; + FILE *fp = fopen(pName, "rb"); + if( fp != NULL ){ + CWaitCursor w; + BYTE head[4]; + memset(head, 0, sizeof(head)); + head[0] = 0x55; + head[1] = 0xaa; + head[2] = char(SAMPTYPE); + head[3] = 0; + FILE *wfp = fopen(tName, "wb"); + if( wfp != NULL ){ + fwrite(head, 1, 4, wfp); + + int rsize = 16384; + int wsize = rsize * SAMPBASE/double(sSamp); + short *rp = new short[rsize]; + short *wp = new short[wsize]; + short *ip = new short[rsize*4]; + CIIR riir; + riir.Create(ffLPF, 2800, sSamp*4, 10, 1, 0.3); + CIIR wiir; + wiir.Create(ffLPF, 2800, SAMPBASE, 10, 1, 0.3); + int rlen, wlen; + short *tp, *sp; + int i, r; + double k; + while(1){ + rlen = fread(rp, 1, rsize * 2, fp); + if( !rlen ) break; + rlen /= 2; + if( SAMPBASE < sSamp ){ // デシメーション + sp = rp; + tp = ip; + for( i = 0; i < rlen; i++, sp++ ){ // 一旦4倍にする + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + *tp++ = riir.Do(*sp); + } + k = double(sSamp*4) / double(SAMPBASE); + tp = wp; + wlen = rlen * SAMPBASE / sSamp; + if( wlen > wsize ) wlen = wsize; + for( i = 0; i < wlen; i++ ){ + r = int((double(i) * k) + 0.5); + if( r >= (rlen*4) ) r = (rlen*4) - 1; + *tp++ = wiir.Do(ip[r]); + } + } + else { // インターポーレーション + k = double(sSamp) / double(SAMPBASE); + tp = wp; + wlen = rlen * SAMPBASE / sSamp; + if( wlen > wsize ) wlen = wsize; + for( i = 0; i < wlen; i++ ){ + r = int((double(i) * k) + 0.5); + if( r >= rlen ) r = rlen - 1; + *tp++ = wiir.Do(rp[r]); + } + } + if( fwrite(wp, 1, wlen * 2, wfp) != size_t(wlen * 2) ) break; + } + if( !fclose(wfp) ) rr = TRUE; + delete ip; + delete rp; + delete wp; + } + fclose(fp); + } + return rr; +} + +void __fastcall CWaveFile::Rewind(void) +{ + if( m_Handle != NULL ){ + m_dis++; + if( m_mode == 2 ){ + mmioSeek(m_Handle, 4, SEEK_SET); + m_pos = 4; + } + else { + mmioSeek(m_Handle, 0, SEEK_SET); + m_pos = 0; + } + m_dis--; + } +} + +void __fastcall CWaveFile::Seek(int n) +{ + if( m_Handle != NULL ){ + n &= 0xfffffffe; + m_dis++; + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + mmioSeek(m_Handle, n + 4, SEEK_SET); + m_pos = n + 4; + } + else { + mmioSeek(m_Handle, n, SEEK_SET); + m_pos = n; + } + m_dis--; + } +} + +long __fastcall CWaveFile::GetPos(void) +{ + if( (m_Head[0] == 0x55)&&(m_Head[1] == 0xaa) ){ + long n = m_pos - 4; + if( n < 0 ) n = 0; + return n; + } + else { + return m_pos; + } +} + +//--------------------------------------------------------------------------- +// CWaveStrageクラス + +__fastcall CWaveStrage::CWaveStrage() +{ + m_Handle = NULL; + + m_pos = m_rpos = m_wpos = 0; + pData = pSync = NULL; +} + +void __fastcall CWaveStrage::Close(void) +{ + if( m_Handle != NULL ){ + mmioClose(m_Handle, 0); + m_Handle = 0; + unlink(m_FileName.c_str()); + } + if( pData != NULL ){ + delete pData; + pData = NULL; + } + if( pSync != NULL ){ + delete pSync; + pSync = NULL; + } +} + +void __fastcall CWaveStrage::Open(void) +{ + Close(); + char bf[256]; + sprintf(bf, "%sSound.tmp", sys.m_BgnDir); + m_FileName = bf; + m_Handle = mmioOpen(bf, NULL, MMIO_READWRITE|MMIO_CREATE|MMIO_ALLOCBUF); + m_wpos = m_rpos = m_pos = 0; + pData = new short[1400*SAMPFREQ/1000]; + pSync = new short[1400*SAMPFREQ/1000]; +} + +void __fastcall CWaveStrage::RInit(void) +{ + m_rpos = 0; +} + +void __fastcall CWaveStrage::WInit(void) +{ + m_wpos = 0; +} + +void __fastcall CWaveStrage::Seek(int n) +{ + mmioSeek(m_Handle, n, SEEK_SET); + m_pos = n; +} + +void __fastcall CWaveStrage::Read(short *sp, int size) +{ + if( m_pos != m_rpos ){ + Seek(m_rpos); + } + mmioRead(m_Handle, (char *)sp, size); + m_rpos += size; + m_pos = m_rpos; +} + +void __fastcall CWaveStrage::Write(short *sp, int size) +{ + if( m_pos != m_wpos ){ + Seek(m_wpos); + } + mmioWrite(m_Handle, (char *)sp, size); + m_wpos += size; + m_pos = m_wpos; +} + +