From 5b0496bf8fbdcf110ae63fffa2d65259fbb9ced9 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Thu, 24 Dec 2009 19:16:07 +0000 Subject: [PATCH] Move everything to trunk --- TODO | 13 + data/album.png | Bin 0 -> 1066 bytes data/artist.png | Bin 0 -> 636 bytes data/clear.png | Bin 0 -> 897 bytes data/configure.png | Bin 0 -> 717 bytes data/currenttrack_bar_left.png | Bin 0 -> 954 bytes data/currenttrack_bar_mid.png | Bin 0 -> 229 bytes data/currenttrack_bar_right.png | Bin 0 -> 931 bytes data/currenttrack_pause.png | Bin 0 -> 191 bytes data/currenttrack_play.png | Bin 0 -> 229 bytes data/data.qrc | 35 + data/exit.png | Bin 0 -> 1134 bytes data/files.png | Bin 0 -> 457 bytes data/folder-new.png | Bin 0 -> 923 bytes data/folder.png | Bin 0 -> 386 bytes data/go-home.png | Bin 0 -> 635 bytes data/go-next.png | Bin 0 -> 721 bytes data/go-previous.png | Bin 0 -> 634 bytes data/go-up.png | Bin 0 -> 672 bytes data/icon.png | Bin 0 -> 9053 bytes data/logo.png | Bin 0 -> 163051 bytes data/logo.xcf | Bin 0 -> 376597 bytes data/mainwindow.css | 8 + data/media-playback-pause.png | Bin 0 -> 721 bytes data/media-playback-start.png | Bin 0 -> 736 bytes data/media-playback-stop.png | Bin 0 -> 736 bytes data/media-skip-backward.png | Bin 0 -> 753 bytes data/media-skip-forward.png | Bin 0 -> 752 bytes data/nomusic.png | Bin 0 -> 10913 bytes data/schema.sql | 32 + data/volumeslider-gradient.png | Bin 0 -> 203 bytes data/volumeslider-handle.png | Bin 0 -> 352 bytes data/volumeslider-handle_glow.png | Bin 0 -> 744 bytes data/volumeslider-inset.png | Bin 0 -> 707 bytes src/analyzers/analyzerbase.cpp | 219 +++++ src/analyzers/analyzerbase.h | 84 ++ src/analyzers/analyzerfactory.cpp | 127 +++ src/analyzers/baranalyzer.cpp | 167 ++++ src/analyzers/baranalyzer.h | 57 ++ src/analyzers/blockanalyzer.cpp | 401 +++++++++ src/analyzers/blockanalyzer.h | 62 ++ src/analyzers/boomanalyzer.cpp | 157 ++++ src/analyzers/boomanalyzer.h | 52 ++ src/analyzers/glanalyzer.cpp | 342 ++++++++ src/analyzers/glanalyzer.h | 62 ++ src/analyzers/glanalyzer2.cpp | 333 ++++++++ src/analyzers/glanalyzer2.h | 73 ++ src/analyzers/glanalyzer3.cpp | 480 +++++++++++ src/analyzers/glanalyzer3.h | 80 ++ src/analyzers/sonogram.cpp | 91 ++ src/analyzers/sonogram.h | 37 + src/analyzers/turbine.cpp | 78 ++ src/analyzers/turbine.h | 22 + src/backgroundthread.cpp | 1 + src/backgroundthread.h | 59 ++ src/directory.h | 16 + src/engine_fwd.h | 26 + src/enginebase.cpp | 49 ++ src/enginebase.h | 281 +++++++ src/fht.cpp | 242 ++++++ src/fht.h | 119 +++ src/library.cpp | 543 ++++++++++++ src/library.h | 110 +++ src/librarybackend.cpp | 382 +++++++++ src/librarybackend.h | 72 ++ src/libraryconfig.cpp | 76 ++ src/libraryconfig.h | 39 + src/libraryconfig.ui | 146 ++++ src/libraryitem.cpp | 35 + src/libraryitem.h | 41 + src/libraryquery.cpp | 56 ++ src/libraryquery.h | 33 + src/libraryview.cpp | 139 ++++ src/libraryview.h | 50 ++ src/librarywatcher.cpp | 153 ++++ src/librarywatcher.h | 59 ++ src/main.cpp | 20 + src/mainwindow.cpp | 349 ++++++++ src/mainwindow.h | 77 ++ src/mainwindow.ui | 554 +++++++++++++ src/player.cpp | 103 +++ src/player.h | 46 ++ src/playlist.cpp | 364 ++++++++ src/playlist.h | 87 ++ src/playlistitem.cpp | 21 + src/playlistitem.h | 35 + src/playlistview.cpp | 280 +++++++ src/playlistview.h | 79 ++ src/sliderwidget.cpp | 369 +++++++++ src/sliderwidget.h | 145 ++++ src/song.cpp | 278 +++++++ src/song.h | 91 ++ src/songmimedata.cpp | 1 + src/songmimedata.h | 15 + src/songplaylistitem.cpp | 51 ++ src/songplaylistitem.h | 29 + src/src.pro | 80 ++ src/systemtrayicon.cpp | 17 + src/systemtrayicon.h | 18 + src/xine-engine.cpp | 1282 +++++++++++++++++++++++++++++ src/xine-engine.h | 165 ++++ src/xine-scope.c | 186 +++++ src/xine-scope.h | 50 ++ tangerine.pro | 2 + 104 files changed, 10533 insertions(+) create mode 100644 TODO create mode 100644 data/album.png create mode 100644 data/artist.png create mode 100644 data/clear.png create mode 100644 data/configure.png create mode 100644 data/currenttrack_bar_left.png create mode 100644 data/currenttrack_bar_mid.png create mode 100644 data/currenttrack_bar_right.png create mode 100644 data/currenttrack_pause.png create mode 100644 data/currenttrack_play.png create mode 100644 data/data.qrc create mode 100644 data/exit.png create mode 100644 data/files.png create mode 100644 data/folder-new.png create mode 100644 data/folder.png create mode 100644 data/go-home.png create mode 100644 data/go-next.png create mode 100644 data/go-previous.png create mode 100644 data/go-up.png create mode 100644 data/icon.png create mode 100644 data/logo.png create mode 100644 data/logo.xcf create mode 100644 data/mainwindow.css create mode 100644 data/media-playback-pause.png create mode 100644 data/media-playback-start.png create mode 100644 data/media-playback-stop.png create mode 100644 data/media-skip-backward.png create mode 100644 data/media-skip-forward.png create mode 100644 data/nomusic.png create mode 100644 data/schema.sql create mode 100644 data/volumeslider-gradient.png create mode 100644 data/volumeslider-handle.png create mode 100644 data/volumeslider-handle_glow.png create mode 100644 data/volumeslider-inset.png create mode 100644 src/analyzers/analyzerbase.cpp create mode 100644 src/analyzers/analyzerbase.h create mode 100644 src/analyzers/analyzerfactory.cpp create mode 100644 src/analyzers/baranalyzer.cpp create mode 100644 src/analyzers/baranalyzer.h create mode 100644 src/analyzers/blockanalyzer.cpp create mode 100644 src/analyzers/blockanalyzer.h create mode 100644 src/analyzers/boomanalyzer.cpp create mode 100644 src/analyzers/boomanalyzer.h create mode 100644 src/analyzers/glanalyzer.cpp create mode 100644 src/analyzers/glanalyzer.h create mode 100644 src/analyzers/glanalyzer2.cpp create mode 100644 src/analyzers/glanalyzer2.h create mode 100644 src/analyzers/glanalyzer3.cpp create mode 100644 src/analyzers/glanalyzer3.h create mode 100644 src/analyzers/sonogram.cpp create mode 100644 src/analyzers/sonogram.h create mode 100644 src/analyzers/turbine.cpp create mode 100644 src/analyzers/turbine.h create mode 100644 src/backgroundthread.cpp create mode 100644 src/backgroundthread.h create mode 100644 src/directory.h create mode 100644 src/engine_fwd.h create mode 100644 src/enginebase.cpp create mode 100644 src/enginebase.h create mode 100644 src/fht.cpp create mode 100644 src/fht.h create mode 100644 src/library.cpp create mode 100644 src/library.h create mode 100644 src/librarybackend.cpp create mode 100644 src/librarybackend.h create mode 100644 src/libraryconfig.cpp create mode 100644 src/libraryconfig.h create mode 100644 src/libraryconfig.ui create mode 100644 src/libraryitem.cpp create mode 100644 src/libraryitem.h create mode 100644 src/libraryquery.cpp create mode 100644 src/libraryquery.h create mode 100644 src/libraryview.cpp create mode 100644 src/libraryview.h create mode 100644 src/librarywatcher.cpp create mode 100644 src/librarywatcher.h create mode 100644 src/main.cpp create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/mainwindow.ui create mode 100644 src/player.cpp create mode 100644 src/player.h create mode 100644 src/playlist.cpp create mode 100644 src/playlist.h create mode 100644 src/playlistitem.cpp create mode 100644 src/playlistitem.h create mode 100644 src/playlistview.cpp create mode 100644 src/playlistview.h create mode 100644 src/sliderwidget.cpp create mode 100644 src/sliderwidget.h create mode 100644 src/song.cpp create mode 100644 src/song.h create mode 100644 src/songmimedata.cpp create mode 100644 src/songmimedata.h create mode 100644 src/songplaylistitem.cpp create mode 100644 src/songplaylistitem.h create mode 100644 src/src.pro create mode 100644 src/systemtrayicon.cpp create mode 100644 src/systemtrayicon.h create mode 100644 src/xine-engine.cpp create mode 100644 src/xine-engine.h create mode 100644 src/xine-scope.c create mode 100644 src/xine-scope.h create mode 100644 tangerine.pro diff --git a/TODO b/TODO new file mode 100644 index 000000000..d7af521e0 --- /dev/null +++ b/TODO @@ -0,0 +1,13 @@ +- Crossfading +- Drag & drop from files tab +- Double click folders in files tab +- Nice error messages +- Automatically install xine plugins + +Long-term: +- Last.fm +- iPod + +Windows: +- Playlist delegates +- Document build steps diff --git a/data/album.png b/data/album.png new file mode 100644 index 0000000000000000000000000000000000000000..612fc8159c38a872dd32717d729cfb81f07251f3 GIT binary patch literal 1066 zcmY*Xc}&x17;XUtnQUk>1U5&OXvRccW^mc&vP@HsqGgN`2}?9&W}*zI3>Fd%5rsL9 zLND6ldH@xi>u8}+z*3}#EwrWdg8tfKFM5sA(t{QXQpbM8{j(>}`@F}Oe0lTaZ7C|u zOG->ngg_uk@O)S?n3H!SAr{ok6K{PBCTLA@-Z=o4rO`Na`tq)i^X2R5G=L#}#PRdO$mE0MriG!uIxdG#cI6+36+^ z_RE8|&+ljSY~S8c-7m)jxNj(O4`F1Rjqk z5C}vfiA<47WwUbmoEKcl53cghf7o|mqz(KR`u+Jl*u}&ocMDkWhr`a6q^9i=AkN2} zO@&w^l(M?%OBMad{>)=f8Vkx*&v37hC)aTkPS%yfFW*ofy+74-@?KY3Zh`po3xNzx|b1`{YClP z%1_>eUx%d~x?D|0+)T(WYHC!r)tIDL^?N5+rB|x{zD=-DY3cQd1k`6IEKhEt+HwCk`HKVBQr1oR`d_zG zRh6f1GqM;5ABFXkeMh8J{Kwx_{y@32IrpL5^z@JU5_*;X@R_e53Hz&R*!BDvYer*w U9jUEi1h#8FJf{%GJXe1IUu1HCf&c&j literal 0 HcmV?d00001 diff --git a/data/artist.png b/data/artist.png new file mode 100644 index 0000000000000000000000000000000000000000..b50ec42a5e86f71478526a925209af02c6dcaa7e GIT binary patch literal 636 zcmV-?0)zdDP)ioX&l9Qg5)@#=1TUz0#I#>Q1{5;Lx$e~Y#YI3)8HD<0{QUDSN(~~VY%#_ka4v$(pV;jV zZemQHIWENnlQeyd@u3f+frSAkjU?190=>u%<>+{?im@p3hlRJF*zH|P+d(I#JS7d3)2M5_K`5F#0i9`Zejs=e8 zfMFOAB@rAB2T;`f+`LjOmcVQ_gVkn%TsHrw0sKXilWsUVIs%U4fMr?O{J6;kKYdnC z?#~$wP%4&zczs?d77E>gK;T9qnWz8-qSa}EDimZzrgpns+t|>!GB7Z(>hXA3uh%D^ zSZlRfAY)@U;jmD6ZnIjSQ3{f+!Nwit4}s_PAP6FDX}Lfmk%-{;`|nz;W?!`;u-n@q z`GkZe*eR1vU*kB<)zQ&W(KYUZa5${&?CdB#Jw4Rzb}M+tB$J8j(P*sH+1a^)&TJ}` zqJZK=NrI{%FoGaJM@I*%*Xy~7i3xBzoiI2!NbBqCNo#8>H5yG)d;6t1|HejBGLd|m zOvRzu?f?b>K&T3&TrR`Z)D)mISglqV85seS$waocw&={v42j3%EILbVZEa617Rw?Q zYXHTnt0|RAeWEB{iN#_H7BRiOy?{iu4J<4ykoEQT8VPQN=yW=P5YnB=WKvik07O=& z`2r8LzrSDH-`}UjVv(lPX^K=7ot5F?VTx}QgTWvgjYhTEdv%kb3J+?7S5D_e8VZF( zS(fSA+A6($=N84uD=3NtDw&AyC{lUU*`02o>3ox#v_4GNFMcr z%gf6QCRQ!}w}ys>V0`?Z`g^qxn-Dld#N~1UP9AemVk(si#Th`InsI!7eEh3cc#t`u z!C>%A=ihO=a7B+S7Uuu}03v!+SaefwW^{L9a%BJjc-kv3FW1Y=%Pvk%EJ)SMFG>dh XHrNJO5L3!r00000NkvXXu0mjfOy-jj literal 0 HcmV?d00001 diff --git a/data/configure.png b/data/configure.png new file mode 100644 index 0000000000000000000000000000000000000000..5ce478b1adfefacc19d35d61e88a6c02ebe97454 GIT binary patch literal 717 zcmV;;0y6!HP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02{9W02{9XUK)`c00007bV*G`2iXAx z12+)F5m%`I00K=(L_t(|+KrN3NRx3C#*f?DM%ip+yqb-i;h^3{#n{|Ose_>C#@NE# z7GW2nLRnqZRk>l z!E^IGoWld>6hQ%)Ob;ZrwY8lTqK?F3D=U#m#6CX$#%MA3twKK3jp{=S3-bwzqR{g1 zWn_6|PHT0V4^ml84HUxVD;?&gUq4YYxrThci3GMzVQs_8wx>aE7+A7!I1H&&3b@>z z8%!qi9rhAf2rzWW0VzB{sMRWCC={ZTLLqRr7qhDNRaNlz?0&5`==X~y;%hk@XtmlC z)z#Ho0)bh$({nG|qLN>Ej>p>@6bJ+}b93`2b1k5YM55;Lw?1I9w}RI{3DeUbfmgwU zk`fL#FdNvgKDCcf%4E{WJ?36(INk6~Szl-8a=AAFK#9fNG~C_Y#rJsJGrheQ zBv;6hcfyN?hOCn~Qef@KUgduny7b2#PFv(s$3;Yx5y)(Lh@2zNPdMU39%!A08&{uL z2UAU&vxvjtpqADa^wRZWsl2>Q3i-Hgymh^|--2{HEh0%0sm`d7%`u#mNW_}#x8;FB z5JX#iH3q4425MvyP%7)Gf&RxmQ&aDUagOpXV6s?qkSO9GJthS14l_j zK~z}7y_ipL8$}q#f6u(Lb`r;FlQ@kX8&@r{>u^CzDkT*XM?@oz2*C|;tJDv{8N@f} z2LK6G;?fgvMx4qG6^UEzNL-RA3H}rBaIoFPsU2d+&MQ6AO0zq^dER+vcXkA@ySvM% zQ7*0bE*F3Yzy|Oxun4388}ytX6SM$420jONfGmJBBQ=*|K0QxrE=80`kcc9j*=WEE zZk_;7fdUelB$7mt2gFzoyD$fQ3VaI`XJ%$8m&=sOWtNtf`nqnP zp3*)&9onD20_=7d^i?8}bd`+?l}d$Vat45Uy*|>E`2T@rf#<-Z)zvJUTU(^lX#g6H z2IGXk1eODSk=(|5X`M=?f+Xtof4NThA+SZ@InqY?L7BV7yJI`L6xf9s@Ex#I$QQVC zXO()R&ZJ^cNH1lM$*@-!O3wW*~zX9YUPqWp87SjQCqqCraR@znvN96rPfeXO) zz&k?V4i0e+TL>uuYoHHQYUuyBi9E>}mIMfw0KOhF*wE{x)tP*o^Q zTv9A4egk~@@(-MJAn~26`OdK8bGO30-#pgV=cE9gnkp+5z09U z=NwMDmgHQJ>#m23f4~p7HUU;8eGinJncQ`^ZW`dQ7u8yge17d1c!BgVgpl)5gqg=V z8%@@cITy^i!9aj&wMIUlKLK6{ErvLL&wDQ)d7L>pb6iQTBkK-eD6j*qQYhpbh+hSN zwd44GAf1R3^5!vT{j%Y5=7KYKIS}CW>neppAt1d1eu(4vu+?nc3n8SuH_SX{rk;~w zGV2UVqaK^=Y;OakyG!R2=iH|EwqoAPNl5O}cj?H$UOd`)vu~aU?sv~2;aA1+T|c2L`2d*<(H;oJMx+n>_( V+-6#F<^#}n22WQ%mvv4FO#s4JQ-=Tm literal 0 HcmV?d00001 diff --git a/data/currenttrack_bar_right.png b/data/currenttrack_bar_right.png new file mode 100644 index 0000000000000000000000000000000000000000..5dfd7dcc68c5f4422bfdf65417bb5f098278c331 GIT binary patch literal 931 zcmV;U16=%xP)~KhJ$0SSkioBHE#mY%38HAhj?vm644JhIT+gz|y?~Fd(skSWtx! zqAjW_At84FF|bg(Iag^_>f9Y3TqCD)k~XQ&@%?%4#}K>JsnhrzU%t}a@bvD!`hMT{ z{oe0Refr7A-!lpW1i(Y!AK)Ia0&KaS&on5P%jnl$f8%{?3{e~tM-f3Up!>K>&b6s55rQhEMXaeVftFGtUeTf{$ku(;BVV`=vPW@h;C<-lb5jgL9 z{-fuvQ5c44-DY87k>kftP;;Ezg9oc;fmch#!n>~LukQ7f9@vl?`Ml=T=~L9}b$ri% zOT_+BDi+>$J-@vNQJ;fg{^UHlT#l8Ml|@9Zm5POTT+e?vb0UCa$6hAr2DDoD-vquY z6$|HF&o{e>LS})vxjEYHHpV0$0KWm3X0k?O*CDSlCQ-nbrDEaw(@E6fj1%;0*B7z`E@NT9)jP$k+n& zUa45PR0f$U-Xb6f#+auo{5YHjjslxHj3Pe4D-6_MYc9DEt3?&9+D?f;MRj8fMYKNJNGwxdU8qYPDxv(pu{S5m^zeF`^Wnh@4$=YMWzwKAq3YRN)1zSdu6b zlyVR`x8&41dp4I^>#5u_NkS6EMxm|<^7+jrXY2W0>`>8!Thv-hKkVB$j{gO|KvBL~ zUD`LfS|8DqEVdYvNWUN2D2m#G`~dujQr&8$I$2*HMNu;T zE0yZw)E@vr5c~|HcKv7A9#q}t;9o;SDY}2%s7#&C{{Td~*M%mDG^_vs002ovPDHLk FV1l+cw~zn; literal 0 HcmV?d00001 diff --git a/data/currenttrack_pause.png b/data/currenttrack_pause.png new file mode 100644 index 0000000000000000000000000000000000000000..f4897310ad542591dd3a3d41781304b8a3df1e26 GIT binary patch literal 191 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$0wn*`OvwRKOvO%~Asif`Z`?qFk|nMYCBgY= zCFO}lsSM@i<$9TU*~Q6;1*v-ZMd`EO*+>Bu1$(+UhDcnlov@LYL6L`fuh4EohQF7U zFJ7uRy;#9(dibi#o}IE6Z{$dIaf-<%S9K*A8l)}Z5ED*L>pDI^LSl0eOLw!Oy6cC2 kjqs_*Pwz-Q_()Y;{`=AE3n!f_0~*iZ>FVdQ&MBb@0BC$bO8@`> literal 0 HcmV?d00001 diff --git a/data/currenttrack_play.png b/data/currenttrack_play.png new file mode 100644 index 0000000000000000000000000000000000000000..8e8809ed5b68db67ae8bca981c5f72ea403386dd GIT binary patch literal 229 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$0wn*`OvwRKjKx9jP7LeL$-D$|n3BBRT^Rni z_n+Ah4nJa0`PlBg3pY5H=O_M1FH!iKuh&oA!*3T1k_IEF}EPEJVp z5&tp1i;>yD$ly=>!4K0D#Sd#8dw)X6hX(}C@XX_>{eRY=^uPhhw#uIO6G{&>a5}%Q zSI-gR;hDpe`JZ`%=K)4;ssGl8laAHS5b~I&ta8uzOu9{Lo`@K~(E~0a2I&B~y!Gb< R9|J9A@O1TaS?83{1ORXbNGAXQ literal 0 HcmV?d00001 diff --git a/data/data.qrc b/data/data.qrc new file mode 100644 index 000000000..30431f60c --- /dev/null +++ b/data/data.qrc @@ -0,0 +1,35 @@ + + + clear.png + go-home.png + go-next.png + go-previous.png + go-up.png + media-playback-pause.png + media-playback-start.png + media-playback-stop.png + media-skip-backward.png + media-skip-forward.png + mainwindow.css + schema.sql + volumeslider-handle_glow.png + volumeslider-handle.png + volumeslider-inset.png + volumeslider-gradient.png + logo.png + icon.png + currenttrack_bar_left.png + currenttrack_bar_mid.png + currenttrack_bar_right.png + currenttrack_pause.png + currenttrack_play.png + album.png + artist.png + files.png + nomusic.png + folder-new.png + folder.png + configure.png + exit.png + + diff --git a/data/exit.png b/data/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..ed5f8b2515e72608d2de9d45fb80ff481926066e GIT binary patch literal 1134 zcmV-!1d;oRP)(xC=n00006VoOIv0RI600RN!9r;`8x1N%ut zK~#9!wUS?G990y?zx!uqcQ)CO3Qb9*q)kbepkNXsL>fp%(uUwejD?y8p{)=!q9{uI zgNUFMD`JgLd5}{2)TjDbX(&h)iK5opBqla%!fsPV$ZoQ`*`3+BGvk@tY+BYL;-3Q_ zbGUQA-}(0J;J>IK2tw^3)mP3K37K=}c6+n4r`M;ZdQ>*cgNlLlcl&$x?F+W`_y4@Q zyxhNgd^{yVZgTFam#l;R5QCNuU}|&|FIk9vK+Wf7}ljFCx0I0B)M_DpyEQn_xvs z?A=Q~uEAY2z;11YDwXs*lI}}%*4fvmp>$V!D(@6yRp3GaWzxc#GqBTX3h8TOTW>GW z*$HJAwfv3_Bzk(_c^;HfD5X-`LtYKmiMLikQ{7@wgTlHxF@gKW#vq%T^x3ZNZrqey z_l*xe6hd{cR#q@KIf=k^p*fBN@6N=&lzJ8Aiq_UJcj|qp8>tYY(>JttV*3LfVM;B3 zC5?rTKY+@u!KI`;5`mk~p={fCBo-WNi;EDJ1tVr5Y8ikJBu~AAJo`vlHhy9SSvSW$s^eS~DeuZ?2*i_g*i_>&r1 zfnT}w8N{XYaEdNU#3_a$6~JQA>QxAU0mO$XJP1_;ck)<&>?w2%4eOMoE%>g1C*T}= z1y+rLs0l<2@=5YbUJd5dF-Qrmh-JbbeGLyEAA=A=e|mK{=TQIKd^kYE6N4iNM&E=< zYcmLJgkUoS<2E=DoVWxI6H^51#kUFi93)NQoD*~w{KF$KCq~eaStO95b^qa`sD1ea z4D!%?$Ui4$y5pqA*WX3=v1dY~2FFrALY+K}7`IVtI2yivHHm063ez;ve&lJ~`^HJ_ z6%qtS6?pTYxn++|sdfE(WZyaj=GtK4Y!XuroD(!CJ&Q;rqVF{|H{XJVoJwNa84C=q z!F~Wtj}9aM&1KkEzrylMgK$eW$_gktK%oRUWx%x^{5n1aH8YKkZ@-L1P+nfHmzkGcoSayYs+V7sKKq@G6j0Hk0G|-o z|Ns93nQ-9PejCE}?78FAaoeTycH8FXKn748h@9F%B5qxGJbLbW_1^XAyXQaQe&EFW z!IK|^PI-{I;CcR%7o{s-HEn#`z3pw^t`9T!y`Q=N{j3A;XCL}J=irA0$38DR`E~iJ zZ|lx|Uw``D`m>)moO!qH>d%8WJ|4dL>B!BmM{a$3^6vN7pZ|XS`S%-${{H{-_dj#3 z4-e2yd?i7C!3?aNTnb9I4yS+p2Ff#W{yz?ssrPho43UszJ$TT|DN%&&z|X$tZEOpt zY`OBiUNc{7@b+0x69x5zf zOFuQv?|XLN)T?e*$tkpCluG{TM_od0zCn%TaxNqU^6^s_y(x2wHvU{?= zQ2($UK6)~Hxvr|PYqxW$OF zngiwx-}fJ6kqnbfa3=%_pqYdSNc3*vrR?eQb<;|C&i5N4#)hFoSUnt&;_%`a7sKOZ zlcy>5PU4%8MAXZ3l_Tt$f0ub(mcY$7yfE;q0w(4xYx{+kJ*{KxDIVirJV98pf%7X~ zEbz-h)EoFh6e*oBMiA7-16T06Lbqs)Bx8ZlYzdw4tRRBKL;v)K!;%|%&Ei62Rqxk>;002ovPDHLkV1lSPvy%V- literal 0 HcmV?d00001 diff --git a/data/folder.png b/data/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..536da3d1c39096335080a97d29953d38e382c121 GIT binary patch literal 386 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfLzW3kH})6 z^6MbX=%g{b0w^e1;u=vBoS#-wo>-L1P+nfHmzkGcoSayYs+V7sKKq@G6i`t`fKQ0) z|NsAi%(S`hfFuwsx$tl9sb7^FzE`jRoWJaC(wyg0cE1Um{Lr)WR{H$6=2d6y8ZKol zcxzOC%DDV=+WfZ#%RiQ``dqc{OT*@`jk|ueZ2Q^@MEigB?)lcc_xse{FQy&&G4tq; zB}ZQ`J@<3{y`^&4cE^O2ihl8666=mAZAn3wsO7OX0ZYk8_>e(gW7&=+2A%p!AXT@VDH~x2fCf#hk{AEdD!dvN^xfyMqJiPn$ X6bytKFJC|L2IO&1S3j3^P6oc5!lIL8@MUQTpt6Hc~*<;sHJ( zuK)l4PfAbIH!(A^ur#%@Hn+92u(P+cwX=3`aCCKX_ww-e^YQWb@d*s{3-I+1@(&0N z1+w*x4D<{Pl2TKWQd1L>k`j`W(lRmp{}_Vo7i2AT{sFeo%IG}t#*k0BwGA)%B3Xe7|6w9K?DE1vv<)M879;%J7F;=Gd5 z%!-Pfnwo-!hT_IFu9lXvj;_|uo~|xuhTh)pIYGP&7S3G~z_2!iVOQJbd`*@#Ck@o;`o@ z`pw(VU%veQ^9L9vOH|^o0K-wbB*-tAp`rm5^j)~}^XIQ$fByb`P`a@KsBFEbi(^Q| zt<;|Dd`$rYF6;M}zuBvu9_+>u2KDjwcG z>uT>9#rA3W?4o~P+fJClr!T8}$ zJCS$qI^o{LM uTFAdLcI_93TAP57bSXBm$5B#$KQr0RRZpyT(^LaGox#)9&t;ucLK6VI&jeEd literal 0 HcmV?d00001 diff --git a/data/go-next.png b/data/go-next.png new file mode 100644 index 0000000000000000000000000000000000000000..a04c99e2544a55fc0e7a0b2d3b33939ad3644f86 GIT binary patch literal 721 zcmV;?0xtcDP)-QyBq8B=CC0L~nB}pY&r5r?n2O2gdSfeRirxGq%C0L{(Pm?25 zoe3K^Bu8K)QklWe9OLnjyM13buiwGAh z3LQ8LB18)#Mhzf64<<+uAutgqI}$Ba5-vp&E?E;YVH7Y|6fs;CIBOO;ZWl6D7%)s2 zJ8vF8S1U|?ELD;k_ttILqC%8{_mld{j2w9uEe(V)NAro`I0)#v~J z|KYj7cK`qYCv;LyQvd(}0s;a90}Bie85%M+O-@c&ba;=Cnx3Spy1m%k>g(tyM)C7|k8r{la5Hg1p_F?B)3x7&sNRG&R(9lcNH>?4-Hj z?$FCf@KF|KMmWqM%SDzK$)T)P7UCSpE@zVvV88_c7XcqIKS|iV00000NkvXXu0mjf Dy00sk literal 0 HcmV?d00001 diff --git a/data/go-previous.png b/data/go-previous.png new file mode 100644 index 0000000000000000000000000000000000000000..940797b8a588cd4a74ce79ffd8c3957041c319e6 GIT binary patch literal 634 zcmV-=0)_pFP)Btj8dji$CWjoEB=citM4UJ9wN_<`s6d|`$e{40W==$&{9 zA^C*lynEr<+3RRQ!!~+OJq$DV`&~|Jlal+WYZ*|`LUMdAQ(v4<>^3H^oF9g_zJ%>) zTNj@wQi`i8*!1zCL|`!63j)9|fBto#XMCRyC2mQOz(B@nay$w+%P9Y-(_fU0Ux6r~aPK?(uRIVknvdoE^f zKESv69MQT@&fd`#@8ZE!l*D5p)M`E$1GE4(Bh7#i5{z=#wu^lJ12}V=M-bEj<337j z1VI%D?*NQ81wo-g)i|Uipj4ph_*g4dP$(>8rT7(sHUsMV`{yr=UD-EFAD54QDy&$x z1C(vvn2OC{I~6M_;90gBeRM0fFJWXnt3nLa}#r&B7#jeXfedf&hSgiI4NQzzi9<_UgR zI62a9?LGW1J#tB2yZ>71v6TGdzhLeeG$r?M3Bk@m2zbS}1b;)1?;q8>GCBM&8?MXX UHoH%CfB*mh07*qoM6N<$f(*zK!2kdN literal 0 HcmV?d00001 diff --git a/data/go-up.png b/data/go-up.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d9cef97e16ca46909765c0a67091c97908660b GIT binary patch literal 672 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 P00000NkvXXu0mjfrP4Ff literal 0 HcmV?d00001 diff --git a/data/logo.png b/data/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..37951cc767e4e7a1ca52a0edd01c52d0169aabd8 GIT binary patch literal 163051 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

Hrhx7$+H32o%oKMR{7=Hez4+?1Wdv?Nwp>S2lwD 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�Gz!nf5)A>H4zck*SPi3He2~LN@kyTN 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 literal 0 HcmV?d00001 diff --git a/data/logo.xcf b/data/logo.xcf new file mode 100644 index 0000000000000000000000000000000000000000..6b3e9666633c6ce5505e3757c5e1425403a05b94 GIT binary patch literal 376597 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

7ZR8# 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 literal 0 HcmV?d00001 diff --git a/data/mainwindow.css b/data/mainwindow.css new file mode 100644 index 000000000..92520e36b --- /dev/null +++ b/data/mainwindow.css @@ -0,0 +1,8 @@ +#playlist { + background-color: white; + background-image: url(:logo.png); + background-attachment: fixed; + background-position: bottom right; + background-repeat: none; + background-clip: content; +} diff --git a/data/media-playback-pause.png b/data/media-playback-pause.png new file mode 100644 index 0000000000000000000000000000000000000000..d133bdc5f4221189327a648dcc85d0de65a2fd1e GIT binary patch literal 721 zcmV;?0xtcDP)MzCV_|S* zE^l&Yo9;Xs0006|Nklm1Vesrj<@hHq+JEDZi=4fu{q6?L(h9jO{p}}(+9z^$D*2s zmX{4pmSS2QdC^cMVxVUP==o0))YQFVBrV3YFm_f0LGsW8C!liVUs+TrylyNl#3UgI z$o{bBPtbSl7!U+W64QS0mn?(A83hPRX8_qlLE4XLFX|eqRI-MS28dcZf}~P86s5f~ z?M7WErj0RWMicOyLX?g5{Vqzo;lpV9_M)KJ@u7HF9JVgBY3A%oRU-b`ylO|N>*dBFn@9Xizzx5DLHM-VcA_g7r6 zW-FBng+ig|+PJd~5HbKhXy;{17A;`kp51Wob`OB3-H-8l?Hf!w00000NkvXXu0mjf DdR0Ku literal 0 HcmV?d00001 diff --git a/data/media-playback-start.png b/data/media-playback-start.png new file mode 100644 index 0000000000000000000000000000000000000000..2820368e8596875c15fe786090cbcf7690d489b5 GIT binary patch literal 736 zcmV<60w4W}P)MzCV_|S* zE^l&Yo9;Xs0007CNklTJ^-NtaC6FHZ?MqQLnc#`bzHl-0uUx?E;eD6A=A4EMr4#!e*wIqo4I{U@WYAkU9nMX9MZcO%5JaVx zX^-3&hx-=H5h@=|mEU!}Wn4?2Jr^XPR5)?uC(GK>w?AJ=_ge9X!!wsn>i3MghaS76 zE)ir>iMGFV)Ly^;RZ>ix4DyD4b$wE7`OGE~shWnScW^RTOeDSW+;c9d$)pmw1Aq9! zf&-*#>Y6Uf^~RGpc4|PblnBTj+SB#Ghkis*)8~>?aV&|Wg&}nW0Z%;fuc!X8>r;!4 zq*5;_#L+B@2m;_YTmE+9yz}}*5Cl<_#f>oZyGjK}W$F@{bLL$^Pi0#WHI&( zi!YtZmhR3GD$KO2&ED{_SIs!1Pb#RCj@|Q6L$(`6?sN$im~K}KaW>cRycfMJ_|>)@ zN9vNLaQ$uMzCV_|S* zE^l&Yo9;Xs0007CNklGm1hbzUmeXm>6QkBUhppZK=^s{?9(l^~-qlf+OOYUmNSztD z<2TJ-n9K6zNtai()#SE~3=E7+lu{pSDZS}aXWeW$n=FmZcuqy8G%+-A;y*c3iHe$r zOCGb7m5b+Qj1>}zv5}`v4CR8VD5$8q;!tHVDHn2=)esa8J@&+je>~AQ5G7Knm*mQY ztW+Whi2ii!*s*^-Yg!_LASjiRazFS>6p=`zD(a@yRipxl4g}?XQtl;s#tH>$>YCav zYHO+sN`=CqM7fuhyNRBGwj2$G#FRp6N<$FkM*ff}cf&ia_-NF<>V0h&3?!lmg5Vj2 zp)dTX-V1Z-!|^u<$=Z=iW~7=LE@*0KsGBk|@{2Fkh4=3K6e3o?nyjZb%xkErNI@Yt z_N&jG%eJ;R2oYMzCV_|S* zE^l&Yo9;Xs0007TNkl=;7vYM;6mH*HIsi;_o68kT{4*j;o?HGXX-^-G@Vt|Lx99`A5|I1aO&bcmF5zgTJ)L!?T80cON&IJD1dn`Z z!-0;rvR-FAWGai3$A+}z+M4!7(S2Xq_OFKAk&-Ttt13-qaiVQh8QbpLvt!vG4(!=g zmugF;p7O0Ykwp5rXa2* zaWzrXk}EuBP%3rFoTv30)Gw3ERVCtT5?2y6`;O%*PD{bKPh2x<1~cFP%~`kas=fT-WIdi~}zJ;EEG|Cq3_ z6z03#wQk>`rnZibj<%*FyWZC=%r7hv3d{}^>z%Qt3ug7{k_rmBrhC5EBijn+7wUup zTplRq;+2*jPk7QFgO4FLWJ2J8G|z|!==00000NkvXXu0mjfWj<3W literal 0 HcmV?d00001 diff --git a/data/media-skip-forward.png b/data/media-skip-forward.png new file mode 100644 index 0000000000000000000000000000000000000000..739243239421033b0bb716f206e533a98dc18ce6 GIT binary patch literal 752 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 DkXdQ} literal 0 HcmV?d00001 diff --git a/data/schema.sql b/data/schema.sql new file mode 100644 index 000000000..621d0d89a --- /dev/null +++ b/data/schema.sql @@ -0,0 +1,32 @@ +CREATE TABLE directories ( + path TEXT NOT NULL, + subdirs INTEGER NOT NULL +); + + +CREATE TABLE songs ( + /* Metadata from taglib */ + title TEXT, + album TEXT, + artist TEXT, + albumartist TEXT, + composer TEXT, + track INTEGER, + disc INTEGER, + bpm REAL, + year INTEGER, + genre TEXT, + comment TEXT, + compilation INTEGER, + + length INTEGER, + bitrate INTEGER, + samplerate INTEGER, + + /* Information about the file on disk */ + directory INTEGER NOT NULL, + filename TEXT NOT NULL, + mtime INTEGER NOT NULL, + ctime INTEGER NOT NULL, + filesize INTEGER NOT NULL +); diff --git a/data/volumeslider-gradient.png b/data/volumeslider-gradient.png new file mode 100644 index 0000000000000000000000000000000000000000..d6dfab83adb4c850e1098590e0addfb4c21009db GIT binary patch literal 203 zcmeAS@N?(olHy`uVBq!ia0vp^1wgFA!3-qR6#ZrZDVB6cUq=Rp^(V|(yIunMk|nMY zCBgY=CFO}lsSJ)O`AMk?p1FzXsX?iUDV2pMQ*D5X*aCb)T>k?B!~bIu9CAPr#*!ev zU1A`C)8v_%D0!9J;3CF+O z`zJP+(S|{gffb?zZZ88HYxSJ_|AAn~8?H$Vh71A_i(t}>Y&n_7|3g8`6_z#zRR$gg zW}pnj1XdgOZU2!#%2DQ21~~>Upc0UNb}gy)<6j>Ce+Y$-|6l#3(#{^rAi=-^GM-tCGP4=n|0g7{nQL7#tWp8N3;MpwOGa0~jJYK;HnZU;=uH yk3kfuOdMz^1cKP24E#XNP+u?sor4LP7#IQWiT=8(D*8SE0000P)k00004XF*Lt006JZ zHwB960000PbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!dPzhcQ++%ZAlh4iZCHi5d=#RBJe5v6N)G+eF=L=lKKlo?JZxUsL)<2 ziXcNPO6sX1&BWEMTzA*mT())EnLC}kPCt~Wz}LO-F>vqszH`oZ4#OPB!DfzvO`f7a zQJ^SL6etS(rvQV+B>o!nr{B6uQhrMygM z0QzVINhnv&_B0E_@Zns~1Q<)9Z0i>UgR5>e1tQ;&S(1H(5WD}NWxHv11S%@^>5b29?&vfmruB=oVF7)n9`~5l*??Tt7 z@bZ;l4fU(i6U8OV(zn1gE2!T(bzt!LrS|qctxZizq^1VLM~{U)laogfoo_`v9)_m* z@a8R-Too7l)=bOg%E0+9wYRUkBNVFd?>y!C(Ozv$gr(wf|K!B@HYcaT)Q>O@x8_K=pvvMll`OJiI@srM5Si44+dN4CIl^Oi==dJ+3rPQlVl4?%%#GZJDD zv^Nr_`3=eBDi&f{EG%RYi)9L%SQzElW7XXSPKK_nIOo6C*0P)emX~eJMQw~vSd>_N a7hnM8i3pao150=S0000z6#*me`N9HS zAf6=P8f_em$A~c@A(sS%TrnhLisI?@v*-g8W(A^uf-nV+00Ebb2pBOUWJt(>DH9SB z6hFB^F~=Z)7ro;-3l?biNdKgac0p*>2?#A(OiYYIaYsZ-%G~7|27|Vz!O#N+_;?71 zS8%P-oHov8q17lrP)vCsA>{`tDMVE$93r7lAPWLz_GIC=@X% zw|ry9oFxDnauA1;VaReMT|#z;Sk?9c_~;@K^FYim5@w_gqq$FaniMKw?Tc0 zLiPy2y%mA7HdUiJkU|+-W)jzH*Cd6oJBK^&+6HwbpCXNPKg|<&$5^ zxLyRGfHXIiF2StUhV3}@I2fL6%RvDym@s9=(&Es_oH~Np?M0hfnnNP`jms$s^IWMa zf~7UY?w!O8 zWtVsLhF63hPmq>dR5K@A)6wTEnU*7N*^`kLYuKD)<=nUKYtw|hXuV1AjM_90zTu+f pfFJq%Us<&KZ=wV206V~g#vcYA#&3ZR^CJKN002ovPDHLkV1i+fHD&++ literal 0 HcmV?d00001 diff --git a/src/analyzers/analyzerbase.cpp b/src/analyzers/analyzerbase.cpp new file mode 100644 index 000000000..c2049ca00 --- /dev/null +++ b/src/analyzers/analyzerbase.cpp @@ -0,0 +1,219 @@ +/*************************************************************************** + viswidget.cpp - description + ------------------- + begin : Die Jan 7 2003 + copyright : (C) 2003 by Max Howell + email : markey@web.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "analyzerbase.h" +#include "enginebase.h" +#include //interpolate() +#include //event() +#include +#include +#include + + +// INSTRUCTIONS Base2D +// 1. do anything that depends on height() in init(), Base2D will call it before you are shown +// 2. otherwise you can use the constructor to initialise things +// 3. reimplement analyze(), and paint to canvas(), Base2D will update the widget when you return control to it +// 4. if you want to manipulate the scope, reimplement transform() +// 5. for convenience are pre-included +// TODO make an INSTRUCTIONS file +//can't mod scope in analyze you have to use transform + + +//TODO for 2D use setErasePixmap Qt function insetead of m_background + +// make the linker happy only for gcc < 4.0 +#if !( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 0 ) ) && !defined(Q_OS_WIN32) +template class Analyzer::Base; +#endif + + +Analyzer::Base::Base( QWidget *parent, uint timeout, uint scopeSize ) + : QWidget( parent ) + , m_timeout( timeout ) + , m_fht( new FHT(scopeSize) ) + , m_engine(NULL) + , m_lastScope(512) +{ + connect( &m_timer, SIGNAL( timeout() ), SLOT( update() ) ); +} + +void Analyzer::Base::hideEvent(QHideEvent *) { + m_timer.stop(); +} + +void Analyzer::Base::showEvent(QShowEvent *) { + m_timer.start(timeout()); +} + +void Analyzer::Base::transform( Scope &scope ) //virtual +{ + //this is a standard transformation that should give + //an FFT scope that has bands for pretty analyzers + + //NOTE resizing here is redundant as FHT routines only calculate FHT::size() values + //scope.resize( m_fht->size() ); + + float *front = static_cast( &scope.front() ); + + float* f = new float[ m_fht->size() ]; + m_fht->copy( &f[0], front ); + m_fht->logSpectrum( front, &f[0] ); + m_fht->scale( front, 1.0 / 20 ); + + scope.resize( m_fht->size() / 2 ); //second half of values are rubbish + delete [] f; +} + +void Analyzer::Base::paintEvent(QPaintEvent * e) +{ + EngineBase *engine = m_engine; + + QPainter p(this); + p.fillRect(e->rect(), palette().color(QPalette::Window)); + + switch( engine->state() ) + { + case Engine::Playing: + { + const Engine::Scope &thescope = engine->scope(); + int i = 0; + + // convert to mono here - our built in analyzers need mono, but we the engines provide interleaved pcm + for( uint x = 0; (int)x < m_fht->size(); ++x ) + { + m_lastScope[x] = double(thescope[i] + thescope[i+1]) / (2*(1<<15)); + i += 2; + } + + transform( m_lastScope ); + analyze( p, m_lastScope ); + + //scope.resize( m_fht->size() ); + + break; + } + case Engine::Paused: + analyze(p, m_lastScope); + break; + + default: + demo(p); + } +} + +int Analyzer::Base::resizeExponent( int exp ) +{ + if ( exp < 3 ) + exp = 3; + else if ( exp > 9 ) + exp = 9; + + if ( exp != m_fht->sizeExp() ) { + delete m_fht; + m_fht = new FHT( exp ); + } + return exp; +} + +int Analyzer::Base::resizeForBands( int bands ) +{ + int exp; + if ( bands <= 8 ) + exp = 4; + else if ( bands <= 16 ) + exp = 5; + else if ( bands <= 32 ) + exp = 6; + else if ( bands <= 64 ) + exp = 7; + else if ( bands <= 128 ) + exp = 8; + else + exp = 9; + + resizeExponent( exp ); + return m_fht->size() / 2; +} + +void Analyzer::Base::paused(QPainter& p) //virtual +{} + +void Analyzer::Base::demo(QPainter& p) //virtual +{ + static int t = 201; //FIXME make static to namespace perhaps + + if( t > 999 ) t = 1; //0 = wasted calculations + if( t < 201 ) + { + Scope s( 32 ); + + const double dt = double(t) / 200; + for( uint i = 0; i < s.size(); ++i ) + s[i] = dt * (sin( M_PI + (i * M_PI) / s.size() ) + 1.0); + + analyze( p, s ); + } + else analyze( p, Scope( 32, 0 ) ); + + ++t; +} + + +void Analyzer::Base::polishEvent() +{ + init(); //virtual +} + +void +Analyzer::interpolate( const Scope &inVec, Scope &outVec ) //static +{ + double pos = 0.0; + const double step = (double)inVec.size() / outVec.size(); + + for ( uint i = 0; i < outVec.size(); ++i, pos += step ) + { + const double error = pos - std::floor( pos ); + const unsigned long offset = (unsigned long)pos; + + unsigned long indexLeft = offset + 0; + + if ( indexLeft >= inVec.size() ) + indexLeft = inVec.size() - 1; + + unsigned long indexRight = offset + 1; + + if ( indexRight >= inVec.size() ) + indexRight = inVec.size() - 1; + + outVec[i] = inVec[indexLeft ] * ( 1.0 - error ) + + inVec[indexRight] * error; + } +} + +void +Analyzer::initSin( Scope &v, const uint size ) //static +{ + double step = ( M_PI * 2 ) / size; + double radian = 0; + + for ( uint i = 0; i < size; i++ ) + { + v.push_back( sin( radian ) ); + radian += step; + } +} diff --git a/src/analyzers/analyzerbase.h b/src/analyzers/analyzerbase.h new file mode 100644 index 000000000..e402171e9 --- /dev/null +++ b/src/analyzers/analyzerbase.h @@ -0,0 +1,84 @@ +// Maintainer: Max Howell , (C) 2004 +// Copyright: See COPYING file that comes with this distribution + +#ifndef ANALYZERBASE_H +#define ANALYZERBASE_H + + +#ifdef __FreeBSD__ +#include +#endif + +#include "engine_fwd.h" +#include "fht.h" //stack allocated and convenience +#include //stack allocated and convenience +#include //stack allocated +#include //baseclass +#include //included for convenience + +#include //baseclass +#ifdef Q_WS_MACX +#include //included for convenience +#include //included for convenience +#else +#include //included for convenience +#include //included for convenience +#endif + +class QEvent; +class QPaintEvent; +class QResizeEvent; + + +namespace Analyzer { + +typedef std::vector Scope; + +class Base : public QWidget +{ +public: + uint timeout() const { return m_timeout; } + + void set_engine(EngineBase* engine) { m_engine = engine; } + +protected: + Base( QWidget*, uint timeout, uint scopeSize = 7 ); + ~Base() { delete m_fht; } + + void hideEvent(QHideEvent *); + void showEvent(QShowEvent *); + void paintEvent( QPaintEvent* ); + + void polishEvent(); + + int resizeExponent( int ); + int resizeForBands( int ); + virtual void init() {} + virtual void transform( Scope& ); + virtual void analyze( QPainter& p, const Scope& ) = 0; + virtual void paused(QPainter& p); + virtual void demo(QPainter& p); + + void changeTimeout( uint newTimeout ) + { + m_timer.setInterval( newTimeout ); + m_timeout = newTimeout; + } + +protected: + QTimer m_timer; + uint m_timeout; + FHT *m_fht; + EngineBase* m_engine; + Scope m_lastScope; +}; + + +void interpolate( const Scope&, Scope& ); +void initSin( Scope&, const uint = 6000 ); + +} //END namespace Analyzer + +using Analyzer::Scope; + +#endif diff --git a/src/analyzers/analyzerfactory.cpp b/src/analyzers/analyzerfactory.cpp new file mode 100644 index 000000000..91c28b013 --- /dev/null +++ b/src/analyzers/analyzerfactory.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + analyzerfactory.cpp - description + ------------------- + begin : Fre Nov 15 2002 + copyright : (C) 2002 by Mark Kretschmann + email : markey@web.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include //for HAVE_QGLWIDGET macro + +#include "amarokcore/amarokconfig.h" +#include "analyzerbase.h" //declaration here + +#include "baranalyzer.h" +#include "boomanalyzer.h" +#include "sonogram.h" +#include "turbine.h" +#include "blockanalyzer.h" + +#ifdef HAVE_QGLWIDGET +#include "glanalyzer.h" +#include "glanalyzer2.h" +#include "glanalyzer3.h" +#endif + +#include +#include + +//separate from analyzerbase.cpp to save compile time + + +QWidget *Analyzer::Factory::createAnalyzer( QWidget *parent ) +{ + //new XmmsWrapper(); //toplevel + + QWidget *analyzer = 0; + + switch( AmarokConfig::currentAnalyzer() ) + { + case 2: + analyzer = new Sonogram( parent ); + break; + case 1: + analyzer = new TurbineAnalyzer( parent ); + break; + case 3: + analyzer = new BarAnalyzer( parent ); + break; + case 4: + analyzer = new BlockAnalyzer( parent ); + break; +#ifdef HAVE_QGLWIDGET + case 5: + analyzer = new GLAnalyzer( parent ); + break; + case 6: + analyzer = new GLAnalyzer2( parent ); + break; + case 7: + analyzer = new GLAnalyzer3( parent ); + break; + case 8: +#else + case 5: +#endif + analyzer = new QLabel( i18n( "Click for Analyzers" ), parent ); //blank analyzer to satisfy Grue + static_cast(analyzer)->setAlignment( Qt::AlignCenter ); + break; + + default: + AmarokConfig::setCurrentAnalyzer( 0 ); + case 0: + analyzer = new BoomAnalyzer( parent ); + } + + return analyzer; +} + +QWidget *Analyzer::Factory::createPlaylistAnalyzer( QWidget *parent) +{ + QWidget *analyzer = 0; + switch( AmarokConfig::currentPlaylistAnalyzer() ) + { + case 1: + analyzer = new TurbineAnalyzer( parent ); + break; + case 2: + analyzer = new Sonogram( parent ); + break; + case 3: + analyzer = new BoomAnalyzer( parent ); + break; + #ifdef HAVE_QGLWIDGET + case 4: + analyzer = new GLAnalyzer( parent ); + break; + case 5: + analyzer = new GLAnalyzer2( parent ); + break; + case 6: + analyzer = new GLAnalyzer3( parent ); + break; + case 7: + #else + case 4: + #endif + analyzer = new QLabel( i18n( "Click for Analyzers" ), parent ); //blank analyzer to satisfy Grue + static_cast(analyzer)->setAlignment( Qt::AlignCenter ); + break; + + default: + AmarokConfig::setCurrentPlaylistAnalyzer( 0 ); + case 0: + analyzer = new BlockAnalyzer( parent ); + break; + } + return analyzer; +} diff --git a/src/analyzers/baranalyzer.cpp b/src/analyzers/baranalyzer.cpp new file mode 100644 index 000000000..b323b4256 --- /dev/null +++ b/src/analyzers/baranalyzer.cpp @@ -0,0 +1,167 @@ +// +// +// C++ Implementation: $MODULE$ +// +// Description: +// +// +// Author: Mark Kretschmann , (C) 2003 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include "baranalyzer.h" +#include //log10(), etc. +#include +#include + + +BarAnalyzer::BarAnalyzer( QWidget *parent ) + : Analyzer::Base( parent, 12, 8 ) + //, m_bands( BAND_COUNT ) + //, barVector( BAND_COUNT, 0 ) + //, roofVector( BAND_COUNT, 50 ) + //, roofVelocityVector( BAND_COUNT, ROOF_VELOCITY_REDUCTION_FACTOR ) +{ + //roof pixmaps don't depend on size() so we do in the ctor + m_bg = parent->palette().color(QPalette::Background); + + QColor fg( 0xff, 0x50, 0x70 ); + + double dr = double(m_bg.red() - fg.red()) / (NUM_ROOFS-1); //-1 because we start loop below at 0 + double dg = double(m_bg.green() - fg.green()) / (NUM_ROOFS-1); + double db = double(m_bg.blue() - fg.blue()) / (NUM_ROOFS-1); + + for ( uint i = 0; i < NUM_ROOFS; ++i ) + { + m_pixRoof[i] = QPixmap( COLUMN_WIDTH, 1 ); + m_pixRoof[i].fill( QColor( fg.red()+int(dr*i), fg.green()+int(dg*i), fg.blue()+int(db*i) ) ); + } + +} + +void BarAnalyzer::resizeEvent( QResizeEvent * e ) +{ + qDebug() << "Baranalyzer Resized(" << width() << "x" << height() << ")"; + init(); +} + +// METHODS ===================================================== + +void BarAnalyzer::init() +{ + const double MAX_AMPLITUDE = 1.0; + const double F = double(height() - 2) / (log10( 255 ) * MAX_AMPLITUDE ); + + + BAND_COUNT = width() / 5; + MAX_DOWN = int(0 -(qMax(1, height() / 50))); + MAX_UP = int(qMax(1, height() / 25)); + + qDebug() << "BAND_COUNT = " << BAND_COUNT << " MAX_UP = " << MAX_UP << "MAX_DOWN = " << MAX_DOWN; + + barVector.resize( BAND_COUNT, 0 ); + roofVector.resize( BAND_COUNT, height() -5 ); + roofVelocityVector.resize( BAND_COUNT, ROOF_VELOCITY_REDUCTION_FACTOR ); + m_roofMem.resize(BAND_COUNT); + m_scope.resize(BAND_COUNT); + + //generate a list of values that express amplitudes in range 0-MAX_AMP as ints from 0-height() on log scale + for ( uint x = 0; x < 256; ++x ) + { + m_lvlMapper[x] = uint( F * log10( x+1 ) ); + } + + m_pixBarGradient = QPixmap( height()*COLUMN_WIDTH, height() ); + m_pixCompose = QPixmap( size() ); + + QPainter p( &m_pixBarGradient ); + for ( int x=0, r=0x40, g=0x30, b=0xff, r2=255-r; + x < height(); ++x ) + { + for ( int y = x; y > 0; --y ) + { + const double fraction = (double)y / height(); + +// p.setPen( QColor( r + (int)(r2 * fraction), g, b - (int)(255 * fraction) ) ); + p.setPen( QColor( r + (int)(r2 * fraction), g, b ) ); + p.drawLine( x*COLUMN_WIDTH, height() - y, (x+1)*COLUMN_WIDTH, height() - y ); + } + } + + + setMinimumSize( QSize( BAND_COUNT * COLUMN_WIDTH, 10 ) ); +} + + +void BarAnalyzer::analyze( QPainter& p, const Scope &s ) +{ + //Analyzer::interpolate( s, m_bands ); + + Scope &v = m_scope; + Analyzer::interpolate( s, v ); + + for ( uint i = 0, x = 0, y2; i < v.size(); ++i, x+=COLUMN_WIDTH+1 ) + { + //assign pre[log10]'d value + y2 = uint(v[i] * 256); //256 will be optimised to a bitshift //no, it's a float + y2 = m_lvlMapper[ (y2 > 255) ? 255 : y2 ]; //lvlMapper is array of ints with values 0 to height() + + int change = y2 - barVector[i]; + + //using the best of Markey's, piggz and Max's ideas on the way to shift the bars + //we have the following: + // 1. don't adjust shift when doing small up movements + // 2. shift large upwards with a bias towards last value + // 3. fall downwards at a constant pace + + /*if ( change > MAX_UP ) //anything too much greater than 2 gives "jitter" + //add some dynamics - makes the value slightly closer to what it was last time + y2 = ( barVector[i] + MAX_UP ); + //y2 = ( barVector[i] * 2 + y2 ) / 3; + else*/ if ( change < MAX_DOWN ) + y2 = barVector[i] + MAX_DOWN; + + + if ( (int)y2 > roofVector[i] ) + { + roofVector[i] = (int)y2; + roofVelocityVector[i] = 1; + } + + //remember where we are + barVector[i] = y2; + + if ( m_roofMem[i].size() > NUM_ROOFS ) + m_roofMem[i].erase( m_roofMem[i].begin() ); + + //blt last n roofs, a.k.a motion blur + for ( uint c = 0; c < m_roofMem[i].size(); ++c ) + //bitBlt( m_pComposePixmap, x, m_roofMem[i]->at( c ), m_roofPixmaps[ c ] ); + //bitBlt( canvas(), x, m_roofMem[i][c], &m_pixRoof[ NUM_ROOFS - 1 - c ] ); + p.drawPixmap(x, m_roofMem[i][c], m_pixRoof[ NUM_ROOFS - 1 - c ]); + + //blt the bar + p.drawPixmap(x, height() - y2, + *gradient(), y2 * COLUMN_WIDTH, height() - y2, COLUMN_WIDTH, y2); + /*bitBlt( canvas(), x, height() - y2, + gradient(), y2 * COLUMN_WIDTH, height() - y2, COLUMN_WIDTH, y2, Qt::CopyROP );*/ + + m_roofMem[i].push_back( height() - roofVector[i] - 2 ); + + //set roof parameters for the NEXT draw + if ( roofVelocityVector[i] != 0 ) + { + if ( roofVelocityVector[i] > 32 ) //no reason to do == 32 + roofVector[i] -= (roofVelocityVector[i] - 32) / 20; //trivial calculation + + if ( roofVector[i] < 0 ) + { + roofVector[i] = 0; //not strictly necessary + roofVelocityVector[i] = 0; + } + else ++roofVelocityVector[i]; + } + } +} diff --git a/src/analyzers/baranalyzer.h b/src/analyzers/baranalyzer.h new file mode 100644 index 000000000..2bb73dd2c --- /dev/null +++ b/src/analyzers/baranalyzer.h @@ -0,0 +1,57 @@ +// Maintainer: Max Howell +// Authors: Mark Kretschmann & Max Howell (C) 2003-4 +// Copyright: See COPYING file that comes with this distribution +// + +#ifndef BARANALYZER_H +#define BARANALYZER_H + +#include "analyzerbase.h" + +typedef std::vector aroofMemVec; + + +class BarAnalyzer : public Analyzer::Base +{ + public: + BarAnalyzer( QWidget* ); + + void init(); + virtual void analyze( QPainter& p, const Scope& ); + //virtual void transform( Scope& ); + + /** + * Resizes the widget to a new geometry according to @p e + * @param e The resize-event + */ + void resizeEvent( QResizeEvent * e); + + uint BAND_COUNT; + int MAX_DOWN; + int MAX_UP; + static const uint ROOF_HOLD_TIME = 48; + static const int ROOF_VELOCITY_REDUCTION_FACTOR = 32; + static const uint NUM_ROOFS = 16; + static const uint COLUMN_WIDTH = 4; + + protected: + QPixmap m_pixRoof[NUM_ROOFS]; + //vector m_roofMem[BAND_COUNT]; + + //Scope m_bands; //copy of the Scope to prevent creating/destroying a Scope every iteration + uint m_lvlMapper[256]; + std::vector m_roofMem; + std::vector barVector; //positions of bars + std::vector roofVector; //positions of roofs + std::vector roofVelocityVector; //speed that roofs falls + + const QPixmap *gradient() const { return &m_pixBarGradient; } + + private: + QPixmap m_pixBarGradient; + QPixmap m_pixCompose; + Scope m_scope; //so we don't create a vector every frame + QColor m_bg; +}; + +#endif diff --git a/src/analyzers/blockanalyzer.cpp b/src/analyzers/blockanalyzer.cpp new file mode 100644 index 000000000..96f458db3 --- /dev/null +++ b/src/analyzers/blockanalyzer.cpp @@ -0,0 +1,401 @@ +// Author: Max Howell , (C) 2003-5 +// Mark Kretschmann , (C) 2005 +// Copyright: See COPYING file that comes with this distribution +// + +#define DEBUG_PREFIX "BlockAnalyzer" + +#include "blockanalyzer.h" + +#include + +#include +#include +#include +#include + +const uint BlockAnalyzer::HEIGHT = 2; +const uint BlockAnalyzer::WIDTH = 4; +const uint BlockAnalyzer::MIN_ROWS = 3; //arbituary +const uint BlockAnalyzer::MIN_COLUMNS = 32; //arbituary +const uint BlockAnalyzer::MAX_COLUMNS = 256; //must be 2**n +const uint BlockAnalyzer::FADE_SIZE = 90; + +BlockAnalyzer::BlockAnalyzer( QWidget *parent ) + : Analyzer::Base( parent, 20, 9 ) + , m_columns( 0 ) //uint + , m_rows( 0 ) //uint + , m_y( 0 ) //uint + , m_barPixmap( 1, 1 ) //null qpixmaps cause crashes + , m_topBarPixmap( WIDTH, HEIGHT ) + , m_scope( MIN_COLUMNS ) //Scope + , m_store( 1 << 8, 0 ) //vector + , m_fade_bars( FADE_SIZE ) //vector + , m_fade_pos( 1 << 8, 50 ) //vector + , m_fade_intensity( 1 << 8, 32 ) //vector +{ + setMinimumSize( MIN_COLUMNS*(WIDTH+1) -1, MIN_ROWS*(HEIGHT+1) -1 ); //-1 is padding, no drawing takes place there + setMaximumWidth( MAX_COLUMNS*(WIDTH+1) -1 ); + + // mxcl says null pixmaps cause crashes, so let's play it safe + for ( uint i = 0; i < FADE_SIZE; ++i ) + m_fade_bars[i] = QPixmap( 1, 1 ); +} + +BlockAnalyzer::~BlockAnalyzer() +{ +} + +void +BlockAnalyzer::resizeEvent( QResizeEvent *e ) +{ + QWidget::resizeEvent( e ); + + m_background = QPixmap(size()); + + const uint oldRows = m_rows; + + //all is explained in analyze().. + //+1 to counter -1 in maxSizes, trust me we need this! + m_columns = qMax( uint(double(width()+1) / (WIDTH+1)), MAX_COLUMNS ); + m_rows = uint(double(height()+1) / (HEIGHT+1)); + + //this is the y-offset for drawing from the top of the widget + m_y = (height() - (m_rows * (HEIGHT+1)) + 2) / 2; + + m_scope.resize( m_columns ); + + if( m_rows != oldRows ) { + m_barPixmap = QPixmap( WIDTH, m_rows*(HEIGHT+1) ); + + for ( uint i = 0; i < FADE_SIZE; ++i ) + m_fade_bars[i] = QPixmap( WIDTH, m_rows*(HEIGHT+1) ); + + m_yscale.resize( m_rows + 1 ); + + const uint PRE = 1, PRO = 1; //PRE and PRO allow us to restrict the range somewhat + + for( uint z = 0; z < m_rows; ++z ) + m_yscale[z] = 1 - (log10( PRE+z ) / log10( PRE+m_rows+PRO )); + + m_yscale[m_rows] = 0; + + determineStep(); + paletteChange( palette() ); + } + + + drawBackground(); +} + +void +BlockAnalyzer::determineStep() +{ + // falltime is dependent on rowcount due to our digital resolution (ie we have boxes/blocks of pixels) + // I calculated the value 30 based on some trial and error + + const double fallTime = 30 * m_rows; + m_step = double(m_rows * timeout()) / fallTime; +} + +void +BlockAnalyzer::transform( Analyzer::Scope &s ) //pure virtual +{ + for( uint x = 0; x < s.size(); ++x ) + s[x] *= 2; + + float *front = static_cast( &s.front() ); + + m_fht->spectrum( front ); + m_fht->scale( front, 1.0 / 20 ); + + //the second half is pretty dull, so only show it if the user has a large analyzer + //by setting to m_scope.size() if large we prevent interpolation of large analyzers, this is good! + s.resize( m_scope.size() <= MAX_COLUMNS/2 ? MAX_COLUMNS/2 : m_scope.size() ); +} + +void +BlockAnalyzer::analyze( QPainter& p, const Analyzer::Scope &s ) +{ + // y = 2 3 2 1 0 2 + // . . . . # . + // . . . # # . + // # . # # # # + // # # # # # # + // + // visual aid for how this analyzer works. + // y represents the number of blanks + // y starts from the top and increases in units of blocks + + // m_yscale looks similar to: { 0.7, 0.5, 0.25, 0.15, 0.1, 0 } + // if it contains 6 elements there are 5 rows in the analyzer + + Analyzer::interpolate( s, m_scope ); + + // Paint the background + p.drawPixmap(0, 0, m_background); + + for( uint y, x = 0; x < m_scope.size(); ++x ) + { + // determine y + for( y = 0; m_scope[x] < m_yscale[y]; ++y ) + ; + + // this is opposite to what you'd think, higher than y + // means the bar is lower than y (physically) + if( (float)y > m_store[x] ) + y = int(m_store[x] += m_step); + else + m_store[x] = y; + + // if y is lower than m_fade_pos, then the bar has exceeded the height of the fadeout + // if the fadeout is quite faded now, then display the new one + if( y <= m_fade_pos[x] /*|| m_fade_intensity[x] < FADE_SIZE / 3*/ ) { + m_fade_pos[x] = y; + m_fade_intensity[x] = FADE_SIZE; + } + + if( m_fade_intensity[x] > 0 ) { + const uint offset = --m_fade_intensity[x]; + const uint y = m_y + (m_fade_pos[x] * (HEIGHT+1)); + p.drawPixmap(x*(WIDTH+1), y, m_fade_bars[offset], 0, 0, WIDTH, height() - y); + } + + if( m_fade_intensity[x] == 0 ) + m_fade_pos[x] = m_rows; + + //REMEMBER: y is a number from 0 to m_rows, 0 means all blocks are glowing, m_rows means none are + p.drawPixmap( x*(WIDTH+1), y*(HEIGHT+1) + m_y, *bar(), 0, y*(HEIGHT+1), bar()->width(), bar()->height() ); + } + + for( uint x = 0; x < m_store.size(); ++x ) + p.drawPixmap(x*(WIDTH+1), int(m_store[x])*(HEIGHT+1) + m_y, m_topBarPixmap ); +} + + + + + +static inline void +adjustToLimits( int &b, int &f, uint &amount ) +{ + // with a range of 0-255 and maximum adjustment of amount, + // maximise the difference between f and b + + if( b < f ) { + if( b > 255 - f ) { + amount -= f; + f = 0; + } else { + amount -= (255 - f); + f = 255; + } + } + else { + if( f > 255 - b ) { + amount -= f; + f = 0; + } else { + amount -= (255 - f); + f = 255; + } + } +} + +/** + * Clever contrast function + * + * It will try to adjust the foreground color such that it contrasts well with the background + * It won't modify the hue of fg unless absolutely necessary + * @return the adjusted form of fg + */ +QColor +ensureContrast( const QColor &bg, const QColor &fg, uint _amount = 150 ) +{ + class OutputOnExit { + public: + OutputOnExit( const QColor &color ) : c( color ) {} + ~OutputOnExit() { int h,s,v; c.getHsv( &h, &s, &v ); } + private: + const QColor &c; + }; + + // hack so I don't have to cast everywhere + #define amount static_cast(_amount) +// #define STAMP debug() << (QValueList() << fh << fs << fv) << endl; +// #define STAMP1( string ) debug() << string << ": " << (QValueList() << fh << fs << fv) << endl; +// #define STAMP2( string, value ) debug() << string << "=" << value << ": " << (QValueList() << fh << fs << fv) << endl; + + OutputOnExit allocateOnTheStack( fg ); + + int bh, bs, bv; + int fh, fs, fv; + + bg.getHsv( &bh, &bs, &bv ); + fg.getHsv( &fh, &fs, &fv ); + + int dv = abs( bv - fv ); + +// STAMP2( "DV", dv ); + + // value is the best measure of contrast + // if there is enough difference in value already, return fg unchanged + if( dv > amount ) + return fg; + + int ds = abs( bs - fs ); + +// STAMP2( "DS", ds ); + + // saturation is good enough too. But not as good. TODO adapt this a little + if( ds > amount ) + return fg; + + int dh = abs( bh - fh ); + +// STAMP2( "DH", dh ); + + if( dh > 120 ) { + // a third of the colour wheel automatically guarentees contrast + // but only if the values are high enough and saturations significant enough + // to allow the colours to be visible and not be shades of grey or black + + // check the saturation for the two colours is sufficient that hue alone can + // provide sufficient contrast + if( ds > amount / 2 && (bs > 125 && fs > 125) ) +// STAMP1( "Sufficient saturation difference, and hues are compliemtary" ); + return fg; + else if( dv > amount / 2 && (bv > 125 && fv > 125) ) +// STAMP1( "Sufficient value difference, and hues are compliemtary" ); + return fg; + +// STAMP1( "Hues are complimentary but we must modify the value or saturation of the contrasting colour" ); + + //but either the colours are two desaturated, or too dark + //so we need to adjust the system, although not as much + ///_amount /= 2; + } + + if( fs < 50 && ds < 40 ) { + // low saturation on a low saturation is sad + const int tmp = 50 - fs; + fs = 50; + if( amount > tmp ) + _amount -= tmp; + else + _amount = 0; + } + + // test that there is available value to honor our contrast requirement + if( 255 - dv < amount ) + { + // we have to modify the value and saturation of fg + //adjustToLimits( bv, fv, amount ); + +// STAMP + + // see if we need to adjust the saturation + if( amount > 0 ) + adjustToLimits( bs, fs, _amount ); + +// STAMP + + // see if we need to adjust the hue + if( amount > 0 ) + fh += amount; // cycles around; + +// STAMP + + return QColor::fromHsv(fh, fs, fv); + } + +// STAMP + + if( fv > bv && bv > amount ) + return QColor::fromHsv( fh, fs, bv - amount); + +// STAMP + + if( fv < bv && fv > amount ) + return QColor::fromHsv( fh, fs, fv - amount); + +// STAMP + + if( fv > bv && (255 - fv > amount) ) + return QColor::fromHsv( fh, fs, fv + amount); + +// STAMP + + if( fv < bv && (255 - bv > amount ) ) + return QColor::fromHsv( fh, fs, bv + amount); + +// STAMP +// debug() << "Something went wrong!\n"; + + return Qt::blue; + + #undef amount +// #undef STAMP +} + +void +BlockAnalyzer::paletteChange( const QPalette& ) //virtual +{ + const QColor bg = palette().color(QPalette::Background); + const QColor fg = ensureContrast( bg, palette().color(QPalette::Highlight) ); + + m_topBarPixmap.fill( fg ); + + const double dr = 15*double(bg.red() - fg.red()) / (m_rows*16); + const double dg = 15*double(bg.green() - fg.green()) / (m_rows*16); + const double db = 15*double(bg.blue() - fg.blue()) / (m_rows*16); + const int r = fg.red(), g = fg.green(), b = fg.blue(); + + bar()->fill( bg ); + + QPainter p( bar() ); + for( int y = 0; (uint)y < m_rows; ++y ) + //graduate the fg color + p.fillRect( 0, y*(HEIGHT+1), WIDTH, HEIGHT, QColor( r+int(dr*y), g+int(dg*y), b+int(db*y) ) ); + + { + const QColor bg = palette().color(QPalette::Background).dark( 112 ); + + //make a complimentary fadebar colour + //TODO dark is not always correct, dumbo! + int h,s,v; palette().color(QPalette::Background).dark( 150 ).getHsv( &h, &s, &v ); + const QColor fg( QColor::fromHsv(h + 120, s, v)); + + const double dr = fg.red() - bg.red(); + const double dg = fg.green() - bg.green(); + const double db = fg.blue() - bg.blue(); + const int r = bg.red(), g = bg.green(), b = bg.blue(); + + // Precalculate all fade-bar pixmaps + for( uint y = 0; y < FADE_SIZE; ++y ) { + m_fade_bars[y].fill( palette().color(QPalette::Background) ); + QPainter f( &m_fade_bars[y] ); + for( int z = 0; (uint)z < m_rows; ++z ) { + const double Y = 1.0 - (log10( FADE_SIZE - y ) / log10( FADE_SIZE )); + f.fillRect( 0, z*(HEIGHT+1), WIDTH, HEIGHT, QColor( r+int(dr*Y), g+int(dg*Y), b+int(db*Y) ) ); + } + } + } + + drawBackground(); +} + +void +BlockAnalyzer::drawBackground() +{ + const QColor bg = palette().color(QPalette::Background); + const QColor bgdark = bg.dark( 112 ); + + m_background.fill( bg ); + + QPainter p( &m_background ); + for( int x = 0; (uint)x < m_columns; ++x ) + for( int y = 0; (uint)y < m_rows; ++y ) + p.fillRect( x*(WIDTH+1), y*(HEIGHT+1) + m_y, WIDTH, HEIGHT, bgdark ); +} + diff --git a/src/analyzers/blockanalyzer.h b/src/analyzers/blockanalyzer.h new file mode 100644 index 000000000..f934960f8 --- /dev/null +++ b/src/analyzers/blockanalyzer.h @@ -0,0 +1,62 @@ +// Maintainer: Max Howell , (C) 2003-5 +// Copyright: See COPYING file that comes with this distribution +// + +#ifndef BLOCKANALYZER_H +#define BLOCKANALYZER_H + +#include "analyzerbase.h" +#include + +class QResizeEvent; +class QMouseEvent; +class QPalette; + + +/** + * @author Max Howell + */ + +class BlockAnalyzer : public Analyzer::Base +{ +public: + BlockAnalyzer( QWidget* ); + ~BlockAnalyzer(); + + static const uint HEIGHT; + static const uint WIDTH; + static const uint MIN_ROWS; + static const uint MIN_COLUMNS; + static const uint MAX_COLUMNS; + static const uint FADE_SIZE; + +protected: + virtual void transform( Scope& ); + virtual void analyze( QPainter& p, const Scope& ); + virtual void resizeEvent( QResizeEvent* ); + virtual void paletteChange( const QPalette& ); + + void drawBackground(); + void determineStep(); + +private: + QPixmap* bar() { return &m_barPixmap; } + + uint m_columns, m_rows; //number of rows and columns of blocks + uint m_y; //y-offset from top of widget + QPixmap m_barPixmap; + QPixmap m_topBarPixmap; + QPixmap m_background; + Scope m_scope; //so we don't create a vector every frame + std::vector m_store; //current bar heights + std::vector m_yscale; + + //FIXME why can't I namespace these? c++ issue? + std::vector m_fade_bars; + std::vector m_fade_pos; + std::vector m_fade_intensity; + + float m_step; //rows to fall per frame +}; + +#endif diff --git a/src/analyzers/boomanalyzer.cpp b/src/analyzers/boomanalyzer.cpp new file mode 100644 index 000000000..1f9d8c719 --- /dev/null +++ b/src/analyzers/boomanalyzer.cpp @@ -0,0 +1,157 @@ +// Author: Max Howell , (C) 2004 +// Copyright: See COPYING file that comes with this distribution + +#include "amarok.h" +#include "boomanalyzer.h" +#include +#include +#include +#include +#include +#include + +BoomAnalyzer::BoomAnalyzer( QWidget *parent ) + : Analyzer::Base2D( parent, 10, 9 ) + , K_barHeight( 1.271 )//1.471 + , F_peakSpeed( 1.103 )//1.122 + , F( 1.0 ) + , bar_height( BAND_COUNT, 0 ) + , peak_height( BAND_COUNT, 0 ) + , peak_speed( BAND_COUNT, 0.01 ) + , barPixmap( COLUMN_WIDTH, 50 ) +{ + QWidget *o, *box = new QWidget( this, 0, WType_TopLevel ); + QSpinBox *m; + int v; + + (new QGridLayout( box, 2, 3 ))->setAutoAdd( true ); + + v = int(K_barHeight*1000); + new QLabel( "Bar fall-rate:", box ); + o = new QSlider( 100, 2000, 100, v, Qt::Horizontal, box ); + (m = new QSpinBox( 100, 2000, 1, box ))->setValue( v ); + connect( o, SIGNAL(valueChanged(int)), SLOT(changeK_barHeight( int )) ); + connect( o, SIGNAL(valueChanged(int)), m, SLOT(setValue( int )) ); + + v = int(F_peakSpeed*1000); + new QLabel( "Peak acceleration: ", box ); + o = new QSlider( 1000, 1300, 50, v, Qt::Horizontal, box ); + (m = new QSpinBox( 1000, 1300, 1, box ))->setValue( v ); + connect( o, SIGNAL(valueChanged(int)), SLOT(changeF_peakSpeed( int )) ); + connect( o, SIGNAL(valueChanged(int)), m, SLOT(setValue( int )) ); + + //box->show(); +} + + +void +BoomAnalyzer::changeK_barHeight( int newValue ) +{ + K_barHeight = (double)newValue / 1000; +} + +void +BoomAnalyzer::changeF_peakSpeed( int newValue ) +{ + F_peakSpeed = (double)newValue / 1000; +} + +void +BoomAnalyzer::init() +{ + const uint HEIGHT = height() - 2; + const double h = 1.2 / HEIGHT; + + F = double(HEIGHT) / (log10( 256 ) * 1.1 /*<- max. amplitude*/); + + barPixmap.resize( COLUMN_WIDTH-2, HEIGHT ); + + QPainter p( &barPixmap ); + for( uint y = 0; y < HEIGHT; ++y ) + { + const double F = (double)y * h; + + p.setPen( QColor( 255 - int(229.0 * F), 255 - int(229.0 * F), 255 - int(191.0 * F) ) ); + p.drawLine( 0, y, COLUMN_WIDTH-2, y ); + } +} + +void +BoomAnalyzer::transform( Scope &s ) +{ + float *front = static_cast( &s.front() ); + + m_fht->spectrum( front ); + m_fht->scale( front, 1.0 / 60 ); + + Scope scope( 32, 0 ); + + const uint xscale[] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,24,29,36,43,52,63,76,91,108,129,153,182,216,255 }; + + for( uint j, i = 0; i < 32; i++ ) + for( j = xscale[i]; j < xscale[i + 1]; j++ ) + if ( s[j] > scope[i] ) + scope[i] = s[j]; + + s = scope; +} + +void +BoomAnalyzer::analyze( const Scope &scope ) +{ + eraseCanvas(); + + QPainter p( canvas() ); + float h; + const uint MAX_HEIGHT = height() - 1; + + for( uint i = 0, x = 0, y; i < BAND_COUNT; ++i, x += COLUMN_WIDTH+1 ) + { + h = log10( scope[i]*256.0 ) * F; + + if( h > MAX_HEIGHT ) + h = MAX_HEIGHT; + + if( h > bar_height[i] ) + { + bar_height[i] = h; + + if( h > peak_height[i] ) + { + peak_height[i] = h; + peak_speed[i] = 0.01; + } + else goto peak_handling; + } + else + { + if( bar_height[i] > 0.0 ) + { + bar_height[i] -= K_barHeight; //1.4 + if( bar_height[i] < 0.0 ) bar_height[i] = 0.0; + } + + peak_handling: + + if( peak_height[i] > 0.0 ) + { + peak_height[i] -= peak_speed[i]; + peak_speed[i] *= F_peakSpeed; //1.12 + + if( peak_height[i] < bar_height[i] ) peak_height[i] = bar_height[i]; + if( peak_height[i] < 0.0 ) peak_height[i] = 0.0; + } + } + + y = height() - uint(bar_height[i]); + bitBlt( canvas(), x+1, y, &barPixmap, 0, y ); + p.setPen( Amarok::ColorScheme::Foreground ); + p.drawRect( x, y, COLUMN_WIDTH, height() - y ); + + y = height() - uint(peak_height[i]); + p.setPen( Amarok::ColorScheme::Text ); + p.drawLine( x, y, x+COLUMN_WIDTH-1, y ); + } +} + +#include "boomanalyzer.moc" diff --git a/src/analyzers/boomanalyzer.h b/src/analyzers/boomanalyzer.h new file mode 100644 index 000000000..55c5ec3a4 --- /dev/null +++ b/src/analyzers/boomanalyzer.h @@ -0,0 +1,52 @@ +// Author: Max Howell , (C) 2004 +// Copyright: See COPYING file that comes with this distribution +// + +#ifndef BOOMANALYZER_H +#define BOOMANALYZER_H + +#include "analyzerbase.h" + +/** +@author Max Howell +*/ + +class BoomAnalyzer : public Analyzer::Base2D +{ +Q_OBJECT +public: + BoomAnalyzer( QWidget* ); + + virtual void init(); + virtual void transform( Scope &s ); + virtual void analyze( const Scope& ); + +public slots: + void changeK_barHeight( int ); + void changeF_peakSpeed( int ); + +protected: + static const uint COLUMN_WIDTH = 4; + static const uint BAND_COUNT = 32; + + double K_barHeight, F_peakSpeed, F; + + std::vector bar_height; + std::vector peak_height; + std::vector peak_speed; + + QPixmap barPixmap; +}; + +namespace Amarok +{ + namespace ColorScheme + { + extern QColor Base; + extern QColor Text; + extern QColor Background; + extern QColor Foreground; + } +} + +#endif diff --git a/src/analyzers/glanalyzer.cpp b/src/analyzers/glanalyzer.cpp new file mode 100644 index 000000000..ec8a6bc4f --- /dev/null +++ b/src/analyzers/glanalyzer.cpp @@ -0,0 +1,342 @@ +/*************************************************************************** + gloscope.cpp - description + ------------------- + begin : Jan 17 2004 + copyright : (C) 2004 by Adam Pigg + email : adam@piggz.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include + +#ifdef HAVE_QGLWIDGET + +#include +#include "glanalyzer.h" +#include + + +GLAnalyzer::GLAnalyzer( QWidget *parent ) + : Analyzer::Base3D(parent, 15) + , m_oldy(32, -10.0f) + , m_peaks(32) +{} + +GLAnalyzer::~GLAnalyzer() +{} + +// METHODS ===================================================== + +void GLAnalyzer::analyze( const Scope &s ) +{ + //kdDebug() << "Scope Size: " << s.size() << endl; + /* Scope t(32); + if (s.size() != 32) + { + Analyzer::interpolate(s, t); + } + else + { + t = s; + }*/ + uint offset = 0; + static float peak; + float mfactor = 0.0; + static int drawcount; + + if (s.size() == 64) + { + offset=8; + } + + glRotatef(0.25f, 0.0f, 1.0f, 0.5f); //Rotate the scene + drawFloor(); + drawcount++; + if (drawcount > 25) + { + drawcount = 0; + peak = 0.0; + } + + for ( uint i = 0; i < 32; i++ ) + { + if (s[i] > peak) + { + peak = s[i]; + } + } + + mfactor = 20 / peak; + for ( uint i = 0; i < 32; i++ ) + { + + //kdDebug() << "Scope item " << i << " value: " << s[i] << endl; + + // Calculate new horizontal position (x) depending on number of samples + x = -16.0f + i; + + // Calculating new vertical position (y) depending on the data passed by amarok + y = float(s[i+offset] * mfactor); //This make it kinda dynamically resize depending on the data + + //Some basic bounds checking + if (y > 30) + y = 30; + else if (y < 0) + y = 0; + + if((y - m_oldy[i]) < -0.6f) // Going Down Too Much + { + y = m_oldy[i] - 0.7f; + } + if (y < 0.0f) + { + y = 0.0f; + } + + m_oldy[i] = y; //Save value as last value + + //Peak Code + if (m_oldy[i] > m_peaks[i].level) + { + m_peaks[i].level = m_oldy[i]; + m_peaks[i].delay = 30; + } + + if (m_peaks[i].delay > 0) + { + m_peaks[i].delay--; + } + + if (m_peaks[i].level > 1.0f) + { + if (m_peaks[i].delay <= 0) + { + m_peaks[i].level-=0.4f; + } + } + // Draw the bar + drawBar(x,y); + drawPeak(x, m_peaks[i].level); + + } + + updateGL(); +} + +void GLAnalyzer::initializeGL() +{ + // Clear frame (next fading will be preferred to clearing) + glClearColor(0.0f, 0.0f, 0.0f, 1.0f);// Set clear color to black + glClear( GL_COLOR_BUFFER_BIT ); + + // Set the shading model + glShadeModel(GL_SMOOTH); + + // Set the polygon mode to fill + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + // Enable depth testing for hidden line removal + glEnable(GL_DEPTH_TEST); + + // Set blend parameters for 'composting alpha' + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); +} + +void GLAnalyzer::resizeGL( int w, int h ) +{ + glViewport( 0, 0, (GLint)w, (GLint)h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho(-16.0f, 16.0f, -10.0f, 10.0f, -50.0f, 100.0f); + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); +} + +void GLAnalyzer::paintGL() +{ + glMatrixMode( GL_MODELVIEW ); +#if 0 + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); +#else + glEnable( GL_DEPTH_TEST ); + glEnable( GL_BLEND ); + glPushMatrix(); + glLoadIdentity(); + glBegin( GL_TRIANGLE_STRIP ); + glColor4f( 0.0f, 0.0f, 0.1f, 0.08f ); + glVertex2f( 20.0f, 10.0f ); + glVertex2f( -20.0f, 10.0f ); + glVertex2f( 20.0f, -10.0f ); + glVertex2f( -20.0f, -10.0f ); + glEnd(); + glPopMatrix(); + glDisable( GL_BLEND ); + glEnable( GL_DEPTH_TEST ); + glClear( GL_DEPTH_BUFFER_BIT ); +#endif + //swapBuffers(); + + glFlush(); + +} + +void GLAnalyzer::drawBar(float xPos, float height) +{ + glPushMatrix(); + + //Sets color to blue + //Set the colour depending on the height of the bar + glColor3f((height/40) + 0.5f, (height/40) + 0.625f, 1.0f); + glTranslatef(xPos, -10.0f, 0.0f); + + glScalef(1.0f, height, 3.0f); + drawCube(); + + //Set colour to full blue + //glColor3f(0.0f, 0.0f, 1.0f); + //drawFrame(); + glPopMatrix(); +} + +void GLAnalyzer::drawFloor() +{ + glPushMatrix(); + + //Sets color to amarok blue + glColor3f( 0.5f, 0.625f, 1.0f); + glTranslatef(-16.0f,-11.0f, -4.0f); + + glScalef(32.0f, 1.0f, 10.0f); + drawCube(); + + //Set colour to full blue + glColor3f(0.0f, 0.0f, 1.0f); + drawFrame(); + glPopMatrix(); +} + +void GLAnalyzer::drawPeak(float xPos, float ypos) +{ + glPushMatrix(); + + //Set the colour to red + glColor3f(1.0f, 0.0f, 0.0f); + glTranslatef(xPos, ypos - 10.0f, 0.0f); + + glScalef(1.0f, 1.0f, 3.0f); + drawCube(); + + glPopMatrix(); +} + +void GLAnalyzer::drawCube() +{ + glPushMatrix(); + glBegin(GL_POLYGON); + + //This is the top face + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + + //This is the front face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the right face + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + + //This is the left face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the bottom face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the back face + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + + glEnd(); + glPopMatrix(); +} +void GLAnalyzer::drawFrame() +{ + glPushMatrix(); + glBegin(GL_LINES); + + + //This is the top face + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + + //This is the front face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the right face + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + + //This is the left face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 0.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the bottom face + glVertex3f(0.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 0.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 0.0f); + + //This is the back face + glVertex3f(0.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 0.0f, 1.0f); + glVertex3f(1.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 1.0f, 1.0f); + glVertex3f(0.0f, 0.0f, 1.0f); + + glEnd(); + glPopMatrix(); +} + +#endif diff --git a/src/analyzers/glanalyzer.h b/src/analyzers/glanalyzer.h new file mode 100644 index 000000000..394c46384 --- /dev/null +++ b/src/analyzers/glanalyzer.h @@ -0,0 +1,62 @@ +/*************************************************************************** + gloscope.h - description + ------------------- + begin : Jan 17 2004 + copyright : (C) 2004 by Adam Pigg + email : adam@piggz.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef GLOSCOPE_H +#define GLOSCOPE_H + +#include +#ifdef HAVE_QGLWIDGET + +#include "analyzerbase.h" + +/** + *@author piggz + */ + +typedef struct +{ + float level; + uint delay; +} +peak_tx; + +class GLAnalyzer : public Analyzer::Base3D +{ +private: + std::vector m_oldy; + std::vector m_peaks; + + void drawCube(); + void drawFrame(); + void drawBar(float xPos, float height); + void drawPeak(float xPos, float ypos); + void drawFloor(); + + GLfloat x, y; +public: + GLAnalyzer(QWidget *); + ~GLAnalyzer(); + void analyze( const Scope & ); + +protected: + void initializeGL(); + void resizeGL( int w, int h ); + void paintGL(); +}; + +#endif +#endif diff --git a/src/analyzers/glanalyzer2.cpp b/src/analyzers/glanalyzer2.cpp new file mode 100644 index 000000000..6f3d1c83a --- /dev/null +++ b/src/analyzers/glanalyzer2.cpp @@ -0,0 +1,333 @@ +/*************************************************************************** + glanalyzer2.cpp - description + ------------------- + begin : Feb 16 2004 + copyright : (C) 2004 by Enrico Ros + email : eros.kde@email.it + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include + +#ifdef HAVE_QGLWIDGET + +#include +#include +#include "glanalyzer2.h" +#include +#include +#include +#include + + +GLAnalyzer2::GLAnalyzer2( QWidget *parent ): +Analyzer::Base3D(parent, 15) +{ + //initialize openGL context before managing GL calls + makeCurrent(); + loadTexture( locate("data","amarok/data/dot.png"), dotTexture ); + loadTexture( locate("data","amarok/data/wirl1.png"), w1Texture ); + loadTexture( locate("data","amarok/data/wirl2.png"), w2Texture ); + + show.paused = true; + show.pauseTimer = 0.0; + show.rotDegrees = 0.0; + frame.rotDegrees = 0.0; +} + +GLAnalyzer2::~GLAnalyzer2() +{ + freeTexture( dotTexture ); + freeTexture( w1Texture ); + freeTexture( w2Texture ); +} + +void GLAnalyzer2::initializeGL() +{ + // Set a smooth shade model + glShadeModel(GL_SMOOTH); + + // Disable depth test (all is drawn on a 2d plane) + glDisable(GL_DEPTH_TEST); + + // Set blend parameters for 'composting alpha' + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); //superpose + //glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); //fade + glEnable( GL_BLEND ); + + // Clear frame with a black background + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear( GL_COLOR_BUFFER_BIT ); +} + +void GLAnalyzer2::resizeGL( int w, int h ) +{ + // Setup screen. We're going to manually do the perspective projection + glViewport( 0, 0, (GLint)w, (GLint)h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glOrtho( -10.0f, 10.0f, -10.0f, 10.0f, -5.0f, 5.0f ); + + // Get the aspect ratio of the screen to draw 'cicular' particles + float ratio = (float)w / (float)h, + eqPixH = 60, + eqPixW = 80; + if ( ratio >= (4.0/3.0) ) { + unitX = 10.0 / (eqPixH * ratio); + unitY = 10.0 / eqPixH; + } else { + unitX = 10.0 / eqPixW; + unitY = 10.0 / (eqPixW / ratio); + } + + // Get current timestamp. + timeval tv; + gettimeofday( &tv, NULL ); + show.timeStamp = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0; +} + +void GLAnalyzer2::paused() +{ + analyze( Scope() ); +} + +void GLAnalyzer2::analyze( const Scope &s ) +{ + bool haveNoData = s.empty(); + + // if we're going into pause mode, clear timers. + if ( !show.paused && haveNoData ) + show.pauseTimer = 0.0; + + // if we have got data, interpolate it (asking myself why I'm doing it here..) + if ( !(show.paused = haveNoData) ) + { + int bands = s.size(), + lowbands = bands / 4, + hibands = bands / 3, + midbands = bands - lowbands - hibands; Q_UNUSED( midbands ); + float currentEnergy = 0, + currentMeanBand = 0, + maxValue = 0; + for ( int i = 0; i < bands; i++ ) + { + float value = s[i]; + currentEnergy += value; + currentMeanBand += (float)i * value; + if ( value > maxValue ) + maxValue = value; + } + frame.silence = currentEnergy < 0.001; + if ( !frame.silence ) + { + frame.meanBand = 100.0 * currentMeanBand / (currentEnergy * bands); + currentEnergy = 100.0 * currentEnergy / (float)bands; + frame.dEnergy = currentEnergy - frame.energy; + frame.energy = currentEnergy; +// printf( "%d [%f :: %f ]\t%f \n", bands, frame.energy, frame.meanBand, maxValue ); + } else + frame.energy = 0.0; + } + + // update the frame + updateGL(); +} + +void GLAnalyzer2::paintGL() +{ + // Compute the dT since the last call to paintGL and update timings + timeval tv; + gettimeofday( &tv, NULL ); + double currentTime = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0; + show.dT = currentTime - show.timeStamp; + show.timeStamp = currentTime; + + // Clear frame + glClear( GL_COLOR_BUFFER_BIT ); + + // Shitch to MODEL matrix and reset it to default + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + + // Fade the previous drawings. +/* glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glBegin( GL_TRIANGLE_STRIP ); + glColor4f( 0.0f, 0.0f, 0.0f, 0.2f ); + glVertex2f( 10.0f, 10.0f ); + glVertex2f( -10.0f, 10.0f ); + glVertex2f( 10.0f, -10.0f ); + glVertex2f( -10.0f, -10.0f ); + glEnd();*/ + + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + glEnable( GL_TEXTURE_2D ); + float alphaN = show.paused ? 0.2 : (frame.energy / 10.0), + alphaP = show.paused ? 1.0 : (1 - frame.energy / 20.0); + if ( alphaN > 1.0 ) + alphaN = 1.0; + if ( alphaP < 0.1 ) + alphaP = 0.1; + glBindTexture( GL_TEXTURE_2D, w2Texture ); + setTextureMatrix( show.rotDegrees, 0.707*alphaP ); + glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2f( 1.0, 1.0 ); + glVertex2f( 10.0f, 10.0f ); + glTexCoord2f( 0.0, 1.0 ); + glVertex2f( -10.0f, 10.0f ); + glTexCoord2f( 1.0, 0.0 ); + glVertex2f( 10.0f, -10.0f ); + glTexCoord2f( 0.0 , 0.0 ); + glVertex2f( -10.0f, -10.0f ); + glEnd(); + glBindTexture( GL_TEXTURE_2D, w1Texture ); + setTextureMatrix( -show.rotDegrees * 2, 0.707 ); + glColor4f( 1.0f, 1.0f, 1.0f, alphaN ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2f( 1.0, 1.0 ); + glVertex2f( 10.0f, 10.0f ); + glTexCoord2f( 0.0, 1.0 ); + glVertex2f( -10.0f, 10.0f ); + glTexCoord2f( 1.0, 0.0 ); + glVertex2f( 10.0f, -10.0f ); + glTexCoord2f( 0.0 , 0.0 ); + glVertex2f( -10.0f, -10.0f ); + glEnd(); + setTextureMatrix( 0.0, 0.0 ); + glDisable( GL_TEXTURE_2D ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + + // Here begins the real draw loop + // some updates to the show + show.rotDegrees += 40.0 * show.dT; + frame.rotDegrees += 80.0 * show.dT; + + // handle the 'pause' status + if ( show.paused ) + { + if ( show.pauseTimer > 0.5 ) + { + if ( show.pauseTimer > 0.6 ) + show.pauseTimer -= 0.6; + drawFullDot( 0.0f, 0.4f, 0.8f, 1.0f ); + drawFullDot( 0.0f, 0.4f, 0.8f, 1.0f ); + } + show.pauseTimer += show.dT; + return; + } + + if ( dotTexture ) { + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, dotTexture ); + } else + glDisable( GL_TEXTURE_2D ); + + glLoadIdentity(); +// glRotatef( -frame.rotDegrees, 0,0,1 ); + glBegin( GL_QUADS ); +// Particle * particle = particleList.first(); +// for (; particle; particle = particleList.next()) + { + glColor4f( 0.0f, 1.0f, 0.0f, 1.0f ); + drawDot( 0, 0, kMax(10.0,(10.0 * frame.energy)) ); + glColor4f( 1.0f, 0.0f, 0.0f, 1.0f ); + drawDot( 6, 0, kMax(10.0, (5.0 * frame.energy)) ); + glColor4f( 0.0f, 0.4f, 1.0f, 1.0f ); + drawDot( -6, 0, kMax(10.0, (5.0 * frame.energy)) ); + } + glEnd(); +} + +void GLAnalyzer2::drawDot( float x, float y, float size ) +{ + float sizeX = size * unitX, + sizeY = size * unitY, + pLeft = x - sizeX, + pTop = y + sizeY, + pRight = x + sizeX, + pBottom = y - sizeY; + glTexCoord2f( 0, 0 ); // Bottom Left + glVertex2f( pLeft, pBottom ); + glTexCoord2f( 0, 1 ); // Top Left + glVertex2f( pLeft, pTop ); + glTexCoord2f( 1, 1 ); // Top Right + glVertex2f( pRight, pTop ); + glTexCoord2f( 1, 0 ); // Bottom Right + glVertex2f( pRight, pBottom ); +} + +void GLAnalyzer2::drawFullDot( float r, float g, float b, float a ) +{ + glBindTexture( GL_TEXTURE_2D, dotTexture ); + glEnable( GL_TEXTURE_2D ); + glColor4f( r, g, b, a ); + glBegin( GL_TRIANGLE_STRIP ); + glTexCoord2f( 1.0, 1.0 ); + glVertex2f( 10.0f, 10.0f ); + glTexCoord2f( 0.0, 1.0 ); + glVertex2f( -10.0f, 10.0f ); + glTexCoord2f( 1.0, 0.0 ); + glVertex2f( 10.0f, -10.0f ); + glTexCoord2f( 0.0 , 0.0 ); + glVertex2f( -10.0f, -10.0f ); + glEnd(); + glDisable( GL_TEXTURE_2D ); +} + + +void GLAnalyzer2::setTextureMatrix( float rot, float scale ) +{ + glMatrixMode( GL_TEXTURE); + glLoadIdentity(); + if ( rot != 0.0 || scale != 0.0 ) + { + glTranslatef( 0.5f, 0.5f, 0.0f ); + glRotatef( rot, 0.0f, 0.0f, 1.0f ); + glScalef( scale, scale, 1.0f ); + glTranslatef( -0.5f, -0.5f, 0.0f ); + } + glMatrixMode( GL_MODELVIEW ); +} + +bool GLAnalyzer2::loadTexture( QString fileName, GLuint& textureID ) +{ + //reset texture ID to the default EMPTY value + textureID = 0; + + //load image + QImage tmp; + if ( !tmp.load( fileName ) ) + return false; + + //convert it to suitable format (flipped RGBA) + QImage texture = QGLWidget::convertToGLFormat( tmp ); + if ( texture.isNull() ) + return false; + + //get texture number and bind loaded image to that texture + glGenTextures( 1, &textureID ); + glBindTexture( GL_TEXTURE_2D, textureID ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, 4, texture.width(), texture.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.bits() ); + return true; +} + + +void GLAnalyzer2::freeTexture( GLuint & textureID ) +{ + if ( textureID > 0 ) + glDeleteTextures( 1, &textureID ); + textureID = 0; +} + +#endif diff --git a/src/analyzers/glanalyzer2.h b/src/analyzers/glanalyzer2.h new file mode 100644 index 000000000..3aeb98ae6 --- /dev/null +++ b/src/analyzers/glanalyzer2.h @@ -0,0 +1,73 @@ +/*************************************************************************** + glanalyzer2.h - description + ------------------- + begin : Feb 16 2004 + copyright : (C) 2004 by Enrico Ros + email : eros.kde@email.it + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef GLSTARVIEW_H +#define GLSTARVIEW_H + +#include +#ifdef HAVE_QGLWIDGET + +#include "analyzerbase.h" +#include +#include + + +class GLAnalyzer2 : public Analyzer::Base3D +{ +public: + GLAnalyzer2(QWidget *); + ~GLAnalyzer2(); + void analyze( const Scope & ); + void paused(); + +protected: + void initializeGL(); + void resizeGL( int w, int h ); + void paintGL(); + +private: + struct ShowProperties { + bool paused; + double timeStamp; + double dT; + double pauseTimer; + float rotDegrees; + } show; + + struct FrameProperties { + float energy; + float dEnergy; + float meanBand; + float rotDegrees; + bool silence; + } frame; + + GLuint dotTexture; + GLuint w1Texture; + GLuint w2Texture; + float unitX, unitY; + + void drawDot( float x, float y, float size ); + void drawFullDot( float r, float g, float b, float a ); + void setTextureMatrix( float rot, float scale ); + + bool loadTexture(QString file, GLuint& textureID); + void freeTexture(GLuint& textureID); +}; + +#endif +#endif diff --git a/src/analyzers/glanalyzer3.cpp b/src/analyzers/glanalyzer3.cpp new file mode 100644 index 000000000..cc7ce4c7f --- /dev/null +++ b/src/analyzers/glanalyzer3.cpp @@ -0,0 +1,480 @@ +/*************************************************************************** + glanalyzer3.cpp - Bouncing Ballzz + ------------------- + begin : Feb 19 2004 + copyright : (C) 2004 by Enrico Ros + email : eros.kde@email.it + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include + +#ifdef HAVE_QGLWIDGET + +#include +#include +#include "glanalyzer3.h" +#include +#include +#include +#include + +#ifndef HAVE_FABSF +inline float fabsf(float f) +{ + return f < 0.f ? -f : f; +} +#endif + + +class Ball +{ + public: + Ball() : x( drand48() - drand48() ), y( 1 - 2.0 * drand48() ), + z( drand48() ), vx( 0.0 ), vy( 0.0 ), vz( 0.0 ), + mass( 0.01 + drand48()/10.0 ) + //,color( (float[3]) { 0.0, drand48()*0.5, 0.7 + drand48() * 0.3 } ) + { + //this is because GCC < 3.3 can't compile the above line, we aren't sure why though + color[0] = 0.0; color[1] = drand48()*0.5; color[2] = 0.7 + drand48() * 0.3; + }; + + float x, y, z, vx, vy, vz, mass; + float color[3]; + + void updatePhysics( float dT ) + { + x += vx * dT; // position + y += vy * dT; // position + z += vz * dT; // position + if ( y < -0.8 ) vy = fabsf( vy ); + if ( y > 0.8 ) vy = -fabsf( vy ); + if ( z < 0.1 ) vz = fabsf( vz ); + if ( z > 0.9 ) vz = -fabsf( vz ); + vx += (( x > 0 ) ? 4.94 : -4.94) * dT; // G-force + vx *= (1 - 2.9 * dT); // air friction + vy *= (1 - 2.9 * dT); // air friction + vz *= (1 - 2.9 * dT); // air friction + } +}; + +class Paddle +{ + public: + Paddle( float xPos ) : onLeft( xPos < 0 ), mass( 1.0 ), + X( xPos ), x( xPos ), vx( 0.0 ) {}; + + void updatePhysics( float dT ) + { + x += vx * dT; // posision + vx += (1300 * (X - x) / mass) * dT; // elasticity + vx *= (1 - 4.0 * dT); // air friction + } + + void renderGL() + { + glBegin( GL_TRIANGLE_STRIP ); + glColor3f( 0.0f, 0.1f, 0.3f ); + glVertex3f( x, -1.0f, 0.0 ); + glVertex3f( x, 1.0f, 0.0 ); + glColor3f( 0.1f, 0.2f, 0.6f ); + glVertex3f( x, -1.0f, 1.0 ); + glVertex3f( x, 1.0f, 1.0 ); + glEnd(); + } + + void bounce( Ball * ball ) + { + if ( onLeft && ball->x < x ) + { + ball->vx = vx * mass / (mass + ball->mass) + fabsf( ball->vx ); + ball->vy = (drand48() - drand48()) * 1.8; + ball->vz = (drand48() - drand48()) * 0.9; + ball->x = x; + } + else if ( !onLeft && ball->x > x ) + { + ball->vx = vx * mass / (mass + ball->mass) - fabsf( ball->vx ); + ball->vy = (drand48() - drand48()) * 1.8; + ball->vz = (drand48() - drand48()) * 0.9; + ball->x = x; + } + } + + void impulse( float strength ) + { + if ( (onLeft && strength > vx) || (!onLeft && strength < vx) ) + vx += strength; + } + + private: + bool onLeft; + float mass, X, x, vx; +}; + + +GLAnalyzer3::GLAnalyzer3( QWidget *parent ): +Analyzer::Base3D(parent, 15) +{ + //initialize openGL context before managing GL calls + makeCurrent(); + loadTexture( locate("data","amarok/data/ball.png"), ballTexture ); + loadTexture( locate("data","amarok/data/grid.png"), gridTexture ); + + balls.setAutoDelete( true ); + leftPaddle = new Paddle( -1.0 ); + rightPaddle = new Paddle( 1.0 ); + for ( int i = 0; i < NUMBER_OF_BALLS; i++ ) + balls.append( new Ball() ); + + show.colorK = 0.0; + show.gridScrollK = 0.0; + show.gridEnergyK = 0.0; + show.camRot = 0.0; + show.camRoll = 0.0; + show.peakEnergy = 1.0; + frame.silence = true; + frame.energy = 0.0; + frame.dEnergy = 0.0; +} + +GLAnalyzer3::~GLAnalyzer3() +{ + freeTexture( ballTexture ); + freeTexture( gridTexture ); + delete leftPaddle; + delete rightPaddle; + balls.clear(); +} + +void GLAnalyzer3::initializeGL() +{ + // Set a smooth shade model + glShadeModel(GL_SMOOTH); + + // Disable depth test (all is drawn 'z-sorted') + glDisable( GL_DEPTH_TEST ); + + // Set blending function (Alpha addition) + glBlendFunc( GL_SRC_ALPHA, GL_ONE ); + + // Clear frame with a black background + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); +} + +void GLAnalyzer3::resizeGL( int w, int h ) +{ + // Setup screen. We're going to manually do the perspective projection + glViewport( 0, 0, (GLint)w, (GLint)h ); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + glFrustum( -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 4.5f ); + + // Get the aspect ratio of the screen to draw 'circular' particles + float ratio = (float)w / (float)h; + if ( ratio >= 1.0 ) { + unitX = 0.34 / ratio; + unitY = 0.34; + } else { + unitX = 0.34; + unitY = 0.34 * ratio; + } + + // Get current timestamp. + timeval tv; + gettimeofday( &tv, NULL ); + show.timeStamp = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0; +} + +void GLAnalyzer3::paused() +{ + analyze( Scope() ); +} + +void GLAnalyzer3::analyze( const Scope &s ) +{ + // compute the dTime since the last call + timeval tv; + gettimeofday( &tv, NULL ); + double currentTime = (double)tv.tv_sec + (double)tv.tv_usec/1000000.0; + show.dT = currentTime - show.timeStamp; + show.timeStamp = currentTime; + + // compute energy integrating frame's spectrum + if ( !s.empty() ) + { + int bands = s.size(); + float currentEnergy = 0, + maxValue = 0; + // integrate spectrum -> energy + for ( int i = 0; i < bands; i++ ) + { + float value = s[i]; + currentEnergy += value; + if ( value > maxValue ) + maxValue = value; + } + currentEnergy *= 100.0 / (float)bands; + // emulate a peak detector: currentEnergy -> peakEnergy (3tau = 30 seconds) + show.peakEnergy = 1.0 + ( show.peakEnergy - 1.0 ) * exp( - show.dT / 10.0 ); + if ( currentEnergy > show.peakEnergy ) + show.peakEnergy = currentEnergy; + // check for silence + frame.silence = currentEnergy < 0.001; + // normalize frame energy against peak energy and compute frame stats + currentEnergy /= show.peakEnergy; + frame.dEnergy = currentEnergy - frame.energy; + frame.energy = currentEnergy; + } else + frame.silence = true; + + // update the frame + updateGL(); +} + +void GLAnalyzer3::paintGL() +{ + // limit max dT to 0.05 and update color and scroll constants + if ( show.dT > 0.05 ) + show.dT = 0.05; + show.colorK += show.dT * 0.4; + if ( show.colorK > 3.0 ) + show.colorK -= 3.0; + show.gridScrollK += 0.2 * show.peakEnergy * show.dT; + + // Switch to MODEL matrix and clear screen + glMatrixMode( GL_MODELVIEW ); + glLoadIdentity(); + glClear( GL_COLOR_BUFFER_BIT ); + + // Draw scrolling grid + if ( (show.gridEnergyK > 0.05) || (!frame.silence && frame.dEnergy < -0.3) ) + { + show.gridEnergyK *= exp( -show.dT / 0.1 ); + if ( -frame.dEnergy > show.gridEnergyK ) + show.gridEnergyK = -frame.dEnergy*2.0; + float gridColor[4] = { 0.0, 1.0, 0.6, show.gridEnergyK }; + drawScrollGrid( show.gridScrollK, gridColor ); + } + + // Roll camera up/down handling the beat + show.camRot += show.camRoll * show.dT; // posision + show.camRoll -= 400 * show.camRot * show.dT; // elasticity + show.camRoll *= (1 - 2.0 * show.dT); // friction + if ( !frame.silence && frame.dEnergy > 0.4 ) + show.camRoll += show.peakEnergy*2.0; + glRotatef( show.camRoll / 2.0, 1,0,0 ); + + // Translate the drawing plane + glTranslatef( 0.0f, 0.0f, -1.8f ); + + // Draw upper/lower planes and paddles + drawHFace( -1.0 ); + drawHFace( 1.0 ); + leftPaddle->renderGL(); + rightPaddle->renderGL(); + + // Draw Balls + if ( ballTexture ) { + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, ballTexture ); + } else + glDisable( GL_TEXTURE_2D ); + glEnable( GL_BLEND ); + Ball * ball = balls.first(); + for ( ; ball; ball = balls.next() ) + { + float color[3], + angle = show.colorK; + // Rotate the color based on 'angle' value [0,3) + if ( angle < 1.0 ) + { + color[ 0 ] = ball->color[ 0 ] * (1 - angle) + ball->color[ 1 ] * angle; + color[ 1 ] = ball->color[ 1 ] * (1 - angle) + ball->color[ 2 ] * angle; + color[ 2 ] = ball->color[ 2 ] * (1 - angle) + ball->color[ 0 ] * angle; + } + else if ( angle < 2.0 ) + { + angle -= 1.0; + color[ 0 ] = ball->color[ 1 ] * (1 - angle) + ball->color[ 2 ] * angle; + color[ 1 ] = ball->color[ 2 ] * (1 - angle) + ball->color[ 0 ] * angle; + color[ 2 ] = ball->color[ 0 ] * (1 - angle) + ball->color[ 1 ] * angle; + } + else + { + angle -= 2.0; + color[ 0 ] = ball->color[ 2 ] * (1 - angle) + ball->color[ 0 ] * angle; + color[ 1 ] = ball->color[ 0 ] * (1 - angle) + ball->color[ 1 ] * angle; + color[ 2 ] = ball->color[ 1 ] * (1 - angle) + ball->color[ 2 ] * angle; + } + // Draw the dot and update its physics also checking at bounces + glColor3fv( color ); + drawDot3s( ball->x, ball->y, ball->z, 1.0 ); + ball->updatePhysics( show.dT ); + if ( ball->x < 0 ) + leftPaddle->bounce( ball ); + else + rightPaddle->bounce( ball ); + } + glDisable( GL_BLEND ); + glDisable( GL_TEXTURE_2D ); + + // Update physics of paddles + leftPaddle->updatePhysics( show.dT ); + rightPaddle->updatePhysics( show.dT ); + if ( !frame.silence ) + { + leftPaddle->impulse( frame.energy*3.0 + frame.dEnergy*6.0 ); + rightPaddle->impulse( -frame.energy*3.0 - frame.dEnergy*6.0 ); + } +} + +void GLAnalyzer3::drawDot3s( float x, float y, float z, float size ) +{ + // Circular XY dot drawing functions + float sizeX = size * unitX, + sizeY = size * unitY, + pXm = x - sizeX, + pXM = x + sizeX, + pYm = y - sizeY, + pYM = y + sizeY; + // Draw the Dot + glBegin( GL_QUADS ); + glTexCoord2f( 0, 0 ); // Bottom Left + glVertex3f( pXm, pYm, z ); + glTexCoord2f( 0, 1 ); // Top Left + glVertex3f( pXm, pYM, z ); + glTexCoord2f( 1, 1 ); // Top Right + glVertex3f( pXM, pYM, z ); + glTexCoord2f( 1, 0 ); // Bottom Right + glVertex3f( pXM, pYm, z ); + glEnd(); + + // Shadow XZ drawing functions + float sizeZ = size / 10.0, + pZm = z - sizeZ, + pZM = z + sizeZ, + currentColor[4]; + glGetFloatv( GL_CURRENT_COLOR, currentColor ); + float alpha = currentColor[3], + topSide = (y + 1) / 4, + bottomSide = (1 - y) / 4; + // Draw the top shadow + currentColor[3] = topSide * topSide * alpha; + glColor4fv( currentColor ); + glBegin( GL_QUADS ); + glTexCoord2f( 0, 0 ); // Bottom Left + glVertex3f( pXm, 1, pZm ); + glTexCoord2f( 0, 1 ); // Top Left + glVertex3f( pXm, 1, pZM ); + glTexCoord2f( 1, 1 ); // Top Right + glVertex3f( pXM, 1, pZM ); + glTexCoord2f( 1, 0 ); // Bottom Right + glVertex3f( pXM, 1, pZm ); + glEnd(); + // Draw the bottom shadow + currentColor[3] = bottomSide * bottomSide * alpha; + glColor4fv( currentColor ); + glBegin( GL_QUADS ); + glTexCoord2f( 0, 0 ); // Bottom Left + glVertex3f( pXm, -1, pZm ); + glTexCoord2f( 0, 1 ); // Top Left + glVertex3f( pXm, -1, pZM ); + glTexCoord2f( 1, 1 ); // Top Right + glVertex3f( pXM, -1, pZM ); + glTexCoord2f( 1, 0 ); // Bottom Right + glVertex3f( pXM, -1, pZm ); + glEnd(); +} + +void GLAnalyzer3::drawHFace( float y ) +{ + glBegin( GL_TRIANGLE_STRIP ); + glColor3f( 0.0f, 0.1f, 0.2f ); + glVertex3f( -1.0f, y, 0.0 ); + glVertex3f( 1.0f, y, 0.0 ); + glColor3f( 0.1f, 0.6f, 0.5f ); + glVertex3f( -1.0f, y, 2.0 ); + glVertex3f( 1.0f, y, 2.0 ); + glEnd(); +} + +void GLAnalyzer3::drawScrollGrid( float scroll, float color[4] ) +{ + if ( !gridTexture ) + return; + glMatrixMode( GL_TEXTURE ); + glLoadIdentity(); + glTranslatef( 0.0, -scroll, 0.0 ); + glMatrixMode( GL_MODELVIEW ); + float backColor[4] = { 1.0, 1.0, 1.0, 0.0 }; + for ( int i = 0; i < 3; i++ ) + backColor[ i ] = color[ i ]; + glEnable( GL_TEXTURE_2D ); + glBindTexture( GL_TEXTURE_2D, gridTexture ); + glEnable( GL_BLEND ); + glBegin( GL_TRIANGLE_STRIP ); + glColor4fv( color ); // top face + glTexCoord2f( 0.0f, 1.0f ); + glVertex3f( -1.0f, 1.0f, -1.0f ); + glTexCoord2f( 1.0f, 1.0f ); + glVertex3f( 1.0f, 1.0f, -1.0f ); + glColor4fv( backColor ); // central points + glTexCoord2f( 0.0f, 0.0f ); + glVertex3f( -1.0f, 0.0f, -3.0f ); + glTexCoord2f( 1.0f, 0.0f ); + glVertex3f( 1.0f, 0.0f, -3.0f ); + glColor4fv( color ); // bottom face + glTexCoord2f( 0.0f, 1.0f ); + glVertex3f( -1.0f, -1.0f, -1.0f ); + glTexCoord2f( 1.0f, 1.0f ); + glVertex3f( 1.0f, -1.0f, -1.0f ); + glEnd(); + glDisable( GL_BLEND ); + glDisable( GL_TEXTURE_2D ); + glMatrixMode( GL_TEXTURE ); + glLoadIdentity(); + glMatrixMode( GL_MODELVIEW ); +} + +bool GLAnalyzer3::loadTexture( QString fileName, GLuint& textureID ) +{ + //reset texture ID to the default EMPTY value + textureID = 0; + + //load image + QImage tmp; + if ( !tmp.load( fileName ) ) + return false; + + //convert it to suitable format (flipped RGBA) + QImage texture = QGLWidget::convertToGLFormat( tmp ); + if ( texture.isNull() ) + return false; + + //get texture number and bind loaded image to that texture + glGenTextures( 1, &textureID ); + glBindTexture( GL_TEXTURE_2D, textureID ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, 4, texture.width(), texture.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.bits() ); + return true; +} + +void GLAnalyzer3::freeTexture( GLuint& textureID ) +{ + if ( textureID > 0 ) + glDeleteTextures( 1, &textureID ); + textureID = 0; +} + +#endif diff --git a/src/analyzers/glanalyzer3.h b/src/analyzers/glanalyzer3.h new file mode 100644 index 000000000..7abd7614b --- /dev/null +++ b/src/analyzers/glanalyzer3.h @@ -0,0 +1,80 @@ +/*************************************************************************** + glanalyzer3.h - description + ------------------- + begin : Feb 16 2004 + copyright : (C) 2004 by Enrico Ros + email : eros.kde@email.it + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include +#ifdef HAVE_QGLWIDGET + +#ifndef GLBOUNCER_H +#define GLBOUNCER_H + +#include "analyzerbase.h" +#include +#include + +class QWidget; +class Ball; +class Paddle; + +class GLAnalyzer3 : public Analyzer::Base3D +{ +public: + GLAnalyzer3(QWidget *); + ~GLAnalyzer3(); + void analyze( const Scope & ); + void paused(); + +protected: + void initializeGL(); + void resizeGL( int w, int h ); + void paintGL(); + +private: + struct ShowProperties { + double timeStamp; + double dT; + float colorK; + float gridScrollK; + float gridEnergyK; + float camRot; + float camRoll; + float peakEnergy; + } show; + + struct FrameProperties { + bool silence; + float energy; + float dEnergy; + } frame; + + static const int NUMBER_OF_BALLS = 16; + + QPtrList balls; + Paddle * leftPaddle, * rightPaddle; + float unitX, unitY; + GLuint ballTexture; + GLuint gridTexture; + + void drawDot3s( float x, float y, float z, float size ); + void drawHFace( float y ); + void drawScrollGrid( float scroll, float color[4] ); + + bool loadTexture(QString file, GLuint& textureID); + void freeTexture(GLuint& textureID); +}; + +#endif +#endif diff --git a/src/analyzers/sonogram.cpp b/src/analyzers/sonogram.cpp new file mode 100644 index 000000000..b29563dbb --- /dev/null +++ b/src/analyzers/sonogram.cpp @@ -0,0 +1,91 @@ +// +// +// C++ Implementation: Sonogram +// +// Description: +// +// +// Author: Melchior FRANZ , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#include +#include "sonogram.h" + +Sonogram::Sonogram(QWidget *parent) : + Analyzer::Base2D(parent, 16, 9) +{ +} + + +Sonogram::~Sonogram() +{ +} + + +void Sonogram::init() +{ + eraseCanvas(); +} + + +void Sonogram::resizeEvent(QResizeEvent *e) +{ + QWidget::resizeEvent(e); + canvas()->resize(size()); + background()->resize(size()); + +//only for gcc < 4.0 +#if !( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 0 ) ) + resizeForBands(height() < 128 ? 128 : height()); +#endif + + background()->fill(backgroundColor()); + bitBlt(canvas(), 0, 0, background()); + bitBlt(this, 0, 0, background()); +} + + +void Sonogram::analyze(const Scope &s) +{ + int x = width() - 1; + QColor c; + QPainter p(canvas()); + + bitBlt(canvas(), 0, 0, canvas(), 1, 0, x, height()); + Scope::const_iterator it = s.begin(), end = s.end(); + for (int y = height() - 1; y;) { + if (it >= end || *it < .005) + c = backgroundColor(); + else if (*it < .05) + c.setHsv(95, 255, 255 - int(*it * 4000.0)); + else if (*it < 1.0) + c.setHsv(95 - int(*it * 90.0), 255, 255); + else + c = Qt::red; + + p.setPen(c); + p.drawPoint(x, y--); + + if (it < end) + ++it; + } +} + + +void Sonogram::transform(Scope &scope) +{ + float *front = static_cast(&scope.front()); + m_fht->power2(front); + m_fht->scale(front, 1.0 / 256); + scope.resize( m_fht->size() / 2 ); +} + + +void Sonogram::demo() +{ + analyze(Scope(m_fht->size(), 0)); +} + diff --git a/src/analyzers/sonogram.h b/src/analyzers/sonogram.h new file mode 100644 index 000000000..609c9b2c7 --- /dev/null +++ b/src/analyzers/sonogram.h @@ -0,0 +1,37 @@ +// +// +// C++ Interface: Sonogram +// +// Description: +// +// +// Author: Melchior FRANZ , (C) 2004 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef SONOGRAM_H +#define SONOGRAM_H + +#include "analyzerbase.h" + +/** +@author Melchior FRANZ +*/ + +class Sonogram : public Analyzer::Base2D +{ +public: + Sonogram(QWidget*); + ~Sonogram(); + +protected: + void init(); + void analyze(const Scope&); + void transform(Scope&); + void demo(); + void resizeEvent(QResizeEvent*); +}; + +#endif diff --git a/src/analyzers/turbine.cpp b/src/analyzers/turbine.cpp new file mode 100644 index 000000000..d2e756407 --- /dev/null +++ b/src/analyzers/turbine.cpp @@ -0,0 +1,78 @@ +// +// Amarok BarAnalyzer 3 - Jet Turbine: Symmetric version of analyzer 1 +// +// Author: Stanislav Karchebny , (C) 2003 +// Max Howell (I modified it to use boom analyzer code) +// +// Copyright: like rest of Amarok +// + +#include +#include + +#include "amarok.h" +#include "turbine.h" + +void TurbineAnalyzer::analyze( const Scope &scope ) +{ + eraseCanvas(); + + QPainter p( canvas() ); + float h; + const uint hd2 = height() / 2; + const uint MAX_HEIGHT = hd2 - 1; + + for( uint i = 0, x = 0, y; i < BAND_COUNT; ++i, x += COLUMN_WIDTH+1 ) + { + h = log10( scope[i]*256.0 ) * F * 0.5; + + if( h > MAX_HEIGHT ) + h = MAX_HEIGHT; + + if( h > bar_height[i] ) + { + bar_height[i] = h; + + if( h > peak_height[i] ) + { + peak_height[i] = h; + peak_speed[i] = 0.01; + } + else goto peak_handling; + } + else + { + if( bar_height[i] > 0.0 ) + { + bar_height[i] -= K_barHeight; //1.4 + if( bar_height[i] < 0.0 ) bar_height[i] = 0.0; + } + + peak_handling: + + if( peak_height[i] > 0.0 ) + { + peak_height[i] -= peak_speed[i]; + peak_speed[i] *= F_peakSpeed; //1.12 + + if( peak_height[i] < bar_height[i] ) peak_height[i] = bar_height[i]; + if( peak_height[i] < 0.0 ) peak_height[i] = 0.0; + } + } + + + y = hd2 - uint(bar_height[i]); + bitBlt( canvas(), x+1, y, &barPixmap, 0, y ); + bitBlt( canvas(), x+1, hd2, &barPixmap, 0, (int)bar_height[i] ); + + p.setPen( Amarok::ColorScheme::Foreground ); + p.drawRect( x, y, COLUMN_WIDTH, (int)bar_height[i]*2 ); + + const uint x2 = x+COLUMN_WIDTH-1; + p.setPen( Amarok::ColorScheme::Text ); + y = hd2 - uint(peak_height[i]); + p.drawLine( x, y, x2, y ); + y = hd2 + uint(peak_height[i]); + p.drawLine( x, y, x2, y ); + } +} diff --git a/src/analyzers/turbine.h b/src/analyzers/turbine.h new file mode 100644 index 000000000..d75c60538 --- /dev/null +++ b/src/analyzers/turbine.h @@ -0,0 +1,22 @@ +// +// Amarok BarAnalyzer 3 - Jet Turbine: Symmetric version of analyzer 1 +// +// Author: Stanislav Karchebny , (C) 2003 +// +// Copyright: like rest of Amarok +// + +#ifndef ANALYZER_TURBINE_H +#define ANALYZER_TURBINE_H + +#include "boomanalyzer.h" + +class TurbineAnalyzer : public BoomAnalyzer +{ + public: + TurbineAnalyzer( QWidget *parent ) : BoomAnalyzer( parent ) {} + + void analyze( const Scope& ); +}; + +#endif diff --git a/src/backgroundthread.cpp b/src/backgroundthread.cpp new file mode 100644 index 000000000..8e09c16f2 --- /dev/null +++ b/src/backgroundthread.cpp @@ -0,0 +1 @@ +#include "backgroundthread.h" diff --git a/src/backgroundthread.h b/src/backgroundthread.h new file mode 100644 index 000000000..0c0ace92c --- /dev/null +++ b/src/backgroundthread.h @@ -0,0 +1,59 @@ +#ifndef BACKGROUNDTHREAD_H +#define BACKGROUNDTHREAD_H + +#include +#include + +#include + +class BackgroundThreadBase : public QThread { + Q_OBJECT + public: + BackgroundThreadBase(QObject* parent = 0) : QThread(parent) {} + signals: + void Initialised(); +}; + +template +class BackgroundThread : public BackgroundThreadBase { + public: + BackgroundThread(QObject* parent = 0); + ~BackgroundThread(); + + boost::shared_ptr Worker() const { return worker_; } + + protected: + void run(); + + private: + boost::shared_ptr worker_; +}; + +template +BackgroundThread::BackgroundThread(QObject *parent) + : BackgroundThreadBase(parent) +{ +} + +template +BackgroundThread::~BackgroundThread() { + if (isRunning()) { + quit(); + if (wait(10000)) + return; + terminate(); + wait(10000); + } +} + +template +void BackgroundThread::run() { + worker_.reset(new T); + + emit Initialised(); + exec(); + + worker_.reset(); +} + +#endif // BACKGROUNDTHREAD_H diff --git a/src/directory.h b/src/directory.h new file mode 100644 index 000000000..c7257c56a --- /dev/null +++ b/src/directory.h @@ -0,0 +1,16 @@ +#ifndef DIRECTORY_H +#define DIRECTORY_H + +#include +#include + +class QSqlQuery; + +struct Directory { + QString path; + int id; +}; + +typedef QList DirectoryList; + +#endif // DIRECTORY_H diff --git a/src/engine_fwd.h b/src/engine_fwd.h new file mode 100644 index 000000000..30068a8ba --- /dev/null +++ b/src/engine_fwd.h @@ -0,0 +1,26 @@ + +#ifndef ENGINE_FWD_H +#define ENGINE_FWD_H + +/// Used by eg engineobserver.h, and thus we reduce header dependencies on enginebase.h + +namespace Engine +{ + class SimpleMetaBundle; + class Base; + + /** + * You should return: + * Playing when playing, + * Paused when paused + * Idle when you still have a URL loaded (ie you have not been told to stop()) + * Empty when you have been told to stop(), or an error occurred and you stopped yourself + * + * It is vital to be Idle just after the track has ended! + */ + enum State { Empty, Idle, Playing, Paused }; +} + +typedef Engine::Base EngineBase; + +#endif diff --git a/src/enginebase.cpp b/src/enginebase.cpp new file mode 100644 index 000000000..909f1cb08 --- /dev/null +++ b/src/enginebase.cpp @@ -0,0 +1,49 @@ +//Copyright: (C) 2003 Mark Kretschmann +// (C) 2004,2005 Max Howell, +//License: See COPYING + +#include "enginebase.h" + +#include + + +Engine::Base::Base() + : m_xfadeLength( 0 ) + , m_xfadeNextTrack( false ) + , m_volume( 50 ) + , m_scope( SCOPESIZE ) + , m_isStream( false ) +{} + + +Engine::Base::~Base() +{ +} + +////////////////////////////////////////////////////////////////////// + + +bool +Engine::Base::load( const QUrl &url, bool stream ) +{ + m_url = url; + m_isStream = stream; + + return true; +} + + +void Engine::Base::setVolume( uint value ) +{ + m_volume = value; + + setVolumeSW( makeVolumeLogarithmic( value ) ); +} + + +uint +Engine::Base::makeVolumeLogarithmic( uint volume ) // static +{ + // We're using a logarithmic function to make the volume ramp more natural. + return static_cast( 100 - 100.0 * std::log10( ( 100 - volume ) * 0.09 + 1.0 ) ); +} diff --git a/src/enginebase.h b/src/enginebase.h new file mode 100644 index 000000000..6ab2c6c40 --- /dev/null +++ b/src/enginebase.h @@ -0,0 +1,281 @@ +//Copyright: (C) 2003 Mark Kretschmann +// (C) 2004 Max Howell, +//License: See COPYING + +#ifndef AMAROK_ENGINEBASE_H +#define AMAROK_ENGINEBASE_H + +#include +#include +#include + +#include +#include + + +/** + * @class Engine::Base + * @author Mark Kretshmann + * @author Max Howell + * + * This is an abstract base class that you need to derive when making your own backends. + * It is typdefed to EngineBase for your conveniece. + * + * The only key thing to get right is what to return from state(), as some Amarok + * behaviour is dependent on you returning the right state at the right time. + * + * Empty = No URL loaded and ready to play + * Idle = URL ready for play, but not playing, so before AND after playback + * Playing = Playing a stream + * Paused = Stream playback is paused + * + * Not returning idle when you have reached End-Of-Stream but Amarok has not told you + * to stop would be bad because some components behave differently when the engine is + * Empty or not. You are Idle because you still have a URL assigned. + * + * load( KURL ) is a key function because after this point your engine is loaded, and + * Amarok will expect you to be able to play the URL until stop() or another load() is + * called. + * + * You must handle your own media, do not rely on Amarok to call stop() before play() etc. + * + * At this time, emitting stateChanged( Engine::Idle ) is not necessary, otherwise you should + * let Amarok know of state changes so it updates the UI correctly. + * + * Basically, reimplement everything virtual and ensure you emit stateChanged() correctly, + * try not to block in any function that is called by Amarok, try to keep the user informed + * with emit statusText() + * + * Only canDecode() needs to be thread-safe. Everything else is only called from the GUI thread. + */ + +#include "engine_fwd.h" + +namespace Engine +{ + typedef std::vector Scope; + + class Base : public QObject + { + Q_OBJECT + + signals: + /** Emitted when end of current track is reached. */ + void trackEnded(); + + /** Transmits status message, the message disappears after ~2s. */ + void statusText( const QString& ); + + /** + * Shows a long message in a non-invasive manner, you should prefer + * this over KMessageBoxes, but do use KMessageBox when you must + * interrupt the user or the message is very important. + */ + void infoMessage( const QString& ); + + /** Transmits metadata package. */ + void metaData( const Engine::SimpleMetaBundle& ); + + /** Signals that a SYNC has been recieved, and new last.fm data needs to be downloaded */ + void lastFmTrackChange(); + + /** Signals a change in the engine's state. */ + void stateChanged( Engine::State ); + + /** Shows Amarok config dialog at specified page */ + void showConfigDialog( const QString& ); + + public: + virtual ~Base(); + + /** + * Initializes the engine. Must be called after the engine was loaded. + * @return True if initialization was successful. + */ + virtual bool init() = 0; + + /** + * Determines if the engine is able to play a given URL. + * @param url The URL of the file/stream. + * @return True if we can play the URL. + */ + virtual bool canDecode( const QUrl &url ) const = 0; + + /** + * Determines if current track is a stream. + * @return True if track is a stream. + */ + inline bool isStream() { return m_isStream; } + + /** + * Load new track for playing. + * @param url URL to be played. + * @param stream True if URL is a stream. + * @return True for success. + */ + virtual bool load( const QUrl &url, bool stream = false ); + + /** + * Load new track and start Playback. Convenience function for Amarok to use. + * @param url URL to be played. + * @param stream True if URL is a stream. + * @return True for success. + */ + bool play( const QUrl &u, bool stream = false ) { return load( u, stream ) && play(); } + + /** + * Start playback. + * @param offset Start playing at @p msec position. + * @return True for success. + */ + virtual bool play( uint offset = 0 ) = 0; + + /** Stops playback */ + virtual void stop() = 0; + + /** Pauses playback */ + virtual void pause() = 0; + + /** Resumes playback if paused */ + virtual void unpause() = 0; + + /** + * Get current engine status. + * @return the correct State as described at the enum + */ + virtual State state() const = 0; + + /** Get time position (msec). */ + virtual uint position() const = 0; + + /** Get track length (msec). */ + virtual uint length() const { return 0; } + + /** + * Jump to new time position. + * @param ms New position. + */ + virtual void seek( uint ms ) = 0; + + /** + * Determines whether media is currently loaded. + * @return True if media is loaded, system is ready to play. + */ + inline bool loaded() const { return state() != Empty; } + + inline uint volume() const { return m_volume; } + + /** + * Fetch the current audio sample buffer. + * @return Audio sample buffer. + */ + virtual const Scope &scope() { return m_scope; }; + + /** + * Set new volume value. + * @param value Volume in range 0 to 100. + */ + void setVolume( uint value ); + + /** Set new crossfade length (msec) */ + void setXfadeLength( int value ) { m_xfadeLength = value; } + + /** Set whether to crossfade the next track + * Used when the engine is switching tracks automatically + * instead of manually. + */ + void setXFadeNextTrack( bool enable ) { m_xfadeNextTrack = enable; } + + /** Set whether equalizer is enabled + * You don't need to cache the parameters, setEqualizerParameters is called straight after this + * function, _always_. + */ + virtual void setEqualizerEnabled( bool ) {}; + + /** Set equalizer parameters, all in range -100..100, where 0 = no adjustment + * @param preamp the preamplification value + * @param bandGains a list of 10 integers, ascending in frequency, the exact frequencies you amplify + * are not too-important at this time + */ + virtual void setEqualizerParameters( int /*preamp*/, const QList &/*bandGains*/ ) {}; + + + /** Tries to retrieve metadata for the given url (called only if url + * is not in the collection). The intended usage is to retrieve + * information for AudiCD tracks when they are added to the playlist + * (i.e. before they are actually played) + * @param url the url of the item + * @param bundle the SimpleMetaBundle to fill + * @return true if metadata found, false otherwise + */ + virtual bool metaDataForUrl(const QUrl &, Engine::SimpleMetaBundle &) + { return false; } + + /** returns true if this engine performs some special action to play + * audio cds: in this case, the KURL::List is filled with the urls of + * the songs in the cd... + * + * @param device the cdrom device , with QString::null meaning use engine-specific default value + * @param urls the list of urls for AudioCD tracks to fill + * @return true if the engine has the feature of reading from audio cds, false otherwise (note that this should return true also in case of error if the engine is capable of reading audio cds in general...) + * */ + virtual bool getAudioCDContents(const QString &, QList&) + { return false; } + + /** + * Whether amarok_proxy.rb is needed for last.fm files. + * @return true if engine doesn't handle 'SYNC' messages in the stream from last.fm. + False if (like >=libxine-1.1.8) it does. + */ + virtual bool lastFmProxyRequired() { return true; } + + /** flush the current stream buffer */ + virtual bool flushBuffer() { return false; } + + /** allow the engine to perform necessary work on changes in the playlist **/ + virtual void playlistChanged() { }; + + virtual void reloadSettings() {}; + + protected: + Base(); + + /** Shows the Amarok configuration dialog at the engine page */ + void showEngineConfigDialog() { emit showConfigDialog( "Engine" ); } + + virtual void setVolumeSW( uint percent ) = 0; + + /** Converts master volume to a logarithmic scale */ + static uint makeVolumeLogarithmic( uint volume ); + + Base( const Base& ); //disable copy constructor + const Base &operator=( const Base& ); //disable copy constructor + + int m_xfadeLength; + bool m_xfadeNextTrack; + + protected: + static const int SCOPESIZE = 1024; + uint m_volume; + QUrl m_url; + Scope m_scope; + bool m_isStream; + }; + + + class SimpleMetaBundle { + public: + QString title; + QString artist; + QString album; + QString comment; + QString genre; + QString bitrate; + QString samplerate; + QString length; + QString year; + QString tracknr; + }; +} + +#endif diff --git a/src/fht.cpp b/src/fht.cpp new file mode 100644 index 000000000..36d276edf --- /dev/null +++ b/src/fht.cpp @@ -0,0 +1,242 @@ +// FHT - Fast Hartley Transform Class +// +// Copyright (C) 2004 Melchior FRANZ - mfranz@kde.org +// +// 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, 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA +// +// $Id$ + +#include +#include +#include "fht.h" + + +FHT::FHT(int n) : + m_buf(0), + m_tab(0), + m_log(0) +{ + if (n < 3) { + m_num = 0; + m_exp2 = -1; + return; + } + m_exp2 = n; + m_num = 1 << n; + if (n > 3) { + m_buf = new float[m_num]; + m_tab = new float[m_num * 2]; + makeCasTable(); + } +} + + +FHT::~FHT() +{ + delete[] m_buf; + delete[] m_tab; + delete[] m_log; +} + + +void FHT::makeCasTable(void) +{ + float d, *costab, *sintab; + int ul, ndiv2 = m_num / 2; + + for (costab = m_tab, sintab = m_tab + m_num / 2 + 1, ul = 0; ul < m_num; ul++) { + d = M_PI * ul / ndiv2; + *costab = *sintab = cos(d); + + costab += 2, sintab += 2; + if (sintab > m_tab + m_num * 2) + sintab = m_tab + 1; + } +} + + +float* FHT::copy(float *d, float *s) +{ + return (float *)memcpy(d, s, m_num * sizeof(float)); +} + + +float* FHT::clear(float *d) +{ + return (float *)memset(d, 0, m_num * sizeof(float)); +} + + +void FHT::scale(float *p, float d) +{ + for (int i = 0; i < (m_num / 2); i++) + *p++ *= d; +} + + +void FHT::ewma(float *d, float *s, float w) +{ + for (int i = 0; i < (m_num / 2); i++, d++, s++) + *d = *d * w + *s * (1 - w); +} + + +void FHT::logSpectrum(float *out, float *p) +{ + int n = m_num / 2, i, j, k, *r; + if (!m_log) { + m_log = new int[n]; + float f = n / log10((double)n); + for (i = 0, r = m_log; i < n; i++, r++) { + j = int(rint(log10(i + 1.0) * f)); + *r = j >= n ? n - 1 : j; + } + } + semiLogSpectrum(p); + *out++ = *p = *p / 100; + for (k = i = 1, r = m_log; i < n; i++) { + j = *r++; + if (i == j) + *out++ = p[i]; + else { + float base = p[k - 1]; + float step = (p[j] - base) / (j - (k - 1)); + for (float corr = 0; k <= j; k++, corr += step) + *out++ = base + corr; + } + } +} + + +void FHT::semiLogSpectrum(float *p) +{ + float e; + power2(p); + for (int i = 0; i < (m_num / 2); i++, p++) { + e = 10.0 * log10(sqrt(*p * .5)); + *p = e < 0 ? 0 : e; + } +} + + +void FHT::spectrum(float *p) +{ + power2(p); + for (int i = 0; i < (m_num / 2); i++, p++) + *p = (float)sqrt(*p * .5); +} + + +void FHT::power(float *p) +{ + power2(p); + for (int i = 0; i < (m_num / 2); i++) + *p++ *= .5; +} + + +void FHT::power2(float *p) +{ + int i; + float *q; + _transform(p, m_num, 0); + + *p = (*p * *p), *p += *p, p++; + + for (i = 1, q = p + m_num - 2; i < (m_num / 2); i++, --q) + *p = (*p * *p) + (*q * *q), p++; +} + + +void FHT::transform(float *p) +{ + if (m_num == 8) + transform8(p); + else + _transform(p, m_num, 0); +} + + +void FHT::transform8(float *p) +{ + float a, b, c, d, e, f, g, h, b_f2, d_h2; + float a_c_eg, a_ce_g, ac_e_g, aceg, b_df_h, bdfh; + + a = *p++, b = *p++, c = *p++, d = *p++; + e = *p++, f = *p++, g = *p++, h = *p; + b_f2 = (b - f) * M_SQRT2; + d_h2 = (d - h) * M_SQRT2; + + a_c_eg = a - c - e + g; + a_ce_g = a - c + e - g; + ac_e_g = a + c - e - g; + aceg = a + c + e + g; + + b_df_h = b - d + f - h; + bdfh = b + d + f + h; + + *p = a_c_eg - d_h2; + *--p = a_ce_g - b_df_h; + *--p = ac_e_g - b_f2; + *--p = aceg - bdfh; + *--p = a_c_eg + d_h2; + *--p = a_ce_g + b_df_h; + *--p = ac_e_g + b_f2; + *--p = aceg + bdfh; +} + + +void FHT::_transform(float *p, int n, int k) +{ + if (n == 8) { + transform8(p + k); + return; + } + + int i, j, ndiv2 = n / 2; + float a, *t1, *t2, *t3, *t4, *ptab, *pp; + + for (i = 0, t1 = m_buf, t2 = m_buf + ndiv2, pp = &p[k]; i < ndiv2; i++) + *t1++ = *pp++, *t2++ = *pp++; + + memcpy(p + k, m_buf, sizeof(float) * n); + + _transform(p, ndiv2, k); + _transform(p, ndiv2, k + ndiv2); + + j = m_num / ndiv2 - 1; + t1 = m_buf; + t2 = t1 + ndiv2; + t3 = p + k + ndiv2; + ptab = m_tab; + pp = p + k; + + a = *ptab++ * *t3++; + a += *ptab * *pp; + ptab += j; + + *t1++ = *pp + a; + *t2++ = *pp++ - a; + + for (i = 1, t4 = p + k + n; i < ndiv2; i++, ptab += j) { + a = *ptab++ * *t3++; + a += *ptab * *--t4; + + *t1++ = *pp + a; + *t2++ = *pp++ - a; + } + memcpy(p + k, m_buf, sizeof(float) * n); +} + diff --git a/src/fht.h b/src/fht.h new file mode 100644 index 000000000..059fb4299 --- /dev/null +++ b/src/fht.h @@ -0,0 +1,119 @@ +// FHT - Fast Hartley Transform Class +// +// Copyright (C) 2004 Melchior FRANZ - mfranz@kde.org +// +// 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, 51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA +// +// $Id$ + +#ifndef FHT_H +#define FHT_H + +/** + * Implementation of the Hartley Transform after Bracewell's discrete + * algorithm. The algorithm is subject to US patent No. 4,646,256 (1987) + * but was put into public domain by the Board of Trustees of Stanford + * University in 1994 and is now freely available[1]. + * + * [1] Computer in Physics, Vol. 9, No. 4, Jul/Aug 1995 pp 373-379 + */ +class FHT +{ + int m_exp2; + int m_num; + float *m_buf; + float *m_tab; + int *m_log; + + /** + * Create a table of "cas" (cosine and sine) values. + * Has only to be done in the constructor and saves from + * calculating the same values over and over while transforming. + */ + void makeCasTable(); + + /** + * Recursive in-place Hartley transform. For internal use only! + */ + void _transform(float *, int, int); + + public: + /** + * Prepare transform for data sets with @f$2^n@f$ numbers, whereby @f$n@f$ + * should be at least 3. Values of more than 3 need a trigonometry table. + * @see makeCasTable() + */ + FHT(int); + + ~FHT(); + inline int sizeExp() const { return m_exp2; } + inline int size() const { return m_num; } + float *copy(float *, float *); + float *clear(float *); + void scale(float *, float); + + /** + * Exponentially Weighted Moving Average (EWMA) filter. + * @param d is the filtered data. + * @param s is fresh input. + * @param w is the weighting factor. + */ + void ewma(float *d, float *s, float w); + + /** + * Logarithmic audio spectrum. Maps semi-logarithmic spectrum + * to logarithmic frequency scale, interpolates missing values. + * A logarithmic index map is calculated at the first run only. + * @param p is the input array. + * @param out is the spectrum. + */ + void logSpectrum(float *out, float *p); + + /** + * Semi-logarithmic audio spectrum. + */ + void semiLogSpectrum(float *); + + /** + * Fourier spectrum. + */ + void spectrum(float *); + + /** + * Calculates a mathematically correct FFT power spectrum. + * If further scaling is applied later, use power2 instead + * and factor the 0.5 in the final scaling factor. + * @see FHT::power2() + */ + void power(float *); + + /** + * Calculates an FFT power spectrum with doubled values as a + * result. The values need to be multiplied by 0.5 to be exact. + * Note that you only get @f$2^{n-1}@f$ power values for a data set + * of @f$2^n@f$ input values. This is the fastest transform. + * @see FHT::power() + */ + void power2(float *); + + /** + * Discrete Hartley transform of data sets with 8 values. + */ + void transform8(float *); + + void transform(float *); +}; + +#endif diff --git a/src/library.cpp b/src/library.cpp new file mode 100644 index 000000000..d52991db9 --- /dev/null +++ b/src/library.cpp @@ -0,0 +1,543 @@ +#include "library.h" +#include "librarybackend.h" +#include "libraryitem.h" +#include "songmimedata.h" +#include "libraryconfig.h" + +#include +#include + +#include + + +Library::Library(EngineBase* engine, QObject* parent) + : QAbstractItemModel(parent), + engine_(engine), + backend_(new BackgroundThread(this)), + watcher_(new BackgroundThread(this)), + root_(new LibraryItem(LibraryItem::Type_Root)), + artist_icon_(":artist.png"), + album_icon_(":album.png"), + config_(new LibraryConfig) +{ + connect(backend_, SIGNAL(Initialised()), SLOT(BackendInitialised())); + connect(watcher_, SIGNAL(Initialised()), SLOT(WatcherInitialised())); + waiting_for_threads_ = 2; +} + +Library::~Library() { + delete root_; + delete config_; +} + +void Library::StartThreads() { + Q_ASSERT(waiting_for_threads_); + + backend_->start(); + watcher_->start(); +} + +void Library::BackendInitialised() { + connect(backend_->Worker().get(), SIGNAL(SongsDiscovered(SongList)), SLOT(SongsDiscovered(SongList))); + connect(backend_->Worker().get(), SIGNAL(SongsDeleted(SongList)), SLOT(SongsDeleted(SongList))); + connect(backend_->Worker().get(), SIGNAL(Error(QString)), SIGNAL(Error(QString))); + connect(backend_->Worker().get(), SIGNAL(TotalSongCountUpdated(int)), SIGNAL(TotalSongCountUpdated(int))); + + config_->SetBackend(backend_->Worker()); + + if (--waiting_for_threads_ == 0) + Initialise(); +} + +void Library::WatcherInitialised() { + watcher_->Worker()->SetEngine(engine_); + if (--waiting_for_threads_ == 0) + Initialise(); +} + +void Library::Initialise() { + // The backend and watcher threads are finished initialising, now we can + // connect them together and start everything off. + watcher_->Worker()->SetBackend(backend_->Worker()); + + connect(backend_->Worker().get(), SIGNAL(DirectoriesDiscovered(DirectoryList)), + watcher_->Worker().get(), SLOT(AddDirectories(DirectoryList))); + connect(watcher_->Worker().get(), SIGNAL(NewOrUpdatedSongs(SongList)), + backend_->Worker().get(), SLOT(AddOrUpdateSongs(SongList))); + connect(watcher_->Worker().get(), SIGNAL(SongsMTimeUpdated(SongList)), + backend_->Worker().get(), SLOT(UpdateMTimesOnly(SongList))); + connect(watcher_->Worker().get(), SIGNAL(SongsDeleted(SongList)), + backend_->Worker().get(), SLOT(DeleteSongs(SongList))); + + // This will start the watcher checking for updates + backend_->Worker()->LoadDirectoriesAsync(); + + backend_->Worker()->UpdateTotalSongCountAsync(); + + Reset(); +} + +bool Library::IsEmpty() const { + return root_->children.isEmpty(); +} + +void Library::SongsDiscovered(const SongList& songs) { + foreach (const Song& song, songs) { + LibraryItem* artist = NULL; + LibraryItem* album = NULL; + + if (song.is_compilation()) { + if (compilation_artist_node_ == NULL) + CreateCompilationArtistNode(true); + artist = compilation_artist_node_; + } else { + if (artist_nodes_.contains(song.artist())) + artist = artist_nodes_[song.artist()]; + else { + artist = CreateArtistNode(true, song.artist()); + } + } + + if (artist->lazy_loaded) { + album = artist->ChildByKey(song.album()); + if (album == NULL) + album = CreateAlbumNode(true, song.album(), artist, song.is_compilation()); + + if (album->lazy_loaded) + CreateSongNode(true, song, album); + } + } +} + +LibraryItem* Library::CreateCompilationArtistNode(bool signal) { + LibraryItem* parent = root_; + if (signal) + beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count()); + + compilation_artist_node_ = + new LibraryItem(LibraryItem::Type_CompilationArtist, "Various Artists", parent); + compilation_artist_node_->sort_text = " various"; + + if (signal) + endInsertRows(); + + return compilation_artist_node_; +} + +LibraryItem* Library::CreateArtistNode(bool signal, const QString& name) { + LibraryItem* parent = root_; + if (signal) + beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count()); + + LibraryItem* ret = new LibraryItem(LibraryItem::Type_Artist, name, parent); + ret->display_text = PrettyArtist(name); + ret->sort_text = SortTextForArtist(name); + + artist_nodes_[name] = ret; + + if (signal) + endInsertRows(); + + if (!name.isEmpty()) { + QChar divider_char = ret->sort_text[0]; + + if (!divider_nodes_.contains(divider_char)) { + if (signal) + beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count()); + + LibraryItem* divider = + new LibraryItem(LibraryItem::Type_Divider, QString(divider_char), root_); + + if (divider_char.isDigit()) + divider->display_text = "0-9"; + + divider_nodes_[divider_char] = divider; + + if (signal) + endInsertRows(); + } + } + + return ret; +} + +LibraryItem* Library::CreateAlbumNode(bool signal, const QString& name, LibraryItem* parent, bool compilation) { + if (signal) + beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count()); + + LibraryItem* ret = new LibraryItem( + compilation ? LibraryItem::Type_CompilationAlbum + : LibraryItem::Type_Album, + name, parent); + + ret->display_text = PrettyAlbum(name); + ret->sort_text = SortTextForAlbum(name); + + if (signal) + endInsertRows(); + + return ret; +} + +LibraryItem* Library::CreateSongNode(bool signal, const Song& song, LibraryItem* parent) { + if (signal) + beginInsertRows(ItemToIndex(parent), parent->children.count(), parent->children.count()); + + LibraryItem* ret = new LibraryItem(LibraryItem::Type_Song, song.title(), parent); + ret->display_text = song.PrettyTitleWithArtist(); + ret->song = song; + + song_nodes_[song.id()] = ret; + + if (signal) + endInsertRows(); + + return ret; +} + +void Library::SongsDeleted(const SongList& songs) { + // Delete song nodes + foreach (const Song& song, songs) { + if (song_nodes_.contains(song.id())) { + LibraryItem* node = song_nodes_[song.id()]; + + beginRemoveRows(ItemToIndex(node->parent), node->row, node->row); + node->parent->Delete(node->row); + song_nodes_.remove(song.id()); + endRemoveRows(); + } + } + + // Delete now-empty album nodes + foreach (const Song& song, songs) { + LibraryItem* artist = NULL; + + if (song.is_compilation() && compilation_artist_node_->lazy_loaded) + artist = compilation_artist_node_; + else if (artist_nodes_.contains(song.artist()) && + artist_nodes_[song.artist()]->lazy_loaded) + artist = artist_nodes_[song.artist()]; + + if (artist == NULL) + continue; + + LibraryItem* node = artist->ChildByKey(song.album()); + if (!node) + continue; + + LazyPopulate(node); + + if (node->children.count() == 0) { + beginRemoveRows(ItemToIndex(node->parent), node->row, node->row); + node->parent->Delete(node->row); + endRemoveRows(); + } + } + + // Delete now-empty artist nodes + foreach (const Song& song, songs) { + // Was it a compilation? + LibraryItem* node = NULL; + if (song.is_compilation()) + node = compilation_artist_node_; + else + node = artist_nodes_.contains(song.artist()) ? artist_nodes_[song.artist()] : NULL; + + if (node) { + LazyPopulate(node); + + if (node->children.count() == 0) { + beginRemoveRows(ItemToIndex(node->parent), node->row, node->row); + node->parent->Delete(node->row); + + if (song.is_compilation()) + compilation_artist_node_ = NULL; + else { + artist_nodes_.remove(song.artist()); + + // Delete now-empty dividers + QString sort_text(SortTextForArtist(song.artist())); + if (!sort_text.isEmpty() && divider_nodes_.contains(sort_text[0])) { + QChar c(sort_text[0]); + bool found = false; + foreach (LibraryItem* artist_node, artist_nodes_.values()) { + if (artist_node->sort_text.startsWith(c)) { + found = true; + break; + } + } + + if (!found) { + root_->Delete(divider_nodes_[c]->row); + divider_nodes_.remove(c); + } + } + } + + endRemoveRows(); + } + } + } +} + +LibraryItem* Library::IndexToItem(const QModelIndex& index) const { + if (!index.isValid()) + return root_; + return reinterpret_cast(index.internalPointer()); +} + +QModelIndex Library::ItemToIndex(LibraryItem* item) const { + if (!item || !item->parent) + return QModelIndex(); + return createIndex(item->row, 0, item); +} + +int Library::columnCount(const QModelIndex &) const { + return 1; +} + +QVariant Library::data(const QModelIndex& index, int role) const { + const LibraryItem* item = IndexToItem(index); + + return data(item, role); +} + +QVariant Library::data(const LibraryItem* item, int role) const { + switch (role) { + case Qt::DisplayRole: + return item->DisplayText(); + + case Qt::DecorationRole: + switch (item->type) { + case LibraryItem::Type_Album: + case LibraryItem::Type_CompilationAlbum: + return album_icon_; + case LibraryItem::Type_Artist: + case LibraryItem::Type_CompilationArtist: + return artist_icon_; + default: + break; + } + break; + + case Role_Type: + return item->type; + + case Role_Key: + return item->key; + + case Role_SortText: + if (item->type == LibraryItem::Type_Song) + return item->song.disc() * 1000 + item->song.track(); + return item->SortText(); + } + return QVariant(); +} + +QModelIndex Library::index(int row, int, const QModelIndex& parent) const { + LibraryItem* parent_item = IndexToItem(parent); + if (!parent_item || parent_item->children.count() <= row) + return QModelIndex(); + + return ItemToIndex(parent_item->children[row]); +} + +QModelIndex Library::parent(const QModelIndex& index) const { + return ItemToIndex(IndexToItem(index)->parent); +} + +int Library::rowCount(const QModelIndex & parent) const { + LibraryItem* item = IndexToItem(parent); + const_cast(this)->LazyPopulate(item); // Ahem + + return item->children.count(); +} + +bool Library::hasChildren(const QModelIndex &parent) const { + LibraryItem* item = IndexToItem(parent); + if (item->lazy_loaded) + return !item->children.isEmpty(); + else + return true; +} + +void Library::LazyPopulate(LibraryItem* item) { + if (item->lazy_loaded) + return; + + switch (item->type) { + case LibraryItem::Type_CompilationArtist: + foreach (const QString& album, backend_->Worker()->GetCompilationAlbums(query_options_)) + CreateAlbumNode(false, album, item, true); + break; + + case LibraryItem::Type_CompilationAlbum: + foreach (const Song& song, backend_->Worker()->GetCompilationSongs(query_options_, item->key)) + CreateSongNode(false, song, item); + break; + + case LibraryItem::Type_Artist: + foreach (const QString& album, backend_->Worker()->GetAlbumsByArtist(query_options_, item->key)) + CreateAlbumNode(false, album, item, false); + break; + + case LibraryItem::Type_Album: + foreach (const Song& song, backend_->Worker()->GetSongs(query_options_, item->parent->key, item->key)) + CreateSongNode(false, song, item); + break; + + default: + qWarning("Tried to LazyPopulate a bad item type"); + break; + } + + item->lazy_loaded = true; +} + +void Library::Reset() { + delete root_; + artist_nodes_.clear(); + song_nodes_.clear(); + divider_nodes_.clear(); + compilation_artist_node_ = NULL; + + root_ = new LibraryItem(LibraryItem::Type_Root); + + // Various artists? + if (backend_->Worker()->HasCompilations(query_options_)) + CreateCompilationArtistNode(false); + + // Populate artists + foreach (const QString& artist, backend_->Worker()->GetAllArtists(query_options_)) + CreateArtistNode(false, artist); + + reset(); +} + +QString Library::PrettyArtist(QString artist) const { + if (artist.isEmpty()) { + artist = "Unknown"; + } + + return artist; +} + +QString Library::SortTextForArtist(QString artist) const { + artist = SortTextForAlbum(artist); + + if (artist.startsWith("the ")) { + artist = artist.right(artist.length() - 4) + ", the"; + } + + return artist; +} + +QString Library::PrettyAlbum(QString album) const { + if (album.isEmpty()) { + album = "Unknown"; + } + + return album; +} + +QString Library::SortTextForAlbum(QString album) const { + if (album.isEmpty()) { + album = " unknown"; + } else { + album = album.toLower(); + } + album = album.remove(QRegExp("[^\\w ]")); + + return album; +} + +Qt::ItemFlags Library::flags(const QModelIndex& index) const { + switch (IndexToItem(index)->type) { + case LibraryItem::Type_Album: + case LibraryItem::Type_Artist: + case LibraryItem::Type_Song: + case LibraryItem::Type_CompilationAlbum: + case LibraryItem::Type_CompilationArtist: + return Qt::ItemIsSelectable | + Qt::ItemIsEnabled | + Qt::ItemIsDragEnabled; + case LibraryItem::Type_Divider: + case LibraryItem::Type_Root: + default: + return Qt::ItemIsEnabled; + } +} + +QStringList Library::mimeTypes() const { + return QStringList() << "text/uri-list"; +} + +QMimeData* Library::mimeData(const QModelIndexList& indexes) const { + SongMimeData* data = new SongMimeData; + QList urls; + + foreach (const QModelIndex& index, indexes) { + GetChildSongs(IndexToItem(index), &urls, &data->songs); + } + + data->setUrls(urls); + + return data; +} + +bool Library::CompareItems(const LibraryItem* a, const LibraryItem* b) const { + return data(a, Library::Role_SortText).toString() < + data(b, Library::Role_SortText).toString(); +} + +void Library::GetChildSongs(LibraryItem* item, QList* urls, SongList* songs) const { + switch (item->type) { + case LibraryItem::Type_Album: + case LibraryItem::Type_Artist: + case LibraryItem::Type_CompilationAlbum: + case LibraryItem::Type_CompilationArtist: { + const_cast(this)->LazyPopulate(item); + + QList children = item->children; + qSort(children.begin(), children.end(), boost::bind( + &Library::CompareItems, this, _1, _2)); + + foreach (LibraryItem* child, children) + GetChildSongs(child, urls, songs); + break; + } + + case LibraryItem::Type_Song: + urls->append(QUrl::fromLocalFile(item->song.filename())); + songs->append(item->song); + break; + + default: + break; + } +} + +SongList Library::GetChildSongs(const QModelIndex& index) const { + QList dontcare; + SongList ret; + + if (!index.isValid()) + return SongList(); + + GetChildSongs(IndexToItem(index), &dontcare, &ret); + return ret; +} + +void Library::ShowConfig() { + config_->show(); +} + +void Library::SetFilterAge(int age) { + query_options_.max_age = age; + Reset(); +} + +void Library::SetFilterText(const QString& text) { + query_options_.filter = text; + Reset(); +} diff --git a/src/library.h b/src/library.h new file mode 100644 index 000000000..261381cea --- /dev/null +++ b/src/library.h @@ -0,0 +1,110 @@ +#ifndef LIBRARY_H +#define LIBRARY_H + +#include +#include + +#include "backgroundthread.h" +#include "librarybackend.h" +#include "librarywatcher.h" +#include "libraryquery.h" +#include "engine_fwd.h" +#include "song.h" + +class LibraryItem; +class LibraryConfig; + +class Library : public QAbstractItemModel { + Q_OBJECT + + public: + Library(EngineBase* engine, QObject* parent = 0); + ~Library(); + + enum { + Role_Type = Qt::UserRole + 1, + Role_SortText, + Role_Key, + }; + + void StartThreads(); + + void GetChildSongs(LibraryItem* item, QList* urls, SongList* songs) const; + SongList GetChildSongs(const QModelIndex& index) const; + + bool IsEmpty() const; + + // QAbstractItemModel + int columnCount(const QModelIndex & parent = QModelIndex()) const; + QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex & index) const; + int rowCount(const QModelIndex & parent = QModelIndex()) const; + bool hasChildren(const QModelIndex &parent) const; + Qt::ItemFlags flags(const QModelIndex& index) const; + QStringList mimeTypes() const; + QMimeData* mimeData(const QModelIndexList& indexes) const; + + signals: + void Error(const QString& message); + void TotalSongCountUpdated(int count); + + public slots: + void ShowConfig(); + + void SetFilterAge(int age); + void SetFilterText(const QString& text); + + private slots: + // From LibraryBackend + void BackendInitialised(); + void SongsDiscovered(const SongList& songs); + void SongsDeleted(const SongList& songs); + void Reset(); + + // From LibraryWatcher + void WatcherInitialised(); + + private: + void Initialise(); + void LazyPopulate(LibraryItem* item); + + LibraryItem* CreateCompilationArtistNode(bool signal); + LibraryItem* CreateArtistNode(bool signal, const QString& name); + LibraryItem* CreateAlbumNode(bool signal, const QString& name, LibraryItem* parent, bool compilation); + LibraryItem* CreateSongNode(bool signal, const Song& song, LibraryItem* parent); + + QString PrettyArtist(QString artist) const; + QString PrettyAlbum(QString album) const; + + QString SortTextForArtist(QString artist) const; + QString SortTextForAlbum(QString album) const; + + LibraryItem* IndexToItem(const QModelIndex& index) const; + QModelIndex ItemToIndex(LibraryItem* item) const; + QVariant data(const LibraryItem* item, int role) const; + + bool CompareItems(const LibraryItem* a, const LibraryItem* b) const; + + private: + EngineBase* engine_; + BackgroundThread* backend_; + BackgroundThread* watcher_; + + int waiting_for_threads_; + + QueryOptions query_options_; + + LibraryItem* root_; + QMap song_nodes_; + QMap artist_nodes_; + QMap divider_nodes_; + LibraryItem* compilation_artist_node_; + + QIcon artist_icon_; + QIcon album_icon_; + + LibraryConfig* config_; +}; + +#endif // LIBRARY_H diff --git a/src/librarybackend.cpp b/src/librarybackend.cpp new file mode 100644 index 000000000..f45a7a3df --- /dev/null +++ b/src/librarybackend.cpp @@ -0,0 +1,382 @@ +#include "librarybackend.h" +#include "libraryquery.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char* LibraryBackend::kDatabaseName = "tangerine.db"; + +LibraryBackend::LibraryBackend(QObject* parent) + : QObject(parent) +{ + QSettings s; + s.beginGroup("Library"); + directory_ = s.value("database_directory", DefaultDirectory()).toString(); + + Connect(); +} + +QString LibraryBackend::DefaultDirectory() { + QDir ret(QDir::homePath() + "/.config/" + QCoreApplication::organizationName()); + return QDir::toNativeSeparators(ret.path()); +} + +QSqlDatabase LibraryBackend::Connect() { + QMutexLocker l(&connect_mutex_); + + // Create the directory if it doesn't exist + if (!QFile::exists(directory_)) { + QDir dir; + if (!dir.mkpath(directory_)) { + } + } + + const QString connection_id("thread_" + QString::number( + reinterpret_cast(QThread::currentThread()))); + + // Try to find an existing connection for this thread + QSqlDatabase db = QSqlDatabase::database(connection_id); + if (db.isOpen()) { + return db; + } + + db = QSqlDatabase::addDatabase("QSQLITE", connection_id); + db.setDatabaseName(directory_ + "/" + kDatabaseName); + if (!db.open()) { + emit Error(db.lastError().text()); + return db; + } + + if (db.tables().count() == 0) { + // Set up initial schema + QFile schema_file(":/schema.sql"); + schema_file.open(QIODevice::ReadOnly); + QString schema(QString::fromUtf8(schema_file.readAll())); + + QStringList commands(schema.split(";\n\n")); + foreach (const QString& command, commands) { + QSqlQuery query(db.exec(command)); + if (CheckErrors(query.lastError())) return db; + } + } + return db; +} + +bool LibraryBackend::CheckErrors(const QSqlError& error) { + if (error.isValid()) { + qDebug() << error; + emit Error(error.text()); + return true; + } + return false; +} + +void LibraryBackend::LoadDirectoriesAsync() { + metaObject()->invokeMethod(this, "LoadDirectories", Qt::QueuedConnection); +} + +void LibraryBackend::UpdateTotalSongCountAsync() { + metaObject()->invokeMethod(this, "UpdateTotalSongCount", Qt::QueuedConnection); +} + +void LibraryBackend::LoadDirectories() { + QSqlDatabase db(Connect()); + + QSqlQuery q("SELECT ROWID, path" + " FROM directories", db); + q.exec(); + if (CheckErrors(q.lastError())) return; + + DirectoryList directories; + while (q.next()) { + Directory dir; + dir.id = q.value(0).toInt(); + dir.path = q.value(1).toString(); + directories << dir; + } + emit DirectoriesDiscovered(directories); +} + +void LibraryBackend::UpdateTotalSongCount() { + QSqlDatabase db(Connect()); + + QSqlQuery q("SELECT COUNT(*) FROM songs", db); + q.exec(); + if (CheckErrors(q.lastError())) return; + if (!q.next()) return; + + emit TotalSongCountUpdated(q.value(0).toInt()); +} + +void LibraryBackend::AddDirectory(const QString &path) { + QSqlDatabase db(Connect()); + + QSqlQuery q("INSERT INTO directories (path, subdirs)" + " VALUES (:path, 1)", db); + q.bindValue(":path", path); + q.exec(); + if (CheckErrors(q.lastError())) return; + + Directory dir; + dir.path = path; + dir.id = q.lastInsertId().toInt(); + + emit DirectoriesDiscovered(DirectoryList() << dir); +} + +void LibraryBackend::RemoveDirectory(const Directory& dir) { + QSqlDatabase db(Connect()); + + // Remove songs first + DeleteSongs(FindSongsInDirectory(dir.id)); + + // Now remove the directory + QSqlQuery q("DELETE FROM directories WHERE ROWID = :id", db); + q.bindValue(":id", dir.id); + q.exec(); + if (CheckErrors(q.lastError())) return; + + emit DirectoriesDeleted(DirectoryList() << dir); +} + +SongList LibraryBackend::FindSongsInDirectory(int id) { + QSqlDatabase db(Connect()); + + QSqlQuery q("SELECT ROWID, " + QString(Song::kColumnSpec) + + " FROM songs WHERE directory = :directory", db); + q.bindValue(":directory", id); + q.exec(); + if (CheckErrors(q.lastError())) return SongList(); + + SongList ret; + while (q.next()) { + Song song; + song.InitFromQuery(q); + ret << song; + } + return ret; +} + +void LibraryBackend::AddOrUpdateSongs(const SongList& songs) { + QSqlDatabase db(Connect()); + + QSqlQuery check_dir( + "SELECT ROWID FROM directories WHERE ROWID = :id", db); + QSqlQuery add_song( + "INSERT INTO songs (" + QString(Song::kColumnSpec) + ")" + " VALUES (" + QString(Song::kBindSpec) + ")", db); + QSqlQuery update_song( + "UPDATE songs SET " + QString(Song::kUpdateSpec) + + " WHERE ROWID = :id", db); + + db.transaction(); + + SongList added_songs; + SongList deleted_songs; + + foreach (const Song& song, songs) { + // Do a sanity check first - make sure the song's directory still exists + // This is to fix a possible race condition when a directory is removed + // while LibraryWatcher is scanning it. + check_dir.bindValue(":id", song.directory_id()); + check_dir.exec(); + if (CheckErrors(check_dir.lastError())) continue; + + if (!check_dir.next()) + continue; // Directory didn't exist + + + if (song.id() == -1) { + // Create + song.BindToQuery(&add_song); + add_song.exec(); + if (CheckErrors(add_song.lastError())) continue; + + Song copy(song); + copy.set_id(add_song.lastInsertId().toInt()); + added_songs << copy; + } else { + // Get the previous song data first + Song old_song(GetSongById(song.id())); + if (!old_song.is_valid()) + continue; + + // Update + song.BindToQuery(&update_song); + update_song.bindValue(":id", song.id()); + update_song.exec(); + if (CheckErrors(update_song.lastError())) continue; + + deleted_songs << old_song; + added_songs << song; + } + } + + db.commit(); + + if (!deleted_songs.isEmpty()) + emit SongsDeleted(deleted_songs); + + if (!added_songs.isEmpty()) + emit SongsDiscovered(added_songs); + + UpdateTotalSongCountAsync(); +} + +void LibraryBackend::UpdateMTimesOnly(const SongList& songs) { + QSqlDatabase db(Connect()); + + QSqlQuery q("UPDATE songs SET mtime = :mtime WHERE ROWID = :id", db); + + db.transaction(); + foreach (const Song& song, songs) { + q.bindValue(":mtime", song.mtime()); + q.bindValue(":id", song.id()); + q.exec(); + CheckErrors(q.lastError()); + } + db.commit(); +} + +void LibraryBackend::DeleteSongs(const SongList &songs) { + QSqlDatabase db(Connect()); + + QSqlQuery q("DELETE FROM songs WHERE ROWID = :id", db); + + db.transaction(); + foreach (const Song& song, songs) { + q.bindValue(":id", song.id()); + q.exec(); + CheckErrors(q.lastError()); + } + db.commit(); + + emit SongsDeleted(songs); + + UpdateTotalSongCountAsync(); +} + +QStringList LibraryBackend::GetAllArtists(const QueryOptions& opt) { + LibraryQuery query(opt); + query.SetColumnSpec("DISTINCT artist"); + query.AddWhere("compilation", 0); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return QStringList(); + + QStringList ret; + while (q.next()) { + ret << q.value(0).toString(); + } + return ret; +} + +QStringList LibraryBackend::GetAlbumsByArtist(const QueryOptions& opt, const QString& artist) { + LibraryQuery query(opt); + query.SetColumnSpec("DISTINCT album"); + query.AddWhere("compilation", 0); + query.AddWhere("artist", artist); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return QStringList(); + + QStringList ret; + while (q.next()) { + ret << q.value(0).toString(); + } + return ret; +} + +SongList LibraryBackend::GetSongs(const QueryOptions& opt, const QString& artist, const QString& album) { + LibraryQuery query(opt); + query.SetColumnSpec("ROWID, " + QString(Song::kColumnSpec)); + query.AddWhere("compilation", 0); + query.AddWhere("artist", artist); + query.AddWhere("album", album); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return SongList(); + + SongList ret; + while (q.next()) { + Song song; + song.InitFromQuery(q); + ret << song; + } + return ret; +} + +Song LibraryBackend::GetSongById(int id) { + QSqlDatabase db(Connect()); + + QSqlQuery q("SELECT ROWID, " + QString(Song::kColumnSpec) + " FROM songs" + " WHERE ROWID = :id", db); + q.bindValue(":id", id); + q.exec(); + if (CheckErrors(q.lastError())) return Song(); + + q.next(); + + Song ret; + ret.InitFromQuery(q); + return ret; +} + +bool LibraryBackend::HasCompilations(const QueryOptions& opt) { + LibraryQuery query(opt); + query.SetColumnSpec("ROWID"); + query.AddWhere("compilation", 1); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return false; + + return q.next(); +} + +QStringList LibraryBackend::GetCompilationAlbums(const QueryOptions& opt) { + LibraryQuery query(opt); + query.SetColumnSpec("DISTINCT album"); + query.AddWhere("compilation", 1); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return QStringList(); + + QStringList ret; + while (q.next()) { + ret << q.value(0).toString(); + } + return ret; +} + +SongList LibraryBackend::GetCompilationSongs(const QueryOptions& opt, const QString& album) { + LibraryQuery query(opt); + query.SetColumnSpec("ROWID, " + QString(Song::kColumnSpec)); + query.AddWhere("compilation", 1); + query.AddWhere("album", album); + + QSqlQuery q(query.Query(Connect())); + q.exec(); + if (CheckErrors(q.lastError())) return SongList(); + + SongList ret; + while (q.next()) { + Song song; + song.InitFromQuery(q); + ret << song; + } + return ret; +} + + diff --git a/src/librarybackend.h b/src/librarybackend.h new file mode 100644 index 000000000..2a95bb0cf --- /dev/null +++ b/src/librarybackend.h @@ -0,0 +1,72 @@ +#ifndef LIBRARYBACKEND_H +#define LIBRARYBACKEND_H + +#include +#include +#include +#include + +#include "directory.h" +#include "song.h" + +struct QueryOptions; + +class LibraryBackend : public QObject { + Q_OBJECT + + public: + LibraryBackend(QObject* parent = 0); + + // This actually refers to the location of the sqlite database + static QString DefaultDirectory(); + + // Get a list of directories in the library. Emits DirectoriesDiscovered. + void LoadDirectoriesAsync(); + + // Counts the songs in the library. Emits TotalSongCountUpdated + void UpdateTotalSongCountAsync(); + + SongList FindSongsInDirectory(int id); + + QStringList GetAllArtists(const QueryOptions& opt); + QStringList GetAlbumsByArtist(const QueryOptions& opt, const QString& artist); + SongList GetSongs(const QueryOptions& opt, const QString& artist, const QString& album); + + bool HasCompilations(const QueryOptions& opt); + QStringList GetCompilationAlbums(const QueryOptions& opt); + SongList GetCompilationSongs(const QueryOptions& opt, const QString& album); + + Song GetSongById(int id); + + void AddDirectory(const QString& path); + void RemoveDirectory(const Directory& dir); + + public slots: + void LoadDirectories(); + void UpdateTotalSongCount(); + void AddOrUpdateSongs(const SongList& songs); + void UpdateMTimesOnly(const SongList& songs); + void DeleteSongs(const SongList& songs); + + signals: + void Error(const QString& message); + + void DirectoriesDiscovered(const DirectoryList& directories); + void DirectoriesDeleted(const DirectoryList& directories); + + void SongsDiscovered(const SongList& songs); + void SongsDeleted(const SongList& songs); + + void TotalSongCountUpdated(int total); + + private: + QSqlDatabase Connect(); + bool CheckErrors(const QSqlError& error); + + private: + static const char* kDatabaseName; + QString directory_; + QMutex connect_mutex_; +}; + +#endif // LIBRARYBACKEND_H diff --git a/src/libraryconfig.cpp b/src/libraryconfig.cpp new file mode 100644 index 000000000..31fd67b45 --- /dev/null +++ b/src/libraryconfig.cpp @@ -0,0 +1,76 @@ +#include "libraryconfig.h" +#include "librarybackend.h" + +#include +#include +#include + +const char* LibraryConfig::kSettingsGroup = "LibraryConfig"; + +LibraryConfig::LibraryConfig(QWidget* parent) + : QDialog(parent), + dir_icon_(":folder.png") +{ + ui_.setupUi(this); + + connect(ui_.add, SIGNAL(clicked()), SLOT(Add())); + connect(ui_.remove, SIGNAL(clicked()), SLOT(Remove())); + connect(ui_.list, SIGNAL(currentRowChanged(int)), SLOT(CurrentRowChanged(int))); +} + +void LibraryConfig::SetBackend(boost::shared_ptr backend) { + backend_ = backend; + + connect(backend_.get(), SIGNAL(DirectoriesDiscovered(DirectoryList)), SLOT(DirectoriesDiscovered(DirectoryList))); + connect(backend_.get(), SIGNAL(DirectoriesDeleted(DirectoryList)), SLOT(DirectoriesDeleted(DirectoryList))); + + ui_.list->setEnabled(true); + ui_.add->setEnabled(true); +} + +void LibraryConfig::Add() { + QSettings settings; + settings.beginGroup(kSettingsGroup); + + QString path(settings.value("last_path", QDir::homePath()).toString()); + path = QFileDialog::getExistingDirectory(this, "Add directory...", path); + + if (!path.isNull()) { + backend_->AddDirectory(path); + } + + settings.setValue("last_path", path); +} + +void LibraryConfig::Remove() { + QListWidgetItem* item = ui_.list->currentItem(); + if (item == NULL) + return; + + Directory dir; + dir.path = item->text(); + dir.id = item->type(); + + backend_->RemoveDirectory(dir); +} + +void LibraryConfig::DirectoriesDiscovered(const DirectoryList& list) { + foreach (const Directory& dir, list) { + new QListWidgetItem(dir_icon_, dir.path, ui_.list, dir.id); + } +} + +void LibraryConfig::DirectoriesDeleted(const DirectoryList& list) { + foreach (const Directory& dir, list) { + for (int i=0 ; icount() ; ++i) { + if (ui_.list->item(i)->type() == dir.id) { + delete ui_.list->takeItem(i); + break; + } + } + } +} + +void LibraryConfig::CurrentRowChanged(int row) { + ui_.remove->setEnabled(row != -1); +} diff --git a/src/libraryconfig.h b/src/libraryconfig.h new file mode 100644 index 000000000..fcefbaa86 --- /dev/null +++ b/src/libraryconfig.h @@ -0,0 +1,39 @@ +#ifndef LIBRARYCONFIG_H +#define LIBRARYCONFIG_H + +#include + +#include + +#include "ui_libraryconfig.h" +#include "directory.h" + +class LibraryBackend; + +class LibraryConfig : public QDialog { + Q_OBJECT + + public: + LibraryConfig(QWidget* parent = 0); + + void SetBackend(boost::shared_ptr backend); + + private slots: + void Add(); + void Remove(); + + void DirectoriesDiscovered(const DirectoryList&); + void DirectoriesDeleted(const DirectoryList&); + + void CurrentRowChanged(int); + + private: + static const char* kSettingsGroup; + + Ui::LibraryConfig ui_; + QIcon dir_icon_; + + boost::shared_ptr backend_; +}; + +#endif // LIBRARYCONFIG_H diff --git a/src/libraryconfig.ui b/src/libraryconfig.ui new file mode 100644 index 000000000..8919e1e73 --- /dev/null +++ b/src/libraryconfig.ui @@ -0,0 +1,146 @@ + + + LibraryConfig + + + + 0 + 0 + 489 + 273 + + + + Music Library + + + + + + These folders will be scanned for music to make up your library + + + + + + + + + false + + + + + + + + + false + + + Add new folder... + + + + :/folder-new.png:/folder-new.png + + + + 22 + 22 + + + + false + + + + + + + false + + + Remove folder + + + + 22 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + list + add + remove + buttonBox + + + + + + + buttonBox + accepted() + LibraryConfig + accept() + + + 248 + 254 + + + 157 + 272 + + + + + buttonBox + rejected() + LibraryConfig + reject() + + + 316 + 260 + + + 286 + 272 + + + + + diff --git a/src/libraryitem.cpp b/src/libraryitem.cpp new file mode 100644 index 000000000..a0e1358ad --- /dev/null +++ b/src/libraryitem.cpp @@ -0,0 +1,35 @@ +#include "libraryitem.h" + +LibraryItem::LibraryItem(Type _type, const QString& _key, LibraryItem* _parent) + : type(_type), + key(_key), + lazy_loaded(_type == Type_Song || _type == Type_Root || _type == Type_Divider), + parent(_parent) +{ + if (parent) { + row = parent->children.count(); + parent->children << this; + } else { + row = 0; + } +} + +LibraryItem::~LibraryItem() { + qDeleteAll(children); +} + +void LibraryItem::Delete(int child_row) { + delete children.takeAt(child_row); + + // Adjust row numbers of those below it :( + for (int i=child_row ; irow --; +} + +LibraryItem* LibraryItem::ChildByKey(const QString& key) const { + foreach (LibraryItem* child, children) { + if (child->key == key) + return child; + } + return NULL; +} diff --git a/src/libraryitem.h b/src/libraryitem.h new file mode 100644 index 000000000..6767a99a9 --- /dev/null +++ b/src/libraryitem.h @@ -0,0 +1,41 @@ +#ifndef LIBRARYITEM_H +#define LIBRARYITEM_H + +#include +#include + +#include "song.h" + +struct LibraryItem { + enum Type { + Type_Root, + Type_Divider, + Type_CompilationArtist, + Type_CompilationAlbum, + Type_Artist, + Type_Album, + Type_Song, + }; + + LibraryItem(Type _type, const QString& _key = QString::null, LibraryItem* _parent = NULL); + ~LibraryItem(); + + void Delete(int child_row); + LibraryItem* ChildByKey(const QString& key) const; + + QString DisplayText() const { return display_text.isNull() ? key : display_text; } + QString SortText() const { return sort_text.isNull() ? key : sort_text; } + + Type type; + QString key; + QString sort_text; + QString display_text; + int row; + bool lazy_loaded; + Song song; + + LibraryItem* parent; + QList children; +}; + +#endif // LIBRARYITEM_H diff --git a/src/libraryquery.cpp b/src/libraryquery.cpp new file mode 100644 index 000000000..d076e4ca5 --- /dev/null +++ b/src/libraryquery.cpp @@ -0,0 +1,56 @@ +#include "libraryquery.h" + +#include +#include + +LibraryQuery::LibraryQuery() +{ +} + +LibraryQuery::LibraryQuery(const QueryOptions& options) +{ + if (!options.filter.isEmpty()) { + where_clauses_ << "(" + "artist LIKE ? OR " + "album LIKE ? OR " + "title LIKE ?)"; + bound_values_ << "%" + options.filter + "%"; + bound_values_ << "%" + options.filter + "%"; + bound_values_ << "%" + options.filter + "%"; + } + + if (options.max_age != -1) { + int cutoff = QDateTime::currentDateTime().toTime_t() - options.max_age; + + where_clauses_ << "ctime > ?"; + bound_values_ << cutoff; + } +} + +void LibraryQuery::AddWhere(const QString& column, const QVariant& value) { + // Do integers inline - sqlite seems to get confused when you pass integers + // to bound parameters + + if (value.type() == QVariant::Int) + where_clauses_ << QString("%1 = %2").arg(column, value.toString()); + else { + where_clauses_ << QString("%1 = ?").arg(column); + bound_values_ << value; + } +} + +QSqlQuery LibraryQuery::Query(QSqlDatabase db) const { + QString sql = QString("SELECT %1 FROM songs").arg(column_spec_); + + if (!where_clauses_.isEmpty()) + sql += " WHERE " + where_clauses_.join(" AND "); + + QSqlQuery q(sql, db); + + // Bind values + foreach (const QVariant& value, bound_values_) { + q.addBindValue(value); + } + + return q; +} diff --git a/src/libraryquery.h b/src/libraryquery.h new file mode 100644 index 000000000..5e3707238 --- /dev/null +++ b/src/libraryquery.h @@ -0,0 +1,33 @@ +#ifndef LIBRARYQUERY_H +#define LIBRARYQUERY_H + +#include +#include +#include +#include +#include + +struct QueryOptions { + QueryOptions() : max_age(-1) {} + + QString filter; + int max_age; +}; + +class LibraryQuery { + public: + LibraryQuery(); + LibraryQuery(const QueryOptions& options); + + void SetColumnSpec(const QString& spec) { column_spec_ = spec; } + void AddWhere(const QString& column, const QVariant& value); + + QSqlQuery Query(QSqlDatabase db) const; + + private: + QString column_spec_; + QStringList where_clauses_; + QVariantList bound_values_; +}; + +#endif // LIBRARYQUERY_H diff --git a/src/libraryview.cpp b/src/libraryview.cpp new file mode 100644 index 000000000..936d1c739 --- /dev/null +++ b/src/libraryview.cpp @@ -0,0 +1,139 @@ +#include "library.h" +#include "libraryview.h" +#include "libraryitem.h" + +#include + +const int LibraryView::kRowsToShow = 50; + +LibraryItemDelegate::LibraryItemDelegate(QObject *parent) + : QStyledItemDelegate(parent) +{ +} + +void LibraryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const { + LibraryItem::Type type = + static_cast(index.data(Library::Role_Type).toInt()); + + switch (type) { + case LibraryItem::Type_Divider: { + QString text(index.data().toString().toUpper()); + + // Draw the background + //QStyledItemDelegate::paint(painter, opt, QModelIndex()); + + painter->save(); + + // Draw the text + QFont bold_font(opt.font); + bold_font.setBold(true); + + QRect text_rect(opt.rect); + text_rect.setLeft(text_rect.left() + 30); + + painter->setPen(opt.palette.color(QPalette::Text)); + painter->setFont(bold_font); + painter->drawText(text_rect, text); + + //Draw the line under the item + QPen line_pen(opt.palette.color(QPalette::Disabled, QPalette::Text).lighter()); + line_pen.setWidth(2); + + painter->setPen(line_pen); + painter->drawLine(opt.rect.bottomLeft(), opt.rect.bottomRight()); + + painter->restore(); + break; + } + + default: + QStyledItemDelegate::paint(painter, opt, index); + break; + } +} + +LibraryView::LibraryView(QWidget* parent) + : QTreeView(parent), + library_(NULL), + total_song_count_(-1), + nomusic_(":nomusic.png") +{ + setItemDelegate(new LibraryItemDelegate(this)); +} + +void LibraryView::SetLibrary(Library *library) { + library_ = library; +} + +void LibraryView::TotalSongCountUpdated(int count) { + bool old = total_song_count_; + total_song_count_ = count; + if (old != total_song_count_) + update(); + + if (total_song_count_ == 0) + setCursor(Qt::PointingHandCursor); + else + unsetCursor(); +} + +void LibraryView::reset() { + QTreeView::reset(); + + // Expand nodes in the tree until we have about 50 rows visible in the view + int rows = model()->rowCount(rootIndex()); + RecursivelyExpand(rootIndex(), &rows); +} + +void LibraryView::paintEvent(QPaintEvent* event) { + QTreeView::paintEvent(event); + QPainter p(viewport()); + + QRect rect(viewport()->rect()); + if (total_song_count_ == 0) { + // Draw the confused tangerine + QRect image_rect((rect.width() - nomusic_.width()) / 2, 50, + nomusic_.width(), nomusic_.height()); + p.drawPixmap(image_rect, nomusic_); + + // Draw the title text + QFont bold_font; + bold_font.setBold(true); + p.setFont(bold_font); + + QFontMetrics metrics(bold_font); + + QRect title_rect(0, image_rect.bottom() + 20, rect.width(), metrics.height()); + p.drawText(title_rect, Qt::AlignHCenter, "Your library is empty!"); + + // Draw the other text + p.setFont(QFont()); + + QRect text_rect(0, title_rect.bottom() + 5, rect.width(), metrics.height()); + p.drawText(text_rect, Qt::AlignHCenter, "Click here to add some music"); + } +} + +void LibraryView::mouseReleaseEvent(QMouseEvent* e) { + QTreeView::mouseReleaseEvent(e); + + if (total_song_count_ == 0) { + emit ShowConfigDialog(); + } +} + +bool LibraryView::RecursivelyExpand(const QModelIndex& index, int* count) { + int children = model()->rowCount(index); + if (*count + children > kRowsToShow) + return false; + + expand(index); + *count += children; + + for (int i=0 ; iindex(i, 0, index), count)) + return false; + } + + return true; +} diff --git a/src/libraryview.h b/src/libraryview.h new file mode 100644 index 000000000..a62ad67bb --- /dev/null +++ b/src/libraryview.h @@ -0,0 +1,50 @@ +#ifndef LIBRARYVIEW_H +#define LIBRARYVIEW_H + +#include +#include + +class Library; + +class LibraryItemDelegate : public QStyledItemDelegate { + public: + LibraryItemDelegate(QObject* parent); + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; +}; + +class LibraryView : public QTreeView { + Q_OBJECT + + public: + LibraryView(QWidget* parent = 0); + + void SetLibrary(Library* library); + + public slots: + void TotalSongCountUpdated(int count); + + signals: + void ShowConfigDialog(); + + protected: + // QAbstractItemView + void reset(); + + // QWidget + void paintEvent(QPaintEvent* event); + void mouseReleaseEvent(QMouseEvent* e); + + private: + void RecheckIsEmpty(); + bool RecursivelyExpand(const QModelIndex& index, int* count); + + private: + static const int kRowsToShow; + + Library* library_; + int total_song_count_; + + QPixmap nomusic_; +}; + +#endif // LIBRARYVIEW_H diff --git a/src/librarywatcher.cpp b/src/librarywatcher.cpp new file mode 100644 index 000000000..e624598ae --- /dev/null +++ b/src/librarywatcher.cpp @@ -0,0 +1,153 @@ +#include "librarywatcher.h" +#include "librarybackend.h" +#include "enginebase.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + + +LibraryWatcher::LibraryWatcher(QObject* parent) + : QObject(parent), + fs_watcher_(new QFileSystemWatcher(this)), + rescan_timer_(new QTimer(this)) +{ + rescan_timer_->setInterval(1000); + rescan_timer_->setSingleShot(true); + + connect(fs_watcher_, SIGNAL(directoryChanged(QString)), SLOT(DirectoryChanged(QString))); + connect(rescan_timer_, SIGNAL(timeout()), SLOT(RescanPathsNow())); +} + +void LibraryWatcher::AddDirectories(const DirectoryList& directories) { + // Iterate through each directory to find a list of files that look like they + // could be music. + + foreach (const Directory& dir, directories) { + paths_watched_[dir.path] = dir; + ScanDirectory(dir.path); + + // Start monitoring this directory for more changes + fs_watcher_->addPath(dir.path); + } +} + +void LibraryWatcher::RemoveDirectories(const DirectoryList &directories) { + foreach (const Directory& dir, directories) { + fs_watcher_->removePath(dir.path); + paths_watched_.remove(dir.path); + paths_needing_rescan_.removeAll(dir.path); + } +} + +void LibraryWatcher::ScanDirectory(const QString& path) { + const Directory& dir = paths_watched_[path]; + qDebug() << "Scanning" << path; + emit ScanStarted(); + + QStringList files_on_disk; + QDirIterator it(dir.path, + QDir::Files | QDir::NoDotAndDotDot | QDir::Readable, + QDirIterator::Subdirectories | QDirIterator::FollowSymlinks); + while (it.hasNext()) { + QString path(it.next()); + + // Don't bother if the engine can't decode it + if (!engine_->canDecode(QUrl::fromLocalFile(path))) + continue; + + files_on_disk << path; + } + + // Ask the database for a list of files in this directory + SongList songs_in_db = backend_->FindSongsInDirectory(dir.id); + + // Now compare the list from the database with the list of files on disk + SongList new_songs; + SongList touched_songs; + foreach (const QString& file, files_on_disk) { + Song matching_song; + if (FindSongByPath(songs_in_db, file, &matching_song)) { + // The song is in the database and still on disk. + // Check the mtime to see if it's been changed since it was added. + + if (matching_song.mtime() != QFileInfo(file).lastModified().toTime_t()) { + qDebug() << file << "changed"; + + // It's changed - reread the metadata from the file + Song song_on_disk; + song_on_disk.InitFromFile(file, dir.id); + song_on_disk.set_id(matching_song.id()); + + if (!matching_song.IsMetadataEqual(song_on_disk)) { + qDebug() << file << "metadata changed"; + // Update the song in the DB + new_songs << song_on_disk; + } else { + // Only the metadata changed + touched_songs << song_on_disk; + } + } + } else { + // The song is on disk but not in the DB + + Song song; + song.InitFromFile(file, dir.id); + if (!song.is_valid()) + continue; + qDebug() << file << "created"; + + new_songs << song; + } + } + + if (!new_songs.isEmpty()) + emit NewOrUpdatedSongs(new_songs); + + if (!touched_songs.isEmpty()) + emit SongsMTimeUpdated(touched_songs); + + // Look for deleted songs + SongList deleted_songs; + foreach (const Song& song, songs_in_db) { + if (!files_on_disk.contains(song.filename())) { + qDebug() << "Song deleted from disk:" << song.filename(); + deleted_songs << song; + } + } + + if (!deleted_songs.isEmpty()) + emit SongsDeleted(deleted_songs); + + qDebug() << "Finished scanning" << path; + emit ScanFinished(); +} + +bool LibraryWatcher::FindSongByPath(const SongList& list, const QString& path, Song* out) { + foreach (const Song& song, list) { + if (song.filename() == path) { + *out = song; + return true; + } + } + return false; +} + +void LibraryWatcher::DirectoryChanged(const QString &path) { + if (!paths_needing_rescan_.contains(path)) + paths_needing_rescan_ << path; + + rescan_timer_->start(); +} + +void LibraryWatcher::RescanPathsNow() { + foreach (const QString& path, paths_needing_rescan_) + ScanDirectory(path); + paths_needing_rescan_.clear(); +} diff --git a/src/librarywatcher.h b/src/librarywatcher.h new file mode 100644 index 000000000..efa32a60a --- /dev/null +++ b/src/librarywatcher.h @@ -0,0 +1,59 @@ +#ifndef LIBRARYWATCHER_H +#define LIBRARYWATCHER_H + +#include "directory.h" +#include "song.h" +#include "engine_fwd.h" + +#include +#include +#include + +#include + +class QFileSystemWatcher; +class QTimer; + +class LibraryBackend; + +class LibraryWatcher : public QObject { + Q_OBJECT + + public: + LibraryWatcher(QObject* parent = 0); + + void SetBackend(boost::shared_ptr backend) { backend_ = backend; } + void SetEngine(EngineBase* engine) { engine_ = engine; } // TODO: shared_ptr + + signals: + void NewOrUpdatedSongs(const SongList& songs); + void SongsMTimeUpdated(const SongList& songs); + void SongsDeleted(const SongList& songs); + + void ScanStarted(); + void ScanFinished(); + + public slots: + void AddDirectories(const DirectoryList& directories); + void RemoveDirectories(const DirectoryList& directories); + + private slots: + void DirectoryChanged(const QString& path); + void RescanPathsNow(); + void ScanDirectory(const QString& path); + + private: + static bool FindSongByPath(const SongList& list, const QString& path, Song* out); + + private: + EngineBase* engine_; + boost::shared_ptr backend_; + + QFileSystemWatcher* fs_watcher_; + QTimer* rescan_timer_; + + QMap paths_watched_; + QStringList paths_needing_rescan_; +}; + +#endif // LIBRARYWATCHER_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 000000000..23f480eaa --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,20 @@ +#include "mainwindow.h" +#include "directory.h" +#include "song.h" + +#include + +int main(int argc, char *argv[]) { + QCoreApplication::setApplicationName("Tangerine"); + QCoreApplication::setOrganizationName("Tangerine"); + QCoreApplication::setOrganizationDomain("davidsansome.com"); + + qRegisterMetaType("DirectoryList"); + qRegisterMetaType("SongList"); + + QApplication a(argc, argv); + + MainWindow w; + + return a.exec(); +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 000000000..779445438 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,349 @@ +#include "mainwindow.h" +#include "player.h" +#include "playlist.h" +#include "library.h" +#include "libraryconfig.h" +#include "songplaylistitem.h" +#include "systemtrayicon.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int MainWindow::kStateVersion = 1; +const char* MainWindow::kSettingsGroup = "MainWindow"; + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), + playlist_(new Playlist(this)), + player_(new Player(playlist_, this)), + library_(new Library(player_->GetEngine(), this)), + library_sort_model_(new QSortFilterProxyModel(this)), + file_model_(new QFileSystemModel(this)), + file_undo_stack_(new QUndoStack(this)), + tray_icon_(new SystemTrayIcon(this)) +{ + ui_.setupUi(this); + tray_icon_->setIcon(windowIcon()); + tray_icon_->setToolTip("Tangerine"); + tray_icon_->show(); + + ui_.volume->setValue(player_->GetVolume()); + + // Models + library_sort_model_->setSourceModel(library_); + library_sort_model_->setSortRole(Library::Role_SortText); + library_sort_model_->setDynamicSortFilter(true); + library_sort_model_->sort(0); + + playlist_->Restore(); + + ui_.playlist->setModel(playlist_); + ui_.library_view->setModel(library_sort_model_); + ui_.library_view->SetLibrary(library_); + + // File browser + ui_.file_view->setModel(file_model_); + ChangeFilePathWithoutUndo(QDir::homePath()); + + connect(ui_.file_back, SIGNAL(clicked()), SLOT(FileBack())); + connect(ui_.file_forward, SIGNAL(clicked()), SLOT(FileForward())); + connect(ui_.file_home, SIGNAL(clicked()), SLOT(FileHome())); + connect(ui_.file_up, SIGNAL(clicked()), SLOT(FileUp())); + connect(ui_.file_path, SIGNAL(textChanged(QString)), SLOT(ChangeFilePath(QString))); + + connect(file_undo_stack_, SIGNAL(canUndoChanged(bool)), ui_.file_back, SLOT(setEnabled(bool))); + connect(file_undo_stack_, SIGNAL(canRedoChanged(bool)), ui_.file_forward, SLOT(setEnabled(bool))); + + connect(ui_.file_view, SIGNAL(activated(QModelIndex)), SLOT(FileClicked(QModelIndex))); + connect(ui_.file_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(FileDoubleClicked(QModelIndex))); + + // Action connections + connect(ui_.action_next_track, SIGNAL(triggered()), player_, SLOT(Next())); + connect(ui_.action_previous_track, SIGNAL(triggered()), player_, SLOT(Previous())); + connect(ui_.action_play_pause, SIGNAL(triggered()), player_, SLOT(PlayPause())); + connect(ui_.action_stop, SIGNAL(triggered()), player_, SLOT(Stop())); + connect(ui_.action_quit, SIGNAL(triggered()), qApp, SLOT(quit())); + connect(ui_.action_stop_after_this_track, SIGNAL(triggered()), SLOT(StopAfterCurrent())); + connect(ui_.library_filter, SIGNAL(textChanged(QString)), library_, SLOT(SetFilterText(QString))); + + // Give actions to buttons + ui_.forward_button->setDefaultAction(ui_.action_next_track); + ui_.back_button->setDefaultAction(ui_.action_previous_track); + ui_.pause_play_button->setDefaultAction(ui_.action_play_pause); + ui_.stop_button->setDefaultAction(ui_.action_stop); + + // Stop actions + QMenu* stop_menu = new QMenu(this); + stop_menu->addAction(ui_.action_stop); + stop_menu->addAction(ui_.action_stop_after_this_track); + ui_.stop_button->setMenu(stop_menu); + + // Player connections + connect(ui_.volume, SIGNAL(valueChanged(int)), player_, SLOT(SetVolume(int))); + + connect(player_, SIGNAL(Error(QString)), SLOT(ReportError(QString))); + connect(player_, SIGNAL(Paused()), SLOT(MediaPaused())); + connect(player_, SIGNAL(Playing()), SLOT(MediaPlaying())); + connect(player_, SIGNAL(Stopped()), SLOT(MediaStopped())); + + connect(player_, SIGNAL(Paused()), playlist_, SLOT(Paused())); + connect(player_, SIGNAL(Playing()), playlist_, SLOT(Playing())); + connect(player_, SIGNAL(Stopped()), playlist_, SLOT(Stopped())); + + connect(player_, SIGNAL(Paused()), ui_.playlist, SLOT(StopGlowing())); + connect(player_, SIGNAL(Playing()), ui_.playlist, SLOT(StartGlowing())); + connect(player_, SIGNAL(Stopped()), ui_.playlist, SLOT(StopGlowing())); + + connect(ui_.playlist, SIGNAL(doubleClicked(QModelIndex)), SLOT(PlayIndex(QModelIndex))); + + // Library connections + connect(library_, SIGNAL(Error(QString)), SLOT(ReportError(QString))); + connect(ui_.library_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(LibraryDoubleClick(QModelIndex))); + connect(ui_.library_view, SIGNAL(ShowConfigDialog()), library_, SLOT(ShowConfig())); + connect(library_, SIGNAL(TotalSongCountUpdated(int)), ui_.library_view, SLOT(TotalSongCountUpdated(int))); + + // Age filters + QActionGroup* filter_age_group = new QActionGroup(this); + filter_age_group->addAction(ui_.filter_age_all); + filter_age_group->addAction(ui_.filter_age_today); + filter_age_group->addAction(ui_.filter_age_week); + filter_age_group->addAction(ui_.filter_age_month); + filter_age_group->addAction(ui_.filter_age_three_months); + filter_age_group->addAction(ui_.filter_age_year); + filter_age_group->setExclusive(true); + + QSignalMapper* filter_age_mapper = new QSignalMapper(this); + filter_age_mapper->setMapping(ui_.filter_age_all, -1); + filter_age_mapper->setMapping(ui_.filter_age_today, 60*60*24); + filter_age_mapper->setMapping(ui_.filter_age_week, 60*60*24*7); + filter_age_mapper->setMapping(ui_.filter_age_month, 60*60*24*30); + filter_age_mapper->setMapping(ui_.filter_age_three_months, 60*60*24*30*3); + filter_age_mapper->setMapping(ui_.filter_age_year, 60*60*24*365); + + connect(ui_.filter_age_all, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(ui_.filter_age_today, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(ui_.filter_age_week, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(ui_.filter_age_month, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(ui_.filter_age_three_months, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(ui_.filter_age_year, SIGNAL(triggered()), filter_age_mapper, SLOT(map())); + connect(filter_age_mapper, SIGNAL(mapped(int)), library_, SLOT(SetFilterAge(int))); + connect(ui_.library_filter_clear, SIGNAL(clicked()), SLOT(ClearLibraryFilter())); + + // Library config menu + QMenu* library_menu = new QMenu(this); + library_menu->addActions(filter_age_group->actions()); + library_menu->addSeparator(); + library_menu->addAction("Configure library...", library_, SLOT(ShowConfig())); + ui_.library_options->setMenu(library_menu); + + // Tray icon + QMenu* tray_menu = new QMenu(this); + tray_menu->addAction(ui_.action_previous_track); + tray_menu->addAction(ui_.action_play_pause); + tray_menu->addAction(ui_.action_stop); + tray_menu->addAction(ui_.action_next_track); + tray_menu->addSeparator(); + tray_menu->addAction(ui_.action_quit); + tray_icon_->setContextMenu(tray_menu); + + connect(tray_icon_, SIGNAL(WheelEvent(int)), SLOT(VolumeWheelEvent(int))); + connect(tray_icon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(TrayClicked(QSystemTrayIcon::ActivationReason))); + + // Analyzer + ui_.analyzer->set_engine(player_->GetEngine()); + + // Load theme + QFile stylesheet(":mainwindow.css"); + if (!stylesheet.open(QIODevice::ReadOnly)) { + qWarning("Could not open stylesheet"); + } else { + setStyleSheet(stylesheet.readAll()); + } + + // Load geometry + QSettings settings; + settings.beginGroup(kSettingsGroup); + + restoreGeometry(settings.value("geometry").toByteArray()); + if (!restoreState(settings.value("state").toByteArray(), kStateVersion)) { + tabifyDockWidget(ui_.files_dock, ui_.radio_dock); + tabifyDockWidget(ui_.files_dock, ui_.library_dock); + } + + if (!settings.value("hidden", false).toBool()) + show(); + + library_->StartThreads(); +} + +MainWindow::~MainWindow() { + SaveGeometry(); +} + +void MainWindow::FileUp() { + QDir dir(file_model_->rootDirectory()); + dir.cdUp(); + + ChangeFilePath(dir.path()); +} + +void MainWindow::FileBack() { + QString new_path(file_undo_stack_->command(file_undo_stack_->index()-1)->text()); + file_undo_stack_->undo(); + ChangeFilePathWithoutUndo(new_path); +} + +void MainWindow::FileForward() { + QString new_path(file_undo_stack_->command(file_undo_stack_->index()+1)->text()); + file_undo_stack_->redo(); + ChangeFilePathWithoutUndo(new_path); +} + +void MainWindow::FileHome() { + ChangeFilePath(QDir::homePath()); +} + +void MainWindow::ChangeFilePath(const QString& new_path) { + QFileInfo info(new_path); + if (!info.exists() || !info.isDir()) + return; + + QString old_path(file_model_->rootPath()); + + ChangeFilePathWithoutUndo(new_path); + file_undo_stack_->push(new QUndoCommand(old_path)); +} + +void MainWindow::ChangeFilePathWithoutUndo(const QString& new_path) { + ui_.file_view->setRootIndex(file_model_->setRootPath(new_path)); + ui_.file_path->setText(new_path); + + QDir dir(new_path); + ui_.file_up->setEnabled(dir.cdUp()); +} + +void MainWindow::FileClicked(const QModelIndex& index) { + if (file_model_->isDir(index)) + ChangeFilePath(file_model_->filePath(index)); +} + +void MainWindow::FileDoubleClicked(const QModelIndex& index) { + if (file_model_->isDir(index)) + return; + + Song song; + song.InitFromFile(file_model_->filePath(index), -1); + + if (!song.is_valid()) + return; + + QModelIndex playlist_index = playlist_->InsertSongs(SongList() << song); + + if (playlist_index.isValid() && player_->GetState() != Engine::Playing) + player_->PlayAt(playlist_index.row()); +} + +void MainWindow::ReportError(const QString& message) { + QMessageBox::warning(this, "Error", message); +} + +void MainWindow::MediaStopped() { + ui_.action_stop->setEnabled(false); + ui_.action_stop_after_this_track->setEnabled(false); + ui_.action_play_pause->setIcon(QIcon(":media-playback-start.png")); + ui_.action_play_pause->setText("Play"); +} + +void MainWindow::MediaPaused() { + ui_.action_stop->setEnabled(true); + ui_.action_stop_after_this_track->setEnabled(true); + ui_.action_play_pause->setIcon(QIcon(":media-playback-start.png")); + ui_.action_play_pause->setText("Play"); +} + +void MainWindow::MediaPlaying() { + ui_.action_stop->setEnabled(true); + ui_.action_stop_after_this_track->setEnabled(true); + ui_.action_play_pause->setIcon(QIcon(":media-playback-pause.png")); + ui_.action_play_pause->setText("Pause"); +} + +void MainWindow::resizeEvent(QResizeEvent*) { + SaveGeometry(); +} + +void MainWindow::SaveGeometry() { + QSettings settings; + settings.beginGroup(kSettingsGroup); + settings.setValue("geometry", saveGeometry()); + settings.setValue("state", saveState(kStateVersion)); +} + +void MainWindow::PlayIndex(const QModelIndex& index) { + if (!index.isValid()) + return; + + player_->PlayAt(index.row()); +} + +void MainWindow::LibraryDoubleClick(const QModelIndex& index) { + QModelIndex first_song = + playlist_->InsertSongs(library_->GetChildSongs( + library_sort_model_->mapToSource(index))); + + if (first_song.isValid() && player_->GetState() != Engine::Playing) + player_->PlayAt(first_song.row()); +} + +void MainWindow::VolumeWheelEvent(int delta) { + ui_.volume->setValue(ui_.volume->value() + delta / 20); +} + +void MainWindow::TrayClicked(QSystemTrayIcon::ActivationReason reason) { + switch (reason) { + case QSystemTrayIcon::DoubleClick: + case QSystemTrayIcon::Trigger: + SetHiddenInTray(isVisible()); + break; + + case QSystemTrayIcon::MiddleClick: + player_->PlayPause(); + break; + + default: + break; + } +} + +void MainWindow::StopAfterCurrent() { + playlist_->StopAfter(playlist_->current_item()); +} + +void MainWindow::closeEvent(QCloseEvent* event) { + event->ignore(); + SetHiddenInTray(true); +} + +void MainWindow::SetHiddenInTray(bool hidden) { + QSettings settings; + settings.beginGroup(kSettingsGroup); + settings.setValue("hidden", hidden); + + if (hidden) + hide(); + else + show(); +} + +void MainWindow::ClearLibraryFilter() { + ui_.library_filter->clear(); + ui_.library_filter->setFocus(); +} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 000000000..5e2a879a4 --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,77 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +#include "ui_mainwindow.h" + +class Playlist; +class Player; +class Library; +class LibraryConfig; + +class QFileSystemModel; +class QSortFilterProxyModel; +class QUndoStack; +class SystemTrayIcon; + +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + + void SetHiddenInTray(bool hidden); + + protected: + void resizeEvent(QResizeEvent* event); + void closeEvent(QCloseEvent* event); + + private slots: + void FileUp(); + void FileBack(); + void FileForward(); + void FileHome(); + void ChangeFilePath(const QString& new_path); + void FileClicked(const QModelIndex& index); + void FileDoubleClicked(const QModelIndex& index); + + void ReportError(const QString& message); + void MediaStopped(); + void MediaPaused(); + void MediaPlaying(); + + void PlayIndex(const QModelIndex& index); + void StopAfterCurrent(); + + void LibraryDoubleClick(const QModelIndex& index); + void ClearLibraryFilter(); + + void VolumeWheelEvent(int delta); + void TrayClicked(QSystemTrayIcon::ActivationReason reason); + + private: + void ChangeFilePathWithoutUndo(const QString& new_path); + void SaveGeometry(); + + private: + static const int kStateVersion; + static const char* kSettingsGroup; + + Ui::MainWindow ui_; + + Playlist* playlist_; + Player* player_; + Library* library_; + + QSortFilterProxyModel* library_sort_model_; + + QFileSystemModel* file_model_; + QUndoStack* file_undo_stack_; + + SystemTrayIcon* tray_icon_; +}; + +#endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui new file mode 100644 index 000000000..e800ebb5d --- /dev/null +++ b/src/mainwindow.ui @@ -0,0 +1,554 @@ + + + MainWindow + + + + 0 + 0 + 804 + 559 + + + + Tangerine + + + + :/icon.png:/icon.png + + + + + 0 + + + 0 + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + true + + + true + + + QAbstractItemView::DragDrop + + + QAbstractItemView::ExtendedSelection + + + false + + + true + + + false + + + true + + + true + + + + + + + QFrame::NoFrame + + + + 1 + + + 0 + + + + + + 22 + 22 + + + + true + + + + + + + + 22 + 22 + + + + true + + + + + + + false + + + + 22 + 22 + + + + QToolButton::MenuButtonPopup + + + true + + + + + + + + 22 + 22 + + + + true + + + + + + + + 16777215 + 30 + + + + Qt::Vertical + + + + + + + + 100 + 0 + + + + + 0 + 36 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + 100 + + + Qt::Horizontal + + + + + + + + + + + + QDockWidget::DockWidgetMovable + + + Library + + + 1 + + + + + 0 + + + 0 + + + + + 0 + + + + + + :/clear.png:/clear.png + + + + 22 + 22 + + + + true + + + + + + + + + + + :/configure.png:/configure.png + + + + 16 + 16 + + + + QToolButton::InstantPopup + + + + + + + + + true + + + QAbstractItemView::DragOnly + + + true + + + QAbstractItemView::ExtendedSelection + + + true + + + true + + + false + + + + + + + + + QDockWidget::DockWidgetMovable + + + Radio + + + 1 + + + + + + QDockWidget::DockWidgetMovable + + + Files + + + 1 + + + + + 0 + + + 0 + + + + + 0 + + + + + false + + + + :/go-previous.png:/go-previous.png + + + true + + + + + + + false + + + ... + + + + :/go-next.png:/go-next.png + + + true + + + + + + + ... + + + + :/go-up.png:/go-up.png + + + true + + + + + + + ... + + + + :/go-home.png:/go-home.png + + + true + + + + + + + + + + + + + + + + + + :/media-skip-backward.png:/media-skip-backward.png + + + Previous track + + + Media Previous + + + + + + :/media-playback-start.png:/media-playback-start.png + + + Play + + + Media Play + + + + + false + + + + :/media-playback-stop.png:/media-playback-stop.png + + + Stop + + + Media Stop + + + + + + :/media-skip-forward.png:/media-skip-forward.png + + + Next track + + + Media Next + + + + + + :/exit.png:/exit.png + + + &Quit + + + Ctrl+Q + + + + + + :/media-playback-stop.png:/media-playback-stop.png + + + Stop after this track + + + + + true + + + true + + + Entire collection + + + + + true + + + Added today + + + + + true + + + Added this week + + + + + true + + + Added within three months + + + Added within three months + + + + + true + + + Added this year + + + + + true + + + Added this month + + + + + + + BlockAnalyzer + QWidget +

analyzers/blockanalyzer.h
+ 1 + + + Amarok::VolumeSlider + QSlider +
sliderwidget.h
+
+ + PlaylistView + QTreeView +
playlistview.h
+
+ + LibraryView + QTreeView +
libraryview.h
+
+ + + + diff --git a/src/player.cpp b/src/player.cpp new file mode 100644 index 000000000..fbf336783 --- /dev/null +++ b/src/player.cpp @@ -0,0 +1,103 @@ +#include "player.h" +#include "playlist.h" +#include "xine-engine.h" + +#include + +Player::Player(Playlist* playlist, QObject* parent) + : QObject(parent), + playlist_(playlist), + engine_(new XineEngine) +{ + if (!engine_->init()) { + qFatal("Couldn't load engine"); + } + + settings_.beginGroup("Player"); + SetVolume(settings_.value("volume", 50).toInt()); + + connect(engine_, SIGNAL(stateChanged(Engine::State)), SLOT(EngineStateChanged(Engine::State))); + connect(engine_, SIGNAL(trackEnded()), SLOT(Next())); +} + +void Player::Next() { + int i = playlist_->next_item(); + playlist_->set_current_item(i); + if (i == -1) { + Stop(); + return; + } + + qDebug() << "Playing item" << i; + PlayAt(i); +} + +void Player::PlayPause() { + switch (engine_->state()) { + case Engine::Paused: + qDebug() << "Unpausing"; + engine_->unpause(); + break; + + case Engine::Playing: + qDebug() << "Pausing"; + engine_->pause(); + break; + + case Engine::Empty: + case Engine::Idle: { + int i = playlist_->current_item(); + if (i == -1) { + if (playlist_->rowCount() == 0) + break; + i = 0; + } + PlayAt(i); + break; + } + } +} + +void Player::Stop() { + qDebug() << "Stopping"; + engine_->stop(); + playlist_->set_current_item(-1); +} + +void Player::Previous() { + int i = playlist_->previous_item(); + playlist_->set_current_item(i); + if (i == -1) { + Stop(); + return; + } + + PlayAt(i); +} + +void Player::EngineStateChanged(Engine::State state) { + switch (state) { + case Engine::Paused: emit Paused(); break; + case Engine::Playing: emit Playing(); break; + case Engine::Empty: + case Engine::Idle: emit Stopped(); break; + } +} + +void Player::SetVolume(int value) { + settings_.setValue("volume", value); + engine_->setVolume(value); +} + +int Player::GetVolume() const { + return engine_->volume(); +} + +Engine::State Player::GetState() const { + return engine_->state(); +} + +void Player::PlayAt(int index) { + playlist_->set_current_item(index); + engine_->play(playlist_->item_at(index)->Url()); +} diff --git a/src/player.h b/src/player.h new file mode 100644 index 000000000..5fd5ecc96 --- /dev/null +++ b/src/player.h @@ -0,0 +1,46 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include +#include + +#include "engine_fwd.h" + +class Playlist; +class Settings; + +class Player : public QObject { + Q_OBJECT + + public: + Player(Playlist* playlist, QObject* parent = 0); + + EngineBase* GetEngine() { return engine_; } + Engine::State GetState() const; + int GetVolume() const; + + public slots: + void PlayAt(int index); + void PlayPause(); + void Next(); + void Previous(); + void Stop(); + void SetVolume(int value); + + signals: + void Playing(); + void Paused(); + void Stopped(); + void Error(const QString& message); + + private slots: + void EngineStateChanged(Engine::State); + + private: + Playlist* playlist_; + QSettings settings_; + + EngineBase* engine_; +}; + +#endif // PLAYER_H diff --git a/src/playlist.cpp b/src/playlist.cpp new file mode 100644 index 000000000..fcb139025 --- /dev/null +++ b/src/playlist.cpp @@ -0,0 +1,364 @@ +#include "playlist.h" +#include "songmimedata.h" +#include "songplaylistitem.h" + +#include +#include +#include +#include + +#include + +const char* Playlist::kRowsMimetype = "application/x-tangerine-playlist-rows"; +const char* Playlist::kSettingsGroup = "Playlist"; + +Playlist::Playlist(QObject *parent) : + QAbstractListModel(parent), + current_is_paused_(false), + ignore_next_sort_(true) +{ +} + +Playlist::~Playlist() { + qDeleteAll(items_); +} + +QVariant Playlist::headerData(int section, Qt::Orientation, int role) const { + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case Column_Title: return "Title"; + case Column_Artist: return "Artist"; + case Column_Album: return "Album"; + case Column_Length: return "Length"; + case Column_Track: return "Track"; + } + + return QVariant(); +} + +QVariant Playlist::data(const QModelIndex& index, int role) const { + switch (role) { + case Role_IsCurrent: + return current_item_.isValid() && index.row() == current_item_.row(); + + case Role_IsPaused: + return current_is_paused_; + + case Role_StopAfter: + return stop_after_.isValid() && stop_after_.row() == index.row(); + + case Qt::DisplayRole: { + PlaylistItem* item = items_[index.row()]; + + switch (index.column()) { + case Column_Title: return item->Title(); + case Column_Artist: return item->Artist(); + case Column_Album: return item->Album(); + case Column_Length: return item->Length(); + case Column_Track: return item->Track(); + } + } + + default: + return QVariant(); + } +} + +int Playlist::current_item() const { + return current_item_.isValid() ? current_item_.row() : -1; +} + +int Playlist::next_item() const { + int i = current_item() + 1; + if (i >= items_.count()) + return -1; + if (stop_after_.isValid() && current_item() == stop_after_.row()) + return -1; + + return i; +} + +int Playlist::previous_item() const { + int i = current_item() - 1; + if (i < 0) + return -1; + return i; +} + +void Playlist::set_current_item(int i) { + QModelIndex old_current = current_item_; + current_item_ = QPersistentModelIndex(index(i, 0, QModelIndex())); + + if (old_current.isValid()) + emit dataChanged(old_current, old_current.sibling(old_current.row(), ColumnCount)); + if (current_item_.isValid()) + emit dataChanged(current_item_, current_item_.sibling(current_item_.row(), ColumnCount)); +} + +Qt::ItemFlags Playlist::flags(const QModelIndex &index) const { + if (index.isValid()) + return Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsDropEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QStringList Playlist::mimeTypes() const { + return QStringList() << "text/uri-list" << kRowsMimetype; +} + +Qt::DropActions Playlist::supportedDropActions() const { + return Qt::MoveAction | Qt::CopyAction; +} + +bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int, const QModelIndex&) { + if (action == Qt::IgnoreAction) + return false; + + QList added_items; + if (const SongMimeData* song_data = qobject_cast(data)) { + // Dragged from the library + InsertSongs(song_data->songs, row); + } else if (data->hasFormat(kRowsMimetype)) { + // Dragged from the playlist + // Rearranging it is tricky... + + // Get the list of rows that were moved + QList source_rows; + QDataStream stream(data->data(kRowsMimetype)); + stream >> source_rows; + qStableSort(source_rows); // Make sure we take them in order + + layoutAboutToBeChanged(); + QList moved_items; + + // Take the items out of the list first, keeping track of whether the + // insertion point changes + int offset = 0; + foreach (int source_row, source_rows) { + moved_items << items_.takeAt(source_row-offset); + if (row != -1 && row >= source_row) + row --; + offset++; + } + + // Put the items back in + const int start = row == -1 ? items_.count() : row; + for (int i=start ; ihasUrls()) { + // URL list dragged from some other app probably + SongList songs; + foreach (const QUrl& url, data->urls()) { + if (url.scheme() != "file") + continue; + + Song song; + song.InitFromFile(url.toLocalFile(), -1); + if (!song.is_valid()) + continue; + + songs << songs; + } + + InsertSongs(songs, row); + } + + return true; +} + +QModelIndex Playlist::InsertItems(const QList& items, int after) { + if (items.isEmpty()) + return QModelIndex(); + + const int start = after == -1 ? items_.count() : after; + const int end = start + items.count() - 1; + + beginInsertRows(QModelIndex(), start, end); + + for (int i=start ; i<=end ; ++i) { + items_.insert(i, items[i - start]); + } + + endInsertRows(); + + Save(); + + return index(start, 0); +} + +QModelIndex Playlist::InsertSongs(const SongList& songs, int after) { + QList items; + foreach (const Song& song, songs) { + items << new SongPlaylistItem(song); + } + return InsertItems(items, after); +} + +QMimeData* Playlist::mimeData(const QModelIndexList& indexes) const { + QMimeData* data = new QMimeData; + + QList urls; + QList rows; + foreach (const QModelIndex& index, indexes) { + if (index.column() != 0) + continue; + + urls << items_[index.row()]->Url(); + rows << index.row(); + } + + QBuffer buf; + buf.open(QIODevice::WriteOnly); + QDataStream stream(&buf); + stream << rows; + buf.close(); + + data->setUrls(urls); + data->setData(kRowsMimetype, buf.data()); + + return data; +} + +bool Playlist::CompareItems(int column, Qt::SortOrder order, + const PlaylistItem* _a, const PlaylistItem* _b) { + const PlaylistItem* a = order == Qt::AscendingOrder ? _a : _b; + const PlaylistItem* b = order == Qt::AscendingOrder ? _b : _a; + + switch (column) { + case Column_Title: return a->Title() < b->Title(); + case Column_Artist: return a->Artist() < b->Artist(); + case Column_Album: return a->Album() < b->Album(); + case Column_Length: return a->Length() < b->Length(); + case Column_Track: return a->Track() < b->Track(); + } + return false; +} + +void Playlist::sort(int column, Qt::SortOrder order) { + if (ignore_next_sort_) { + ignore_next_sort_ = false; + return; + } + + layoutAboutToBeChanged(); + + // This is a slow and nasty way to keep the persistent indices + QMap old_persistent_mappings; + foreach (const QModelIndex& index, persistentIndexList()) { + old_persistent_mappings[index.row()] = items_[index.row()]; + } + + qStableSort(items_.begin(), items_.end(), + boost::bind(&Playlist::CompareItems, column, order, _1, _2)); + + QMapIterator it(old_persistent_mappings); + while (it.hasNext()) { + it.next(); + for (int col=0 ; coltype_string()); + items_.at(i)->Save(s); + } + s.endArray(); +} + +void Playlist::Restore() { + qDeleteAll(items_); + items_.clear(); + + QSettings s; + s.beginGroup(kSettingsGroup); + + int count = s.beginReadArray("items"); + for (int i=0 ; iRestore(s); + items_ << item; + } + s.endArray(); + + reset(); +} + +bool Playlist::removeRows(int row, int count, const QModelIndex& parent) { + beginRemoveRows(parent, row, row+count-1); + + // Remove items + for (int i=0 ; i +#include + +#include "playlistitem.h" +#include "song.h" + +class Playlist : public QAbstractListModel { + Q_OBJECT + + public: + Playlist(QObject* parent = 0); + ~Playlist(); + + enum Column { + Column_Title = 0, + Column_Artist, + Column_Album, + Column_Length, + Column_Track, + + ColumnCount + }; + + enum Role { + Role_IsCurrent = Qt::UserRole + 1, + Role_IsPaused, + Role_StopAfter, + }; + + static const char* kRowsMimetype; + static const char* kSettingsGroup; + + static bool CompareItems(int column, Qt::SortOrder order, + const PlaylistItem* a, const PlaylistItem* b); + + // Persistence + void Save() const; + void Restore(); + + // Accessors + int current_item() const; + int next_item() const; + int previous_item() const; + PlaylistItem* item_at(int index) const { return items_[index]; } + + // Changing the playlist + QModelIndex InsertItems(const QList& items, int after = -1); + QModelIndex InsertSongs(const SongList& items, int after = -1); + void StopAfter(int row); + + // QAbstractListModel + int rowCount(const QModelIndex& = QModelIndex()) const { return items_.count(); } + int columnCount(const QModelIndex& = QModelIndex()) const { return ColumnCount; } + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; + QMimeData* mimeData(const QModelIndexList& indexes) const; + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); + void sort(int column, Qt::SortOrder order); + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); + + public slots: + void set_current_item(int index); + void Paused(); + void Playing(); + void Stopped(); + + private: + void SetCurrentIsPaused(bool paused); + + private: + QList items_; + + QPersistentModelIndex current_item_; + QPersistentModelIndex stop_after_; + bool current_is_paused_; + + // Hack to stop QTreeView::setModel sorting the playlist + bool ignore_next_sort_; +}; + +#endif // PLAYLIST_H diff --git a/src/playlistitem.cpp b/src/playlistitem.cpp new file mode 100644 index 000000000..eb172f6ec --- /dev/null +++ b/src/playlistitem.cpp @@ -0,0 +1,21 @@ +#include "playlistitem.h" +#include "songplaylistitem.h" + +#include + +QString PlaylistItem::type_string() const { + switch (type()) { + case Type_Song: return "Song"; + default: + qWarning() << "Invalid PlaylistItem type:" << type(); + return QString::null; + } +} + +PlaylistItem* PlaylistItem::NewFromType(const QString& type) { + if (type == "Song") + return new SongPlaylistItem; + + qWarning() << "Invalid PlaylistItem type:" << type; + return NULL; +} diff --git a/src/playlistitem.h b/src/playlistitem.h new file mode 100644 index 000000000..e1af35502 --- /dev/null +++ b/src/playlistitem.h @@ -0,0 +1,35 @@ +#ifndef PLAYLISTITEM_H +#define PLAYLISTITEM_H + +#include +#include + +class QSettings; + +class PlaylistItem { + public: + PlaylistItem() {} + virtual ~PlaylistItem() {} + + static PlaylistItem* NewFromType(const QString& type); + + enum Type { + Type_Song, + }; + + virtual Type type() const = 0; + QString type_string() const; + + virtual void Save(QSettings& settings) const = 0; + virtual void Restore(const QSettings& settings) = 0; + + virtual QString Title() const = 0; + virtual QString Artist() const = 0; + virtual QString Album() const = 0; + virtual int Length() const = 0; + virtual int Track() const = 0; + + virtual QUrl Url() = 0; +}; + +#endif // PLAYLISTITEM_H diff --git a/src/playlistview.cpp b/src/playlistview.cpp new file mode 100644 index 000000000..07fcda107 --- /dev/null +++ b/src/playlistview.cpp @@ -0,0 +1,280 @@ +#include "playlistview.h" +#include "playlist.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +const char* PlaylistView::kSettingsGroup = "Playlist"; +const int PlaylistView::kGlowIntensitySteps = 32; + + +PlaylistDelegateBase::PlaylistDelegateBase(QTreeView* view) + : QStyledItemDelegate(view), + view_(view) +{ +} + +void PlaylistDelegateBase::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { + QStyledItemDelegate::paint(painter, Adjusted(option, index), index); + + if (view_->header()->logicalIndexAt(QPoint(0,0)) == index.column()) { + if (index.data(Playlist::Role_StopAfter).toBool()) { + QColor color(Qt::white); + if (!index.data(Playlist::Role_IsCurrent).toBool() && + !(option.state & QStyle::State_Selected)) { + color = option.palette.color(QPalette::Highlight); + } + + const int kStopSize = 10; + const int kStopBorder = 2; + + QRect stop_rect(option.rect); + stop_rect.setLeft(stop_rect.right() - kStopSize - kStopBorder); + stop_rect.setWidth(kStopSize); + stop_rect.moveTop(stop_rect.top() + (stop_rect.height() - kStopSize) / 2); + stop_rect.setHeight(kStopSize); + + painter->setOpacity(0.65); + painter->fillRect(stop_rect, color); + painter->setOpacity(1.0); + } + } +} + +QStyleOptionViewItemV4 PlaylistDelegateBase::Adjusted(const QStyleOptionViewItem& option, const QModelIndex& index) const { + if (view_->header()->logicalIndexAt(QPoint(0,0)) != index.column()) + return option; + + QStyleOptionViewItemV4 ret(option); + + if (index.data(Playlist::Role_IsCurrent).toBool()) { + // Move the text in a bit on the first column for the song that's currently + // playing + ret.rect.setLeft(ret.rect.left() + 20); + } + + return ret; +} + + + +LengthItemDelegate::LengthItemDelegate(QTreeView* view) + : PlaylistDelegateBase(view) +{ +} + +QString LengthItemDelegate::displayText(const QVariant& value, const QLocale& locale) const { + bool ok = false; + int seconds = value.toInt(&ok); + QString ret = "-"; + + if (ok && seconds > 0) { + int hours = seconds / (60*60); + int minutes = (seconds / 60) % 60; + seconds %= 60; + + if (hours) + ret.sprintf("%d:%02d:%02d", hours, minutes, seconds); + else + ret.sprintf("%d:%02d", minutes, seconds); + } + return ret; +} + + +PlaylistView::PlaylistView(QWidget *parent) + : QTreeView(parent), + glow_enabled_(false), + glow_timer_(new QTimer(this)), + glow_intensity_step_(0), + row_height_(-1), + currenttrack_play_(":currenttrack_play.png"), + currenttrack_pause_(":currenttrack_pause.png"), + menu_(new QMenu(this)) +{ + setItemDelegate(new PlaylistDelegateBase(this)); + setItemDelegateForColumn(Playlist::Column_Length, new LengthItemDelegate(this)); + header()->setMovable(true); + + connect(header(), SIGNAL(sectionResized(int,int,int)), SLOT(SaveGeometry())); + connect(header(), SIGNAL(sectionMoved(int,int,int)), SLOT(SaveGeometry())); + + glow_timer_->setInterval(1500 / kGlowIntensitySteps); + connect(glow_timer_, SIGNAL(timeout()), SLOT(GlowIntensityChanged())); + + menu_->addAction(QIcon(":media-playback-stop.png"), "Stop playing after track", + this, SLOT(StopAfter())); +} + +void PlaylistView::setModel(QAbstractItemModel *model) { + QTreeView::setModel(model); + LoadGeometry(); +} + +void PlaylistView::LoadGeometry() { + QSettings settings; + settings.beginGroup(kSettingsGroup); + + header()->restoreState(settings.value("state").toByteArray()); +} + +void PlaylistView::SaveGeometry() { + QSettings settings; + settings.beginGroup(kSettingsGroup); + settings.setValue("state", header()->saveState()); +} + +void PlaylistView::ReloadBarPixmaps() { + currenttrack_bar_left_ = LoadBarPixmap(":currenttrack_bar_left.png"); + currenttrack_bar_mid_ = LoadBarPixmap(":currenttrack_bar_mid.png"); + currenttrack_bar_right_ = LoadBarPixmap(":currenttrack_bar_right.png"); +} + +QList PlaylistView::LoadBarPixmap(const QString& filename) { + QImage image(filename); + image = image.scaledToHeight(row_height_, Qt::SmoothTransformation); + + // Colour the bar with the palette colour + QPainter p(&image); + p.setCompositionMode(QPainter::CompositionMode_SourceAtop); + p.setOpacity(0.4); + p.fillRect(image.rect(), palette().color(QPalette::Highlight).lighter(125)); + p.end(); + + // Animation steps + QList ret; + for(int i=0 ; i(this)->last_current_item_ = index; + const_cast(this)->last_glow_rect_ = opt.rect; + + int step = glow_intensity_step_; + if (step >= kGlowIntensitySteps) + step = 2*(kGlowIntensitySteps-1) - step + 1; + + int row_height = opt.rect.height(); + if (row_height != row_height_) { + // Recreate the pixmaps if the height changed since last time + const_cast(this)->row_height_ = row_height; + const_cast(this)->ReloadBarPixmaps(); + } + + QRect middle(opt.rect); + middle.setLeft(middle.left() + currenttrack_bar_left_[0].width()); + middle.setRight(middle.right() - currenttrack_bar_right_[0].width()); + + // Selection + if (selectionModel()->isSelected(index)) + painter->fillRect(opt.rect, opt.palette.color(QPalette::Highlight)); + + // Draw the bar + painter->drawPixmap(opt.rect.topLeft(), currenttrack_bar_left_[step]); + painter->drawPixmap(opt.rect.topRight() - currenttrack_bar_right_[0].rect().topRight(), currenttrack_bar_right_[step]); + painter->drawPixmap(middle, currenttrack_bar_mid_[step]); + + // Draw the play icon + QPoint play_pos(currenttrack_bar_left_[0].width() / 3 * 2, + (row_height - currenttrack_play_.height()) / 2); + painter->drawPixmap(opt.rect.topLeft() + play_pos, + is_paused ? currenttrack_pause_ : currenttrack_play_); + + // Set the font + opt.palette.setColor(QPalette::Text, Qt::white); + opt.palette.setColor(QPalette::HighlightedText, Qt::white); + opt.palette.setColor(QPalette::Highlight, Qt::transparent); + opt.font.setItalic(true); + opt.decorationSize = QSize(20,20); + } + + QTreeView::drawRow(painter, opt, index); +} + +void PlaylistView::GlowIntensityChanged() { + glow_intensity_step_ = (glow_intensity_step_ + 1) % (kGlowIntensitySteps * 2); + + viewport()->update(last_glow_rect_); +} + +void PlaylistView::StopGlowing() { + glow_enabled_ = false; + glow_timer_->stop(); + glow_intensity_step_ = kGlowIntensitySteps; +} + +void PlaylistView::StartGlowing() { + glow_enabled_ = true; + if (isVisible()) + glow_timer_->start(); +} + +void PlaylistView::hideEvent(QHideEvent*) { + glow_timer_->stop(); +} + +void PlaylistView::showEvent(QShowEvent*) { + if (glow_enabled_) + glow_timer_->start(); +} + +bool CompareSelectionRanges(const QItemSelectionRange& a, const QItemSelectionRange& b) { + return b.bottom() < a.bottom(); +} + +void PlaylistView::keyPressEvent(QKeyEvent* event) { + if (model() && event->matches(QKeySequence::Delete)) { + QItemSelection selection(selectionModel()->selection()); + + // Sort the selection so we remove the items at the *bottom* first, ensuring + // we don't have to mess around with changing row numbers + qSort(selection.begin(), selection.end(), CompareSelectionRanges); + + foreach (const QItemSelectionRange& range, selection) { + model()->removeRows(range.top(), range.height(), range.parent()); + } + + event->accept(); + } else { + QTreeView::keyPressEvent(event); + } +} + +void PlaylistView::contextMenuEvent(QContextMenuEvent* e) { + menu_index_ = indexAt(e->pos()); + if (!menu_index_.isValid()) + return; + + menu_->popup(e->globalPos()); + e->accept(); +} + +void PlaylistView::StopAfter() { + Playlist* playlist = qobject_cast(model()); + Q_ASSERT(playlist); + + playlist->StopAfter(menu_index_.row()); +} diff --git a/src/playlistview.h b/src/playlistview.h new file mode 100644 index 000000000..50b68c07d --- /dev/null +++ b/src/playlistview.h @@ -0,0 +1,79 @@ +#ifndef PLAYLISTVIEW_H +#define PLAYLISTVIEW_H + +#include +#include + +class PlaylistDelegateBase : public QStyledItemDelegate { + public: + PlaylistDelegateBase(QTreeView* view); + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + + QStyleOptionViewItemV4 Adjusted(const QStyleOptionViewItem& option, const QModelIndex& index) const; + + protected: + QTreeView* view_; +}; + +class LengthItemDelegate : public PlaylistDelegateBase { + public: + LengthItemDelegate(QTreeView* view); + QString displayText(const QVariant& value, const QLocale& locale) const; +}; + + +class PlaylistView : public QTreeView { + Q_OBJECT + + public: + PlaylistView(QWidget* parent = 0); + + // QTreeView + void setModel(QAbstractItemModel *model); + void drawRow(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + void keyPressEvent(QKeyEvent* event); + + // QAbstractScrollArea + void contextMenuEvent(QContextMenuEvent* e); + + public slots: + void StopGlowing(); + void StartGlowing(); + + protected: + void hideEvent(QHideEvent* event); + void showEvent(QShowEvent* event); + + private slots: + void LoadGeometry(); + void SaveGeometry(); + void GlowIntensityChanged(); + + void StopAfter(); + + private: + void ReloadBarPixmaps(); + QList LoadBarPixmap(const QString& filename); + + private: + static const char* kSettingsGroup; + static const int kGlowIntensitySteps; + + bool glow_enabled_; + QTimer* glow_timer_; + int glow_intensity_step_; + QModelIndex last_current_item_; + QRect last_glow_rect_; + + int row_height_; // Used to invalidate the currenttrack_bar pixmaps + QList currenttrack_bar_left_; + QList currenttrack_bar_mid_; + QList currenttrack_bar_right_; + QPixmap currenttrack_play_; + QPixmap currenttrack_pause_; + + QMenu* menu_; + QModelIndex menu_index_; +}; + +#endif // PLAYLISTVIEW_H diff --git a/src/sliderwidget.cpp b/src/sliderwidget.cpp new file mode 100644 index 000000000..372237a5f --- /dev/null +++ b/src/sliderwidget.cpp @@ -0,0 +1,369 @@ +/*************************************************************************** + amarokslider.cpp - description + ------------------- + begin : Dec 15 2003 + copyright : (C) 2003 by Mark Kretschmann + email : markey@web.de + copyright : (C) 2005 by Gábor Lehel + email : illissius@gmail.com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "sliderwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +Amarok::Slider::Slider( Qt::Orientation orientation, QWidget *parent, uint max ) + : QSlider( orientation, parent ) + , m_sliding( false ) + , m_outside( false ) + , m_prevValue( 0 ) +{ + setRange( 0, max ); +} + +void +Amarok::Slider::wheelEvent( QWheelEvent *e ) +{ + if( orientation() == Qt::Vertical ) { + // Will be handled by the parent widget + e->ignore(); + return; + } + + // Position Slider (horizontal) + int step = e->delta() * 1500 / 18; + int nval = QSlider::value() + step; + nval = qMax(nval, minimum()); + nval = qMin(nval, maximum()); + + QSlider::setValue( nval ); + + emit sliderReleased( value() ); +} + +void +Amarok::Slider::mouseMoveEvent( QMouseEvent *e ) +{ + if ( m_sliding ) + { + //feels better, but using set value of 20 is bad of course + QRect rect( -20, -20, width()+40, height()+40 ); + + if ( orientation() == Qt::Horizontal && !rect.contains( e->pos() ) ) { + if ( !m_outside ) + QSlider::setValue( m_prevValue ); + m_outside = true; + } else { + m_outside = false; + slideEvent( e ); + emit sliderMoved( value() ); + } + } + else QSlider::mouseMoveEvent( e ); +} + +void +Amarok::Slider::slideEvent( QMouseEvent *e ) +{ + QStyleOptionSlider option; + initStyleOption(&option); + QRect sliderRect(style()->subControlRect(QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this)); + + QSlider::setValue( orientation() == Qt::Horizontal + ? ((QApplication::layoutDirection() == Qt::RightToLeft) ? + QStyle::sliderValueFromPosition(minimum(), maximum(), width() - (e->pos().x() - sliderRect.width()/2), width() + sliderRect.width(), true ) + : QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x() - sliderRect.width()/2, width() - sliderRect.width() ) ) + : QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().y() - sliderRect.height()/2, height() - sliderRect.height() ) ); +} + +void +Amarok::Slider::mousePressEvent( QMouseEvent *e ) +{ + QStyleOptionSlider option; + initStyleOption(&option); + QRect sliderRect(style()->subControlRect(QStyle::CC_Slider, &option, QStyle::SC_SliderHandle, this)); + + m_sliding = true; + m_prevValue = QSlider::value(); + + if ( !sliderRect.contains( e->pos() ) ) + mouseMoveEvent( e ); +} + +void +Amarok::Slider::mouseReleaseEvent( QMouseEvent* ) +{ + if( !m_outside && QSlider::value() != m_prevValue ) + emit sliderReleased( value() ); + + m_sliding = false; + m_outside = false; +} + +void +Amarok::Slider::setValue( int newValue ) +{ + //don't adjust the slider while the user is dragging it! + + if ( !m_sliding || m_outside ) + QSlider::setValue( adjustValue( newValue ) ); + else + m_prevValue = newValue; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +/// CLASS PrettySlider +////////////////////////////////////////////////////////////////////////////////////////// + +#define THICKNESS 7 +#define MARGIN 3 + +Amarok::PrettySlider::PrettySlider( Qt::Orientation orientation, SliderMode mode, + QWidget *parent, uint max ) + : Amarok::Slider( orientation, parent, max ) + , m_mode( mode ) +{ + if( m_mode == Pretty) + { + setFocusPolicy( Qt::NoFocus ); + } +} + +void +Amarok::PrettySlider::mousePressEvent( QMouseEvent *e ) +{ + Amarok::Slider::mousePressEvent( e ); + + slideEvent( e ); +} + +void +Amarok::PrettySlider::slideEvent( QMouseEvent *e ) +{ + if( m_mode == Pretty ) + QSlider::setValue( orientation() == Qt::Horizontal + ? QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x(), width()-2 ) + : QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().y(), height()-2 ) ); + else + Amarok::Slider::slideEvent( e ); +} + +namespace Amarok { + namespace ColorScheme { + extern QColor Background; + extern QColor Foreground; + } +} + + +#if 0 +/** these functions aren't required in our fixed size world, + but they may become useful one day **/ + +QSize +Amarok::PrettySlider::minimumSizeHint() const +{ + return sizeHint(); +} + +QSize +Amarok::PrettySlider::sizeHint() const +{ + constPolish(); + + return (orientation() == Horizontal + ? QSize( maxValue(), THICKNESS + MARGIN ) + : QSize( THICKNESS + MARGIN, maxValue() )).expandedTo( QApplit ication::globalStrut() ); +} +#endif + +////////////////////////////////////////////////////////////////////////////////////////// +/// CLASS VolumeSlider +////////////////////////////////////////////////////////////////////////////////////////// + +Amarok::VolumeSlider::VolumeSlider( QWidget *parent, uint max ) + : Amarok::Slider( Qt::Horizontal, parent, max ) + , m_animCount( 0 ) + , m_animTimer( new QTimer( this ) ) + , m_pixmapInset( QPixmap( ":volumeslider-inset.png" )) +{ + setFocusPolicy( Qt::NoFocus ); + + // BEGIN Calculate handle animation pixmaps for mouse-over effect + QImage pixmapHandle ( ":volumeslider-handle.png" ); + QImage pixmapHandleGlow( ":volumeslider-handle_glow.png" ); + + float opacity = 0.0; + const float step = 1.0 / ANIM_MAX; + QImage dst; + for ( int i = 0; i < ANIM_MAX; ++i ) { + dst = pixmapHandle.copy(); + + QPainter p(&dst); + p.setOpacity(opacity); + p.drawImage(0, 0, pixmapHandleGlow); + p.end(); + + m_handlePixmaps.append( QPixmap::fromImage( dst ) ); + opacity += step; + } + // END + + generateGradient(); + + setMinimumWidth( m_pixmapInset.width() ); + setMinimumHeight( m_pixmapInset.height() ); + + connect( m_animTimer, SIGNAL( timeout() ), this, SLOT( slotAnimTimer() ) ); +} + +void +Amarok::VolumeSlider::generateGradient() +{ + const QImage mask( ":volumeslider-gradient.png" ); + + QImage gradient_image(mask.size(), QImage::Format_ARGB32_Premultiplied); + QPainter p(&gradient_image); + + QLinearGradient gradient(gradient_image.rect().topLeft(), + gradient_image.rect().topRight()); + gradient.setColorAt(0, palette().color(QPalette::Background)); + gradient.setColorAt(1, palette().color(QPalette::Highlight)); + p.fillRect(gradient_image.rect(), QBrush(gradient)); + + p.setCompositionMode(QPainter::CompositionMode_DestinationIn); + p.drawImage(0, 0, mask); + p.end(); + + m_pixmapGradient = QPixmap::fromImage(gradient_image); +} + +void +Amarok::VolumeSlider::slotAnimTimer() //SLOT +{ + if ( m_animEnter ) { + m_animCount++; + update(); + if ( m_animCount == ANIM_MAX - 1 ) + m_animTimer->stop(); + } else { + m_animCount--; + update(); + if ( m_animCount == 0 ) + m_animTimer->stop(); + } +} + +void +Amarok::VolumeSlider::mousePressEvent( QMouseEvent *e ) +{ + if( e->button() != Qt::RightButton ) { + Amarok::Slider::mousePressEvent( e ); + slideEvent( e ); + } +} + +void +Amarok::VolumeSlider::contextMenuEvent( QContextMenuEvent *e ) +{ + QMap values; + QMenu menu; + menu.setTitle("Volume"); + values[menu.addAction("100%" )] = 100; + values[menu.addAction("80%" )] = 80; + values[menu.addAction("60%" )] = 60; + values[menu.addAction("40%" )] = 40; + values[menu.addAction("20%" )] = 20; + values[menu.addAction("0%" )] = 0; + + QAction* ret = menu.exec( mapToGlobal( e->pos() ) ); + if( ret ) + { + QSlider::setValue( values[ret] ); + emit sliderReleased( values[ret] ); + } +} + +void +Amarok::VolumeSlider::slideEvent( QMouseEvent *e ) +{ + QSlider::setValue( QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x(), width()-2 ) ); +} + +void +Amarok::VolumeSlider::wheelEvent( QWheelEvent *e ) +{ + const uint step = e->delta() / 10; + QSlider::setValue( QSlider::value() + step ); + + emit sliderReleased( value() ); +} + +void +Amarok::VolumeSlider::paintEvent( QPaintEvent * ) +{ + QPainter p(this); + + const int padding = 7; + const int offset = int( double( ( width() - 2 * padding ) * value() ) / maximum() ); + + p.drawPixmap(0, 0, m_pixmapGradient, 0, 0, offset + padding, 0); + p.drawPixmap(0, 0, m_pixmapInset); + p.drawPixmap(offset - m_handlePixmaps[0].width() / 2 + padding, 0, m_handlePixmaps[m_animCount]); + + // Draw percentage number + p.setPen( palette().color( QPalette::Disabled, QPalette::Text ).dark() ); + QFont font; + font.setPixelSize( 9 ); + p.setFont( font ); + const QRect rect( 0, 0, 34, 15 ); + p.drawText( rect, Qt::AlignRight | Qt::AlignVCenter, QString::number( value() ) + '%' ); +} + +void +Amarok::VolumeSlider::enterEvent( QEvent* ) +{ + m_animEnter = true; + m_animCount = 0; + + m_animTimer->start( ANIM_INTERVAL ); +} + +void +Amarok::VolumeSlider::leaveEvent( QEvent* ) +{ + // This can happen if you enter and leave the widget quickly + if ( m_animCount == 0 ) + m_animCount = 1; + + m_animEnter = false; + m_animTimer->start( ANIM_INTERVAL ); +} + +void +Amarok::VolumeSlider::paletteChange( const QPalette& ) +{ + generateGradient(); +} diff --git a/src/sliderwidget.h b/src/sliderwidget.h new file mode 100644 index 000000000..681026f58 --- /dev/null +++ b/src/sliderwidget.h @@ -0,0 +1,145 @@ +/*************************************************************************** + amarokslider.h - description + ------------------- + begin : Dec 15 2003 + copyright : (C) 2003 by Mark Kretschmann + email : markey@web.de + copyright : (C) 2005 by Gábor Lehel + email : illissius@gmail.com +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef AMAROKSLIDER_H +#define AMAROKSLIDER_H + + +#include +#include +#include + +class QPalette; +class QTimer; + +namespace Amarok +{ + class Slider : public QSlider + { + Q_OBJECT + + public: + Slider( Qt::Orientation, QWidget*, uint max = 0 ); + + virtual void setValue( int ); + + //WARNING non-virtual - and thus only really intended for internal use + //this is a major flaw in the class presently, however it suits our + //current needs fine + int value() const { return adjustValue( QSlider::value() ); } + + signals: + //we emit this when the user has specifically changed the slider + //so connect to it if valueChanged() is too generic + //Qt also emits valueChanged( int ) + void sliderReleased( int ); + + protected: + virtual void wheelEvent( QWheelEvent* ); + virtual void mouseMoveEvent( QMouseEvent* ); + virtual void mouseReleaseEvent( QMouseEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + virtual void slideEvent( QMouseEvent* ); + + bool m_sliding; + + /// we flip the value for vertical sliders + int adjustValue( int v ) const + { + int mp = (minimum() + maximum()) / 2; + return orientation() == Qt::Vertical ? mp - (v - mp) : v; + } + + private: + bool m_outside; + int m_prevValue; + + Slider( const Slider& ); //undefined + Slider &operator=( const Slider& ); //undefined + }; + + + class PrettySlider : public Slider + { + Q_OBJECT + + public: + typedef enum + { + Normal, // Same behavior as Slider *unless* there's a moodbar + Pretty + } SliderMode; + + PrettySlider( Qt::Orientation orientation, SliderMode mode, + QWidget *parent, uint max = 0 ); + + protected: + virtual void slideEvent( QMouseEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + + private: + PrettySlider( const PrettySlider& ); //undefined + PrettySlider &operator=( const PrettySlider& ); //undefined + + SliderMode m_mode; + }; + + class VolumeSlider: public Slider + { + Q_OBJECT + + public: + VolumeSlider( QWidget *parent, uint max = 0 ); + + protected: + virtual void paintEvent( QPaintEvent* ); + virtual void enterEvent( QEvent* ); + virtual void leaveEvent( QEvent* ); + virtual void paletteChange( const QPalette& ); + virtual void slideEvent( QMouseEvent* ); + virtual void mousePressEvent( QMouseEvent* ); + virtual void contextMenuEvent( QContextMenuEvent* ); + virtual void wheelEvent( QWheelEvent *e ); + + private slots: + virtual void slotAnimTimer(); + + private: + void generateGradient(); + + VolumeSlider( const VolumeSlider& ); //undefined + VolumeSlider &operator=( const VolumeSlider& ); //undefined + + //////////////////////////////////////////////////////////////// + static const int ANIM_INTERVAL = 18; + static const int ANIM_MAX = 18; + + bool m_animEnter; + int m_animCount; + QTimer* m_animTimer; + + QPixmap m_pixmapInset; + QPixmap m_pixmapGradient; + + QList m_handlePixmaps; + }; + +} + +#endif diff --git a/src/song.cpp b/src/song.cpp new file mode 100644 index 000000000..d38be064a --- /dev/null +++ b/src/song.cpp @@ -0,0 +1,278 @@ +#include "song.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +const char* Song::kColumnSpec = + "title, album, artist, albumartist, composer, " + "track, disc, bpm, year, genre, comment, compilation, " + "length, bitrate, samplerate, directory, filename, " + "mtime, ctime, filesize"; + +const char* Song::kBindSpec = + ":title, :album, :artist, :albumartist, :composer, " + ":track, :disc, :bpm, :year, :genre, :comment, :compilation, " + ":length, :bitrate, :samplerate, :directory_id, :filename, " + ":mtime, :ctime, :filesize"; + +const char* Song::kUpdateSpec = + "title = :title, album = :album, artist = :artist, " + "albumartist = :albumartist, composer = :composer, track = :track, " + "disc = :disc, bpm = :bpm, year = :year, genre = :genre, " + "comment = :comment, compilation = :compilation, length = :length, " + "bitrate = :bitrate, samplerate = :samplerate, " + "directory = :directory_id, filename = :filename, mtime = :mtime, " + "ctime = :ctime, filesize = :filesize"; + +Song::Song() + : valid_(false), + id_(-1), + track_(-1), + disc_(-1), + bpm_(-1), + year_(-1), + compilation_(false), + length_(-1), + bitrate_(-1), + samplerate_(-1), + directory_id_(-1), + mtime_(-1), + ctime_(-1), + filesize_(-1) +{ +} + +void Song::InitFromFile(const QString& filename, int directory_id) { + filename_ = filename; + directory_id_ = directory_id; + + TagLib::FileRef fileref = TagLib::FileRef(QFile::encodeName(filename).constData()); + + if( fileref.isNull() ) + return; + + QFileInfo info(filename); + filesize_ = info.size(); + mtime_ = info.lastModified().toTime_t(); + ctime_ = info.created().toTime_t(); + + TagLib::Tag* tag = fileref.tag(); + if (tag) { + #define strip(x) TStringToQString( x ).trimmed() + title_ = strip(tag->title()); + artist_ = strip(tag->artist()); + album_ = strip(tag->album()); + comment_ = strip(tag->comment()); + genre_ = strip(tag->genre()); + year_ = tag->year(); + track_ = tag->track(); + #undef strip + + valid_ = true; + } + + QString disc; + QString compilation; + if (TagLib::MPEG::File* file = dynamic_cast(fileref.file())) { + if (file->ID3v2Tag()) { + if (!file->ID3v2Tag()->frameListMap()["TPOS"].isEmpty()) + disc = TStringToQString(file->ID3v2Tag()->frameListMap()["TPOS"].front()->toString()).trimmed(); + + if (!file->ID3v2Tag()->frameListMap()["TBPM"].isEmpty()) + bpm_ = TStringToQString(file->ID3v2Tag()->frameListMap()["TBPM"].front()->toString()).trimmed().toFloat(); + + if (!file->ID3v2Tag()->frameListMap()["TCOM"].isEmpty()) + composer_ = TStringToQString(file->ID3v2Tag()->frameListMap()["TCOM"].front()->toString()).trimmed(); + + if (!file->ID3v2Tag()->frameListMap()["TPE2"].isEmpty()) // non-standard: Apple, Microsoft + albumartist_ = TStringToQString(file->ID3v2Tag()->frameListMap()["TPE2"].front()->toString()).trimmed(); + + if (!file->ID3v2Tag()->frameListMap()["TCMP"].isEmpty()) + compilation = TStringToQString(file->ID3v2Tag()->frameListMap()["TCMP"].front()->toString()).trimmed(); + } + } + else if (TagLib::Ogg::Vorbis::File* file = dynamic_cast(fileref.file())) { + if (file->tag()) { + if ( !file->tag()->fieldListMap()["COMPOSER"].isEmpty() ) + composer_ = TStringToQString(file->tag()->fieldListMap()["COMPOSER"].front()).trimmed(); + + if ( !file->tag()->fieldListMap()["BPM"].isEmpty() ) + bpm_ = TStringToQString(file->tag()->fieldListMap()["BPM"].front()).trimmed().toFloat(); + + if ( !file->tag()->fieldListMap()["DISCNUMBER"].isEmpty() ) + disc = TStringToQString(file->tag()->fieldListMap()["DISCNUMBER"].front()).trimmed(); + + if ( !file->tag()->fieldListMap()["COMPILATION"].isEmpty() ) + compilation = TStringToQString(file->tag()->fieldListMap()["COMPILATION"].front()).trimmed(); + } + } + else if (TagLib::FLAC::File* file = dynamic_cast(fileref.file())) { + if ( file->xiphComment() ) { + if (!file->xiphComment()->fieldListMap()["COMPOSER"].isEmpty()) + composer_ = TStringToQString( file->xiphComment()->fieldListMap()["COMPOSER"].front() ).trimmed(); + + if (!file->xiphComment()->fieldListMap()["BPM"].isEmpty() ) + bpm_ = TStringToQString( file->xiphComment()->fieldListMap()["BPM"].front() ).trimmed().toFloat(); + + if (!file->xiphComment()->fieldListMap()["DISCNUMBER"].isEmpty() ) + disc = TStringToQString( file->xiphComment()->fieldListMap()["DISCNUMBER"].front() ).trimmed(); + + if (!file->xiphComment()->fieldListMap()["COMPILATION"].isEmpty() ) + compilation = TStringToQString( file->xiphComment()->fieldListMap()["COMPILATION"].front() ).trimmed(); + } + } + + if ( !disc.isEmpty() ) { + int i = disc.indexOf('/'); + if ( i != -1 ) + // disc.right( i ).toInt() is total number of discs, we don't use this at the moment + disc_ = disc.left( i ).toInt(); + else + disc_ = disc.toInt(); + } + + if ( compilation.isEmpty() ) { + // well, it wasn't set, but if the artist is VA assume it's a compilation + if ( artist_.toLower() == "various artists" ) + compilation_ = true; + } else { + int i = compilation.toInt(); + compilation_ = (i == 1); + } + + bitrate_ = fileref.audioProperties()->bitrate(); + length_ = fileref.audioProperties()->length(); + samplerate_ = fileref.audioProperties()->sampleRate(); +} + +void Song::InitFromQuery(const QSqlQuery& q) { + valid_ = true; + + #define tostr(n) (q.value(n).isNull() ? QString::null : q.value(n).toString()) + #define toint(n) (q.value(n).isNull() ? -1 : q.value(n).toInt()) + #define tofloat(n) (q.value(n).isNull() ? -1 : q.value(n).toDouble()) + + id_ = toint(0); + title_ = tostr(1); + album_ = tostr(2); + artist_ = tostr(3); + albumartist_ = tostr(4); + composer_ = tostr(5); + track_ = toint(6); + disc_ = toint(7); + bpm_ = tofloat(8); + year_ = toint(9); + genre_ = tostr(10); + comment_ = tostr(11); + compilation_ = q.value(12).toBool(); + + length_ = toint(13); + bitrate_ = toint(14); + samplerate_ = toint(15); + + directory_id_ = toint(16); + filename_ = tostr(17); + mtime_ = toint(18); + ctime_ = toint(19); + filesize_ = toint(20); + + #undef tostr + #undef toint + #undef tofloat +} + +void Song::BindToQuery(QSqlQuery *query) const { + #define intval(x) (x == -1 ? QVariant() : x) + + query->bindValue(":title", title_); + query->bindValue(":album", album_); + query->bindValue(":artist", artist_); + query->bindValue(":albumartist", albumartist_); + query->bindValue(":composer", composer_); + query->bindValue(":track", intval(track_)); + query->bindValue(":disc", intval(disc_)); + query->bindValue(":bpm", intval(bpm_)); + query->bindValue(":year", intval(year_)); + query->bindValue(":genre", genre_); + query->bindValue(":comment", comment_); + query->bindValue(":compilation", compilation_ ? 1 : 0); + + query->bindValue(":length", intval(length_)); + query->bindValue(":bitrate", intval(bitrate_)); + query->bindValue(":samplerate", intval(samplerate_)); + + query->bindValue(":directory_id", intval(directory_id_)); + query->bindValue(":filename", filename_); + query->bindValue(":mtime", intval(mtime_)); + query->bindValue(":ctime", intval(ctime_)); + query->bindValue(":filesize", intval(filesize_)); + + #undef intval +} + +QString Song::PrettyTitleWithArtist() const { + QString title(title_); + + if (title.isEmpty()) + title = QFileInfo(filename_).baseName(); + + if (compilation_ && !artist_.isEmpty()) + title = artist_ + " - " + title; + + return title; +} + +QString Song::PrettyTitle() const { + QString title(title_); + + if (title.isEmpty()) + title = QFileInfo(filename_).baseName(); + + return title; +} + +QString Song::PrettyLength() const { + if (length_ == -1) + return QString::null; + + int hours = length_ / (60*60); + int minutes = (length_ / 60) % 60; + int seconds = length_ % 60; + + QString text; + if (hours) + text.sprintf("%d:%02d:%02d", hours, minutes, seconds); + else + text.sprintf("%d:%02d", minutes, seconds); + return text; +} + +bool Song::IsMetadataEqual(const Song& other) const { + return title_ == other.title_ && + album_ == other.album_ && + artist_ == other.artist_ && + albumartist_ == other.albumartist_ && + composer_ == other.composer_ && + track_ == other.track_ && + disc_ == other.disc_ && + qFuzzyCompare(bpm_, other.bpm_) && + year_ == other.year_ && + genre_ == other.genre_ && + comment_ == other.comment_ && + compilation_ == other.compilation_ && + length_ == other.length_ && + bitrate_ == other.bitrate_ && + samplerate_ == other.samplerate_; +} diff --git a/src/song.h b/src/song.h new file mode 100644 index 000000000..f8dd0f635 --- /dev/null +++ b/src/song.h @@ -0,0 +1,91 @@ +#ifndef SONG_H +#define SONG_H + +#include +#include +#include + +class Song { + public: + Song(); + + static const char* kColumnSpec; + static const char* kBindSpec; + static const char* kUpdateSpec; + + // Constructors + void InitFromFile(const QString& filename, int directory_id); + void InitFromQuery(const QSqlQuery& query); + + // Save + void BindToQuery(QSqlQuery* query) const; + + // Simple accessors + bool is_valid() const { return valid_; } + int id() const { return id_; } + + QString title() const { return title_; } + QString album() const { return album_; } + QString artist() const { return artist_; } + QString albumartist() const { return albumartist_; } + QString composer() const { return composer_; } + int track() const { return track_; } + int disc() const { return disc_; } + float bpm() const { return bpm_; } + int year() const { return year_; } + QString genre() const { return genre_; } + QString comment() const { return comment_; } + bool is_compilation() const { return compilation_; } + + int length() const { return length_; } + int bitrate() const { return bitrate_; } + int samplerate() const { return samplerate_; } + + int directory_id() const { return directory_id_; } + QString filename() const { return filename_; } + uint mtime() const { return mtime_; } + uint ctime() const { return ctime_; } + int filesize() const { return filesize_; } + + // Pretty accessors + QString PrettyTitle() const; + QString PrettyTitleWithArtist() const; + QString PrettyLength() const; + + // Setters + void set_id(int id) { id_ = id; } + + // Comparison functions + bool IsMetadataEqual(const Song& other) const; + + private: + bool valid_; + int id_; + + QString title_; + QString album_; + QString artist_; + QString albumartist_; + QString composer_; + int track_; + int disc_; + float bpm_; + int year_; + QString genre_; + QString comment_; + bool compilation_; + + int length_; + int bitrate_; + int samplerate_; + + int directory_id_; + QString filename_; + int mtime_; + int ctime_; + int filesize_; +}; + +typedef QList SongList; + +#endif // SONG_H diff --git a/src/songmimedata.cpp b/src/songmimedata.cpp new file mode 100644 index 000000000..e19e90103 --- /dev/null +++ b/src/songmimedata.cpp @@ -0,0 +1 @@ +#include "songmimedata.h" diff --git a/src/songmimedata.h b/src/songmimedata.h new file mode 100644 index 000000000..7ab040c7d --- /dev/null +++ b/src/songmimedata.h @@ -0,0 +1,15 @@ +#ifndef SONGMIMEDATA_H +#define SONGMIMEDATA_H + +#include + +#include "song.h" + +class SongMimeData : public QMimeData { + Q_OBJECT + + public: + SongList songs; +}; + +#endif // SONGMIMEDATA_H diff --git a/src/songplaylistitem.cpp b/src/songplaylistitem.cpp new file mode 100644 index 000000000..f11ca8ceb --- /dev/null +++ b/src/songplaylistitem.cpp @@ -0,0 +1,51 @@ +#include "songplaylistitem.h" + +#include +#include + +SongPlaylistItem::SongPlaylistItem() +{ +} + +SongPlaylistItem::SongPlaylistItem(const Song& song) + : song_(song) +{ +} + +void SongPlaylistItem::Save(QSettings& settings) const { + settings.setValue("filename", song_.filename()); + settings.setValue("library_directory", song_.directory_id()); +} + +void SongPlaylistItem::Restore(const QSettings& settings) { + QString filename(settings.value("filename").toString()); + int directory_id(settings.value("library_directory", -1).toInt()); + + song_.InitFromFile(filename, directory_id); +} + +QString SongPlaylistItem::Title() const { + return song_.PrettyTitle(); +} + +QString SongPlaylistItem::Artist() const { + return song_.artist(); +} + +QString SongPlaylistItem::Album() const { + return song_.album(); +} + +int SongPlaylistItem::Length() const { + return song_.length(); +} + +int SongPlaylistItem::Track() const { + return song_.track(); +} + +QUrl SongPlaylistItem::Url() { + QUrl ret(QUrl::fromLocalFile(song_.filename())); + ret.setHost("localhost"); + return ret; +} diff --git a/src/songplaylistitem.h b/src/songplaylistitem.h new file mode 100644 index 000000000..4868d9b3e --- /dev/null +++ b/src/songplaylistitem.h @@ -0,0 +1,29 @@ +#ifndef SONGPLAYLISTITEM_H +#define SONGPLAYLISTITEM_H + +#include "playlistitem.h" +#include "song.h" + +class SongPlaylistItem : public PlaylistItem { + public: + SongPlaylistItem(); + SongPlaylistItem(const Song& song); + + Type type() const { return Type_Song; } + + void Save(QSettings& settings) const; + void Restore(const QSettings& settings); + + QString Title() const; + QString Artist() const; + QString Album() const; + int Length() const; + int Track() const; + + QUrl Url(); + + private: + Song song_; +}; + +#endif // SONGPLAYLISTITEM_H diff --git a/src/src.pro b/src/src.pro new file mode 100644 index 000000000..bbef9979d --- /dev/null +++ b/src/src.pro @@ -0,0 +1,80 @@ +# ------------------------------------------------- +# Project created by QtCreator 2009-12-15T18:38:35 +# ------------------------------------------------- +QT += sql \ + opengl +TARGET = tangerine +TEMPLATE = app +SOURCES += main.cpp \ + mainwindow.cpp \ + player.cpp \ + library.cpp \ + librarybackend.cpp \ + playlist.cpp \ + playlistitem.cpp \ + enginebase.cpp \ + analyzers/baranalyzer.cpp \ + analyzers/analyzerbase.cpp \ + fht.cpp \ + analyzers/blockanalyzer.cpp \ + xine-engine.cpp \ + xine-scope.c \ + sliderwidget.cpp \ + playlistview.cpp \ + backgroundthread.cpp \ + librarywatcher.cpp \ + song.cpp \ + songmimedata.cpp \ + songplaylistitem.cpp \ + libraryview.cpp \ + libraryitem.cpp \ + libraryconfig.cpp \ + systemtrayicon.cpp \ + libraryquery.cpp +HEADERS += mainwindow.h \ + player.h \ + library.h \ + librarybackend.h \ + playlist.h \ + playlistitem.h \ + enginebase.h \ + engine_fwd.h \ + analyzers/baranalyzer.h \ + analyzers/analyzerbase.h \ + fht.h \ + analyzers/blockanalyzer.h \ + xine-engine.h \ + xine-scope.h \ + sliderwidget.h \ + playlistview.h \ + backgroundthread.h \ + librarywatcher.h \ + directory.h \ + song.h \ + songmimedata.h \ + songplaylistitem.h \ + libraryview.h \ + libraryitem.h \ + libraryconfig.h \ + systemtrayicon.h \ + libraryquery.h +FORMS += mainwindow.ui \ + libraryconfig.ui +RESOURCES += ../data/data.qrc +OTHER_FILES += ../data/schema.sql \ + ../data/mainwindow.css +!win32 { + QMAKE_CXXFLAGS += $$system(taglib-config --cflags) + LIBS += $$system(taglib-config --libs) + QMAKE_CXXFLAGS += $$system(xine-config --cflags) + LIBS += $$system(xine-config --libs) +} +win32 { + INCLUDEPATH += C:/msys/1.0/local/include \ + C:/msys/1.0/local/include/taglib + LIBS += -Lc:/msys/1.0/local/lib \ + -Lc:/msys/1.0/local/bin \ + -ltag \ + -lxine \ + -lpthreadGC2 +} diff --git a/src/systemtrayicon.cpp b/src/systemtrayicon.cpp new file mode 100644 index 000000000..8c3be406b --- /dev/null +++ b/src/systemtrayicon.cpp @@ -0,0 +1,17 @@ +#include "systemtrayicon.h" + +#include +#include + +SystemTrayIcon::SystemTrayIcon(QObject* parent) + : QSystemTrayIcon(parent) +{ +} + +bool SystemTrayIcon::event(QEvent* event) { + if (event->type() == QEvent::Wheel) { + emit WheelEvent(static_cast(event)->delta()); + return true; + } + return QSystemTrayIcon::event(event); +} diff --git a/src/systemtrayicon.h b/src/systemtrayicon.h new file mode 100644 index 000000000..a3454fcb1 --- /dev/null +++ b/src/systemtrayicon.h @@ -0,0 +1,18 @@ +#ifndef SYSTEMTRAYICON_H +#define SYSTEMTRAYICON_H + +#include + +class SystemTrayIcon : public QSystemTrayIcon { + Q_OBJECT + + public: + SystemTrayIcon(QObject* parent = 0); + + bool event(QEvent* event); + + signals: + void WheelEvent(int delta); +}; + +#endif // SYSTEMTRAYICON_H diff --git a/src/xine-engine.cpp b/src/xine-engine.cpp new file mode 100644 index 000000000..d535d7569 --- /dev/null +++ b/src/xine-engine.cpp @@ -0,0 +1,1282 @@ +/*************************************************************************** + * Copyright (C) 2005 Christophe Thommeret * + * (C) 2005 Ian Monroe * + * (C) 2005,6 Mark Kretschmann * + * (C) 2004,5 Max Howell * + * (C) 2003,4 J. Kofler * + * * + * 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. * + * * + ***************************************************************************/ + +#define DEBUG_PREFIX "xine-engine" + +#include "xine-engine.h" +#include "xine-scope.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +extern "C" +{ + #include +} + +#ifndef LLONG_MAX +#define LLONG_MAX 9223372036854775807LL +#endif + + +//define this to use xine in a more standard way +//#define XINE_SAFE_MODE + + +///some logging static globals +namespace Log +{ + static uint bufferCount = 0; + static uint scopeCallCount = 1; //prevent divideByZero + static uint noSuitableBuffer = 0; +} + +static Fader *s_fader = 0; +static OutFader *s_outfader = 0; + + +XineEngine::XineEngine() + : EngineBase() + , m_xine( 0 ) + , m_stream( 0 ) + , m_audioPort( 0 ) + , m_eventQueue( 0 ) + , m_post( 0 ) + , m_preamp( 1.0 ) + , m_stopFader( false ) + , m_fadeOutRunning ( false ) + , m_equalizerEnabled( false ) +{ + m_settings.beginGroup("Player"); + reloadSettings(); +} + +XineEngine::~XineEngine() +{ + // Wait until the fader thread is done + if( s_fader ) { + m_stopFader = true; + s_fader->resume(); // safety call if the engine is in the pause state + s_fader->wait(); + } + + delete s_fader; + delete s_outfader; + + if( m_fadeoutOnExit ) { + bool terminateFader = false; + fadeOut( m_fadeoutDuration, &terminateFader, true ); // true == exiting + } + + //if( m_xine ) xine_config_save( m_xine, configPath() ); + + if( m_stream ) xine_close( m_stream ); + if( m_eventQueue ) xine_event_dispose_queue( m_eventQueue ); + if( m_stream ) xine_dispose( m_stream ); + if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort ); + if( m_post ) xine_post_dispose( m_xine, m_post ); + if( m_xine ) xine_exit( m_xine ); + + qDebug() << "xine closed"; + + qDebug() << "Scope statistics:"; + qDebug() << " Average list size: " << Log::bufferCount / Log::scopeCallCount; + qDebug() << " Buffer failure: " << double(Log::noSuitableBuffer*100) / Log::scopeCallCount << "%"; +} + +void XineEngine::reloadSettings() { + m_currentAudioPlugin = m_settings.value("XineAudioOutput", "auto").toString(); + m_fadeoutEnabled = m_settings.value("FadeoutEnabled", true).toBool(); + m_fadeoutOnExit = m_settings.value("FadeoutOnExit", true).toBool(); + m_fadeoutDuration = m_settings.value("FadeoutDuration", 2000).toInt(); + m_crossfadeEnabled = m_settings.value("CrossfadeEnabled", true).toBool(); +} + +bool +XineEngine::init() +{ + qDebug() << "'Bringing joy to small mexican gerbils, a few weeks at a time.'"; + +#ifdef Q_OS_WIN32 + putenv(QString("XINE_PLUGIN_PATH=" + + QCoreApplication::applicationDirPath() + "/xine/plugins").toAscii().constData()); +#endif + + m_xine = xine_new(); + + if( !m_xine ) { + QMessageBox::critical( 0, "Error", "Amarok could not initialize xine." ); + return false; + } + + #ifdef XINE_SAFE_MODE + xine_engine_set_param( m_xine, XINE_ENGINE_PARAM_VERBOSITY, 99 ); + #endif + + //xine_config_load( m_xine, configPath() ); + //debug() << "w00t" << configPath() << endl; + + xine_init( m_xine ); + + makeNewStream(); + + #ifndef XINE_SAFE_MODE + startTimer( 200 ); //prunes the scope + #endif + + return true; +} + +bool +XineEngine::makeNewStream() +{ + m_audioPort = xine_open_audio_driver( m_xine, m_currentAudioPlugin.toLocal8Bit().constData(), NULL ); + if( !m_audioPort ) { + //TODO make engine method that is the same but parents the dialog for us + QMessageBox::critical(0, "Error", "xine was unable to initialize any audio drivers." ); + return false; + } + + m_stream = xine_stream_new( m_xine, m_audioPort, NULL ); + if( !m_stream ) { + xine_close_audio_driver( m_xine, m_audioPort ); + m_audioPort = NULL; + QMessageBox::critical(NULL, "Error", "Amarok could not create a new xine stream."); + return false; + } + + if( m_eventQueue ) + xine_event_dispose_queue( m_eventQueue ); + + xine_event_create_listener_thread( + m_eventQueue = xine_event_new_queue( m_stream ), + &XineEngine::XineEventListener, + (void*)this ); + + #ifndef XINE_SAFE_MODE + //implemented in xine-scope.h + m_post = scope_plugin_new( m_xine, m_audioPort ); + + xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); + xine_set_param( m_stream, XINE_PARAM_IGNORE_VIDEO, 1 ); + #endif +#ifdef XINE_PARAM_EARLY_FINISHED_EVENT + if ( xine_check_version(1,1,1) && !(m_xfadeLength > 0) ) { + // enable gapless playback + qDebug() << "gapless playback enabled."; + //xine_set_param(m_stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 ); + } +#endif + return true; +} + +// Makes sure an audio port and a stream exist. +bool +XineEngine::ensureStream() +{ + if( !m_stream ) + return makeNewStream(); + + return true; +} + +bool +XineEngine::load( const QUrl &url, bool isStream ) +{ + if( !ensureStream() ) + return false; + + Engine::Base::load( url, isStream ); + + if( s_outfader ) { + s_outfader->finish(); + delete s_outfader; + } + + if( m_xfadeLength > 0 && xine_get_status( m_stream ) == XINE_STATUS_PLAY && + url.scheme().toLower() == "file" && + xine_get_param( m_stream, XINE_PARAM_SPEED ) != XINE_SPEED_PAUSE && + ( m_xfadeNextTrack || //set by engine controller when switching tracks automatically + m_crossfadeEnabled)) + { + m_xfadeNextTrack = false; + // Stop a probably running fader + if( s_fader ) { + m_stopFader = true; + s_fader->finish(); // makes the fader stop abruptly + delete s_fader; + } + s_fader = new Fader( this, m_xfadeLength ); + setEqualizerParameters( m_intPreamp, m_equalizerGains ); + } + + // for users who stubbonly refuse to use DMIX or buy a good soundcard + // why doesn't xine do this? I cannot say. + xine_close( m_stream ); + + qDebug() << "Before xine_open() *****"; + + if( xine_open( m_stream, QFile::encodeName( url.toString() ) ) ) + { + qDebug() << "After xine_open() *****"; + + #ifndef XINE_SAFE_MODE + //we must ensure the scope is pruned of old buffers + timerEvent( 0 ); + + xine_post_out_t *source = xine_get_audio_source( m_stream ); + xine_post_in_t *target = (xine_post_in_t*)xine_post_input( m_post, const_cast("audio in") ); + xine_post_wire( source, target ); + #endif + + playlistChanged(); + + return true; + } + else + { + #ifdef XINE_PARAM_GAPLESS_SWITCH + if ( xine_check_version(1,1,1) && !(m_xfadeLength > 0) ) + xine_set_param( m_stream, XINE_PARAM_GAPLESS_SWITCH, 0); + #endif + } + + // FAILURE to load! + //s_fader will delete itself + determineAndShowErrorMessage(); + + return false; +} + +bool +XineEngine::play( uint offset ) +{ + if( !ensureStream() ) + return false; + + const bool has_audio = xine_get_stream_info( m_stream, XINE_STREAM_INFO_HAS_AUDIO ); + const bool audio_handled = xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_HANDLED ); + + if (has_audio && audio_handled && xine_play( m_stream, 0, offset )) + { + if( s_fader ) + s_fader->start( QThread::LowestPriority ); + + emit stateChanged( Engine::Playing ); + + return true; + } + + //we need to stop the track that is prepped for crossfade + delete s_fader; + + emit stateChanged( Engine::Empty ); + + determineAndShowErrorMessage(); + + xine_close( m_stream ); + + return false; +} + +void +XineEngine::determineAndShowErrorMessage() +{ + QString body; + + qDebug() << "xine_get_error()"; + switch (xine_get_error( m_stream )) { + case XINE_ERROR_NO_INPUT_PLUGIN: + body = "No suitable input plugin. This often means that the url's protocol is not supported. Network failures are other possible causes."; + break; + + case XINE_ERROR_NO_DEMUX_PLUGIN: + body = "No suitable demux plugin. This often means that the file format is not supported."; + break; + + case XINE_ERROR_DEMUX_FAILED: + body = "Demuxing failed."; + break; + + case XINE_ERROR_INPUT_FAILED: + body = "Could not open file."; + break; + + case XINE_ERROR_MALFORMED_MRL: + body = "The location is malformed."; + break; + + case XINE_ERROR_NONE: + // xine is thick. xine doesn't think there is an error + // but there may be! We check for other errors below. + + default: + if (!xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_HANDLED )) + { + // xine can read the plugin but it didn't find any codec + // THUS xine=daft for telling us it could handle the format in canDecode! + body = "There is no available decoder."; + QString const ext = QFileInfo(m_url.path()).completeSuffix(); + // TODO + //if (ext == "mp3" && EngineController::installDistroCodec( "xine-engine" )) + // return; + } + else if (!xine_get_stream_info( m_stream, XINE_STREAM_INFO_HAS_AUDIO )) + body = "There is no audio channel!"; + break; + } + + // TODO + /*Amarok::StatusBar::instance()->longMessage( + "" + i18n("Error Loading Media") + "

" + body + "

" + m_url.prettyURL(), + KDE::StatusBar::Error );*/ +} + +void +XineEngine::stop() +{ + if( s_fader && s_fader->isRunning()) + s_fader->resume(); // safety call if the engine is in the pause state + + if ( !m_stream ) + return; + + if( (m_fadeoutEnabled && !m_fadeOutRunning) || state() == Engine::Paused ) + { + s_outfader = new OutFader( this, m_fadeoutDuration ); + s_outfader->start(); + ::usleep( 100 ); //to be sure engine state won't be changed before it is checked in fadeOut() + m_url = QUrl(); //to ensure we return Empty from state() + + std::fill( m_scope.begin(), m_scope.end(), 0 ); + } + else if( !m_fadeOutRunning ) + { + xine_stop( m_stream ); + xine_close( m_stream ); + xine_set_param( m_stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1); + } + + emit stateChanged( Engine::Empty ); +} + +void +XineEngine::pause() +{ + if ( !m_stream ) + return; + + if( xine_get_param( m_stream, XINE_PARAM_SPEED ) != XINE_SPEED_PAUSE ) + { + if( s_fader && s_fader->isRunning() ) + s_fader->pause(); + + xine_set_param( m_stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE ); + xine_set_param( m_stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1); + emit stateChanged( Engine::Paused ); + + } +} + +void +XineEngine::unpause() +{ + if ( !m_stream ) + return; + + if( xine_get_param( m_stream, XINE_PARAM_SPEED ) == XINE_SPEED_PAUSE ) + { + if( s_fader && s_fader->isRunning() ) + s_fader->resume(); + + xine_set_param( m_stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL ); + emit stateChanged( Engine::Playing ); + } +} + +Engine::State +XineEngine::state() const +{ + if ( !m_stream || m_fadeOutRunning ) + return Engine::Empty; + + switch( xine_get_status( m_stream ) ) + { + case XINE_STATUS_PLAY: return xine_get_param( m_stream, XINE_PARAM_SPEED ) != XINE_SPEED_PAUSE ? Engine::Playing : Engine::Paused; + case XINE_STATUS_IDLE: return Engine::Empty; + case XINE_STATUS_STOP: + default: return m_url.isEmpty() ? Engine::Empty : Engine::Idle; + } +} + +uint +XineEngine::position() const +{ + if ( state() == Engine::Empty ) + return 0; + + int pos; + int time = 0; + int length; + + // Workaround for problems when you seek too quickly, see BUG 99808 + int tmp = 0, i = 0; + while( ++i < 4 ) + { + xine_get_pos_length( m_stream, &pos, &time, &length ); + if( time > tmp ) break; + usleep( 100000 ); + } + + // Here we check for new metadata periodically, because xine does not emit an event + // in all cases (e.g. with ogg streams). See BUG 122505 + if ( state() != Engine::Idle && state() != Engine::Empty ) + { + const Engine::SimpleMetaBundle bundle = fetchMetaData(); + if( bundle.title != m_currentBundle.title || bundle.artist != m_currentBundle.artist ) { + qDebug() << "Metadata received."; + m_currentBundle = bundle; + + XineEngine* p = const_cast( this ); + p->emit metaData( bundle ); + } + } + + return time; +} + +uint +XineEngine::length() const +{ + if ( !m_stream ) + return 0; + + // xine often delivers nonsense values for VBR files and such, so we only + // use the length for remote files + + if( m_url.scheme().toLower() == "file" ) + return 0; + + else { + int pos; + int time; + int length = 0; + + xine_get_pos_length( m_stream, &pos, &time, &length ); + if( length < 0 ) + length=0; + + return length; + } +} + +void +XineEngine::seek( uint ms ) +{ + if( !ensureStream() ) + return; + + if( xine_get_param( m_stream, XINE_PARAM_SPEED ) == XINE_SPEED_PAUSE ) { + // FIXME this is a xine API issue really, they need to add a seek function + xine_play( m_stream, 0, (int)ms ); + xine_set_param( m_stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE ); + } + else + xine_play( m_stream, 0, (int)ms ); +} + +void +XineEngine::setVolumeSW( uint vol ) +{ + if ( !m_stream ) + return; + if( !s_fader ) + xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, static_cast( vol * m_preamp ) ); +} + +void +XineEngine::fadeOut( uint fadeLength, bool* terminate, bool exiting ) +{ + if( m_fadeOutRunning ) //Let us not start another fadeout... + return; + + m_fadeOutRunning = !m_fadeOutRunning; + const bool isPlaying = m_stream && ( xine_get_status( m_stream ) == XINE_STATUS_PLAY ); + const float originalVol = Engine::Base::makeVolumeLogarithmic( m_volume ) * m_preamp; + + // On shutdown, limit fadeout to 3 secs max, so that we don't risk getting killed + const int length = exiting ? qMin( fadeLength, 3000u ) : fadeLength; + + if( length > 0 && isPlaying ) + { + // fader-class doesn't work in this spot as is, so some parts need to be copied here... (ugly) + uint stepsCount = length < 1000 ? length / 10 : 100; + uint stepSizeUs = (int)( 1000.0 * (float)length / (float)stepsCount ); + + ::usleep( stepSizeUs ); + QTime t; + t.start(); + float mix = 0.0; + while ( mix < 1.0 ) + { + if( *terminate ) break; + + ::usleep( stepSizeUs ); + float vol = Engine::Base::makeVolumeLogarithmic( m_volume ) * m_preamp; + float mix = (float)t.elapsed() / (float)length; + if ( mix > 1.0 ) + { + break; + } + if ( m_stream ) + { + float v = 4.0 * (1.0 - mix) / 3.0; + xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)( v < 1.0 ? vol * v : vol ) ); + } + } + } + if( m_fadeOutRunning && m_stream ) + xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, (uint) originalVol ); + m_fadeOutRunning = !m_fadeOutRunning; +} + +void +XineEngine::setEqualizerEnabled( bool enable ) +{ + if ( !m_stream ) + return; + + m_equalizerEnabled = enable; + + if( !enable ) { + QList gains; + for( uint x = 0; x < 10; x++ ) + gains << -101; // sets eq gains to zero. + + setEqualizerParameters( 0, gains ); + } +} + +/* + sets the eq params for xine engine - have to rescale eq params to fitting range (adapted from kaffeine and xfmedia) + + preamp + pre: (-100..100) + post: (0.1..1.9) - this is not really a preamp but we use the xine preamp parameter for our normal volume. so we make a postamp. + + gains + pre: (-100..100) + post: (1..200) - (1 = down, 100 = middle, 200 = up, 0 = off) + */ +void +XineEngine::setEqualizerParameters( int preamp, const QList &gains ) +{ + if ( !m_stream ) + return; + + m_equalizerGains = gains; + m_intPreamp = preamp; + QList::ConstIterator it = gains.begin(); + + xine_set_param( m_stream, XINE_PARAM_EQ_30HZ, int( (*it )*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_60HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_125HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_250HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_500HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_1000HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_2000HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_4000HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_8000HZ, int( (*++it)*0.995 + 100 ) ); + xine_set_param( m_stream, XINE_PARAM_EQ_16000HZ, int( (*++it)*0.995 + 100 ) ); + + m_preamp = ( preamp - 0.1 * preamp + 100 ) / 100.0; + setVolume( m_volume ); +} + +bool +XineEngine::canDecode( const QUrl &url ) const +{ + static QStringList list; + if(list.isEmpty()) + { + static QMutex mutex; + QMutexLocker l(&mutex); + + if (list.isEmpty()) { + char* exts = xine_get_file_extensions( m_xine ); + list = QString(exts).split(' '); + free( exts ); exts = NULL; + //images + list.removeAll("png"); + list.removeAll("jpg"); + list.removeAll("jpeg"); + list.removeAll("gif"); + list.removeAll("ilbm"); + list.removeAll("iff"); + //subtitles + list.removeAll("asc"); + list.removeAll("txt"); + list.removeAll("sub"); + list.removeAll("srt"); + list.removeAll("smi"); + list.removeAll("ssa"); + //HACK we also check for m4a because xine plays them but + //for some reason doesn't return the extension + if(!list.contains("m4a")) + list << "m4a"; + } + } + + if (url.scheme() == "cdda") + // play audio CDs pls + return true; + + QString path = url.path(); + + // partial downloads from Konqi and other browsers + // tend to have a .part extension + if (path.endsWith( ".part" )) + path = path.left( path.length() - 5 ); + + const QString ext = path.mid( path.lastIndexOf( '.' ) + 1 ).toLower(); + + return list.contains( ext ); +} + +const Engine::Scope& +XineEngine::scope() +{ + if( !m_post || !m_stream || xine_get_status( m_stream ) != XINE_STATUS_PLAY ) + return m_scope; + + MyNode* const myList = scope_plugin_list( m_post ); + metronom_t* const myMetronom = scope_plugin_metronom( m_post ); + const int myChannels = scope_plugin_channels( m_post ); + int scopeidx = 0; + + if (myChannels > 2) + return m_scope; + + //prune the buffer list and update m_currentVpts + timerEvent( 0 ); + + for( int n, frame = 0; frame < 512; ) + { + MyNode *best_node = 0; + + for( MyNode *node = myList->next; node != myList; node = node->next, Log::bufferCount++ ) + if( node->vpts <= m_currentVpts && (!best_node || node->vpts > best_node->vpts) ) + best_node = node; + + if( !best_node || best_node->vpts_end < m_currentVpts ) { + Log::noSuitableBuffer++; break; } + + int64_t + diff = m_currentVpts; + diff -= best_node->vpts; + diff *= 1<<16; + diff /= myMetronom->pts_per_smpls; + + const int16_t* + data16 = best_node->mem; + data16 += diff; + + diff += diff % myChannels; //important correction to ensure we don't overflow the buffer + diff /= myChannels; //use units of frames, not samples + + //calculate the number of available samples in this buffer + n = best_node->num_frames; + n -= diff; + n += frame; //clipping for # of frames we need + + if( n > 512 ) + n = 512; //we don't want more than 512 frames + + for( int a, c; frame < n; ++frame, data16 += myChannels ) { + for( a = c = 0; c < myChannels; ++c ) + { + // we now give interleaved pcm to the scope + m_scope[scopeidx++] = data16[c]; + if (myChannels == 1) // duplicate mono samples + m_scope[scopeidx++] = data16[c]; + } + } + + m_currentVpts = best_node->vpts_end; + m_currentVpts++; //FIXME needs to be done for some reason, or you get situations where it uses same buffer again and again + } + + Log::scopeCallCount++; + + return m_scope; +} + +void +XineEngine::timerEvent( QTimerEvent* ) +{ + if ( !m_stream ) + return; + + //here we prune the buffer list regularly + + MyNode *myList = scope_plugin_list( m_post ); + + if ( ! myList ) return; + + //we operate on a subset of the list for thread-safety + MyNode * const first_node = myList->next; + MyNode const * const list_end = myList; + + m_currentVpts = (xine_get_status( m_stream ) == XINE_STATUS_PLAY) + ? xine_get_current_vpts( m_stream ) + : LLONG_MAX; //if state is not playing OR paused, empty the list + //: std::numeric_limits::max(); //TODO don't support crappy gcc 2.95 + + for( MyNode *prev = first_node, *node = first_node->next; node != list_end; node = node->next ) + { + //we never delete first_node + //this maintains thread-safety + if( node->vpts_end < m_currentVpts ) { + prev->next = node->next; + + free( node->mem ); + free( node ); + + node = prev; + } + + prev = node; + } +} + +bool +XineEngine::event( QEvent* e ) +{ + #define message static_cast(static_cast(e)->data()) + + switch( e->type() ) + { + case XineEvent::PlaybackFinished: //XINE_EVENT_UI_PLAYBACK_FINISHED + emit trackEnded(); + return true; + + case XineEvent::InfoMessage: + emit infoMessage( (*message).arg( m_url.toString() ) ); + delete message; + return true; + + case XineEvent::StatusMessage: + emit statusText( *message ); + delete message; + return true; + + case XineEvent::MetaInfoChanged: { //meta info has changed + qDebug() << "Metadata received."; + const Engine::SimpleMetaBundle bundle = fetchMetaData(); + m_currentBundle = bundle; + emit metaData( bundle ); + } return true; + + case XineEvent::Redirecting: + emit statusText( QString("Redirecting to: ").arg( *message ) ); + load( QUrl( *message ), false ); + play(); + delete message; + return true; + case XineEvent::LastFMTrackChanged: + emit lastFmTrackChange(); + return true; + default: + ; + } + + #undef message + return false; +} + +//SLOT +void +XineEngine::playlistChanged() +{ + // TODO + /*#ifdef XINE_PARAM_EARLY_FINISHED_EVENT + #ifdef XINE_PARAM_GAPLESS_SWITCH + if ( xine_check_version(1,1,1) && !(m_xfadeLength > 0) + && m_url.isLocalFile() && Playlist::instance()->isTrackAfter() ) + { + xine_set_param(m_stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 ); + debug() << "XINE_PARAM_EARLY_FINISHED_EVENT enabled" << endl; + } + else + { + //we don't want an early finish event if there is no track after the current one + xine_set_param(m_stream, XINE_PARAM_EARLY_FINISHED_EVENT, 0 ); + debug() << "XINE_PARAM_EARLY_FINISHED_EVENT disabled" << endl; + } + #endif + #endif*/ +} + +static time_t last_error_time = 0; // hysteresis on xine errors +static int last_error = XINE_MSG_NO_ERROR; + +void +XineEngine::XineEventListener( void *p, const xine_event_t* xineEvent ) +{ + time_t current; + + if( !p ) return; + + #define xe static_cast(p) + + switch( xineEvent->type ) + { + case XINE_EVENT_UI_SET_TITLE: + + qDebug() << "XINE_EVENT_UI_SET_TITLE"; + + QApplication::postEvent( xe, new XineEvent( XineEvent::MetaInfoChanged ) ); + + break; + + case XINE_EVENT_UI_PLAYBACK_FINISHED: + qDebug() << "XINE_EVENT_UI_PLAYBACK_FINISHED"; + + #ifdef XINE_PARAM_GAPLESS_SWITCH + // TODO + /*if ( xine_check_version(1,1,1) && xe->m_url.isLocalFile() //Remote media break with gapless + //don't prepare for a track that isn't coming + && Playlist::instance() + && Playlist::instance()->isTrackAfter() + && !AmarokConfig::crossfade() ) + xine_set_param( xe->m_stream, XINE_PARAM_GAPLESS_SWITCH, 1);*/ + #endif + //emit signal from GUI thread + QApplication::postEvent( xe, new XineEvent(XineEvent::PlaybackFinished) ); + break; + + case XINE_EVENT_PROGRESS: { + xine_progress_data_t* pd = (xine_progress_data_t*)xineEvent->data; + + QString + msg = "%1 %2%"; + msg = msg.arg( QString::fromUtf8( pd->description ) ) + .arg( QString::number(pd->percent) + QLocale::system().percent() ); + + XineEvent *e = new XineEvent( XineEvent::StatusMessage ); + e->setData( new QString( msg ) ); + + QApplication::postEvent( xe, e ); + + } break; + + case XINE_EVENT_MRL_REFERENCE: { + /// xine has read the stream and found it actually links to something else + /// so we need to play that instead + + QString message = QString::fromUtf8( static_cast(xineEvent->data)->mrl ); + XineEvent *e = new XineEvent( XineEvent::Redirecting ); + e->setData( new QString( message ) ); + + QApplication::postEvent( xe, e ); + + } break; + + case XINE_EVENT_UI_MESSAGE: + { + qDebug() << "message received from xine"; + + xine_ui_message_data_t *data = (xine_ui_message_data_t *)xineEvent->data; + QString message; + + switch( data->type ) + { + case XINE_MSG_NO_ERROR: + { + //series of \0 separated strings, terminated with a \0\0 + char str[2000]; + char *p = str; + for( char *msg = data->messages; !(*msg == '\0' && *(msg+1) == '\0'); ++msg, ++p ) + *p = *msg == '\0' ? '\n' : *msg; + *p = '\0'; + + qDebug() << str; + + break; + } + + case XINE_MSG_ENCRYPTED_SOURCE: + break; + + case XINE_MSG_UNKNOWN_HOST: + message = "The host is unknown for the URL: %1"; goto param; + case XINE_MSG_UNKNOWN_DEVICE: + message = "The device name you specified seems invalid."; goto param; + case XINE_MSG_NETWORK_UNREACHABLE: + message = "The network appears unreachable."; goto param; + case XINE_MSG_AUDIO_OUT_UNAVAILABLE: + message = "Audio output unavailable; the device is busy."; goto param; + case XINE_MSG_CONNECTION_REFUSED: + message = "The connection was refused for the URL: %1"; goto param; + case XINE_MSG_FILE_NOT_FOUND: + message = "xine could not find the URL: %1"; goto param; + case XINE_MSG_PERMISSION_ERROR: + message = "Access was denied for the URL: %1"; goto param; + case XINE_MSG_READ_ERROR: + message = "The source cannot be read for the URL: %1"; goto param; + case XINE_MSG_LIBRARY_LOAD_ERROR: + message = "A problem occurred while loading a library or decoder."; goto param; + + case XINE_MSG_GENERAL_WARNING: + message = "General Warning"; goto explain; + case XINE_MSG_SECURITY: + message = "Security Warning"; goto explain; + default: + message = "Unknown Error"; goto explain; + + + explain: + + // Don't flood the user with error messages + if( (last_error_time + 10) > time( ¤t ) && + data->type == last_error ) + { + last_error_time = current; + return; + } + last_error_time = current; + last_error = data->type; + + if( data->explanation ) + { + message.prepend( "" ); + message += ":

"; + message += QString::fromUtf8( (char*)data + data->explanation ); + } + else break; //if no explanation then why bother! + + //FALL THROUGH + + param: + + // Don't flood the user with error messages + if((last_error_time + 10) > time(¤t) && + data->type == last_error) + { + last_error_time = current; + return; + } + last_error_time = current; + last_error = data->type; + + message.prepend( "

" ); + message += "

"; + + if(data->explanation) + { + message += "xine parameters: "; + message += QString::fromUtf8( (char*)data + data->parameters ); + message += ""; + } + else message += "Sorry, no additional information is available."; + + QApplication::postEvent( xe, new XineEvent(XineEvent::InfoMessage, new QString(message)) ); + } + + } //case + case XINE_EVENT_UI_CHANNELS_CHANGED: //Flameeyes used this for last.fm track changes + QApplication::postEvent( xe, new XineEvent(XineEvent::LastFMTrackChanged) ); + break; + } //switch + + #undef xe +} + +Engine::SimpleMetaBundle +XineEngine::fetchMetaData() const +{ + Engine::SimpleMetaBundle bundle; + bundle.title = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_TITLE ) ); + bundle.artist = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_ARTIST ) ); + bundle.album = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_ALBUM ) ); + bundle.comment = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_COMMENT ) ); + bundle.genre = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_GENRE ) ); + bundle.bitrate = QString::number( xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_BITRATE ) / 1000 ); + bundle.samplerate = QString::number( xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE ) ); + bundle.year = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_YEAR ) ); + bundle.tracknr = QString::fromUtf8( xine_get_meta_info( m_stream, XINE_META_INFO_TRACK_NUMBER ) ); + + return bundle; +} + +bool XineEngine::metaDataForUrl(const QUrl &url, Engine::SimpleMetaBundle &b) +{ + bool result = false; + xine_stream_t* tmpstream = xine_stream_new(m_xine, NULL, NULL); + if (xine_open(tmpstream, QFile::encodeName(url.toString()))) { + QString audioCodec = QString::fromUtf8(xine_get_meta_info(tmpstream, XINE_META_INFO_SYSTEMLAYER)); + + if (audioCodec == "CDDA") { + QString title = QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_TITLE)); + if ((!title.isNull()) && (!title.isEmpty())) { //no meta info + b.title = title; + b.artist = + QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_ARTIST)); + b.album = + QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_ALBUM)); + b.genre = + QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_GENRE)); + b.year = + QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_YEAR)); + b.tracknr = + QString::fromUtf8( + xine_get_meta_info(tmpstream, XINE_META_INFO_TRACK_NUMBER)); + if( b.tracknr.isEmpty() ) + b.tracknr = QFileInfo(url.path()).fileName(); + } else { + b.title = QString("Track %1").arg(QFileInfo(url.path()).fileName()); + b.album = "AudioCD"; + } + } + + if (audioCodec == "CDDA" || audioCodec == "WAV") { + result = true; + int samplerate = xine_get_stream_info( tmpstream, XINE_STREAM_INFO_AUDIO_SAMPLERATE ); + + // xine would provide a XINE_STREAM_INFO_AUDIO_BITRATE, but unfortunately not for CDDA or WAV + // so we calculate the bitrate by our own + int bitsPerSample = xine_get_stream_info( tmpstream, XINE_STREAM_INFO_AUDIO_BITS ); + int nbrChannels = xine_get_stream_info( tmpstream, XINE_STREAM_INFO_AUDIO_CHANNELS ); + int bitrate = (samplerate * bitsPerSample * nbrChannels) / 1000; + + b.bitrate = QString::number(bitrate); + b.samplerate = QString::number(samplerate); + int pos, time, length = 0; + xine_get_pos_length(tmpstream, &pos, &time, &length); + b.length = QString::number(length / 1000); + } + xine_close(tmpstream); + } + xine_dispose(tmpstream); + return result; +} + +bool XineEngine::getAudioCDContents(const QString &device, QList &urls) +{ + char **xine_urls = NULL; + int num; + int i = 0; + + if (!device.isNull()) { + qDebug() << "xine-engine setting CD Device to: " << device; + xine_cfg_entry_t config; + if (!xine_config_lookup_entry(m_xine, "input.cdda_device", &config)) { + emit statusText("Failed CD device lookup in xine engine"); + return false; + } + config.str_value = (char *)device.toAscii().constData(); + xine_config_update_entry(m_xine, &config); + } + + emit statusText("Getting AudioCD contents..."); + + xine_urls = xine_get_autoplay_mrls(m_xine, "CD", &num); + + if (xine_urls) { + while (xine_urls[i]) { + urls << QUrl(xine_urls[i]); + ++i; + } + } + else emit statusText("Could not read AudioCD"); + + return true; +} + +bool XineEngine::flushBuffer() +{ + return false; +} + +bool XineEngine::lastFmProxyRequired() +{ + return !( xine_check_version(1,1,9) ); +} + +////////////////////////////////////////////////////////////////////////////// +/// class Fader +////////////////////////////////////////////////////////////////////////////// + +Fader::Fader( XineEngine *engine, uint fadeMs ) + : QThread(engine) + , m_engine( engine ) + , m_xine( engine->m_xine ) + , m_decrease( engine->m_stream ) + , m_increase( 0 ) + , m_port( engine->m_audioPort ) + , m_post( engine->m_post ) + , m_fadeLength( fadeMs ) + , m_paused( false ) + , m_terminated( false ) +{ + if( engine->makeNewStream() ) + { + m_increase = engine->m_stream; + + xine_set_param( m_increase, XINE_PARAM_AUDIO_AMP_LEVEL, 0 ); + } + else { + s_fader = 0; + deleteLater(); + } +} + +Fader::~Fader() +{ + wait(); + + xine_close( m_decrease ); + xine_dispose( m_decrease ); + xine_close_audio_driver( m_xine, m_port ); + if( m_post ) xine_post_dispose( m_xine, m_post ); + + if( !m_engine->m_stopFader ) + m_engine->setVolume( m_engine->volume() ); + + m_engine->m_stopFader = false; + s_fader = 0; +} + +void +Fader::run() +{ + // do a volume change in 100 steps (or every 10ms) + uint stepsCount = m_fadeLength < 1000 ? m_fadeLength / 10 : 100; + uint stepSizeUs = (int)( 1000.0 * (float)m_fadeLength / (float)stepsCount ); + + float mix = 0.0; + float elapsedUs = 0.0; + while ( mix < 1.0 ) + { + if ( m_terminated ) + break; + // sleep a constant amount of time + QThread::usleep( stepSizeUs ); + + if ( m_paused ) + continue; + + elapsedUs += stepSizeUs; + + // get volume (amarok main * equalizer preamp) + float vol = Engine::Base::makeVolumeLogarithmic( m_engine->m_volume ) * m_engine->m_preamp; + + // compute the mix factor as the percentage of time spent since fade begun + float mix = (elapsedUs / 1000.0) / (float)m_fadeLength; + if ( mix > 1.0 ) + { + if ( m_increase ) + xine_set_param( m_increase, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)vol ); + break; + } + + // change volume of streams (using dj-like cross-fade profile) + if ( m_decrease ) + { + //xine_set_param( m_decrease, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(vol * (1.0 - mix)) ); // linear + float v = 4.0 * (1.0 - mix) / 3.0; + xine_set_param( m_decrease, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)( v < 1.0 ? vol * v : vol ) ); + } + if ( m_increase ) + { + //xine_set_param( m_increase, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)(vol * mix) ); //linear + float v = 4.0 * mix / 3.0; + xine_set_param( m_increase, XINE_PARAM_AUDIO_AMP_LEVEL, (uint)( v < 1.0 ? vol * v : vol ) ); + } + } + + //stop using cpu! + xine_stop( m_decrease ); + + deleteLater(); +} + +void +Fader::pause() +{ + m_paused = true; +} + +void +Fader::resume() +{ + m_paused = false; +} + +void +Fader::finish() +{ + m_terminated = true; +} + +////////////////////////////////////////////////////////////////////////////// +/// class OutFader +////////////////////////////////////////////////////////////////////////////// + +OutFader::OutFader( XineEngine *engine, uint fadeLength ) + : QThread(engine) + , m_engine( engine ) + , m_terminated( false ) + , m_fadeLength( fadeLength ) +{ +} + +OutFader::~OutFader() +{ + wait(); + + s_outfader = 0; +} + +void +OutFader::run() +{ + m_engine->fadeOut( m_fadeLength, &m_terminated ); + + xine_stop( m_engine->m_stream ); + xine_close( m_engine->m_stream ); + xine_set_param( m_engine->m_stream, XINE_PARAM_AUDIO_CLOSE_DEVICE, 1); + + deleteLater(); +} + +void +OutFader::finish() +{ + m_terminated = true; +} diff --git a/src/xine-engine.h b/src/xine-engine.h new file mode 100644 index 000000000..74ae30450 --- /dev/null +++ b/src/xine-engine.h @@ -0,0 +1,165 @@ +/*************************************************************************** + * Copyright (C) 2004,5 Max Howell * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef XINE_ENGINE_H +#define XINE_ENGINE_H + +#include "enginebase.h" +#include +#include +#include + +extern "C" +{ + #include + #include +} + +class XineConfigDialog; + +class XineEvent : public QEvent { +public: + enum EventType { + PlaybackFinished = QEvent::User + 1, + InfoMessage, + StatusMessage, + MetaInfoChanged, + Redirecting, + LastFMTrackChanged, + }; + + XineEvent(EventType type, void* data = NULL) : QEvent(QEvent::Type(type)), data_(data) {} + + void setData(void* data) { data_ = data; } + void* data() const { return data_; } + +private: + void* data_; +}; + +class XineEngine : public Engine::Base +{ + Q_OBJECT + + friend class Fader; + friend class OutFader; + + ~XineEngine(); + + virtual bool init(); + virtual bool canDecode( const QUrl& ) const; + virtual bool load( const QUrl &url, bool stream ); + virtual bool play( uint = 0 ); + virtual void stop(); + virtual void pause(); + virtual void unpause(); + virtual uint position() const; + virtual uint length() const; + virtual void seek( uint ); + + virtual bool metaDataForUrl(const QUrl &url, Engine::SimpleMetaBundle &b); + virtual bool getAudioCDContents(const QString &device, QList &urls); + virtual bool flushBuffer(); + + virtual Engine::State state() const; + virtual const Engine::Scope &scope(); + + virtual void setEqualizerEnabled( bool ); + virtual void setEqualizerParameters( int preamp, const QList& ); + virtual void setVolumeSW( uint ); + virtual void fadeOut( uint fadeLength, bool* terminate, bool exiting = false ); + + static void XineEventListener( void*, const xine_event_t* ); + virtual bool event( QEvent* ); + virtual void timerEvent( QTimerEvent* ); + + virtual void playlistChanged(); + virtual void reloadSettings(); + + Engine::SimpleMetaBundle fetchMetaData() const; + + virtual bool lastFmProxyRequired(); + + bool makeNewStream(); + bool ensureStream(); + + void determineAndShowErrorMessage(); //call after failure to load/play + + xine_t *m_xine; + xine_stream_t *m_stream; + xine_audio_port_t *m_audioPort; + xine_event_queue_t *m_eventQueue; + xine_post_t *m_post; + + int64_t m_currentVpts; + float m_preamp; + + bool m_stopFader; + bool m_fadeOutRunning; + + QString m_currentAudioPlugin; //to see if audio plugin has been changed + //need to save these for when the audio plugin is changed and xine reloaded + bool m_equalizerEnabled; + int m_intPreamp; + QList m_equalizerGains; + + QSettings m_settings; + bool m_fadeoutOnExit; + bool m_fadeoutEnabled; + bool m_crossfadeEnabled; + int m_fadeoutDuration; + + mutable Engine::SimpleMetaBundle m_currentBundle; + +public: + XineEngine(); + +signals: + void resetConfig(xine_t *xine); +}; + +class Fader : public QThread +{ + XineEngine *m_engine; + xine_t *m_xine; + xine_stream_t *m_decrease; + xine_stream_t *m_increase; + xine_audio_port_t *m_port; + xine_post_t *m_post; + uint m_fadeLength; + bool m_paused; + bool m_terminated; + + virtual void run(); + +public: + Fader( XineEngine *, uint fadeLengthMs ); + ~Fader(); + void pause(); + void resume(); + void finish(); +}; + +class OutFader : public QThread +{ + XineEngine *m_engine; + bool m_terminated; + uint m_fadeLength; + + virtual void run(); + +public: + OutFader( XineEngine *, uint fadeLengthMs ); + ~OutFader(); + + void finish(); +}; + +#endif diff --git a/src/xine-scope.c b/src/xine-scope.c new file mode 100644 index 000000000..8ff422e97 --- /dev/null +++ b/src/xine-scope.c @@ -0,0 +1,186 @@ +/* Author: Max Howell , (C) 2004 + Copyright: See COPYING file that comes with this distribution + + This has to be a c file or for some reason it won't link! (GCC 3.4.1) +*/ + +/* gcc doesn't like inline for me */ +#define inline +/* need access to port_ticket */ +#define XINE_ENGINE_INTERNAL + +#include "xine-scope.h" +#include +#include + +typedef struct scope_plugin_s scope_plugin_t; + +struct scope_plugin_s +{ + post_plugin_t post; + + metronom_t metronom; + int channels; + MyNode *list; +}; + +/************************* + * post plugin functions * + *************************/ + +static int +scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode ) +{ + #define port ((post_audio_port_t*)port_gen) + #define this ((scope_plugin_t*)((post_audio_port_t*)port_gen)->post) + + _x_post_rewire( (post_plugin_t*)port->post ); + _x_post_inc_usage( port ); + + port->stream = stream; + port->bits = bits; + port->rate = rate; + port->mode = mode; + + this->channels = _x_ao_mode2channels( mode ); + + return port->original_port->open( port->original_port, stream, bits, rate, mode ); +} + +static void +scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream ) +{ + MyNode *node; + + /* ensure the buffers are deleted during the next XineEngine::timerEvent() */ + for( node = this->list->next; node != this->list; node = node->next ) + node->vpts = node->vpts_end = -1; + + port->stream = NULL; + port->original_port->close( port->original_port, stream ); + + _x_post_dec_usage( port ); +} + +static void +scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream ) +{ +/* FIXME With 8-bit samples the scope won't work correctly. For a special 8-bit code path, + the sample size could be checked like this: if( port->bits == 8 ) */ + + const int num_samples = buf->num_frames * this->channels; + metronom_t *myMetronom = &this->metronom; + MyNode *new_node; + + /* I keep my own metronom because xine wouldn't for some reason */ + memcpy( &this->metronom, stream->metronom, sizeof(metronom_t) ); + + new_node = malloc( sizeof(MyNode) ); + new_node->vpts = myMetronom->got_audio_samples( myMetronom, buf->vpts, buf->num_frames ); + new_node->num_frames = buf->num_frames; + new_node->mem = malloc( num_samples * 2 ); + memcpy( new_node->mem, buf->mem, num_samples * 2 ); + + { + int64_t + K = myMetronom->pts_per_smpls; /*smpls = 1<<16 samples*/ + K *= num_samples; + K /= (1<<16); + K += new_node->vpts; + + new_node->vpts_end = K; + } + + port->original_port->put_buffer( port->original_port, buf, stream ); + + /* finally we should append the current buffer to the list + * this is thread-safe due to the way we handle the list in the GUI thread */ + new_node->next = this->list->next; + this->list->next = new_node; + + #undef port + #undef this +} + +static void +scope_dispose( post_plugin_t *this ) +{ + MyNode *list = ((scope_plugin_t*)this)->list; + MyNode *prev; + MyNode *node = list; + + /* Free all elements of the list (a ring buffer) */ + do { + prev = node->next; + + free( node->mem ); + free( node ); + + node = prev; + } + while( node != list ); + + + free( this ); +} + + +/************************ + * plugin init function * + ************************/ + +xine_post_t* +scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target ) +{ + scope_plugin_t *scope_plugin = xine_xmalloc( sizeof(scope_plugin_t) ); + post_plugin_t *post_plugin = (post_plugin_t*)scope_plugin; + + { + post_in_t *input; + post_out_t *output; + post_audio_port_t *port; + + _x_post_init( post_plugin, 1, 0 ); + + port = _x_post_intercept_audio_port( post_plugin, audio_target, &input, &output ); + port->new_port.open = scope_port_open; + port->new_port.close = scope_port_close; + port->new_port.put_buffer = scope_port_put_buffer; + + post_plugin->xine_post.audio_input[0] = &port->new_port; + post_plugin->xine_post.type = PLUGIN_POST; + + post_plugin->dispose = scope_dispose; + } + + /* code is straight from xine_init_post() + can't use that function as it only dlopens the plugins + and our plugin is statically linked in */ + + post_plugin->running_ticket = xine->port_ticket; + post_plugin->xine = xine; + + /* scope_plugin_t init */ + scope_plugin->list = xine_xmalloc( sizeof(MyNode) ); + scope_plugin->list->next = scope_plugin->list; + + return &post_plugin->xine_post; +} + +MyNode* +scope_plugin_list( void *post ) +{ + return ((scope_plugin_t*)post)->list; +} + +int +scope_plugin_channels( void *post ) +{ + return ((scope_plugin_t*)post)->channels; +} + +metronom_t* +scope_plugin_metronom( void *post ) +{ + return &((scope_plugin_t*)post)->metronom; +} diff --git a/src/xine-scope.h b/src/xine-scope.h new file mode 100644 index 000000000..ce2d7ee7d --- /dev/null +++ b/src/xine-scope.h @@ -0,0 +1,50 @@ +/* Author: Max Howell , (C) 2004 + Copyright: See COPYING file that comes with this distribution + + This has to be a c file or for some reason it won't link! (GCC 3.4.1) +*/ + +#ifndef XINESCOPE_H +#define XINESCOPE_H + +/* need access to some stuff for scope time stamping */ +#define METRONOM_INTERNAL + +#include +#include + +typedef struct my_node_s MyNode; + +struct my_node_s +{ + MyNode *next; + int16_t *mem; + int num_frames; + int64_t vpts; + int64_t vpts_end; +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + xine_post_t* + scope_plugin_new( xine_t*, xine_audio_port_t* ); + + /* we sacrifice type-safety here because some GCCs appear broken + * and choke on redefining the xine_post_t typedef + */ + + MyNode* + scope_plugin_list( void* ); + + int + scope_plugin_channels( void* ); + + metronom_t* + scope_plugin_metronom( void* ); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tangerine.pro b/tangerine.pro new file mode 100644 index 000000000..65d926226 --- /dev/null +++ b/tangerine.pro @@ -0,0 +1,2 @@ +TEMPLATE = subdirs +SUBDIRS = src