From c5c16ad74b5c94600697af1751eb372edc81b841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=98=8C?= <392871505@qq.com> Date: Sun, 17 May 2026 22:33:19 +0800 Subject: [PATCH] style(acoustic): Unify size_t to std::size_t, fix hardcoded SPL, add threshold CLI - Replace all bare 'size_t' with 'std::size_t' in core/*.cpp, io/*.cpp, headers - Fix distance_estimator: 'threat' class now uses config.ref_spl_gunshot instead of hardcoded 150.0f - Add --threshold CLI arg to demo_offline (default 0.5) - Rewrite mobile_phone_source.cpp to match PIMPL header API - All tests pass: test_core_lib 6/6, demo_offline 20/20, extract_mel_cpp, test_classifier_cpp --- .../src/acoustic/build/demo_offline.exe | Bin 210373 -> 238987 bytes .../src/acoustic/build/extract_mel_cpp.exe | Bin 115387 -> 115387 bytes .../acoustic/build/test_classifier_cpp.exe | Bin 145600 -> 145600 bytes .../src/acoustic/build/test_core_lib.exe | Bin 308080 -> 308080 bytes .../acoustic_analyzer/io/wav_file_source.h | 6 +- .../acoustic/src/core/distance_estimator.cpp | 4 +- .../acoustic/src/core/feature_extractor.cpp | 10 +- .../src/acoustic/src/core/fft_utils.cpp | 10 +- .../acoustic/src/core/gcc_phat_localizer.cpp | 16 +- .../acoustic/src/io/mobile_phone_source.cpp | 188 +++++++++++------- .../src/acoustic/src/io/wav_file_source.cpp | 16 +- .../src/acoustic/tests/demo_offline.cpp | 6 +- 12 files changed, 153 insertions(+), 103 deletions(-) diff --git a/src/drone-software/src/acoustic/build/demo_offline.exe b/src/drone-software/src/acoustic/build/demo_offline.exe index 312871cbd2cbaf05ebb59475a200f8794e1adbf4..1a4091aff989888370ac861609ad310804d35577 100644 GIT binary patch delta 74227 zcmbrn4O~>k_dmY(!YZI}*9R0IK|}@d0iVT3P_|YBBNOu>4K+>kA+tr%gf*8fx9ci8 z8k$;GT2@vjehWpHZ~iz}7_g7z!|eiNXr>_w@4|2;CIxybTIxC~*PzXXG!u*afDr&*^N46}QoU^~it zBg|&MO5wdKkfPdq{-)MKQHzrYG7XIZx0el*Tld`298s#*0>Q_3RZZwI{i&x2BA0p= zA+PHY%C^dlLwLu*07E3Q&#({V@W6DW@XzoEJ1@5mi6B(q0MDvs4gA6bSLmsmtOruL zNHqn_EjHdSJc#;@e})j5+5FlE73xWo%-%q5oW}JbGGV*=8a3-Ev{@VPN4`Oui)KAR`#Jtc5Z9WbqD2k;i0EkQGD{vG-I@+KaAF21N4v=s0B|01wP$nrNCY6S zgbR!(sKnSCn23+|tXqbR_Na0e46!)P1(p)?9^?Z{+8&FF^m8T~iW^a}YOtWYZIQh7 z3Qr~$5aZ@%_7gJZKdRJ^F_-uN6-tyl*4Hj=Z_Y9Wdvw&g9agNNL1EM{8l&7 z^c8j@@QVD?pR6!wl>FJBtWl#b@}fUk-$v8q@IP5zqX}}_O?J7_un|tlP!l>Zk_bOc z9bIT~1@GsXBaxY`21ikuE3^Q47Ux-u)A&&!@|`JFi8ZH?|ACV|*|>T0rIH~9wVNPk zH_Cxz<}tRpam)x5cs`w_gy#^e40U?a0VUL6AYem}feOsM;BHjcam=b%>_;M|SZX>= z?jSS&;0Z&^9+V6#mJT#nTPYtuFcO4lFFg;QW0KjA#7%ZPc_KL~T6>RTDq;tM&|b33 z`1)XpZ4OSDHW3&s&Qsb|$gjnj6g6-ZRjyW+^utriXsLYA!r~kmuLZ79L1M-bDyW;QgrkS!q6V6K6>^>=pzoO{aJ_?AbhHp{I!*+J9r zW}}d0QCCN;03DndZ2${tqRLmVu`Nwf`HA$M4 z|6S`we$6Lk-pL(HCUHmUgaRLT!ZO)ZrMu!@;>$a$om;|QRN|DkYV&Sr+m^7iN{q6| zn@0?qxr8+_#VCWkdBmaaOV}t=cjfltIxM=pm^lFVX>Fcc+rO9{G7W3C6nXWT^cXuI zzG~3<3?Dt0wNpq~9N%Ufv8eY)SX}qUS>lVV!4?$}SE{7#CD?_0v~OrT^S4KYN%EPC z>_CUN*nR=9yNnH2v6AQo za>FOsfS7xw7nm(3QF@dW#oW^(cs|jX6tyrprrHvp6g5F{G#DVUc3pcn$$FNigxliG z;lr%`!qU5j`n}y>Vwqik@+;{lv1zekw)||#kXX==D0GDy=2DfDGy$8!N0)UG{lK(*1L+SiX$wX@oH$h4?_7BxY$sQdh?sFYA-^uzSd#`Nx> zd_0~{@4pB;&Ct$Aq9;#v|BR#(z5?*by{rYyBRmbfb6jdCvG(0!rMYZ$x6yL-S@uG= zuF^GD)U8m^l?ldc)MNXR=);)wR~3`7yiS^sde&-LU$XbR_mSI3?5FPc$YB!e z(IZN}bc2oSaXzv)b^Nfql^%}J!}fYOq_@Pz^&BDpI)`oQ`KNqiHrp7tzwJGpej3^(fPNN6I}V*0|4AdFW{-_3bLZH=T9w`>ZlCgYc7i2mCeD zSaIK8a(9XSj^N#CEV|!Aax;lN({H-Gu8jTIZ-HDJyVTSX0QkP50w1a z^Zg^GRQ68)9`|&W4DJrGqTkaHx(C)xTtzW)wTtQLz&1Fkp-vDX}L9 zERl0gvP%Oj@}QHf@4zFn^_d*qQODTmq3P0T_V&=x@{&?^edr7FcO`7?uq-*f zgoO+*rAEt#-z&Ekwf{QGYkzc<Su9&qcvi^Qy!PLvu!DpWuwGyrdZ^g$5_&sF0w4K`D5O< zHK&pI)E#|C7^kO)-w{?f6YvH-zn30CAN%Zq<#MNeY}D9P`HOtEW$bF%oX=t&OqH+hWlul2T+Z0b zZajFu9JQB?9+xMp@3SAqCCTRZSxg#0_OPeZ%%+FOku1jwS$-@LOiAlVy!kz?d&gmk zME(tJQUXn@hC&BzZ76imw@S`@z?sK)@7Pp_3;GAR{(##!zPsNq2@*RxzMI@wVpoye zj%3G&x>IuOL*4zxBDwORB)?xl#Ic7u_*D;=*e?%tkQ+(NG@-lS8%QQhXiv%X3Gsey z0JU|(0(ts7tntJLWaS<9$iz%}<8F3#;{9^cZq{|uJ$@eymDp30EPe|RemtqC-#rMc zCdK)MBkVXiz0D&-sDDM6TiPFkNcT1pY}h?SVlPcjlp9Ly`^h5%%LhZrO$Gp~nAys2 z9dbuKJYV{YefaQ1>1uwHDKjPMQvQ;uBPHo3`{B9)L>K(;e<#C0qmkEFjM z{mi6k>3&DCTs%7MHF@R^7C3!kV9*X)w;ztOuxS%pGspB1^3K=TvFWMugRikRGnUI= zzRG&d?8!=Jgv*XsnR`aIYg|+cPIl`i^~%=Xuujae9vAPb+`!`h~cYC5cEm)?0a}oCX)@O3l8gQs{W>DV6BzL?yaNdB`{rDq3r{ zF8|LbERtV*yu|K#va8?0fe_Cp2l~B&@ZBe$_wz?Mcu^O>n~;{7i@N(=Lb!3!r~Q5; zW~3R$xcuM2P#8RKy3b)#Mm_sk5C7Cdw;mcKtaeWg?fFD!z`25VA*czxbU-rX=3-YA zomj9($YppmFHc2K6MFnW{;j9>NX-us*9Lpdd1|I{4J*uOC%wteXS^v-yv>}8SIdvB zWi6LXkltVmmwYS-{goe=*-mQx*`I>rZ}YIk?M;98C-~iptymiAx3`OwzjNshDZCko zx~e=M`0>06#+ptNoBece+jfb^s2aNh#%QaQ1E9%mQ53XV(T4P8{}o?L zAFz;TQvKS;V6A?pv)|5Wi9P?!_|EenWXZ05Q5C?1eN?j38kK6X7lx57T}Ied<0ybO zSUI(a)`gl*zN@^9^6iBQRAoC<6so+_MPln$M*8hS_~FXIe$ONPedWJQrI%6cGWI!2 zP~989%}(1tXy0}vl)UrPrP8)h5f7;ub>^0Z@ zt-2Ce$;fEb17{myaSIEDZfldt8m;LmUs%G1thv|kGVHWx*Nl+Ix!LhGJ^h|W^46Np zJtkq}n5@DJkc`2NyP}vnCBV=@I4>$X#Wha8l@fD2*?9^X{dzW+@>AF5N%F{_nLBq( z^I+`xlGXd8M>(sKotKiG-)kN#yKmjs(xIS4~Z_vzT^!F~wSs!z>s6 z)1`{Unr_(VcRU0(%7$;{^%tPnTH9(mHGPqkt9Q=Tbn3c^(lwo0>tT={-pmvEm-O%( zJv^?52lVhQJ$z9QpVz}>dKjsPO)0dYp(`&4#257Nv>q1g;a)v_RS(ze;YvMRq=(b> zaI7AV(8Jz(7^#O%^-xA=qn=*bs1u-vr}eN{5BKWft9rOz4_E5pB0Ze0hhz0{gdX`Bs)zDM$;MfIWrI$D9-h|2Vm;iehp+14dOcjJhl})Zx*m?z!x4JeTMr}ku&Ex( z8*HNCD@-Rq53y(Dgca-IUOjwO57+DANK7v|d3&hG+d#ygujwmXQK;yi6p z{maO=cTqLpa+<3>&4K1sK>V^Pyo0)^rUs_Pk+@pdt7>eMC6UWkDKQ3TvF@AWo6Ir^ zZ@Ns*9ODEN)}qZl{9uK#U7LIPjYN2EbJ+uNwD3>^DNx`eyom%P#(NWekeK65bVee_ zn`ni^%ics|BucST{qO*yzFw}HBStyPEzV-?6w0->c;xDAO}98xOeJPGqM^94&VakYTbHqfZS7ga z)&SW`(KZb&Vacj-EX7-}>086)j?0*RYfO_B0o3JUt&~nW)Zp)z0-&YI)m(yWy~^So z5rNDDl-Y{?wY80$L(vv2Zd-^vm7?8E$~x{22DgU;v;$?fVVkyv_`Qxb`OR&U(paxyW9~%&nMcS9QYHC#D z^(B(QUMM+@zb;_~FGb45O9+8N2Qf;{3eo=;d0s%0N-ZprdyvQd7BqAl2zms>aa zYYjE#k#goO65W;ugjLxB+V9nm> z(e^O1z~zPosATXweISf55E||Mscgy{-E0q19THjNGtctjRYMn2mTIoHI8(t>3XM}J z%Vq5B1J2>V9BaK983zGXIUHII;^l4}WKm`J0&hz#MN1{-Y6CadkRb26=|F4!*kd{6#oqos&O`eNJ#i3aT$C0>O8{hpu1yu7Bs*; z)JL3>5f3(tQewGkOyUXjBaHZOz$pqbgZ;59vhk7m-o8XSSk#-7hCGW5KsG}^AM};I znM3rI7-u4fc<#y4G)z8dC1lX)#yqq#ZazEkX4?U?9wxa#yHHAKuG)}s)>2|@3qblS zF$U=|H1I9_p<>9Soc!Ro9+q0gPDW*Wb--esL=TBmuw};D%ZnJK? zN6VdWv&`LN<v|H5?zF{ECpLg@Ia=#gzi_z`?d{e6 z*8B0WHMdv$S%=_Z3nD`>#9l31JLxTW`hvrqaLQ?L7OOV%HRB6twy2_IU>Qcl6NW+x zp#ee93Y(`Pj}+Q?TLBRKMqpqts;mGQtS*{3M-rwS_Nq^G1|0&~Dr~ZYg`korOtjV% zeQ}8rPD-GbY06<6DP2@h4w+5%s&L<;BiKTn=Nk(Q7hz0jZrNmUHOKJ`AIEBoRED91 z7?Et@_|{7NLKJ5U6rtltv&sFg7uuET4^CH?P<1i+2HVV4iy)K0or+bEnrIwfynLdF z29Pc)(pC-uw9^c)y_W=gAx^U!d&$56@%f{HRuc|8X&OyT<1K(0MVfsmk88jo7?aT4 zWdVU{Cg*4yT1_*dSN1~xlBAVbJ@k57YG8jxaMh*oUk-BX{EUDApW>s@oQMK`Jhroj+rWUyv3|$`%W-u`gv*eOL^-@DGaT$WM^+Gs0Pc3BC}@C z(hSx{`lxAQ%A-roU8#Hyc{`Dm8-S+oL-lyGW=)~SGhheny$6FTDZvd1n*XPJQXk4l znV8Ew?RiI*wnT8f+-Vcs0hDEUoq2XUXqu-u+iZpaR^apIe*Y2|>!DpRCAGs?%& zj36<%M1*QCziTkT2UN6Q2v6iQ)p?4~;o=SuxNEBUTA;a7<>Yd_C%Gq>Xo0BkL9w>7 zVEy5RO>dGD*<20s(^2YqfDh<>ND|?m5xj?~0h}pWeR(P&Krj>u;H2Tz9=ji7%x_!W z%?8W`Kt|A#kW#ItRUiQuL@CCH_3z@H@`yT|+K&eiKQ2Nu zrTV6CT&ARKnwciN8B)1qv)qR~#js8wVmtb~+MxfCU8%C>ui^A$?~-8y0H%FJw8*NhM}J zl}a4@fP?;29&_3pdw7DLPR9-&r>E1Q;Yq&GD@qe{DJ}^WA`RrcJyJ9Yhzm;0Bs=BG z2L|QiLVI<0Yb+kNW%lY=ipAO%+N&e16Y;Rk0#AB63NxqLwLn-YOU8Rf*h+Y#ARf4Z z2xAKBy$InZ>n{MParA+o1lP9f9@rlHwz?JF*uK_~?$AjZ5~n!$8NH6&OXUQs(O#XI z@qjJal~S0jI*5H1bt5qoqfxH9I1^xV5f7s}@F@X31oy7uc)uNIgtzmx1iJH3Qo=b( z9jZr|j~=UAkLJK~o?{cZs9iO|DOugY3%^b0(e;woIpad5MEt;gsevr=yU^ z>FIRP_ zkSTTNz+j}E9HspbA?}$SEF$sBnx`=UDzE5t97GvvTLjnRc@4$U3<{vcQAPwAY#?+#RTWXVTz31<}z z5V(N$;XZcEMbgvJ&gaDc(BC-g8PVT3Wlajv#JLc!tmX1U>=MH#CYi)Xt9I& zddcBtT6F<4D~^vi!-;M~MvVOsS7;d#_CtGkPRqa160KYNCKXNE5=S|K;*Zv!|03G4 z)@Fi)?irm$MPLw9w7#zL$(P{#t3!)YGqiBvaI`X6R;E$m$++v+ymGdoakEqf2AG}b(jcD%O6&m1E3 z;aE$u8<+60p*Ze@bJR|rV?V^%YHfaf8x5XE2Sn813HHE9@hulZj4#3atRt^o$USu z**NAHf~Ad=JgIiu;^B0qS3im5qoaux2*)9H;O^&O8I9`>ASBHX7~S8r;AnsQxfX2% z2e*y|h(9%|FPjMgd}qp68@@R$w?S_WiB=ph5Dpck6!?}QeKXlQny)|ZCjkUI`L0#4 z503JXO@b*_h8R8|Dt|g17054f?8cM+e6%#SSNPd&@Dp?=KfwU3&0%m8Wb`N?`z)3( z%T8X)(?--L{2oQ+C1iW?Li-_7@`enELLow-^F{nX6J*4fDfbsU9Y+vV&CB69%WTB0 z3Y^LpdRkd*Ft<)!vR6o!z+!KH@fBr)Fgxsrs9s?9c$Fh?rCztF#xy!9n{gUvOO4C$ zFqd9YCYEA_ybJd~qn=RYwQ6i}XaLq|LO*4#ijE7>RFt*ZJVAnN$QYF@M&>R%p%mM( zN^;G_sV?F#V$mf@Q4z!`lCB|FYHCQhdIOnz8|*s!A&ya5vkf4Wu;HZwW$pWb7o$~Y z*Xc42{Sn!1;c9>Z25fKqUQ;8L+pGI2FVX(k$u&ASkb+gxn0N`W8wtDMjX!uZQFQY^ zQE$7GeAQJZI>IfVtjoLujC!B@c?QLK4-(h6QNoM*~S2c-6(?G#9FA7rk;tZ-|(+ zSaX7t50U*4ALQ)LKv1Z+2u=7Jwtd+4!$HHV5)65{E|xgB1C@phD9xHw#xZe~;ah^S zbj5QiR@T}>F#h#GccHFtg@li#n`-VhSU|7whd`9@eK8_v|6;7UTYWNP>XW&tJ82o} zpQZ|l1Cg40Eo$o>Q*6$aoZ7koARN9r%sUOf(5&A2Znm)2pMxl@BTgvoTh+8~{$=4l})5o*j_$o(G=VH1jeIvvz|l|R8u`=RYf8mvvl z*bv*y-ITR-+bKy+S*~wK)QtxL1eR?=pr$0zIR!0N3oy9odmK0thZ|qWnbV2qq>CK# zaEr-Me{Yf)8GUmf&xI&R_ViSsQE9J+3u z5)MbG>ejGlMHw=2l46UJIA%|vYL1HG$W)%;bX=n<<^=FP)*LP5Oihb|+e(*e(l`2c z&fF~vb{SGng!5?)RbZ~287jvvL;Fc${2rO}&z%zowq@{bwtd8YqQjt!D zD;chJ8{R;qcocL5Hz&l3V zyjOB?I~Dz<@h~WB+aclG7Z3ne$Uf%gPTq$75aG7L=TJ^1S5aJAqJ8#2wkt^I{>;I1;eM z|0nKDE_DA2lZAJz;QDtF;&_AO ziI$YL+bDKOLm{$rk*LF(XON_k@%jCCc0q;{L#5UZS$jwgxUwb%z!;h))PMIXJiLSE zz+EIk^lZH$>v*gm-o9Ku9ipsi-K@*ev3Z=y^iq*p3?1zWZq; z`ND`HxqDz1fOuLD-4jIfAj$^t=)vZMEckZ>TXTlgX@V>|2sLu}@JyzrN%EUs5SY-z z>*aKI!*w1nRnrR9vCSbXb>t8=%D%^G4TrKq)oReHSc*%`HqIIMF(b8r5zfg$H@vMB zpcNV<>e(BBs5_8{dcZwyQL;gfnYN)R^e~2CF3nPU7A?xEJ;dT#f#i>Op@q;FNOFAv z{zo9{>FFKp&P0YSLU^!ghzXJwXIMA-65kG_P-Aa>O<@z>JUyB?aslh^fsybLw1&fo zjUZ823&*Kx4*xr;FZvVeiwO1Ao`~Ai9p%|?L^f~Xiqfr6_@A(2KXygw>RMf|^kLc! zaY*|i(mJwrtR7L;K7+JK;Ghi=KL4#PJoC{euY%@`-@ukcNQ-0AWjeMTxUuJacDA@4}z0F!CG;y(G>t_pR>?w1j5a!k3_~Wh)KLT zA-g|9H7x-%Nm#rz8$=9Zb*v-Af=oPEgIv0Nat|RYgUO4-;B z6zl&reYILhV*Ne#f1cL7FuR$Wb`3aq{-dImg+egR0easRx-2K8^&h0Z;yezX>dp<0 zZjmsf3W3fRKry~X8FaMieurqjX#|AfOp!q^XU{JH5mg$$3T=pERMcj z)j*#>T(}0hXtQ&38(pF~M1P=%)4#qAj|Y%kJd3zkud(cOB3A0#8>cxFUbVsIOvUjg z>e{)R7EAh8Bz&{@)h{R^bO7b*lh_oz^b5%U6@|~&S|w)2y`AjP#i%q(c?eFqo<)lz zytR-r8y1hi652@2C@iCSqAhcoDC`7SV;FDpVKZqD-rQocEqrx6v%Hgx?!RD+(8qi6 zp$jLs`tZ2|-#!kd+>Uz|b{yjA1i4JaxfQlR#8WAMI^yn~SLqPJdxOB+%%u8rSl@kF zN7`-r29u1?I@9`QxDcK@w@cK_NT|qq(>?7Xwm-BH<1SrJZh5O(a!-gjC$~_<;|R|_ zisSwbr+pVM5QnRD&V3QKxr+g(z7SA_9D>mgVzvEHYvQaMjVF*u;MxWpy71>l;-Rd~ zC3(QzFI)k6SG5P@CgAzCrj1nOy_F;K2b-%Ged}!x2C!}_cqPDwFCfgX_Q&W~mFoGISR8IlB3;5#wLh1aFdh+#ewn7DOL(2s!}@xLqi{E`yo2>hn)@`SB^eW3g6uD z4kqjxR0=>PY6R|Zx{H(o??VD$#dwv{Pz@lvlpqkd^=(OGUy1K+Yy!5)xX0)Ht9u=q zE-0dkeoHQlmWARh%Aw6#HI*QwbTvW~hvXafjqrJUA%qj68t#ZXSDI|tsS}P0j!VSL zIUW%w!mWfiJH`H&*z6e*O7v3SzPo?MYdnh6^o+(jWc>@Miu8{m=c zq$_{rlm-6>&Ymd`ceM4orEpf&txNa%WHqgH7TsGs!G};o++sItBsdx_f0ZdK7s4-s zR2>$@6kBE#i=7Pa{mek2ptdfFwtuG4+m-(pauzXh>uC+d1?^Vryyv$YGw60BZZ!qa z3IzY-?=U*NqbE3B|9T@`8KfZ%0~@?8X3Wu^M+<(z&Fif&cZdf6{#yTIA`z%XSK#DG?Z>Xxxg6!>zc1T5sMoQM?MR4z!d2 z2s6Zdf&%13&;=Ok0qlDZ?)aU+u%58YAQ>UKq4Tylt44XaYhbpKfN5L+^*clQ=Wt5Q zw1yJG3RJ;yi$x7hFGI#AQtaha(jqOFpP+X{^d<*^>K*)E~-;8gA;?R8K|%d92r=gfw`MiWyr`x#|f1u+SiwV z?0ClG)M+2wDvQnA=_7Y_`tK6Z}N0i&6|coQ#4$RfjGnOzo==O>Ym%157IRq0=~Poi~sU= z|E|_{*|W+FR=?|0HlYQ{ycLZ{VDdqHO!ll3h79sK!TruJGGam@bB_TZvZDQ$!95J# z2z%BU7>*g}Cdc#;;G@Z=z|C>oA@{QeyKnhZSpwD{PeTeb0(0FO@@Qe-Pk6Mw3h2|- zK&^M8TK7)4vjOZw>qnM}pUu{d{0KR-{D2#$&+R$lChkd;MjMLbe#CtC9Ip+>OaVSr zMdph6AXw`(=O8I87EJhqkT2vN(Jdv?0fo}3tRwcUBZiEtSoff_g1m%c{te_hira3u z77=<{0w9hZ+SDxtF)m@q@19m$pqwD3+ zN9CSzpduoJY@O}2dO|U8SJQUW>4V-Xrvb(MIv`h?{b2hErAadi$CFss4uUlooMnOL z-8PIDEu!TXT&49bqVs-#F6cxWF+QJDa&cS@R+aFn}?TCSC(ZOp*3E&X{0AJ&uYr z^#RQHpoI{iI}B3rLMl_SCoBA$tFS=P1t?(ZL7oc@*{uP_i9i$c+JpZ9fGXGpDF+7L zC2IXT(r6MB*#rLrWUL^o2S|)1$*xP~<6`ly222c}^uFHlp3}AXt=Tj5BP8Ch@i?Is z4ie23h4#Ih2z|EuS?S#oTNm=Xt;73aH2;Hft&HY-6Stjm__WMK4D-I=HPG#D0BTFj zrCddFwc(Fu6&GIqp=|2ApvFJeyj9FubVylU%H_|iXZ)DQY9`>wVhKy+Bd9P)IUr{*10w>cvP;8(y)e}gebreV>Zr3WK?IqmVfJ{E` zVSmty7LEJW2;%Tb!KXWdXnu*fU^?}!8_2KAzgCT*=*HIqr4mp>0D&MOAw-`wP?sBG z9fln@tbN12v@Q9TcX2_o)!W+qH%aohr|gpXP#4sZmCwOu-UqrAzLi>6a?&~L_klLO z2#Va#ipyMnHoPDNzT#ms)29}Pg4Y>CRP!!zZ@(8XZKsRSNK4=-Zj|q%arJ~1P!LPb z_IQd*KOAXMr#9X+1kgkmN)i{;5I^smZm3oW1$EPcVhW%b+qkGvAykiHk zrJbN5_su99QmFBFuSV&$uvn*<>c5Cn1te9p&cZ0?tDwfQQtvgzbrCJ=X>|Lpx1}n` z4$u!+%+)sU>oDR5oX(0c*v>#fmOp=4h)4_*Z){+9=@~+0l&5h$PD`BcotQ=`mCoa0 zG5!1694}s5SVWfss&N0fl0#R~`=-|Juz9NdJ)QZI>>7c_K?KKcK|H03KKkiH@C{<( z-6VRwrgmYVJ+?`Ip$8&?HwNhq2@|Xka0a)s>GO)-*PO)rcXc+T`f^IGn#6ACE)L?@ z;2L3qjxk@00L8+8K<@xOMMfW9Ktor4pcu~!6M66qTU_`L!TSwgB#`(!60o89%X7K) zU!TKxC*d`qf&erVi?0Vw`@Q5h`gJLhNw<`V|03Pr*QqwPqQKMV^z zFnD5zMlnE@B7_%$&R))-b9DZ51{eNe0pPtNl!0n8AuBw1SLqhi%4t$=-rWuQDhb1# zUgSbKncBA^7ITYUFQgm))l`W#HrNLOen=+0ty`O%pg6wLA;|yWM<5Z(vxoJjWH((3 zfN{UNm~_%D+VF9Eo12h|V+=~ES>?G4=m97nY(AIuBpTqafj!k0mUKf~3l%SFsr=xs zDp9->*beubIaItkViC3!XE3@pgF6N2@Kz4J_3*bG(>aB!mx3cl(da*NBw{hm3hFp9 zigjcxPyzNL2KPm3pEpL6_a8^@F(`c>Ny&&o zDU*hT+7U{s3VGOFaV4ecN~#JbZRt}q9JKEuJ*xR;g2u}(dir4hL6ZiXQrds<_aaMG zlRnYU)V>=@Zw+>!K9+I?$Y&5?CRLL`FLsg_DuUlnMl0Z_!4m+UY5tzGxdqr;fPr3@ zi};{!0^V_+)=i3`$yNo2B`i4DpX52Ldd}p;F1Z@-N6Q&Q^$#In=rngCN~v>qQEJGTa0jK$>*D?y-?ghtDNvrF*$7?S zB^-ym#@>L24QKE~@NTy*F-CZELiiOSboV$%q8fuxLIs<8(5EvR?VclORk-CK`R zAG3z?+Vxo!!CCZ?j-<<-NC?N6x;XG*Q*@*L3I?wJ&HL82|72C5!kzD1(`tdtlI6YY^*jlUG2p*L(XG+_Qs z-0vd?i1_K3*!78*17Y{+R*1c@i={~OgBbE=VHk!^-pm_pP7Qk3bw7MogH$ZmnxPSp zfhDljjJ*kv+X%)kh|+{Cy5I*G*!9L1$nkWbIwWlv>R=cEKH|NfYZ#1vViyU6Awa~g zIa3?&r+#P?g~F!Y1Me3B^7n+{#HQ61T&Vk<6h08>gTeYFo$J7S2*9V!vf-@J;g+O<)Syd$7TX$6?4&-YY`}IZRPjj%Yc?D8dV;>oaJ*v~swT z=z|~TTZ7FPmmh#!Xjrvh)b%RbZ5)sM$EaoE2VBlYnhW#-RT+TG4Bl~gLV(Nuiu_eNq8mFbHjxo39RvvwG)OOaiG#;OpOBdow_CwJQ-?b~1o8Qq~vC{9$I zg%*ic#xg3}Y+E)|zN^$xjq>Z+OBptP@qdq~w zJ{;Tft7dqGJ&}&^xMuY3I$Xx|4Va}uBZ$xMlP+m1#vF7*-*~?PGXXpvIoiSC2`U8017-a?Z$_DO#5(}Yri8o-}N@c2XV?7Z411P#> zS*;(z2%J6PdqbaW!g~-8o^z=sn$HWGD?oFFkLK5fG+h11I0=I) zSs?&`g*s4$$~beFCK_9JomZ$|28Ethjrotx0_Wq@C=uZ#omwAK|3F0-6jasg#5~Rz zWP)SvILJaSK)~xd)=hft`0*`xIYIDAj5e^Z!a@NdhAW>gnq3oxjWNUFIyYBKr)J{Y zE!PH{Z`m$`D3F;$E&5cV&fr#J3YY0qr^0LDv;aDvR12HZr-RFvU*PR~=cH))Z_iIl zy?cM_lLZmraxC`v^a}nt#Q6;MZu>8gBCTz)QOY@ei(fm3p?T2_`lN%{#?7ILRLb}G z75E4MpLTp=;7c_)q2)V#)aE;UT6)kOZai1$##qXV{(Ny`%6 zYi{G3l8jfOGc`=)7|bO4DntOLl$&ow_z-d>R6!HHt}?6;^O=UutIe<_tq-Hmc}Sps zVF3GYeOF?`${Am5#pl?_FM=meKh>}RqEq8(#XV>I(;@f@y}9Bk*>f=RIrPDTbGsErKzmM`<8&Y%)J`Lw0&IK0n}l# zam^Tpkf<#~7zW`2431iKDI++N=OXRjc<<~k*~FKWNk+=}w^M9{1<+Wyxb*A72amwt zt~sTE76ZkXIj^YRxy0zJM*%hCodQ@9%60Lqvm)5|fqtzt!i=$C&mB{S;}lv*_5j5m zGGL&UkSs^iH-EtGJzP9VVR#Mg-@SX}d>Qt3u$1S|%A>3~3R|E-C+T&y`?;+;;&P?cDSgr>H+ zXN&28T&`d=bd6q$0~^akv<7b)oI@1vd%+P%KTt#;(kcTvCIJNh*BSn480*t;6P}^9 zt23IyjN)6ZSbV@lA6HVe7XTVawu=UbbD9l}_|$J1-X-B5$UzYSfFyrZ1{}F18}c9T z!Bu#g>?p1hinWSQ-dmntXdCLFNP8P^exhyh*%X1Ps#dq?;8@DAU&dRk*3M*k=l%vlY)s4t26V6t)if*&TgziTne?O;6Jwa#*B|2Pt%%Cy)@$ z7_kX(u5(8N40pW6kru|U3z*1P9|i=N=4oN#wt{ID*G_Oi;R6x43T8Idx#Z;YyC&%C zIc=Dd@bx9^i|qK2=8Q7SoYV1Zei(=!&WLcHI(1{Svor>49Gr4hU?7gS$RB}QTn$gn ztc3N9jgU6jTuIA1O~`lfVkd-!lp;P(}y!+c?q=( zM%QuZ_;eKB;^SyRjTwVE%cft1he{?h8zX>{Zd9TdX#B!zh4WMl{62hi0B%*| zDP3RKVl%fmGX~%QT)8zUTm`eDNkT+d_G+`;KT6B@S^&@;MO`I<1XxXGwK@^GAyAsrMa~3?u zhQ2a8fa}Ryo>Y;}viNL9T#v8!jWm2oPfS>|Mp}tp{|JMkny-g55nhCo6+9-E@iU|< zh#br;@3fcj*})cGlL{6TX)6KDx2Ra6$`@7KZ8z}_S)6RldlLuke2bKtcbBCa9e1Q> z)=S$fF@%s8moY1Xeg9sJJT`(g-m^uT$#(6Dl=r^QcE2Aky~-;0bPAe_eF|jGIQMl{ z_;IVC>Q`!NC~0|}4ST2)*N(D%cnP+l{2Z+odddtz_PHm}3gL}%|Gfl1F`UzuRQx5e<8MWb;idu4B& z{Mimd(mY{1|9m_)czXdzIutRbhuO3&j8Z-I zR7Mb`I_zNU@~2A~>{|ZN5D!$+6=hN(<`ray_1qH~(gp)oKT8_O*6&NOeFIMveK6V^ zUeMG3Yj{bAzw$qZH+48Yv~{{8;~ ypcp`(Ek`V)#3hgXu`+BIiUAr;jHZczHT4- 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�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 IMeJ1n9}?LIH~;_u delta 48760 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 a>aeC`>r!7*o5C-q-kR3*`OB%BQvM%mS;({i diff --git a/src/drone-software/src/acoustic/build/extract_mel_cpp.exe b/src/drone-software/src/acoustic/build/extract_mel_cpp.exe index ce056fbe7b1e37fc0f6a637fba8293eb56f8b90f..4a04e4e24bf75a78ed7e0a48388947b4d6cfaeb7 100644 GIT binary patch delta 24 gcmdnp%D%gmeL@G*?28k-{FrW+H{RNMi}B$>0FM9+UjP6A delta 24 gcmdnp%D%gmeL@FQ)`f{(eoU*%8gFgA#rW_b0E$uz`v3p{ diff --git a/src/drone-software/src/acoustic/build/test_classifier_cpp.exe b/src/drone-software/src/acoustic/build/test_classifier_cpp.exe index 8700e6b50adab4ccf6f03417b6f746541b2d32da..3320b8a4943bf65cacef61530055c36443844d48 100644 GIT binary patch delta 27 jcmX@`k>kKejtL!13olOW@?+Xn*LbV-7UR}iOwY^#$u$lO delta 27 jcmX@`k>kKejtL!1`4=X3`7w3WHr{Hz#klnr(=&4b!#xe9 diff --git a/src/drone-software/src/acoustic/build/test_core_lib.exe b/src/drone-software/src/acoustic/build/test_core_lib.exe index c751169b6cfab6bd7c34152c56b85124c278def6..7e1fbd077753aca6d2a3c0f2f6d51625620a338f 100644 GIT binary patch delta 452 zcmezHOz6Wip$Q#KGcHc-@?)AYYvZkOllsLB3=AI4KREeYAA(pr6N^eRb8=FPJi8e@ zEIIgFK7&P5D++S*i!<|qLZ$T$6&!h`m7nB#n1e47k~;_y+8^yPQ6$)6(ldfD+lJY0p$gFjVB*7)vhn81+s80IV&xCH!5?~vU*iIQ*yWe$|NsBzmu~>t0WyU31W?h-La-Q!F9h@nTj^e) z+Z!!PGKx}5H>EXJuq2k0u6n5lRFuXq@4~IM})Dgt;QUt8sfkC0Mg1I;& zzl6WF3?e7=^4CA0COv-n7La`mlP8!dGOADBWah;9Wb#)t@5u%)WSf1>+kMR$xBHqi zF`KHEIWRC}EN5b90McK8xB$pzaAaWM2jUVSTL4IlY%k4Wnpw`+FrEJilQJ`dA;a{E vXPIOf_fOY9X6)QWy_M;?D`E0Fb>Um%DhjbFY6$OiMAcz{B(;k--? z{Q5We+q=M`k*sDwfzSLg7eDjIT>vUzwE`*75Igl^)>N=IUOun@P+ovndGa<>ZDIbF zMu>?*Y5eaGfDFAl`Gcuwee(bR|M}%X7PIc)VPbe$24VKW(V_j2Xn^l4(3b(rmB4o3=A2| znHVMjX%IoAUs|pJPgUED2M`qFXc~6+O&wIjr=^OyR@|t)6 diff --git a/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h b/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h index d71ae0e..5898cb5 100644 --- a/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h +++ b/src/drone-software/src/acoustic/include/acoustic_analyzer/io/wav_file_source.h @@ -22,7 +22,7 @@ public: bool open(); bool parse_wav_header(); void resample_if_needed(std::vector& mono, int src_rate, int dst_rate); - size_t read(std::vector>& out, size_t max_samples); + std::size_t read(std::vector>& out, std::size_t max_samples); void close(); std::size_t num_channels() const { return num_channels_; } @@ -39,8 +39,8 @@ private: uint32_t file_sample_rate_; uint16_t bits_per_sample_; long data_start_; - size_t total_samples_; - size_t read_pos_; + std::size_t total_samples_; + std::size_t read_pos_; }; } // namespace acoustic diff --git a/src/drone-software/src/acoustic/src/core/distance_estimator.cpp b/src/drone-software/src/acoustic/src/core/distance_estimator.cpp index c2407d7..59a7a6e 100644 --- a/src/drone-software/src/acoustic/src/core/distance_estimator.cpp +++ b/src/drone-software/src/acoustic/src/core/distance_estimator.cpp @@ -28,8 +28,8 @@ struct DistanceEstimator::Impl { if (sound_type == "gunshot") return config.ref_spl_gunshot; if (sound_type == "artillery") return config.ref_spl_artillery; if (sound_type == "explosion") return config.ref_spl_explosion; - if (sound_type == "threat") return 150.0f; - // Fallback: use gunshot/threat reference + if (sound_type == "threat") return config.ref_spl_gunshot; // binary model uses gunshot ref + // Fallback: use gunshot reference return config.ref_spl_gunshot > 0.0f ? config.ref_spl_gunshot : 150.0f; } diff --git a/src/drone-software/src/acoustic/src/core/feature_extractor.cpp b/src/drone-software/src/acoustic/src/core/feature_extractor.cpp index 4c79e66..4cfa66b 100644 --- a/src/drone-software/src/acoustic/src/core/feature_extractor.cpp +++ b/src/drone-software/src/acoustic/src/core/feature_extractor.cpp @@ -74,7 +74,7 @@ struct FeatureExtractor::Impl { } Eigen::MatrixXf ComputeMelSpec(const std::vector& audio) { - size_t n_samples = audio.size(); + std::size_t n_samples = audio.size(); int n_fft_bins = n_fft / 2 + 1; int n_frames = static_cast((static_cast(n_samples) - n_fft) / hop_length) + 1; if (n_frames < 1) n_frames = 1; @@ -89,7 +89,7 @@ struct FeatureExtractor::Impl { for (int t = 0; t < n_frames; ++t) { int start = t * hop_length; for (int i = 0; i < n_fft; ++i) { - size_t idx = start + i; + std::size_t idx = start + i; fft_buf[i] = (idx < n_samples ? preemph[idx] : 0.0f) * window[i]; } compute_power_spectrum(fft_buf.data(), n_fft, power.data()); @@ -164,13 +164,13 @@ std::vector FeatureExtractor::MelSpectrogramMultiChannel( const std::vector& audio_samples, std::size_t num_channels) { if (num_channels == 0) return {}; - size_t total = audio_samples.size(); - size_t samples_per_channel = total / num_channels; + std::size_t total = audio_samples.size(); + std::size_t samples_per_channel = total / num_channels; std::vector results; results.reserve(num_channels); for (std::size_t ch = 0; ch < num_channels; ++ch) { std::vector ch_audio(samples_per_channel); - for (size_t i = 0; i < samples_per_channel; ++i) { + for (std::size_t i = 0; i < samples_per_channel; ++i) { ch_audio[i] = audio_samples[i * num_channels + ch]; } results.push_back(impl_->ComputeMelSpec(ch_audio)); diff --git a/src/drone-software/src/acoustic/src/core/fft_utils.cpp b/src/drone-software/src/acoustic/src/core/fft_utils.cpp index 6f790ed..7bdab56 100644 --- a/src/drone-software/src/acoustic/src/core/fft_utils.cpp +++ b/src/drone-software/src/acoustic/src/core/fft_utils.cpp @@ -4,16 +4,16 @@ namespace acoustic { -void apply_preemphasis(const float* in, float* out, size_t n, float coef) { +void apply_preemphasis(const float* in, float* out, std::size_t n, float coef) { if (n == 0) return; out[0] = in[0]; - for (size_t i = 1; i < n; ++i) { + for (std::size_t i = 1; i < n; ++i) { out[i] = in[i] - coef * in[i - 1]; } } -void apply_hann_window(float* data, size_t n) { - for (size_t i = 0; i < n; ++i) { +void apply_hann_window(float* data, std::size_t n) { + for (std::size_t i = 0; i < n; ++i) { float w = 0.5f - 0.5f * std::cos(2.0f * static_cast(M_PI) * i / (n - 1)); data[i] *= w; } @@ -83,7 +83,7 @@ bool load_mel_filter_bank(const std::string& path, int n_mels, int n_fft_bins, std::vector& filter_bank) { std::ifstream f(path, std::ios::binary); if (!f) return false; - size_t expected = static_cast(n_mels) * n_fft_bins; + std::size_t expected = static_cast(n_mels) * n_fft_bins; filter_bank.resize(expected); f.read(reinterpret_cast(filter_bank.data()), expected * sizeof(float)); return f.gcount() == static_cast(expected * sizeof(float)); diff --git a/src/drone-software/src/acoustic/src/core/gcc_phat_localizer.cpp b/src/drone-software/src/acoustic/src/core/gcc_phat_localizer.cpp index 66194a0..b8915ba 100644 --- a/src/drone-software/src/acoustic/src/core/gcc_phat_localizer.cpp +++ b/src/drone-software/src/acoustic/src/core/gcc_phat_localizer.cpp @@ -85,7 +85,7 @@ struct GccPhatLocalizer::Impl { } } - float ComputeGccPhatDelay(const float* ch1, const float* ch2, size_t n) { + float ComputeGccPhatDelay(const float* ch1, const float* ch2, std::size_t n) { int nfft = 1; while (nfft < static_cast(2 * n)) nfft <<= 1; @@ -132,7 +132,7 @@ struct GccPhatLocalizer::Impl { bool SolveDirection(const std::vector& delays, float& azimuth, float& elevation) { int M = mic_config.num_mics; - if (M < 2 || delays.size() != static_cast(M * (M - 1) / 2)) { + if (M < 2 || delays.size() != static_cast(M * (M - 1) / 2)) { return false; } @@ -184,14 +184,14 @@ GccPhatLocalizer& GccPhatLocalizer::operator=(GccPhatLocalizer&&) noexcept = def std::pair GccPhatLocalizer::Localize(const Eigen::MatrixXf& multi_channel_audio) { int M = impl_->mic_config.num_mics; if (M < 2 || multi_channel_audio.cols() < M) return {0.0f, 0.0f}; - size_t n = multi_channel_audio.rows(); + std::size_t n = multi_channel_audio.rows(); if (n == 0) return {0.0f, 0.0f}; std::vector delays; for (int i = 0; i < M; ++i) { for (int j = i + 1; j < M; ++j) { std::vector ch1(n), ch2(n); - for (size_t s = 0; s < n; ++s) { + for (std::size_t s = 0; s < n; ++s) { ch1[s] = multi_channel_audio(static_cast(s), i); ch2[s] = multi_channel_audio(static_cast(s), j); } @@ -211,12 +211,12 @@ std::pair GccPhatLocalizer::Localize(const Eigen::MatrixXf& multi_ std::pair GccPhatLocalizer::Localize(const std::vector& flat_samples, std::size_t num_channels) { if (num_channels == 0) return {0.0f, 0.0f}; - size_t total = flat_samples.size(); - size_t samples_per_channel = total / num_channels; + std::size_t total = flat_samples.size(); + std::size_t samples_per_channel = total / num_channels; if (samples_per_channel == 0) return {0.0f, 0.0f}; Eigen::MatrixXf mat(static_cast(samples_per_channel), static_cast(num_channels)); - for (size_t ch = 0; ch < num_channels; ++ch) { - for (size_t i = 0; i < samples_per_channel; ++i) { + for (std::size_t ch = 0; ch < num_channels; ++ch) { + for (std::size_t i = 0; i < samples_per_channel; ++i) { mat(static_cast(i), static_cast(ch)) = flat_samples[i * num_channels + ch]; } } diff --git a/src/drone-software/src/acoustic/src/io/mobile_phone_source.cpp b/src/drone-software/src/acoustic/src/io/mobile_phone_source.cpp index 4e8b8db..7b58a43 100644 --- a/src/drone-software/src/acoustic/src/io/mobile_phone_source.cpp +++ b/src/drone-software/src/acoustic/src/io/mobile_phone_source.cpp @@ -1,7 +1,12 @@ #include "acoustic_analyzer/io/mobile_phone_source.h" +#include #include #include #include +#include +#include +#include +#include #include #include #include @@ -10,92 +15,135 @@ namespace acoustic { -MobilePhoneSource::MobilePhoneSource(int port, int sample_rate, float timeout_sec) - : port_(port), sample_rate_(sample_rate), timeout_sec_(timeout_sec), sockfd_(-1) {} +struct MobilePhoneSource::Impl { + int port_ = 0; + int sample_rate_ = 16000; + float timeout_sec_ = 10.0f; + int sockfd_ = -1; + bool running_ = false; + std::thread recv_thread_; + std::mutex mutex_; + std::condition_variable cv_; + std::queue buffer_; -MobilePhoneSource::~MobilePhoneSource() { - close(); -} + Impl(int port, int sample_rate, float timeout_sec) + : port_(port), sample_rate_(sample_rate), timeout_sec_(timeout_sec) {} -bool MobilePhoneSource::open() { - sockfd_ = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd_ < 0) return false; + ~Impl() { Close(); } - int opt = 1; - setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + bool Open() { + sockfd_ = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd_ < 0) return false; - sockaddr_in addr{}; - addr.sin_family = AF_INET; - addr.sin_port = htons(port_); - addr.sin_addr.s_addr = INADDR_ANY; + int opt = 1; + setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); - if (bind(sockfd_, reinterpret_cast(&addr), sizeof(addr)) < 0) { - ::close(sockfd_); - sockfd_ = -1; - return false; - } + sockaddr_in addr{}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port_); + addr.sin_addr.s_addr = INADDR_ANY; - // Set non-blocking - int flags = fcntl(sockfd_, F_GETFL, 0); - fcntl(sockfd_, F_SETFL, flags | O_NONBLOCK); + if (bind(sockfd_, reinterpret_cast(&addr), sizeof(addr)) < 0) { + ::close(sockfd_); + sockfd_ = -1; + return false; + } - running_ = true; - recv_thread_ = std::thread(&MobilePhoneSource::receive_loop, this); - return true; -} + int flags = fcntl(sockfd_, F_GETFL, 0); + fcntl(sockfd_, F_SETFL, flags | O_NONBLOCK); -void MobilePhoneSource::close() { - running_ = false; - if (recv_thread_.joinable()) recv_thread_.join(); - if (sockfd_ >= 0) { - ::close(sockfd_); - sockfd_ = -1; + running_ = true; + recv_thread_ = std::thread(&Impl::ReceiveLoop, this); + return true; } -} -void MobilePhoneSource::receive_loop() { - std::vector packet_buf(2048); - sockaddr_in client_addr{}; - socklen_t addr_len = sizeof(client_addr); - auto start = std::chrono::steady_clock::now(); - - while (running_) { - ssize_t n = recvfrom(sockfd_, packet_buf.data(), - packet_buf.size() * sizeof(float), - 0, reinterpret_cast(&client_addr), &addr_len); - if (n > 0) { - size_t samples = n / sizeof(float); - std::lock_guard lock(mutex_); - for (size_t i = 0; i < samples; ++i) { - buffer_.push(packet_buf[i]); - } - cv_.notify_one(); - start = std::chrono::steady_clock::now(); - } else { - auto now = std::chrono::steady_clock::now(); - float elapsed = std::chrono::duration(now - start).count(); - if (elapsed > timeout_sec_) { - // Timeout: stop waiting - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } + void Close() { + running_ = false; + if (recv_thread_.joinable()) recv_thread_.join(); + if (sockfd_ >= 0) { + ::close(sockfd_); + sockfd_ = -1; } } -} -size_t MobilePhoneSource::read(std::vector>& out, size_t max_samples) { - std::unique_lock lock(mutex_); - if (buffer_.empty()) { - cv_.wait_for(lock, std::chrono::milliseconds(100)); + void ReceiveLoop() { + std::vector packet_buf(2048); + sockaddr_in client_addr{}; + socklen_t addr_len = sizeof(client_addr); + auto start = std::chrono::steady_clock::now(); + + while (running_) { + ssize_t n = recvfrom(sockfd_, packet_buf.data(), + packet_buf.size() * sizeof(float), + 0, reinterpret_cast(&client_addr), &addr_len); + if (n > 0) { + size_t samples = static_cast(n) / sizeof(float); + std::lock_guard lock(mutex_); + for (size_t i = 0; i < samples; ++i) { + buffer_.push(packet_buf[i]); + } + cv_.notify_one(); + start = std::chrono::steady_clock::now(); + } else { + auto now = std::chrono::steady_clock::now(); + float elapsed = std::chrono::duration(now - start).count(); + if (elapsed > timeout_sec_) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + } } - size_t available = std::min(max_samples, buffer_.size()); - out.resize(1); - out[0].resize(available); - for (size_t i = 0; i < available; ++i) { - out[0][i] = buffer_.front(); - buffer_.pop(); + std::vector Read(std::size_t max_samples) { + std::unique_lock lock(mutex_); + if (buffer_.empty()) { + cv_.wait_for(lock, std::chrono::milliseconds(100)); + } + + std::size_t available = std::min(max_samples, buffer_.size()); + std::vector out(available); + for (std::size_t i = 0; i < available; ++i) { + out[i] = buffer_.front(); + buffer_.pop(); + } + return out; } - return available; +}; + +MobilePhoneSource::MobilePhoneSource(ros::NodeHandle& nh, + const std::string& topic, + float timeout_sec, + int sample_rate) + : impl_(std::make_unique(0, sample_rate, timeout_sec)) { + (void)nh; + (void)topic; + // Topic-based ROS subscriber could be added here; currently using UDP fallback. +} + +MobilePhoneSource::~MobilePhoneSource() = default; + +bool MobilePhoneSource::Open() { + return impl_->Open(); +} + +std::vector MobilePhoneSource::Read(std::size_t num_samples) { + return impl_->Read(num_samples); +} + +void MobilePhoneSource::Close() { + impl_->Close(); +} + +std::size_t MobilePhoneSource::NumChannels() const { + return 1; +} + +int MobilePhoneSource::SampleRate() const { + return impl_->sample_rate_; +} + +bool MobilePhoneSource::IsOpen() const { + return impl_->sockfd_ >= 0; } } // namespace acoustic diff --git a/src/drone-software/src/acoustic/src/io/wav_file_source.cpp b/src/drone-software/src/acoustic/src/io/wav_file_source.cpp index f7177d4..7cb624a 100644 --- a/src/drone-software/src/acoustic/src/io/wav_file_source.cpp +++ b/src/drone-software/src/acoustic/src/io/wav_file_source.cpp @@ -112,22 +112,22 @@ float convert_sample(const uint8_t* raw, int bytes, bool is_float) { void WavFileSource::resample_if_needed(std::vector& mono, int src_rate, int dst_rate) { if (src_rate == dst_rate || dst_rate <= 0) return; double ratio = static_cast(dst_rate) / src_rate; - size_t new_len = static_cast(mono.size() * ratio); + std::size_t new_len = static_cast(mono.size() * ratio); std::vector resampled(new_len); - for (size_t i = 0; i < new_len; ++i) { + for (std::size_t i = 0; i < new_len; ++i) { double src_idx = i / ratio; - size_t idx0 = static_cast(src_idx); - size_t idx1 = std::min(idx0 + 1, mono.size() - 1); + std::size_t idx0 = static_cast(src_idx); + std::size_t idx1 = std::min(idx0 + 1, mono.size() - 1); double frac = src_idx - idx0; resampled[i] = static_cast(mono[idx0] * (1.0 - frac) + mono[idx1] * frac); } mono.swap(resampled); } -size_t WavFileSource::read(std::vector>& out, size_t max_samples) { +std::size_t WavFileSource::read(std::vector>& out, std::size_t max_samples) { if (!fp_) return 0; - size_t samples_to_read = std::min(max_samples, total_samples_ - read_pos_); + std::size_t samples_to_read = std::min(max_samples, total_samples_ - read_pos_); if (samples_to_read == 0) return 0; int bytes_per_sample = bits_per_sample_ / 8; @@ -137,7 +137,7 @@ size_t WavFileSource::read(std::vector>& out, size_t max_samp std::vector raw(samples_to_read * block_align); fseek(fp_, static_cast(data_start_ + read_pos_ * block_align), SEEK_SET); - size_t read_blocks = fread(raw.data(), block_align, samples_to_read, fp_); + std::size_t read_blocks = fread(raw.data(), block_align, samples_to_read, fp_); if (read_blocks == 0) return 0; out.resize(num_channels_); @@ -145,7 +145,7 @@ size_t WavFileSource::read(std::vector>& out, size_t max_samp out[ch].resize(read_blocks); } - for (size_t i = 0; i < read_blocks; ++i) { + for (std::size_t i = 0; i < read_blocks; ++i) { for (int ch = 0; ch < num_channels_; ++ch) { out[ch][i] = convert_sample(&raw[i * block_align + ch * bytes_per_sample], bytes_per_sample, is_float); diff --git a/src/drone-software/src/acoustic/tests/demo_offline.cpp b/src/drone-software/src/acoustic/tests/demo_offline.cpp index a027bdc..1e40dff 100644 --- a/src/drone-software/src/acoustic/tests/demo_offline.cpp +++ b/src/drone-software/src/acoustic/tests/demo_offline.cpp @@ -26,7 +26,7 @@ struct Prediction { }; void print_usage(const char* prog) { - std::cerr << "Usage: " << prog << " [--model ] [--label_map ]" << std::endl; + std::cerr << "Usage: " << prog << " [--model ] [--label_map ] [--threshold ]" << std::endl; } bool ends_with(const std::string& s, const std::string& suffix) { @@ -189,16 +189,18 @@ int main(int argc, char** argv) { std::string target = argv[1]; std::string model_path = "models/gunshot_classifier.onnx"; std::string label_map_path = "models/label_map.json"; + float threshold = 0.5f; for (int i = 2; i < argc; ++i) { if (std::strcmp(argv[i], "--model") == 0 && i + 1 < argc) model_path = argv[++i]; else if (std::strcmp(argv[i], "--label_map") == 0 && i + 1 < argc) label_map_path = argv[++i]; + else if (std::strcmp(argv[i], "--threshold") == 0 && i + 1 < argc) threshold = std::stof(argv[++i]); } ClassifierConfig cc; cc.model_path = model_path; cc.label_map_path = label_map_path; - cc.threshold = 0.5f; + cc.threshold = threshold; cc.smoothing_window = 1; GunshotClassifier classifier(cc); if (!classifier.IsLoaded()) {