<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Oscar Madera</title>
    <description>The latest articles on DEV Community by Oscar Madera (@oscarbol09).</description>
    <link>https://dev.to/oscarbol09</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4192940%2Fbbb0d361-5a86-4a91-801e-9cf5263febfd.jpg</url>
      <title>DEV Community: Oscar Madera</title>
      <link>https://dev.to/oscarbol09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oscarbol09"/>
    <language>en</language>
    <item>
      <title>SpotForge: 3 Facts In, a Broadcast-Ready Radio Ad Out (Gemma + ElevenLabs)</title>
      <dc:creator>Oscar Madera</dc:creator>
      <pubDate>Mon, 19 Oct 2026 02:01:48 +0000</pubDate>
      <link>https://dev.to/oscarbol09/spotforge-3-facts-in-a-broadcast-ready-radio-ad-out-gemma-elevenlabs-1cah</link>
      <guid>https://dev.to/oscarbol09/spotforge-3-facts-in-a-broadcast-ready-radio-ad-out-gemma-elevenlabs-1cah</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SpotForge&lt;/strong&gt; turns three facts about a local business (name, offer, call to action) into a 30-second commercial audio ad, with copy, voice, and a music bed, in about 15 seconds.&lt;/p&gt;

&lt;p&gt;The people who would pay are freelancers who manage social media for neighborhood shops. A pizzeria wants a Tuesday 2x1 promo for Instagram Stories, but an agency charges hundreds of dollars for a single spot, and a phone voice note sounds amateur. SpotForge fills that gap.&lt;/p&gt;

&lt;p&gt;The pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gemma 4&lt;/strong&gt; writes an AIDA script (Attention, Interest, Desire, Action) with a word budget based on speech rate (~2.5 words/s in Spanish, ~2.8 in English).&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;deterministic normalizer&lt;/strong&gt; turns &lt;code&gt;2x1&lt;/code&gt;, &lt;code&gt;$15&lt;/code&gt;, &lt;code&gt;30%&lt;/code&gt;, and phone numbers into spoken words, because TTS engines mangle them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ElevenLabs&lt;/strong&gt; renders the voiceover.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mutagen&lt;/strong&gt; measures the real MP3 duration. If it overshoots the target by more than 3 seconds, one adaptive retry runs with a smaller word budget.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FFmpeg&lt;/strong&gt; mixes in a CC0 music bed with ducking and a fadeout.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The business math&lt;/strong&gt; (ElevenLabs Starter plan, $6/month at the time of writing; check current pricing): roughly $0.08–$0.12 of voice cost per spot, sold at $5–$15. A freelancer with 5 clients and 2 spots per week makes about $150/month for $6 of tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Live app: &lt;a href="https://spotforge.onrender.com" rel="noopener noreferrer"&gt;spotforge.onrender.com&lt;/a&gt; &lt;em&gt;(free Render tier: the first load can take about a minute to wake up)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three spots generated end-to-end:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Business&lt;/th&gt;
&lt;th&gt;Voice&lt;/th&gt;
&lt;th&gt;Duration&lt;/th&gt;
&lt;th&gt;Audio&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pizzería Don Mario&lt;/td&gt;
&lt;td&gt;George&lt;/td&gt;
&lt;td&gt;28.4s&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/oscarbol09/spotforge/raw/master/static/audio/demo_pizzeria.mp3" rel="noopener noreferrer"&gt;demo_pizzeria.mp3&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barbería El Bigote&lt;/td&gt;
&lt;td&gt;Liam&lt;/td&gt;
&lt;td&gt;31.9s&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/oscarbol09/spotforge/raw/master/static/audio/demo_barber.mp3" rel="noopener noreferrer"&gt;demo_barber.mp3&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apex Auto Repair&lt;/td&gt;
&lt;td&gt;Roger&lt;/td&gt;
&lt;td&gt;27.3s&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/oscarbol09/spotforge/raw/master/static/audio/demo_autorepair.mp3" rel="noopener noreferrer"&gt;demo_autorepair.mp3&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A script Gemma wrote for the pizzeria (Spanish):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"¿Buscas el auténtico sabor de Italia sin salir de casa? En Pizzería Don Mario, usamos horno de leña y masa madre... Los martes y jueves tenemos dos por uno en todas nuestras pizzas familiares... Llama al cinco cinco cinco, cero uno, nueve dos."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/oscarbol09" rel="noopener noreferrer"&gt;
        oscarbol09
      &lt;/a&gt; / &lt;a href="https://github.com/oscarbol09/spotforge" rel="noopener noreferrer"&gt;
        spotforge
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Commercial audio ad generator for local businesses using Google Gemma open weights, ElevenLabs studio voice synthesis, and FFmpeg audio mixing.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;SpotForge&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Turn three basic facts about a local business into a broadcast-ready 30-second commercial audio ad using Google Gemma open weights, deterministic text normalization, ElevenLabs studio voice synthesis, and FFmpeg audio mixing.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://www.python.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ddb318d0fb787b3b555b3a396bb359732f25df2a08098667dab708fad3cb29d9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f507974686f6e2d332e31322d626c75652e737667" alt="Python 3.12"&gt;&lt;/a&gt;
&lt;a href="https://fastapi.tiangolo.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e6d8c7e3084bfbde24d54933cc93597119f6eb018e3e46b6b15eb34f08ebee41/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466173744150492d302e3131352b2d677265656e2e737667" alt="FastAPI"&gt;&lt;/a&gt;
&lt;a href="https://ai.google.dev/gemma" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5edd0527f311558253faac732cf1e04c00e82c2fda820ca0e651c1985df41f35/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d6f64656c2d47656d6d6125323034253230284f70656e25323057656967687473292d6f72616e67652e737667" alt="Model: Gemma 4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is SpotForge?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Neighborhood businesses—pizzerias, barbershops, auto mechanics, dental practices—frequently need high-impact promotional audio for social video (Instagram Stories, TikTok Ads), local radio, or telephone hold messaging.&lt;/p&gt;
&lt;p&gt;Most cannot afford traditional production:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Creative Agencies and Studios&lt;/strong&gt;: Cost $300 to $800 per 30-second spot for scriptwriting, studio recording, and voice talent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Recording&lt;/strong&gt;: Cellphone microphone recordings lack commercial energy, proper breathing pauses, and background music, leading listeners to scroll away.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;SpotForge&lt;/strong&gt; converts &lt;strong&gt;3 business inputs&lt;/strong&gt; (business name, core offer, and call to action) into an air-ready commercial ad in seconds:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AIDA Ad Copywriting&lt;/strong&gt;: Google Gemma 4 generates a structured script (Attention -&amp;gt; Interest -&amp;gt; Desire -&amp;gt; Action) constrained by speech cadence targets (~2.5 words/second in Spanish…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/oscarbol09/spotforge" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;FastAPI backend, a vanilla JS single-page frontend, MIT license, 7 architecture decision records in &lt;code&gt;docs/adr/&lt;/code&gt;, and a pytest suite (32 tests).&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open-weight copywriting:&lt;/strong&gt; Gemma 4 (&lt;code&gt;gemma-4-26b-a4b-it&lt;/code&gt;) behind a &lt;code&gt;BaseLLMBackend&lt;/code&gt; interface. It runs through Google AI Studio by default, or fully local through Ollama (&lt;code&gt;LLM_BACKEND=ollama&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One structured prompt&lt;/strong&gt; combining role, AIDA constraints, and word budget. Gemma also returns its reasoning parts, which I filter out so only the spoken copy reaches the TTS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why a rule-based normalizer instead of asking the LLM:&lt;/strong&gt; regex plus &lt;code&gt;num2words&lt;/code&gt; gives the same result every time, and phone numbers get grouped so they sound like an announcer, not a robot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real duration control:&lt;/strong&gt; LLM word counts are only an estimate, so I measure the actual MP3 and retry once if needed. Voices read at different speeds, so this mattered more than I expected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FFmpeg mixing&lt;/strong&gt; with looped CC0 beds, 15% ducking under the voice, and a 2-second fade. If FFmpeg is missing, the app degrades to voice-only with a warning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment and cost protection:&lt;/strong&gt; a &lt;code&gt;Dockerfile&lt;/code&gt; that ships FFmpeg, a &lt;code&gt;render.yaml&lt;/code&gt; blueprint with a health check at &lt;code&gt;/api/health&lt;/code&gt;, and a per-client rate limiter so a public demo can't drain my API quota.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy notice:&lt;/strong&gt; the footer tells users their text is processed by Google AI Studio and ElevenLabs, and generated audio is deleted automatically after 24 hours (covered by unit tests).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Margins.&lt;/strong&gt; A solo freelancer can't absorb per-token pricing that scales with every script and every client. Open weights keep the copywriting step at zero marginal cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability.&lt;/strong&gt; I'm not tied to one vendor's endpoint or pricing. The same prompt runs on a hosted Gemma or on a local Ollama instance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy, with a limit I want to be upfront about.&lt;/strong&gt; With Ollama, the script generation, which handles unreleased promos and discount codes, can stay entirely on the freelancer's laptop. The voice step is the exception: the final text is sent to ElevenLabs, which is a closed service. Making that step open is the natural next step for this project.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fine-tuning potential.&lt;/strong&gt; With open weights, I could fine-tune on regional radio copy and local slang, which a general-purpose API handles poorly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Gemma:&lt;/strong&gt; Gemma 4 for AIDA copywriting, with cloud and local Ollama backends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of ElevenLabs:&lt;/strong&gt; Multilingual v2 voiceover, curated voices, character-usage tracking, and real-duration calibration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Use of Render:&lt;/strong&gt; deployed on Render with a Dockerfile (FFmpeg included), &lt;code&gt;render.yaml&lt;/code&gt; blueprint, and health checks.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
