From 7e51a04b713e79b2b5114f269e4af79ba9fe6050 Mon Sep 17 00:00:00 2001 From: Frank DeMarco Date: Tue, 4 Jun 2019 03:20:13 -0400 Subject: [PATCH] stash and write audio to recording --- demo/Demo.cpp | 17 ++++--- demo/Demo.hpp | 5 +- demo/config.json | 3 +- demo/resource/Ag.ogg | Bin 0 -> 12856 bytes src/Game.cpp | 8 ++++ src/Recorder.cpp | 109 ++++++++++++++++++++++++++++++++----------- src/Recorder.hpp | 10 +++- 7 files changed, 116 insertions(+), 36 deletions(-) create mode 100644 demo/resource/Ag.ogg diff --git a/demo/Demo.cpp b/demo/Demo.cpp index 691437d..0e54658 100644 --- a/demo/Demo.cpp +++ b/demo/Demo.cpp @@ -140,13 +140,11 @@ Demo::Demo() Mix_PlayMusic(music, -1); load_gl_context(); delegate.subscribe(&Demo::respond, this); - // Input* l = new Input(this); - // delete l; - // input.print_branch(); - // mushroom.print_branch(); - // Input* i = new Input(this); - // get_delegate().unsubscribe(i); - // delete i; + // audio_file.open("audio.raw", std::ios::binary); + // SDL_AudioSpec spec; + // audio_device_id = SDL_OpenAudioDevice(NULL, SDL_TRUE, &spec, &spec, 0); + // SDL_Log("opened audio device %i", audio_device_id); + // SDL_PauseAudioDevice(audio_device_id, SDL_FALSE); } void Demo::load_sdl_context() @@ -317,6 +315,11 @@ void Demo::respond(SDL_Event& event) load_gl_context(); } } + else if (delegate.compare(event, "play-sound")) + { + Mix_Chunk* music = Mix_LoadWAV("resource/Ag.ogg"); + Mix_PlayChannel(-1, music, 0); + } } void Demo::update() diff --git a/demo/Demo.hpp b/demo/Demo.hpp index c8832b7..8f6c646 100644 --- a/demo/Demo.hpp +++ b/demo/Demo.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "sdl2-gfx/SDL2_gfxPrimitives.h" @@ -54,7 +55,7 @@ struct Demo : Game SDL_Texture *grass_texture; int frame_count = 0, frame_count_timestamp; bool right_active = false, down_active = false, left_active = false, - up_active = false; + up_active = false, is_writing_audio = true; SDL_Event event; GLuint vbo, space_texture_id, mvp_id, framerate_texture_id, flat_program, world_program, fake_texture_id; @@ -62,6 +63,8 @@ struct Demo : Game int abc, def, ghi, jkl, mno, pqr, stu, vwx, yz; Mushroom mushroom = Mushroom(this); Sprite grass = Sprite(this, "resource/Field.png"); + // SDL_AudioDeviceID audio_device_id; + // std::ofstream audio_file; Demo(); void load_sdl_context(); diff --git a/demo/config.json b/demo/config.json index 1d959aa..4c3c9bb 100644 --- a/demo/config.json +++ b/demo/config.json @@ -14,7 +14,8 @@ "keys": { "context": " ", - "print-video-memory": "?" + "print-video-memory": "?", + "play-sound": "s" }, "recording": { diff --git a/demo/resource/Ag.ogg b/demo/resource/Ag.ogg new file mode 100644 index 0000000000000000000000000000000000000000..cafe51828829519eab68e500dc7990c909fb4294 GIT binary patch literal 12856 zcmch7cU)6X)9<18UIau85PFfSfFQj^KnT4_?}Bs%K_k7_(0d6Gnsg8ar1vIW1W}}l zB3+7dPw@9V@AJO*^SSr_b@#K`v$JPs_RQ>eX6Gb%;NYMOU<3b@2(Bq(Om{!MsRD}y z%lEOTwUZZS09&aNa{j8%I-vz^o1ya!4KhvnBF8_Oh;{27w3r;X{a(5Jb z;OPK)Bz`l2Ade+zJE0kFds@54h&pzp81kaS`wuYf+(F8NusVJP8+w9h7uRIF&+*=GGjbYYd}toHIx>PX{;ky z!x+FOoY`}LwKUt4n71rHh*)F*609MzRh+CPwN+LWC$-JpFrh#q(C{9nAv|MXQ{9Gd z9^f@5xsm-(Lv*DF1bh|+d`4SJ1wxGY2%eI3Pf*lfwIBcjR1;85q*bq_9j;{_orFHv z=hvYTpA=Qr)zj1mi;uaXuic!l&zx_daeAm}OQ3N}sOfyD`AMi1L)bs{SKy};OubSa zf(7KWOQx>!6tXcDevvH12??vj25d1Vfe;05GBTlRY}_j^E<;n03heu66t4*=kv%E9@2J;hYL z#QMFY!K&)5G>Fs~J=CE1*Ct@L9RTEnnR`8$2SIDV1*Sa34ZURMyfo)PQ(!Fee=aYt z@B%8rnq!~pj35+Eu(~n}0u;+oK&VLicO`H_M8Q``=0xVfs3dvjT0WXKYpOF+FN^Cn zIz8)Z2Oo_wu7Z2XGnCPrpD~f?HKtCQiTc~~qs}6zLca&c7&o%X`xvdjc~0*$3D65h zAg}R6=6cy{TCf+1%;IW%t@l^nKd?YQ%pU8M{0wqLe#mlpO=J%CPHnS)j1pnS{wI9o zzps{fNjgKc=bd9+Uc3(@m*JDh#5SUmQenY~y;aSGA;?3#xI}gb#&; z!+21CJqp}Zh;4#AKI4^>gr$29@sxsI@t+&_6FN?HWAZ=h_#U$kH3wKHMFez3W%Tv* z4SijW(|i`2L(S)XKFtMwnv1o#7WO}Z^>5DsK&J`0@=2t1jBtN;u$BVR-wpnk=XlWe zCo&HvLhsi>HQ)1(?u$J*5Sye?))CXxr8A$T^O>Tz)4gpzC2lvRZ#Uy>x6ou~+8k)y z^pC^*b(>FfKL6o47#Craj9XPp!u>DL$>)yyA`!=~o&+^c;`B>(h|EN18cL}8Tui}UfTwn$+J_8rf*OU1_dklDYMoe=`3^Z&C05Af8 zV(q$F2z8RDHf&hk7{;?vM!&{mOPf3&JU|O4HPI@uf$`uAH&aWMkR~zPY$HX2j3?T> z<9Hkg2{T|sXnZj2;Q~4UfUnM`4po0IR;YT&uelm2O@)B^OUG}h=MEe^WdYO=pR$Z6 zODAsZNrPtz7CHE#S14fR!$wG80nt!D7WIAUq_2KrnzXD@NhOhN4@8x7?V~hw^$W@| ztkNBjUibVLAQrK(ACVe&lDRKi!5|f z5a$>b)&DoyB_^ZmZC!S7s6<(XAS~Aj#jI0zR8jZV86hDbtBsSvSIZ#*lpA0Xm_fn;Kd8jaqrmF0-0sZsxy} zbow)?86`V#&4snrIuc`gef_44az0Ug8}c+th{Md&o0AxNMt6(ZlD?@ zHO1{R&_g0~DRwP&0D!3p*`n=LU|0s%#IS(@ zv5&zk4vdO6F_K&WQ1%WBfV@*l93@f-A|^8?0*bK#2Il^{ziJDB=pUz1p3>95pY)F* zQoxgy8$4dic|nf@tp(mI=Zz{sV~k~Hcx9D2pZ~H77O+A@4#?r%u8ebsi_sf74!{5i z2r6NGR$Eeq0frD-1wtMaB{cvDt$za)J}!F2X7)QUt81S?d^hCL9J6=wm>Mp^!-H zN?}k}SXHl)3-bLe(j>ZemK)_Q(r4f@J}S9k8&lhtO#;X{x&y%78Y`cWl()650kXyl>^<5}~1B;04>0z!e+HX4mFgOHy)fPmF_ zgryYMcTKKb+2J)7K&pVz^q-?$9mN3lz*7yA41 z5EcAg2o%5pN+v1*_Y?F>1i;QK(4!?8E21G68dix5D1h-u5q!qKD|R#dtLKby zzJD+F|F6gU|F|p`Vv>;@F-fB`p{|mmJnz^QO7J(Bnt<;vq`Dvmn6E$wAClZ;PL6}! z2NA`(#vC%Ht_A|phBP-A+yRb;_a={o@h35mfSZ75WC)JI7!@YaOK&qO-#4Mo4MNg+ zq;?$=!d(Eu)J1qU69kI)gpPAnBa=&&B;jXgZk|R1n@UM=y#%y3t#!0;pOFh02qP1i z@NBxvhzy7&ZM4t4GwJO)GjP$(k0vg)vzab6;GzNU0!<7qU_6C@;F)JKjgg#7$2=FS zZLDx#CYTsv;C8Q{$)@V{EDHu-pKM}lXU)6>0LYy#EWo2vO<|kA8^-P?jirbS$Gi+c z@BvFg#LK7NpcR5}067HR&Jcgq2X41*=&duzPof*OjEtTDFArTyHwTA4nep$P)v%plwR7_j~GSNBprprh*^6eGX^4|G1f^Y#5WYx)FZ1x zw0OQ2_sznIGLq?CVg*9AK`2280U=6O(U)>qvi~E&YgqW1L zKg8?36AnNbGC-ObVMIzzQ~t8hS_&{Svm78mkjBO~M3Zcayu&m9=mQCX;Ic;aV$mib zf@$2Iej$6%(n%zxj3Nh5EwEq%;Q5k724Tz0kc=abr%0eoq)MVrra{uu{f+3j2nqmU zix&}LZy#6Gy@~@>vJENj`HIV-%mD^(xho;Kln4aks)wNwh`+Di@4yI;DVSGp%o{vg zuVoR$&hDXwjb&keUaGN)DKanJBqOIVukrE{{m{GseR=tAq$Mw{*)yx|~gmfp+0ed*g6T<^oer(Z)&KyfN4L*7r#(u9B72<$}83LvkYbPART4Et9gjdOrS9Y->@M z?b>A3^rAP$jbv=)=F_FudreetI=BuD$GC2>wKpDOH5_Ihk`dX2)|dXWJ;ai5@0DvO zr+Fho+(>XQra&U>L=V5#wO8%P^{d?Sonq^SwR}E}_%FUgpEigdM@>oyUTF6$4E^EO zzIXe{9~uApwRj0K(VLTZWi5RYAG#3XziW7vLT*&ijFcGQV2 z)$2t1T-IS~_aFeOg zs>GI#{d*mX4TrQ(@EU$q9`qB^H+jwef)fi*=NirC2t)efS6k_YI=?7hvn3r!45+_M zeUsuePWh03Bvo&9(el7>!nphMY3*tY&y?)u@Hr}L>ecw6@QJi?o^E^ejZe&LVJO(i zHcon-2+)8VzaAiZMPdN!P#+1|AmX^Ce-3M|pLD=f%a=90q6V_@-JkEC(C| zYA|tT!V_XT^wN)hh9aZ!j`I7FN#E7Xl+SKmyJ%l8x<9-&eS=AqxK-+|me6Zc`Rt_M z!`DyV6W51}2M%pXWUE*5uJ-Qe@8j4#HPc^jQ%}8++hTdc&C5${SG`52TOv6s!Y8g% zH44j-QZ^nfgyR~UHs9u((z<@ErmU%%I0Hv%n?826M-`gr>psX~8;&9D&7fx}GJYC0 z{r%u=$D;_A;*gidb&yot_uO5%X4vkh3@RcxP&G9&E4T!%aEKbGe3H?A@P5r(ejjtG zz{W9hbzUoN!#jd8K3nf$4iRL?+k55^qQnAbi&D*iw3iUY*X?ylN3*7}Wuuj%uBZrD zB^qhxs+2k-l9C}W+*VQ&Qx-nSh@2TIGpJD3%z^P0782?x%~l!6M> zgxx`T@h){`I_}Qp#!1`T+Y^)SHyV7qS&aw3KJ&bP=Jq{Iu`X%w4PwIm^n*RPpjitom6D#` zjJQtOeH1mUKnEwE5gTZ*?j(*0LEQdSWmJRB&YC~^#E2#ZuB=l`rO2lA@+FZNPh?ny zW4XL}8DW%~JTET1e9DS+yCzp^daI!@f{CC~iyykupcP!Ea`(oYE#E~Wph8Pt?-3!; zU=IooLX3%38P{MJ0p2A7&V`<2q5KhX!d+DA5C+_c1WVi0wGEr6M0s#!Q4IyPQpL_t z?w2X$3OQ8Ty`lHRsT!?wh_&SPd(nl?lXlskX}){ga0hcyH7Imq#}wkXwwo4MVyWoh zEKPmuOG$*jcpC-DL6POeD-GpZ*G!xv z>2<=D>3qr<#LwLOJbLJ=M5zR*yVbCI+?I%u=Qm+{SDkM+VPChR>Nxp$Lt1@Aw|Sx> ze2S>Wl{4&&2P*9oQk>ZNd|bLK150O;#fK_Ko$XPap;F>0m7LLzRrt8pp==^5NeMAP z4MZMc`A(RWD|EDWcisg0yapLRyzhDX6g{xEK}b)HPu;~)oS@CG4jUZCHWN%!Ei%DH zgNLEKJTSJyN(Wrv%N*REW@w6N?u z97W3O{B1h*NJ;0z`DB`p3sQ$~c%W4om0;(pH;uM$vvbwdM7wFy&cMUM7^xz(*@a<5 zsV2lc1=M;>@ssijFgABvsSFMFsmSyQWIpmH^TUS;*4W7tN+UriTUJ2%Wr#JluwoLz z+6MuVd+8{T(*VZ`N5p6xnxYYkaw?o>bkmd(^yZEsv{527J+%|{x)5!JPS4lnnR5D$ z<$bVFZC&clEumiq0)jUR1*w$E53GB5BD@uvi&S_lD{XGrggA1|Tsjg)$N?j6Uif1_ zgAYdkxi&KK8QSWoYa(?_A17vrr@(YdO$?mt%aC@OX^d2K%F3E3?NmEk`y~-&#;C%Q zl3ds<_cXn-xO1HzGEqE=jc!|D+df0Rn;}$5MURx76-q#z6p1Iy42B$K2D)w_F#<|L zDNIB}sczp15D|;0O+l#P3UWajbsuaU=uAG7lKq;3EwN91Q>AG$VTLk29a1?pL$z6+ zF|iTle64njg&x(A9AlCla&({mB_4#lluAsa6-p1~hDyaHx)VnhO>i@0a1v5Kl2>D+ z?;#aqO36>=M#gJD410-Ni!XeOq-%J5xWBt!)#!Pus(_Y$ZLl2f2%G?4s_*T<=s(v+ zXH8nV@~FBp-874}soK80}GHf7_gY5O)b_cpzqW@YLO3{}!pm_(`Uov3UZ zs&`#Suh8AgM4*%|-wQ_LL|3{zp|=$KPh=M5snf$!QS1kk zAp?2qDQwY|14Ht3Xg=j~vtnnYF^$i5E)TCNJ)@n0ovqIF5I zmk@S$Sqp8FQ5`K{^o~d>Mag>07K>7ikXp+MqRZnQmXN@&220aOvXZ=zzTlUYkPZmo zza@)9H9ccYRQL321!aRAy%||?STDOpXg*%uiZev~0%oU-B4rgFt}`iDG0;{~VPq7P zLn_CL+bUrB-tGSJbwLhW@s1_def6EMU$b?OSAMvm8r{rM;%JmMkyNAxK5uM{t~zdl zIyEyT*?^b`8@IQVe35P$;kAfOTB%s2UZbBsgQ?W6>_xg4Fge7atu zvsJNHLmxC5I%3YACpRcW;JV=~W$!g{}9aBO~=))FTZb_+DR#C=_9LWdD zE9ITF>1fGgYQNNI;aCa*B!u`CXqss~M$5qw+)&%tAie3&@0}nx zCjTa;h2t!(-$)))UUvVQbF36?Poxy3xPi6@Qw6>pnO39aw38g2jS{~>cA<3_k6p+e zNQ}S24fdd^&pjqCy#-Ntc%=+_vAn#q!t!EvLhe%UoMu9ql=YBIY05I0c`#mB&%Wd)58U0Qu1 z=gMv;{s=W2V3IUIaBC;p?g!Qv#We5Z;o%QBJ>kYWI<}C)Nrj}ne2EkV0<#5pLlN;i zdI9Gc2A}foa*wDeMOQNAM#1+l!#Z_1n04E1@Rw48Bm}nQXq5`Wq8N4s(uHDP$Jm6- z0!ZH1M{oGBqO*z~1zK7=Z?{4FbV;S6+7!tpxXR)~g}0+MXlxmElEqOO-HRg& zoujig9P%A~dP!J!Y>4UDNvMca3Ei1u$4H2W9xwyhsDuQfX(1J|`~ z%f6D#eKFVKeB?9yXHfdZxgWFX;TkF5Gn=mtyQf>5XKW{SpWLWEtoB%$8E!6|Y@h56 z$<%cmi_$YJ{<3X8W3pOK!~b>HrGNR&LWRR2iJ&Kn^O^TGlkXm`jk`B~EQmHgUwkDD zbZz{gTo|d1SSMN$H3MoMRX@9K^)P6L_LmR<;QR!XZsse-N`&SQK>;8`ux*$8)iP)9 zZvKLI;OUh4?#(}ql_d5bWA%QsWw3wGqwDBtNkhA?+)yFCl!F$HPn_J=@x~`H>U&O4Q zKkDB5vskn-$HB5y%M{JNqjTJDCRjzl`mNV^zVXhwHqL4?({iHv{iqyyyJt2=_}4hR z*M3f}i67k58=mZF^-WOisLESALu0!fNsevEOx3OZ^09HfP4LQ?%|+Emu>D@#1y{)X z-E5Tl^Vpq05xZuu)rL9-_{meI(#<=6J`ugBnaiAgUVqv|5ntyoNq2v4|E|lat+69l zvvfhsv+u{Y_ej%MfAdBKqrCMa&bQlS6Lb}HKB%k(t8gi2KD>r6(LB-hBd6hUbrc^w zjr>}>uOI6R*H-_nZx1ch9;kmeFFDqWeB}LJlHuvG@dHjt?3j5j|Fg8`M~g)+=ft-k zdA-1T7Fc-xeEav&d-{#zozdqW%bz62+CL?QT3U}-{BF-1^V2%qIQ!x+J#p|fCf7}M z-q=9=VR4{-2bl`p*kC}+>*suui6eS3&0m5!OYdx|GCbt$vtx73xw&{NVWfK8^0@Xv zTL+ri{qU#8es{0!!4sR(-8jV?w)Ls2gX2fv2OGZ#jd#cl89(Gc;9E0yg#uS!V&MWH zGB5@6B^KtNC0w8H($QaDGG1PCTwZcsUP@kG@?KtEyS%(!_=h&&;m~zzAcDBP=}1=s zkYmXIAo!ub<*>rcW=v*;@1#py0O$72gzE?_fR|VfYxCL!mh`jR&@I6k6FX`Efr=3= zH&f2K5z+aH?FE_;);fBcv&DJVPlql!mM-GlNpAi~xJtg?sPaHST-5XM&UigCnr|tOGQ3x~a_%nXZ+$+7vZ*slre-;RYkU5PUh4N-N&1_axl7-y z&wCAvHrmEU?!?ER%-p(2pMD%Z$Njv`_1-btW0H`IFTt%7^};2=(r_1pTfGuxBG z{%f7TE5@{avKMc>*$4=I>bEB^#wIemNAhy=&;0Up>~maPSsqSlI@8nex7#B{LTMkEbp3hNB?8|%=uS> z4!4f)OFgMfJXcjIENifTk8jZN#BKCwIQB4e|A|=-_l;`udC`;%8f;3UT~RiH$%ZyQ z0jBRS1KOQse*26~LOLw{Tb-PH#%}n)9uSnnE+R%-o(+bk%P?G6?^K>Yk>KbYypdCs zH8(}V1>gb8v;l6zI9Pxfp2gxm0tdhg@L4spVJ71_d=|fVj%HV}7+nq=*9VA6udO^B z;s&pPnOJ@a;7!Z`a1T%+O7Zh?pcS>{#GK$4vg$I*=P!!;Cg-;+;)cDqfBzbxHFQ*s zu)3Yhmj76X_><9P(|wUkd)-f41@FRULU;C@>c?SU_H(krUjLCE_EmBd7dP0cjMBT@ z5#=_g_7ioij zvQ&KGn;)}ze+|W+W(#|YlID&X5BFsVEz8_^D8|UMyVA|L@gr+2?r`IJJ8rp5iCf}q zUFw%GOIzRubT(tpk4>&cU( zw&mS#&aUw`dzt6UaH*RjXLn&nur|H3-ngzU(;X-Haz(>w91 zhi7dXZo#9!R>wZ{Hq~r!s7H=9BYkU9R2pyZym3UcS}cb13p0%tpLG;%Rj!WRXKF5f z+RZP{wRrD*B4Bcn43#I3U;^3_N$%{U_ialT^(H^)aXnMc$%c*+EM_@t6R?!IJ>a+Y z++L>-cwVX_zS6T6!)UPwePs)#op_DR{mwku36c1?gY+J%g8_M3G|zSEKH}wf z%x>|5NoRj?M`D=bay)Qjm;jT4RYw|Od}Z%#Jdq&AQzN*|k-a{`x7 zNH+Zj?a!{O=Jr1$aM(`h0ONsbN914*TIRHY`x)Enn=Gdj>Z(&UWl`Rj0lV9dEl(aK zcch3)qh|HI@B1c9Qh!1WoMbBEX3`pm9DTPq2{<@vs(DH#OCTW&^PUQHb2VMO_1ZhW zgY3D_+NifI}dPe}k-URUSugT#~ASg15y$#Vp;NK1HQ#MJ&Y+Y68 zmhYS&vz9dU{CYsbrZL$|!SAt{e13fGeAC>_iE;eGk7ud-U`62Yxv%SCp1|_Ot-K6U z-|CmMOsG%oO6w&Xh8vo>D89p;fVHz%a|zPPXGRRaF6}G(bR@-`f8)2+5cBB?xWV}P zUhf`gjQH}3%Iq?3;7JHm`ICu{`qR&(vB#ABH@3o-q&_*tkTKD^ayVs01i)M{*z6~Df1ZGpbc^4VK^+Y&T^T9obp9|INVrmo> zbW?eAdFGxU$1lU18JY_B1$W7?$TzE+=ZyDOvP+r8FPBcdju?*h$(P)3KD^lq44u@^ z9zFBbr7w)X)RnYu*}|#ucBDG~5Z?J)_S3NUk;6h=UNfUi({c^!W&Uo$A7>RYzUQ)9 zqB-3cEjz=9BX1`SeUtTWPi3bkEzQcNlh&o=TqZv5ROX=F5l?oQ*${DSJP!jtbs6xCgA zD=L5@mNq-K_>F7CasznzIA8Jch~<1KYLU*7;JI`2t1smg)%hyEN1Dd1n6%1U+)QfQ z=O3Oy=xRoOUA$ej{CM-#JYV}yhmrSbx7x99*{V2?)8=GlJn*&HJf8PCEv1q%-S|zr zbgSO9$v2F5VcYj*Wqr9UaqCAv%k)IHE$nN1WeX+?SzO}voBeHhHglgx6O&u^7_rK% zDRv8Y%E=1H4zuVq0(~l4e^sXyW_Q4PXVw=d3u7+p0`K;Oao(QkWt!|&lGTH;VWn>> zQk-pnzZJN&9B{#hYCf@jKJhKNJzxjkKDX!5M^PGp@>u>F7=4;(`hkx{a&%hv`P+-3 zEkBQoUsb>SWwZ8i>kUhCU8)@@R@HY7HR((4Pxp^MmnFlYIbPdJZd|marr6=fe)D2< z=5F38O*Z+HXZ*1&i@p;dipcHG|CH7*d5nwyC|j9bAAg}V;4(BZ{{eTu-mXr~_kP9q z9-)KE4*OpW=L18(zlvWT{rQaEIQrApagKCT$QzVD+P%|8bz>zP)*YCXeMWls>-vSk z;dg;!w|zY3y(+0M&_7znFHuxqcweFY`?&wKWYGke+hIp^aXMZ=~eN50>XXz2d9L;t7&>q8l-!=Sg&S{G!cdxH3#FTGfQ zpaHo@=4?WA2+q%5rZ)+J{1q_?cEP0y{>kQVLq4XX{@=+ur_CHaS)YI}OFs*6NP&0x zfLTZv9uAPehS;gq)2|o-fBS`qg#LL<))${R_NRv>Bd_i5GwuE7RoU%k*RLy7URp#S zpy$1w6R=BVN^Rbs6adLf`N({zrFrS^G=xX!(hF!w#u=M>~GcJ8Gjw zJ@;tj$HSiTlvGPDIdoh|u-9bi$=CJSI`}~;7`H+cEVy*MI|R#aDFJ$*6W22(&^ z$NmWbEsT}EbrdfS5;wjV5%z`M^9oqJv1p5PKGkq9=lYs7LE5L(tSy=x=cybKj`t1?>=Z{Eg zbNk{KLT`5Kt+rJ&@sG9-4>?S|+Wyk)?Ny$(&loNpa1-JS1X8>~*A1xalMqTG*RAyy z)xs?@&xS9)iaeq~&G1zmcl-ia=mK2NOGAS3DZ$RSH$((PG)nnr?o4T=IZHF&a}RSX z{C?a!etTGpuPs*q3;}@mPhkMSlZf8H&j-F@uQvf@9;TdH=io(IiW^ z4~7eV{&?c!nOu6k_aWW53~TJASS9|lc*TM^G(fC;tUCOhVoD_$pCG)s-Ox|?q2Z`* z6V$lfkfmHUMR0x-YP%fSx7>~!_`G~<{4vaxn@=G+sVBZ-e-qUm^HoN@eOrIw!`Sk3 zqVIG78|#`+b#Ac5_Fm@aj#7)FI3Cg0<0qc!1GlxFbnKJ{w8ft$L=TfpZkmVQnQ6Yr zIsdhGe$t-F@a)#!*ny{+o#=(d7(I^N(9=&^tITh+-{mdI-kNQRm)yM!Sh9G1?~Cs4 zl#TRz2KK!_nIEoscb>p3266C*RQ5?9$ZlWwm|)&0`DGA6OxVf1fVb|`2N9RQQn7u!eZYs z^hqlB4SLh}H{(jD!9Iz0IaNP<1?2myq(JPar7a`HJ-IW*7Y zu*5Xnz4Y>PvNhMKzpm`hbt1VRGXopGL92InwecTZlDRw178obo$Q%t f = std::bind(&Recorder::finish_writing_video, this); @@ -288,7 +317,8 @@ void Recorder::write_mp4() std::string pixel_format = get_configuration()["recording"]["mp4-pixel-format"].get(); fs::path images_match = current_video_directory / "%05d.png"; - mp4_command << "ffmpeg -f image2 -framerate " << (1000 / get_frame_length()) << + mp4_command << "ffmpeg -f s16le -ac 2 -ar 22050 -i " << current_audio_path.string() << + " -f image2 -framerate " << (1000 / get_frame_length()) << " -i " << images_match.string() << " -s " << size.x << "x" << size.y << " -c:v libx264 -crf 17 -pix_fmt " << pixel_format << " " << current_video_directory.string() << ".mp4"; @@ -296,6 +326,11 @@ void Recorder::write_mp4() std::system(mp4_command.str().c_str()); } +void Recorder::write_audio(Uint8* stream, int len) +{ + audio_file.write(reinterpret_cast(stream), len); +} + void Recorder::update() { if (is_recording and get_memory_size() > @@ -306,3 +341,25 @@ void Recorder::update() animation.set_frame_length(get_frame_length()); animation.update(); } + +void process_audio(void* user_data, Uint8* stream, int len) +{ + Recorder* recorder = static_cast(user_data); + int max_length = recorder->get_configuration()["recording"]["max-stash-length"]; + float length = recorder->get_frame_length() * recorder->current_stash.pixel_buffers.size(); + if (length > max_length) + { + delete[] recorder->current_stash.audio_buffers.front(); + recorder->current_stash.audio_buffers.erase(recorder->current_stash.audio_buffers.begin()); + recorder->current_stash.audio_buffer_lengths.erase( + recorder->current_stash.audio_buffer_lengths.begin()); + } + Uint8* stream_copy = new Uint8[len]; + std::memcpy(stream_copy, stream, len); + recorder->current_stash.audio_buffers.push_back(stream_copy); + recorder->current_stash.audio_buffer_lengths.push_back(len); + if (recorder->is_recording) + { + recorder->write_audio(stream_copy, len); + } +} diff --git a/src/Recorder.hpp b/src/Recorder.hpp index 6310093..f2e23d8 100644 --- a/src/Recorder.hpp +++ b/src/Recorder.hpp @@ -23,6 +23,8 @@ struct Stash { std::vector pixel_buffers; + std::vector audio_buffers; + std::vector audio_buffer_lengths; int frame_offset; Stash(int frame_offset = 0) : frame_offset(frame_offset) {} @@ -35,9 +37,10 @@ struct Recorder : Node Stash most_recent_stash; std::vector in_game_stashes; std::vector video_stashes; - fs::path current_video_directory; + fs::path current_video_directory, current_audio_path; Animation animation = Animation(&Recorder::add_frame, this); bool is_recording = false, writing_recording = false, writing_most_recent = false; + std::ofstream audio_file; Recorder(Node*); float get_frame_length(); @@ -46,16 +49,21 @@ struct Recorder : Node void grab_stash(); void write_most_recent_frames(); void start_recording(); + void open_audio_file(); void add_frame(); int get_memory_size(); + void make_directory(); void write_stash_frames(bool, int); void keep_stash(); void end_recording(); void finish_writing_video(); void write_mp4(); + void write_audio(Uint8*, int); void update(); std::string get_class_name() { return "Recorder"; } }; +void process_audio(void*, Uint8*, int); + #endif