Doc. no.ST-01
RevisionA
Issued2026-08-06
StatusDraft — pre-build
ClassFeasibility
Sections5

Acoustic Shot
Detection

Feasibility assessment — smartphone microphone as substitute for a dedicated competition shot timer. Covers acoustic limits, sensor architecture, detection method, market position, and development scope. Platforms: iOS / Android. Venue class: outdoor bay.

Table 1 — Governing parameters
ParameterValueUnitRef.
Muzzle report, 9 mm @ 1 m155–160dB SPL1.2
Phone MEMS mic overload point120–130dB SPL1.2
Adjacent bay @ 50 m, free field~124dB SPL2.1
Berm insertion loss, estimated10–20dB2.1
Muzzle blast directivity, fore vs. aft10–15dB2.2
Split interval requiring resolution0.12–0.15s1.2
Reverberation tail — outdoor50–150ms2.0
Reverberation tail — indoor200–400ms1.2
Capture rate, unprocessed48 000Hz1.3
Display resolution, sport standard0.01s1.3
Reference hardware buzzer output105dB SPL1.2
Phone speaker output, typical85–95dB SPL1.2
Hearing protection attenuation25–33dB NRR1.2
AssessmentConditional5.5
UNRESOLVED t0 0.160.14 0.150.13 FS
Fig. 1 — Shot string, outdoor bay. Start signal at t0, five confirmed impulses, splits in seconds. The flagged peak is the design problem: berm reflection, adjacent-bay report, or a live round the detector cannot afford to discard.
1.0

Core Feasibility

1.1Inquiry
Inquiry 01Scope definition

I'm scoping a mobile app for competitive shooters and range masters that would take over the role of the dedicated shot timer used to score stage runs. The core question: can a smartphone reliably detect shots and measure the intervals between them through its microphone, at close proximity to the shooter? Producing the start signal through the speaker is straightforward.

The appeal is the data layer — tracking every shooter across every stage of a competition, computing scores at the end, and giving match officials tooling they don't currently have. Targeting both iOS and Android. What's your read on feasibility and implementation?

Yes, but with real caveats. Phone-mic shot detection works well enough for solo practice and single-bay drills, and it's shaky enough at a live multi-bay match that I wouldn't build the business on it. The consensus among shooters is that phone microphones pick up echoes, neighboring bays, and ambient noise as false shots, and that phone mics simply aren't designed for detecting gunshots, so sensitivity is inconsistent. The good news is that the hard part of your idea — match management, per-shooter tracking across stages, scoring — is where the actual value is, and that part is pure software.

1.2Acoustic constraints

The core physics working against you:

Overload. A 9mm at 1 m is roughly 155–160 dB SPL. The MEMS mics in phones have an acoustic overload point around 120–130 dB. Every shot slams the mic into hard clipping. That's actually fine for detecting something happened, but it destroys the waveform you'd want for classifying it, and some mic assemblies take a few ms to recover.

Reverb and echo. In a bay with berms or an indoor range, the tail of one shot can last 200–400 ms. Fast shooters run 0.15 s splits, and a top-tier Bill drill dips toward 0.12. So your second shot arrives while the first one is still ringing. A naive threshold-plus-dead-time detector either misses shots (dead time too long) or double-counts echoes (too short). This is the single biggest algorithmic problem.

Adjacent bays. At a match, three squads are firing simultaneously 30 m away. Hardware timers solve this with tuned sensitivity and a mic mounted inches from the shooter. A phone on a barrel three feet away has a much worse signal-to-interference ratio.

Beep audibility. This one gets overlooked. The AMG Commander runs a 105 dB, 1.5 kHz buzzer. A phone speaker manages maybe 85–95 dB and is physically tiny. Shooters wear muffs with 25–33 dB NRR. Your start signal may simply not be heard. Partial mitigation: muffs attenuate high frequencies far more than low, so a 500–900 Hz tone penetrates better than a 3 kHz chirp — but you're still fighting hardware limits.

1.3Platform capture

You need to defeat the phone's speech-optimized audio pipeline (AGC, noise suppression, echo cancellation), all of which will mangle impulse detection:

  • Android: MediaRecorder.AudioSource.UNPROCESSED (API 24+, gate on AudioManager.PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED, and fall back to VOICE_RECOGNITION, which typically disables AGC/NS). Use AAudio via the Oboe library for low-latency, low-jitter capture.
  • iOS: AVAudioSession with .measurement mode, which disables system-applied signal processing. Use AVAudioEngine or a RemoteIO Audio Unit — explicitly not VoiceProcessingIO. On newer iPhones you can also select the input data source and polar pattern.

48 kHz mono gives you ~21 µs resolution, hugely more than the 0.01 s the sport displays. Precision isn't your problem; discrimination is.

1.4Timing reference

Don't try to reconcile output latency, input latency, and clock drift between the speaker and the mic. Instead: play the beep and detect the beep in the recorded stream. Its onset in the input buffer is t=0. That's an acoustically true zero, immune to buffer size, device model, and Bluetooth. It's the cleanest architectural decision available to you, and it costs almost nothing.

1.5Detection method

Two-stage works well:

  • Onset candidates. Track the envelope and look for transients with sub-millisecond rise time and high crest factor. Gunshots have an attack far sharper than a reverb tail, brass hitting concrete, or a distant bay. Spectral flux or a high-frequency-content function works better than raw energy.
  • Gating against the tail. Instead of a fixed refractory window, model the decay after each confirmed shot as an exponential and require the next onset to exceed that decaying curve, not the static noise floor. This is what lets you catch a 0.13 s split without also catching its own echo.
  • Optional classifier. A small CNN on log-mel frames, running via TFLite/Core ML, can help reject adjacent-bay shots — distant reports lose high frequencies to air absorption and arrive with a softer, more diffuse onset. Near-field shots clip; far-field ones usually don't. With AGC disabled, absolute level alone is a surprisingly strong discriminator.
1.6Software-only capability

Record the full audio of every string as compressed FLAC (a 30-second run is ~1.5 MB). This unlocks:

  • Re-analysis. Detection was wrong? Re-run at different sensitivity after the fact, without a re-shoot.
  • RO review with a waveform scrubber. Tap to delete a false shot or insert a missed one. Even $200 timers get strings wrong; the difference is they can't show you why. This is a genuinely better user experience than any dedicated unit, and I'd make it the centerpiece.
1.7Hardware interop

The AMG Commander uses a simple, open protocol, and the company states developers are given access on request; it was the first timer integrated into PractiScore on both Android and iOS. It uses a BLE push model, so a timer can be brought to a match and used with any scoring device without pairing hassle.

That's your derisking move. Ship mic detection for practice, and BLE ingest for matches. You get match-grade reliability without solving acoustics, and you compete on the software layer where you can actually win.

1.8Match management

This is the real product, and it's mostly conventional engineering:

  • Data model: Match → Stage → Squad → Shooter → StageRun → String → Shots + hits + penalties.
  • Scoring engine, made pluggable. USPSA is hit factor (points ÷ time) normalized against the stage winner. IDPA is time-plus with points-down converted to seconds. Steel Challenge is five strings, drop the worst, sum the rest, with per-miss penalties. Rules change annually — make this data-driven config, not hardcoded logic, or you'll rewrite it every January.
  • Offline-first, always. Ranges have terrible connectivity. You need local persistence plus device-to-device sync (WiFi Direct / local network / BLE) with conflict resolution, because a squad's tablet may never see the internet during a match.
  • Know the incumbent. PractiScore is entrenched, free, and the default at nearly every club in the US. Head-on competition is brutal. The gap I'd target is longitudinal athlete analytics — draw times, splits, transitions, reload times trended across months and matches, benchmarked against peers. Competitors want that badly and don't have it.
1.9Stack

Flutter or React Native for UI, with a shared DSP core in C++ or Rust exposed via FFI, plus thin native audio shims (Oboe on Android, AVAudioEngine on iOS). Audio capture must be native; everything above it can be cross-platform.

1.10First actions

Before writing app code: buy a CED7000 or an AMG, and build a throwaway rig that records raw audio while the hardware timer runs. Collect a few hundred strings across pistol/PCC/rifle, indoor/outdoor, suppressed/unsuppressed, quiet bay/adjacent bays firing. Then tune offline against ground truth. If your detector can't hit ~99% agreement on split times in that dataset, you know before you've built a product on top of it.

One thing to verify yourself: whether match officials in your target disciplines will accept phone-based timing for official scoring. I couldn't find a rule that flatly prohibits it, but RO culture is conservative and the practical answer at most matches will be "bring a real timer." Check the current USPSA and IDPA rulebooks directly rather than trusting secondhand summaries.

2.0

Outdoor Acoustics

2.1Inquiry / clipping
Inquiry 02Venue constraint

Worth noting: every venue this would target is an outdoor range. And it seems like amplitude alone should be enough to separate shots fired on the recorded bay from those on the bay next door.

Outdoor helps enormously — more than the dB argument does. Losing hard parallel surfaces collapses your reverb tail from a few hundred milliseconds to maybe 50–150 ms of berm slap-back, and that was the problem that actually threatened split resolution. That one environmental fact removes most of my concern about resolving 0.13 s splits.

The level-discrimination idea is directionally right but thinner than it looks, for one specific reason.

Level only discriminates if both signals land inside the mic's linear range. Run the numbers: a 9mm at 1 m is ~158 dB. Free-field spreading costs 6 dB per doubling of distance, so a shot in the next bay at 50 m arrives around 124 dB. Phone MEMS mics overload somewhere around 120–130 dB. The adjacent bay is sitting right at your ceiling.

Above the overload point, everything reads the same: full scale. You can't measure that the near shot is 158 dB, only that it railed the ADC. So the useful comparison isn't 158 vs 124, it's "railed" vs "possibly also railed."

What saves you in practice is berm geometry. A berm between bays is an acoustic barrier worth roughly 10–20 dB of insertion loss depending on height and diffraction path, plus ground absorption over the intervening distance. That likely drops the neighbor to 105–115 dB — comfortably below saturation and clearly separable. But it depends on your specific range's layout, and it's the berm doing the work, not the inverse square law.

2.2Margin consumers

Muzzle direction. Blast is directional — 10–15 dB hotter in front of the muzzle than behind it. The RO stands behind the shooter. So when your shooter engages a wide array and swings the gun 90° across the bay, or moves downrange away from the phone, their own shots can drop 10 dB within a single string. Meanwhile the neighbor's shooter might be angled toward you. Set your threshold high enough to reject the next bay and you'll start dropping your own shooter's shots on the wide targets. That's precisely the complaint ROs have about mic-based apps, and it's a level-threshold artifact.

Phone placement. RO holding it at 0.3 m versus set on a barrel at 3 m is 20 dB of swing on the near signal. If placement isn't controlled, a fixed threshold isn't meaningful.

Device variance. Mic sensitivity and preamp gain differ across every handset. A dBFS threshold tuned on a Pixel is wrong on a Samsung. You'd need per-device calibration or a purely relative measure.

2.3Robust features

Level is worth using — just not alone, and not as the primary discriminator:

  • Clip duration. How many consecutive samples sit at full scale. This is a level proxy that works above saturation, which raw peak amplitude doesn't. Cheap to compute and surprisingly effective.
  • Spectral tilt. Air absorption is frequency-dependent and strongly attenuates above ~8 kHz over 50 m. The high-frequency energy ratio is a distance proxy that's largely independent of absolute level, so it holds up when both signals clip.
  • Rise time. A near-field muzzle blast is effectively a step function. By the time a shot has diffracted over a berm and reflected off ground, the attack is measurably smeared. Onset slope separates near from far even when both peaks rail.
  • Adaptive per-string baseline. Rather than an absolute threshold, characterize the first confirmed shot of the string and score subsequent onsets relative to it. This absorbs placement and device variance automatically.
2.4Unavailable to hardware

Stereo / multi-mic direction of arrival. Phones have two or three mics, and both iOS and most modern Android devices will hand you stereo capture. With ~10–14 cm spacing you get up to about ±400 µs of inter-channel delay — at 48 kHz that's ~20 samples, enough for coarse bearing estimation. If you know roughly which way the phone faces, you can reject events arriving from the wrong side. That's robust to level, robust to clipping, and it's the single strongest anti-neighbor tool available to you.

Cross-bay cancellation over the local network. If your app is running on phones in bays 3, 4, and 5 simultaneously, they can share event timestamps over WiFi. An event seen by all three, loudest on bay 4, belongs to bay 4 — every other device discards it. A standalone hardware timer structurally cannot do this. At a match where your app is the scoring platform across all stages, you'd have exactly the conditions needed. I'd treat this as a headline differentiator rather than a nice-to-have.

2.5Validation test

Don't design around assumptions here. Go to your actual target range on a match day, put a phone in the RO position with AGC disabled and raw capture running, and record continuously through several bays' worth of shooting. Then just plot the peak-level and clip-duration distributions for own-bay versus adjacent-bay events.

If the distributions separate with a 10+ dB gap, your instinct is correct and simple thresholding will carry you. If they overlap — or if a meaningful fraction of neighbor shots rail the ADC — you know you need the feature stack before you've written a line of app code. Either way you'll also capture the wide-array level drop, which is the failure mode I'd worry about most.

3.0

Sensor Placement

3.1Inquiry / BT transport
Inquiry 03Alternative sensor siting

What about a Bluetooth lapel microphone worn on the shooter's person, so the sensor travels with them through the course of fire?

Right instinct, wrong transport. Getting the mic onto the shooter genuinely solves the discrimination problem — at 0.5 m from the muzzle versus 50 m to the next bay, you now have ~40 dB of raw separation before the berm even contributes. The wide-array level-drop problem I flagged also mostly disappears, since the mic rotates with the gun. That's a real win.

The trouble is that consumer Bluetooth audio is close to the worst possible pipe for this signal.

The codec is a speech codec, and you don't control the DSP. Bluetooth microphone input runs over HFP — historically 8 kHz CVSD, or 16 kHz mSBC if you're lucky, and LC3 under LE Audio isn't fundamentally different in intent. These are tuned to make voice intelligible at low bitrate, which means they aggressively smear transients. Your entire near/far discrimination strategy rests on rise time and spectral tilt, and a voice codec destroys both. Worse, most BT mics and headset stacks apply their own noise suppression, limiting, and AGC in firmware, and there is no API to turn any of it off. On the phone's own mic you can request UNPROCESSED or .measurement mode. Over BT you get whatever the accessory vendor decided.

Jitter and packet loss. Constant latency wouldn't matter — splits are differences within one stream, so a fixed offset cancels. What kills you is that the delay isn't fixed. Jitter buffers expand and contract, packet-loss concealment inserts and drops samples, and the phone resamples to its own clock. Any of those shifts your timeline by milliseconds unpredictably, and a dropout during a string simply eats shots. On a 2.4 GHz-congested outdoor range with a human body between the mic and the phone, dropouts are not hypothetical.

Overload gets worse, not better. A lapel mic at 0.5 m sees roughly 165 dB. Consumer lav capsules have acoustic overload points around 110–120 dB, and many have limiter circuits with recovery times in the tens of milliseconds — which would blank out exactly the window where your next shot lands. Add wind noise and clothing rustle from a shooter sprinting through a field course, and the false-positive rate climbs at the same time.

3.2Event transport

Do the detection at the sensor, where the audio is uncompressed, unprocessed, and on a single stable clock. Then transmit timestamps over BLE. Timestamps are completely immune to latency, jitter, and buffering — a packet arriving 200 ms late still says "shot at 2.847 s" and is exactly as accurate.

This is precisely what the existing products do. RangeTech attaches the timer to the shooter and sends the data back to the mobile device, so the RO can stand behind the line and even trigger the start remotely. AMG does the same with BLE push. It's the right architecture — but it means you're shipping hardware, which is a different company than the one you were planning to start.

3.3No-new-hardware variant

Put the phone on the shooter's belt, and have the RO drive it from a second device over BLE or local WiFi.

This is worth thinking about carefully, because it quietly fixes several things at once:

  • All timing happens in one audio clock domain on one device. The RO's device sends only "start" and receives results after the string — neither is latency-sensitive.
  • The phone generates the beep from its own speaker, now ~30 cm from the shooter's head instead of 3 m. That's a 20 dB improvement on the beep-audibility problem I raised earlier, which was otherwise a hard physical wall.
  • The mic is 0.5 m from the muzzle with the full unprocessed pipeline available — no codec, no vendor AGC, no dropouts.
  • You still get the full audio recording for post-string review and re-analysis.

The costs are practical rather than technical: it's the shooter's phone taking abuse in a belt pouch, and you need a pairing/handoff flow that doesn't add friction. That last one matters more than it sounds — a squad of twelve across five stages means sixty handoffs, and if each one costs fifteen seconds of Bluetooth negotiation, ROs will abandon your app by lunch. BLE advertise-and-push (no pairing dialog) rather than classic pairing is the way to go, and AMG's decision to use push specifically to avoid pairing hassle is worth copying.

3.4Wired alternative

If you're set on a separate mic, a cheap wired lavalier into USB-C sidesteps every codec, latency, and battery problem in one move. USB audio class devices can give you 48 kHz uncompressed, and both platforms will hand you the raw stream. It's less elegant, but a $20 lav and a short cable to a belt-pouched phone is more reliable than any wireless option and costs you nothing in development.

3.5Open questions

Two things I'd verify rather than assume: whether attaching a device to a competitor runs into equipment rules in your target disciplines, and — more importantly — whether ROs will actually accept a workflow where they don't physically hold the timer. Range officer culture is built around the RO controlling the start signal and being able to call a stop. Asking them to give that up is a bigger ask than any of the engineering here.

4.0

Market Position

4.1Inquiry / tier 1
Inquiry 04Competitive landscape

On limiter behavior — the limiter hit itself is a detectable event, so that's a signal rather than purely a loss. And a range-owned phone resolves the device-abuse problem cleanly.

But before going further on architecture: what does the competitive landscape actually look like right now for phone-delivered apps aimed at competitive shooters?

Both good calls. Limiter recovery is a detectable signature — the gain-recovery ramp after a hit has a characteristic shape, and you could infer "something loud enough to trigger the limiter happened" plus estimate severity from recovery duration. It's the same trick as clip-duration, one layer up. The catch is that it's vendor-specific firmware behavior with no spec, so you'd be reverse-engineering per accessory model. Workable as a supplementary feature, fragile as a foundation. And a range-owned phone dissolves the abuse objection cleanly — it also fixes device calibration, since you'd be tuning for one known handset instead of a thousand.

Tier 1 — match management: effectively a monopoly. PractiScore owns this outright and it's the single most important fact for your plan. It's free, combines iOS and Android scoring apps with web services for registration, squadding, payments, and results, and over 700 clubs worldwide use it at no cost. The scoring app covers IPSC/USPSA, Steel Challenge, 3Gun, IDPA, ICORE, SASS, NRA/Bullseye, and PRS, runs fully offline, and has been used at national-level matches with over a thousand competitors. PractiScore 2 shipped as a rewrite with a new UI and rules support.

So the match-management half of your idea — the part I said was the real value — is occupied by a free, entrenched, multi-discipline incumbent with a decade of RO muscle memory behind it. That doesn't kill your idea, but it means "PractiScore but with a built-in timer" is not a viable pitch on its own.

4.2Tier 2 — hardware + app

This is where the money and the polish are:

  • AMG Lab Commander ($189–224) with PractiScore integration and a separate PractiScore Log app for practice tracking.
  • SG Timer (Shooters Global), ~$150+, from Poland, with a companion app called Drills. This one is your closest philosophical competitor — it does video capture with timer data overlaid in real time, remote timer control, performance analysis, and 3D/AR stage creation and sharing. They've got JJ Racaza fronting the training-analysis angle.
  • RangeTech, which does the shooter-worn-sensor architecture we discussed, with auto-scoring for USPSA, IDPA, Multigun, and Steel Challenge.

The pattern is unmistakable: everyone who's serious sells hardware and gives the app away as a differentiator.

4.3Tier 3 — phone only

There are many, mostly free, mostly small, and heavily skewed toward dry fire rather than live fire. Recent entrants: Dry Fire Pro uses on-device ML to detect the trigger click; ITP does mic-based split timing and tells users to hang the phone's bottom mic over a table edge for accuracy; BSHOCK runs shot detection off Apple Watch sensors with synced video. The older Android incumbent IPSC Shot Timer still self-describes as a beta and warns it's for training purposes only.

Nobody in this tier is credibly attempting live-fire match scoring. The whole category has conceded that ground.

4.4Tier 4 — alt sensing

PlinkPal is worth studying closely, because it solves your exact problem a different way. It pairs a Wear OS watch and uses the watch's motion sensors to detect recoil rather than sound, specifically so it works when the shooter next to you is mag-dumping, plus remote start from the wrist.

That's clever, and it sidesteps every acoustic problem we've spent three messages on — no overload, no echo, no adjacent bay, no codec. It's also the same insight as your lapel-mic idea but with a sensor that doesn't saturate. Worth serious consideration: a watch on the support wrist sees recoil impulses directly, and accelerometer sampling at 200–800 Hz gives you ~1–5 ms resolution, adequate for 0.01 s display. The weakness is discriminating recoil from movement in a field course where the shooter is sprinting — which is exactly the case USPSA cares about and static drills don't. Worth testing before assuming it transfers.

4.5Assessment

Three things stand out.

The unoccupied square is real. Nobody offers phone-mic live-fire timing integrated with multi-stage match management. That's not because it's unthought-of; it's because the acoustics are hard and PractiScore is free. Those are the two obstacles, and they're the ones you'd have to beat.

The paid analytics market is smaller than it looks. PractiScore Competitor is the flagship paid competitor-analytics app, at $9.99, and on Android it has roughly 12,000 lifetime downloads and about 240 in a recent 30-day window. Even allowing that iOS skews higher in this demographic, that's a niche of a niche. The shooters who want deep data are passionate but not numerous, and they're already buying $200 hardware. Price your expectations accordingly.

The credibility problem is structural. Every serious product in this space is hardware-anchored, and the review consensus we saw earlier explicitly frames apps as the inferior option. You'd be entering with the format the market has already labeled unreliable. That's beatable with demonstrated accuracy, but it's a marketing cost you should budget for, not a technical one.

4.6Next investigation

The most useful thing you could learn isn't technical — it's whether match directors are actually unhappy with PractiScore. If it works fine for them, you're solving a problem nobody has. If there are real, repeated complaints (setup friction, sync failures, the timer-to-tablet transcription step), those are your wedge, and the mic timing becomes the feature that removes a step rather than a gimmick.

The other question worth answering early: does your target range's RO corps want the timing automated at all? There's an argument they don't — the RO holding the timer and reading the number aloud is a verification ritual, and removing the human from it may read as a downgrade rather than an upgrade. I'd ask five ROs before writing code. That's a cheaper experiment than anything else in this thread.

5.0

Development Scope

5.1Inquiry / phases
Inquiry 05Effort estimate

I'll run all of this by an RO I know personally. The field sounds fairly saturated — I'm not certain I want to commit serious time to it, though it could work as a portfolio piece. What's a realistic ballpark to a first real-world testing module?

Good instinct to check with the RO first — that conversation is worth more than any estimate I can give you.

For scoping: the thing that makes this tractable as a portfolio piece is that you should not build the app first. The fastest path to knowing whether it works is a dumb recording rig plus offline analysis, and that's where nearly all the interesting work lives anyway.

Phase 0 — Capture rig (3 days to 2 weeks). An app that does exactly two things: play a beep, and record raw 48 kHz unprocessed audio to a file. No detection, no UI. Single platform only — pick whichever you already know. The range is wide because the unprocessed-audio-source APIs are genuinely fiddly and thinly documented on both platforms; if you've never fought AudioSource.UNPROCESSED or .measurement mode before, budget the two weeks.

Phase 1 — Data collection (calendar-gated, see 5.3). Buy a CED7000 or AMG (~$150–220) for ground truth. Get to a match, record continuously, log the hardware timer's numbers alongside.

Phase 2 — Offline detector (2–6 weeks part-time). Python and numpy against your corpus. This is the real work and the real risk. Outdoors with a decent signal it might come together in a couple of weekends. If the data is uglier than expected, it's unbounded — this is the phase that eats projects.

Phase 3 — Port to real-time on-device (1–2 weeks). Ring buffer, beep-as-t-zero, port the detector to C++ or Rust. Mechanical once Phase 2 works.

Phase 4 — Minimal testable app (2–3 weeks). Start/stop, shot list with splits, waveform review scrubber, save the string. That's it.

5.2Estimates
Table 2 — Time to first field-testable module
Developer profilePart-timeFull-time
Mobile dev, some DSP background6–10 wk3–4 wk
Competent dev, new to audio3–5 mo6–8 wk
5.3Calendar constraint

Your iteration loop is gated by match schedule, not code. Outdoor club matches run maybe twice a month. If your first data pull reveals a problem you can't fix from the recordings you have, you wait two weeks for the next opportunity. A six-week project can easily land at three months of calendar time for that reason alone.

Mitigate it by over-collecting on trip one: multiple phone positions simultaneously, different calibers, adjacent bays active and quiet, wide arrays, movement. Recording is free. Return trips are not.

5.4Portfolio framing

If this is a portfolio piece rather than a product, the app is the least impressive artifact you can produce. Anyone can ship a UI. What's actually rare and demonstrable:

  • A labeled corpus of a few hundred strings with hardware ground truth
  • A detector evaluated properly — ROC curve, precision/recall against the CED, error distribution on split times, honest characterization of where it fails
  • A writeup explaining why outdoor rise-time discrimination works and why the naive dB-threshold approach doesn't

That's a signals-processing portfolio piece with real-world messy data and a rigorous evaluation, which is considerably more interesting to a technical audience than another CRUD app. And it's Phases 0–2 only — call it 4–6 weeks part-time, with a functional demo app as an optional bonus.

Explicitly skip match management. It's months of unglamorous CRUD and sync work, it's the part PractiScore already owns, and it demonstrates nothing you couldn't show more cheaply elsewhere.

5.5Kill criterion
Abort condition — set before starting

After two weekends of offline detector work on real match data, if agreement with the hardware timer on shot count is below 95%, stop. Write it down now, while you're not emotionally invested. The failure mode with signal processing projects is that there's always one more feature to try, and the sunk cost gets ugly around week ten.

Even hitting the kill criterion leaves you with the corpus, the analysis, and a writeup about why phone-mic shot detection is harder than it looks. That's still a portfolio piece — arguably a more honest one than a demo that only works in the parking lot.