<?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: Niv Dvir</title>
    <description>The latest articles on DEV Community by Niv Dvir (@nivdvir).</description>
    <link>https://dev.to/nivdvir</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3838336%2Fdb2e5a42-2c89-4772-88e1-ce7f6e4aa813.png</url>
      <title>DEV Community: Niv Dvir</title>
      <link>https://dev.to/nivdvir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nivdvir"/>
    <language>en</language>
    <item>
      <title>How I Built a Cochlear Spiral Spectrogram That Visualizes Music Like the Inner Ear</title>
      <dc:creator>Niv Dvir</dc:creator>
      <pubDate>Sun, 22 Mar 2026 12:23:13 +0000</pubDate>
      <link>https://dev.to/nivdvir/how-i-built-a-cochlear-spiral-spectrogram-that-visualizes-music-like-the-inner-ear-3k49</link>
      <guid>https://dev.to/nivdvir/how-i-built-a-cochlear-spiral-spectrogram-that-visualizes-music-like-the-inner-ear-3k49</guid>
      <description>&lt;p&gt;What if you could see music the way your inner ear hears it?&lt;/p&gt;

&lt;p&gt;I built a visualization system that maps audio frequencies onto a &lt;strong&gt;Fermat spiral&lt;/strong&gt; — the same geometric curve that describes how the human cochlea arranges its frequency-sensitive hair cells. The result reveals the hidden geometry of harmony: you can literally &lt;em&gt;see&lt;/em&gt; the difference between a major and minor chord.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/66RiYBl7aQY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Idea
&lt;/h2&gt;

&lt;p&gt;Traditional spectrograms show frequency vs. time as a rectangular heatmap. They're useful but clinical — they don't capture the &lt;em&gt;feeling&lt;/em&gt; of music.&lt;/p&gt;

&lt;p&gt;The cochlea (your inner ear) isn't rectangular. It's a spiral. Low frequencies resonate at the outer end, high frequencies at the inner end — logarithmically spaced, just like musical octaves.&lt;/p&gt;

&lt;p&gt;So I asked: &lt;strong&gt;what if we visualize frequencies on an actual spiral?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Audio Analysis (scipy FFT)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;381 logarithmically-spaced frequency bins (20 Hz — 8 kHz)&lt;/li&gt;
&lt;li&gt;ISO 226 equal-loudness contours for perceptual accuracy&lt;/li&gt;
&lt;li&gt;60 FPS frame-by-frame analysis
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Simplified core: FFT → cochlear frequency mapping
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;scipy.fft&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;rfft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rfftfreq&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;analyze_frame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;44100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;381&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;spectrum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;rfft&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;freqs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rfftfreq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;samples&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sample_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Logarithmic bins: 20 Hz to 8 kHz (cochlear range)
&lt;/span&gt;    &lt;span class="n"&gt;bin_edges&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log10&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;n_bins&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;amplitudes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zeros&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_bins&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_bins&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;bin_edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freqs&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;bin_edges&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;amplitudes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spectrum&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;amplitudes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Spiral Mapping (Fermat Spiral)
&lt;/h3&gt;

&lt;p&gt;Each frequency bin gets a position on a Fermat spiral: &lt;strong&gt;r = sqrt(θ)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Low frequencies sit at the outer edge (like the cochlea's apex), high frequencies spiral inward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Map frequency bins to spiral coordinates
&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;linspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_bins&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;theta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Chromesthesia Color Mapping
&lt;/h3&gt;

&lt;p&gt;Colors follow a &lt;strong&gt;chromesthesia&lt;/strong&gt; mapping — the neurological phenomenon where people "see" sounds as colors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low frequencies (bass) → warm reds/oranges&lt;/li&gt;
&lt;li&gt;Mid frequencies (voice, guitar) → greens/yellows&lt;/li&gt;
&lt;li&gt;High frequencies (cymbals, harmonics) → cool blues/cyans&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Temporal Features (The Secret Sauce)
&lt;/h3&gt;

&lt;p&gt;Static spectrograms miss the &lt;em&gt;movement&lt;/em&gt; of music. I added 5 temporal features, each validated across &lt;strong&gt;1,704 audio samples&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Optimal parameter&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Melodic trails&lt;/td&gt;
&lt;td&gt;Short glowing trails following melody&lt;/td&gt;
&lt;td&gt;10 frames, 0.70 decay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rhythm pulses&lt;/td&gt;
&lt;td&gt;Radial pulse on beat hits&lt;/td&gt;
&lt;td&gt;0.50 intensity, 0.25 decay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harmonic auras&lt;/td&gt;
&lt;td&gt;Sustained glow for held chords&lt;/td&gt;
&lt;td&gt;4.0s blend time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Atmospheric context&lt;/td&gt;
&lt;td&gt;Background mood from 60s window&lt;/td&gt;
&lt;td&gt;0.35 influence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harmonic connections&lt;/td&gt;
&lt;td&gt;Lines between harmonically related notes&lt;/td&gt;
&lt;td&gt;Octave + fifth detection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Harmony Looks Beautiful
&lt;/h2&gt;

&lt;p&gt;This is the magical part. When notes are &lt;strong&gt;harmonically related&lt;/strong&gt; (octaves, fifths, thirds), they land at &lt;strong&gt;symmetric positions&lt;/strong&gt; on the spiral. A major chord creates a visually balanced, symmetric pattern. Dissonance creates asymmetric, chaotic (but still beautiful) patterns.&lt;/p&gt;

&lt;p&gt;Different musical traditions create remarkably different visual signatures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Classical harmony&lt;/strong&gt; → orderly radial symmetry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arabic maqam&lt;/strong&gt; → quarter-tone asymmetry with unique geometric beauty&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EDM/electronic&lt;/strong&gt; → explosive, pulsing energy patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/bhgEEtMXEJ0"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It: The Wellspring
&lt;/h2&gt;

&lt;p&gt;I also built a crowdsourcing platform called &lt;a href="https://synesthesia-labeler.onrender.com" rel="noopener noreferrer"&gt;&lt;strong&gt;The Wellspring&lt;/strong&gt;&lt;/a&gt; where people can rate how well these visualizations capture the music. The goal: build an open dataset for AI-powered audio visualization evaluation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Audio analysis:&lt;/strong&gt; scipy (FFT), librosa&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering:&lt;/strong&gt; PIL (2D), PyVista (3D optional)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video encoding:&lt;/strong&gt; FFmpeg (H.264, CRF 18, 60 FPS)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web platform:&lt;/strong&gt; React 18 + TypeScript, Node/Express, PostgreSQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm working on browser-based creation tools so anyone can create their own audio-visual harmony — no installation needed. The vision: a global community of creators exploring the intersection of sound and moving image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The ancient dance between rhythm and movement, renewed with modern tools.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Channel: &lt;a href="https://www.youtube.com/@NivDvir-ND" rel="noopener noreferrer"&gt;youtube.com/@NivDvir-ND&lt;/a&gt;&lt;br&gt;
The Wellspring: &lt;a href="https://synesthesia-labeler.onrender.com" rel="noopener noreferrer"&gt;synesthesia-labeler.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear your thoughts — especially from anyone working on audio visualization, creative coding, or signal processing!&lt;/p&gt;

</description>
      <category>audio</category>
    </item>
  </channel>
</rss>
