pax_global_header00006660000000000000000000000064132154104230014505gustar00rootroot0000000000000052 comment=fbee6ce31440b9d217c15a8091a21fab74b79b78 gxtuner-3.0/000077500000000000000000000000001321541042300130435ustar00rootroot00000000000000gxtuner-3.0/.gitignore000066400000000000000000000000541321541042300150320ustar00rootroot00000000000000*.o config.h resample.h gxtuner GxTuner.png gxtuner-3.0/GxTuner.png000066400000000000000000000415031321541042300151500ustar00rootroot00000000000000PNG  IHDR%6sBITOtEXtSoftwaregnome-screenshot> IDATxi]u&xN}{m F )JHnY<%G{c~uw'&:OGό#fuLbV/Vk5%$"e%JP^n9?P|_ ͛w=yd&C!N`Zk!D$"B"o&-obOuϷ{BZ$( !q]s[%4Pލ "O1Ѻ0-CT^Ny)mb񢦅G*K)س[B۶~8cs.V ~"A*B)EDEد[k.T.I (zb!}$@ Ϧ%G1&#yi(!$ҔR7l$YOYwpi ѓdݴ=L?힔w!DP7褏Q!Fh,UE]] !f3qJhD4 #(%{1" 0l7tfi&`0 x׫=.TC˙9≶I!=~` IE:{$%"6OHP|b9GNF@" i % ~=߳@Z%!(n&ԩO"hRoUxa1H.ɼ >ؼND%.MYP~y;_j*"J$W$􄟎|e^o>3/})wп W~a{B6"svѶSX"k||Fy==w!BR HD"l)Eƈ 6 #fk~奯*n2D8##B2bѤ c P(}$ql)Rl~ұ;eҊ@9sdgGs귟# sDZT8 !A( @)20L\4(5M4-䙤W^w9vBvBihyHN$/HTC ӤH k/"J!DӴf(ۆa%MdFQ|J:ߺ[LԚ/@ۗ j(IHя:w BI)5dZ9b;A+P'jGs4-q*$jb8AQE*GC>hg_J/[s% !vҴդ[q4C @Ҥ}v} 7@pqNj<+CX'X9"ܾ 1aL;#p]~<-w =)=$wD¯0zz%D hq$O2fͿmPs9Wxٚ{ťh񌨈O|BDoYu: =1Bi< mTW͖7"f|$ĽFrD;Ijf<2d?Kz͂V~uQeUs=bvšZeBo,BQ˶(3NOxƨ\2 UVi!І.OIE1h<1vHB WT}uPhP8=I{A 'ϯλ-R_:+-NA`/ӻC QT9{"Orj< c g:F!"s 11Eu4Cq]Q@ˑTHI5?2.˽%"?te/ASR5{Ÿi#GS*.xNc(Rh{ULgмAJ.-y#e@1Q)"͎Qɫ (OF64bV.]w'O{K C==t[FT0u\WT.xv#Skrk3S*mAdzKBMg賗@KB:&YBLVdTbsQ%3B.zRe;( ~я>RWVnCj-`+ מz'F>?{$yT.` ֌u-^#-u AAKQW_|M]ilKzwٓ2ڍGGUBruѱ)03cu戹\;#yxlRUm:z:P&d28mÿQ=)d}ggq@QqWl9"d9_%:+hvthZ?hD3*e"R𳨵 GOj|M7 Yz߱~SA!bg΂R|G>|8Ү `4X#e`KKz(T @}0)DGhZ#YmKD䈐hS'(,T9Bi#Ғ`FghDpιVmZ[Boccȑ#Ǐ?C=4::n[w1qai!Jc]K(eE'ʏ)qŮ# kֹΉUC؝- Q9eƄB4י[P:Qk̮¸ 7EײF=Qó_izn$4}[o_]AFL%-_h:Qu߉l^^rPdȴJ(Vf]0P % (&g Zǣ[\0:Z}$XǑ j79(*h-3T´"8TnȴJ)7|9/'N#T#fN}&I,w.- FąFh$V d_%;.7o4ϟsvq_AƎFl{VeFs\٘u -558`$Lau:\ yqz&eJtd58јPE;"@͌)Vm{F~anڑWQϩ!7o4؏'}4jmƙ N*ao:(h?%Qf3N8qɓ'O۷o7_8_~p,eszyĥV#Lǎ;|j5S#C30sq ybVt4zXS ~AhxJ(ymj(bNOʦ\ұ y Ys[(9X9ܬ$.!xūWġC!m85Ov3t+&;ݵ~ &NzP`3\.;wܹs\.˥w[K/暑1}!C?tP6M݋׭5>?`sף3,Zҗ/:P7x cuB4\kem4 ?ވnzzlɣfTի,LU;Ϳi9uifLqNc˟Lz.7joy KkyMQʚ7994_"v@-S1+hE/RKL"OU=*8cG3Y7>= זZ'}#=#‰ f3rk}'{-|?D{r:@{#G@}}>9\xmyb\@hdj嚷^x◗„T<{Ƽ2 31}\;zB:uM:gW\Yʬg4pG}f ?D8wP _^ǍE>~:oj$b}}zm$I Cɍ]G/BNl.%|ʊeY躮a⥫{"ׯU"վهD})=3{ղf|3>Y5ƒ?CcboT2u\: 59Rt2WkNxQsW\YhH@t?;hb%l4i%$xyPcO}}qMY]]BT[U_zh$8@3/-XWC4^T7j 48w&8Ns+UώV W[oYzF6kxLIH R=>/~lBI*(77nU)~h ׮nzN]\(uaeqK_?y,;S*Gp&*T0ƘyBT*MNN߿f^'?KͅڧMDҬKsk9f+8xE |3PS|pI Ѽߞ.Wv$V9;m\9Sfӝ[B׽O"~ރE1J(7٥FYG*a/_pV9u8B."( ,(qW~[r=)K,&CsOuFtNϏd[&5nr$s\OHdg!j48D #lÏ5x0A9[!-sf^^s''4zuqQcoa@X+у'͑Kk\Tݧ=l0%lOJm Sszlj"T-⨪ߩ72@t;y3Bb˷o -ts9 l5YVgF@9ԛ,c_x'sm"afnv0Bm% Pxj%ѱɇK E:+YᕙKkQ gOr*io?UuqJNNNNJ*65YM!Ńs8lbL?XçF~r 8+#6?Y'rij*!v\w/_v͚[ew? a뺮'8I繗_z}CjѥZ#lcG ۧ|skQ{ ӌAB:v4 O< 4J!ݏ 3JPUe.ye' gל "uҙLlۆz_Thtni}{ 6Fc;Ivo\wI{t9*],=P(/'qj)/tV#8{B6ayB\ SCQ6k/Wk;iu@Dvt1f"ٔz >G]ws3ޒ]!IB A٪*{c<:ԩ[kT恭EW833̭YV1Ĵ÷Ri[6)(PVU蟮_c&z3DžBV rqyպ ь"8cZ9.Dv)Y53n6o2Qm#f냄ITM~||OV'_q5ю0=0ti;s,nD[1oFbٺ(>i=P[IoYKUM2_ĕ4H=]l` A:tQ|j9g+ȟoZK0l"i[{9j'"j Yc\6G(;uqbϖx}:}1py)rWv?g0h@wV4nخ`jDa N|9t4ToiuҒ-%3iN@t?"Vv-vu8[bl7ȗ#" Was]oҾev?>#rZVS3~ n'~IDZvi&d.)! q7q_~yuuqFb qٰCF3>מ1<[ŸUTx7|kx2/m C^JuKtiHW\1M3OOOscH(BM6dX`N)lJۚu9?Я`@qD m$_^^vstg6 %E?dDA~`GBYMSaoA l-qT: ]s')%E͛7)JLsNk|1{ MpߣQ@@HMuA9YpӁ5v[e[(ڑ"{rSje~dlD "U>Fx @z7vˮ$tO,..MqeЌxͣ߮eЭpDK#u􊇗N|^Rd%g MWVZ IBФx'5Qr*(ߪyW;4t{=ϫj.]\Η֐XC..flY-=Z\?6-heyCY_v95wu]/JrYnqfփ\g|[)tt|R-/bލ9%Y05grՁ*鞡C;=Γ;߮،m{aaR|>/A?䥆^٧{mhu?YW+Exh%֒%cSY~>U$q](: 9ޅeY4>>nr:Q`K dVSwx7=H܃?-{Weo_\];@ xC{ 㿫&`3Ͳ2[P=!)t}NLrnݺOS,-q76?e8ޱ:l~y=3=?(>v؄ZɊ??mzZڞM}-h ɉM˗/ l6+O~_RD7?lF5|MwS%wA=dzV/][9'1SۋjZ2T*VmaseIH/o~aۧI*>UWrN]641x]q7lxfӥ6J_I=sij6<:m-}l#4!5Fwrfd<5)yaIY->3#m2~扯z14E=$Fl3Dr9X2Ym67nܰ,Kݗ$jRTY k[ٵ`3Ŀ6 " !+5.nFP)GU"Gɇo9_^^4MB1.eIMx&wo&:yj]7؂ Uz>sߣi@;>"hQvn8h4ri8  tl#]\`qwCMt %,XO1c?\'?od٣+g_.Ε-:n+ <㻋-T*sy BlT{Mk\Wlw^D$;lf۰dpV6Sx8=<}evs ӄY;mr\.'눁OdxP.xlYݶ_߯ tP_jQ%^ݝJ=@~sg.wB oaIhs۶md2i4WE.m^t+4{g6'-[wGf)՛$qͳ>S^ܗz(aJܽl6mۖN1F'4P*edƅ! ,zsq0+^} Z`k}[f4/ZD5()X7ZPp>dG'nswB:rG  J3T **K=\df'u[\%rD@6:7xc) '5T(Dò+^z]q,F}m{H⪌E[>?}$¼6-řw6C]{7/5Ӽ|I |Қ'it@Ldr\.f?^8`J{k#?t\Erō^ mZ~IRotRB#=ti`3?~iqy6?q52#K`?5t۫~?}`ȉt]W/mKv}c毚},M@"SHCΪݫC*~v7O=W¤~{EdgӔR4}>*} Ƙy麮mۥ`!okvfD@r` _V91Ҽ9YᏌ=^e$h_V=gK?X{*~`_Eqg/\L'sD0 #H["nUK;c[^n󣯯?xޤ# 13 Ƥ$n ˩h`N§߫Pپ_9GV>Be\h[p(uG!B$dt]gVL{]EqG!-Z8Wx˯:i{F$D+G|Sٗ*?1@5kUڄe QS+-N?n.8!$޷*/44M  ?Fm69 x h2P b } >hkkyw(A 5 @6+bvϴ8!M_W~1N iHQb.2D-NWQ|Qq.z2w4j^5E^˳["y0%ErOݨ]xq>R==O>3/lAHN*PykX %RJHg8#E@!gW*ϕ+J囿hU[Fy-NZah*˵ 0֙ZjJPz'%RD(r}`)(Q~'6FÒqh'Iw_#Y#r.޻i$25HlBDem0iE0tBDDRI+?hq,شmbE ?$XWS??v:l$$M~o@.swĶlCm~񐴥p@4Q   v"JNL.sY٬VՆ2yu1j&={sۍ(d DQ![ w Kp(_cIpa(l7u]Fpc/sBf '__U.,ZZAD D_!zdLɕ9 諚~d! U(3N( 8N!IG rPgQ;slW7+zy<͝֏@u!hӰlw@)\tqT"QȰP*!r‡"QTl:I: "BDj?/kH#\qv~|" k[ av',R4xJ,CUPHep1r6jjömh0Rjޏ1("*G.2B䑏b+;  $PDƮ{!4ä ѯPC P44A"PP_s@r]p/ʤA4ۋyVӮ՛Vf1&i{@72}х~`g%I"? Yǟo0EvrLx Sa$ĉ۱yĿ!%~kTb%DÁmSP`5;- H <ϱ]v]וRY4zZ{T.iF$ r ڣDJ:Q'BÀX#BpN`9JOp )鱦5Hh"&F!kܱ]ƹӐضۧkFo"몪6@9(="kN`T*CQ=Ħ'jg?}^dK&igΜ)JQY[m5I]Q4 lͪY]ՋPbsH$i쭫odW?M9uTT"._2t#yL 4 3SSbV1WVV!Bt[?s7W Rl RT,IV+ Dd(v@ *Q=ϫj;H#ɱSǖ@EwkUejjJ3fE(\br`kjADNUЦnY!C9t!ZͩC-JR뺧{<3@& YodOY{XJB6z+NydT d\*,̸c8pPNĕ iqyv-O] r[Jv#fq D(&sfiuVwC (8LZq#UfJNxkQ4t@ :g6=IDAT? 1?OǾom!lR:_@YWvF@\%dOL[e#z K `CNɱ&[__%݋o:=; o5yRr‡ `ߡށ)+FT~m;k9V֒9V{ׯ6զ̆ M=ڰkkS~W'C`7_YO]yVڪ(9NZxlgx#JJ7zR0I6Ht:r䈖yQ'O?gمG΀ K@N&t]677O[Gg^kP% ڳq)R9 '[B\._Z]PohlIax $ct٬R,,,UiTo ټ0xh(Aɖ0pBT*bQ-O|ѧff߼khAquۼV]tkn!8٘ä Hc %C3̌5Gsy-'>wqmQ4jcI9 YiW*K.)zC Df2SX%[ʊyKW n1or9hܼysfffx[AlDZ$;11o>!t.6A.-JLf"{!b!b!`,vXIENDB`gxtuner-3.0/LICENSE000066400000000000000000000431761321541042300140630ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) 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 this service 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 make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. 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. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the 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 a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE 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. 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 convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision 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, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. {signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice This 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. gxtuner-3.0/Makefile000066400000000000000000000150661321541042300145130ustar00rootroot00000000000000## makefile for gxtuner by @brummer ## please edit to your needs ## set the install Path for gxtuner #@defines PREFIX = /usr BIN_DIR = $(PREFIX)/bin SHARE_DIR = $(PREFIX)/share DESKAPPS_DIR = $(SHARE_DIR)/applications PIXMAPS_DIR = $(SHARE_DIR)/pixmaps INCLUDE_DIR = /usr/include/ INCLUDE_L_DIR = /usr/local/include/ VER = 2.4 NAME = gxtuner LIBS = `pkg-config --libs jack gtk+-3.0 gthread-2.0 fftw3f x11` -lzita-resampler CFLAGS += -Wall -ffast-math `pkg-config --cflags jack gtk+-3.0 gthread-2.0 fftw3f` OBJS = resources.o jacktuner.o gxtuner.o cmdparser.o gx_pitch_tracker.o gtkknob.o \ paintbox.o tuner.o deskpager.o main.o DEBNAME = $(NAME)_$(VER) CREATEDEB = dh_make -y -s -n -e $(USER)@org -p $(DEBNAME) -c gpl >/dev/null DIRS = $(BIN_DIR) $(DESKAPPS_DIR) $(PIXMAPS_DIR) BUILDDEB = dpkg-buildpackage -rfakeroot -b 2>/dev/null | grep dpkg-deb #SOURCES =$(OBJS:%.o=%.cpp) ## output style (bash colours) BLUE = "\033[1;34m" BROWN = "\033[0;33m" GREEN = "\033[0;32m" LGREEN = "\033[1;32m" RED = "\033[1;31m" NONE = "\033[0m" #@default build with jack session support all : config @$(MAKE) check #@build resource file resources : resource.xml @echo $(LGREEN)"generate resource file,"$(NONE) -@glib-compile-resources --target=resources.c --generate-source resource.xml -@glib-compile-resources --target=resources.h --generate-header resource.xml #@build without jack session support nosession : nconf @$(MAKE) check #@link object files to build executable link : $(OBJS) @rm -rf $(NAME) @echo $(BROWN) - $(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) $(OBJS) $(LIBS) -o $(NAME) #@check if build have worked check : link @if [ -f ./$(NAME) ]; then echo $(BLUE)"build finish, now run make install"; \ else echo $(RED)"sorry, build failed"; fi @echo $(NONE) #@create resampler.h to set the used zita-resamper version resamp : -@if [ -f ./resample.h ] ; then \ echo ''; else \ if [ -f $(INCLUDE_DIR)zita-resampler/resampler.h 2>/dev/null ]; then \ echo '#include ' > resample.h; else \ if [ -f $(INCLUDE_DIR)zita-resampler.h 2>/dev/null ]; then \ echo '#include ' > resample.h; else \ if [ -f $(INCLUDE_L_DIR)zita-resampler/resampler.h 2>/dev/null ]; then \ echo '#include ' > resample.h; else \ if [ -f $(INCLUDE_L_DIR)zita-resampler.h 2>/dev/null ]; then \ echo '#include ' > resample.h; else \ echo $(RED)"error: zita-resampler library not found"$(GREEN); fi; fi; fi; fi; fi; @if [ -f resample.h ]; then echo $(LGREEN)"zita-resampler library ok"$(GREEN); \ else exit 2; fi; #@create config.h for build with jack session support config : resamp -@if cat config.h 2>/dev/null | grep HAVE_JACK_SESSION >/dev/null; then \ echo ''; else \ echo '#define VERSION "$(VER)"' > config.h ;\ echo '#define PIXMAPS_DIR "$(PIXMAPS_DIR)"' >> config.h ;\ echo '#ifndef HAVE_JACK_SESSION' >> config.h ;\ echo '#define HAVE_JACK_SESSION 1' >> config.h ; \ echo '#endif' >> config.h ;\ fi; @echo $(LGREEN)"build $(NAME) with jack_session support"$(GREEN) @echo "" #@create config.h for build without jack session support nconf : resamp -@if [ -f ./config.h 2>/dev/null ] ; then \ if cat config.h 2>/dev/null | grep HAVE_JACK_SESSION >/dev/null; then \ echo '#define VERSION "$(VER)"' > config.h ;\ echo '#define PIXMAPS_DIR "$(PIXMAPS_DIR)"' >> config.h ;\ fi; else \ echo '#define VERSION "$(VER)"' > config.h ;\ echo '#define PIXMAPS_DIR "$(PIXMAPS_DIR)"' >> config.h ;\ fi; @echo $(RED)"build $(NAME) without jack_session support !!"$(GREEN) @echo "" #@build object files resources.o : resources.c resources.h @rm -rf resources.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c resources.c jacktuner.o : jacktuner.cpp jacktuner.h config.h @rm -rf jacktuner.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c jacktuner.cpp gxtuner.o : gxtuner.cpp gxtuner.h @rm -rf gxtuner.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c gxtuner.cpp cmdparser.o : cmdparser.cpp cmdparser.h config.h @rm -rf cmdparser.o -$(CXX) $(LDFLAGS) $(CFLAGS) -c cmdparser.cpp gx_pitch_tracker.o : gx_pitch_tracker.cpp gx_pitch_tracker.h resample.h @rm -rf gx_pitch_tracker.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c gx_pitch_tracker.cpp gtkknob.o : gtkknob.cc gtkknob.h @rm -rf gtkknob.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c gtkknob.cc tuner.o :tuner.cpp tuner.h config.h paintbox.h gtkknob.h gxtuner.h deskpager.h @rm -rf tuner.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c tuner.cpp paintbox.o : paintbox.cpp paintbox.h @rm -rf paintbox.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c paintbox.cpp deskpager.o : deskpager.cpp deskpager.h @rm -rf deskpager.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c deskpager.cpp main.o : main.cpp jacktuner.h gxtuner.h cmdparser.h gx_pitch_tracker.h tuner.h deskpager.h @rm -rf main.o -$(CXX) $(LDFLAGS) $(CFLAGS) $(CPPFLAGS) -c main.cpp #@install all install : @mkdir -p $(DESTDIR)$(BIN_DIR) @mkdir -p $(DESTDIR)$(DESKAPPS_DIR) @mkdir -p $(DESTDIR)$(PIXMAPS_DIR) install $(NAME) $(DESTDIR)$(BIN_DIR) install $(NAME).desktop $(DESTDIR)$(DESKAPPS_DIR) install $(NAME).png $(DESTDIR)$(PIXMAPS_DIR) @echo $(BLUE)"$(NAME) installation finish,"$(NONE) #@well, clean up the build clean : @echo $(RED)"clean up," @rm -rf $(NAME) config.h resample.h *-stamp *~ *.o @echo ". ." $(BLUE)", done"$(NONE) #@clean up included the debian folder clean-full : @echo $(RED)"clean up," @rm -rf gxtuner config.h resample.h *-stamp *~ *.o @rm -rf ./debian/*.log ./debian/*.substvars ./debian/gxtuner @echo ". ." $(BLUE)", done"$(NONE) #@create tar ball tar : clean-full @cd ../ && \ tar -cf $(NAME)-$(VER).tar.bz2 --bzip2 gxtuner @echo $(LGREEN)"build gxtuner-"$(VER)".tar.bz2"$(NONE) #@create a tar ball, exclude ./debian dist-tar : clean @cd ../ && \ tar -cf $(NAME)-$(VER)-nopkg.tar.bz2 --bzip2 gxtuner --exclude=debian @echo $(LGREEN)"build gxtuner-"$(VER)"-nopkg.tar.bz2"$(NONE) #@build a debian packet for all arch deb : @rm -rf ./debian @echo $(BLUE)"create ./debian"$(NONE) -@ $(CREATEDEB) @ #@echo $(BLUE)"touch ./debian/dirs"$(NONE) @ #-@echo $(DIRS) > ./debian/dirs @echo $(BLUE)"try to build debian package, that may take some time"$(LGREEN) -@ if $(BUILDDEB); then echo ". ." $(BLUE)", done"$(NONE); else \ echo $(RED)"sorry, build fail"$(NONE); fi @rm -rf ./debian #@remove the installed stuff uninstall : rm -rf $(BIN_DIR)/$(NAME) $(DESKAPPS_DIR)/$(NAME).desktop $(PIXMAPS_DIR)/$(NAME).png @echo $(RED)"uninstall gxtuner, . . . finish"$(NONE) gxtuner-3.0/README000066400000000000000000000056521321541042300137330ustar00rootroot00000000000000 * 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. * Copyright (C) 2011-2017 Hermann Meyer, Andreas Degert, Hans Bezemer gxtuner 3.0 A (linux) tuner for jack, with full jack session managment support Besides a regular tuning option, it's possible to use GXtuner for extended Just Intonation. A4 = 440 Hz A4 reference pitch can adjusted at command line and/or runtime in a half tone range: 415Hz <-> 467Hz gxtuner uses a default threshold level at 0.001. The threshold can be adjusted at command line and/or runtime in a range of 0.001 <-> 0.2 ############# COMMANDLINE OPTIONS ################ Help Options: -h, --help Show help options --help-all Show all help options --help-gtk GTK configuration options --help-jack JACK configuration options --help-engine ENGINE configuration options GTK configuration options -x, --posx=POSITION_X window position x-axis ( -x 1 . . .) -y, --posy=POSITION_Y window position y-axis ( -y 1 . . .) -w, --wigth=WIDTH 'default' width ( -w 500 . . .) -l, --height=HEIGHT 'default' height ( -l 300 . . .) -d, --desktop=NUM set to virtual desktop num ( -d 0 . . .) JACK configuration options -i, --jack-input=PORT connect to JACK port name (-i system:capture_1) ENGINE configuration options -p, --pitch=PITCH set reference pitch (-p 415.0 <-> 467.0) -t, --threshold=THRESHOLD set threshold level (-t 0,001 <-> 0.2) All settings are optional, they will be all restored by the jack session manager ############## BUILD DEPENDENCY’S ################# the following packages are needed to build gxtuner : libc6-dev libcairo2-dev libfftw3-3-dev libgcc1-dev libglib2.0-0-dev libgtk3.0-0-dev libstdc++6-dev libzita-resampler0-dev libjack-jackd2-0-dev or libjack-0.116-dev note that those packages could have different, but similar names on different distributions. There is no configure script, make will simply fail when one of those packages isn't found. to build gxtuner with jack_session support simply run $ make to build gxtuner without jack_session support run $ make nosession in the source directory. If you wish to install[1] gxtuner run $ make install to uninstall gxtuner run $ make uninstall you can run gxtuner from any location you choose without installation. [1] but to work propper with jack_session manager you need to install it ############## MORE MAKE OPTIONS ################# to build a Debian package, run $ make deb to clean up the build tree run $ make clean or $ make clean-full to build a tar.bz2 archive run $ make tar gxtuner home is : https://github.com/brummer10/gxtunergxtuner-3.0/README.md000066400000000000000000000020041321541042300143160ustar00rootroot00000000000000# gxtuner A simple (linux) guitar tuner for jack ![GxTuner](https://github.com/brummer10/gxtuner/raw/master/GxTuner.png) ###### BUILD DEPENDENCY’S the following packages are needed to build gxtuner : - libc6-dev - libcairo2-dev - libfftw3-3-dev - libgcc1-dev - libglib2.0-0-dev - libgtk3.0-0-dev - libstdc++6-dev - libzita-resampler0-dev - libjack-jackd2-0-dev - or - libjack-0.116-dev note that those packages could have different, but similar names on different distributions. There is no configure script, make will simply fail when one of those packages isn't found. to build gxtuner with jack_session support simply run $ make to build gxtuner without jack_session support run $ make nosession in the source directory. If you wish to install[1] gxtuner run $ make install to uninstall gxtuner run $ make uninstall to build a Debian package, run $ make deb you can run gxtuner from any location you choose without installation. [1] but to work propper with jack_session manager you need to install it gxtuner-3.0/TODOLIST000066400000000000000000000002161321541042300142260ustar00rootroot00000000000000To do: - Rework calculation of needle position for tuner - Rework Boxes. When maximized, the boxes move to one side now - Add Partch scale. gxtuner-3.0/cmdparser.cpp000066400000000000000000000266421321541042300155410ustar00rootroot00000000000000/* * Copyright (C) 2017 Hermann Meyer, Andreas Degert, Hans Bezemer * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: comparse.cpp guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "./cmdparser.h" #include "./config.h" CmdParse::CmdParse() {} CmdParse::~CmdParse() {} void CmdParse::init() { error = NULL; infostring = "\n version "; infostring += VERSION; infostring += "\n A tuner for jack, with an option for Just Intonation\n"; infostring += " with full jack session management support"; opt_context = g_option_context_new(infostring.c_str()); jack_uuid = NULL; jack_input = NULL; size_x = NULL; size_y = NULL; pos_x = NULL; pos_y = NULL; desktop = NULL; pitch = NULL; threshold = NULL; mode = NULL; reference_note = NULL; //#1 reference_03comma = NULL; reference_05comma = NULL; reference_07comma = NULL; reference_11comma = NULL; reference_13comma = NULL; reference_17comma = NULL; reference_19comma = NULL; reference_23comma = NULL; reference_29comma = NULL; reference_31comma = NULL; } void CmdParse::write_optvar() { // *** process UUID (hidden option) if (jack_uuid != NULL) { optvar[JACK_UUID] = jack_uuid; // leads to no automatic connection g_free(jack_uuid); } else if (!optvar[JACK_UUID].empty()) { optvar[JACK_UUID] = ""; } // *** process ENGINE options if (pitch != NULL) { optvar[PITCH] = pitch; g_free(pitch); } else if (!optvar[PITCH].empty()) { optvar[PITCH] = ""; } if (threshold != NULL) { optvar[THRESHOLD] = threshold; g_free(threshold); } else if (!optvar[THRESHOLD].empty()) { optvar[THRESHOLD] = ""; } if (mode != NULL) { optvar[MODE] = mode; g_free(mode); } else if (!optvar[MODE].empty()) { optvar[MODE] = ""; } if (reference_note != NULL) { //#2 optvar[REFERENCE_NOTE] = reference_note; g_free(reference_note); } else if (!optvar[REFERENCE_NOTE].empty()) { optvar[REFERENCE_NOTE] = ""; } if (reference_03comma != NULL) { optvar[REFERENCE_03COMMA] = reference_03comma; g_free(reference_03comma); } else if (!optvar[REFERENCE_03COMMA].empty()) { optvar[REFERENCE_03COMMA] = ""; } if (reference_05comma != NULL) { optvar[REFERENCE_05COMMA] = reference_05comma; g_free(reference_05comma); } else if (!optvar[REFERENCE_05COMMA].empty()) { optvar[REFERENCE_05COMMA] = ""; } if (reference_07comma != NULL) { optvar[REFERENCE_07COMMA] = reference_07comma; g_free(reference_07comma); } else if (!optvar[REFERENCE_07COMMA].empty()) { optvar[REFERENCE_07COMMA] = ""; } if (reference_11comma != NULL) { optvar[REFERENCE_11COMMA] = reference_11comma; g_free(reference_11comma); } else if (!optvar[REFERENCE_11COMMA].empty()) { optvar[REFERENCE_11COMMA] = ""; } if (reference_13comma != NULL) { optvar[REFERENCE_13COMMA] = reference_13comma; g_free(reference_13comma); } else if (!optvar[REFERENCE_13COMMA].empty()) { optvar[REFERENCE_13COMMA] = ""; } if (reference_17comma != NULL) { optvar[REFERENCE_17COMMA] = reference_17comma; g_free(reference_17comma); } else if (!optvar[REFERENCE_17COMMA].empty()) { optvar[REFERENCE_17COMMA] = ""; } if (reference_19comma != NULL) { optvar[REFERENCE_19COMMA] = reference_19comma; g_free(reference_19comma); } else if (!optvar[REFERENCE_19COMMA].empty()) { optvar[REFERENCE_19COMMA] = ""; } if (reference_23comma != NULL) { optvar[REFERENCE_23COMMA] = reference_23comma; g_free(reference_23comma); } else if (!optvar[REFERENCE_23COMMA].empty()) { optvar[REFERENCE_23COMMA] = ""; } if (reference_29comma != NULL) { optvar[REFERENCE_29COMMA] = reference_29comma; g_free(reference_29comma); } else if (!optvar[REFERENCE_29COMMA].empty()) { optvar[REFERENCE_29COMMA] = ""; } if (reference_31comma != NULL) { optvar[REFERENCE_31COMMA] = reference_31comma; g_free(reference_31comma); } else if (!optvar[REFERENCE_31COMMA].empty()) { optvar[REFERENCE_31COMMA] = ""; } // *** process GTK options if (size_y != NULL) { optvar[SIZE_Y] = size_y; g_free(size_y); } else if (!optvar[SIZE_Y].empty()) { optvar[SIZE_Y] = ""; } if (size_x != NULL) { optvar[SIZE_X] = size_x; g_free(size_x); } else if (!optvar[SIZE_X].empty()) { optvar[SIZE_X] = ""; } if (pos_y != NULL) { optvar[POS_Y] = pos_y; g_free(pos_y); } else if (!optvar[POS_Y].empty()) { optvar[POS_Y] = ""; } if (pos_x != NULL) { optvar[POS_X] = pos_x; g_free(pos_x); } else if (!optvar[POS_X].empty()) { optvar[POS_X] = ""; } if (desktop != NULL) { optvar[DESK] = desktop; g_free(desktop); } else if (!optvar[DESK].empty()) { optvar[DESK] = ""; } // *** process JACK options if (jack_input != NULL) { optvar[JACK_INP] = jack_input; g_free(jack_input); } else if (!optvar[JACK_INP].empty()) { optvar[JACK_INP] = ""; // leads to no automatic connection } } void CmdParse::parse(int& argc, char**& argv) { // parsing command options if (!g_option_context_parse(opt_context, &argc, &argv, &error)) { g_print ("option parsing failed: %s\n", error->message); error = NULL; } g_option_context_free(opt_context); } void CmdParse::setup_groups() { optgroup_gtk = g_option_group_new("gtk", "\033[1;32mGTK configuration options\033[0m", "\033[1;32mGTK configuration options\033[0m", NULL, NULL); GOptionEntry opt_entries_gtk[] = { { "posx", 'x', 0, G_OPTION_ARG_STRING, &pos_x, "window position x-axis ( -x 1 -> . .)", "POSITION_X"}, { "posy", 'y', 0, G_OPTION_ARG_STRING, &pos_y, "window position y-axis ( -y 1 -> . . )", "POSITION_Y" }, { "wigth", 'w', 0, G_OPTION_ARG_STRING, &size_x, "'default' width ( -w 120 -> . .)", "WIDTH"}, { "height", 'l', 0, G_OPTION_ARG_STRING, &size_y, "'default' height ( -l 100 -> . .)", "HEIGHT" }, { "desktop", 'd', 0, G_OPTION_ARG_STRING, &desktop, "set to virtual desktop num ( -d 0 -> . .)", "NUM" }, { NULL } }; g_option_group_add_entries(optgroup_gtk, opt_entries_gtk); optgroup_jack = g_option_group_new("jack", "\033[1;32mJACK configuration options\033[0m", "\033[1;32mJACK configuration options\033[0m", NULL, NULL); GOptionEntry opt_entries_jack[] = { { "jack-input", 'i', 0, G_OPTION_ARG_STRING, &jack_input, "connect to JACK port name (-i system:capture_1)", "PORT" }, { NULL } }; g_option_group_add_entries(optgroup_jack, opt_entries_jack); GOptionEntry opt_entries_uuid[] = { { "jack-uuid", 'U', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, &jack_uuid, "JACK session UUID (set by session manager)", "UUID" }, { NULL } }; g_option_group_add_entries(optgroup_jack, opt_entries_uuid); optgroup_engine = g_option_group_new("engine", "\033[1;32mENGINE configuration options\033[0m", "\033[1;32mENGINE configuration options\033[0m", NULL, NULL); GOptionEntry opt_entries_engine[] = { { "pitch", 'p', 0, G_OPTION_ARG_STRING, &pitch, "set reference pitch ( -p 200,0 <-> 600,0)", "PITCH"}, { "threshold", 't', 0, G_OPTION_ARG_STRING, &threshold, "set threshold level (-t 0,001 <-> 0,5)", "THRESHOLD" }, { "mode", 'm', 0, G_OPTION_ARG_STRING, &mode, "set tuner mode (-m chromatic / scale3diatonic / scale35chromatic / scale357chromatic / scale37chromatic / scaleovertones )", "MODE" }, { "reference_note", 'R', 0, G_OPTION_ARG_STRING, &reference_note, "set reference note (-R C / D / E / F / G / A / B )", "REFERENCE_NOTE" }, { "reference_03comma", 'A', 0, G_OPTION_ARG_STRING, &reference_03comma, "set reference 3 limit comma (-A min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_03COMMA" }, { "reference_05comma", 'B', 0, G_OPTION_ARG_STRING, &reference_05comma, "set reference 5 limit comma (-B min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_05COMMA" }, { "reference_07comma", 'C', 0, G_OPTION_ARG_STRING, &reference_07comma, "set reference 7 limit comma (-C min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_07COMMA" }, { "reference_11comma", 'D', 0, G_OPTION_ARG_STRING, &reference_11comma, "set reference 11 limit comma (-D min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_11COMMA" }, { "reference_13comma", 'E', 0, G_OPTION_ARG_STRING, &reference_13comma, "set reference 13 limit comma (-E min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_13COMMA" }, { "reference_17comma", 'F', 0, G_OPTION_ARG_STRING, &reference_17comma, "set reference 17 limit comma (-F min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_17COMMA" }, { "reference_19comma", 'G', 0, G_OPTION_ARG_STRING, &reference_19comma, "set reference 19 limit comma (-G min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_19COMMA" }, { "reference_23comma", 'H', 0, G_OPTION_ARG_STRING, &reference_23comma, "set reference 23 limit comma (-H min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_23COMMA" }, { "reference_29comma", 'I', 0, G_OPTION_ARG_STRING, &reference_29comma, "set reference 29 limit comma (-I min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_29COMMA" }, { "reference_31comma", 'J', 0, G_OPTION_ARG_STRING, &reference_31comma, "set reference 31 limit comma (-J min3 / min2 / min1 / 0 / 1 / 2 / 3 )", "REFERENCE_31COMMA" }, { NULL } }; g_option_group_add_entries(optgroup_engine, opt_entries_engine); g_option_context_add_group(opt_context, optgroup_gtk); g_option_context_add_group(opt_context, optgroup_jack); g_option_context_add_group(opt_context, optgroup_engine); g_option_context_set_ignore_unknown_options(opt_context, true); } // ---- parse command line options void CmdParse::process_cmdline_options(int& argc, char**& argv) { init(); setup_groups(); parse(argc, argv); write_optvar(); } CmdParse cmd;gxtuner-3.0/cmdparser.h000066400000000000000000000063771321541042300152110ustar00rootroot00000000000000/* * Copyright (C) 2017 Hermann Meyer, Andreas Degert, Hans Bezemer * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: comparse.h guitar tuner for jack * * ---------------------------------------------------------------------------- */ #pragma once #ifndef CMD_PARSER_H_ #define CMD_PARSER_H_ #include #include #include #define JACK_INP (0) #define SIZE_X (1) #define SIZE_Y (2) #define POS_X (3) #define POS_Y (4) #define PITCH (5) #define THRESHOLD (6) #define JACK_UUID (7) #define DESK (8) #define MODE (9) #define REFERENCE_NOTE (10) #define REFERENCE_03COMMA (11) #define REFERENCE_05COMMA (12) #define REFERENCE_07COMMA (13) #define REFERENCE_11COMMA (14) #define REFERENCE_13COMMA (15) #define REFERENCE_17COMMA (16) #define REFERENCE_19COMMA (17) #define REFERENCE_23COMMA (18) #define REFERENCE_29COMMA (19) #define REFERENCE_31COMMA (20) class CmdParse { private: GError* error; GOptionContext* opt_context; GOptionGroup* optgroup_gtk; GOptionGroup* optgroup_jack; GOptionGroup* optgroup_engine; gchar* jack_uuid; gchar* jack_input; gchar* size_x; gchar* size_y; gchar* pos_x; gchar* pos_y; gchar* desktop; gchar* pitch; gchar* threshold; gchar* mode; gchar* reference_note; gchar* reference_03comma; gchar* reference_05comma; gchar* reference_07comma; gchar* reference_11comma; gchar* reference_13comma; gchar* reference_17comma; gchar* reference_19comma; gchar* reference_23comma; gchar* reference_29comma; gchar* reference_31comma; std::string infostring; void init(); void setup_groups(); void parse(int& argc, char**& argv); void write_optvar(); protected: std::string optvar[21]; //#3 public: explicit CmdParse(); ~CmdParse(); std::string get_optvar(int a) {return optvar[a];} void process_cmdline_options(int& argc, char**& argv); }; extern CmdParse cmd; #endif // CMD_PARSER_H_gxtuner-3.0/config.h000066400000000000000000000001761321541042300144650ustar00rootroot00000000000000#define VERSION "3.0" #define PIXMAPS_DIR "/usr/share/pixmaps" #ifndef HAVE_JACK_SESSION #define HAVE_JACK_SESSION 1 #endif gxtuner-3.0/deskpager.cpp000066400000000000000000000074631321541042300155260ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: deskpager.cpp set and get the virtual desktop for a gtkwindow * * ---------------------------------------------------------------------------- */ #include "./deskpager.h" DeskPager::DeskPager() {} DeskPager::~DeskPager() {} guint DeskPager::get_all_desktops () { data = NULL; if (!gdk_property_get ( gdk_screen_get_root_window (gdk_screen_get_default ()), gdk_atom_intern ("_NET_NUMBER_OF_DESKTOPS", FALSE), gdk_atom_intern ("CARDINAL", FALSE), 0, G_MAXLONG, FALSE, &actual_property_type, &actual_format, &actual_length, reinterpret_cast(&data))) { gchar *actual_property_type_name; g_critical ("Unable to get _NET_NUMBER_OF_DESKTOPS"); actual_property_type_name = gdk_atom_name (actual_property_type); if (actual_property_type_name) { g_message ("actual_property_type: %s", actual_property_type_name); g_free (actual_property_type_name); } return -1; } desktops_count = static_cast(data[0]); g_free (data); return desktops_count; } void DeskPager::move_window_to_desktop(guint desktop_num, GtkWidget * window) { if (desktop_num+1 > get_all_desktops()) return; display = gdk_x11_get_default_xdisplay(); root_win = GDK_WINDOW_XID(gdk_get_default_root_window()); displays = gdk_window_get_display (gtk_widget_get_window(window)); xevent.type = ClientMessage; xevent.xclient.type = ClientMessage; xevent.xclient.serial = 0; xevent.xclient.send_event = True; xevent.xclient.display = display; xevent.xclient.window = GDK_WINDOW_XID (gtk_widget_get_window(window)); xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (displays, "_NET_WM_DESKTOP"); //atom_net_current_desktop; xevent.xclient.format = 32; xevent.xclient.data.l[0] = desktop_num; xevent.xclient.data.l[1] = CurrentTime; xevent.xclient.data.l[2] = 0; xevent.xclient.data.l[3] = 0; xevent.xclient.data.l[4] = 0; XSendEvent(display, root_win, False, SubstructureNotifyMask | SubstructureRedirectMask, &xevent); XFlush(display); } gint DeskPager::get_active_desktop_for_window (GtkWidget * window) { data = NULL; if (!gdk_property_get (gtk_widget_get_window(window), gdk_atom_intern ("_NET_WM_DESKTOP", FALSE), gdk_atom_intern ("CARDINAL", FALSE), 0, G_MAXLONG, FALSE, &actual_property_type, &actual_format, &actual_length, reinterpret_cast(&data))) { gchar *actual_property_type_name; g_critical ("Unable to get _NET_WM_DESKTOP"); actual_property_type_name = gdk_atom_name (actual_property_type); if (actual_property_type_name) { g_message ("actual_property_type: %s", actual_property_type_name); g_free (actual_property_type_name); } return -1; } num_desktop = static_cast(data[0]); g_free (data); return num_desktop; } DeskPager dp; gxtuner-3.0/deskpager.h000066400000000000000000000034401321541042300151620ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: deskpager.h set and get the virtual desktop for a gtkwindow * * ---------------------------------------------------------------------------- */ #pragma once #ifndef _DESKPAGER_H_ #define _DESKPAGER_H_ #include #include class DeskPager { private: GdkAtom actual_property_type; int actual_format; int actual_length; gint desktops_count; gint num_desktop; Display *display; Window root_win; GdkDisplay *displays; XEvent xevent; long *data; guint get_all_desktops (); public: explicit DeskPager(); ~DeskPager(); void move_window_to_desktop(guint desktop_num, GtkWidget * window); gint get_active_desktop_for_window (GtkWidget * window); }; extern DeskPager dp; #endif // _DESKPAGER_H_ gxtuner-3.0/gtkknob.cc000066400000000000000000000430711321541042300150160ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: gtkkob.cc guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "gtkknob.h" #include #include #ifndef min #define min(x, y) ((x) < (y) ? (x) : (y)) #endif #ifndef max #define max(x, y) ((x) < (y) ? (y) : (x)) #endif #define GTK_KNOB_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), GTK_TYPE_KNOB, GtkKnobPrivate)) G_DEFINE_TYPE(GtkKnob, gtk_knob, GTK_TYPE_RANGE); typedef struct _GtkKnobPrivate GtkKnobPrivate; struct _GtkKnobPrivate { int knob_x; int knob_y; int knob_step; int button_is; double start_x, start_y, max_value; int last_quadrant; int order; }; const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs static void print_value(GObject *widget, char* s) { //GtkWidget * label = (GTK_WIDGET(obj)); float v = gtk_adjustment_get_value(GTK_ADJUSTMENT(widget)); //char s[64]; if (gtk_adjustment_get_step_increment(GTK_ADJUSTMENT(widget)) < 0.009999) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[3-1], v); } else if (gtk_adjustment_get_step_increment(GTK_ADJUSTMENT(widget)) < 0.09999) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[2-1], v); } else if (gtk_adjustment_get_step_increment(GTK_ADJUSTMENT(widget)) < 0.9999) { const char* format[] = {"%.1f", "%.2f", "%.3f"}; snprintf(s, 63, format[1-1], v); } else if (gtk_adjustment_get_step_increment(GTK_ADJUSTMENT(widget)) < 9.9999) { snprintf(s, 63, "%d", (int)v); } else snprintf(s, 63, "%d", (int)v); //return s; } static void knob_expose(GtkWidget *widget, cairo_t *cr, int knob_x, int knob_y, int arc_offset) { /** check resize **/ int grow; static const double vala = 37.; GtkAllocation *allocation = g_new0 (GtkAllocation, 1); gtk_widget_get_allocation(GTK_WIDGET(widget), allocation); if(allocation->width-vala > allocation->height) { grow = allocation->height; } else { grow = allocation->width-vala; } knob_x = grow-4; knob_y = grow-4; /** get values for the knob **/ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int knobx,knobx1; GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(widget); int order = priv->order; if (order) { knobx = (2 + (allocation->width-vala-4 - knob_x) * 0.5); knobx1 = (2 + (allocation->width-vala-4)* 0.5); } else { knobx = (2 + (allocation->width+vala-4 - knob_x) * 0.5); knobx1 = (2 + (allocation->width+vala-4)* 0.5); } int knoby = (2 + (allocation->height-4 - knob_y) * 0.5); int knoby1 = (2 + (allocation->height-4) * 0.5); double knobstate = (gtk_adjustment_get_value(adj) - gtk_adjustment_get_lower(adj)) / (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)); double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero); double knobstate1 = (0. - gtk_adjustment_get_lower(adj)) / (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)); double pointer_off = knob_x/6; double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2; double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle); double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle); double radius1 = min(knob_x, knob_y) / 2 ; /** get widget forground color convert to cairo **/ //GtkStyle *style = gtk_widget_get_style (widget); //double r = min(0.6,style->fg[gtk_widget_get_state_flags(widget)].red/65535.0), // g = min(0.6,style->fg[gtk_widget_get_state_flags(widget)].green/65535.0), // b = min(0.6,style->fg[gtk_widget_get_state_flags(widget)].blue/65535.0); double r = 0.6; double b = 0.6; double g = 0.6; /** paint focus **/ //GtkStyleContext *contex = gtk_widget_get_style_context (widget); //if (gtk_widget_has_focus(widget)== TRUE) { // gtk_render_focus(contex, cr, knobx-2, knoby-2, knob_x+4, knob_y+4); //} /** create clowing knobs with cairo **/ cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI ); cairo_pattern_t*pat = cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 ); if(gtk_adjustment_get_lower(adj)<416 && gtk_adjustment_get_value(adj)>440.) { cairo_pattern_add_color_stop_rgb (pat, 0, 0.4 +( knobstate-0.5), 0.4, 0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, 0.15+( knobstate-0.3), 0.15 , 0.15); cairo_pattern_add_color_stop_rgb (pat, 1, 0.15,0.15,0.15); } else if(gtk_adjustment_get_lower(adj)>414 && gtk_adjustment_get_value(adj)<440.) { cairo_pattern_add_color_stop_rgb (pat, 0, 0.4 , 0.4, 0.4 + (0.5 - knobstate)); cairo_pattern_add_color_stop_rgb (pat, 0.7, 0.15 , 0.15, 0.15 + (0.7 - knobstate)); cairo_pattern_add_color_stop_rgb (pat, 1, 0.15,0.15,0.15); } else if(gtk_adjustment_get_lower(adj)<5 && gtk_adjustment_get_value(adj)<4.) { cairo_pattern_add_color_stop_rgb (pat, 0, 0.4+knobstate*0.5 , 0.4-(knobstate*0.2), 0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, 0.15+knobstate*0.5 , 0.4-(knobstate*0.2), 0.15); cairo_pattern_add_color_stop_rgb (pat, 1,0.15,0.15,0.15); } else { cairo_pattern_add_color_stop_rgb (pat, 0, 0.4, 0.4, 0.4); cairo_pattern_add_color_stop_rgb (pat, 0.7, 0.15, 0.4, 0.15); cairo_pattern_add_color_stop_rgb (pat, 1, 0.15, 0.15,0.15); } GdkRGBA fg_color = {0.3, 0.3, 0.3, 0.7}; cairo_set_source (cr, pat); cairo_fill_preserve (cr); gdk_cairo_set_source_rgba(cr, &fg_color); cairo_set_line_width(cr, 2.0); cairo_stroke(cr); /** create a rotating pointer on the kob**/ gdk_cairo_set_source_rgba(cr, &fg_color); cairo_set_line_width(cr,max(3, min(5, knob_x/15))); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); cairo_move_to(cr, knobx+radius1, knoby+radius1); cairo_line_to(cr,lengh_x,lengh_y); cairo_stroke_preserve(cr); cairo_set_line_width(cr,min(5, max(1,knob_x/30))); pat = cairo_pattern_create_linear (knobx+radius1, knoby+radius1,lengh_x,lengh_y); if(gtk_adjustment_get_lower(adj)<0 && gtk_adjustment_get_value(adj)>0.) { cairo_pattern_add_color_stop_rgb (pat, 0.9, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.3, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 0.1, r, g, b); } else if(gtk_adjustment_get_lower(adj)<0 && gtk_adjustment_get_value(adj)<=0.) { cairo_pattern_add_color_stop_rgb (pat, 0.9, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.3, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 0.1, r, g, b); } else { cairo_pattern_add_color_stop_rgb (pat, 0.9, r+0.4, g+0.4 +knobstate, b+0.4); cairo_pattern_add_color_stop_rgb (pat, 0.3, r+0.15, g+0.15 + knobstate*0.5, b+0.15); cairo_pattern_add_color_stop_rgb (pat, 0.1, r, g, b); } cairo_set_source (cr, pat); cairo_stroke_preserve(cr); gdk_cairo_set_source_rgba(cr, &fg_color); cairo_set_line_width(cr, 0.5); cairo_stroke(cr); cairo_pattern_destroy (pat); char s[64]; print_value(G_OBJECT(adj),s); cairo_set_source_rgba (cr, 0.8, 0.8, 0.2,0.6); cairo_set_font_size (cr, 11.0); cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); if (order) { cairo_move_to (cr, knobx1+15., knoby1+5.); } else { cairo_move_to (cr, knobx1-50., knoby1+5.); } cairo_show_text(cr, s); g_free (allocation); } /**************************************************************** ** general expose events for all "knob" controllers */ //----------- draw the Knob when moved static gboolean gtk_knob_expose (GtkWidget *widget, cairo_t *cr) { g_assert(GTK_IS_KNOB(widget)); GtkKnob *knob = GTK_KNOB(widget); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); knob_expose(widget, cr, priv->knob_x, priv->knob_y, 0); return FALSE; } /**************************************************************** ** set value from key bindings */ static void gtk_knob_set_value (GtkWidget *widget, int dir_down) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); int oldstep = (int)(0.5f + (gtk_adjustment_get_value(adj) - gtk_adjustment_get_lower(adj)) / gtk_adjustment_get_step_increment(adj)); int step; int nsteps = (int)(0.5f + (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)) / gtk_adjustment_get_step_increment(adj)); if (dir_down) step = oldstep - 1; else step = oldstep + 1; float value = gtk_adjustment_get_lower(adj) + step * (double)(gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj)) / nsteps; gtk_widget_grab_focus(widget); gtk_range_set_value(GTK_RANGE(widget), value); } /**************************************************************** ** keyboard bindings */ static gboolean gtk_knob_key_press (GtkWidget *widget, GdkEventKey *event) { g_assert(GTK_IS_KNOB(widget)); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); switch (event->keyval) { case GDK_KEY_Home: gtk_range_set_value(GTK_RANGE(widget), gtk_adjustment_get_lower(adj)); return TRUE; case GDK_KEY_End: gtk_range_set_value(GTK_RANGE(widget), gtk_adjustment_get_upper(adj)); return TRUE; case GDK_KEY_Up: gtk_knob_set_value(widget, 0); return TRUE; case GDK_KEY_Right: gtk_knob_set_value(widget, 0); return TRUE; case GDK_KEY_Down: gtk_knob_set_value(widget, 1); return TRUE; case GDK_KEY_Left: gtk_knob_set_value(widget, 1); return TRUE; } return FALSE; } /**************************************************************** ** alternative (radial) knob motion mode (ctrl + mouse pressed) */ static void knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, int knob_x, int knob_y, gboolean drag, int state) { static double last_y = 2e20; GtkKnob *knob = GTK_KNOB(widget); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); GtkAllocation *allocation = g_new0 (GtkAllocation, 1); gtk_widget_get_allocation(GTK_WIDGET(widget), allocation); double radius = min(knob_x, knob_y) / 2; int knobx = (allocation->width - knob_x) / 2; int knoby = (allocation->height - knob_y) / 2; double posx = (knobx + radius) - x; // x axis right -> left double posy = (knoby + radius) - y; // y axis top -> bottom double value; if (!drag) { if (state & GDK_CONTROL_MASK) { last_y = 2e20; return; } else { last_y = posy; } } if (last_y < 1e20) { // in drag started with Control Key const double scaling = 0.005; double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling); value = (last_y - posy) * scal; last_y = posy; gtk_range_set_value(GTK_RANGE(widget), gtk_adjustment_get_value(adj) - value * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))); return; } double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI if (drag) { // block "forbidden zone" and direct moves between quadrant 1 and 4 int quadrant = 1 + (int)(angle/M_PI_2); if (priv->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) { angle = scale_zero; } else if (priv->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) { angle = 2*M_PI - scale_zero; } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } priv->last_quadrant = quadrant; } } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } priv->last_quadrant = 0; } angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1 gtk_range_set_value(GTK_RANGE(widget), gtk_adjustment_get_lower(adj) + angle * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))); g_free (allocation); } /**************************************************************** ** mouse button pressed set value */ static gboolean gtk_knob_button_press (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnob *knob = GTK_KNOB(widget); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); switch (event->button) { case 1: // left button gtk_widget_grab_focus(widget); gtk_widget_grab_default (widget); gtk_grab_add(widget); priv->button_is = 1; knob_pointer_event(widget, event->x, event->y, priv->knob_x, priv->knob_y, FALSE, event->state); break; case 2: //wheel priv->button_is = 2; break; case 3: // right button priv->button_is = 3; break; default: // do nothing break; } return TRUE; } /**************************************************************** ** mouse button release */ static gboolean gtk_knob_button_release (GtkWidget *widget, GdkEventButton *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnob *knob = GTK_KNOB(widget); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); priv->button_is = 0; if (gtk_widget_has_grab(widget)) gtk_grab_remove(widget); return FALSE; } /**************************************************************** ** set the value from mouse movement */ static gboolean gtk_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event) { g_assert(GTK_IS_KNOB(widget)); GtkKnob *knob = GTK_KNOB(widget); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); gdk_event_request_motions (event); if (gtk_widget_has_grab(widget)) { knob_pointer_event(widget, event->x, event->y, priv->knob_x, priv->knob_y, TRUE, event->state); } return FALSE; } /**************************************************************** ** set value from mouseweel */ static gboolean gtk_knob_scroll (GtkWidget *widget, GdkEventScroll *event) { g_assert(GTK_IS_KNOB(widget)); if(event->delta_y < 0) gtk_knob_set_value(widget, 0); else if (event->delta_y > 0) gtk_knob_set_value(widget, 1); return FALSE; } static void gtk_knob_map (GtkWidget *widget) { GTK_WIDGET_CLASS (gtk_knob_parent_class)->map (widget); } static void gtk_knob_unmap (GtkWidget *widget) { GTK_WIDGET_CLASS (gtk_knob_parent_class)->unmap (widget); } static void gtk_knob_get_preferred_size (GtkWidget *widget, GtkOrientation orientation, gint *minimal_size, gint *natural_size) { if (orientation == GTK_ORIENTATION_HORIZONTAL) { *minimal_size = *natural_size = 62; } else { *minimal_size = *natural_size = 25; } } static void gtk_knob_get_preferred_width ( GtkWidget *widget, gint *minimal_width, gint *natural_width) { gtk_knob_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimal_width, natural_width); } static void gtk_knob_get_preferred_height ( GtkWidget *widget, gint *minimal_height, gint *natural_height) { gtk_knob_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimal_height, natural_height); } /**************************************************************** ** init the GtkKnobClass */ static void gtk_knob_class_init (GtkKnobClass *klass) { GObjectClass *obj_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); //--------- connect the events with funktions widget_class->map = gtk_knob_map; widget_class->unmap = gtk_knob_unmap; widget_class->draw = gtk_knob_expose; widget_class->get_preferred_width = gtk_knob_get_preferred_width; widget_class->get_preferred_height = gtk_knob_get_preferred_height; widget_class->button_press_event = gtk_knob_button_press; widget_class->button_release_event = gtk_knob_button_release; widget_class->motion_notify_event = gtk_knob_pointer_motion; widget_class->key_press_event = gtk_knob_key_press; widget_class->scroll_event = gtk_knob_scroll; g_type_class_add_private(obj_class, sizeof (GtkKnobPrivate)); } /**************************************************************** ** init the Knob type/size */ static void gtk_knob_init (GtkKnob *knob) { g_assert(GTK_IS_KNOB(knob)); GtkWidget *widget = GTK_WIDGET(knob); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(knob); priv->knob_x = 62; priv->knob_y = 25; priv->knob_step = 86; priv->button_is = 0; priv->order = 2; gtk_widget_set_can_focus (widget, true); gtk_widget_set_can_default(widget, true); } /**************************************************************** ** redraw when value changed */ static gboolean gtk_knob_value_changed(gpointer obj) { GtkWidget *widget = (GtkWidget *)obj; g_assert(GTK_IS_KNOB(widget)); gtk_widget_queue_draw(widget); return FALSE; } /**************************************************************** ** create small knob */ GtkWidget *gtk_knob_new_with_value_label(GtkAdjustment *_adjustment, int order) { GtkWidget *widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL )); GtkKnobPrivate *priv = GTK_KNOB_GET_PRIVATE(widget); priv->order = order; if (widget) { gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment); g_signal_connect(G_OBJECT(widget), "value-changed", G_CALLBACK(gtk_knob_value_changed), widget); } return widget; } gxtuner-3.0/gtkknob.h000066400000000000000000000037331321541042300146610ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: gtkknob.h guitar tuner for jack * * ---------------------------------------------------------------------------- */ #ifndef __GTK_KNOB_H__ #define __GTK_KNOB_H__ #ifdef __cplusplus extern "C" { #endif #pragma once #include G_BEGIN_DECLS #define GTK_TYPE_KNOB (gtk_knob_get_type()) #define GTK_KNOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob)) #define GTK_IS_KNOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB)) #define GTK_KNOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_KNOB, GtkKnobClass)) #define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_KNOB)) #define GTK_KNOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_KNOB, GtkKnobClass)) typedef struct _GtkKnob GtkKnob; typedef struct _GtkKnobClass GtkKnobClass; struct _GtkKnob { GtkRange parent; }; struct _GtkKnobClass { GtkRangeClass parent_class; }; //------forward declaration GType gtk_knob_get_type (void); GtkWidget *gtk_knob_new_with_value_label(GtkAdjustment *_adjustment, int order); G_END_DECLS #ifdef __cplusplus } #endif #endif gxtuner-3.0/gx_pitch_tracker.cpp000066400000000000000000000353561321541042300171030ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert * Copyright (C) 2011 Pete Shorthose * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * -------------------------------------------------------------------------- */ /* ------- This is the guitarix tuner, part of gx_engine_audio.cpp ------- */ /**************************************************************** ** Pitch Tracker ** ** some code and ideas taken from K4Guitune (William Spinelli) ** changed to NSDF method (some code from tartini / Philip McLeod) ** */ #include "./gx_pitch_tracker.h" // downsampling factor static const int DOWNSAMPLE = 2; static const float SIGNAL_THRESHOLD_ON = 0.001; static const float SIGNAL_THRESHOLD_OFF = 0.0009; static const float TRACKER_PERIOD = 0.1; // The size of the read buffer static const int FFT_SIZE = 2048; #define max(x, y) (((x) > (y)) ? (x) : (y)) #define min(x, y) (((x) < (y)) ? (x) : (y)) inline void Dsp::clear_state_f() { for (int i=0; i<2; i++) iVec0[i] = 0; for (int i=0; i<2; i++) fRec4[i] = 0; for (int i=0; i<2; i++) fVec1[i] = 0; for (int i=0; i<2; i++) fRec3[i] = 0; for (int i=0; i<2; i++) fRec2[i] = 0; for (int i=0; i<3; i++) fRec1[i] = 0; for (int i=0; i<3; i++) fRec0[i] = 0; } inline void Dsp::init(int samplingFreq) { fSamplingFreq = samplingFreq; iConst0 = min(192000, max(1, fSamplingFreq)); fConst1 = tan((3138.4510609362032 / double(iConst0))); fConst2 = (2 * (1 - (1.0 / pow(fConst1,2)))); fConst3 = (1.0 / fConst1); fConst4 = (1 + ((fConst3 - 0.7653668647301795) / fConst1)); fConst5 = (1.0 / (1 + ((0.7653668647301795 + fConst3) / fConst1))); fConst6 = (1 + ((fConst3 - 1.8477590650225735) / fConst1)); fConst7 = (1.0 / (1 + ((fConst3 + 1.8477590650225735) / fConst1))); fConst8 = (72.25663103256524 / double(iConst0)); fConst9 = (1 - fConst8); fConst10 = (1.0 / (1 + fConst8)); clear_state_f(); } void Dsp::compute(int count, float *input0, float *output0) { for (int i=0; i(p))->run(); return NULL; } PitchTracker::PitchTracker() : error(false), busy(false), tick(0), m_pthr(0), resamp(), m_sampleRate(), fixed_sampleRate(41000), m_freq(-1), signal_threshold_on(SIGNAL_THRESHOLD_ON), signal_threshold_off(SIGNAL_THRESHOLD_OFF), tracker_period(TRACKER_PERIOD), m_buffersize(), m_fftSize(), m_buffer(new float[FFT_SIZE]), m_bufferIndex(0), m_input(new float[FFT_SIZE]), m_audioLevel(false), m_fftwPlanFFT(0), m_fftwPlanIFFT(0) { const int size = FFT_SIZE + (FFT_SIZE+1) / 2; m_fftwBufferTime = reinterpret_cast (fftwf_malloc(size * sizeof(*m_fftwBufferTime))); m_fftwBufferFreq = reinterpret_cast (fftwf_malloc(size * sizeof(*m_fftwBufferFreq))); memset(m_buffer, 0, FFT_SIZE * sizeof(*m_buffer)); memset(m_input, 0, FFT_SIZE * sizeof(*m_input)); memset(m_fftwBufferTime, 0, size * sizeof(*m_fftwBufferTime)); memset(m_fftwBufferFreq, 0, size * sizeof(*m_fftwBufferFreq)); sem_init(&m_trig, 0, 0); if (!m_buffer || !m_input || !m_fftwBufferTime || !m_fftwBufferFreq) { error = true; } } PitchTracker::~PitchTracker() { stop_thread(); fftwf_destroy_plan(m_fftwPlanFFT); fftwf_destroy_plan(m_fftwPlanIFFT); fftwf_free(m_fftwBufferTime); fftwf_free(m_fftwBufferFreq); delete[] m_input; delete[] m_buffer; } void PitchTracker::set_threshold(float v) { signal_threshold_on = v; signal_threshold_off = v*0.9; } float PitchTracker::get_threshold() { // Value of the threshold above which the processing is activated. return signal_threshold_on; } void PitchTracker::set_fast_note_detection(bool v) { if (v) { signal_threshold_on = SIGNAL_THRESHOLD_ON * 5; signal_threshold_off = SIGNAL_THRESHOLD_OFF * 5; tracker_period = TRACKER_PERIOD / 10; } else { signal_threshold_on = SIGNAL_THRESHOLD_ON; signal_threshold_off = SIGNAL_THRESHOLD_OFF; tracker_period = TRACKER_PERIOD; } } bool PitchTracker::setParameters(int sampleRate, int buffersize, pthread_t j_thread) { assert(buffersize <= FFT_SIZE); if (error) { return false; } m_sampleRate = fixed_sampleRate / DOWNSAMPLE; resamp.setup(sampleRate, m_sampleRate, 1, 16); // 16 == least quality jack_thread = j_thread; if (m_buffersize != buffersize) { m_buffersize = buffersize; m_fftSize = m_buffersize + (m_buffersize+1) / 2; fftwf_destroy_plan(m_fftwPlanFFT); fftwf_destroy_plan(m_fftwPlanIFFT); m_fftwPlanFFT = fftwf_plan_r2r_1d( m_fftSize, m_fftwBufferTime, m_fftwBufferFreq, FFTW_R2HC, FFTW_ESTIMATE); m_fftwPlanIFFT = fftwf_plan_r2r_1d( m_fftSize, m_fftwBufferFreq, m_fftwBufferTime, FFTW_HC2R, FFTW_ESTIMATE); } if (!m_fftwPlanFFT || !m_fftwPlanIFFT) { error = true; return false; } if (!m_pthr) { start_thread(); } low_high_cut.init(sampleRate); return !error; } void PitchTracker::stop_thread() { pthread_cancel (m_pthr); pthread_join (m_pthr, NULL); } void PitchTracker::start_thread() { int min = 0, max = 0; pthread_attr_t attr; struct sched_param spar; int priority, policy; pthread_getschedparam(jack_thread, &policy, &spar); priority = spar.sched_priority; min = sched_get_priority_min(policy); max = sched_get_priority_max(policy); priority -= 6; // zita-convoler uses 5 levels if (priority > max) priority = max; if (priority < min) priority = min; spar.sched_priority = priority; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE ); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL); pthread_attr_setschedpolicy(&attr, policy); pthread_attr_setschedparam(&attr, &spar); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); // pthread_attr_setstacksize(&attr, 0x10000); if (pthread_create(&m_pthr, &attr, static_run, reinterpret_cast(this))) { error = true; } pthread_attr_destroy(&attr); } void PitchTracker::init(int samplerate, pthread_t j_thread) { setParameters(samplerate, FFT_SIZE, j_thread); } void PitchTracker::reset() { tick = 0; m_bufferIndex = 0; resamp.reset(); m_freq = -1; } void PitchTracker::add(int count, float* input) { if (error) { return; } float output[count]; low_high_cut.compute(count,input,output); resamp.inp_count = count; resamp.inp_data = output; for (;;) { resamp.out_data = &m_buffer[m_bufferIndex]; int n = FFT_SIZE - m_bufferIndex; resamp.out_count = n; resamp.process(); n -= resamp.out_count; // n := number of output samples if (!n) { // all soaked up by filter return; } m_bufferIndex = (m_bufferIndex + n) % FFT_SIZE; if (resamp.inp_count == 0) { break; } } if (++tick * count >= m_sampleRate * DOWNSAMPLE * tracker_period) { if (busy) { return; } busy = true; tick = 0; copy(); sem_post(&m_trig); } } void PitchTracker::copy() { int start = (FFT_SIZE + m_bufferIndex - m_buffersize) % FFT_SIZE; int end = (FFT_SIZE + m_bufferIndex) % FFT_SIZE; int cnt = 0; if (start >= end) { cnt = FFT_SIZE - start; memcpy(m_input, &m_buffer[start], cnt * sizeof(*m_input)); start = 0; } memcpy(&m_input[cnt], &m_buffer[start], (end - start) * sizeof(*m_input)); } inline float sq(float x) { return x * x; } inline void parabolaTurningPoint(float y_1, float y0, float y1, float xOffset, float *x) { float yTop = y_1 - y1; float yBottom = y1 + y_1 - 2 * y0; if (yBottom != 0.0) { *x = xOffset + yTop / (2 * yBottom); } else { *x = xOffset; } } static int findMaxima(float *input, int len, int *maxPositions, int *length, int maxLen) { int pos = 0; int curMaxPos = 0; int overallMaxIndex = 0; while (pos < (len-1)/3 && input[pos] > 0.0) { pos += 1; // find the first negitive zero crossing } while (pos < len-1 && input[pos] <= 0.0) { pos += 1; // loop over all the values below zero } if (pos == 0) { pos = 1; // can happen if output[0] is NAN } while (pos < len-1) { if (input[pos] > input[pos-1] && input[pos] >= input[pos+1]) { // a local maxima if (curMaxPos == 0) { curMaxPos = pos; // the first maxima (between zero crossings) } else if (input[pos] > input[curMaxPos]) { curMaxPos = pos; // a higher maxima (between the zero crossings) } } pos += 1; if (pos < len-1 && input[pos] <= 0.0) { // a negative zero crossing if (curMaxPos > 0) { // if there was a maximum maxPositions[*length] = curMaxPos; // add it to the vector of maxima *length += 1; if (overallMaxIndex == 0) { overallMaxIndex = curMaxPos; } else if (input[curMaxPos] > input[overallMaxIndex]) { overallMaxIndex = curMaxPos; } if (*length >= maxLen) { return overallMaxIndex; } curMaxPos = 0; // clear the maximum position, so we start looking for a new ones } while (pos < len-1 && input[pos] <= 0.0) { pos += 1; // loop over all the values below zero } } } if (curMaxPos > 0) { // if there was a maximum in the last part maxPositions[*length] = curMaxPos; // add it to the vector of maxima *length += 1; if (overallMaxIndex == 0) { overallMaxIndex = curMaxPos; } else if (input[curMaxPos] > input[overallMaxIndex]) { overallMaxIndex = curMaxPos; } curMaxPos = 0; // clear the maximum position, so we start looking for a new ones } return overallMaxIndex; } static int findsubMaximum(float *input, int len, float threshold) { int indices[10]; int length = 0; int overallMaxIndex = findMaxima(input, len, indices, &length, 10); if (length == 0) { return -1; } threshold += (1.0 - threshold) * (1.0 - input[overallMaxIndex]); float cutoff = input[overallMaxIndex] * threshold; for (int j = 0; j < length; j++) { if (input[indices[j]] >= cutoff) { return indices[j]; } } // should never get here return -1; } void PitchTracker::run() { for (;;) { busy = false; sem_wait(&m_trig); if (error) { continue; } float sum = 0.0; for (int k = 0; k < m_buffersize; ++k) { sum += fabs(m_input[k]); } float threshold = (m_audioLevel ? signal_threshold_off : signal_threshold_on); m_audioLevel = (sum / m_buffersize >= threshold); if ( m_audioLevel == false ) { if (m_freq != 0) { m_freq = 0; //new_freq(); } continue; } memcpy(m_fftwBufferTime, m_input, m_buffersize * sizeof(*m_fftwBufferTime)); memset(m_fftwBufferTime+m_buffersize, 0, (m_fftSize - m_buffersize) * sizeof(*m_fftwBufferTime)); fftwf_execute(m_fftwPlanFFT); for (int k = 1; k < m_fftSize/2; k++) { m_fftwBufferFreq[k] = sq(m_fftwBufferFreq[k]) + sq(m_fftwBufferFreq[m_fftSize-k]); m_fftwBufferFreq[m_fftSize-k] = 0.0; } m_fftwBufferFreq[0] = sq(m_fftwBufferFreq[0]); m_fftwBufferFreq[m_fftSize/2] = sq(m_fftwBufferFreq[m_fftSize/2]); fftwf_execute(m_fftwPlanIFFT); double sumSq = 2.0 * static_cast(m_fftwBufferTime[0]) / static_cast(m_fftSize); for (int k = 0; k < m_fftSize - m_buffersize; k++) { m_fftwBufferTime[k] = m_fftwBufferTime[k+1] / static_cast(m_fftSize); } int count = (m_buffersize + 1) / 2; for (int k = 0; k < count; k++) { sumSq -= sq(m_input[m_buffersize-1-k]) + sq(m_input[k]); // dividing by zero is very slow, so deal with it seperately if (sumSq > 0.0) { m_fftwBufferTime[k] *= 2.0 / sumSq; } else { m_fftwBufferTime[k] = 0.0; } } const float thres = 0.99; // was 0.6 int maxAutocorrIndex = findsubMaximum(m_fftwBufferTime, count, thres); float x = 0.0; if (maxAutocorrIndex >= 0) { parabolaTurningPoint(m_fftwBufferTime[maxAutocorrIndex-1], m_fftwBufferTime[maxAutocorrIndex], m_fftwBufferTime[maxAutocorrIndex+1], maxAutocorrIndex+1, &x); x = m_sampleRate / x; if (x > 1060.0) { // precision drops above 1000 Hz x = 0.0; } } if (m_freq != x) { m_freq = x; //new_freq(); } } } float PitchTracker::get_estimated_note() { return m_freq <= 0.0 ? 1000.0 : 12 * log2f(2.272727e-03f * m_freq); } PitchTracker pitch_tracker; gxtuner-3.0/gx_pitch_tracker.h000066400000000000000000000100201321541042300165250ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert * Copyright (C) 2011 Pete Shorthose * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * -------------------------------------------------------------------------- */ #pragma once #ifndef GX_PITCH_TRACKER_H_ #define GX_PITCH_TRACKER_H_ #include #include #include #include //#include #include #include #include #include "resample.h" /* ------------- Pitch Tracker ------------- */ class Dsp { private: int fSamplingFreq; int iVec0[2]; int iConst0; double fConst1; double fConst2; double fConst3; double fConst4; double fConst5; double fConst6; double fConst7; double fConst8; double fConst9; double fRec4[2]; double fVec1[2]; double fConst10; double fRec3[2]; double fRec2[2]; double fRec1[3]; double fRec0[3]; public: void clear_state_f(); void init(int samplingFreq); void compute(int count, float *input0, float *output0); }; class PitchTracker { public: explicit PitchTracker(); ~PitchTracker(); void init(int samplerate, pthread_t j_thread); void add(int count, float *input); float get_estimated_freq() { return m_freq < 0 ? 0 : m_freq; } float get_estimated_note(); void stop_thread(); void reset(); void set_threshold(float v); float get_threshold(); void set_fast_note_detection(bool v); //Glib::Dispatcher new_freq; private: Dsp low_high_cut; bool setParameters(int sampleRate, int buffersize, pthread_t j_thread); void run(); static void *static_run(void* p); void start_thread(); void copy(); bool error; volatile bool busy; int tick; sem_t m_trig; pthread_t m_pthr; pthread_t jack_thread; Resampler resamp; int m_sampleRate; int fixed_sampleRate; float m_freq; // Value of the threshold above which // the processing is activated. float signal_threshold_on; // Value of the threshold below which // the input audio signal is deactivated. float signal_threshold_off; // Time between frequency estimates (in seconds) float tracker_period; // number of samples in input buffer int m_buffersize; // Size of the FFT window. int m_fftSize; // The audio buffer that stores the input signal. float *m_buffer; // Index of the first empty position in the buffer. int m_bufferIndex; // buffer for input signal float *m_input; // Whether or not the input level is high enough. bool m_audioLevel; // Support buffer used to store signals in the time domain. float *m_fftwBufferTime; // Support buffer used to store signals in the frequency domain. float *m_fftwBufferFreq; // Plan to compute the FFT of a given signal. fftwf_plan m_fftwPlanFFT; // Plan to compute the IFFT of a given signal (with additional zero-padding). fftwf_plan m_fftwPlanIFFT; }; extern PitchTracker pitch_tracker; #endif // SRC_HEADERS_GX_PITCH_TRACKER_H_ gxtuner-3.0/gxtuner.cpp000066400000000000000000001572571321541042300152640ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: gxtuner.cpp guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "./gxtuner.h" #include #include #include #define P_(s) (s) // FIXME -> gettext // Use propertys to set variables for the widget from outside, // add new propertys here in the enum enum { PROP_FREQ = 1, PROP_REFERENCE_PITCH = 2, PROP_MODE = 3, PROP_REFERENCE_NOTE =4, PROP_REFERENCE_03COMMA =5, PROP_REFERENCE_05COMMA =6, PROP_REFERENCE_07COMMA =7, PROP_REFERENCE_11COMMA =8, PROP_REFERENCE_13COMMA =9, PROP_REFERENCE_17COMMA =10, PROP_REFERENCE_19COMMA =11, PROP_REFERENCE_23COMMA =12, PROP_REFERENCE_29COMMA =13, PROP_REFERENCE_31COMMA =14, }; static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr); static void draw_background(cairo_surface_t *surface_tuner); static void gx_tuner_class_init (GxTunerClass *klass); static void gx_tuner_base_class_finalize(GxTunerClass *klass); static void gx_tuner_init(GxTuner *tuner); static void gx_tuner_set_property( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gx_tuner_get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static void gx_tuner_destroy(GObject *object); static const int tuner_width = 100; static const int tuner_height = 60; static const double rect_width = 100; static const double rect_height = 60; static int cents = 0; static float mini_cents = 0.0; // base scale: 3limit diatonic (Pythagorean) static int scale3base[7][NRPRIMES] = { //{notename,2,3,5,7,11,13,17,19,23,29,31} {0,2,-1,0,0,0,0,0,0,0,0,0}, //F 0 {0,0,0,0,0,0,0,0,0,0,0,0}, //C 1 {0,-1,1,0,0,0,0,0,0,0,0,0}, //G 2 {0,-3,2,0,0,0,0,0,0,0,0,0}, //D 3 {0,-4,3,0,0,0,0,0,0,0,0,0}, //A 4 {0,-6,4,0,0,0,0,0,0,0,0,0}, //E 5 {0,-7,5,0,0,0,0,0,0,0,0,0} //B 6 }; const char* scale3basenames[7] = {"F","C","G","D","A","E","B"}; static int a03comma[NRPRIMES] = {0,-11,7,0,0,0,0,0,0,0,0,0}; static int a05comma[NRPRIMES] = {0,-4,4,-1,0,0,0,0,0,0,0,0}; static int a07comma[NRPRIMES] = {0,-6,2,0,1,0,0,0,0,0,0,0}; static int a11comma[NRPRIMES] = {0,-5,1,0,0,1,0,0,0,0,0,0}; static int a13comma[NRPRIMES] = {0,-10,4,0,0,0,1,0,0,0,0,0}; static int a17comma[NRPRIMES] = {0,7,-7,0,0,0,0,1,0,0,0,0}; static int a19comma[NRPRIMES] = {0,-9,3,0,0,0,0,0,1,0,0,0}; static int a23comma[NRPRIMES] = {0,5,-6,0,0,0,0,0,0,1,0,0}; static int a29comma[NRPRIMES] = {0,-8,2,0,0,0,0,0,0,0,1,0}; static int a31comma[NRPRIMES] = {0,3,-5,0,0,0,0,0,0,0,0,1}; //here we define the scales. Every row of the array has 11 digits. The first static int scale3diatonic[7][NRPRIMES] = { //notename+integers for the comma's {1,0,0,0,0,0,0,0,0,0,0,0}, //C {3,0,0,0,0,0,0,0,0,0,0,0}, //D {5,0,0,0,0,0,0,0,0,0,0,0}, //E {0,0,0,0,0,0,0,0,0,0,0,0}, //F {2,0,0,0,0,0,0,0,0,0,0,0}, //G {4,0,0,0,0,0,0,0,0,0,0,0}, //A {6,0,0,0,0,0,0,0,0,0,0,0} //B }; static int numnotesscale3diatonic = 7; static int scale35chromatic[12][NRPRIMES] = { //basenote,2,3,5,7,11,13,17,19,23,29,31 {1,0,0,0,0,0,0,0,0,0,0,0}, //C {1,0,1,0,0,0,0,0,0,0,0,0}, //C♯ {3,0,0,0,0,0,0,0,0,0,0,0}, //D {5,0,-1,1,0,0,0,0,0,0,0,0}, //Eb+ {5,0,0,-1,0,0,0,0,0,0,0,0}, //E- {0,0,0,0,0,0,0,0,0,0,0,0}, //F {2,0,-1,-1,0,0,0,0,0,0,0,0}, //Gb 36/25 {2,0,0,0,0,0,0,0,0,0,0,0}, //G {4,0,-1,1,0,0,0,0,0,0,0,0}, //Ab+ 8/5 {4,0,0,-1,0,0,0,0,0,0,0,0}, //A- 5/3 {6,0,-1,1,0,0,0,0,0,0,0,0}, //Bb+ 9/5 {6,0,0,-1,0,0,0,0,0,0,0,0} //B- 15/8 }; static int numnotesscale35chromatic = 12; static int scale357chromatic[22][NRPRIMES] = { //basenote,2,3,5,7,11,13,17,19,23,29,31 {1,0,0,0,0,0,0,0,0,0,0,0}, //C {3,0,-1,0,1,0,0,0,0,0,0,0}, //Db7 28/27 {3,0,-1,1,0,0,0,0,0,0,0,0}, //Db+ 16/15 {3,0,0,-1,0,0,0,0,0,0,0,0}, //D- 10/9 {3,0,0,0,-1,0,0,0,0,0,0,0}, //DL 8/7 {5,0,-1,0,1,0,0,0,0,0,0,0}, //Eb7 7/6 {5,0,-1,1,0,0,0,0,0,0,0,0}, //Eb+ 6/5 {5,0,0,-1,0,0,0,0,0,0,0,0}, //E- 5/4 {5,0,0,0,-1,0,0,0,0,0,0,0}, //EL 9/7 {0,0,0,0,1,0,0,0,0,0,0,0}, //F7 21/16 {0,0,0,1,0,0,0,0,0,0,0,0}, //F+ 27/20 {0,0,1,-1,0,0,0,0,0,0,0,0}, //F#- 45/32 {0,0,1,0,-1,0,0,0,0,0,0,0}, //F#L 81/56 {2,0,0,0,0,0,0,0,0,0,0,0}, //G 3/2 {4,0,-1,0,1,0,0,0,0,0,0,0}, //Ab7 14/9 {4,0,-1,1,0,0,0,0,0,0,0,0}, //Ab+ 8/5 {4,0,0,-1,0,0,0,0,0,0,0,0}, //A- 5/3 {4,0,0,0,-1,0,0,0,0,0,0,0}, //AL 12/7 {6,0,-1,0,1,0,0,0,0,0,0,0}, //Bb7 7/4 {6,0,-1,1,0,0,0,0,0,0,0,0}, //Bb+ 9/5 {6,0,0,-1,0,0,0,0,0,0,0,0}, //B- 15/8 {6,0,0,0,-1,0,0,0,0,0,0,0} //BL 27/14 }; static int numnotesscale357chromatic = 22; static int scale37chromatic[12][NRPRIMES] = { //basenote,2,3,5,7,11,13,17,19,23,29,31 {1,0,0,0,0,0,0,0,0,0,0,0}, //C 1/1 {3,0,-1,0,1,0,0,0,0,0,0,0}, //Db7 49/48 {3,0,0,0,0,0,0,0,0,0,0,0}, //D 9/8 {5,0,-1,0,1,0,0,0,0,0,0,0}, //Eb7 7/6 {5,0,0,0,-1,0,0,0,0,0,0,0}, //EL 9/7 {0,0,0,0,0,0,0,0,0,0,0,0}, //F 4/3 {0,0,1,0,-2,0,0,0,0,0,0,0}, //F#LL 72/49 {2,0,0,0,0,0,0,0,0,0,0,0}, //G 3/2 {4,0,-1,0,1,0,0,0,0,0,0,0}, //Ab7 14/9 {4,0,0,0,-1,0,0,0,0,0,0,0}, //AL 12/7 {6,0,-1,0,1,0,0,0,0,0,0,0}, //Bb7 7/4 {6,0,0,0,-1,0,0,0,0,0,0,0} //BL 27/14 }; static int numnotesscale37chromatic = 12; static int scaleovertones[8][NRPRIMES] = { //basenote,2,3,5,7,11,13,17,19,23,29,31 {1,0,0,0,0,0,0,0,0,0,0,0}, //C 1/1 {3,0,0,0,0,0,0,0,0,0,0,0}, //D 9/8 {5,0,0,-1,0,0,0,0,0,0,0,0}, //E- 5/4 {0,0,0,0,0,1,0,0,0,0,0,0}, //F11 11/8 {2,0,0,0,0,0,0,0,0,0,0,0}, //G 3/2 {4,0,-1,0,0,0,1,0,0,0,0,0}, //Ab13 13/8 {6,0,-1,0,1,0,0,0,0,0,0,0}, //Bb7 7/4 {6,0,0,-1,0,0,0,0,0,0,0,0}, //B- 15/8 }; static int numnotesscaleovertones = 8; static const double dashline[] = { 3.0 }; static const double dashes[] = { 0.0, /* ink */ rect_height, /* skip */ 10.0, /* ink */ 10.0 /* skip */ }; static const double dash_ind[] = { 0, /* ink */ 14, /* skip */ rect_height-18, /* ink */ 100.0 /* skip */ }; static const double no_dash[] = { 1000, /* ink */ 0, /* skip */ 1000, /* ink */ 0 /* skip */ }; static void gx_tuner_get_preferred_size (GtkWidget *widget, GtkOrientation orientation, gint *minimal_size, gint *natural_size) { if (orientation == GTK_ORIENTATION_HORIZONTAL) { *minimal_size = *natural_size = 100; } else { *minimal_size = *natural_size = 60; } } static void gx_tuner_get_preferred_width ( GtkWidget *widget, gint *minimal_width, gint *natural_width) { gx_tuner_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimal_width, natural_width); } static void gx_tuner_get_preferred_height ( GtkWidget *widget, gint *minimal_height, gint *natural_height) { gx_tuner_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimal_height, natural_height); } GType gx_tuner_get_type(void) { static GType tuner_type = 0; if (!tuner_type) { const GTypeInfo tuner_info = { sizeof (GxTunerClass), NULL, /* base_class_init */ (GBaseFinalizeFunc) gx_tuner_base_class_finalize, (GClassInitFunc) gx_tuner_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (GxTuner), 0, /* n_preallocs */ (GInstanceInitFunc) gx_tuner_init, NULL, /* value_table */ }; tuner_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "GxTuner", &tuner_info, (GTypeFlags)0); } return tuner_type; } static void gx_tuner_class_init(GxTunerClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); widget_class->draw = gtk_tuner_expose; widget_class->get_preferred_width = gx_tuner_get_preferred_width; widget_class->get_preferred_height = gx_tuner_get_preferred_height; // here we setup get and set methodes for the properties gobject_class->set_property = gx_tuner_set_property; gobject_class->get_property = gx_tuner_get_property; // here we install the propertys for the widget, add new // properties here g_object_class_install_property( gobject_class, PROP_FREQ, g_param_spec_double ( "freq", P_("Frequency"), P_("The frequency for which tuning is displayed"), 0.0, 1000.0, 0.0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_PITCH, g_param_spec_double ( "reference-pitch", P_("Reference Pitch"), P_("The frequency for which tuning is displayed"), 400.0, 500.0, 440.0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_MODE, g_param_spec_int ( "mode", P_("Tuning Mode"), P_("The Mode for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_NOTE, g_param_spec_int ( //#2 "reference-note", P_("Reference note"), P_("The note for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_03COMMA, g_param_spec_int ( "reference-03comma", P_("Reference 03 comma"), P_("The 03 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_05COMMA, g_param_spec_int ( "reference-05comma", P_("Reference 05 comma"), P_("The 05 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_07COMMA, g_param_spec_int ( "reference-07comma", P_("Reference 07 comma"), P_("The 07 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_11COMMA, g_param_spec_int ( "reference-11comma", P_("Reference 11 comma"), P_("The 11 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_13COMMA, g_param_spec_int ( "reference-13comma", P_("Reference 13 comma"), P_("The 13 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_17COMMA, g_param_spec_int ( "reference-17comma", P_("Reference 17 comma"), P_("The 17 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_19COMMA, g_param_spec_int ( "reference-19comma", P_("Reference 19 comma"), P_("The 19 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_23COMMA, g_param_spec_int ( "reference-23comma", P_("Reference 23 comma"), P_("The 23 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_29COMMA, g_param_spec_int ( "reference-29comma", P_("Reference 29 comma"), P_("The 29 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class, PROP_REFERENCE_31COMMA, g_param_spec_int ( "reference-31comma", P_("Reference 31 comma"), P_("The 31 comma for which tuning is displayed"), 0, 1, 0, G_PARAM_READWRITE)); gobject_class->finalize = gx_tuner_destroy; klass->surface_tuner = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, tuner_width*3., tuner_height*3.); g_assert(klass->surface_tuner != NULL); draw_background(klass->surface_tuner); } static void gx_tuner_destroy(GObject *object) { g_return_if_fail (object != NULL); g_return_if_fail (GX_IS_TUNER (object)); GxTuner *tuner = GX_TUNER(object); for(int i=0;itempscaletranslatednames[i]); } } static void gx_tuner_base_class_finalize(GxTunerClass *klass) { if (klass->surface_tuner) { g_object_unref(klass->surface_tuner); } } static void gx_tuner_init (GxTuner *tuner) { // here we set all propertys to a default value g_assert(GX_IS_TUNER(tuner)); tuner->freq = 0; tuner->reference_pitch = 440.0; tuner->mode = 1; tuner->reference_note = 1; //#3 tuner->reference_03comma = 3; tuner->reference_05comma = 3; tuner->reference_07comma = 3; tuner->reference_11comma = 3; tuner->reference_13comma = 3; tuner->reference_17comma = 3; tuner->reference_19comma = 3; tuner->reference_23comma = 3; tuner->reference_29comma = 3; tuner->reference_31comma = 3; tuner->scale_w = 1.; tuner->scale_h = 1.; for(int i=0;itempscaletranslatednames[i] = (char*)malloc(sizeof(char*)); // allocate } for(int n=0;ntempscaletranslated[n][i]=0; } } //GtkWidget *widget = GTK_WIDGET(tuner); } // this are the function calls to set the propertys called by // gx_tuner_set_property, here we set the internal var to the // value of the property void gx_tuner_set_freq(GxTuner *tuner, double freq) { g_assert(GX_IS_TUNER(tuner)); if (tuner->freq != freq) { tuner->freq = freq; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "freq"); } } void gx_tuner_set_reference_pitch(GxTuner *tuner, double reference_pitch) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_pitch = reference_pitch; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-pitch"); } void gx_tuner_set_mode(GxTuner *tuner, int mode) { g_assert(GX_IS_TUNER(tuner)); tuner->mode = mode; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "mode"); } void gx_tuner_set_reference_note(GxTuner *tuner, int reference_note) { //#4 g_assert(GX_IS_TUNER(tuner)); tuner->reference_note = reference_note; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-note"); } void gx_tuner_set_reference_03comma(GxTuner *tuner, int reference_03comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_03comma = reference_03comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-03comma"); } void gx_tuner_set_reference_05comma(GxTuner *tuner, int reference_05comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_05comma = reference_05comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-05comma"); } void gx_tuner_set_reference_07comma(GxTuner *tuner, int reference_07comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_07comma = reference_07comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-07comma"); } void gx_tuner_set_reference_11comma(GxTuner *tuner, int reference_11comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_11comma = reference_11comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-11comma"); } void gx_tuner_set_reference_13comma(GxTuner *tuner, int reference_13comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_13comma = reference_13comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-13comma"); } void gx_tuner_set_reference_17comma(GxTuner *tuner, int reference_17comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_17comma = reference_17comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-17comma"); } void gx_tuner_set_reference_19comma(GxTuner *tuner, int reference_19comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_19comma = reference_19comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-19comma"); } void gx_tuner_set_reference_23comma(GxTuner *tuner, int reference_23comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_23comma = reference_23comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-23comma"); } void gx_tuner_set_reference_29comma(GxTuner *tuner, int reference_29comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_29comma = reference_29comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-29comma"); } void gx_tuner_set_reference_31comma(GxTuner *tuner, int reference_31comma) { g_assert(GX_IS_TUNER(tuner)); tuner->reference_31comma = reference_31comma; gtk_widget_queue_draw(GTK_WIDGET(tuner)); g_object_notify(G_OBJECT(tuner), "reference-31comma"); } double gx_tuner_get_reference_pitch(GxTuner *tuner) { g_assert(GX_IS_TUNER(tuner)); return tuner->reference_pitch; } GtkWidget *gx_tuner_new(void) { return (GtkWidget*)g_object_new(GX_TYPE_TUNER, NULL); } // here we set properties, add new ones here static void gx_tuner_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GxTuner *tuner = GX_TUNER(object); switch(prop_id) { case PROP_FREQ: gx_tuner_set_freq(tuner, g_value_get_double(value)); break; case PROP_REFERENCE_PITCH: gx_tuner_set_reference_pitch(tuner, g_value_get_double(value)); break; case PROP_MODE: gx_tuner_set_mode(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_NOTE: //#5 gx_tuner_set_reference_note(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_03COMMA: gx_tuner_set_reference_03comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_07COMMA: gx_tuner_set_reference_07comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_11COMMA: gx_tuner_set_reference_11comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_13COMMA: gx_tuner_set_reference_13comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_17COMMA: gx_tuner_set_reference_17comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_19COMMA: gx_tuner_set_reference_19comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_23COMMA: gx_tuner_set_reference_23comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_29COMMA: gx_tuner_set_reference_29comma(tuner, g_value_get_int(value)); break; case PROP_REFERENCE_31COMMA: gx_tuner_set_reference_31comma(tuner, g_value_get_int(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } // the property get methode, return the current value static void gx_tuner_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GxTuner *tuner = GX_TUNER(object); switch(prop_id) { case PROP_FREQ: g_value_set_double(value, tuner->freq); break; case PROP_REFERENCE_PITCH: g_value_set_double(value, tuner->reference_pitch); break; case PROP_MODE: g_value_set_int(value, tuner->mode); break; case PROP_REFERENCE_NOTE: //#6 g_value_set_int(value, tuner->reference_note); break; case PROP_REFERENCE_03COMMA: g_value_set_int(value, tuner->reference_03comma); break; case PROP_REFERENCE_05COMMA: g_value_set_int(value, tuner->reference_05comma); break; case PROP_REFERENCE_07COMMA: g_value_set_int(value, tuner->reference_07comma); break; case PROP_REFERENCE_11COMMA: g_value_set_int(value, tuner->reference_11comma); break; case PROP_REFERENCE_13COMMA: g_value_set_int(value, tuner->reference_13comma); break; case PROP_REFERENCE_17COMMA: g_value_set_int(value, tuner->reference_17comma); break; case PROP_REFERENCE_19COMMA: g_value_set_int(value, tuner->reference_19comma); break; case PROP_REFERENCE_23COMMA: g_value_set_int(value, tuner->reference_23comma); break; case PROP_REFERENCE_29COMMA: g_value_set_int(value, tuner->reference_29comma); break; case PROP_REFERENCE_31COMMA: g_value_set_int(value, tuner->reference_31comma); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static double log_scale(int cent, double set) { if (cent == 0) { return set; } else if (cent < 2 && cent > -2) { // 1 cent if (set<0.0) return set - 0.0155; else return set + 0.0155; } else if (cent < 3 && cent > -3) { // 2 cent if (set<0.0) return set - 0.0265; else return set + 0.0265; }else if (cent < 4 && cent > -4) { // 3 cent if (set<0.0) return set - 0.0355; else return set + 0.0355; } else if (cent < 5 && cent > -5) { // 4 cent if (set<0.0) return set - 0.0455; else return set + 0.0455; } else if (cent < 6 && cent > -6) { // 5 cent if (set<0.0) return set - 0.0435; else return set + 0.0435; } else if (cent < 7 && cent > -7) { // 6 cent if (set<0.0) return set - 0.0425; else return set + 0.0425; } else if (cent < 8 && cent > -8) { // 7 cent if (set<0.0) return set - 0.0415; else return set + 0.0415; } else if (cent < 9 && cent > -9) { // 8 cent if (set<0.0) return set - 0.0405; else return set + 0.0405; } else if (cent < 10 && cent > -10) { // 9 cent if (set<0.0) return set - 0.0385; else return set + 0.0385; } else if (cent < 11 && cent > -11) { // 10 cent if (set<0.0) return set - 0.0365; else return set + 0.0365; } else if (cent < 51 && cent > -51) { // < 50 cent return set + (0.4/cent); } else return set; } static void gx_tuner_triangle(cairo_t *cr, double posx, double posy, double width, double height) { double h2 = height/2.0; cairo_move_to(cr, posx, posy-h2); if (width > 0) { cairo_curve_to(cr,posx, posy-h2, posx+10, posy, posx, posy+h2); } else { cairo_curve_to(cr,posx, posy-h2, posx-10, posy, posx, posy+h2); } cairo_curve_to(cr,posx, posy+h2, posx+width/2, posy+h2, posx+width, posy); cairo_curve_to(cr, posx+width, posy, posx+width/2, posy-h2, posx, posy-h2); cairo_fill(cr); } static void gx_tuner_strobe(cairo_t *cr, double x0, double y0, double cents) { static double move = 0; static double hold_l = 0; cairo_pattern_t *pat = cairo_pattern_create_linear (x0+50, y0,x0, y0); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REFLECT); cairo_pattern_add_color_stop_rgb (pat, 0, 0.1, 0.8, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.1, 0.6, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.2, 0.3, 0.6, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.3, 0.4, 0.4, 0.1); cairo_pattern_add_color_stop_rgb (pat, 1, 0.8, 0.1, 0.1); cairo_set_source (cr, pat); if (abs(cents)>0) { if(hold_l>0 ) hold_l -= 10.0 ; if (cents>0) move += pow(abs(cents),0.25); else if (cents<0) move -= pow(abs(cents),0.25); } else if (fabs(cents)>0.015){ move += cents; if(hold_l>0 ) hold_l -= 10.0 ; } else { move = 0; if(hold_lrect_width) move = 0; cairo_set_dash (cr, dashline, sizeof(dashline)/sizeof(dashline[0]), move); cairo_set_line_width(cr, 2.0); cairo_move_to(cr,x0+hold_l, y0+1); cairo_line_to(cr, x0+rect_width-hold_l , y0+1); cairo_stroke(cr); cairo_pattern_destroy(pat); } static gboolean gtk_tuner_expose_just(GtkWidget *widget, cairo_t *cr) { GxTuner *tuner = GX_TUNER(widget); //setting the scale if (tuner->mode == 1){ tuner->tempnumofnotes = numnotesscale3diatonic; for (int n=0 ; ntempnumofnotes /*notes of choosen scale */; n++){ for (int i=0; itempscale[n][i] = scale3diatonic[n][i]; } } } else if (tuner->mode == 2 ){ tuner->tempnumofnotes = numnotesscale35chromatic; for (int n=0 ; ntempnumofnotes; n++){ for (int i=0; itempscale[n][i] = scale35chromatic[n][i]; } } } else if (tuner->mode == 3 ){ tuner->tempnumofnotes = numnotesscale357chromatic; for (int n=0 ; ntempnumofnotes; n++){ for (int i=0; itempscale[n][i] = scale357chromatic[n][i]; } } } else if (tuner->mode == 4 ){ tuner->tempnumofnotes = numnotesscale37chromatic; for (int n=0 ; ntempnumofnotes; n++){ for (int i=0; itempscale[n][i] = scale37chromatic[n][i]; } } }else if (tuner->mode == 5 ){ tuner->tempnumofnotes = numnotesscaleovertones; for (int n=0 ; ntempnumofnotes; n++){ for (int i=0; itempscale[n][i] = scaleovertones[n][i]; } } } //1. creating tempreference_note tuner->tempreference_note[0] = tuner->reference_note; tuner->tempreference_note[1] = 0; tuner->tempreference_note[2] = tuner->reference_03comma-3; tuner->tempreference_note[3] = tuner->reference_05comma-3; tuner->tempreference_note[4] = tuner->reference_07comma-3; tuner->tempreference_note[5] = tuner->reference_11comma-3; tuner->tempreference_note[6] = tuner->reference_13comma-3; tuner->tempreference_note[7] = tuner->reference_17comma-3; tuner->tempreference_note[8] = tuner->reference_19comma-3; tuner->tempreference_note[9] = tuner->reference_23comma-3; tuner->tempreference_note[10] = tuner->reference_29comma-3; tuner->tempreference_note[11] = tuner->reference_31comma-3; //2. tempscaletranslated //memset(tuner->tempscaletranslated[0], 0, sizeof(tempscaletranslated)); for(int i=0;itempscaletranslatednames[i], 0, sizeof(char)); } //int temp; for (int n=0; ntempnumofnotes; n++){ tuner->tempscaletranslated[n][2]=0; tuner->temp=0; for (int i=1; itempscaletranslated[n][i]=tuner->tempreference_note[i]+tuner->tempscale[n][i]; } tuner->temp = tuner->tempscale[n][0] + tuner->tempreference_note[0]-1; if (tuner->temp < 0){ tuner->temp = tuner->temp + 7; tuner->tempscaletranslated[n][2]=tuner->tempscaletranslated[n][2]-1; tuner->tempscaletranslated[n][0]= tuner->temp; }else if (tuner->temp > 6){ tuner->temp = tuner->temp - 7; tuner->tempscaletranslated[n][2]=tuner->tempscaletranslated[n][2]+1; tuner->tempscaletranslated[n][0]= tuner->temp; } else {tuner->tempscaletranslated[n][0]= tuner->temp;} } //3. creatnotenames with tempscaletranslated int i = 0; for (int n=0; ntempnumofnotes; n++){ strcat(tuner->tempscaletranslatednames[n],scale3basenames[tuner->tempscaletranslated[n][0]]); while (i < 24){ i = 0; i++; // 3limit comma if (tuner->tempscaletranslated[n][2] < 0){ for (int j=0; jtempscaletranslated[n][2]); j++){ strcat(tuner->tempscaletranslatednames[n],"♭"); i++; } } else if (tuner->tempscaletranslated[n][2] > 0){ for (int j=0; jtempscaletranslated[n][2]; j++){ strcat(tuner->tempscaletranslatednames[n],"♯"); i++; } } // 5limit comma if (tuner->tempscaletranslated[n][3] < 0){ for (int j=0; jtempscaletranslated[n][3]); j++){ strcat(tuner->tempscaletranslatednames[n],"-"); i++; } } else if (tuner->tempscaletranslated[n][3] > 0){ for (int j=0; jtempscaletranslated[n][3]; j++){ strcat(tuner->tempscaletranslatednames[n],"+"); i++; } } // 7limit comma if (tuner->tempscaletranslated[n][4] < 0){ for (int j=0; jtempscaletranslated[n][4]); j++){ strcat(tuner->tempscaletranslatednames[n],"L"); i++; } } else if (tuner->tempscaletranslated[n][4] > 0){ for (int j=0; jtempscaletranslated[n][4]; j++){ strcat(tuner->tempscaletranslatednames[n],"7"); i++; } } // 11limit comma if (tuner->tempscaletranslated[n][5] < 0){ for (int j=0; jtempscaletranslated[n][5]); j++){ strcat(tuner->tempscaletranslatednames[n],"↓"); i++; } } else if (tuner->tempscaletranslated[n][5] > 0){ for (int j=0; jtempscaletranslated[n][5]; j++){ strcat(tuner->tempscaletranslatednames[n],"↑"); i++; } } // 13limit comma if (tuner->tempscaletranslated[n][6] < 0){ for (int j=0; jtempscaletranslated[n][6]); j++){ strcat(tuner->tempscaletranslatednames[n],"ƐƖ"); i++; } } else if (tuner->tempscaletranslated[n][6] > 0){ for (int j=0; jtempscaletranslated[n][6]; j++){ strcat(tuner->tempscaletranslatednames[n],"13"); i++; } } // 17limit comma if (tuner->tempscaletranslated[n][7] < 0){ for (int j=0; jtempscaletranslated[n][7]); j++){ strcat(tuner->tempscaletranslatednames[n],"LƖ"); i++; } } else if (tuner->tempscaletranslated[n][7] > 0){ for (int j=0; jtempscaletranslated[n][7]; j++){ strcat(tuner->tempscaletranslatednames[n],"17"); i++; } } // 19limit comma if (tuner->tempscaletranslated[n][8] < 0){ for (int j=0; jtempscaletranslated[n][8]); j++){ strcat(tuner->tempscaletranslatednames[n],"6Ɩ"); i++; } } else if (tuner->tempscaletranslated[n][8] > 0){ for (int j=0; jtempscaletranslated[n][8]; j++){ strcat(tuner->tempscaletranslatednames[n],"19"); i++; } } // 23limit comma if (tuner->tempscaletranslated[n][9] < 0){ for (int j=0; jtempscaletranslated[n][9]); j++){ strcat(tuner->tempscaletranslatednames[n],"ƐS"); i++; } } else if (tuner->tempscaletranslated[n][9] > 0){ for (int j=0; jtempscaletranslated[n][9]; j++){ strcat(tuner->tempscaletranslatednames[n],"23"); i++; } } // 29limit comma if (tuner->tempscaletranslated[n][10] < 0){ for (int j=0; jtempscaletranslated[n][10]); j++){ strcat(tuner->tempscaletranslatednames[n],"6S"); i++; } } else if (tuner->tempscaletranslated[n][10] > 0){ for (int j=0; jtempscaletranslated[n][10]; j++){ strcat(tuner->tempscaletranslatednames[n],"29"); i++; } } // 31limit comma if (tuner->tempscaletranslated[n][11] < 0){ for (int j=0; jtempscaletranslated[n][11]); j++){ strcat(tuner->tempscaletranslatednames[n],"ƖƐ"); i++; } } else if (tuner->tempscaletranslated[n][11] > 0){ for (int j=0; jtempscaletranslated[n][11]; j++){ strcat(tuner->tempscaletranslatednames[n],"31"); i++; } } strcat(tuner->tempscaletranslatednames[n],"\0"); break; } } // 4. calculating the translated scale: + comma's and chroma's to powers of primes for (int n=0; ntempnumofnotes; n++){ for (int i=1; itempscaletranslatedpowprimes[n][i] = scale3base[tuner->tempscale[n][0]][i] + tuner->tempscale[n][2] * a03comma[i] + tuner->tempscale[n][3] * a05comma[i] + tuner->tempscale[n][4] * a07comma[i] + tuner->tempscale[n][5] * a11comma[i] + tuner->tempscale[n][6] * a13comma[i] + tuner->tempscale[n][7] * a17comma[i] + tuner->tempscale[n][8] * a19comma[i] + tuner->tempscale[n][9] * a23comma[i] + tuner->tempscale[n][10] * a29comma[i] + tuner->tempscale[n][11] * a31comma[i]; } } // 5. calculate tempscaletranslateratios for (int n=0; ntempnumofnotes; n++){ double tempratio; tempratio = (pow(2.0,tuner->tempscaletranslatedpowprimes[n][1]) * pow(3.0,tuner->tempscaletranslatedpowprimes[n][2]) * pow(5.0,tuner->tempscaletranslatedpowprimes[n][3]) * pow(7.0,tuner->tempscaletranslatedpowprimes[n][4]) * pow(11.0,tuner->tempscaletranslatedpowprimes[n][5]) * pow(13.0,tuner->tempscaletranslatedpowprimes[n][6]) * pow(17.0,tuner->tempscaletranslatedpowprimes[n][7]) * pow(19.0,tuner->tempscaletranslatedpowprimes[n][8]) * pow(23.0,tuner->tempscaletranslatedpowprimes[n][9]) * pow(29.0,tuner->tempscaletranslatedpowprimes[n][10]) * pow(31.0,tuner->tempscaletranslatedpowprimes[n][11])) ; //check if ratio is between 1/1 (unison) and 2/0 (octave) and set it between those two ratios) int ratiocheck = log(tempratio)/log(2.0); if(ratiocheck<0){ tuner->tempscaleratios[n] = 1/tempratio/pow(2.0,ratiocheck); } else { tuner->tempscaleratios[n] = tempratio/pow(2.0,ratiocheck); } } tuner->tempscaleratios[tuner->tempnumofnotes]=2.0; // Calculate ratio of reference note for (int i=1; itempreference_notepowprimes[i] = scale3base[tuner->tempreference_note[0]][i] + tuner->tempreference_note[2] * a03comma[i] + tuner->tempreference_note[3] * a05comma[i] + tuner->tempreference_note[4] * a07comma[i] + tuner->tempreference_note[5] * a11comma[i] + tuner->tempreference_note[6] * a13comma[i] + tuner->tempreference_note[7] * a17comma[i] + tuner->tempreference_note[8] * a19comma[i] + tuner->tempreference_note[9] * a23comma[i] + tuner->tempreference_note[10] * a29comma[i] + tuner->tempreference_note[11] * a31comma[i]; } tuner->tempreference_noteratio = (pow(2.0,tuner->tempreference_notepowprimes[1]) * pow(3.0,tuner->tempreference_notepowprimes[2]) * pow(5.0,tuner->tempreference_notepowprimes[3]) * pow(7.0,tuner->tempreference_notepowprimes[4]) * pow(11.0,tuner->tempreference_notepowprimes[5]) * pow(13.0,tuner->tempreference_notepowprimes[6]) * pow(17.0,tuner->tempreference_notepowprimes[7]) * pow(19.0,tuner->tempreference_notepowprimes[8]) * pow(23.0,tuner->tempreference_notepowprimes[9]) * pow(29.0,tuner->tempreference_notepowprimes[10]) * pow(31.0,tuner->tempreference_notepowprimes[11])) ; // Frequency Octave divider float multiply = 1.0; // ratio float percent = 0.0; // Note indicator int display_note = 0; // Octave names for display static const char* octave[] = {"0","1","2","3","4","5","6","7"," "}; // Octave indicator static int indicate_oc = 0; // fetch widget size and location GtkAllocation *allocation = g_new0 (GtkAllocation, 1); gtk_widget_get_allocation(GTK_WIDGET(widget), allocation); double x0 = (allocation->width - 100) * 0.5; double y0 = (allocation->height - 60) * 0.5; static double grow = 0.; if(allocation->width > allocation->height +(10.*grow*3)) { grow = (allocation->height/60.)/10.; } else { grow = (allocation->width/100.)/10.; } tuner->scale_h = (allocation->height/60.)/3.; tuner->scale_w = (allocation->width/100.)/3.; // translate widget size to standard size cairo_translate(cr, -x0*tuner->scale_w, -y0*tuner->scale_h); cairo_scale(cr, tuner->scale_w, tuner->scale_h); cairo_set_source_surface(cr, GX_TUNER_CLASS(GTK_WIDGET_GET_CLASS(widget))->surface_tuner, x0, y0); cairo_paint (cr); cairo_restore(cr); cairo_save(cr); cairo_translate(cr, -x0*tuner->scale_w*3., -y0*tuner->scale_h*3.); cairo_scale(cr, tuner->scale_w*3., tuner->scale_h*3.); // fetch Octave we are in float scale = -0.4; if (tuner->freq) { // this is the frequency we get from the pitch tracker float freq_is = tuner->freq; // Set reference frequency to the first note of the translated scale (16/27 is the reciproce of a Pythagorean sixt, i.c. C-->A) float ref_c = tuner->reference_pitch * 16.0 / 27.0 * tuner->tempreference_noteratio; // now check in which octave we are with the tracked frequency // and set the frequency octave divider // ref_c is now the frequency of the first note in octave, // but we want to check if the frequency is below the last note in octave // so, for example if freq_is is below ref_c we are in octave 3 // if freq_is is below ref_c/2 we are in octave 2, etc. for (int n=0 ; n <= 8 ; ++n ) { float ratiodiffhighnoteandoctave = exp((log(tuner->tempscaleratios[tuner->tempnumofnotes])+log(2.0))/2) ; //fprintf(stderr, "ratio highestnote %f ratiodiffhighnoteandoctave %f \n", tuner->tempscaleratios[tuner->tempnumofnotes-1] , ratiodiffhighnoteandoctave); if (freq_is < (ref_c*pow(2,n-3))-(2-ratiodiffhighnoteandoctave)*(ref_c*pow(2,n-3)) && freq_is >0.0) { indicate_oc = n; multiply = pow(2, 4-n); break; } } percent = (freq_is/(ref_c/multiply)); // now we chould check which ratio we have // we split the range using log-average for (int n=0 ; n < tuner->tempnumofnotes ; ++n ){ float ratiodiff = exp((log(tuner->tempscaleratios[n])+log(tuner->tempscaleratios[n+1]))/2) ; fprintf(stderr, "ratio note: %f ratiodiff: %f \n", tuner->tempscaleratios[n] , ratiodiff); if (percent < ratiodiff) { display_note = n; scale = (percent-tuner->tempscaleratios[n])/2.0; break; } } fprintf(stderr, " percent == %f freq = %f ref_c = %f indicate_oc = %i value of numberofnotes is %i \n", percent, freq_is, ref_c, indicate_oc, tuner->tempnumofnotes); // display note cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2); cairo_set_font_size(cr, 10.0); cairo_move_to(cr,x0+40 -9 , y0+30 +9 ); //original was 50 and 54 cairo_show_text(cr, tuner->tempscaletranslatednames[display_note]); cairo_set_font_size(cr, 8.0); cairo_move_to(cr,x0+40 , y0+30 +16 ); cairo_show_text(cr, octave[indicate_oc]); } // display frequency char s[10]; snprintf(s, sizeof(s), "%.1f Hz", tuner->freq); cairo_set_source_rgb (cr, 0.5, 0.5, 0.1); cairo_set_font_size (cr, 7.5); cairo_text_extents_t ex; cairo_text_extents(cr, s, &ex); cairo_move_to (cr, x0+98-ex.width, y0+58); cairo_show_text(cr, s); // display cent if(scale>-0.4) { if(scale>0.004) { // here we translate the scale factor to cents and display them cents = static_cast((floorf(scale * 10000) / 50)); snprintf(s, sizeof(s), "+%i", cents); cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); gx_tuner_strobe(cr, x0, y0, static_cast(cents)); } else if(scale<-0.004) { cents = static_cast((ceil(scale * 10000) / 50)); snprintf(s, sizeof(s), "%i", cents); cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); gx_tuner_strobe(cr, x0, y0, static_cast(cents)); } else { cents = static_cast((ceil(scale * 10000) / 50)); mini_cents = (scale * 10000) / 50; if (mini_cents<0) snprintf(s, sizeof(s), "%.2f", mini_cents); else snprintf(s, sizeof(s), "+%.2f", mini_cents); cairo_set_source_rgb (cr, 0.05* abs(cents), 0.5, 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); gx_tuner_strobe(cr, x0, y0, mini_cents); } } else { cents = 100; snprintf(s, sizeof(s), "+ - cent"); } cairo_set_source_rgb (cr, 0.5, 0.5, 0.1); cairo_set_font_size (cr, 6.0); cairo_text_extents(cr, s, &ex); cairo_move_to (cr, x0+28-ex.width, y0+58); cairo_show_text(cr, s); double ux=2., uy=2.; cairo_device_to_user_distance (cr, &ux, &uy); if (ux < uy) ux = uy; cairo_set_line_width (cr, ux + grow); // indicator (line) cairo_move_to(cr,x0+50, y0+rect_height+5); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_dash (cr, dash_ind, sizeof(dash_ind)/sizeof(dash_ind[0]), 1); cairo_line_to(cr, (log_scale(cents, scale)*2*rect_width)+x0+50, y0+(scale*scale*30)+2); cairo_set_source_rgb(cr, 0.5, 0.1, 0.1); cairo_stroke(cr); g_free (allocation); return FALSE; } static gboolean gtk_tuner_expose (GtkWidget *widget, cairo_t *cr) { GxTuner *tuner = GX_TUNER(widget); // here we check in which mode we are add your mode here. if (tuner->mode > 0) { if (!gtk_tuner_expose_just (widget, cr)) return FALSE; } static const char* note[12] = {"A ","A#","B ","C ","C#","D ","D#","E ","F ","F#","G ","G#"}; static const char* octave[9] = {"0","1","2","3","4","5","6","7"," "}; static int indicate_oc = 0; GtkAllocation *allocation = g_new0 (GtkAllocation, 1); gtk_widget_get_allocation(GTK_WIDGET(widget), allocation); double x0 = (allocation->width - 100) * 0.5; double y0 = (allocation->height - 60) * 0.5; static double grow = 0.; if(allocation->width > allocation->height +(10.*grow*3)) { grow = (allocation->height/60.)/10.; } else { grow = (allocation->width/100.)/10.; } tuner->scale_h = (allocation->height/60.)/3.; tuner->scale_w = (allocation->width/100.)/3.; cairo_translate(cr, -x0*tuner->scale_w, -y0*tuner->scale_h); cairo_scale(cr, tuner->scale_w, tuner->scale_h); cairo_set_source_surface(cr, GX_TUNER_CLASS(GTK_WIDGET_GET_CLASS(widget))->surface_tuner, x0, y0); cairo_paint (cr); cairo_restore(cr); cairo_save(cr); cairo_translate(cr, -x0*tuner->scale_w*3., -y0*tuner->scale_h*3.); cairo_scale(cr, tuner->scale_w*3., tuner->scale_h*3.); float scale = -0.4; if (tuner->freq) { float freq_is = tuner->freq; float fvis = 12 * log2f(freq_is/tuner->reference_pitch); int vis = int(round(fvis)); scale = (fvis-vis) / 2; vis = vis % 12; if (vis < 0) { vis += 12; } if (fabsf(scale) < 0.1) { if (freq_is < 31.78 && freq_is >0.0) { indicate_oc = 0; } else if (freq_is < 63.57) { indicate_oc = 1; } else if (freq_is < 127.14) { indicate_oc = 2; } else if (freq_is < 254.28) { indicate_oc = 3; } else if (freq_is < 509.44) { indicate_oc = 4; } else if (freq_is < 1017.35) { indicate_oc = 5; } else if (freq_is < 2034.26) { indicate_oc = 6; } else if (freq_is < 4068.54) { indicate_oc = 7; } else { indicate_oc = 8; } }else { indicate_oc = 8; } // display note cairo_set_source_rgba(cr, fabsf(scale)*3.0, 1-fabsf(scale)*3.0, 0.2,1-fabsf(scale)*2); cairo_set_font_size(cr, 18.0); cairo_move_to(cr,x0+50 -9 , y0+30 +9 ); cairo_show_text(cr, note[vis]); cairo_set_font_size(cr, 8.0); cairo_move_to(cr,x0+54 , y0+30 +16 ); cairo_show_text(cr, octave[indicate_oc]); } // display frequency char s[10]; snprintf(s, sizeof(s), "%.1f Hz", tuner->freq); cairo_set_source_rgb (cr, 0.5, 0.5, 0.1); cairo_set_font_size (cr, 7.5); cairo_text_extents_t ex; cairo_text_extents(cr, s, &ex); cairo_move_to (cr, x0+98-ex.width, y0+58); cairo_show_text(cr, s); // display cent if(scale>-0.4) { if(scale>0.004) { cents = static_cast((floorf(scale * 10000) / 50)); snprintf(s, sizeof(s), "+%i", cents); cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); gx_tuner_strobe(cr, x0, y0, static_cast(cents)); } else if(scale<-0.004) { cents = static_cast((ceil(scale * 10000) / 50)); snprintf(s, sizeof(s), "%i", cents); cairo_set_source_rgb (cr, 0.05, 0.5+0.022* abs(cents), 0.1); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); cairo_set_source_rgb (cr, 0.5+ 0.022* abs(cents), 0.35, 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); gx_tuner_strobe(cr, x0, y0, static_cast(cents)); } else { cents = static_cast((ceil(scale * 10000) / 50)); mini_cents = (scale * 10000) / 50; if (mini_cents<0) snprintf(s, sizeof(s), "%.2f", mini_cents); else snprintf(s, sizeof(s), "+%.2f", mini_cents); cairo_set_source_rgb (cr, 0.05* abs(cents), 0.5, 0.1); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); gx_tuner_strobe(cr, x0, y0, mini_cents); } } else { cents = 100; snprintf(s, sizeof(s), "+ - cent"); } cairo_set_source_rgb (cr, 0.5, 0.5, 0.1); cairo_set_font_size (cr, 6.0); cairo_text_extents(cr, s, &ex); cairo_move_to (cr, x0+28-ex.width, y0+58); cairo_show_text(cr, s); double ux=2., uy=2.; cairo_device_to_user_distance (cr, &ux, &uy); if (ux < uy) ux = uy; cairo_set_line_width (cr, ux + grow); // indicator (line) cairo_move_to(cr,x0+50, y0+rect_height+5); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_set_dash (cr, dash_ind, sizeof(dash_ind)/sizeof(dash_ind[0]), 1); cairo_line_to(cr, (log_scale(cents, scale)*2*rect_width)+x0+50, y0+(scale*scale*30)+2); cairo_set_source_rgb(cr, 0.5, 0.1, 0.1); cairo_stroke(cr); g_free (allocation); return FALSE; } /* ** paint tuner background picture (the non-changing parts) */ static void draw_background(cairo_surface_t *surface) { cairo_t *cr; double x0 = 0; double y0 = 0; cr = cairo_create(surface); cairo_scale(cr, 3, 3); // background cairo_rectangle (cr, x0-1,y0-1,rect_width+2,rect_height+2); cairo_set_source_rgb (cr, 0, 0, 0); cairo_fill_preserve(cr); // light cairo_pattern_t*pat = cairo_pattern_create_radial (-50, y0, 5,rect_width-10, rect_height, 20.0); cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 0.8); cairo_pattern_add_color_stop_rgba (pat, 0.3, 0.4, 0.4, 0.4, 0.8); cairo_pattern_add_color_stop_rgba (pat, 0.6, 0.05, 0.05, 0.05, 0.8); cairo_pattern_add_color_stop_rgba (pat, 1, 0.0, 0.0, 0.0, 0.8); cairo_set_source (cr, pat); //cairo_rectangle (cr, x0+2,y0+2,rect_width-3,rect_height-3); cairo_fill(cr); // division scale pat = cairo_pattern_create_linear (x0+50, y0,x0, y0); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REFLECT); cairo_pattern_add_color_stop_rgb (pat, 0, 0.1, 0.8, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.1, 0.1, 0.6, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.2, 0.3, 0.6, 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.3, 0.4, 0.4, 0.1); cairo_pattern_add_color_stop_rgb (pat, 1, 0.8, 0.1, 0.1); cairo_set_source (cr, pat); cairo_set_dash (cr, dashes, sizeof (dashes)/sizeof(dashes[0]), 100.0); cairo_set_line_width(cr, 3.0); for (int i = -5; i < -1; i++) { cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((i*0.08))*rect_width)+x0+50, y0+(((i*0.1*i*0.1))*30)+2); } for (int i = 2; i < 6; i++) { cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((i*0.08))*rect_width)+x0+50, y0+(((i*0.1*i*0.1))*30)+2); } cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, x0+50, y0+2); cairo_stroke(cr); cairo_set_line_width(cr, 1); cairo_set_dash (cr, dashes, sizeof (dashes)/sizeof(dashes[0]), 100.0); cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((-3*0.04))*rect_width)+x0+50, y0+(((-3*0.1*-3*0.1))*30)+2); cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((-2*0.048))*rect_width)+x0+50, y0+(((-2*0.1*-2*0.1))*30)+2); cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((3*0.04))*rect_width)+x0+50, y0+(((3*0.1*3*0.1))*30)+2); cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((2*0.048))*rect_width)+x0+50, y0+(((2*0.1*2*0.1))*30)+2); for (int i = -2; i < 3; i++) { cairo_move_to(cr,x0+50, y0+rect_height-5); cairo_line_to(cr, (((i*0.035))*rect_width)+x0+50, y0+(((i*0.1*i*0.1))*30)+2); } cairo_stroke(cr); pat = cairo_pattern_create_linear (x0+30, y0, x0+70, y0); cairo_pattern_add_color_stop_rgb (pat, 1, 0.2, 0.2 , 0.2); cairo_pattern_add_color_stop_rgb (pat, 0.5, 0.1, 0.1 , 0.1); cairo_pattern_add_color_stop_rgb (pat, 0,0.05, 0.05 , 0.05); cairo_set_source (cr, pat); cairo_arc(cr, x0+50, y0+rect_height+5, 12.0, 0, 2*M_PI); cairo_fill_preserve(cr); cairo_set_dash (cr, no_dash, sizeof(no_dash)/sizeof(no_dash[0]), 0); cairo_pattern_add_color_stop_rgb (pat, 0, 0.1, 0.1 , 0.1); cairo_pattern_add_color_stop_rgb (pat, 0.8, 0.05, 0.05 , 0.05); cairo_pattern_add_color_stop_rgb (pat, 1,0.01, 0.01 , 0.01); cairo_set_source (cr, pat); cairo_set_line_width(cr, 1.0); cairo_stroke(cr); cairo_set_source_rgb(cr,0.1,0.1,0.1); gx_tuner_triangle(cr, x0+20, y0+45, 15, 10); gx_tuner_triangle(cr, x0+80, y0+45, -15, 10); cairo_stroke(cr); // indicator shaft (circle) cairo_pattern_destroy(pat); cairo_destroy(cr); }gxtuner-3.0/gxtuner.desktop000066400000000000000000000004571321541042300161400ustar00rootroot00000000000000 [Desktop Entry] Name=gxtuner GenericName=Tuner Comment=Simple Tuner Interface for jack GenericName[fr]=Accordeur Comment[fr]=Interface d'accordeur simple pour JACK Keywords=audio;sound;jackd;tuner;tune Exec=gxtuner Icon=gxtuner Categories=AudioVideo;X-Jack;Midi;X-MIDI; Terminal=false Type=Application gxtuner-3.0/gxtuner.h000066400000000000000000000102111321541042300147030ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: gxtuner.h guitar tuner for jack * * ---------------------------------------------------------------------------- */ #pragma once #ifndef _GX_TUNER_H_ #define _GX_TUNER_H_ #ifdef __cplusplus extern "C" { #endif #include #include #include G_BEGIN_DECLS #define GX_TYPE_TUNER (gx_tuner_get_type()) #define GX_TUNER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GX_TYPE_TUNER, GxTuner)) #define GX_IS_TUNER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GX_TYPE_TUNER)) #define GX_TUNER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GX_TYPE_TUNER, GxTunerClass)) #define GX_IS_TUNER_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GX_TYPE_TUNER)) # define NRPRIMES 12 # define MAXSCALENOTES 53 typedef struct _GxTuner GxTuner; typedef struct _GxTunerClass GxTunerClass; // the internal struct of the tuner widget, // add variables for new propertys in the struct struct _GxTuner { GtkDrawingArea parent; //char** tempscaletranslatednames; double freq; double reference_pitch; double scale_w; double scale_h; //double *tempscaleratios; double tempscaleratios[MAXSCALENOTES]; double tempreference_noteratio; char* tempscaletranslatednames[MAXSCALENOTES]; int temp; int tempscale[MAXSCALENOTES][NRPRIMES]; int tempnumofnotes; int tempreference_note[NRPRIMES]; int tempreference_notepowprimes[NRPRIMES]; int tempscaletranslated[MAXSCALENOTES][NRPRIMES]; int tempscaletranslatedpowprimes[MAXSCALENOTES][NRPRIMES]; int mode; int reference_note; //#1 int reference_03comma; int reference_05comma; int reference_07comma; int reference_11comma; int reference_13comma; int reference_17comma; int reference_19comma; int reference_23comma; int reference_29comma; int reference_31comma; }; struct _GxTunerClass { GtkDrawingAreaClass parent_class; /*< private >*/ cairo_surface_t *surface_tuner; }; GType gx_tuner_get_type(); // this are the calles which could be used from outside the widget // if you add a new property, add a call to set it here void gx_tuner_set_freq(GxTuner *tuner, double freq); void gx_tuner_set_reference_pitch(GxTuner *tuner, double reference_pitch); double gx_tuner_get_reference_pitch(GxTuner *tuner); void gx_tuner_set_mode(GxTuner *tuner, int mode); void gx_tuner_set_reference_note(GxTuner *tuner, int reference_note); //#2 void gx_tuner_set_reference_03comma(GxTuner *tuner, int reference_03comma); void gx_tuner_set_reference_05comma(GxTuner *tuner, int reference_05comma); void gx_tuner_set_reference_07comma(GxTuner *tuner, int reference_07comma); void gx_tuner_set_reference_11comma(GxTuner *tuner, int reference_11comma); void gx_tuner_set_reference_13comma(GxTuner *tuner, int reference_13comma); void gx_tuner_set_reference_17comma(GxTuner *tuner, int reference_17comma); void gx_tuner_set_reference_19comma(GxTuner *tuner, int reference_19comma); void gx_tuner_set_reference_23comma(GxTuner *tuner, int reference_23comma); void gx_tuner_set_reference_29comma(GxTuner *tuner, int reference_29comma); void gx_tuner_set_reference_31comma(GxTuner *tuner, int reference_31comma); GtkWidget *gx_tuner_new(void); //char* namecomma(int a, const char* b , const char* c); G_END_DECLS #ifdef __cplusplus } #endif #endif // _GX_TUNER_H_gxtuner-3.0/gxtuner.png000066400000000000000000000016461321541042300152540ustar00rootroot00000000000000PNG  IHDRĴl;sBIT|d]IDAT8=lE3w#M &¢4Q * z Z()( $(P@C+q>罏y9>j޼yhު9qQY6a }5hMU?E[D-1@2'"8;\~vKl%KVbOà+>T-Aw%`߸9{ 5v7'M'x/T*Ώ{{}S^ NCCR@u+%R~*Tjv=C/]=R"S$4@ĜvnIENDB`gxtuner-3.0/jacktuner.cpp000066400000000000000000000100451321541042300155350ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: jacktuner.cpp guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "./jacktuner.h" JackTuner::JackTuner() {} JackTuner::~JackTuner() {} bool JackTuner::gx_jack_init(std::string jack_uuid) { client_name = "gxtuner"; input_port = 0; #ifdef HAVE_JACK_SESSION if (!jack_uuid.empty()) { client = jack_client_open (client_name.c_str(), jack_options_t( JackNoStartServer | JackSessionID), &jackstat, jack_uuid.c_str()); } else { client = jack_client_open(client_name.c_str(), JackNoStartServer, &jackstat); } #else client = jack_client_open(client_name.c_str(), JackNoStartServer, &jackstat); #endif if (client) { jack_sr = jack_get_sample_rate(client); // jack sample rate jack_bs = jack_get_buffer_size(client); // jack buffer size jack_set_process_callback(client, gx_jack_process, 0); // compute jack_on_shutdown (client, jack_shutdown, 0); // shutdown clean up #ifdef HAVE_JACK_SESSION if (jack_set_session_callback) { jack_set_session_callback(client, gx_jack_session_callback, 0); } #endif input_port = jack_port_register(client, "in_0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput|JackPortIsTerminal, 0); } else { fprintf (stderr, "connection to jack failed, . . exit\n"); exit(1); } return true; } void JackTuner::gx_jack_activate(std::string jack_uuid, std::string jack_in) { if (jack_activate (client)) { fprintf (stderr, "cannot activate client\n"); exit (1); } else { #ifdef HAVE_JACK_SESSION if (!jack_in.empty() && jack_uuid.empty()) { jack_connect(client, jack_in.c_str(), jack_port_name(input_port)); } #else if (!jack_in.empty()) { jack_connect(client, jack_in.c_str(), jack_port_name(input_port)); } #endif } } void JackTuner::jack_shutdown (void *arg) {fptr->qt();} int JackTuner::gx_jack_process(jack_nframes_t nframes, void *arg) { float *input = static_cast (jack_port_get_buffer(jt.input_port, nframes)); fptr->pt(nframes, input); return 0; } #ifdef HAVE_JACK_SESSION int JackTuner::gx_jack_session_callback_helper(void* arg) { jack_session_event_t *event = static_cast(arg); int x = 0,y = 0,w = 0,l = 0; fptr->widi(&x, &y,&w,&l); double p = 0.0,t = 0.0; int d = 0; fptr->rp(&p); fptr->gt(&t); fptr->desk(&d); std::string cmd("gxtuner -U "); cmd += event->client_uuid; char buffer [100]; sprintf (buffer, " -x %i -y %i -w %i -l %i -p %f -t %f -d %i",x, y, w, l, p, t, d); cmd += buffer; event->command_line = strdup(cmd.c_str()); jack_session_reply(jt.client, event); if (event->type == JackSessionSaveAndQuit) { fptr->ex(); } jack_session_event_free(event); return 0; } void JackTuner::gx_jack_session_callback(jack_session_event_t *event, void *arg) { g_idle_add(jt.gx_jack_session_callback_helper, static_cast(event)); } #endif FuncPtr *fptr = 0; JackTuner jt; gxtuner-3.0/jacktuner.h000066400000000000000000000051401321541042300152020ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: jacktuner.h guitar tuner for jack * * ---------------------------------------------------------------------------- */ #pragma once #ifndef JACK_TUNER_H_ #define JACK_TUNER_H_ #include "./config.h" #include #include #include #include #ifdef HAVE_JACK_SESSION #include #endif #include #include typedef void (*funcpointer) (int* x, int* y, int* w, int* l); typedef void (*getpointer) (double* x); typedef void (*getintpointer) (int* x); typedef void (*npointer) (); typedef void (*gettracker) (int x, float *input); class JackTuner { private: jack_status_t jackstat; std::string client_name; static void jack_shutdown (void *arg); static int gx_jack_process(jack_nframes_t nframes, void *arg); #ifdef HAVE_JACK_SESSION static void gx_jack_session_callback(jack_session_event_t *event, void *arg); static int gx_jack_session_callback_helper(void* arg); #endif public: explicit JackTuner(); ~JackTuner(); jack_port_t* input_port; jack_client_t* client; jack_nframes_t jack_sr; // jack sample rate jack_nframes_t jack_bs; // jack buffer size void gx_jack_activate(std::string jack_uuid, std::string jack_in); bool gx_jack_init(std::string jack_uuid); }; extern JackTuner jt; class FuncPtr { public: funcpointer widi; getpointer rp; getpointer gt; getintpointer desk; npointer ex; npointer qt; gettracker pt; }; extern FuncPtr *fptr; #endif // JACK_TUNER_H_ gxtuner-3.0/main.cpp000066400000000000000000000076471321541042300145110ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: main.cpp guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "./cmdparser.h" #include "./gx_pitch_tracker.h" #include "./gxtuner.h" #include "./jacktuner.h" #include "./tuner.h" #include "./deskpager.h" static void wrap_window_area(int* x, int* y, int* w, int* l) { tw.window_area(x, y, w, l); } static void wrap_get_reference_pitch(double* x) { *x = gx_tuner_get_reference_pitch(GX_TUNER(tw.get_tuner())); } static void wrap_get_threshold(double* x) { *x = pitch_tracker.get_threshold(); } static void wrap_session_quit() { tw.session_quit(); } static void wrap_pitch_tracker_add(int x, float* input) { pitch_tracker.add(x, input); } static void wrap_main_quit() { gtk_main_quit (); } static std::string wrap_get_optvar(int x) { return cmd.get_optvar(x); } static jack_port_t* wrap_input_port() { return jt.input_port; } static jack_client_t* wrap_client() { return jt.client; } static float wrap_estimated_freq() { return pitch_tracker.get_estimated_freq(); } static void wrap_set_threshold(float x) { pitch_tracker.set_threshold(x); } static void wrap_get_desk(int *x) { *x = dp.get_active_desktop_for_window(GTK_WIDGET(tw.get_window())); } static void set_pointers_to_f() { // set function pointers to wrap functions fptr->widi = &wrap_window_area; fptr->rp = &wrap_get_reference_pitch; fptr->gt = &wrap_get_threshold; fptr->ex = &wrap_session_quit; fptr->pt = &wrap_pitch_tracker_add; fptr->qt = &wrap_main_quit; fptr->desk = &wrap_get_desk; cptr->cv = &wrap_get_optvar; cptr->gp = &wrap_input_port; cptr->gc = &wrap_client; cptr->ef = &wrap_estimated_freq; cptr->sf = &wrap_set_threshold; } int main(int argc, char *argv[]) { // trap signals to quit clean signal(SIGTERM, tw.signal_handler); signal(SIGHUP, tw.signal_handler); signal(SIGINT, tw.signal_handler); signal(SIGQUIT, tw.signal_handler); // init thread system tw.g_threads = 0; // process comandline options cmd.process_cmdline_options(argc, argv); // set pointers to function pointer classes fptr = new FuncPtr; cptr = new CmdPtr; set_pointers_to_f(); // init jack jt.gx_jack_init(cptr->cv(JACK_UUID)); // init gtk gtk_init (&argc, &argv); // activate jack jt.gx_jack_activate(cptr->cv(JACK_UUID), cptr->cv(JACK_INP)); // start pitchtracker pitch_tracker.init(static_cast(jt.jack_sr), jack_client_thread_id(cptr->gc())); // create window tw.create_window(); // start thread to update the frequency tw.g_threads = g_timeout_add( 100, tw.gx_update_frequency, 0); // run main programm gtk_main (); // stop pitch tracker thread pitch_tracker.stop_thread(); // delete function pointer class pointer delete fptr; delete cptr; //fprintf (stderr,"gxtuner, return 0 ...\n"); return 0; } gxtuner-3.0/paintbox.cpp000066400000000000000000000277741321541042300154140ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "paintbox.h" #include #include #include #define P_(s) (s) // FIXME -> gettext #include "resources.h" enum { PROP_PAINT_FUNC = 1, PROP_ICON_SET = 2, }; static void gx_paint_box_destroy(GtkWidget *object); static void gx_paint_box_set_property( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void gx_paint_box_get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); static gboolean gx_paint_box_expose(GtkWidget *widget, cairo_t *cr); static void gx_paint_box_style_set (GtkWidget *widget, GtkStyle *previous_style); G_DEFINE_TYPE(GxPaintBox, gx_paint_box, GTK_TYPE_BOX) #define get_stock_id(widget) (GX_PAINT_BOX_CLASS(GTK_WIDGET_GET_CLASS(widget))->stock_id) static void gx_paint_box_get_preferred_size (GtkWidget *widget, GtkOrientation orientation, gint *minimal_size, gint *natural_size) { if (orientation == GTK_ORIENTATION_HORIZONTAL) { *minimal_size = *natural_size = 100; } else { *minimal_size = *natural_size = 100; } } static void gx_paint_box_get_preferred_width ( GtkWidget *widget, gint *minimal_width, gint *natural_width) { gx_paint_box_get_preferred_size (widget, GTK_ORIENTATION_HORIZONTAL, minimal_width, natural_width); } static void gx_paint_box_get_preferred_height ( GtkWidget *widget, gint *minimal_height, gint *natural_height) { gx_paint_box_get_preferred_size (widget, GTK_ORIENTATION_VERTICAL, minimal_height, natural_height); } static void gx_paint_box_class_init (GxPaintBoxClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GtkWidgetClass *widget_class = (GtkWidgetClass*)klass; gobject_class->set_property = gx_paint_box_set_property; gobject_class->get_property = gx_paint_box_get_property; widget_class->destroy = gx_paint_box_destroy; widget_class->style_set = gx_paint_box_style_set; widget_class->draw = gx_paint_box_expose; widget_class->get_preferred_width = gx_paint_box_get_preferred_width; widget_class->get_preferred_height = gx_paint_box_get_preferred_height; klass->stock_id = "rahmen"; g_object_class_install_property( gobject_class, PROP_PAINT_FUNC, g_param_spec_string("paint-func", P_("Paint Type"), P_("Type of paint function for background"), "", G_PARAM_READWRITE)); gtk_widget_class_install_style_property( GTK_WIDGET_CLASS(klass), g_param_spec_string("paint-func", P_("Paint Type"), P_("Type of paint function for background"), NULL, G_PARAM_READWRITE)); g_object_class_install_property( gobject_class,PROP_ICON_SET, g_param_spec_int ("icon-set", P_("Icon Set"), P_("Type of Icon function for background"), 0, G_MAXINT, 0, G_PARAM_READWRITE)); gtk_widget_class_install_style_property( GTK_WIDGET_CLASS(klass), g_param_spec_int("icon-set", P_("Icon Set"), P_("Type of Icon function for background"), 0, G_MAXINT, 0, G_PARAM_READABLE)); gtk_widget_class_install_style_property( GTK_WIDGET_CLASS(klass), g_param_spec_int("width", P_("Width"), P_("size.width request for paintbox"), 0, G_MAXINT, 0, G_PARAM_READABLE)); gtk_widget_class_install_style_property( GTK_WIDGET_CLASS(klass), g_param_spec_int("height", P_("Height"), P_("size.height request for paintbox"), 0, G_MAXINT, 0, G_PARAM_READABLE)); } static void set_paint_func(GxPaintBox *paint_box, const gchar *paint_func) { gchar *spf; gtk_widget_style_get(GTK_WIDGET(paint_box), "paint-func", &spf, NULL); if (spf) { if (paint_box->paint_func && strcmp(paint_box->paint_func, spf) == 0) { return; } } else { if (!paint_func) { paint_func = ""; } if (paint_box->paint_func && strcmp(paint_box->paint_func, paint_func) == 0) { return; } spf = g_strdup(paint_func); } g_free(paint_box->paint_func); paint_box->paint_func = spf; set_expose_func(paint_box, spf); g_object_notify(G_OBJECT(paint_box), "paint-func"); } static void gx_paint_box_style_set(GtkWidget *widget, GtkStyle *previous_style) { GxPaintBox *paint_box = GX_PAINT_BOX(widget); set_paint_func(paint_box, paint_box->paint_func); } static void gx_paint_box_init (GxPaintBox *paint_box) { gtk_widget_set_redraw_on_allocate(GTK_WIDGET(paint_box), TRUE); paint_box->paint_func = g_strdup(""); set_paint_func(paint_box, NULL); paint_box->gxr_image = NULL; paint_box->icon_set = 0; paint_box->stock_image = gdk_pixbuf_new_from_resource( "/gxtuner/rahmen.png", NULL); } static void gx_paint_box_destroy(GtkWidget *object) { GxPaintBox *paint_box = GX_PAINT_BOX(object); if (paint_box->paint_func) { g_free(paint_box->paint_func); paint_box->paint_func = NULL; } if (G_IS_OBJECT(paint_box->gxr_image)) { g_object_unref(paint_box->gxr_image); } paint_box->gxr_image = NULL; if (G_IS_OBJECT(paint_box->stock_image)) { g_object_unref(paint_box->stock_image); } paint_box->stock_image = NULL; GTK_WIDGET_CLASS(gx_paint_box_parent_class)->destroy(object); } static gboolean gx_paint_box_expose(GtkWidget *widget, cairo_t *cr) { GxPaintBox *paint_box = GX_PAINT_BOX(widget); if (paint_box->expose_func) { paint_box->expose_func(widget, cr); } GTK_WIDGET_CLASS(gx_paint_box_parent_class)->draw(widget, cr); return FALSE; } static void set_icon(GxPaintBox *paint_box, int value) { int spf; gtk_widget_style_get(GTK_WIDGET(paint_box), "icon-set", &spf, NULL); paint_box->icon_set = spf; } static void gx_paint_box_set_property( GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GxPaintBox *paint_box = GX_PAINT_BOX(object); switch (prop_id) { case PROP_PAINT_FUNC: set_paint_func(paint_box, g_value_get_string(value)); break; case PROP_ICON_SET: set_icon(paint_box, g_value_get_int(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } static void gx_paint_box_get_property( GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { switch (prop_id) { case PROP_PAINT_FUNC: g_value_set_string(value, GX_PAINT_BOX(object)->paint_func); break; case PROP_ICON_SET: g_value_set_int (value, GX_PAINT_BOX(object)->icon_set); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } GtkWidget *gx_paint_box_new (GtkOrientation orientation, gboolean homogeneous, gint spacing) { return (GtkWidget*)g_object_new( GX_TYPE_PAINT_BOX, "orientation", orientation, "spacing", spacing, "homogeneous", homogeneous ? TRUE : FALSE, NULL); } /**************************************************************** ** Paint functions */ static void rahmen_expose(GtkWidget *wi, cairo_t *cr) { GtkAllocation *allocation = g_new0 (GtkAllocation, 1); gtk_widget_get_allocation(GTK_WIDGET(wi), allocation); gint rect_width = allocation->width-2; gint rect_height = allocation->height-3; if (rect_width <= 0 || rect_height <= 0) { return; } GxPaintBox *paintbox = GX_PAINT_BOX(wi); /* create a cairo context */ gint x0 = 1; gint y0 = 1; static double ne_w = 0.; if (ne_w != rect_width*rect_height || !(GDK_IS_PIXBUF (paintbox-> gxr_image))) { ne_w = rect_width*rect_height; if (G_IS_OBJECT(paintbox-> gxr_image)) { g_object_unref(paintbox->gxr_image); } GdkPixbuf *frame; double scalew = rect_width/double(gdk_pixbuf_get_width(paintbox->stock_image)-48); double scaleh = rect_height/double(gdk_pixbuf_get_height(paintbox->stock_image)-48); paintbox->gxr_image = gdk_pixbuf_scale_simple( paintbox->stock_image, rect_width, rect_height, GDK_INTERP_NEAREST); // upper border frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,24,0,gdk_pixbuf_get_width(paintbox->stock_image)-48,12); gdk_pixbuf_scale ( frame, paintbox->gxr_image,0,0,rect_width,12,0,0,scalew,1,GDK_INTERP_BILINEAR); // under border frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,24,gdk_pixbuf_get_height(paintbox->stock_image)-12, gdk_pixbuf_get_width(paintbox->stock_image)-48,12); gdk_pixbuf_scale ( frame,paintbox->gxr_image,0,gdk_pixbuf_get_height(paintbox->gxr_image)-12, rect_width,12,0,gdk_pixbuf_get_height(paintbox->gxr_image)-12, scalew,1,GDK_INTERP_BILINEAR); // left border frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,0,24,12,gdk_pixbuf_get_height(paintbox->stock_image)-48); gdk_pixbuf_scale( frame, paintbox->gxr_image,0,12,12,rect_height-24,0,0,1,scaleh,GDK_INTERP_BILINEAR); // right border frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,gdk_pixbuf_get_width(paintbox->stock_image)-12, 24,12,gdk_pixbuf_get_height(paintbox->stock_image)-48); gdk_pixbuf_scale( frame,paintbox->gxr_image,gdk_pixbuf_get_width(paintbox->gxr_image)-12, 12,12,rect_height-24,gdk_pixbuf_get_width(paintbox->gxr_image)-12, 0,1,scaleh,GDK_INTERP_BILINEAR); //left upper corner frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,0,0,20,20); gdk_pixbuf_scale ( frame, paintbox->gxr_image,0,0,20,20,0,0,1,1,GDK_INTERP_BILINEAR); //right upper corner frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,gdk_pixbuf_get_width(paintbox->stock_image)-20,0,20,20); gdk_pixbuf_scale ( frame, paintbox->gxr_image,gdk_pixbuf_get_width(paintbox->gxr_image)-20, 0,20,20,gdk_pixbuf_get_width(paintbox->gxr_image)-20,0,1,1, GDK_INTERP_BILINEAR); //left under corner frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,0,gdk_pixbuf_get_height(paintbox->stock_image)-20,20,20); gdk_pixbuf_scale ( frame, paintbox->gxr_image,0,gdk_pixbuf_get_height(paintbox->gxr_image)-20, 20,20,0,gdk_pixbuf_get_height(paintbox->gxr_image)-20,1,1, GDK_INTERP_BILINEAR); //right under corner frame = gdk_pixbuf_new_subpixbuf( paintbox->stock_image,gdk_pixbuf_get_width(paintbox->stock_image)-20, gdk_pixbuf_get_height(paintbox->stock_image)-20,20,20); gdk_pixbuf_scale ( frame, paintbox->gxr_image,gdk_pixbuf_get_width(paintbox->gxr_image)-20, gdk_pixbuf_get_height(paintbox->gxr_image)-20, 20,20,gdk_pixbuf_get_width(paintbox->gxr_image)-20, gdk_pixbuf_get_height(paintbox->gxr_image)-20,1,1, GDK_INTERP_BILINEAR); g_object_unref(paintbox->stock_image); g_object_unref(frame); } // base gdk_cairo_set_source_pixbuf(cr,paintbox->gxr_image, x0, y0); cairo_rectangle (cr, x0,y0,rect_width,rect_height); cairo_fill (cr); cairo_pattern_t*pat = cairo_pattern_create_linear (x0, y0, rect_width, y0); cairo_pattern_add_color_stop_rgb (pat, 1, 0.2, 0.2 , 0.2); cairo_pattern_add_color_stop_rgb (pat, 0.5, 0.1, 0.1 , 0.1); cairo_pattern_add_color_stop_rgb (pat, 0,0.05, 0.05 , 0.05); x0 += 11; y0 += 11; rect_width -= 22; rect_height -= 22; cairo_set_source (cr, pat); cairo_rectangle (cr, x0,y0,rect_width,rect_height); cairo_fill (cr); cairo_pattern_destroy (pat); g_free (allocation); } void set_expose_func(GxPaintBox *paint_box, const gchar *paint_func) { if (strcmp(paint_func, "rahmen_expose") == 0) { paint_box->expose_func = rahmen_expose; } else { paint_box->expose_func = 0; } } gxtuner-3.0/paintbox.h000066400000000000000000000041351321541042300150430ustar00rootroot00000000000000/* * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #ifndef __PAINT_BOX_H__ #define __PAINT_BOX_H__ #ifdef __cplusplus extern "C" { #endif #include G_BEGIN_DECLS #define GX_TYPE_PAINT_BOX (gx_paint_box_get_type ()) #define GX_PAINT_BOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GX_TYPE_PAINT_BOX, GxPaintBox)) #define GX_PAINT_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GX_TYPE_PAINT_BOX, GxPaintBoxClass)) #define GX_IS_PAINT_BOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GX_TYPE_PAINT_BOX)) #define GX_IS_PAINT_BOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GX_TYPE_PAINT_BOX)) #define GX_PAINT_BOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GX_TYPE_PAINT_BOX, GxPaintBoxClass)) typedef struct _GxPaintBox GxPaintBox; typedef struct _GxPaintBoxClass GxPaintBoxClass; struct _GxPaintBox { GtkBox box; gchar *paint_func; void (*expose_func)(GtkWidget*, cairo_t *); GdkPixbuf *gxr_image; GdkPixbuf *stock_image; guint icon_set; }; struct _GxPaintBoxClass { GtkBoxClass parent_class; const gchar *stock_id; }; GType gx_paint_box_get_type(void) G_GNUC_CONST; GtkWidget *gx_paint_box_new(GtkOrientation orientation, gboolean homogeneous, gint spacing); void set_expose_func(GxPaintBox *paint_box, const gchar *paint_func); G_END_DECLS #ifdef __cplusplus } #endif #endif /* __PAINT_BOX_H__ */ gxtuner-3.0/rahmen.png000066400000000000000000000150021321541042300150210ustar00rootroot00000000000000PNG  IHDR=2bKGD pHYs  tIME %^IDATx]M$U=FGi$`رA`;{gɛÒ?7 $ ,+dAc{{eF\7#3^wWT'O܈A e "R~s΍D<n,YojsxzOݗK!"C<<Gz]j:FtiD,˃4~S}u+&}otnfp4\4GOL9WWHirDY[ Y"ſn|9MYS$=1MRmje ~+3ﳮx=+mΒ:>2?fhj nӕur%#5_dV7]$x)0NS6AoskхVuxj#+! 2y"\ >x;#H@Sנ+S]v̗TZ~@2ҧkеǫ+. $EY%+D뺮,,?F%T+z *[BGіHkф]4I%˦<3+_蕤U8><<ܽ| \=RҧYd?"[jR2qog*Ⅼ ҸR) ܇wN9/?~E> Xsl6es<]-#15rWwL׾\肪 U:ߛXyN5 126D>{-AS#S30n,iF߳[ox&Z].՟::هRr[nxAO{Jg}'35m?m7)mtЂ59/cՆ?L_ҺʧF&s>ZW7ZĠ)B Ci=r]qAH`xWEJ@ϩT=ޣ4u W2SHYЈp]GOr 6s"in#2q]n-\F֣8~Bgi/q>цG/oh9RhX[d9r?Tz&6\;oUfh*M&M +(4Nw*#3|AJfkf3cwp]\+`rLm3Љ9R0g.4`JseBdSjÊC&z1' +SO."t`vθ *<KԗaE֤=ٰBg-;&Sg9joX1{kXs(+8u73Vc02& 1KV,lgXJ3ax*c eG9mXGy4鳗)φT<;B T  }Q7ޙ&5V- Yy&&B/eZo;Z0XG{hKhX2 *qqlJkqа. BІkA:cCl6| mӵ5ٸB#NH/k)  t`(œ +`b,k>:5u1mjd n E9A}HnɸeQ!#a8kIgBǡaŰBR2 E<+@:O `ðإNqM-aL;~Je7j9Je-5\] sq7S(Fgz{~#=W4a91q~p}0/|{ ,sa%R}0V%(Rg5桋 G} VmSnE =ɵy\bц5T7_pU>+2)ZDཔ p5妊a_|n4H[4'fνBVk7pUlM? V:.n6pDׅs^ igX 6fOJA Hi -)a_KSMY˲ + 5<ƐFL8Ƀq <6a6$eiieG"u8fJ蘈:(0l)$ܰBD3L4m6\6Lq ЕC5J!Rx/VGHFBBV\pm:|n_8k"˔ ]Q?o6K|_|?u 5BkHBZ3A??-7K|fj`=:4P۶܅y)ܺ/>_Rޅ2[]s-dplGp<z?v{2⑱lg?~oO??{$D3_|^;Jmѵ-nn piB7M{ ιh(&e$TjD7dC /"!c*=OMuMh=Y3q-PFж-^}Yv?Τz{ick]\ȐdPB >eԒ @iFHX( 9۸zp+n.LM\5[t6ER9.Qca"4΁8Bo1Aƕ7k]n.[+ыZWwh(mێNtϟ?|=_t!LFBRep@ڬjDyB-ˤOD^ԫ0Em˜ et-H 9%/ !s>HF[4ol7hZl?!E{Q刽t>s.oGN$n:u$g ~Ki!4N2h&7W25RyuO+n':p)مDBV1.*ẋe vJjξ;EB4=%=?^xwww'C`?~n{+~Cw'!*S,z_ Go oLNQfʺQu (~T{$5$>(W}`!WgǩDuwH厪]'[= A 6 ƺ{S{L~ ^b8E#BDl8@%—p#b%Y!SD#zS*$` B0JgXS/3MX}D#pz;njO99ˡ;],f?ZR_fjAqA@^Gzt)պ>}]ܺy֍PvV?sJ4MQ1e>rk:8w]FzUosn8RDnf?Ih,IENDB`gxtuner-3.0/resource.xml000066400000000000000000000002661321541042300154200ustar00rootroot00000000000000 rahmen.png gxtuner.png gxtuner-3.0/resources.c000066400000000000000000001537011321541042300152300ustar00rootroot00000000000000#include #if defined (__ELF__) && ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 6)) # define SECTION __attribute__ ((section (".gresource.resource"), aligned (8))) #else # define SECTION #endif static const SECTION union { const guint8 data[7818]; const double alignment; void * const ptr;} resource_resource_data = { { 0x47, 0x56, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf0, 0x14, 0xd8, 0x8f, 0x02, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x08, 0x00, 0x4c, 0x00, 0x98, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x30, 0xc3, 0x4e, 0x37, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x76, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x66, 0x04, 0x00, 0x00, 0xd4, 0xb5, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x66, 0x04, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x68, 0x04, 0x00, 0x00, 0x6c, 0x04, 0x00, 0x00, 0xfe, 0x7f, 0x8b, 0x27, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x04, 0x00, 0x00, 0x0a, 0x00, 0x76, 0x00, 0x78, 0x04, 0x00, 0x00, 0x8a, 0x1e, 0x00, 0x00, 0x67, 0x78, 0x74, 0x75, 0x6e, 0x65, 0x72, 0x2f, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x67, 0x78, 0x74, 0x75, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x16, 0x08, 0x06, 0x00, 0x00, 0x00, 0xc4, 0xb4, 0x6c, 0x3b, 0x00, 0x00, 0x00, 0x04, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64, 0x88, 0x00, 0x00, 0x03, 0x5d, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x8d, 0x93, 0x3d, 0x6c, 0x1c, 0x45, 0x14, 0xc7, 0x7f, 0x33, 0xb3, 0x1f, 0x77, 0xb7, 0xde, 0xf3, 0xf9, 0x23, 0x8e, 0x83, 0x4d, 0xa2, 0x08, 0x0b, 0x05, 0x08, 0x26, 0x11, 0x10, 0x91, 0xc2, 0xa2, 0xc0, 0x34, 0x51, 0x0a, 0x1a, 0x2a, 0x0a, 0x7a, 0x0a, 0x5a, 0x84, 0x90, 0x28, 0xe8, 0x29, 0x28, 0xa9, 0xa0, 0x88, 0xe4, 0x0a, 0x24, 0x28, 0xd3, 0x50, 0x40, 0x43, 0x83, 0xec, 0x02, 0x2b, 0x71, 0x82, 0x12, 0x13, 0x3e, 0xfc, 0x85, 0xcf, 0xe7, 0xbd, 0x8f, 0xbd, 0xdd, 0xd9, 0x79, 0x14, 0xf6, 0x39, 0x3e, 0x7f, 0xe5, 0xfe, 0xd2, 0x6a, 0xde, 0xbc, 0x79, 0xef, 0xf7, 0xde, 0x68, 0xde, 0xaa, 0xb9, 0xb9, 0x39, 0x71, 0xce, 0x51, 0x14, 0x96, 0xc2, 0x59, 0x9c, 0xb1, 0xd8, 0x36, 0x14, 0x61, 0x17, 0xf7, 0xf1, 0x0a, 0xdd, 0xd4, 0xc3, 0x7d, 0x35, 0x89, 0x68, 0x4d, 0xeb, 0xbb, 0x16, 0xb5, 0x8b, 0x55, 0x92, 0x8f, 0x12, 0xca, 0x3f, 0x45, 0xd8, 0x5b, 0x1b, 0x44, 0xf3, 0x2d, 0xec, 0xb7, 0xe3, 0x14, 0x8b, 0x31, 0xf8, 0x16, 0xa5, 0x40, 0x32, 0x83, 0x27, 0x22, 0x38, 0xe7, 0xf0, 0x86, 0x3b, 0x5c, 0x7e, 0xff, 0x0f, 0x76, 0xb7, 0x4b, 0x3c, 0x59, 0xb8, 0x80, 0x28, 0xa1, 0x34, 0x03, 0x39, 0x19, 0xf9, 0x70, 0x8e, 0x4e, 0x42, 0xfa, 0xa4, 0x05, 0xf5, 0x4a, 0x4a, 0xf4, 0x2a, 0x34, 0x63, 0x28, 0x14, 0xd4, 0xae, 0x37, 0x79, 0xf1, 0x76, 0xc2, 0xea, 0x8f, 0x11, 0x7a, 0x66, 0xf6, 0x2f, 0x94, 0x2e, 0x10, 0x07, 0x43, 0x17, 0x3b, 0xc4, 0xd7, 0xeb, 0xe8, 0x91, 0x0e, 0x62, 0x85, 0x7c, 0x0b, 0x4c, 0x15, 0x74, 0x2c, 0x00, 0x84, 0xcd, 0x82, 0x78, 0xcd, 0xee, 0x81, 0x15, 0x98, 0x49, 0x28, 0x3a, 0x60, 0xeb, 0xa0, 0x94, 0x30, 0x7a, 0x33, 0x61, 0xec, 0x8a, 0x45, 0x07, 0x0a, 0x7d, 0xe3, 0xdd, 0x27, 0xc4, 0xa3, 0x6d, 0xf2, 0xa6, 0x61, 0x67, 0x65, 0x88, 0xf0, 0x9c, 0xc3, 0xbf, 0xd0, 0xc1, 0xe5, 0x50, 0xac, 0x1b, 0x74, 0x0c, 0x3a, 0xde, 0x63, 0xcd, 0x7e, 0xdf, 0xe0, 0x83, 0x0f, 0xff, 0x44, 0x01, 0x68, 0xf0, 0xce, 0x83, 0x74, 0xa0, 0xa8, 0x2b, 0x54, 0xb5, 0xcb, 0xf0, 0x4b, 0x8e, 0xb4, 0xa1, 0xa8, 0x3f, 0x0c, 0xd0, 0x51, 0xad, 0xe0, 0xf2, 0x9b, 0xff, 0x52, 0x64, 0x8a, 0xfa, 0xfd, 0x0a, 0x00, 0xe5, 0x37, 0xea, 0x48, 0x0e, 0xea, 0x51, 0x8c, 0x0a, 0xa1, 0x7b, 0xa9, 0x09, 0x0a, 0xbc, 0x1c, 0xbc, 0x74, 0xaf, 0xfb, 0xee, 0x78, 0x1b, 0x35, 0xe6, 0x90, 0xad, 0x00, 0xb5, 0x51, 0xa1, 0x3c, 0x93, 0x12, 0x8e, 0x39, 0xb6, 0x1f, 0x1a, 0xd2, 0xad, 0x12, 0x3a, 0xcb, 0xe0, 0xf9, 0xd9, 0x06, 0x95, 0x89, 0x16, 0x8d, 0x7b, 0x31, 0x79, 0x62, 0x88, 0xae, 0xe4, 0xc8, 0x50, 0x97, 0x6c, 0x4d, 0x91, 0x6f, 0x80, 0x1d, 0xc9, 0xc0, 0x81, 0xb7, 0x69, 0x50, 0x6d, 0x85, 0xda, 0x35, 0xc8, 0x68, 0x8e, 0x4d, 0x84, 0xf4, 0x31, 0x20, 0x50, 0x7e, 0xad, 0x83, 0x0e, 0x61, 0x7d, 0x31, 0xc0, 0x39, 0x85, 0x77, 0x7f, 0xa9, 0xc6, 0xf4, 0x5b, 0x3b, 0x4c, 0x5e, 0xdb, 0x62, 0xe5, 0xee, 0x79, 0x76, 0x56, 0x3c, 0xb2, 0xd8, 0x22, 0xd5, 0x94, 0x62, 0xb1, 0x4c, 0xf1, 0xd9, 0x39, 0xfc, 0x4d, 0x83, 0x6e, 0x2a, 0xa2, 0x1f, 0xaa, 0x04, 0x49, 0x93, 0x52, 0x52, 0xc2, 0x46, 0x9a, 0xfc, 0x73, 0x83, 0x6b, 0x1b, 0x94, 0x16, 0xc4, 0x58, 0x92, 0xc7, 0x8a, 0xdd, 0x7b, 0x43, 0x54, 0xa7, 0x5a, 0x78, 0xcb, 0xbf, 0x4e, 0x30, 0xf2, 0x72, 0xc2, 0xd8, 0x4c, 0x02, 0x77, 0x27, 0x58, 0xfd, 0x7a, 0x9a, 0xa2, 0x0b, 0xd2, 0x06, 0xe5, 0xc0, 0x6c, 0x07, 0x98, 0xfd, 0x41, 0x50, 0xb2, 0x6f, 0x08, 0x98, 0x66, 0x00, 0xcb, 0xc1, 0x81, 0xe3, 0xbf, 0x6f, 0xa6, 0xd8, 0x8e, 0x52, 0xa4, 0xe5, 0x33, 0xf3, 0xf6, 0x0e, 0xde, 0xc6, 0x6a, 0x85, 0x9f, 0xef, 0x4c, 0x51, 0x5f, 0x2b, 0x61, 0xbb, 0x8a, 0xc2, 0xfa, 0x14, 0x45, 0x81, 0x38, 0xc7, 0xe0, 0x52, 0x48, 0x06, 0x92, 0x95, 0x01, 0xe1, 0xd1, 0x2f, 0x35, 0xbc, 0x56, 0x2b, 0xa5, 0xb5, 0x14, 0x21, 0x22, 0x80, 0xc3, 0x39, 0xb7, 0x6f, 0x0f, 0xae, 0xfe, 0x78, 0x45, 0xde, 0x36, 0x78, 0x59, 0x96, 0x0f, 0x10, 0x0c, 0x0c, 0x50, 0xec, 0x70, 0x8e, 0x37, 0x48, 0x77, 0x02, 0xa0, 0x15, 0xa2, 0x06, 0x68, 0x60, 0x5f, 0xfa, 0xac, 0xea, 0x7b, 0x49, 0x42, 0xfd, 0x66, 0x8d, 0xdd, 0x85, 0x31, 0x1a, 0x57, 0xd3, 0xa7, 0x85, 0x9e, 0xa1, 0x63, 0xe0, 0xa7, 0xc0, 0x3d, 0xe5, 0x9e, 0x21, 0x7f, 0xcf, 0x47, 0x5d, 0x8b, 0x71, 0xf3, 0xe5, 0x83, 0xf3, 0xa3, 0x71, 0x47, 0xe5, 0x9d, 0x55, 0x55, 0x04, 0x3a, 0x97, 0x02, 0xf4, 0x55, 0xc3, 0xf6, 0x6f, 0x9b, 0x94, 0x47, 0xc7, 0x81, 0xdd, 0x33, 0x81, 0xbd, 0x33, 0x7d, 0xd8, 0x71, 0x38, 0x41, 0x44, 0x40, 0x43, 0xe7, 0x9d, 0x18, 0xa5, 0x52, 0xc2, 0x2f, 0x53, 0xb2, 0x75, 0x8b, 0xa0, 0x90, 0x43, 0xf1, 0xa7, 0xdd, 0xe0, 0x00, 0xac, 0x94, 0xea, 0x87, 0x02, 0x9d, 0x28, 0x44, 0xdd, 0x0a, 0xe0, 0x41, 0xca, 0x28, 0x3e, 0xb2, 0x6c, 0xb1, 0x25, 0x4b, 0x56, 0xc9, 0xfb, 0x62, 0x4f, 0xfa, 0xbc, 0xc3, 0xa0, 0xbe, 0x2b, 0x01, 0xe9, 0xeb, 0x3e, 0xe5, 0xe9, 0x10, 0xf3, 0xdc, 0x14, 0xee, 0x06, 0x54, 0x16, 0xfe, 0xc1, 0x2d, 0x41, 0x77, 0x06, 0xfc, 0x25, 0x8e, 0x8d, 0x60, 0xdf, 0xb8, 0xf5, 0xba, 0xed, 0x39, 0x7b, 0xab, 0x0b, 0x35, 0xf6, 0x76, 0x15, 0xb7, 0xf4, 0x37, 0xd1, 0x27, 0x4d, 0xfc, 0x96, 0x87, 0xa9, 0x27, 0x78, 0x2f, 0x54, 0xe8, 0xce, 0x1b, 0x2a, 0xbf, 0x83, 0xce, 0x8f, 0x03, 0x7b, 0x7b, 0x7d, 0xd4, 0xd1, 0x53, 0x5e, 0x0a, 0x08, 0xb2, 0x14, 0xef, 0x4e, 0x13, 0x7f, 0x43, 0x43, 0x52, 0x40, 0xea, 0xd0, 0x75, 0xf0, 0x2b, 0x25, 0xb2, 0x52, 0x7e, 0x2a, 0xf4, 0xa0, 0xe3, 0x93, 0x54, 0x6a, 0xa4, 0x84, 0x9f, 0x76, 0xe8, 0x3d, 0x43, 0x2f, 0x5d, 0x3d, 0xe8, 0x52, 0xfd, 0x22, 0x05, 0xbc, 0x53, 0xa1, 0xf0, 0x8c, 0x1f, 0xe4, 0x24, 0xfb, 0x34, 0xdf, 0xd1, 0xfd, 0xff, 0xe5, 0x40, 0xf3, 0x80, 0xc4, 0x9c, 0x76, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, 0x00, 0x28, 0x75, 0x75, 0x61, 0x79, 0x29, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x61, 0x68, 0x6d, 0x65, 0x6e, 0x2e, 0x70, 0x6e, 0x67, 0x00, 0x00, 0x02, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0xb4, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3d, 0xcd, 0x06, 0x32, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe0, 0x08, 0x08, 0x0d, 0x02, 0x25, 0x5e, 0xbe, 0xf7, 0x9a, 0x00, 0x00, 0x19, 0x8f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0x5d, 0x4d, 0xaf, 0x24, 0xc9, 0x55, 0x3d, 0xf7, 0x46, 0xd6, 0x47, 0xf7, 0x18, 0x69, 0x24, 0xda, 0x1f, 0xd2, 0x60, 0xd8, 0xb1, 0x41, 0x02, 0x8d, 0x60, 0xc3, 0xd6, 0x3b, 0x7b, 0x67, 0xc9, 0x1a, 0xc9, 0x9b, 0x91, 0x11, 0xc3, 0x92, 0x3f, 0xe3, 0xad, 0x37, 0x88, 0xcd, 0x20, 0x24, 0x10, 0xac, 0xf8, 0x0b, 0x2c, 0xb0, 0x05, 0x2b, 0x64, 0xbc, 0x41, 0x96, 0x85, 0xc1, 0x63, 0x8d, 0x7b, 0xba, 0xdf, 0x7b, 0xf5, 0xea, 0x65, 0x46, 0x5c, 0x16, 0xf1, 0x91, 0x37, 0x23, 0x33, 0xab, 0xb2, 0x5e, 0x77, 0x57, 0xbe, 0x91, 0xef, 0x19, 0xf5, 0x54, 0xbd, 0xac, 0xfc, 0xce, 0x13, 0x27, 0x4f, 0xdc, 0x88, 0xb8, 0x41, 0x18, 0xe2, 0x03, 0x00, 0x7f, 0x0d, 0xe0, 0xdb, 0x00, 0xfe, 0x10, 0xc0, 0x1e, 0xbf, 0x65, 0x20, 0xa2, 0xc9, 0xe5, 0x22, 0x52, 0x7e, 0x73, 0xce, 0x8d, 0x96, 0xeb, 0xed, 0x44, 0x04, 0xcc, 0x3c, 0xb9, 0x0e, 0x11, 0xcd, 0x6e, 0xa3, 0x97, 0xd5, 0xdb, 0x2c, 0x59, 0x6f, 0x6a, 0xbf, 0x73, 0xe7, 0x78, 0x0e, 0xfa, 0x7a, 0x4f, 0xdd, 0x97, 0x4b, 0x21, 0x22, 0x93, 0xcb, 0x43, 0x08, 0x10, 0x11, 0x3c, 0x3c, 0x3c, 0xa0, 0x6d, 0x5b, 0x84, 0x10, 0x1e, 0xf7, 0xfc, 0xd4, 0xf7, 0x4f, 0x00, 0xfc, 0x10, 0xc0, 0xb3, 0x37, 0x25, 0xc4, 0x25, 0x37, 0x6f, 0xee, 0x61, 0xe5, 0x07, 0xa4, 0x89, 0x31, 0xf7, 0x40, 0x99, 0x79, 0xb4, 0x1f, 0x7d, 0x2e, 0x35, 0xc9, 0xf4, 0xc3, 0x9a, 0x3a, 0xd7, 0xa9, 0x73, 0x9f, 0x23, 0xd2, 0xdc, 0x75, 0xcc, 0x11, 0xfa, 0x14, 0x09, 0xa7, 0xf6, 0xb9, 0xe4, 0x1e, 0xcc, 0xdd, 0xc7, 0x7a, 0x3f, 0xfa, 0xf8, 0x7a, 0x1b, 0xbd, 0xbf, 0x10, 0x02, 0x98, 0x19, 0x21, 0x84, 0xd9, 0x6b, 0xad, 0x97, 0xd5, 0xbf, 0xeb, 0xfd, 0xe7, 0xfd, 0x79, 0xef, 0x07, 0xbf, 0x89, 0x48, 0x21, 0x71, 0xfe, 0x97, 0xe1, 0xbd, 0x47, 0x08, 0xa1, 0x90, 0xfb, 0x31, 0x84, 0xfe, 0x04, 0xc0, 0x8f, 0x2e, 0x25, 0x2f, 0x33, 0xc3, 0x39, 0x87, 0xa6, 0x69, 0xe0, 0x9c, 0x03, 0x11, 0x95, 0x9b, 0xbf, 0x84, 0xd0, 0xe7, 0x94, 0x63, 0xe9, 0xc3, 0xac, 0x97, 0x4d, 0xdd, 0xe8, 0x39, 0x02, 0xd7, 0xbf, 0xd7, 0xe7, 0x5f, 0x6f, 0xb7, 0x64, 0x7f, 0xf5, 0xbe, 0xe6, 0x48, 0x5b, 0xef, 0xa3, 0x5e, 0x2f, 0x5f, 0x7f, 0x26, 0x85, 0xbe, 0x27, 0x79, 0x59, 0x5e, 0xaf, 0x26, 0xeb, 0x14, 0xb9, 0xea, 0x75, 0x33, 0x69, 0x33, 0xf1, 0xf4, 0xb9, 0x6a, 0xa2, 0xe5, 0x63, 0x77, 0x5d, 0x07, 0xe7, 0x1c, 0xbc, 0xf7, 0x70, 0xce, 0x8d, 0x54, 0x54, 0xef, 0x5f, 0xef, 0x3b, 0x2b, 0x6f, 0xd3, 0x34, 0x10, 0x11, 0x74, 0x5d, 0x57, 0x88, 0x2b, 0x22, 0x85, 0xc0, 0x99, 0xe0, 0x7a, 0x7f, 0x5d, 0xd7, 0xe1, 0x78, 0x3c, 0x96, 0x6d, 0x96, 0x10, 0xfa, 0x03, 0x00, 0x3f, 0x5b, 0xaa, 0xcc, 0xcc, 0x8c, 0xcd, 0x66, 0x83, 0xcd, 0x66, 0x53, 0x48, 0x3c, 0xf5, 0x40, 0xa7, 0x96, 0xe7, 0x8b, 0xcd, 0x25, 0x56, 0x93, 0x55, 0x7f, 0xaf, 0x15, 0xba, 0x26, 0xc0, 0x1c, 0xc1, 0xa6, 0x2c, 0x41, 0xde, 0xb7, 0x26, 0xd9, 0x29, 0x42, 0x3b, 0xe7, 0x66, 0x15, 0xb0, 0x26, 0x6b, 0x7e, 0xa0, 0xa7, 0xc8, 0x3d, 0xa7, 0x6e, 0x53, 0xc7, 0xae, 0x1f, 0x66, 0x4d, 0x3c, 0x4d, 0xe8, 0x5a, 0xd5, 0x6a, 0x22, 0xd6, 0xaf, 0xf2, 0x29, 0x92, 0x7a, 0xef, 0x47, 0x44, 0xcf, 0xc7, 0xd2, 0xfb, 0xd1, 0xbf, 0x4d, 0xed, 0x3b, 0x3f, 0xbb, 0xac, 0xc2, 0xf5, 0x3d, 0x6b, 0xdb, 0x16, 0x22, 0x52, 0x9e, 0x4b, 0x26, 0xaf, 0xf7, 0xbe, 0x90, 0x5a, 0x2f, 0x9b, 0xba, 0x86, 0xe3, 0xf1, 0x88, 0xe3, 0xf1, 0x78, 0x96, 0x9f, 0x4d, 0xf2, 0xcc, 0xcf, 0x96, 0x10, 0x79, 0xb7, 0xdb, 0x61, 0xbb, 0xdd, 0x8e, 0x1e, 0x60, 0x56, 0xea, 0x9a, 0x2c, 0xf9, 0x6f, 0xad, 0xdc, 0xf9, 0x44, 0xbd, 0xf7, 0x68, 0x9a, 0x66, 0x44, 0x12, 0x7d, 0x21, 0x73, 0xa4, 0xcd, 0xeb, 0xe5, 0x1b, 0xdf, 0x34, 0x4d, 0x51, 0xac, 0x69, 0x22, 0xc6, 0xb2, 0xab, 0xb7, 0x9b, 0x23, 0xec, 0xd4, 0xef, 0x53, 0x16, 0x65, 0x8e, 0xac, 0x53, 0x2a, 0x3a, 0x67, 0x05, 0xe6, 0x7c, 0x65, 0x4d, 0xc0, 0xa6, 0x69, 0x46, 0x0a, 0x58, 0xab, 0x6e, 0x7d, 0x6d, 0xba, 0x20, 0xe8, 0xfb, 0xaa, 0x0b, 0x62, 0x5e, 0xae, 0x0b, 0x08, 0x33, 0xa3, 0xeb, 0x3a, 0x6c, 0xb7, 0x5b, 0xb4, 0x6d, 0x1b, 0x8f, 0x81, 0x71, 0x01, 0xd4, 0x6f, 0x88, 0xbc, 0x2c, 0xff, 0x9d, 0x7f, 0xcb, 0xfb, 0x9a, 0xb3, 0x67, 0x44, 0x34, 0x29, 0x20, 0xb5, 0x5a, 0x33, 0x33, 0xf6, 0xfb, 0x3d, 0x98, 0x19, 0x0f, 0x0f, 0x0f, 0xa3, 0x82, 0x53, 0x13, 0xfa, 0xdb, 0xe7, 0xc8, 0xbc, 0xd9, 0x6c, 0xb0, 0xdf, 0xef, 0x4b, 0x09, 0xd3, 0xc4, 0xca, 0xff, 0x9a, 0xa6, 0x29, 0xdf, 0xe7, 0x3c, 0xac, 0x26, 0x79, 0x56, 0x77, 0x4d, 0xfe, 0x5c, 0x8a, 0xf5, 0x36, 0xf9, 0x35, 0x55, 0x2b, 0x79, 0x5f, 0x48, 0x86, 0xdb, 0xcc, 0x91, 0xf5, 0x94, 0x3d, 0xa8, 0xfd, 0xe3, 0x29, 0x05, 0x3f, 0xe5, 0xfb, 0x4f, 0xd9, 0x9c, 0x5a, 0xed, 0xea, 0x82, 0x5b, 0xff, 0x3e, 0x47, 0x7a, 0x5d, 0x90, 0x6a, 0x85, 0x9e, 0x3a, 0x46, 0xad, 0x74, 0xf9, 0x19, 0x69, 0x8b, 0xa1, 0xb7, 0xd7, 0x44, 0x2c, 0xcb, 0x83, 0x00, 0x34, 0x7e, 0x53, 0xcc, 0x7d, 0xe6, 0x75, 0xba, 0xae, 0x2b, 0x8a, 0x9b, 0x9f, 0x9d, 0x26, 0x7d, 0xfd, 0xd6, 0xd4, 0x6f, 0xf0, 0x74, 0xc6, 0xf0, 0xbe, 0xbf, 0xee, 0xdd, 0x6e, 0x07, 0x66, 0xc6, 0xe1, 0x70, 0x98, 0xad, 0x34, 0x12, 0x80, 0xc3, 0x5c, 0x34, 0x83, 0x88, 0xb0, 0xdf, 0xef, 0x47, 0xaa, 0x9c, 0x4f, 0x4c, 0x93, 0xc1, 0x39, 0x57, 0x08, 0x9f, 0x95, 0x57, 0x97, 0xe2, 0x10, 0xc2, 0x48, 0x69, 0x72, 0xe9, 0xac, 0x15, 0x44, 0x93, 0x59, 0x5b, 0x93, 0xda, 0x16, 0x0c, 0x89, 0x8d, 0x59, 0x22, 0xc5, 0xbf, 0x05, 0xcc, 0x6e, 0x96, 0x9c, 0xf9, 0x7c, 0xf3, 0x39, 0x9e, 0xab, 0xcc, 0x4d, 0x59, 0x87, 0x53, 0x24, 0x3c, 0x57, 0x8f, 0xd0, 0xea, 0x5b, 0x7f, 0x9f, 0xaa, 0x84, 0x69, 0x6b, 0x40, 0x44, 0xc5, 0x3e, 0xe8, 0xfd, 0xd6, 0x0f, 0x3d, 0xfe, 0xad, 0x8f, 0x31, 0x4d, 0x52, 0x6d, 0xa5, 0xb4, 0x1a, 0x6a, 0x65, 0xf7, 0xbe, 0x03, 0x11, 0x8f, 0x0a, 0x95, 0x7e, 0xe6, 0xf9, 0xd9, 0x11, 0x11, 0xba, 0xae, 0x2b, 0xcf, 0x33, 0xef, 0xb3, 0xae, 0x03, 0x78, 0xef, 0x8b, 0x3d, 0xa9, 0x2b, 0x8d, 0x1a, 0x6d, 0xdb, 0xce, 0x92, 0x3a, 0x3e, 0xe9, 0x19, 0x32, 0x3f, 0x7f, 0xfe, 0x1c, 0x9b, 0xcd, 0x66, 0xa4, 0x68, 0x9a, 0xd0, 0xd9, 0x6a, 0xe4, 0x0b, 0xda, 0x6e, 0xb7, 0x03, 0x95, 0xd3, 0x95, 0x80, 0xda, 0x12, 0xe8, 0x75, 0x72, 0x25, 0x23, 0x93, 0x35, 0x5f, 0x64, 0xfd, 0x56, 0xd0, 0x37, 0x8c, 0x5d, 0xfa, 0x24, 0x1e, 0x78, 0xb4, 0x29, 0x8b, 0x30, 0xd8, 0x4e, 0x9d, 0x87, 0xf6, 0x87, 0x53, 0x36, 0x41, 0x6f, 0x73, 0xca, 0xdb, 0xea, 0x6b, 0xd1, 0x85, 0xb5, 0x56, 0xe2, 0x1a, 0xba, 0xc0, 0xd6, 0xfe, 0x75, 0x78, 0x9c, 0xf8, 0xb8, 0x6a, 0x1f, 0x9b, 0xaf, 0x23, 0x2b, 0x21, 0x11, 0x20, 0x32, 0x15, 0x79, 0x08, 0x89, 0xc0, 0x1e, 0x22, 0xe9, 0x5c, 0x04, 0x10, 0x8c, 0x0b, 0x8f, 0x3e, 0xc6, 0x78, 0x1f, 0x02, 0x80, 0x06, 0xfe, 0x3b, 0x8a, 0x05, 0x23, 0x04, 0x81, 0x48, 0x00, 0x40, 0xa3, 0x8a, 0xa1, 0xf6, 0xdb, 0x53, 0xd7, 0xa0, 0x2b, 0x88, 0x53, 0x11, 0x90, 0x9a, 0xd4, 0x5d, 0xd7, 0xe1, 0xf6, 0xf6, 0x76, 0xb4, 0xbc, 0xb9, 0x94, 0xcc, 0x97, 0x54, 0x94, 0xf2, 0x89, 0xe6, 0x5a, 0xb1, 0x7e, 0x40, 0xb5, 0x32, 0xeb, 0xd2, 0xa7, 0x6b, 0xd0, 0xb5, 0xc7, 0xab, 0x2b, 0x2e, 0x00, 0x20, 0x24, 0x45, 0x05, 0xa6, 0x08, 0x59, 0x13, 0x25, 0x2b, 0x44, 0xfd, 0x9a, 0xeb, 0xba, 0xae, 0x2c, 0xcb, 0x0f, 0x2c, 0xff, 0x9d, 0xcf, 0x3f, 0x12, 0x90, 0x46, 0xa4, 0xd1, 0xf7, 0x25, 0x93, 0x54, 0x2b, 0x7a, 0x3c, 0xa6, 0x80, 0x88, 0x67, 0x7d, 0xb2, 0xf7, 0x5d, 0xda, 0x17, 0x8f, 0x08, 0x3d, 0xf7, 0x5a, 0xaf, 0x2d, 0x47, 0xbd, 0x9d, 0x26, 0x43, 0xbe, 0xc6, 0x3a, 0x72, 0xa4, 0x95, 0x6e, 0xea, 0xed, 0xd0, 0x17, 0x5c, 0x41, 0xc8, 0xe7, 0x10, 0xfa, 0xc2, 0x43, 0x04, 0xb4, 0x6d, 0x07, 0x50, 0x5c, 0x5e, 0x48, 0x2a, 0x1e, 0x8c, 0xde, 0x4e, 0x64, 0x6f, 0x5c, 0xbf, 0x79, 0xf2, 0xe9, 0x68, 0x81, 0x18, 0xd7, 0xe1, 0x00, 0x2d, 0xc8, 0xce, 0x39, 0x6c, 0xb7, 0xdb, 0x51, 0x45, 0x71, 0x52, 0xa1, 0x9f, 0x3d, 0x7b, 0x86, 0xdd, 0x6e, 0x37, 0x52, 0x96, 0xac, 0x6c, 0x59, 0xa1, 0xa7, 0x2a, 0x86, 0x75, 0x09, 0xd7, 0x37, 0xa8, 0x2e, 0x10, 0xf9, 0xf5, 0xae, 0xd5, 0x31, 0x2f, 0xcf, 0xc4, 0xae, 0x2b, 0x1c, 0x53, 0xaa, 0xae, 0x09, 0xaf, 0x0b, 0xc3, 0x66, 0xb3, 0x41, 0xdb, 0x3e, 0x80, 0xd9, 0x0d, 0x2a, 0x8f, 0xf5, 0x5b, 0x42, 0x47, 0x02, 0x86, 0xd1, 0x96, 0x48, 0xae, 0xba, 0x00, 0xe8, 0xe3, 0x6b, 0xd5, 0xd1, 0x84, 0xad, 0xef, 0x5d, 0xaf, 0xa0, 0x34, 0x49, 0x96, 0x25, 0xcb, 0xa6, 0x3c, 0x77, 0x7f, 0xee, 0xbd, 0xdf, 0x25, 0xc7, 0x20, 0x02, 0x82, 0x0f, 0x55, 0xe5, 0x31, 0xa9, 0x2c, 0x00, 0x82, 0x40, 0x88, 0x40, 0x88, 0x4a, 0xcd, 0x0c, 0x78, 0x2f, 0x45, 0x71, 0xb3, 0x35, 0x41, 0xfa, 0x8b, 0x29, 0xde, 0x0f, 0x08, 0x41, 0x28, 0x11, 0xa7, 0xdc, 0x33, 0xd2, 0x25, 0x2b, 0xee, 0x97, 0x08, 0x8e, 0x39, 0x16, 0x00, 0x49, 0xd5, 0x4a, 0xf5, 0x19, 0x44, 0x10, 0x7c, 0x5f, 0x08, 0xfb, 0x82, 0x92, 0x39, 0xe3, 0xe1, 0xbd, 0x8c, 0xb8, 0x54, 0xbf, 0xdd, 0xee, 0xee, 0xee, 0x06, 0xb6, 0x68, 0xa4, 0xd0, 0xdb, 0xed, 0x16, 0xdb, 0xed, 0xf6, 0x6c, 0x03, 0x48, 0xba, 0xc1, 0xfe, 0xee, 0xee, 0xee, 0xee, 0x78, 0x3c, 0x1e, 0xbb, 0xae, 0xeb, 0x44, 0x44, 0x57, 0x3f, 0x45, 0xfd, 0x03, 0x00, 0xa7, 0x96, 0x73, 0xfa, 0xf7, 0xd5, 0x6a, 0xfd, 0xba, 0xb1, 0xa7, 0xfe, 0xad, 0xfe, 0x5d, 0xce, 0xc4, 0xd7, 0xe5, 0x4c, 0xc8, 0x52, 0x16, 0x2c, 0x17, 0xb5, 0xbf, 0x25, 0xfb, 0x5d, 0xd2, 0x88, 0xb5, 0x6c, 0x4d, 0xc1, 0xa0, 0x70, 0xa5, 0xb7, 0xbd, 0x10, 0x40, 0xe9, 0x7b, 0x24, 0x59, 0x00, 0xc8, 0xf5, 0x6a, 0x49, 0x92, 0x4e, 0xba, 0xdf, 0x06, 0x10, 0x20, 0x97, 0xb5, 0xc4, 0xfd, 0x48, 0x4f, 0x1e, 0x1e, 0x83, 0x04, 0x08, 0x91, 0xc0, 0xae, 0x5c, 0x3c, 0x5d, 0x70, 0xc5, 0xc3, 0x75, 0x7d, 0xf5, 0x5c, 0x65, 0x74, 0x17, 0x24, 0x5e, 0x0b, 0xf1, 0x86, 0xf6, 0xbb, 0x1d, 0xed, 0x9f, 0x3f, 0x67, 0x47, 0x0e, 0x22, 0x0c, 0xa2, 0x5c, 0xb0, 0x05, 0x53, 0x75, 0x40, 0x66, 0xc6, 0x76, 0xbb, 0xc5, 0xe1, 0x70, 0x98, 0x3e, 0x3c, 0x33, 0xe3, 0x2b, 0x5f, 0xf9, 0xca, 0xe8, 0x95, 0xa4, 0x55, 0x38, 0x7f, 0x3e, 0x3c, 0x3c, 0xdc, 0xbd, 0x7c, 0xf9, 0xf2, 0x95, 0x0c, 0x8b, 0x0d, 0xa5, 0x7f, 0x5c, 0x3d, 0x16, 0x52, 0xc7, 0xd2, 0xa7, 0xf6, 0xbb, 0x15, 0x59, 0x64, 0x89, 0xbf, 0x3f, 0xf3, 0xf8, 0xa9, 0x22, 0xe1, 0x5b, 0x6a, 0x13, 0xef, 0x8f, 0x52, 0x88, 0x32, 0x71, 0xf4, 0xc1, 0x6f, 0xf9, 0x67, 0x2a, 0xe2, 0x85, 0xac, 0x0b, 0x92, 0x9c, 0xd2, 0xb8, 0xa4, 0x52, 0xba, 0x00, 0x29, 0xdf, 0x09, 0xdc, 0x87, 0xce, 0xd2, 0x7f, 0xfd, 0x77, 0x4e, 0x3c, 0x49, 0x56, 0x26, 0x71, 0x26, 0x2f, 0x4f, 0x2e, 0x19, 0x00, 0x23, 0xc0, 0x0f, 0xb6, 0x17, 0x08, 0x42, 0x7a, 0x1c, 0x04, 0x42, 0x40, 0x80, 0x20, 0xe4, 0x7d, 0x90, 0x24, 0xd9, 0xa1, 0xf4, 0x34, 0x09, 0xf1, 0x3b, 0x25, 0x69, 0x92, 0x54, 0x90, 0xb8, 0x49, 0x47, 0x0a, 0x69, 0x3d, 0x4e, 0xcb, 0x42, 0xda, 0x56, 0xd5, 0x1b, 0xbb, 0x87, 0x48, 0x73, 0x7f, 0x00, 0xc4, 0x27, 0xa2, 0x30, 0x84, 0x1b, 0xc0, 0x87, 0xc8, 0x8e, 0xf7, 0xdf, 0x7f, 0x9f, 0xb6, 0xdb, 0x2d, 0x45, 0xe1, 0xd4, 0x6f, 0xb7, 0x31, 0xb1, 0xbd, 0xf7, 0x38, 0x1c, 0x0e, 0xa5, 0x9e, 0x36, 0x50, 0xe8, 0x1c, 0x16, 0x39, 0xd5, 0x44, 0x9d, 0x82, 0xdc, 0x87, 0x57, 0xaf, 0x5e, 0xbd, 0x02, 0xf0, 0x00, 0xf0, 0xdf, 0x02, 0xee, 0x1f, 0x80, 0xf6, 0xbf, 0x44, 0xe4, 0x0e, 0x06, 0xc3, 0xa5, 0x5a, 0xf1, 0xcd, 0x6f, 0x3e, 0xf3, 0xbf, 0xf8, 0xc5, 0x1f, 0x39, 0xe0, 0x2f, 0x85, 0xf1, 0x9d, 0xcf, 0x3f, 0x7f, 0x89, 0xf7, 0xdf, 0x7f, 0xff, 0xc5, 0x7e, 0xbf, 0x7f, 0x1e, 0x45, 0x3e, 0x0b, 0xc2, 0x58, 0xe3, 0x9c, 0x73, 0xd8, 0x6c, 0x36, 0x85, 0xd0, 0x65, 0x8d, 0x73, 0xea, 0xac, 0x3c, 0x5d, 0xf8, 0xfc, 0xf3, 0xcf, 0x7f, 0x2d, 0x82, 0x1f, 0x03, 0xf2, 0x91, 0x88, 0xdc, 0xd8, 0x23, 0x31, 0xbc, 0x35, 0x72, 0xd3, 0x57, 0x7f, 0x07, 0xf4, 0xeb, 0xbf, 0x77, 0x4c, 0x7f, 0xf2, 0xe2, 0xc5, 0xd7, 0xbe, 0x16, 0x10, 0x5c, 0xe8, 0x82, 0xaa, 0x8b, 0x0d, 0x55, 0x3a, 0xdb, 0xdf, 0x9b, 0x9b, 0x9b, 0x58, 0x9f, 0xd1, 0xde, 0x79, 0x4e, 0x9d, 0x35, 0x0e, 0x87, 0xc3, 0x01, 0x90, 0x7f, 0x17, 0x09, 0xdf, 0x31, 0x32, 0x1b, 0xde, 0x36, 0x44, 0x3e, 0x7b, 0x2d, 0x41, 0xbe, 0x1d, 0x82, 0xfc, 0xe4, 0xf6, 0xf6, 0xf6, 0x8e, 0x53, 0x84, 0x23, 0x53, 0x33, 0xaa, 0xf4, 0x30, 0xfa, 0x91, 0x1b, 0xf6, 0x90, 0xbc, 0x6e, 0x89, 0x08, 0x2c, 0x69, 0xfe, 0xee, 0xba, 0xee, 0x46, 0x04, 0xdf, 0xb3, 0x5b, 0x6f, 0x78, 0xb7, 0xc4, 0xc6, 0xf7, 0xbb, 0xee, 0xe1, 0x26, 0x5a, 0x5d, 0x2e, 0xe4, 0xd5, 0x9f, 0x99, 0xe0, 0x3a, 0x3a, 0xc5, 0xd9, 0x87, 0x9c, 0x52, 0xe7, 0xca, 0x72, 0xfc, 0xb3, 0x88, 0xbc, 0xb6, 0x5b, 0x6e, 0x78, 0xb7, 0x84, 0x96, 0xd7, 0x41, 0xf0, 0x4f, 0x99, 0xc0, 0x91, 0x7b, 0x04, 0xe6, 0xb1, 0x4a, 0x67, 0x0e, 0x0f, 0x08, 0x7d, 0xae, 0xbb, 0x27, 0x33, 0xc3, 0x35, 0x8c, 0xb6, 0x6d, 0x3f, 0xb5, 0xdb, 0x6d, 0xb8, 0x06, 0x1e, 0x8e, 0x0f, 0x7f, 0x37, 0xec, 0x29, 0xa9, 0x6d, 0xc6, 0x74, 0xd0, 0x82, 0x35, 0xbb, 0xcf, 0xc1, 0x39, 0x87, 0x17, 0x2f, 0xf0, 0x63, 0xbb, 0xd5, 0x86, 0xeb, 0xe0, 0xab, 0x3f, 0xc1, 0x4c, 0xb7, 0x5f, 0xad, 0xd2, 0xba, 0xc1, 0x8d, 0xf3, 0xca, 0xa7, 0xac, 0x46, 0x26, 0x73, 0xe3, 0x1c, 0x3e, 0xfb, 0xcc, 0xec, 0x86, 0xe1, 0x5a, 0xb6, 0xe3, 0x57, 0x37, 0xa8, 0x5a, 0x07, 0xa7, 0x9c, 0xc4, 0xa0, 0xfb, 0xc5, 0x29, 0x42, 0xeb, 0x0d, 0x96, 0xd8, 0x12, 0x83, 0xe1, 0xad, 0x43, 0xab, 0xf2, 0x69, 0xcf, 0x3d, 0x8c, 0x72, 0x9c, 0x5d, 0x71, 0x41, 0x48, 0xcf, 0x60, 0x78, 0x57, 0xa4, 0x16, 0x45, 0xea, 0xa9, 0x4a, 0xe1, 0x40, 0xa1, 0xcf, 0xa9, 0xf3, 0x54, 0xf7, 0x3d, 0x83, 0xe1, 0x8a, 0xde, 0xa3, 0x34, 0xe7, 0x9f, 0xf3, 0x08, 0xcd, 0x12, 0x75, 0xae, 0xbf, 0x1b, 0x0c, 0x57, 0x13, 0xe7, 0x01, 0xff, 0x08, 0x32, 0xd1, 0x53, 0x8a, 0x48, 0x96, 0x59, 0x8e, 0xb9, 0xd0, 0x88, 0xc1, 0x70, 0x5d, 0xe4, 0x08, 0x47, 0x00, 0x4f, 0xf0, 0x72, 0xb8, 0xe6, 0x09, 0xe8, 0x36, 0x73, 0x22, 0x81, 0x69, 0xb4, 0xe1, 0xea, 0x6e, 0x23, 0x32, 0x71, 0xc0, 0xbd, 0xba, 0xc7, 0x5d, 0x6e, 0x2d, 0x5c, 0xe4, 0xa1, 0xf5, 0x46, 0x06, 0xc3, 0xda, 0xd6, 0xa3, 0x38, 0x07, 0x7e, 0x84, 0x42, 0x67, 0x69, 0x2f, 0x71, 0x3e, 0xf3, 0xd1, 0x86, 0x95, 0xad, 0x47, 0x2f, 0xd3, 0x6f, 0x68, 0x39, 0xac, 0x52, 0x68, 0x58, 0x85, 0xc2, 0x17, 0xe6, 0xe4, 0x5b, 0x64, 0x39, 0x72, 0x3f, 0x54, 0xa3, 0xb4, 0xe1, 0xea, 0x1e, 0x7a, 0x26, 0x15, 0x04, 0xf3, 0x1b, 0x10, 0xba, 0xaf, 0x18, 0x9a, 0x8f, 0x36, 0x5c, 0xd9, 0x3b, 0xab, 0x81, 0xba, 0x6f, 0x55, 0xa1, 0xe3, 0xa0, 0x66, 0xd3, 0x68, 0xc3, 0x1a, 0x2a, 0x4d, 0xa3, 0x06, 0x95, 0xf0, 0x26, 0x84, 0x8e, 0x1d, 0xa8, 0x4d, 0xa1, 0x0d, 0x2b, 0x28, 0x34, 0x0f, 0x1b, 0x4e, 0xce, 0x11, 0x77, 0xb1, 0xe5, 0x08, 0xc1, 0x2a, 0x86, 0x86, 0xeb, 0x23, 0xe6, 0xee, 0xa0, 0x33, 0xba, 0x7c, 0x41, 0xe7, 0xa4, 0x4a, 0xaa, 0xed, 0x0e, 0x1b, 0xae, 0xee, 0xa1, 0x89, 0x66, 0xf2, 0x88, 0xf3, 0xd8, 0x6b, 0xb3, 0x66, 0xf7, 0x02, 0x33, 0x63, 0x77, 0xd8, 0x70, 0x5d, 0xff, 0x5c, 0x2b, 0xb6, 0xe6, 0x60, 0xb8, 0xd0, 0x72, 0x4c, 0xe5, 0x6d, 0x33, 0x18, 0xae, 0xaa, 0xd0, 0x89, 0x7f, 0x39, 0x05, 0x17, 0x0f, 0x52, 0x30, 0x67, 0x9e, 0x2e, 0xec, 0x9c, 0x34, 0x97, 0x7f, 0xd8, 0x60, 0xb8, 0xaa, 0x4a, 0x97, 0xee, 0xa3, 0x73, 0xbf, 0xd3, 0x65, 0x95, 0xc2, 0x42, 0x64, 0x53, 0x6a, 0xc3, 0x8a, 0xd6, 0x43, 0x26, 0x02, 0x15, 0x93, 0x1e, 0x7a, 0x99, 0x31, 0x27, 0x18, 0x9d, 0x0d, 0x2b, 0xca, 0xf4, 0xc8, 0x53, 0x4f, 0xb5, 0x16, 0x2e, 0x22, 0x74, 0x9d, 0xa0, 0xda, 0x60, 0xb8, 0x76, 0xa5, 0xb0, 0xd4, 0xe7, 0xce, 0xb8, 0x88, 0xc5, 0x0a, 0x0d, 0x12, 0xb3, 0x1c, 0x86, 0xd5, 0x2a, 0x85, 0xa7, 0xc8, 0x3c, 0xb2, 0x1c, 0x4b, 0xd4, 0x97, 0xad, 0xfb, 0xa8, 0x61, 0x45, 0x85, 0xd6, 0xa4, 0x3d, 0xc9, 0xd3, 0xe5, 0x16, 0xc6, 0xd4, 0xd9, 0xb0, 0x8e, 0x42, 0x67, 0xee, 0x2d, 0x12, 0xde, 0xc5, 0x3b, 0x26, 0x53, 0x67, 0xc3, 0x1a, 0x8c, 0x8e, 0x39, 0xf2, 0xdf, 0x6a, 0x6f, 0xbb, 0x58, 0x31, 0xb4, 0x7b, 0x6b, 0x58, 0xc3, 0x73, 0x28, 0xff, 0xbc, 0xa0, 0x2b, 0xe9, 0xe2, 0x38, 0xb4, 0x88, 0x75, 0xf0, 0x37, 0xac, 0xc4, 0xe9, 0x33, 0x56, 0x63, 0x30, 0xd3, 0xd7, 0x32, 0xbb, 0xa1, 0x26, 0x09, 0x31, 0x18, 0xae, 0x8c, 0xc1, 0xbc, 0x97, 0xa7, 0xf8, 0x89, 0x4b, 0x1b, 0x56, 0x2c, 0x6c, 0x67, 0x58, 0xcb, 0x4a, 0xab, 0xd0, 0x1d, 0xd3, 0x1b, 0xa4, 0x02, 0x33, 0xcb, 0x61, 0x78, 0x2a, 0xb6, 0x63, 0x09, 0x65, 0x97, 0x47, 0x39, 0x18, 0xd6, 0xf4, 0x6d, 0x58, 0x47, 0x9d, 0x79, 0x8a, 0xe0, 0x34, 0xe9, 0xb3, 0x97, 0x8f, 0x29, 0xf4, 0xa6, 0xcf, 0x86, 0xb5, 0xe4, 0x99, 0x54, 0xbf, 0x8d, 0x3c, 0x3b, 0xae, 0xbc, 0x99, 0x42, 0x1b, 0x0c, 0xeb, 0x54, 0x08, 0xd5, 0x20, 0xed, 0x13, 0x0a, 0x7d, 0x51, 0xd3, 0x37, 0x11, 0x81, 0x9d, 0x19, 0x0e, 0xc3, 0x1a, 0xde, 0x99, 0x26, 0x35, 0xb8, 0x56, 0xe8, 0x8b, 0x2d, 0x87, 0xd8, 0x20, 0x59, 0xc3, 0x1a, 0xfe, 0x79, 0x26, 0xba, 0x26, 0x42, 0x03, 0xb2, 0x97, 0xe9, 0xbb, 0x2f, 0xa9, 0x65, 0x5a, 0x6f, 0x3b, 0xc3, 0xf5, 0x15, 0x5a, 0x30, 0x98, 0x11, 0x9d, 0xa4, 0x58, 0x91, 0x47, 0x7b, 0x68, 0x4b, 0xd6, 0x68, 0x58, 0x95, 0xd0, 0x32, 0xce, 0x0b, 0x13, 0x2a, 0xdb, 0x71, 0x71, 0x1a, 0x03, 0xb3, 0x1b, 0x86, 0xd5, 0x6c, 0x07, 0xab, 0x8e, 0xfe, 0x4a, 0x89, 0x6b, 0xcb, 0x71, 0x11, 0xa1, 0xad, 0x95, 0xd0, 0xb0, 0x96, 0x87, 0x2e, 0xa2, 0xaa, 0x96, 0xd7, 0x0a, 0xfd, 0xa8, 0x96, 0x42, 0xf3, 0xd0, 0x86, 0x6b, 0x83, 0x1d, 0x41, 0x02, 0x80, 0x3a, 0xbf, 0xdd, 0x63, 0xf2, 0x43, 0xd7, 0x1e, 0xda, 0xe8, 0x6c, 0xb8, 0x36, 0x7c, 0x17, 0x06, 0x0a, 0x9d, 0x6d, 0xc6, 0x1b, 0xa7, 0xd3, 0xb5, 0xbe, 0x1c, 0x86, 0x35, 0xb0, 0xd9, 0xb8, 0xd2, 0x06, 0x42, 0x23, 0x4e, 0xd2, 0x48, 0xb2, 0x2f, 0x6b, 0x29, 0xb4, 0x8a, 0xa1, 0xe1, 0xda, 0x0a, 0x1d, 0xc2, 0xa0, 0xdb, 0x05, 0x91, 0x94, 0x74, 0x60, 0xc3, 0x28, 0xc7, 0xc5, 0x93, 0x06, 0x19, 0x99, 0x0d, 0x2b, 0x60, 0x62, 0x2c, 0x6b, 0xee, 0x3e, 0x3a, 0x35, 0xce, 0x75, 0x31, 0xa1, 0x6d, 0x6a, 0x64, 0xc3, 0x1a, 0x20, 0x92, 0xd2, 0xdb, 0x6e, 0x09, 0x05, 0x97, 0x45, 0x39, 0xc8, 0xf2, 0xda, 0x19, 0xd6, 0x41, 0x08, 0x7d, 0x48, 0x6e, 0xc9, 0xb8, 0xd6, 0x65, 0x51, 0x0e, 0x21, 0x23, 0xb4, 0x61, 0x15, 0x38, 0x17, 0xa3, 0x6b, 0xc4, 0x49, 0xa1, 0x67, 0x42, 0xc7, 0x17, 0xc7, 0xa1, 0xad, 0x61, 0xc5, 0xb0, 0x96, 0x42, 0x0f, 0x94, 0xf9, 0x8c, 0xb0, 0xf2, 0x52, 0x32, 0x1b, 0xa1, 0x0d, 0xab, 0xd4, 0x09, 0x45, 0xd2, 0x3c, 0x2b, 0xa4, 0xa6, 0x40, 0xe6, 0xc9, 0xf5, 0x16, 0x11, 0x3a, 0x4f, 0x09, 0x60, 0x96, 0xc3, 0xb0, 0x06, 0xd8, 0xa5, 0x4e, 0x71, 0x83, 0xec, 0xa3, 0xe1, 0x4d, 0x2d, 0x87, 0xa9, 0xb3, 0x61, 0x1d, 0x4c, 0x3b, 0x03, 0x7e, 0xb3, 0x4a, 0xa1, 0x65, 0xef, 0x37, 0xac, 0x6a, 0x39, 0x88, 0x4a, 0x65, 0xf0, 0xad, 0xa4, 0xd3, 0x2d, 0x1b, 0xd9, 0xfd, 0x35, 0x5c, 0x9b, 0xd0, 0xc9, 0x5d, 0x0c, 0x73, 0x71, 0x84, 0x37, 0x53, 0xe8, 0x28, 0xfd, 0x46, 0x67, 0xc3, 0x7a, 0x96, 0xc3, 0x7b, 0x19, 0xf4, 0x8b, 0x7e, 0x23, 0x0f, 0x3d, 0x57, 0xb3, 0x34, 0x18, 0xae, 0x61, 0x39, 0xb4, 0xa0, 0x9e, 0xa2, 0xed, 0xe2, 0x31, 0x85, 0x71, 0xa7, 0x96, 0x7e, 0xd4, 0x70, 0x7d, 0x30, 0x2f, 0xcf, 0x7c, 0x7b, 0xd1, 0x20, 0xd9, 0x10, 0x2c, 0x73, 0x92, 0x61, 0x25, 0x52, 0xab, 0x14, 0x1a, 0xc4, 0x18, 0x0e, 0x9a, 0x7d, 0x8c, 0xe5, 0x30, 0x18, 0x56, 0xb3, 0x1c, 0xc5, 0x25, 0x28, 0x52, 0x67, 0x35, 0xe6, 0xa1, 0x8b, 0x10, 0x91, 0x0b, 0x47, 0x7d, 0x1b, 0x0c, 0xd7, 0x56, 0xe7, 0x94, 0x6d, 0x80, 0x53, 0x6e, 0x45, 0x09, 0x3d, 0xc9, 0xb5, 0x15, 0x79, 0x5c, 0xd8, 0xce, 0x62, 0xd1, 0x86, 0x35, 0xa0, 0xc5, 0x54, 0x7f, 0xe7, 0x37, 0xb0, 0x1c, 0xba, 0x5f, 0xaa, 0xc1, 0x70, 0x55, 0x3e, 0x2b, 0x32, 0xeb, 0x29, 0x92, 0xf9, 0xb1, 0x1e, 0x5a, 0x44, 0xe0, 0xbd, 0x94, 0x20, 0xb7, 0xc1, 0x70, 0x35, 0x0f, 0xad, 0xa6, 0xe5, 0xa6, 0x8a, 0xbc, 0x61, 0xc2, 0x1a, 0x5f, 0x94, 0x97, 0xc3, 0x7c, 0xb4, 0xe1, 0xfa, 0x6e, 0x83, 0xe2, 0x18, 0xc2, 0x34, 0x48, 0x5b, 0x34, 0xc9, 0x27, 0x04, 0xd6, 0x3c, 0xb4, 0xe1, 0x4b, 0x51, 0x31, 0x2c, 0xc9, 0x18, 0x79, 0x9a, 0xba, 0x17, 0x45, 0x39, 0x26, 0x0d, 0xb9, 0xc1, 0x70, 0x0d, 0xcb, 0xa1, 0x85, 0x54, 0xb4, 0xed, 0x0d, 0x93, 0x0e, 0xc2, 0xd2, 0x18, 0x18, 0x9e, 0xba, 0x89, 0xee, 0x27, 0x0c, 0x52, 0x4a, 0x2d, 0x18, 0x0f, 0x9a, 0xbd, 0x3c, 0x9d, 0xae, 0xc1, 0xb0, 0x92, 0x4a, 0xd7, 0x6a, 0x4d, 0xd3, 0x16, 0xda, 0x92, 0x35, 0x1a, 0x9e, 0x7e, 0xa5, 0x30, 0x2b, 0x72, 0x19, 0xb5, 0x72, 0xa2, 0x11, 0x65, 0xc1, 0x10, 0xac, 0xbe, 0xb7, 0x93, 0xc5, 0xa1, 0x0d, 0x6b, 0xa8, 0x73, 0x89, 0x3d, 0x13, 0x95, 0xf1, 0x85, 0xb3, 0x15, 0xc8, 0xf3, 0x56, 0x83, 0xca, 0x00, 0x45, 0x8b, 0x43, 0x1b, 0xae, 0xae, 0xd0, 0x95, 0x9f, 0xee, 0x39, 0xc8, 0x8f, 0x25, 0xb4, 0xa4, 0x61, 0x30, 0xe6, 0xa1, 0x0d, 0xeb, 0x7a, 0xe8, 0x61, 0x5b, 0x48, 0x78, 0x1c, 0xa1, 0x49, 0xe5, 0x11, 0x33, 0x1f, 0x6d, 0x58, 0xd1, 0x4c, 0x47, 0xfb, 0x41, 0x32, 0x20, 0xf9, 0x24, 0xa1, 0x97, 0x46, 0x30, 0x2c, 0xd2, 0x61, 0x58, 0xa3, 0x52, 0x98, 0xb9, 0x47, 0x49, 0x58, 0x05, 0xf3, 0x7d, 0xf3, 0x6d, 0x4c, 0xa1, 0xe1, 0xcb, 0xe5, 0xa3, 0x2b, 0x1b, 0x52, 0xfe, 0xa6, 0x85, 0x2d, 0x85, 0x59, 0x95, 0x83, 0x55, 0x08, 0x0d, 0x2b, 0xfa, 0xe7, 0x9a, 0xe0, 0x23, 0x92, 0x87, 0x8b, 0x15, 0xda, 0xfc, 0xb3, 0x61, 0x45, 0x62, 0x97, 0x5e, 0x77, 0xa7, 0x67, 0x92, 0xb0, 0x96, 0x42, 0xc3, 0x93, 0x27, 0xb2, 0x00, 0x70, 0xb9, 0x9d, 0x5b, 0xa6, 0xe7, 0xfa, 0x79, 0x5c, 0x5f, 0x0e, 0x83, 0xe1, 0xca, 0x60, 0x15, 0xaa, 0x93, 0x4c, 0x5c, 0x1e, 0x6b, 0xf1, 0xa0, 0xf5, 0xf0, 0x94, 0xfa, 0xf6, 0xdd, 0xf6, 0xd8, 0x32, 0x27, 0x19, 0xae, 0x5f, 0x21, 0xcc, 0x33, 0x18, 0xa7, 0x0e, 0xfe, 0xe7, 0xb2, 0xf8, 0x37, 0xcb, 0x2b, 0x85, 0xc1, 0x22, 0x1d, 0x86, 0xab, 0x23, 0xe4, 0xde, 0x76, 0xaa, 0x1f, 0x47, 0x6c, 0x2d, 0x0c, 0x93, 0x5c, 0x5d, 0xdc, 0xb0, 0x12, 0x77, 0x6a, 0x15, 0x43, 0xc3, 0x95, 0x15, 0x1a, 0x7d, 0x6b, 0xb5, 0x44, 0x22, 0x4e, 0x66, 0xf2, 0x5a, 0xec, 0xa1, 0x45, 0x97, 0x0c, 0xbb, 0xbf, 0x86, 0x95, 0x6c, 0x07, 0x11, 0x55, 0x09, 0x1b, 0x27, 0x2a, 0x8f, 0x97, 0x28, 0x74, 0xda, 0xca, 0xee, 0xae, 0xe1, 0xba, 0x51, 0x0e, 0xc5, 0x43, 0xa9, 0x96, 0x3d, 0x4a, 0xa1, 0x07, 0xbe, 0xd9, 0x62, 0xd1, 0x86, 0x95, 0x48, 0xad, 0x03, 0x17, 0x74, 0xc2, 0x49, 0x9c, 0x25, 0xf4, 0x25, 0x13, 0xb6, 0x18, 0x0c, 0x6f, 0x1b, 0xce, 0x11, 0x9a, 0x86, 0x47, 0x09, 0xcf, 0xeb, 0x00, 0xc5, 0xe3, 0x72, 0xdb, 0x99, 0x42, 0x1b, 0xae, 0x8c, 0x50, 0xe5, 0x83, 0x99, 0x1a, 0x4b, 0xa8, 0x71, 0x11, 0xa1, 0x8d, 0xce, 0x86, 0x35, 0x2a, 0x84, 0x21, 0x84, 0x18, 0x83, 0x4e, 0xe1, 0xbb, 0x53, 0xfd, 0x8a, 0x2e, 0x6a, 0xfa, 0xb6, 0xe6, 0x6f, 0xc3, 0x1a, 0x84, 0x46, 0xd5, 0x52, 0xc8, 0x3c, 0x3f, 0x91, 0xd5, 0x45, 0xfd, 0xa1, 0x0d, 0x86, 0xab, 0x5b, 0x8e, 0x39, 0x39, 0xa6, 0xe9, 0xc9, 0x60, 0xad, 0x2f, 0x87, 0xe1, 0xa9, 0x4b, 0x74, 0x6a, 0xf2, 0xe6, 0x62, 0x79, 0x25, 0x75, 0x50, 0x0a, 0x95, 0x83, 0x30, 0x42, 0x1b, 0x9e, 0x3c, 0x9a, 0x86, 0x87, 0x19, 0xfc, 0x4b, 0xe7, 0xa4, 0x31, 0x79, 0x45, 0xe4, 0x7c, 0x5f, 0x0e, 0x83, 0x61, 0x4d, 0xf8, 0x2e, 0xf4, 0xad, 0xd5, 0xf9, 0x5f, 0x98, 0xf7, 0xdb, 0xa6, 0xd0, 0x86, 0x27, 0x0f, 0xe7, 0x86, 0xe3, 0x08, 0x89, 0x64, 0x32, 0x84, 0x7c, 0x51, 0xb2, 0x46, 0x1b, 0xb1, 0x62, 0x58, 0xc5, 0x42, 0x73, 0xdf, 0xa8, 0x32, 0xf8, 0x9c, 0x09, 0xdf, 0x2d, 0x8e, 0x72, 0x58, 0x24, 0xc4, 0xb0, 0x0a, 0x52, 0x77, 0x51, 0xd6, 0x09, 0xcf, 0x31, 0x9e, 0x34, 0x68, 0x40, 0x68, 0x83, 0xe1, 0xc9, 0x2a, 0x34, 0x11, 0x04, 0x61, 0x90, 0xa4, 0xf1, 0xad, 0x8c, 0x29, 0x34, 0xcb, 0x61, 0x58, 0x8b, 0xd0, 0x04, 0x2e, 0x15, 0xc2, 0xa2, 0xd0, 0x3c, 0xcd, 0xcf, 0xc5, 0x51, 0x0e, 0xeb, 0x0f, 0x6d, 0x58, 0xc7, 0x43, 0x47, 0xd5, 0x15, 0xa4, 0xc9, 0x5f, 0x53, 0xcb, 0xe1, 0x54, 0xa4, 0x83, 0x88, 0x2e, 0x23, 0xb4, 0x69, 0xb4, 0xe1, 0xda, 0xe8, 0x5a, 0x3f, 0x70, 0x07, 0x41, 0x4e, 0x4f, 0x5e, 0x65, 0x1e, 0xda, 0xf0, 0xf4, 0x2d, 0x07, 0x63, 0x90, 0xbe, 0xe0, 0xd4, 0xd8, 0x56, 0xf3, 0xd0, 0x86, 0x27, 0x0d, 0x76, 0xc3, 0xd1, 0xde, 0x73, 0xc3, 0xb0, 0x98, 0x1f, 0x61, 0x39, 0xc4, 0x06, 0xc9, 0x1a, 0xae, 0x8c, 0xe0, 0x53, 0x2f, 0xcf, 0x99, 0xce, 0x48, 0x65, 0xbd, 0x64, 0x43, 0x2e, 0x6c, 0xfa, 0xb6, 0x04, 0x77, 0x86, 0xeb, 0x23, 0xb6, 0x14, 0x12, 0x24, 0x84, 0x92, 0xd6, 0x60, 0x8a, 0xdc, 0x44, 0x97, 0xa6, 0x31, 0x30, 0x18, 0xae, 0x4e, 0x66, 0x17, 0x23, 0x1c, 0x49, 0xa9, 0x4f, 0x8f, 0xfc, 0xa6, 0x0b, 0x15, 0xda, 0x48, 0x6d, 0xb8, 0xb6, 0xe5, 0x08, 0x21, 0x26, 0x4e, 0xca, 0x15, 0x43, 0xa2, 0x62, 0x41, 0x1e, 0x55, 0x29, 0xd4, 0x79, 0x39, 0x6c, 0x90, 0xac, 0x61, 0x8d, 0x4a, 0x21, 0x3b, 0x4a, 0x64, 0x96, 0x91, 0x5b, 0x28, 0x39, 0x1c, 0x2f, 0x9d, 0x49, 0x76, 0x2a, 0x5b, 0x8d, 0xc1, 0xf0, 0xae, 0xe1, 0xbb, 0x54, 0x6f, 0xa3, 0xe1, 0x94, 0x6e, 0x10, 0x1a, 0x34, 0xf4, 0x5d, 0x94, 0x7d, 0x54, 0xe7, 0xe6, 0x35, 0x18, 0xae, 0x89, 0x53, 0xa9, 0xe8, 0x08, 0xe3, 0x44, 0xfc, 0xbc, 0x74, 0xa7, 0xd6, 0xdb, 0xce, 0xb0, 0x0a, 0xa1, 0x39, 0xf5, 0x73, 0xe6, 0x38, 0x72, 0x45, 0x67, 0x50, 0x9a, 0x0a, 0x54, 0x5c, 0x56, 0x29, 0x34, 0x52, 0x1b, 0xae, 0x0c, 0xc7, 0x0c, 0x11, 0x41, 0x10, 0x41, 0xf0, 0x32, 0x16, 0x58, 0x46, 0x89, 0x26, 0x5f, 0x3c, 0x62, 0xc5, 0xe8, 0x6c, 0xb8, 0xba, 0x87, 0xf6, 0x52, 0xa6, 0x45, 0x2e, 0x3d, 0xec, 0xd4, 0x84, 0xf6, 0x5c, 0x55, 0x0e, 0xad, 0x96, 0x67, 0x78, 0xf2, 0x1e, 0x9a, 0x26, 0x2c, 0x46, 0xdd, 0x7d, 0x34, 0x84, 0x47, 0x0c, 0x92, 0xb5, 0x28, 0xb4, 0x61, 0x25, 0x56, 0x97, 0x74, 0x06, 0x75, 0x8e, 0xbb, 0x3a, 0x95, 0x81, 0x29, 0xb4, 0xe1, 0x49, 0xa3, 0xf3, 0x1e, 0x92, 0x42, 0x19, 0x94, 0xec, 0x46, 0xee, 0x1b, 0x5d, 0x5b, 0x0c, 0x1b, 0xf5, 0x6d, 0x78, 0xf2, 0xd8, 0x6c, 0xdc, 0xb0, 0xef, 0x46, 0xfa, 0x9e, 0x2d, 0x47, 0xad, 0xd0, 0x96, 0x97, 0xc3, 0xf0, 0xa4, 0x11, 0x3b, 0xf3, 0x2b, 0x55, 0xae, 0x5a, 0xac, 0x55, 0x90, 0xe3, 0x11, 0x51, 0x0e, 0x0b, 0xdb, 0x19, 0xae, 0x4d, 0x68, 0x1d, 0xd1, 0xe0, 0xbe, 0x45, 0xb0, 0x8e, 0x41, 0xe7, 0x99, 0xda, 0x2e, 0xab, 0x14, 0x5a, 0xe7, 0x24, 0xc3, 0x95, 0x91, 0xd3, 0x80, 0x91, 0x22, 0x77, 0xce, 0x9e, 0x34, 0x25, 0xaf, 0x16, 0x87, 0x36, 0x7c, 0x29, 0x14, 0x3a, 0xa7, 0x2f, 0xc8, 0x19, 0x94, 0xb2, 0x5a, 0xbf, 0x11, 0xa1, 0xad, 0xa5, 0xd0, 0x70, 0x6d, 0x64, 0x32, 0x87, 0x34, 0x48, 0x3b, 0x27, 0x99, 0x11, 0x19, 0xf6, 0xed, 0xb8, 0xa8, 0xb7, 0x9d, 0x25, 0x3b, 0x37, 0xac, 0xa9, 0xd0, 0xda, 0xee, 0x4a, 0x26, 0xf7, 0x63, 0xfb, 0x43, 0x57, 0xc5, 0xc5, 0xee, 0xb0, 0xe1, 0xaa, 0x70, 0xce, 0x15, 0x95, 0x8e, 0x95, 0x41, 0x3d, 0x6a, 0x25, 0x98, 0xe5, 0x30, 0x7c, 0xf9, 0x14, 0x3a, 0x84, 0xd0, 0x4f, 0x5c, 0x3f, 0x48, 0xdc, 0xc8, 0x43, 0x6b, 0xb2, 0x34, 0x6c, 0x37, 0x37, 0x28, 0xd1, 0x60, 0x78, 0xd7, 0x08, 0x21, 0xc4, 0xae, 0xa3, 0xaa, 0xdb, 0x68, 0x9f, 0x39, 0x29, 0x3c, 0xce, 0x43, 0x1b, 0x0c, 0x6b, 0x5b, 0x8e, 0xdc, 0xe3, 0x0e, 0x42, 0x29, 0xf2, 0x21, 0x93, 0xc2, 0x6b, 0xb9, 0xed, 0x0c, 0x4f, 0x1a, 0xde, 0x7b, 0x04, 0xd5, 0x31, 0xe9, 0x54, 0xc3, 0xca, 0xc5, 0x43, 0xb0, 0xcc, 0x74, 0x18, 0xae, 0x8d, 0x3c, 0x69, 0x7d, 0x8e, 0x6e, 0x80, 0x64, 0x52, 0x5c, 0x2f, 0x9e, 0x34, 0xc8, 0x3c, 0xb4, 0x61, 0xb5, 0x8a, 0x21, 0xd2, 0x2c, 0x58, 0x44, 0x08, 0xbe, 0x4f, 0x1a, 0x3a, 0xe5, 0x18, 0x1a, 0x23, 0xb3, 0xe1, 0x29, 0xa3, 0x49, 0x89, 0x66, 0x24, 0xcd, 0x26, 0x9b, 0x49, 0x2c, 0x61, 0xcc, 0xcb, 0x8b, 0x2a, 0x85, 0xd6, 0xb0, 0x62, 0x58, 0xc5, 0x43, 0x27, 0x22, 0x67, 0x45, 0x76, 0x4e, 0xf9, 0x67, 0xa1, 0x51, 0xbe, 0x45, 0xeb, 0xcb, 0x61, 0x78, 0xda, 0x76, 0x43, 0xa6, 0x3d, 0x73, 0xee, 0x0f, 0x5d, 0x47, 0x3b, 0x16, 0x4f, 0x1a, 0xa4, 0xc7, 0x76, 0x19, 0x0c, 0xd7, 0x82, 0x73, 0xae, 0xb4, 0x50, 0x73, 0xca, 0xcd, 0x91, 0x3b, 0x28, 0x11, 0xc9, 0xe3, 0x15, 0x5a, 0xe7, 0x43, 0x30, 0x18, 0xae, 0x28, 0xd1, 0x45, 0x70, 0x83, 0x8e, 0xb6, 0x25, 0x3e, 0x66, 0x85, 0xce, 0xbd, 0xef, 0x16, 0x87, 0xed, 0x42, 0x1c, 0x56, 0x6b, 0x37, 0xd8, 0x70, 0x55, 0x6c, 0xb6, 0x4d, 0x3f, 0x0c, 0x0b, 0x18, 0xe6, 0x89, 0x56, 0x1e, 0x3a, 0x7f, 0x2e, 0x6e, 0xfa, 0x36, 0x18, 0xd6, 0xc0, 0xe1, 0x70, 0x44, 0xd7, 0x85, 0xbe, 0x73, 0x92, 0xb6, 0xc0, 0x95, 0x7f, 0x5e, 0x1c, 0xe5, 0x20, 0xcb, 0x69, 0x67, 0x58, 0x09, 0xdb, 0xed, 0x36, 0x66, 0x4f, 0x4a, 0x41, 0x09, 0x9a, 0x48, 0x69, 0xa0, 0xeb, 0x81, 0x0b, 0x2d, 0x87, 0x29, 0xb4, 0x61, 0x1d, 0x84, 0x94, 0xb5, 0x5f, 0xcf, 0x1a, 0x4b, 0x14, 0x53, 0x83, 0x4d, 0x59, 0xe0, 0xcb, 0xb2, 0x8f, 0x1a, 0x0c, 0x2b, 0xa0, 0xef, 0x0b, 0x9d, 0x92, 0x35, 0x86, 0x3c, 0xc6, 0x90, 0x46, 0x4c, 0xb6, 0x38, 0xb4, 0xe1, 0xc9, 0x83, 0x1d, 0xc1, 0x71, 0x09, 0x3c, 0xab, 0x14, 0xbb, 0x8a, 0x91, 0xe1, 0x11, 0x84, 0x36, 0xe3, 0x61, 0xb8, 0x36, 0x24, 0x65, 0x1d, 0xed, 0xbc, 0xa0, 0x69, 0xb8, 0xef, 0x69, 0x97, 0xd2, 0x16, 0x80, 0x87, 0x81, 0x8b, 0x65, 0xdd, 0x47, 0xd9, 0x22, 0x1d, 0x86, 0x75, 0xd0, 0x38, 0x87, 0x66, 0xe3, 0x4a, 0xe8, 0x98, 0x88, 0xe0, 0x1c, 0xc1, 0x07, 0x8e, 0xbe, 0x3a, 0x28, 0xe2, 0x87, 0x30, 0x6c, 0x29, 0x9c, 0xf3, 0xca, 0x24, 0x96, 0xf0, 0xdc, 0xb0, 0x9e, 0x42, 0xf7, 0x7f, 0x44, 0xeb, 0xe1, 0x9c, 0x03, 0xf3, 0xd0, 0x02, 0x8f, 0x08, 0xad, 0x33, 0xd4, 0x4c, 0xed, 0x34, 0xef, 0xf8, 0xfb, 0xdf, 0xff, 0xab, 0xaf, 0xdb, 0x6d, 0x36, 0x5c, 0x03, 0x1f, 0x7f, 0xfc, 0xf1, 0xd7, 0x36, 0xdb, 0x06, 0x4c, 0x71, 0xe2, 0x20, 0xe7, 0x92, 0xcd, 0xd0, 0x95, 0x43, 0x35, 0xf7, 0x4a, 0x21, 0xf4, 0x52, 0x78, 0x2f, 0xb8, 0xbb, 0xfb, 0xcd, 0xf7, 0xec, 0x56, 0x1b, 0xae, 0x81, 0xdb, 0xdb, 0xfb, 0xef, 0x12, 0x47, 0xcb, 0xcb, 0xe4, 0xfa, 0x48, 0x46, 0x12, 0xde, 0x10, 0x42, 0xc9, 0x42, 0xea, 0xbd, 0xef, 0x1b, 0x56, 0xe2, 0x5c, 0x70, 0xa7, 0x6d, 0x87, 0x88, 0xa0, 0xeb, 0x3a, 0x7c, 0xf6, 0xd9, 0xff, 0xfc, 0xc0, 0x6e, 0xb5, 0xe1, 0x1a, 0xf8, 0xcd, 0xcb, 0x5f, 0xfd, 0xa0, 0xe1, 0x06, 0x8e, 0x1c, 0x38, 0xa9, 0xb2, 0x6b, 0x22, 0xab, 0xcb, 0x94, 0xc9, 0x09, 0x5d, 0xd7, 0xf5, 0x51, 0x0e, 0x11, 0x81, 0xf7, 0xfe, 0xec, 0x01, 0xba, 0xae, 0xc3, 0xcf, 0x7f, 0xfe, 0xf3, 0x0f, 0x3f, 0xfa, 0xe8, 0xa3, 0x6f, 0xd8, 0xed, 0x36, 0xbc, 0x4b, 0x7c, 0xf4, 0xd1, 0x5f, 0x7c, 0xe3, 0xf6, 0xf6, 0xf3, 0x3f, 0x75, 0x0d, 0xc3, 0x35, 0xac, 0xba, 0x8b, 0x12, 0x42, 0xe2, 0x6b, 0x48, 0xf2, 0x1c, 0x42, 0x18, 0x12, 0x5a, 0x33, 0xfc, 0x9c, 0x41, 0x3f, 0x1e, 0x8f, 0xee, 0xa7, 0x3f, 0xfd, 0xe9, 0xbf, 0xd9, 0x2d, 0x37, 0xbc, 0x4b, 0x7c, 0xf6, 0xeb, 0xff, 0xfc, 0xd7, 0xcd, 0x66, 0xb3, 0xa1, 0x6a, 0x60, 0xac, 0x84, 0x00, 0xef, 0x3d, 0x1e, 0x1e, 0x3a, 0xf8, 0x34, 0x89, 0x50, 0xdb, 0xb6, 0x85, 0xdc, 0x85, 0xd0, 0x79, 0xe1, 0xb9, 0x29, 0xdc, 0xba, 0xae, 0xc3, 0x2f, 0x7f, 0xf9, 0xcb, 0x0f, 0x3e, 0xfc, 0xf0, 0xc3, 0x5f, 0x98, 0x52, 0x1b, 0xde, 0x85, 0x32, 0x7f, 0xeb, 0x5b, 0x7f, 0xfe, 0xdf, 0x5d, 0xd7, 0xfd, 0x81, 0x73, 0xae, 0x9f, 0xca, 0x2d, 0x64, 0xdb, 0x1b, 0xf0, 0x70, 0x6c, 0xd1, 0x16, 0x47, 0x11, 0x70, 0x3c, 0x1e, 0xcb, 0xf6, 0x7a, 0x98, 0x16, 0x9e, 0x3f, 0x7f, 0x8e, 0xed, 0x76, 0x7b, 0x32, 0xe2, 0x91, 0xb1, 0xd9, 0x6c, 0xf0, 0xfc, 0xbd, 0x67, 0xfe, 0x9b, 0xbf, 0xf7, 0xfb, 0x3f, 0x7e, 0xf1, 0xe2, 0xeb, 0x7f, 0xb3, 0xdf, 0x6f, 0xfe, 0xf1, 0xd3, 0x4f, 0x3f, 0xfd, 0x3f, 0x7b, 0x24, 0x86, 0xc7, 0x44, 0x33, 0x0e, 0x87, 0xee, 0xbb, 0x5f, 0x7c, 0xf1, 0xbf, 0x1f, 0xdf, 0x1d, 0x5e, 0xfe, 0x19, 0x3b, 0xde, 0xe6, 0x4a, 0xa0, 0x84, 0x80, 0xe0, 0x05, 0x6d, 0xeb, 0xd1, 0xb5, 0x2d, 0x6e, 0x6e, 0xee, 0xf0, 0xf2, 0xe5, 0x0d, 0x8e, 0xc7, 0x16, 0x00, 0x70, 0x7f, 0x7f, 0x8f, 0xfb, 0xfb, 0xfb, 0x69, 0x42, 0x37, 0x4d, 0x83, 0xf7, 0xde, 0x7b, 0xaf, 0xff, 0xf1, 0x0c, 0xa9, 0x89, 0x08, 0xdb, 0xed, 0x16, 0xfb, 0xfd, 0x1e, 0xce, 0xb9, 0x81, 0xb2, 0xc7, 0x1a, 0x68, 0x28, 0x93, 0x26, 0xe6, 0x65, 0x24, 0x54, 0x1a, 0x6a, 0x44, 0x04, 0x08, 0x00, 0x37, 0x3c, 0x58, 0x27, 0x8f, 0xf0, 0xcd, 0xeb, 0xcc, 0xe5, 0x61, 0x28, 0xf9, 0x82, 0xd5, 0x3a, 0xba, 0x30, 0xea, 0xcf, 0xfc, 0x4a, 0xd2, 0x6f, 0xa0, 0x92, 0x00, 0x50, 0x6d, 0x53, 0x7a, 0x6d, 0x31, 0x97, 0x6d, 0xea, 0xeb, 0x9a, 0x1a, 0x9c, 0xd9, 0x7f, 0xe6, 0xf1, 0x14, 0x18, 0x34, 0x06, 0xe8, 0x7d, 0xe4, 0x7b, 0x92, 0x07, 0x16, 0x49, 0x90, 0xb2, 0x6d, 0x3c, 0x97, 0x74, 0x2c, 0x21, 0x40, 0x42, 0xba, 0x36, 0x20, 0x84, 0xf8, 0x5b, 0xee, 0xe6, 0x2e, 0xc1, 0x0f, 0x46, 0x73, 0x88, 0xa0, 0x74, 0x7a, 0x27, 0x50, 0xd9, 0x2e, 0x1f, 0x27, 0xaf, 0x43, 0x04, 0x10, 0x33, 0x20, 0x02, 0x66, 0x82, 0x4e, 0x52, 0xe1, 0x98, 0x40, 0x4c, 0xe5, 0x1e, 0x94, 0x73, 0x17, 0x01, 0x3b, 0x07, 0x26, 0x86, 0x84, 0x00, 0x76, 0x5c, 0xd6, 0xcb, 0xa9, 0x06, 0x88, 0xe3, 0x31, 0xbb, 0xce, 0x63, 0xb3, 0x71, 0xa5, 0x97, 0x1c, 0xb3, 0x2b, 0xa1, 0x5f, 0x3d, 0xc5, 0x04, 0x91, 0x94, 0xd9, 0xab, 0x88, 0x08, 0x9b, 0x4d, 0x1c, 0x9d, 0x52, 0xa2, 0x18, 0xe9, 0xfe, 0x05, 0x2f, 0x38, 0x1e, 0x5b, 0xdc, 0xdf, 0xdf, 0xe3, 0x8b, 0x97, 0x37, 0x78, 0xfd, 0xfa, 0x50, 0x82, 0x14, 0xb7, 0xb7, 0xb7, 0x83, 0x7b, 0xdb, 0xd4, 0x76, 0xa2, 0x6d, 0xdb, 0xa2, 0xd2, 0xe7, 0x94, 0x3a, 0x79, 0x6a, 0x3c, 0x3c, 0x3c, 0x0c, 0x48, 0x98, 0xc9, 0xa9, 0x09, 0x45, 0xaa, 0xa9, 0xd2, 0x7b, 0x5f, 0x4c, 0x3d, 0x11, 0x81, 0xba, 0xfe, 0x06, 0xea, 0x70, 0x79, 0x99, 0x91, 0x99, 0xe3, 0x53, 0x0c, 0xd5, 0x3c, 0xb8, 0x99, 0x18, 0xde, 0xfb, 0x74, 0x2c, 0x29, 0xdb, 0xe5, 0xbf, 0x29, 0x3d, 0xc4, 0x78, 0xac, 0xfe, 0xc1, 0x65, 0xf2, 0xe4, 0x75, 0xf3, 0xfa, 0xfd, 0xcd, 0x21, 0x88, 0x04, 0x10, 0xf1, 0xf0, 0x5e, 0x50, 0x7a, 0x00, 0xaa, 0x23, 0x40, 0xdc, 0xaf, 0x2e, 0x14, 0x71, 0x7b, 0x42, 0x62, 0x0f, 0x0a, 0xd3, 0xd2, 0x31, 0x28, 0x4d, 0xec, 0x94, 0x92, 0x77, 0x4b, 0x29, 0x02, 0x10, 0x11, 0x38, 0xc7, 0xaa, 0xa0, 0x95, 0xc9, 0xf9, 0xa2, 0xfa, 0x10, 0x81, 0x09, 0x85, 0xac, 0x71, 0x9b, 0xf8, 0xab, 0x73, 0x8c, 0xae, 0xf3, 0xf1, 0x9c, 0x11, 0xcf, 0x3d, 0xde, 0x9f, 0x48, 0xdc, 0x48, 0x1a, 0x86, 0xf7, 0xf1, 0x3e, 0xba, 0x8d, 0x83, 0xf7, 0x91, 0x64, 0xc1, 0xa7, 0xfb, 0x43, 0x0c, 0xe6, 0xb8, 0x2f, 0x22, 0x82, 0xef, 0x02, 0xb6, 0x9b, 0x06, 0xde, 0x07, 0x10, 0x13, 0x9a, 0x86, 0x11, 0x02, 0x21, 0x04, 0x81, 0x63, 0x2a, 0xcf, 0x3d, 0x1f, 0x9b, 0x99, 0xb1, 0xd9, 0x00, 0x1c, 0x4f, 0x12, 0x8e, 0x19, 0x4d, 0xe3, 0xd0, 0x75, 0x01, 0x4d, 0xc3, 0x68, 0x9a, 0x06, 0xcc, 0x3d, 0x59, 0x9d, 0x9a, 0x33, 0xc5, 0x71, 0xfa, 0x2d, 0x00, 0x82, 0x50, 0x46, 0xab, 0x84, 0x10, 0xd0, 0xb6, 0x2d, 0x5e, 0xbf, 0xba, 0xc3, 0xdd, 0xdd, 0x7d, 0x59, 0x76, 0x7f, 0x7f, 0x3f, 0xb2, 0xc7, 0x03, 0x85, 0xce, 0xa4, 0x7a, 0xef, 0xbd, 0xf7, 0x06, 0x8a, 0x7b, 0x69, 0xb3, 0xf7, 0x63, 0x9a, 0xc9, 0x6b, 0x95, 0xd4, 0xe4, 0x98, 0xda, 0x5d, 0xbd, 0x5c, 0xb2, 0xda, 0xc8, 0x90, 0x64, 0x91, 0x98, 0x98, 0x50, 0xf3, 0x13, 0xe7, 0x90, 0xf3, 0x01, 0x42, 0x9f, 0x0f, 0x06, 0xca, 0x0b, 0xad, 0x80, 0xe5, 0x3e, 0x65, 0x15, 0xa5, 0xd4, 0x92, 0xa5, 0x0b, 0x0f, 0x40, 0x69, 0x46, 0x90, 0x48, 0xd2, 0x58, 0x18, 0x83, 0x08, 0x28, 0x0d, 0x02, 0xcd, 0x05, 0xab, 0xdf, 0x07, 0xf5, 0x39, 0xdb, 0xb8, 0x7a, 0xeb, 0x70, 0x1e, 0xb5, 0xd1, 0x2b, 0x6e, 0x2e, 0x9c, 0x4c, 0xe9, 0x4d, 0xe7, 0x5c, 0xe9, 0xa9, 0x16, 0xd2, 0x35, 0xec, 0xb6, 0x5b, 0x74, 0xc9, 0x7f, 0x36, 0xce, 0x45, 0x52, 0x39, 0x2e, 0x03, 0x51, 0x63, 0x61, 0x22, 0x34, 0xce, 0x81, 0x38, 0xa6, 0xde, 0x42, 0xba, 0x6f, 0xce, 0x31, 0x1a, 0xc7, 0xf0, 0x41, 0x8a, 0xf8, 0x10, 0x11, 0x9a, 0xc6, 0x95, 0x37, 0x6b, 0xac, 0x96, 0xc5, 0xe5, 0xdb, 0x5d, 0x83, 0xf6, 0xa1, 0xc3, 0x6e, 0xbf, 0x1d, 0xa8, 0x2e, 0xd2, 0x5b, 0x9a, 0x2b, 0xd1, 0x8b, 0xf7, 0x96, 0x00, 0x04, 0xf8, 0xf4, 0x86, 0xef, 0x5a, 0x8f, 0xbb, 0xc3, 0x01, 0xaf, 0xbe, 0xb8, 0xc5, 0xeb, 0x57, 0x77, 0x68, 0xdb, 0x28, 0x84, 0x87, 0xc3, 0x01, 0x6d, 0xdb, 0x8e, 0xb9, 0x87, 0x89, 0x4e, 0x74, 0x9b, 0xcd, 0x06, 0xcf, 0x9f, 0x3f, 0x9f, 0x7c, 0x3d, 0x5f, 0x8c, 0x74, 0xe2, 0x21, 0x4c, 0xff, 0x46, 0x42, 0xbd, 0x52, 0xa7, 0x1c, 0xd6, 0x14, 0x65, 0x70, 0x40, 0xda, 0xac, 0x6a, 0xf9, 0x8d, 0xde, 0x0f, 0x94, 0x44, 0x79, 0xd5, 0x42, 0x2d, 0xcb, 0xa4, 0x97, 0xcc, 0x4f, 0x19, 0x13, 0xb7, 0xbf, 0xbe, 0x44, 0xfc, 0x5e, 0x9b, 0xd3, 0xf5, 0xe6, 0x9b, 0x1c, 0xd4, 0xab, 0x30, 0x93, 0x19, 0x45, 0x6d, 0xeb, 0xc2, 0x98, 0x0b, 0x96, 0xbe, 0x65, 0x83, 0x02, 0xa1, 0x1a, 0x07, 0x74, 0x01, 0x89, 0xaa, 0x16, 0x2d, 0x48, 0x7f, 0x0c, 0x14, 0x92, 0x83, 0x10, 0xd5, 0x39, 0x25, 0x2f, 0x0c, 0x21, 0x80, 0x98, 0x07, 0xd7, 0x1c, 0xad, 0x92, 0x94, 0xc2, 0x10, 0x73, 0xc3, 0x01, 0x3e, 0x48, 0xec, 0xb1, 0x46, 0xf1, 0xd8, 0xfd, 0x5b, 0x34, 0xfe, 0x6f, 0xbb, 0x8d, 0xe4, 0xdb, 0x6c, 0x37, 0x68, 0x1f, 0x5a, 0x6c, 0xb6, 0x9b, 0xb4, 0x3f, 0x1a, 0x08, 0x15, 0x21, 0xb6, 0xda, 0xc5, 0xfd, 0xc4, 0xfd, 0x45, 0x7b, 0xc3, 0x51, 0xe9, 0x93, 0xcd, 0xcc, 0x05, 0x83, 0x99, 0x8a, 0xe5, 0x88, 0xbd, 0xe6, 0x9a, 0x74, 0xcd, 0x3e, 0xf6, 0x73, 0x2e, 0x6f, 0x47, 0x4e, 0x16, 0x24, 0x14, 0xf5, 0x6e, 0x1f, 0x3a, 0xdc, 0xde, 0x1e, 0xf0, 0xc5, 0xcb, 0x1b, 0xdc, 0xde, 0x1e, 0xd0, 0x75, 0xe1, 0x24, 0x99, 0x67, 0x09, 0x0d, 0x00, 0xbb, 0xdd, 0x0e, 0xfb, 0xfd, 0x7e, 0xe4, 0x4b, 0x1f, 0xc5, 0x69, 0x9e, 0x21, 0x34, 0x4e, 0xab, 0xa4, 0x84, 0xde, 0x32, 0x68, 0x92, 0xea, 0xef, 0x9c, 0x26, 0x37, 0x57, 0xe6, 0x32, 0x35, 0x87, 0x52, 0x7f, 0x79, 0xf9, 0x75, 0x4f, 0xf9, 0xf5, 0xde, 0x2b, 0x6e, 0xee, 0x27, 0x9e, 0x3a, 0x70, 0x8d, 0x3c, 0x70, 0x5c, 0x27, 0x92, 0xa9, 0x1f, 0x02, 0xd4, 0x2f, 0xef, 0xfd, 0x60, 0x9f, 0xff, 0x6f, 0x3c, 0x42, 0xbe, 0x7f, 0x53, 0xf4, 0x43, 0x87, 0x48, 0x59, 0x0f, 0xad, 0xfa, 0xda, 0xbe, 0x50, 0x21, 0x9d, 0xbe, 0xee, 0x62, 0xa7, 0x98, 0x7b, 0x6b, 0x53, 0xea, 0x07, 0x88, 0xfe, 0x96, 0xa2, 0xda, 0x7a, 0x1f, 0x06, 0x16, 0x90, 0xd4, 0x3e, 0x29, 0xd9, 0x85, 0xfc, 0xb6, 0xc8, 0x44, 0xef, 0x42, 0x88, 0x56, 0xc1, 0x31, 0xda, 0x2e, 0x2a, 0x78, 0xcc, 0x87, 0x01, 0x65, 0x0d, 0x93, 0xe7, 0x76, 0x9c, 0xb2, 0x81, 0x4a, 0x6a, 0xa2, 0xce, 0xbe, 0x3b, 0x80, 0xd9, 0x45, 0x42, 0xbb, 0xde, 0xe7, 0x07, 0xe9, 0x8f, 0x15, 0xf4, 0xeb, 0x34, 0x3d, 0x88, 0x10, 0xa2, 0x25, 0x3d, 0xde, 0x3f, 0xe0, 0xf5, 0xcd, 0x1d, 0x5e, 0xbf, 0xba, 0xc3, 0xf1, 0x78, 0x84, 0xf7, 0x91, 0xe4, 0x77, 0x77, 0x77, 0x27, 0x43, 0xcc, 0x04, 0xe0, 0x00, 0x60, 0x3f, 0xf5, 0xe3, 0x7e, 0xbf, 0xc7, 0x6e, 0xb7, 0x7b, 0x2b, 0xa4, 0x7e, 0xdb, 0x18, 0x91, 0x1c, 0x43, 0xe5, 0x1e, 0x92, 0x14, 0x95, 0x77, 0xed, 0x27, 0x9d, 0x21, 0xa6, 0xb2, 0xbe, 0xb6, 0x2a, 0xc5, 0x07, 0x53, 0x2c, 0x8c, 0x7a, 0x5f, 0xa5, 0xfc, 0x0c, 0x9e, 0x47, 0x6f, 0x0b, 0xc6, 0x6f, 0x00, 0x4c, 0xdc, 0xc3, 0xcc, 0x4e, 0x51, 0xe6, 0x66, 0xca, 0xba, 0x51, 0x75, 0x0c, 0x1e, 0x28, 0x7e, 0x54, 0x7b, 0x81, 0x24, 0x35, 0x24, 0x89, 0x3e, 0x9b, 0x28, 0x57, 0x02, 0xa5, 0xf4, 0x7d, 0x60, 0x1a, 0xbe, 0x21, 0xb4, 0x57, 0x67, 0xc7, 0xa9, 0x00, 0x44, 0x75, 0xcd, 0xfe, 0x9f, 0x88, 0x8b, 0xdf, 0x77, 0x3c, 0xb8, 0xa1, 0xe0, 0x44, 0xe6, 0xf2, 0x46, 0xa3, 0xf8, 0xc6, 0xe5, 0xd4, 0x81, 0xc8, 0x7b, 0x0f, 0xe7, 0x78, 0x50, 0xbf, 0x82, 0x2a, 0xf0, 0xa2, 0x2a, 0xce, 0xb1, 0x71, 0x24, 0x36, 0x90, 0xdc, 0x1f, 0x8e, 0xb8, 0xb9, 0x3d, 0xe0, 0xfe, 0x70, 0x4c, 0xf5, 0x2d, 0x41, 0xdb, 0xc6, 0x4a, 0x61, 0x38, 0xa3, 0x8c, 0x04, 0xe0, 0x3f, 0x00, 0xfc, 0xf1, 0xdc, 0x0a, 0xbb, 0xdd, 0x0e, 0xbb, 0xdd, 0x2e, 0xd6, 0xca, 0x9f, 0x18, 0xa9, 0x97, 0x92, 0xbd, 0x28, 0x52, 0x22, 0xbc, 0x28, 0x82, 0x66, 0x65, 0xec, 0xd7, 0x21, 0x55, 0x59, 0xac, 0xac, 0x42, 0xa5, 0xe6, 0x7a, 0x14, 0x50, 0x59, 0x37, 0x2b, 0x2c, 0xaa, 0x0a, 0x22, 0xe9, 0x08, 0xca, 0x98, 0xf8, 0xa3, 0x8a, 0x30, 0x61, 0x50, 0x31, 0x8c, 0x15, 0xc2, 0xe1, 0x9c, 0x23, 0x5c, 0x45, 0x76, 0x98, 0xd3, 0xb5, 0x31, 0x23, 0x31, 0x3b, 0xaa, 0x63, 0x79, 0xeb, 0xa9, 0x82, 0x53, 0xb6, 0x0d, 0x31, 0xf7, 0x85, 0x7a, 0xc9, 0x35, 0xc9, 0xa6, 0xe4, 0xab, 0xc8, 0xcb, 0x73, 0xc5, 0x92, 0x88, 0xfb, 0xbc, 0xcd, 0x4c, 0xfd, 0x3d, 0x12, 0x29, 0x91, 0x0e, 0x76, 0x5c, 0xde, 0xb0, 0x34, 0xd5, 0x63, 0x28, 0x59, 0xb5, 0xe0, 0x3d, 0xda, 0x44, 0xe4, 0x87, 0x63, 0x8b, 0xe3, 0xb1, 0x45, 0xdb, 0xb6, 0x45, 0x91, 0xbb, 0xae, 0xc3, 0xf1, 0x78, 0x5c, 0xd4, 0xf0, 0x97, 0xa3, 0x1c, 0xff, 0x72, 0x8a, 0xd0, 0x51, 0xee, 0x3d, 0x9e, 0x3d, 0x7b, 0x16, 0x2f, 0x1c, 0xd3, 0x09, 0x3e, 0x9e, 0x12, 0x48, 0xe5, 0x8e, 0xaa, 0x89, 0x5d, 0x13, 0x27, 0x5b, 0x81, 0xa1, 0x3d, 0xe8, 0xd7, 0x09, 0x41, 0xe0, 0x1c, 0x06, 0xd1, 0x0f, 0x20, 0xab, 0x36, 0x0d, 0xc6, 0xba, 0x15, 0x7b, 0x93, 0x94, 0x53, 0x7b, 0xf2, 0x4c, 0x7e, 0x01, 0x20, 0x5e, 0x8a, 0x1b, 0x62, 0x96, 0x38, 0xf5, 0xef, 0xa0, 0xc4, 0x45, 0xf2, 0xc6, 0xc2, 0x23, 0x00, 0x02, 0x42, 0x12, 0xf3, 0xb2, 0xdf, 0x44, 0xc6, 0x6c, 0x38, 0x18, 0x40, 0xd7, 0x25, 0xc2, 0x97, 0x70, 0x23, 0x62, 0x04, 0x89, 0xc6, 0x25, 0x9d, 0xb2, 0x59, 0x21, 0x01, 0x53, 0xa7, 0xa2, 0x44, 0x84, 0x23, 0x7a, 0x16, 0x53, 0x2a, 0x24, 0xb9, 0x60, 0x0c, 0x42, 0x9f, 0xaa, 0x30, 0x4a, 0x9e, 0xd4, 0x67, 0x58, 0x53, 0x2f, 0xf9, 0x33, 0xf4, 0x4d, 0x0e, 0xb9, 0xf7, 0xa6, 0x08, 0xbc, 0x97, 0x58, 0x01, 0xf4, 0x7d, 0x44, 0x23, 0x86, 0xe4, 0x1e, 0x70, 0x3c, 0xb6, 0x8b, 0xba, 0x64, 0xd4, 0x0a, 0xfd, 0x01, 0x80, 0x9f, 0x01, 0x78, 0x76, 0x2e, 0x72, 0xb1, 0xdb, 0xed, 0xb0, 0xd9, 0x6c, 0x0a, 0xb1, 0xbf, 0x2c, 0x8a, 0xfd, 0x34, 0x5e, 0x1b, 0x38, 0x3d, 0xe4, 0xa7, 0xaa, 0xec, 0x4e, 0xbd, 0x5d, 0xca, 0x6a, 0xca, 0xeb, 0xa7, 0x40, 0x60, 0xfa, 0x4e, 0x83, 0x22, 0x49, 0x13, 0x05, 0x58, 0xbf, 0x59, 0x16, 0x3f, 0xba, 0x73, 0xe7, 0x3e, 0x7a, 0x3b, 0x8a, 0xaa, 0xc7, 0x8c, 0xeb, 0x4f, 0x39, 0xfe, 0x9c, 0x39, 0x14, 0x89, 0xdc, 0x15, 0xcb, 0xa1, 0x3b, 0xcb, 0x5d, 0x2c, 0x66, 0xe9, 0xf3, 0x13, 0x00, 0x3f, 0x5a, 0x1a, 0x92, 0xcb, 0xc4, 0xe6, 0x52, 0xa9, 0x18, 0x9f, 0xb0, 0x8d, 0x14, 0x5f, 0x66, 0x8b, 0x6a, 0x41, 0x8b, 0xcf, 0x71, 0x41, 0x1b, 0x40, 0x5e, 0x47, 0x7a, 0x05, 0xd6, 0xf1, 0xf2, 0xa9, 0x8a, 0x74, 0xff, 0x29, 0xd5, 0xba, 0xe3, 0xe3, 0xd5, 0xcb, 0xfa, 0x3e, 0xf1, 0x7d, 0x5d, 0xe4, 0xdc, 0xba, 0xa4, 0xba, 0x79, 0xd6, 0x8d, 0x50, 0xe3, 0x06, 0xa9, 0xb7, 0xf4, 0x76, 0x56, 0xdf, 0x3f, 0x01, 0xf0, 0xc3, 0x73, 0x4a, 0xad, 0x89, 0xdd, 0x34, 0x4d, 0x51, 0xec, 0xba, 0x31, 0x65, 0xd9, 0x3e, 0x72, 0xd8, 0x6b, 0x3a, 0x8a, 0xf1, 0x38, 0xa2, 0xcc, 0x77, 0x7f, 0x5d, 0xf2, 0x46, 0x99, 0x7a, 0xd8, 0xe7, 0xf6, 0x55, 0x6f, 0x73, 0x6e, 0xdd, 0xfa, 0xb7, 0xa9, 0x38, 0xfc, 0x52, 0x82, 0xd1, 0x44, 0x6e, 0x8a, 0xdf, 0x66, 0xfc, 0x3f, 0xe0, 0xe0, 0x49, 0x8e, 0xd2, 0x68, 0x96, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, 0x00, 0x00, 0x28, 0x75, 0x75, 0x61, 0x79, 0x29 } }; static GStaticResource static_resource = { resource_resource_data.data, sizeof (resource_resource_data.data), NULL, NULL, NULL }; extern GResource *resource_get_resource (void); GResource *resource_get_resource (void) { return g_static_resource_get_resource (&static_resource); } /* If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and destructors, in a sane way, including e.g. on library unload. If not you're on your own. Some compilers need #pragma to handle this, which does not work with macros, so the way you need to use this is (for constructors): #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor) #endif G_DEFINE_CONSTRUCTOR(my_constructor) static void my_constructor(void) { ... } */ #ifndef __GTK_DOC_IGNORE__ #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) #define G_HAS_CONSTRUCTORS 1 #define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void); #define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void); #elif defined (_MSC_VER) && (_MSC_VER >= 1500) /* Visual studio 2008 and later has _Pragma */ #define G_HAS_CONSTRUCTORS 1 /* We do some weird things to avoid the constructors being optimized * away on VS2015 if WholeProgramOptimization is enabled. First we * make a reference to the array from the wrapper to make sure its * references. Then we use a pragma to make sure the wrapper function * symbol is always included at the link stage. Also, the symbols * need to be extern (but not dllexport), even though they are not * really used from another object file. */ /* We need to account for differences between the mangling of symbols * for Win32 (x86) and x64 programs, as symbols on Win32 are prefixed * with an underscore but symbols on x64 are not. */ #ifdef _WIN64 #define G_MSVC_SYMBOL_PREFIX "" #else #define G_MSVC_SYMBOL_PREFIX "_" #endif #define G_DEFINE_CONSTRUCTOR(_func) G_MSVC_CTOR (_func, G_MSVC_SYMBOL_PREFIX) #define G_DEFINE_DESTRUCTOR(_func) G_MSVC_DTOR (_func, G_MSVC_SYMBOL_PREFIX) #define G_MSVC_CTOR(_func,_sym_prefix) \ static void _func(void); \ extern int (* _array ## _func)(void); \ int _func ## _wrapper(void) { _func(); g_slist_find (NULL, _array ## _func); return 0; } \ __pragma(comment(linker,"/include:" _sym_prefix # _func "_wrapper")) \ __pragma(section(".CRT$XCU",read)) \ __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _wrapper; #define G_MSVC_DTOR(_func,_sym_prefix) \ static void _func(void); \ extern int (* _array ## _func)(void); \ int _func ## _constructor(void) { atexit (_func); g_slist_find (NULL, _array ## _func); return 0; } \ __pragma(comment(linker,"/include:" _sym_prefix # _func "_constructor")) \ __pragma(section(".CRT$XCU",read)) \ __declspec(allocate(".CRT$XCU")) int (* _array ## _func)(void) = _func ## _constructor; #elif defined (_MSC_VER) #define G_HAS_CONSTRUCTORS 1 /* Pre Visual studio 2008 must use #pragma section */ #define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 #define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 #define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ section(".CRT$XCU",read) #define G_DEFINE_CONSTRUCTOR(_func) \ static void _func(void); \ static int _func ## _wrapper(void) { _func(); return 0; } \ __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper; #define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ section(".CRT$XCU",read) #define G_DEFINE_DESTRUCTOR(_func) \ static void _func(void); \ static int _func ## _constructor(void) { atexit (_func); return 0; } \ __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; #elif defined(__SUNPRO_C) /* This is not tested, but i believe it should work, based on: * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c */ #define G_HAS_CONSTRUCTORS 1 #define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 #define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 #define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ init(_func) #define G_DEFINE_CONSTRUCTOR(_func) \ static void _func(void); #define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ fini(_func) #define G_DEFINE_DESTRUCTOR(_func) \ static void _func(void); #else /* constructors not supported for this compiler */ #endif #endif /* __GTK_DOC_IGNORE__ */ #ifdef G_HAS_CONSTRUCTORS #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(resource_constructor) #endif G_DEFINE_CONSTRUCTOR(resource_constructor) #ifdef G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA #pragma G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(resource_destructor) #endif G_DEFINE_DESTRUCTOR(resource_destructor) #else #warning "Constructor not supported on this compiler, linking in resources will not work" #endif static void resource_constructor (void) { g_static_resource_init (&static_resource); } static void resource_destructor (void) { g_static_resource_fini (&static_resource); } gxtuner-3.0/resources.h000066400000000000000000000002161321541042300152250ustar00rootroot00000000000000#ifndef __RESOURCE_resource_H__ #define __RESOURCE_resource_H__ #include extern GResource *resource_get_resource (void); #endif gxtuner-3.0/tuner.cpp000066400000000000000000001044301321541042300147060ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: tuner.cpp guitar tuner for jack * * ---------------------------------------------------------------------------- */ #include "./config.h" #include "./tuner.h" #include "./paintbox.h" #include "./gtkknob.h" #include "./gxtuner.h" #include "./deskpager.h" #include "./resources.h" TunerWidget::TunerWidget() {} TunerWidget::~TunerWidget() {} void TunerWidget::session_quit() { jack_port_unregister(cptr->gc(), cptr->gp()); jack_deactivate(cptr->gc()); jack_client_close(cptr->gc()); if (tw.g_threads > 0) { g_source_remove(tw.g_threads); } gtk_main_quit (); } void TunerWidget::destroy( GtkWidget *widget, gpointer data) { jack_port_unregister(cptr->gc(), cptr->gp()); jack_deactivate(cptr->gc()); jack_client_close(cptr->gc()); if (tw.g_threads > 0) { g_source_remove(tw.g_threads); } gtk_main_quit (); } gboolean TunerWidget::delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { return FALSE; } gboolean TunerWidget::gx_update_frequency(gpointer arg) { gx_tuner_set_freq(GX_TUNER(tw.get_tuner()), cptr->ef()); return true; } gboolean TunerWidget::ref_freq_changed(gpointer arg) { gx_tuner_set_reference_pitch(GX_TUNER(tw.get_tuner()), gtk_adjustment_get_value(GTK_ADJUSTMENT(arg))); return true; } gboolean TunerWidget::threshold_changed(gpointer arg) { cptr->sf(gtk_adjustment_get_value(GTK_ADJUSTMENT(arg))); return true; } gboolean TunerWidget::mode_changed(gpointer arg) { int m = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); GtkWidget *top = gtk_widget_get_toplevel(GTK_WIDGET(arg)); std::string title ="gxtuner - "; title +=gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(arg)); gtk_window_set_title(GTK_WINDOW(top),title.c_str()); gx_tuner_set_mode(GX_TUNER(tw.get_tuner()),m); return true; } gboolean TunerWidget::reference_note_changed(gpointer arg) { //#1 int R = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_note(GX_TUNER(tw.get_tuner()),R); return true; } gboolean TunerWidget::reference_03comma_changed(gpointer arg) { int A = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_03comma(GX_TUNER(tw.get_tuner()),A); return true; } gboolean TunerWidget::reference_05comma_changed(gpointer arg) { int B = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_05comma(GX_TUNER(tw.get_tuner()),B); return true; } gboolean TunerWidget::reference_07comma_changed(gpointer arg) { int C = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_07comma(GX_TUNER(tw.get_tuner()),C); return true; } gboolean TunerWidget::reference_11comma_changed(gpointer arg) { int D = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_11comma(GX_TUNER(tw.get_tuner()),D); return true; } gboolean TunerWidget::reference_13comma_changed(gpointer arg) { int E = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_13comma(GX_TUNER(tw.get_tuner()),E); return true; } gboolean TunerWidget::reference_17comma_changed(gpointer arg) { int F = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_17comma(GX_TUNER(tw.get_tuner()),F); return true; } gboolean TunerWidget::reference_19comma_changed(gpointer arg) { int G = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_19comma(GX_TUNER(tw.get_tuner()),G); return true; } gboolean TunerWidget::reference_23comma_changed(gpointer arg) { int H = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_23comma(GX_TUNER(tw.get_tuner()),H); return true; } gboolean TunerWidget::reference_29comma_changed(gpointer arg) { int I = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_29comma(GX_TUNER(tw.get_tuner()),I); return true; } gboolean TunerWidget::reference_31comma_changed(gpointer arg) { int J = gtk_combo_box_get_active(GTK_COMBO_BOX(arg)); gx_tuner_set_reference_31comma(GX_TUNER(tw.get_tuner()),J); return true; } void TunerWidget::signal_handler(int sig) { // print out a warning g_print ("signal: %i received, exiting ...\n", sig); destroy(NULL,NULL); } void TunerWidget::create_window() { // create main window and set icon to use err = NULL; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); GdkPixbuf *icon = gdk_pixbuf_new_from_resource("/gxtuner/gxtuner.png", NULL); gtk_window_set_icon(GTK_WINDOW(window),icon); if (err != NULL) g_error_free(err); g_object_unref(icon); // create all used widgets tuner = gx_tuner_new(); box = gx_paint_box_new(GTK_ORIENTATION_VERTICAL,false, 0); box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_homogeneous(GTK_BOX(box1),false); box2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_set_homogeneous(GTK_BOX(box2),false); set_expose_func(GX_PAINT_BOX(box),"rahmen_expose"); gtk_container_set_border_width(GTK_CONTAINER(box1),15); abox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(abox),false); bbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(bbox),false); cbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(cbox),false); dbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(dbox),false); ebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(ebox),false); fbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(fbox),false); gbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(gbox),false); hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hbox),false); habox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(habox),false); hbbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hbbox),false); hcbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hcbox),false); hhbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(hhbox),false); ibox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(ibox),false); jbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(jbox),false); kbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(kbox),false); lbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(lbox),false); mbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(mbox),false); nbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(nbox),false); obox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(obox),false); pbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous(GTK_BOX(pbox),false); //pabox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); //gtk_box_set_homogeneous(GTK_BOX(pabox),false); //pbbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); //gtk_box_set_homogeneous(GTK_BOX(pbbox),false); //pcbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); //gtk_box_set_homogeneous(GTK_BOX(pcbox),false); adj = gtk_adjustment_new(440, 200, 600, 0.1, 1.0, 0); spinner = gtk_knob_new_with_value_label(GTK_ADJUSTMENT(adj), 0); gtk_widget_set_valign(spinner, GTK_ALIGN_START); gtk_widget_set_margin_end(spinner, 4); gtk_widget_set_margin_bottom(spinner, 2); adjt = gtk_adjustment_new(0.001, 0.001, 0.2, 0.001, 1.0, 0); spinnert = gtk_knob_new_with_value_label(GTK_ADJUSTMENT(adjt), 1); gtk_widget_set_valign(spinnert, GTK_ALIGN_START); gtk_widget_set_margin_start(spinnert, 4); gtk_widget_set_margin_bottom(spinnert, 2); // scale selectord = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "chromatic"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "scale3diatonic"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "scale35chromatic"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "scale357chromatic"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "scale37chromatic"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectord), NULL, "scaleovertones"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 1); gtk_widget_set_opacity(GTK_WIDGET(selectord), 0.1); // Reference note selectore = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "F"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "C"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "G"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "D"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "A"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "E"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectore), NULL, "B"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 1); gtk_widget_set_opacity(GTK_WIDGET(selectore), 0.1); // Flat or Sharps selectorf = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♭♭♭"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♭♭"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♭"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♯"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♯♯"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorf), NULL, "♯♯♯"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorf), 0.1); // 5 comma selectorg = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "---"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "--"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "-"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "+"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "++"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorg), NULL, "+++"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorg), 0.1); // 7 comma selectorh = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "ㄥㄥㄥ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "ㄥㄥ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "ㄥ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "7"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "77"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorh), NULL, "777"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorh), 0.1); // 11 comma selectori = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↓↓↓"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↓↓"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↓"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↑"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↑↑"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectori), NULL, "↑↑↑"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 3); gtk_widget_set_opacity(GTK_WIDGET(selectori), 0.1); // 13 comma selectorj = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "ƐƖƐƖƐƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "ƐƖƐƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "ƐƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "13"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "1313"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorj), NULL, "131313"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorj), 0.1); // 17 comma selectork = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "ㄥƖㄥƖㄥƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "ㄥƖㄥƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "ㄥƖ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "17"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "1717"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectork), NULL, "171717"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 3); gtk_widget_set_opacity(GTK_WIDGET(selectork), 0.1); // 19 comma selectorl = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "6Ɩ6Ɩ6Ɩ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "6Ɩ6Ɩ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "6Ɩ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "19"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "1919"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorl), NULL, "191919"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorl), 0.1); // 23 comma selectorm = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "ƐᄅƐᄅƐᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "ƐᄅƐᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "Ɛᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "23"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "2323"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorm), NULL, "232323"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorm), 0.1); // 29 comma selectorn = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "6ᄅ6ᄅ6ᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "6ᄅ6ᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "6ᄅ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "29"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "2929"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectorn), NULL, "292929"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 3); gtk_widget_set_opacity(GTK_WIDGET(selectorn), 0.1); // 31 comma selectoro = gtk_combo_box_text_new(); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "ƖƐƖƐƖƐ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "ƖƐƖƐ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "ƖƐ"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "0"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "31"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "3131"); gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(selectoro), NULL, "313131"); gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 3); gtk_widget_set_opacity(GTK_WIDGET(selectoro), 0.1); // set some options to widgets gtk_widget_set_app_paintable(window, TRUE); gtk_widget_set_redraw_on_allocate(GTK_WIDGET(window), TRUE); gtk_widget_set_can_focus(GTK_WIDGET(spinner), true); gtk_widget_set_can_focus(GTK_WIDGET(spinnert), true); gtk_widget_set_can_default(GTK_WIDGET(spinner), true); gtk_widget_set_can_default(GTK_WIDGET(spinnert), true); gtk_widget_set_tooltip_text(GTK_WIDGET(spinner),"reference pitch"); gtk_widget_set_tooltip_text(GTK_WIDGET(spinnert),"threshold"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectord),"scale"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectore),"Reference note"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorf),"Flats or Sharps"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorg),"Syncomma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorh),"7 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectori),"11 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorj),"13 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectork),"17 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorl),"19 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorm),"23 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectorn),"29 comma"); gtk_widget_set_tooltip_text(GTK_WIDGET(selectoro),"31 comma"); // stack all together // the main window box gtk_container_add (GTK_CONTAINER(window), box2); // the paintbox to create the frame gtk_box_pack_start(GTK_BOX(box2), box,true,true,0); gtk_box_pack_end(GTK_BOX(box2), pbox, false,false,0); gtk_box_pack_end(GTK_BOX(box2), hbox, false,false,0); // put the tuner inside the frame gtk_box_pack_start(GTK_BOX(box), box1,true,true,0); gtk_box_pack_start(GTK_BOX(box1), tuner,true,true,0); // put all the selectors and spinners in a box gtk_container_add (GTK_CONTAINER (abox), spinner); gtk_container_add (GTK_CONTAINER (bbox), spinnert); gtk_container_add (GTK_CONTAINER (dbox), selectord); gtk_container_add (GTK_CONTAINER (ebox), selectore); gtk_container_add (GTK_CONTAINER (fbox), selectorf); gtk_container_add (GTK_CONTAINER (gbox), selectorg); gtk_container_add (GTK_CONTAINER (hhbox), selectorh); gtk_container_add (GTK_CONTAINER (ibox), selectori); gtk_container_add (GTK_CONTAINER (jbox), selectorj); gtk_container_add (GTK_CONTAINER (kbox), selectork); gtk_container_add (GTK_CONTAINER (lbox), selectorl); gtk_container_add (GTK_CONTAINER (mbox), selectorm); gtk_container_add (GTK_CONTAINER (nbox), selectorn); gtk_container_add (GTK_CONTAINER (obox), selectoro); //put all the filled boxes in hbox and pbox gtk_box_pack_start(GTK_BOX(hbox),habox,false,false,5); gtk_box_pack_start(GTK_BOX(habox),abox,false,false,5); gtk_box_pack_start(GTK_BOX(hbox),hbbox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),cbox,true,false,5); gtk_box_pack_start(GTK_BOX(hbbox),dbox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),ebox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),fbox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),gbox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),hhbox,false,false,5); gtk_box_pack_start(GTK_BOX(hbbox),ibox,false,false,5); gtk_box_pack_start(GTK_BOX(hbox),hcbox,false,false,5); gtk_box_pack_start(GTK_BOX(hcbox),bbox,false,false,5); //gtk_box_pack_start(GTK_BOX(pbox),pabox,false,false,5); //gtk_box_pack_start(GTK_BOX(pbox),pbbox,false,false,5); gtk_box_pack_start(GTK_BOX(pbox),jbox,false,false,15); gtk_box_pack_start(GTK_BOX(pbox),kbox,false,false,15); gtk_box_pack_start(GTK_BOX(pbox),lbox,false,false,15); gtk_box_pack_end(GTK_BOX(pbox),obox,false,false,15); gtk_box_pack_end(GTK_BOX(pbox),nbox,false,false,15); gtk_box_pack_end(GTK_BOX(pbox),mbox,false,false,15); //gtk_box_pack_start(GTK_BOX(pbox),pcbox,false,false,5); // connect the signal handlers // connect the controls with a function to do what they should do // when they changed there value. g_signal_connect(G_OBJECT(adj), "value-changed", G_CALLBACK(ref_freq_changed),(gpointer)adj); g_signal_connect(G_OBJECT(adjt), "value-changed", G_CALLBACK(threshold_changed),(gpointer)adjt); g_signal_connect(GTK_COMBO_BOX(selectord), "changed", G_CALLBACK(mode_changed),(gpointer)selectord); g_signal_connect(GTK_COMBO_BOX(selectore), "changed", //#2 G_CALLBACK(reference_note_changed),(gpointer)selectore); g_signal_connect(GTK_COMBO_BOX(selectorf), "changed", G_CALLBACK(reference_03comma_changed),(gpointer)selectorf); g_signal_connect(GTK_COMBO_BOX(selectorg), "changed", G_CALLBACK(reference_05comma_changed),(gpointer)selectorg); g_signal_connect(GTK_COMBO_BOX(selectorh), "changed", G_CALLBACK(reference_07comma_changed),(gpointer)selectorh); g_signal_connect(GTK_COMBO_BOX(selectori), "changed", G_CALLBACK(reference_11comma_changed),(gpointer)selectori); g_signal_connect(GTK_COMBO_BOX(selectorj), "changed", G_CALLBACK(reference_13comma_changed),(gpointer)selectorj); g_signal_connect(GTK_COMBO_BOX(selectork), "changed", G_CALLBACK(reference_17comma_changed),(gpointer)selectork); g_signal_connect(GTK_COMBO_BOX(selectorl), "changed", G_CALLBACK(reference_19comma_changed),(gpointer)selectorl); g_signal_connect(GTK_COMBO_BOX(selectorm), "changed", G_CALLBACK(reference_23comma_changed),(gpointer)selectorm); g_signal_connect(GTK_COMBO_BOX(selectorn), "changed", G_CALLBACK(reference_29comma_changed),(gpointer)selectorn); g_signal_connect(GTK_COMBO_BOX(selectoro), "changed", G_CALLBACK(reference_31comma_changed),(gpointer)selectoro); g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL); g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL); parse_cmd(); show(); } void TunerWidget::parse_cmd() { GtkCssProvider* provider = gtk_css_provider_new(); GdkDisplay * display = gdk_display_get_default (); GdkScreen * sc = gdk_display_get_default_screen (display); GdkWindow * wd = gdk_screen_get_root_window (sc); gtk_style_context_add_provider_for_screen(sc, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider), " * { \n" " color: #fff; \n" " background-color: black; \n" "} \n", -1, NULL); g_object_unref(provider); // *** commandline parsing *** // set default window position optional by command line options int x = 90; int y = 90; if (!cptr->cv(3).empty()) { x = atoi(cptr->cv(3).c_str()); } else { x = gdk_window_get_width(wd)/2 -x; } if (!cptr->cv(4).empty()) { y = atoi(cptr->cv(4).c_str()); } else { y = gdk_window_get_height(wd)/2 -y; } gtk_window_move(GTK_WINDOW(window),x,y); // set default window size optional by command line options x = 500; y = 300; if (!cptr->cv(1).empty()) { x = atoi(cptr->cv(1).c_str()); } if (!cptr->cv(2).empty()) { y = atoi(cptr->cv(2).c_str()); } gtk_window_resize(GTK_WINDOW(window), x,y); // set reference pitch and threshold by command line options double p,t; if (!cptr->cv(5).empty()) { p = atof(cptr->cv(5).c_str()); } else { p = 440.0; } if (!cptr->cv(6).empty()) { t = atof(cptr->cv(6).c_str()); } else { t = 0.001; } gtk_window_set_title(GTK_WINDOW(window),"gxtuner-chromatic"); // here we check if a special mode is given on commandline, // add your mode here as well. if (!cptr->cv(9).empty()) { std::string m = cptr->cv(9).c_str(); if(m == "scale3diatonic") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 1); } else if(m == "scale35chromatic") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 2); } else if(m == "scale357chromatic") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 3); } else if(m == "scale37chromatic") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 4); }else if(m == "scaleovertones") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectord), 5); } } if (!cptr->cv(10).empty()) { //#3 std::string R = cptr->cv(10).c_str(); if(R == "F") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 0); } else if(R == "C") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 1); } else if(R == "G") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 2); } else if(R == "D") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 3); } else if(R == "A") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 4); } else if(R == "E") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 5); } else if(R == "B") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectore), 6); } } if (!cptr->cv(11).empty()) { std::string A = cptr->cv(11).c_str(); if(A == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 0); } else if(A == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 1); } else if(A == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 2); } else if(A == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 3); } else if(A == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 4); } else if(A == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 5); } else if(A == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorf), 6); } } if (!cptr->cv(12).empty()) { std::string B = cptr->cv(12).c_str(); if(B == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 0); } else if(B == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 1); } else if(B == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 2); } else if(B == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 3); } else if(B == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 4); } else if(B == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 5); } else if(B == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorg), 6); } } if (!cptr->cv(13).empty()) { std::string C = cptr->cv(13).c_str(); if(C == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 0); } else if(C == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 1); } else if(C == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 2); } else if(C == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 3); } else if(C == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 4); } else if(C == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 5); } else if(C == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorh), 6); } } if (!cptr->cv(14).empty()) { std::string D = cptr->cv(14).c_str(); if(D == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 0); } else if(D == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 1); } else if(D == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 2); } else if(D == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 3); } else if(D == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 4); } else if(D == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 5); } else if(D == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectori), 6); } } if (!cptr->cv(15).empty()) { std::string E = cptr->cv(15).c_str(); if(E == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 0); } else if(E == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 1); } else if(E == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 2); } else if(E == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 3); } else if(E == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 4); } else if(E == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 5); } else if(E == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorj), 6); } } if (!cptr->cv(16).empty()) { std::string F = cptr->cv(16).c_str(); if(F == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 0); } else if(F == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 1); } else if(F == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 2); } else if(F == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 3); } else if(F == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 4); } else if(F == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 5); } else if(F == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectork), 6); } } if (!cptr->cv(17).empty()) { std::string G = cptr->cv(17).c_str(); if(G == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 0); } else if(G == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 1); } else if(G == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 2); } else if(G == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 3); } else if(G == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 4); } else if(G == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 5); } else if(G == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorl), 6); } } if (!cptr->cv(18).empty()) { std::string H = cptr->cv(18).c_str(); if(H == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 0); } else if(H == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 1); } else if(H == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 2); } else if(H == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 3); } else if(H == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 4); } else if(H == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 5); } else if(H == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorm), 6); } } if (!cptr->cv(19).empty()) { std::string I = cptr->cv(19).c_str(); if(I == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 0); } else if(I == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 1); } else if(I == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 2); } else if(I == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 3); } else if(I == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 4); } else if(I == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 5); } else if(I == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectorn), 6); } } if (!cptr->cv(20).empty()) { std::string J = cptr->cv(20).c_str(); if(J == "min3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 0); } else if(J == "min2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 1); } else if(J == "min1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 2); } else if(J == "0") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 3); } else if(J == "1") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 4); } else if(J == "2") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 5); } else if(J == "3") { gtk_combo_box_set_active(GTK_COMBO_BOX(selectoro), 6); } } gtk_adjustment_set_value(GTK_ADJUSTMENT(adj),p); gtk_adjustment_set_value(GTK_ADJUSTMENT(adjt),t); // set virtual desktop to use desk = 0; if (!cptr->cv(8).empty()) { desk = atoi(cptr->cv(8).c_str()); } } void TunerWidget::show() { // finaly show the window with all widgets gtk_widget_show_all(window); if (desk) dp.move_window_to_desktop(desk, window); } TunerWidget tw; CmdPtr *cptr = 0;gxtuner-3.0/tuner.h000066400000000000000000000120131321541042300143460ustar00rootroot00000000000000/* * Copyright (C) 2011 Hermann Meyer, Andreas Degert * * 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 2 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * --------------------------------------------------------------------------- * * file: tuner.h guitar tuner for jack * * ---------------------------------------------------------------------------- */ #pragma once #ifndef _TUNER_H_ #define _TUNER_H_ #include //#include #include #include #include #include typedef std::string (*getcmdvar) (int x); typedef float (*getptvar) (); typedef jack_port_t* (*getport) (); typedef jack_client_t* (*getclient) (); typedef void (*setptvar) (float x); // the tuner widget class, add all functions and widget pointers // used in the tuner class here. class TunerWidget { private: int desk; GtkAdjustment* adjt; GtkAdjustment* adj; GtkWidget* window; GtkWidget* tuner; GError* err; GtkWidget* box; GtkWidget* box1; GtkWidget* box2; GtkWidget* abox; GtkWidget* bbox; GtkWidget* cbox; GtkWidget* dbox; GtkWidget* ebox; GtkWidget* fbox; GtkWidget* gbox; GtkWidget* hbox; GtkWidget* habox; GtkWidget* hbbox; GtkWidget* hcbox; GtkWidget* hhbox; GtkWidget* ibox; GtkWidget* jbox; GtkWidget* kbox; GtkWidget* lbox; GtkWidget* mbox; GtkWidget* nbox; GtkWidget* obox; GtkWidget* pbox; //GtkWidget* pabox; //GtkWidget* pbbox; //GtkWidget* pcbox; GtkWidget* spinner; GtkWidget* spinnert; GtkWidget* selectord; //changes mode GtkWidget* selectore; // changes reference note GtkWidget* selectorf; // 03comma GtkWidget* selectorg; // 05comma GtkWidget* selectorh; // 07comma GtkWidget* selectori; // 11comma GtkWidget* selectorj; // 13comma GtkWidget* selectork; // 17comma GtkWidget* selectorl; // 19comma GtkWidget* selectorm; // 23comma GtkWidget* selectorn; // 29comma GtkWidget* selectoro; // 31comma static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data); static gboolean ref_freq_changed(gpointer arg); static gboolean threshold_changed(gpointer arg); static gboolean mode_changed(gpointer arg); static gboolean reference_note_changed(gpointer arg); //#1 static gboolean reference_03comma_changed(gpointer arg); static gboolean reference_05comma_changed(gpointer arg); static gboolean reference_07comma_changed(gpointer arg); static gboolean reference_11comma_changed(gpointer arg); static gboolean reference_13comma_changed(gpointer arg); static gboolean reference_17comma_changed(gpointer arg); static gboolean reference_19comma_changed(gpointer arg); static gboolean reference_23comma_changed(gpointer arg); static gboolean reference_29comma_changed(gpointer arg); static gboolean reference_31comma_changed(gpointer arg); static void destroy( GtkWidget *widget, gpointer data); public: explicit TunerWidget(); ~TunerWidget(); int g_threads; void* get_tuner() { return tuner;} void* get_window() { return window;} void session_quit(); void create_window(); void parse_cmd(); void show(); void window_area(int* x, int* y, int* w, int* l) { gtk_window_get_position(GTK_WINDOW(window), x, y); gtk_window_get_size(GTK_WINDOW(window), w, l); } static void signal_handler(int sig); static gboolean gx_update_frequency(gpointer arg); }; extern TunerWidget tw; class CmdPtr { public: getcmdvar cv; getport gp; getclient gc; getptvar ef; setptvar sf; }; extern CmdPtr *cptr; #endif // _TUNER_H_