chromaprint-fixed
Version:
A JavaScript implementation of AcoustID Chromaprint
140 lines (104 loc) • 5.77 kB
HTML
<html>
<head>
<title>chroma.coffee</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
<link rel="stylesheet" media="all" href="../docco.css" />
</head>
<body>
<div id="container">
<div id="background"></div>
<ul id="jump_to">
<li>
<a class="large" href="javascript:void(0);">Jump To …</a>
<a class="small" href="javascript:void(0);">+</a>
<div id="jump_wrapper">
<div id="jump_page_wrapper">
<div id="jump_page">
<a class="source" href="algorithms.html">
src/algorithms.coffee
</a>
<a class="source" href="calculator.html">
src/calculator.coffee
</a>
<a class="source" href="chroma.html">
src/chroma.coffee
</a>
<a class="source" href="fpcalc.html">
src/fpcalc.coffee
</a>
<a class="source" href="silenceRemover.html">
src/silenceRemover.coffee
</a>
</div>
</div>
</li>
</ul>
<ul class="sections">
<li id="title">
<div class="annotation">
<h1>chroma.coffee</h1>
</div>
</li>
<li id="section-1">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-1">¶</a>
</div>
</div>
<div class="content"><div class='highlight'><pre>@chromaprint ?= {}
NUM_BANDS = <span class="hljs-number">12</span>
log2 = Math.log(<span class="hljs-number">2</span>)
<span class="hljs-function">
<span class="hljs-title">freqToOctave</span> = <span class="hljs-params">(freq, base = <span class="hljs-number">440</span> / <span class="hljs-number">16.0</span>)</span> -></span>
Math.log(freq / base) / log2
<span class="hljs-function">
<span class="hljs-title">chroma</span> = <span class="hljs-params">(minFreq, maxFreq, frameSize, sampleRate, interpolate)</span> -></span>
notes = []
features = [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]
<span class="hljs-function">
<span class="hljs-title">freqToIndex</span> = <span class="hljs-params">(frq)</span> -></span> Math.round(frameSize * frq / sampleRate)
<span class="hljs-function"> <span class="hljs-title">indexToFreq</span> = <span class="hljs-params">(idx)</span> -></span> (idx * sampleRate) / frameSize
<span class="hljs-function"> <span class="hljs-title">indexToOctave</span> = <span class="hljs-params">(i)</span> -></span> freqToOctave(indexToFreq(i))
minIndex = Math.max(<span class="hljs-number">1</span>, freqToIndex(minFreq))
maxIndex = Math.min(frameSize / <span class="hljs-number">2</span>, freqToIndex(maxFreq))
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> [minIndex...maxIndex]
octave = indexToOctave(i)
notes[i] = NUM_BANDS * (octave - Math.floor(octave))
(frame) ->
<span class="hljs-function"> <span class="hljs-title">energy</span> = <span class="hljs-params">(i)</span> -></span> frame[i] ? <span class="hljs-number">0</span> <span class="hljs-comment"># null/false/undefined entries are 0</span>
<span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> [minIndex...maxIndex]
e = energy(i)
note = notes[i]
unit = Math.floor(note)
fraction = note - unit
<span class="hljs-keyword">if</span> interpolate</pre></div></div>
</li>
<li id="section-2">
<div class="annotation">
<div class="pilwrap ">
<a class="pilcrow" href="#section-2">¶</a>
</div>
<p>we apply the fractional note to the neighbouring feature</p>
</div>
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> fraction < <span class="hljs-number">0.5</span>
unit2 = (unit + NUM_BANDS - <span class="hljs-number">1</span>) % NUM_BANDS
a = <span class="hljs-number">0.5</span> + fraction
<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> fraction > <span class="hljs-number">0.5</span>
unit2 = (unit + <span class="hljs-number">1</span>) % NUM_BANDS
a = <span class="hljs-number">1.5</span> - fraction
<span class="hljs-keyword">else</span>
unit2 = unit
a = <span class="hljs-number">1.0</span>
features[unit] += e * a
features[unit2] += e * (<span class="hljs-number">1</span> - a)
<span class="hljs-keyword">else</span>
features[unit] += e
features
@chromaprint.chroma = chroma</pre></div></div>
</li>
</ul>
</div>
</body>
</html>