From 8f284092fa33c1a96644a5d82a785a2b259e2356 Mon Sep 17 00:00:00 2001 From: Neil Date: Wed, 7 Sep 2016 21:41:04 +0200 Subject: [PATCH] Sketch in sound support --- README.txt | 2 +- data/sounds/mouth_pop_2a.ogg | Bin 0 -> 6495 bytes data/sounds/silence.ogg | Bin 0 -> 4195 bytes data/sounds/sources.txt | 25 ++++++++++++++++++++++ tabakrolletjie/constants.py | 9 ++++++++ tabakrolletjie/loader.py | 10 +++++++++ tabakrolletjie/main.py | 2 ++ tabakrolletjie/sound.py | 40 +++++++++++++++++++++++++++++++++++ 8 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 data/sounds/mouth_pop_2a.ogg create mode 100644 data/sounds/silence.ogg create mode 100644 data/sounds/sources.txt create mode 100644 tabakrolletjie/sound.py diff --git a/README.txt b/README.txt index c7b132f..96cd265 100644 --- a/README.txt +++ b/README.txt @@ -19,7 +19,7 @@ Fonts: data/fonts/DejaVu-Copyright.txt Sounds: - +data/sounds/sources.txt Running the Game diff --git a/data/sounds/mouth_pop_2a.ogg b/data/sounds/mouth_pop_2a.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9498f99fe8f1d49c309d9e44e57b0f6222599825 GIT binary patch literal 6495 zcmcgwdpy+J+Fx^F24O;O4UM*#5p6UQTQ!M@8ODsCacNweD3qERyK-bO?2<|hVWW{t z5p4`JKi*6F5psdvrT`<#8wc|Yg#dH;ErHP7!^Ydz~(&-47g&syup zJ2H|D(BO|U>EXCe&N_={c_?F4{LbCs+xYShluM2L0ZZciqXXqFpZSj>pNWDkexBoq z=9;g6Eq0iBJyvkoe_LGC3h&*Kq?m2tehTfRO(a`u8*3X_No00JRG4rpZ-+24k|&_Z zm7|pACogf{;0N`ifKG%TWorQ|J1E0|pKlXs5YZo)u}rMvOs?Sj1)ZTZ76#tAc)N(- zog2=gxE8ROP%eT+Q8r*}1#L5da=21Hndf@GH1KAxmX_6pMionYmS0(Odd7cwwdEk}_n2ym7xms*WafF}q_KOun z_MO_we12wfPZlD#vxP=5tXBn000`-&&HEoyQCKqjF_JE{VEjkz6Z{j5D~cPY_G$weaczN`M4IltR8q z!2B5=ypOTTv(mCh2{Q|KL(V7_awZMI4$n)=A$N7wIAP}EEaZ-b1)EHk=0I*?IMLvC z!EVTzlo#1d70YK_oh{-2<{*PyaoMBw(^dVD%gqV4nJz91PMBFXVC?+7VqTv@SV2nU z(;!zn`Dpt*r)d5gnGX;2H%x!kfn9Cov%?8t`R3`{Cd+3_5++VZF4(7f4stVB<%`Sb z&U=mrz(h=7xtpZvK$5N>-fr>(F$Hf?RemzVqWZL)Se9kl-XZ5eVp(>?@%ibS-Oj3% z^7|fYwGF;OJFNzc#RO+ORH7iwv&M?}i2$%})sM(ruNZNsR7k=zD3$qWML6N0JToje z*7OoMH*a3`x&ru2N)xbNKg}xE8}uyJnkT5g#WA; z=3R%Lgk`N)Hh_jeZzQY?n^t{(x5J-qlHh{0T{>>Nh#kjFJL)aFUR&PNvSY8bWAp7e zd{>T;Arl}nIc0F<43{I6Q+cJzY2RN~)Kj?V4#3pvBTxRUrl?YrGXNOK(L~O8Ebq=X z-IP}mP&g5A(ro+5(-~){(FzfoTtr^Tc_%4_<=YA?0}3l4{XbMg1;DcaVD2Ke!FmjO zMRc2wF3bfqU@m~3x@B8-WK%oqsf;%+J_5!7mD`8?>kEL>5raqE*e|7*4E zte009*kv&5Kuch3Pl)g(QrA=RuZli3(KeB$ZNX)XB%oi{{Zt3%n zIGip@W!akNrZPRuivbV;9Q>)3_GB$W(Tad*eYTVLYpRcg>aF9-7I1y2i0rjf-&;Bx zS<~x_uo2#nFT!bZx<_5Z_C@YdkpW+1$PPi`U6BD^A0mXKqw%prGH!tGejkK4>dOtX zM`VNCfWbsgUSh~=C*&QyPq?N}z#S0A1_`+%?|s?vi~%99Pske*@&Y*AfD3kTv=`yY z1l*x`9_KhR)F|u|CPLv54v+JJ7a&UukQM(T;Er&(92pWYcz7sJ$Q_IwJMQF-$Ti=i zLZEU-{J63~yFLj-X>0)O@q-f)PM#2s4hgsctGGxWGBhCM#0z0_3<}E_vUjmT7Y>Ky z#g5u@W$%%I_lZb+Y{;PSNxpFC!W!gVB0Dc_Ou!AfkT`0vbwoG4SC|-*8yn)!8=4hz z9fmLMAeOyQy=HOw#!r{(SG;WYx+n~C2p)OX*;GqB|C`#ivubW5v$?%7@tF8kD{G{f0$nbKP*g z&BJD^1(&UfZP6ot3y|fWt%*>(c3*b5EPBLws41;}$IAGz$d|2N`f#@yhX+EavjLg9 z#T5|DLFh44ABknB&azG|h-NNAWyo@=T~xcSl?dYveSnG}s~AYG6=Nl%tIwDHhT2C( zeEb*#5~PnB3twyy9Btxq28FU*-UyY!S%t9kpgfNQUwAGrC{M2H9-Gni27(0%SOvX; zO{7bkA=7q65C*3a8OY^zzM&)9cCxoFY`Cv9AOi|OjmR}4vH>2akvonjl36f@?wMF z=qd)MNj`U|DV7VXp2Dhr9wOv&o4BJ;a*#XpE*23Ag9dqHdEC)O@gcK`FgRRja~>~9 zZ|lgikxRAOjQKFhb0?QO0#)m6?33^Y5TT5U3>}XRxWF44OqAP)aEDfL2by>RO~QcV ziKDq(ZoCkJ7HN|2vtjYE0eiS3gV35p#4mC5ePXHAndapHgtnjnsYPtdjB57)Bvts@ z(`_b6R8@GZ5O1VR7Ug6+D4U3VZ6`@$CTo%?X0e_Z!Q}TSmH4u@TS-_fk6L)#GZk1# zt-SRZq@~wj0Sg5d9Ek`hi7c$HesRQfZwVPbe{cRKpu{|*`uU}%TG&%q`TS1(w=uA% za{AKQninVGZe4xptmTVlaztq+kFuS^dm6MLLI-bPemZKsx}W%=PUgan^cw zlkzMUJV3DkELaUU+-v<&23zBR(QE&?4`>)M^4*c)jbMjy2 z{-;P)`G5BPb+vyV{fAZa10Mfk+P@3`-z@$AR+anT%|nCor9@C}OebUhgcFF6uv8tV ziZ*20z(df>@qj)*(}7aeAaTH%NaW7*yVv6@B$B{qL~%CD)2iaG1HPhM66jeBFK zsJnqu(csHwSmnWsOx2)%1cTDpA9$#-b(j@hds{!c#;(yXDATGnFd79`t7`x$ZdJ{Z zI2KjcUy&FP<2D;9twpH>$J8uV_j;U(SlOhqh_B%|r4w-%+8`!az}t}qys~ZScEA~l zwVXTPC~QjZD{gEaDix`U3mww~Un*w8j{u3hDS>!1fx?th3CkJ3Oe}|=4*d8~5Wl?A^ejtJRz%k32>n!FmvTvjMoe2#j-Shfgze?xX2d&?V6$<`7vh?P z2Y71~RvE9l(F9Lug&;Sv-C(NYcO9K-8x@z21Db?|S}0n0%E^H=wVvBxMNisgA|Zu@ zPa#CK?$lE?y)h zumpfM9ARPa=Cs>N8`E2r-F|?1_(vfS;58Z+c%uXag5q-w`?gWh1>~P&^1JKv6;9)Z z%gyRb3(`}%()qFc7(s0G&KVlb(I4?k;8PEwJf8P{_gTbR{=d(Ys3U)sHU^rKGF)WAO zfd1X0IeDVwO7)TjNm@G_s3{*Eh;@@ie0mAI18$%$KJNeYsOZYINn-lG<|mmpkH30A zBPAi11kq@eNa?fOx)|L0j{3gwfB@7tp{~iBYtkjCX2Gm5LQE0-d>rf-i>N`M9RMRBnP1c zgq`jfeXWBU2bFcBG<8%$ZD1D(r3H+K=JXEvI2T{c*SD?4QbgXMvn0YEwCEnbk@7JK z(0v16wMV5#Z7F!l(mX~+PZ=-D9H6ezg69RWFNi$h5r6y!#BF^Z774x1j4=D40ok(0G$lzq$ohc zRdgrv!^icXSU+pf*VZxwhW>40G@cBMhv&Z5<~vvfi>^OTzFD;V*jLnQl;9s(vE7p8^E_u%LVFxpmZAg1B#oMMPRTk8W3elLcNkBC^~kXvd;_<@XW&E*>x_HW}vh0`enfr^? z%75Sa$@`OrS`sA?w^e7REmbAns95!V za!X1a?~dIqog{Albb;|n4r4}`QMUZ#{sil@FU2ep`NPZDACkq&N<9G8f+jI&n3kJZ zJfPzD0CxgVRh0s`;Lif(C3S;Re}e%bcfL{jq^&6R4*7GE>R>`aYo zb!{%kJkRYa{yu+>5WcbNv%$K%Cl2HlwGmG4#qD47vyaBWU9=G|1!pNm(J*AthZSk; z$(LeC`S4aGcid18nNRKOPRpar4!+f*IS1%5YNk@__9Xi^)-~>U_56tBr@hAXJxWrg zL3H8yzwKeq4cRgXy5BRD_jY z$2tLRc>l!qz{9}^MT-Jb)EBvbOXU6mVv0`bS4}{U3wV=1T@vWH_)vRY`HdM&r+Z+G z-NFYeio&gTtXs49ap4Bi^R<=7o-BUSwfaf>kC&@4M~k1n-0TzjUC)%$ZD-kfoaOj> zOem^E1rLm+Wf)Bw+FeVeg#Sw{0r649I$FGG=Sl_&K-OuQ)E7E`FtSMJ)ccf#`q?ZAHX&F5llmLV0MG%pg3FpeUV zMQ9P)Nu-$X}MAq;-B(318S-?@awvgEItddik%- zVc9aH8xLP%qrd;m z0g(2=h15yOIIK2Muj@gni&W%bnY8zn2lJqgCERjCwYeQT86lQ$-*tT02RBWrM>#%& z50Wp>hF_i~dmBG4T6o{zRWEbFX1fc8%%k<})TmDdS@^vAEL4cfL1h6@0^TXO&@glh z79~x^F{6MbP$kon(F&-L=Myp|({*kga4l%v7Wn+C*5a-H;F8v|VWlXy&U?+)J2dro zt4@%Pp3kmm{?Yj8b#@xjnZAAhZ;Y{1$=g|YtN2w}{99!kIA&Zh6}l}n1>1sEnrcDA z94uFYn`;YJKo?<6=fn61Ol%MRzK%wdj?wRW3GcKXo({Qg(Q!e8mJ!tud*{N}rY@gv zd{h&+EMEJ3?+^3`=%$Agd#<;A`~Ct~NG4GN1&c1-5{O%rnB^6iEGcR#3Xs-=DJ3bO z0lM|yfk2AE(-c6NkE3X_%Ln{xj8tTItZ}lT?NL47z@bz7>L$?-tKLrsmev*24|!kz z`E=b}+|zscFG?%Ju3Y_zx*+w^d?9|JBDvZY22Nboo1lNmL zcT3#pKA!;FcQ3DrKMsF7r$4MQ(L2q!jx}=x2UW&PF^0fj^ac2nl2w3`X%EV{PKx=% zt0gXq+&;SX-B;kW6LWIGcG@xHq+d3l%rXplCU#qj4XDn#zcu)RPF<)u`Oec)m9hPt zR_7CM<9We^&-j_(zlT05+h8%CLpz`hnt&=$qgkU`oKvtyKwJ6*)e;YksPMnp5czOt zJ|N$@oOEqIFF}F#dilS4UnyZOXM`V8TYn=3GiqTKH9&YY^MQUgC}RBc9Tx`=N>bQM zE#*7Rl!fMA=9e?ejG`A@zq9OHifi8eMO&}4jm>Isdq6F8j?m%)q&LOr@nmdEILe=f z+e1UilWl%y2K#-!x`8R?eS?zDJ>T><>kQL778j^F<=t1=N08F%kFV2Nv*1;|-k~p; z$j>ca-Jv7=YZa!-!}co;EIQ(ZT3zWXR84dgKuIylXfnX-iZrNzE}8{8{w)|$IJ)G) zT!fXkVp}FUtV3tvu_!?Q1@qZ3(Y!}p6D?Bi2jruHL2tJYn@YMmH8!QCTy-9)i=xuc arcaL&(AE^7BXiRo1J1L6dt4g z5ONGN=>OA-S56hCoxF#tGSZs|AYl@rdg?nr@+i3m5B4MsV zsZgxV%@a!WFIk&fUv98ASqVxvBPl*ptlO}Sfiwu=cAj)&#J<9X@pUCxGXmY%?%P?q zEu1z%?v|=ivE3^QckA3$k^|#jGomKErfuQ6JX)5>C0=jwIdj$nQV`>n_^9&`qpX^p7W+l^pfMqy19>sabeUKeIV_I*@fcmS@ zOm{_E&^V}G88QsF`rh$;q@D}e$1cr=lw&~khAP-Wkedsg@2*IVQ#pgJ<3TCK+c$P= zM~E{5)arp&Z}5#_ppph`UBS(RKp8%2CEwXh@$8f;x>>kzOAyMSx_!Ud2GWo1Lw)I zy?N7?-G5Qf1)V3iRqh@bCXGbIPo~oN2?2Xua#o$Ul+s+|Cf*A*rAqtaa0)5cAXNM} z!31aJ!}?djRgSnc9jbgPH*cy;Z*I0;4>VVN_-fUS_Ui9n{SxZE=AD*+wc-agzIFJ* zg%IrVjSwR|`xW&(?#J$L6C8>fxtr*CD;mN#PvW0W%8Ku*iZj-ia`jUx^F(HK>Cg6- zK5L!It1f%C+PrP=^MSopr<%Wb%lgIluYUDNtzJTJF&&|GzEy-ToAAx#ci}~vhKo|9 zNv6I?&o`2;nS38!Vu{M!yjH&w)2L6$$!mXiv7ADuk~oJ$iw5r>VfHUT{}1YcC9p%Oe4X0?Fb7p zZZ--uLo%o|G6;E9%f<_qpHMAd?Bk|HS#hH3YT{!5asD)uD$U&jsEbO#(47L#okGrH zUv@Q7HIZ0Q3a7_omw&f)0&Ep>#tR;?1%?VH{u}#x?8W|H!T&k}7+iHX;kQG?VR}ax z1{(Mez9EpfsuFoH{oAY0t~I%{3pvr0hqE4~;AG}C!UeAAVLwKe()F*=@O8@Q&SO~Z9S6XiS`HMTJ#etQ<=HQ7i~QP$&xJ?jSb06 zcMGU1s@!aDUu4H(3t*_23)1Fm&0kX*z+!CS3~h9(++=R97J8z#U@R6pzO=BI3p%T> zHy@aLz1J3ty?q5Lj!cpMfSI;r>&iO`J$iSTPLX}D-a!sW=J*hpR4TeHL5+A(zwhx91tLT?(C zvycWA5m|7X&xQST%0n6{o|=fzd5@noLZ-CUNQhly+MI}g67r)Agvx2Ok6xT*uF}$Q zlMKY}s-@rtqyjkYElDuCx+v~|*roe;9s)N~(8r|LGa)Z9na$NhG8)T;GYSeefF%yv znKgT=DAcT3rv|_yfZ6uz&DK8z4#<9c{PyQV2;E^WLEQ;YZrhYk@R!O|bz-06lPvfu9tr<+WPp(G9Gs>Ss%cFdl&d%w7GV%@o-3Cj-fD8m8aewG*E+1WZGQqBSo>@TnE7}U9yb9nf($~_nCV_J#m z&~%OLh&@e55Er)9mJ%+KG|Ep|I*dI>eWY>Vnx#|OAD*u47#OMPEFw;RR@tFkv1*U0 zfB43(_Xl~kyQT7zyxPtStY6jbkw-t@wQPj7s!ArmR=Ha-!uztSBXTO(q5S#1&qt83NSM3$V(Jh3DT>s=ZoyHsoHz^_F2!T@fb)z* zJ4}oCVar4$-IyYFrIQ2^;Tl;Y7zAFqF{Q_q4#7!b4+@L~cvp}Q$uUoxlVx79^JvNw zPsLA_I>>o?{UjmRw`E6oVczDAnf8)OPhS(8{Is7O6VBoRx6{U1%x~BNj@qbKO7(Y=#scAn+`4=FOiKqYo literal 0 HcmV?d00001 diff --git a/data/sounds/sources.txt b/data/sounds/sources.txt new file mode 100644 index 0000000..40b4b63 --- /dev/null +++ b/data/sounds/sources.txt @@ -0,0 +1,25 @@ +Sources of sound files +====================== + +silence.ogg +----------- + +Notes: + Generated 2 secs of silence - dd if=/dev/zero of=silence.pcm bs=176400 count=2 ; oggenc -r silence.pcm + Generated by Neil Muller, Aug 2010 + Not copyrightable. + + +mouth_pop_2a.ogg +---------------- + +URL: + http://archive.org/download/Berklee44v5/Berklee44v5.zip +Source: + http://archive.org/details/Berklee44v5 +License: + http://creativecommons.org/licenses/by/3.0 +Notes: + Ogg generated using 'oggenc -q -1 mouth_pop_2a.wav' + + diff --git a/tabakrolletjie/constants.py b/tabakrolletjie/constants.py index 8edc2e9..380c277 100644 --- a/tabakrolletjie/constants.py +++ b/tabakrolletjie/constants.py @@ -27,3 +27,12 @@ FITTINGS_CATEGORY = 1 << 3 FONTS = { 'sans': 'DejaVuSans.ttf', } + +# Sound stuff +FREQ = 44100 +BITSIZE = -16 +CHANNELS = 2 +BUFFER = 1024 +DEFAULT_VOLUME = 1.0 + +NO_SOUND = os.environ.get("TABAK_NO_SOUND", "").lower() in ("1", "y", "yes") diff --git a/tabakrolletjie/loader.py b/tabakrolletjie/loader.py index 252960b..7f012a0 100644 --- a/tabakrolletjie/loader.py +++ b/tabakrolletjie/loader.py @@ -6,6 +6,7 @@ import os import pygame.image import pygame.font import pygame.display +import pygame.mixer from .constants import DEBUG @@ -52,6 +53,15 @@ class Loader(object): # Do we need to cache this? return font + def load_sound(self, *parts): + """Return a pygame sound""" + fn = self.full_path("sounds", *parts) + sound = self._cache.get(fn, None) + if not sound: + sound = pygame.mixer.Sound(fn) + self._cache[fn] = sound + return sound + _DATA_PREFIX = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "data")) diff --git a/tabakrolletjie/main.py b/tabakrolletjie/main.py index f09d681..f358403 100644 --- a/tabakrolletjie/main.py +++ b/tabakrolletjie/main.py @@ -8,6 +8,7 @@ from .constants import SCREEN_SIZE, TITLE from .engine import Engine from .gamestate import GameState from .scenes.menu import MenuScene +from .sound import sound def main(): @@ -17,6 +18,7 @@ def main(): pygame.display.set_mode(SCREEN_SIZE, pgl.SWSURFACE) pygame.display.set_caption(TITLE) # TODO: set an icon + sound.init() screen = pygame.display.get_surface() gamestate = GameState() diff --git a/tabakrolletjie/sound.py b/tabakrolletjie/sound.py new file mode 100644 index 0000000..14a01ff --- /dev/null +++ b/tabakrolletjie/sound.py @@ -0,0 +1,40 @@ + +from pygame import mixer + +from .constants import FREQ, BITSIZE, CHANNELS, BUFFER, DEFAULT_VOLUME, NO_SOUND +from .loader import loader + +class SoundManager(object): + + def init(self): + """This is not in __init__, because we want to delay until after + other pygame initialistion""" + self._init = False + if not NO_SOUND: + mixer.init(FREQ, BITSIZE, CHANNELS, BUFFER) + silence = loader.load_sound("silence.ogg") + if silence.get_length() < 1: + raise RuntimeError("Sound load error - silence.ogg too short") + try: + self.play_sound("silence.ogg") + self._init = True + except Exception, err: + print "Failed to enable sound: %r" % err + + def play_sound(self, name, volume=DEFAULT_VOLUME): + if self._init: + sound = loader.load_sound(name) + if sound is not None: + sound.set_volume(volume) + sound.play() + + def play_music(self, name, volume=DEFAULT_VOLUME): + pass + + def stop(self): + if self._init: + mixer.fadeout(1000) + mixer.music.stop() + + +sound = SoundManager() -- 2.34.1