← Build log

Why We're Investing 40+ Hours in Core Audio Preprocessing Instead of Quick Fixes

Published: January 11, 2025

Sometimes the most important product decisions happen at 1 AM when your beautiful transcription software is spitting out [BLANK_AUDIO] [BLANK_AUDIO] [BLANK_AUDIO] instead of, you know, actual words. That’s when you realize you’ve got a choice: slap a band-aid on the problem or dig into the messy technical reality that will make or break your product’s core value proposition.

Last night, staring at logs showing 62% silence in a 3-minute recording, I made the call to invest serious engineering time into what most founders would dismiss as “technical debt.” Here’s why that decision might be the difference between building something that works and building something that actually works.

Update: This post chronicles our complete journey from FFmpeg investigation through licensing discoveries to our final Core Audio solution, including the systematic prompt-driven approach that got us there.

TLDR: The 40-Hour Investment That Saves 400 Hours

  • Problem: Removed SOX preprocessing (GPL licensing), audio quality crashed
  • Wrong path: Investigated FFmpeg → licensing nightmare, bundling complexity
  • Right path: Enhance existing Swift CLI with native Core Audio preprocessing
  • Investment: ~40 hours of systematic engineering work
  • Payoff: Zero licensing issues, zero external dependencies, production-ready audio quality
  • Bottom line: Sometimes the best solution is enhancing what you already have

The Problem: When Audio Quality Determines Product Success

Our VoiceCatcher app had a problem that would kill the product if left unfixed. After removing SOX preprocessing due to GPL compliance requirements, our transcription quality nosedived:

  • 62% silence in a 3-minute recording
  • Multiple 20-second blank segments
  • [BLANK_AUDIO] tokens instead of clean speech
  • User trust evaporating with each failed transcription

The contextual paragraph formatter was working perfectly—it was correctly rejecting the blank tokens as invalid sentence boundaries. The issue wasn’t our algorithm; it was the garbage audio we were feeding it.

The Architecture Decision: FFmpeg vs. Core Audio

Phase 1: The FFmpeg Investigation

Initially, FFmpeg seemed like the obvious choice:

  • 95% of SOX capabilities for audio preprocessing
  • Commercial LGPL licensing (seemed viable)
  • Industry standard for audio processing

But when we dug into the real requirements for a consumer DMG application, the picture changed dramatically:

FFmpeg Licensing Reality Check:

  • LGPL compliance requires source code distribution
  • Dynamic linking only (no static bundling)
  • Attribution requirements in app and website
  • GPL components must be disabled (--disable-gpl --disable-nonfree)
  • Binary size impact: 50-100MB+ for full feature set

The Killer: FFmpegKit (the go-to Swift wrapper) was discontinued in 2024, leaving us with unmaintained dependencies for a commercial product.

Security Gotcha: When I was exploring quick fixes, Cursor actually recommended downloading a precompiled SOX binary from some random GitHub release page. That’s exactly the kind of shortcut that gets companies compromised—downloading random binaries from questionable sources and treating them as “dependencies.” My experience immediately raised red flags: if you’re building commercial software, you never download precompiled binaries from unofficial sources. This near-miss reinforced why a systematic approach was essential.

Phase 2: The Core Audio Revelation

Then we realized something obvious: our Swift CLI already uses Core Audio through AVFoundation. Why build external dependencies when we could enhance what’s already working?

Existing Foundation:

  • ✅ 16kHz mono linear PCM output (perfect for Whisper)
  • ✅ Zero external dependencies (pure Swift + AVFoundation)
  • ✅ Commercial licensing (Apple’s frameworks)
  • ✅ Production tested in our Electron app
  • ✅ File + stdout support working flawlessly

The “Aha” Moment: Instead of replacing our audio system, we could enhance it with preprocessing filters using the same Core Audio framework it already uses.

The Systematic Approach: Solutions Architecture with Checks and Balances

Here’s where this gets interesting from a process perspective. I’m using ChatGPT as my solutions architect to craft prompts and double-check technical recommendations, creating a checks-and-balances system that’s been crucial for avoiding costly wrong turns.

This isn’t about replacing human judgment—it’s about augmenting decision-making with systematic analysis:

  1. Initial problem analysis → Human intuition + AI technical research
  2. Solution exploration → AI helps map licensing, technical, and integration challenges
  3. Implementation planning → Collaborative prompt crafting for precise requirements
  4. Risk assessment → Cross-validation of technical decisions

The FFmpeg→Core Audio pivot happened because this process helped us dig deeper into licensing implications and recognize we already had a better foundation.

The Implementation Plan: Two Targeted Prompts

Instead of a massive rewrite, we’re making surgical enhancements with two focused prompts:

Prompt 1: Swift CLI Enhancement

We have a working Swift CLI for audio capture built with AVFoundation. It already:

- Records 16kHz mono linear PCM audio
- Outputs to file or stdout
- Includes audio normalization
- Is built as a standalone CLI app for use in a commercial Electron app
- Has no GPL or system-level dependencies

Now we want to extend this same app with native **audio preprocessing** features to fully replace our old SoX pipeline.

🔧 Please add the following features:

1. **Optional Filters (via CLI):**
   - `--highpass [freq]`: Apply high-pass EQ at specified frequency (e.g. 80Hz)
   - `--lowpass [freq]`: Apply low-pass EQ (e.g. 8000Hz)
   - `--normalize-volume`: Use AVAudioEngine to boost gain appropriately

2. **Chunking Support:**
   - `--chunk-size [sec]`: Split audio into time-based chunks (e.g. 10 sec)
   - Works with both `--file` and `--stdout`
   - For `--file`, name like `audio_chunk_001.wav`
   - For `--stdout`, send chunk boundary markers if needed

3. **Silence Detection Support:**
   - Optional `--boost-silence-detection` to apply gain control or noise floor adjustment
   - Improves compatibility with our Node-side silence shutoff logic

4. **Tests and Help Output:**
   - Update CLI help text with all new flags
   - Add Swift unit tests using `XCTest` to validate:
     - Filters apply correctly
     - Chunking works with valid durations
     - Invalid args produce expected error messages

📦 This CLI is used in a commercial macOS app and must remain dependency-free. Do not use ffmpeg or SoX.

Do **not rewrite** the app — just enhance it.

Prompt 2: Node.js Wrapper Integration

Our Node.js wrapper is already successfully calling our Swift audio-capture CLI and piping output to Whisper.

We've just enhanced the Swift CLI with new flags:

- `--highpass [freq]`
- `--lowpass [freq]`
- `--chunk-size [sec]`
- `--normalize-volume`
- `--boost-silence-detection`

Please update the Node wrapper to:

1. Accept these options as part of the config object
2. Append the correct flags to the Swift CLI spawn command
3. Add TypeScript types for the new options
4. Update Vitest tests to:
   - Validate correct flag generation for config
   - Confirm correct behavior in file and stdout mode
   - Add mock support for testing chunk boundaries or filtering

This wrapper is part of a production Electron app — make sure it's clean, production-safe, and error-tolerant.

Why This Approach Works: Technical and Business Alignment

Technical Wins:

  • 4 weeks vs. 8-10 weeks implementation time (enhancement vs. rebuild)
  • Zero licensing complexity (native macOS frameworks)
  • Zero binary bloat (uses system-provided Core Audio)
  • Proven reliability (building on working foundation)
  • Real-time processing capability for chunking

Business Wins:

  • No compliance risk from external audio libraries
  • Faster time to market with incremental enhancement
  • Lower technical debt than adding new dependencies
  • Easier maintenance with familiar Swift codebase
  • User trust preserved through reliable audio quality

Product Wins:

  • Chunking support eliminates single points of failure for long recordings
  • Intelligent silence detection reduces wasted processing time
  • Contextual formatter preservation keeps our finely-tuned paragraph algorithm intact
  • Backward compatibility ensures existing functionality remains untouched

The Bigger Lesson: Enhancement > Replacement

This project taught me something important about technical decision-making: the best solution isn’t always building something new. Sometimes it’s recognizing what you already have and making it better.

Our Swift CLI was already:

  • ✅ Working reliably in production
  • ✅ Using the right frameworks (Core Audio/AVFoundation)
  • ✅ Producing the right output format (16kHz mono PCM)
  • ✅ Commercially compliant with zero licensing issues

The “enhancement mindset” turned a potentially complex FFmpeg integration into a straightforward Core Audio feature addition. Same quality improvement, fraction of the risk.

Implementation Reality: The Next 40 Hours

Here’s what the actual work looks like:

Week 1-2: Swift CLI Enhancement

  • Add AVAudioEngine preprocessing pipeline
  • Implement CLI flag parsing for new options
  • Add chunking logic with intelligent boundary detection
  • Write comprehensive XCTest suite for all new features

Week 3: Node.js Integration

  • Extend TypeScript interfaces for new audio options
  • Update spawn command building logic
  • Add Vitest test coverage for flag generation and edge cases
  • Integration testing with existing transcription pipeline

Week 4: Testing & Polish

  • End-to-end testing with real recordings
  • Performance optimization for chunking workflows
  • Documentation updates and final production validation
  • Zero disruption to existing users during rollout

The Systematic Mindset

What made this decision process work was treating technical architecture like a business decision:

  1. Analyze true requirements (commercial licensing, zero dependencies)
  2. Evaluate hidden costs (maintenance, compliance, integration complexity)
  3. Leverage existing assets (working Swift CLI + Core Audio foundation)
  4. Plan incremental delivery (enhance, don’t replace)
  5. Validate with systematic prompts (AI-assisted technical due diligence)

The result? A solution that’s technically sound, commercially viable, and delivers faster than the “obvious” alternative.

Sometimes the best engineering decision is recognizing when you’re already most of the way there.


This is part of our ongoing series about building production-quality voice transcription software. The complete implementation plan and technical details are documented in our Core Audio Enhancement Strategy.