Spaces:
Sleeping
Sleeping
Download examples/index.html from k-l-lambda/speaking-midi: direct link, hf CLI and curl.
- Browser
- Download file 32 kB
-
https://huggingface.co/spaces/k-l-lambda/speaking-midi/resolve/main/examples/index.html
- Command line
-
hf download hf://spaces/k-l-lambda/speaking-midi/examples/index.html
-
curl -L -o index.html https://huggingface.co/spaces/k-l-lambda/speaking-midi/resolve/main/examples/index.html
32 kB
| <html lang="en"> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>Speaking MIDI · Audio demos</title> | |
| <style> | |
| body{font:16px/1.6 system-ui,sans-serif;color:#203040;background:#f5f7fa;max-width:1120px;margin:auto;padding:24px} | |
| h1,h2,h3{line-height:1.2}h1{font-size:2.5rem}section{background:white;border:1px solid #d9e1ea;border-radius:16px;padding:24px;margin:28px 0}a{color:#075eb0}img,canvas{width:100%;height:auto}canvas{height:320px;cursor:crosshair;border:1px solid #d9e1ea}audio{display:block;width:100%;margin:8px 0}.players{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px}details{margin:18px 0}label{font-weight:600}footer{font-size:.9rem;color:#536273}.velocity-key{display:flex;align-items:center;gap:8px;font-size:.85rem}.velocity-key span{display:inline-block;width:140px;height:10px;background:linear-gradient(to right,hsl(240 72% 46%),hsl(191 72% 46%),hsl(142 72% 46%),hsl(94 72% 46%),hsl(45 72% 46%));border-radius:4px} | |
| </style> | |
| <h1>Speaking MIDI</h1> | |
| <p>Two approximately eight-second Qwen3-TTS recordings, fitted using only the Grand Piano preset in <code>gm.sf3</code>. Both use Qwen3-TTS 1.7B VoiceDesign with the same recorded voice-design instruction. Compare the speech with its piano reconstruction, then inspect the exported MIDI.</p> | |
| <p>Listen before revealing the transcript. Lower spectral error does not establish speech intelligibility. These longer examples have not received ASR or human listening evaluation. Playback uses saved audio; no model download or external service is required.</p> | |
| <details><summary>Voice description used for both languages</summary><p lang="zh">一位温柔自信的年轻女性,声音清晰,语气亲切,表达轻快而富有感染力。</p><p>This exact instruction was supplied to VoiceDesign for both recordings.</p></details> | |
| <section> | |
| <h2>English · 7.84 s</h2> | |
| <p>148 MIDI notes · log-band error 0.4577 → 0.3875 (15.3% reduction).</p> | |
| <div class="players"><label>Target speech (common RMS)<audio controls preload="metadata" src="en/target.wav"></audio></label><label>Spectral baseline<audio controls preload="metadata" src="en/baseline.wav"></audio></label><label>Fitted piano<audio controls preload="metadata" src="en/refined.wav" data-piano=en></audio></label></div> | |
| <details><summary>Reveal transcript</summary><p lang="en">Good morning, everyone. The warm sunlight is streaming through the open window. Listen carefully as the piano tries to repeat each of these words.</p></details> | |
| <p><a href="en/refined.mid">Download MIDI</a> · <a href="en/source.wav">Original Qwen output</a> · <a href="en/metrics.json">Metrics</a></p> | |
| <h3>MIDI piano roll</h3><p>Play the fitted piano to follow the cursor. Click the roll to seek. Colors show velocity; rectangles show key-hold duration, not release tails.</p> | |
| <p class="velocity-key">Velocity: 1 <span aria-hidden="true"></span> 127</p> | |
| <canvas data-roll="en" role="img" aria-label="English MIDI piano roll"></canvas> | |
| <noscript><img src="en/piano-roll.png" alt="English piano roll"></noscript> | |
| <script type="application/json" id="notes-en">{"seconds": 8.34, "notes": [{"pitch": 104, "velocity": 69, "start": 0.07, "duration": 0.04000000000000001}, {"pitch": 64, "velocity": 99, "start": 0.02, "duration": 0.1}, {"pitch": 61, "velocity": 29, "start": 0.09000000000000001, "duration": 0.06000000000000001}, {"pitch": 65, "velocity": 29, "start": 0.15000000000000002, "duration": 0.06}, {"pitch": 66, "velocity": 29, "start": 0.0, "duration": 0.24000000000000002}, {"pitch": 78, "velocity": 69, "start": 0.2, "duration": 0.04000000000000001}, {"pitch": 85, "velocity": 59, "start": 0.2, "duration": 0.06}, {"pitch": 86, "velocity": 39, "start": 0.23, "duration": 0.060000000000000026}, {"pitch": 79, "velocity": 29, "start": 0.25, "duration": 0.06000000000000005}, {"pitch": 100, "velocity": 39, "start": 0.27, "duration": 0.06000000000000005}, {"pitch": 101, "velocity": 49, "start": 0.29000000000000004, "duration": 0.06000000000000005}, {"pitch": 98, "velocity": 69, "start": 0.31000000000000005, "duration": 0.06000000000000005}, {"pitch": 66, "velocity": 49, "start": 0.3500000000000001, "duration": 0.06000000000000005}, {"pitch": 67, "velocity": 99, "start": 0.2, "duration": 0.22000000000000014}, {"pitch": 65, "velocity": 29, "start": 0.3800000000000001, "duration": 0.06000000000000005}, {"pitch": 81, "velocity": 39, "start": 0.5000000000000001, "duration": 0.06000000000000005}, {"pitch": 102, "velocity": 49, "start": 0.5000000000000001, "duration": 0.06000000000000005}, {"pitch": 61, "velocity": 49, "start": 0.5100000000000001, "duration": 0.06000000000000005}, {"pitch": 98, "velocity": 49, "start": 0.5100000000000001, "duration": 0.06000000000000005}, {"pitch": 103, "velocity": 49, "start": 0.5200000000000001, "duration": 0.06000000000000005}, {"pitch": 99, "velocity": 49, "start": 0.6400000000000001, "duration": 0.06000000000000005}, {"pitch": 101, "velocity": 49, "start": 0.6400000000000001, "duration": 0.06000000000000005}, {"pitch": 62, "velocity": 109, "start": 0.48000000000000015, "duration": 0.24000000000000005}, {"pitch": 80, "velocity": 59, "start": 0.5300000000000001, "duration": 0.2400000000000001}, {"pitch": 95, "velocity": 49, "start": 0.5300000000000001, "duration": 0.2400000000000001}, {"pitch": 84, "velocity": 39, "start": 0.7300000000000002, "duration": 0.06000000000000005}, {"pitch": 60, "velocity": 89, "start": 0.6900000000000002, "duration": 0.1200000000000001}, {"pitch": 88, "velocity": 39, "start": 0.7500000000000002, "duration": 0.06000000000000005}, {"pitch": 80, "velocity": 39, "start": 0.8100000000000003, "duration": 0.06000000000000005}, {"pitch": 94, "velocity": 39, "start": 0.8100000000000003, "duration": 0.06000000000000005}, {"pitch": 61, "velocity": 39, "start": 0.8300000000000003, "duration": 0.06000000000000005}, {"pitch": 64, "velocity": 29, "start": 0.8900000000000003, "duration": 0.06000000000000005}, {"pitch": 67, "velocity": 39, "start": 0.9500000000000004, "duration": 0.040000000000000036}, {"pitch": 79, "velocity": 29, "start": 0.7600000000000002, "duration": 0.2400000000000002}, {"pitch": 66, "velocity": 29, "start": 0.8900000000000003, "duration": 0.1200000000000001}, {"pitch": 108, "velocity": 79, "start": 0.8200000000000003, "duration": 0.2400000000000002}, {"pitch": 97, "velocity": 49, "start": 0.8600000000000003, "duration": 0.2400000000000002}, {"pitch": 80, "velocity": 39, "start": 1.2800000000000005, "duration": 0.040000000000000036}, {"pitch": 73, "velocity": 39, "start": 1.2800000000000005, "duration": 0.06000000000000005}, {"pitch": 104, "velocity": 49, "start": 1.3000000000000005, "duration": 0.06000000000000005}, {"pitch": 61, "velocity": 29, "start": 1.4200000000000006, "duration": 0.06000000000000005}, {"pitch": 85, "velocity": 29, "start": 1.4300000000000006, "duration": 0.06000000000000005}, {"pitch": 60, "velocity": 69, "start": 1.2900000000000005, "duration": 0.2200000000000002}, {"pitch": 84, "velocity": 59, "start": 1.4500000000000006, "duration": 0.06000000000000005}, {"pitch": 79, "velocity": 49, "start": 1.4100000000000006, "duration": 0.1200000000000001}, {"pitch": 91, "velocity": 39, "start": 1.4700000000000006, "duration": 0.06000000000000005}, {"pitch": 59, "velocity": 69, "start": 1.5100000000000007, "duration": 0.06000000000000005}, {"pitch": 93, "velocity": 49, "start": 1.5200000000000007, "duration": 0.06000000000000005}, {"pitch": 99, "velocity": 49, "start": 1.5300000000000007, "duration": 0.06000000000000005}, {"pitch": 64, "velocity": 69, "start": 1.7500000000000007, "duration": 0.06000000000000005}, {"pitch": 83, "velocity": 39, "start": 1.7600000000000007, "duration": 0.06000000000000005}, {"pitch": 94, "velocity": 49, "start": 1.7700000000000007, "duration": 0.06000000000000005}, {"pitch": 90, "velocity": 29, "start": 1.9100000000000008, "duration": 0.06000000000000005}, {"pitch": 81, "velocity": 69, "start": 1.9300000000000008, "duration": 0.06000000000000005}, {"pitch": 61, "velocity": 59, "start": 1.9400000000000008, "duration": 0.06000000000000005}, {"pitch": 63, "velocity": 109, "start": 1.7600000000000007, "duration": 0.2400000000000002}, {"pitch": 103, "velocity": 49, "start": 1.9600000000000009, "duration": 0.06000000000000005}, {"pitch": 59, "velocity": 39, "start": 1.9800000000000009, "duration": 0.11999999999999966}, {"pitch": 57, "velocity": 39, "start": 2.0300000000000007, "duration": 0.09999999999999964}, {"pitch": 104, "velocity": 49, "start": 2.0900000000000007, "duration": 0.05999999999999961}, {"pitch": 102, "velocity": 49, "start": 2.3400000000000003, "duration": 0.05999999999999961}, {"pitch": 101, "velocity": 49, "start": 2.35, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 39, "start": 2.37, "duration": 0.05999999999999961}, {"pitch": 97, "velocity": 49, "start": 2.38, "duration": 0.05999999999999961}, {"pitch": 64, "velocity": 99, "start": 2.4699999999999993, "duration": 0.03999999999999959}, {"pitch": 65, "velocity": 29, "start": 2.499999999999999, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 29, "start": 2.5899999999999985, "duration": 0.05999999999999961}, {"pitch": 103, "velocity": 49, "start": 2.5999999999999983, "duration": 0.05999999999999961}, {"pitch": 59, "velocity": 59, "start": 2.629999999999998, "duration": 0.05999999999999961}, {"pitch": 57, "velocity": 29, "start": 2.6899999999999977, "duration": 0.23999999999999977}, {"pitch": 59, "velocity": 39, "start": 2.9199999999999977, "duration": 0.07999999999999963}, {"pitch": 103, "velocity": 49, "start": 2.9999999999999973, "duration": 0.05999999999999961}, {"pitch": 77, "velocity": 49, "start": 3.009999999999997, "duration": 0.05999999999999961}, {"pitch": 58, "velocity": 79, "start": 2.8399999999999976, "duration": 0.23999999999999888}, {"pitch": 104, "velocity": 49, "start": 3.039999999999997, "duration": 0.05999999999999961}, {"pitch": 70, "velocity": 39, "start": 2.9699999999999975, "duration": 0.21999999999999842}, {"pitch": 57, "velocity": 49, "start": 3.1499999999999964, "duration": 0.11999999999999922}, {"pitch": 59, "velocity": 49, "start": 3.159999999999996, "duration": 0.11999999999999922}, {"pitch": 61, "velocity": 29, "start": 3.259999999999996, "duration": 0.05999999999999961}, {"pitch": 64, "velocity": 69, "start": 3.2999999999999954, "duration": 0.040000000000000036}, {"pitch": 68, "velocity": 29, "start": 3.3799999999999955, "duration": 0.06000000000000005}, {"pitch": 64, "velocity": 39, "start": 3.4599999999999955, "duration": 0.05999999999999961}, {"pitch": 60, "velocity": 39, "start": 3.4899999999999953, "duration": 0.059999999999999165}, {"pitch": 66, "velocity": 69, "start": 3.3399999999999954, "duration": 0.23999999999999888}, {"pitch": 98, "velocity": 49, "start": 3.519999999999995, "duration": 0.059999999999999165}, {"pitch": 54, "velocity": 69, "start": 3.529999999999995, "duration": 0.059999999999999165}, {"pitch": 81, "velocity": 69, "start": 3.5399999999999947, "duration": 0.059999999999999165}, {"pitch": 80, "velocity": 49, "start": 3.5799999999999943, "duration": 0.05999999999999961}, {"pitch": 104, "velocity": 49, "start": 3.5799999999999943, "duration": 0.23999999999999977}, {"pitch": 107, "velocity": 49, "start": 3.589999999999994, "duration": 0.23999999999999977}, {"pitch": 108, "velocity": 49, "start": 3.639999999999994, "duration": 0.23999999999999977}, {"pitch": 107, "velocity": 49, "start": 3.8599999999999937, "duration": 0.1200000000000001}, {"pitch": 61, "velocity": 69, "start": 4.369999999999994, "duration": 0.040000000000000036}, {"pitch": 81, "velocity": 39, "start": 4.369999999999994, "duration": 0.05999999999999961}, {"pitch": 97, "velocity": 49, "start": 4.399999999999994, "duration": 0.05999999999999961}, {"pitch": 65, "velocity": 99, "start": 4.529999999999994, "duration": 0.03999999999999915}, {"pitch": 98, "velocity": 39, "start": 4.539999999999994, "duration": 0.05999999999999961}, {"pitch": 64, "velocity": 39, "start": 4.559999999999993, "duration": 0.05999999999999961}, {"pitch": 63, "velocity": 29, "start": 4.569999999999993, "duration": 0.05999999999999961}, {"pitch": 103, "velocity": 49, "start": 4.679999999999993, "duration": 0.0600000000000005}, {"pitch": 102, "velocity": 49, "start": 4.709999999999993, "duration": 0.0600000000000005}, {"pitch": 107, "velocity": 79, "start": 4.739999999999993, "duration": 0.05999999999999961}, {"pitch": 64, "velocity": 69, "start": 4.779999999999993, "duration": 0.03999999999999915}, {"pitch": 101, "velocity": 49, "start": 4.789999999999993, "duration": 0.05999999999999961}, {"pitch": 66, "velocity": 99, "start": 4.819999999999992, "duration": 0.040000000000000036}, {"pitch": 84, "velocity": 39, "start": 4.819999999999992, "duration": 0.040000000000000036}, {"pitch": 99, "velocity": 49, "start": 4.8499999999999925, "duration": 0.05999999999999961}, {"pitch": 97, "velocity": 49, "start": 4.859999999999992, "duration": 0.05999999999999961}, {"pitch": 79, "velocity": 39, "start": 4.869999999999992, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 39, "start": 5.019999999999992, "duration": 0.040000000000000036}, {"pitch": 63, "velocity": 39, "start": 5.009999999999992, "duration": 0.05999999999999961}, {"pitch": 69, "velocity": 39, "start": 5.099999999999992, "duration": 0.040000000000000036}, {"pitch": 55, "velocity": 49, "start": 5.139999999999992, "duration": 0.11999999999999922}, {"pitch": 56, "velocity": 59, "start": 5.049999999999992, "duration": 0.23999999999999932}, {"pitch": 107, "velocity": 49, "start": 5.239999999999991, "duration": 0.05999999999999961}, {"pitch": 58, "velocity": 39, "start": 5.389999999999991, "duration": 0.040000000000000036}, {"pitch": 104, "velocity": 49, "start": 5.399999999999991, "duration": 0.0600000000000005}, {"pitch": 103, "velocity": 49, "start": 5.499999999999991, "duration": 0.05999999999999961}, {"pitch": 60, "velocity": 39, "start": 5.5699999999999905, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 69, "start": 5.61999999999999, "duration": 0.05999999999999961}, {"pitch": 80, "velocity": 49, "start": 5.62999999999999, "duration": 0.05999999999999961}, {"pitch": 64, "velocity": 99, "start": 5.68999999999999, "duration": 0.03999999999999915}, {"pitch": 107, "velocity": 79, "start": 5.66999999999999, "duration": 0.05999999999999872}, {"pitch": 97, "velocity": 49, "start": 5.6999999999999895, "duration": 0.05999999999999961}, {"pitch": 65, "velocity": 79, "start": 5.719999999999989, "duration": 0.05999999999999961}, {"pitch": 62, "velocity": 39, "start": 5.7899999999999885, "duration": 0.05999999999999961}, {"pitch": 80, "velocity": 39, "start": 5.809999999999988, "duration": 0.040000000000000036}, {"pitch": 60, "velocity": 39, "start": 5.809999999999988, "duration": 0.05999999999999961}, {"pitch": 104, "velocity": 49, "start": 5.809999999999988, "duration": 0.05999999999999961}, {"pitch": 102, "velocity": 49, "start": 5.9599999999999875, "duration": 0.05999999999999961}, {"pitch": 97, "velocity": 49, "start": 5.969999999999987, "duration": 0.05999999999999961}, {"pitch": 58, "velocity": 69, "start": 6.019999999999987, "duration": 0.03999999999999915}, {"pitch": 81, "velocity": 39, "start": 6.039999999999987, "duration": 0.05999999999999961}, {"pitch": 104, "velocity": 49, "start": 6.059999999999986, "duration": 0.05999999999999961}, {"pitch": 108, "velocity": 69, "start": 6.229999999999986, "duration": 0.05999999999999961}, {"pitch": 59, "velocity": 69, "start": 6.249999999999986, "duration": 0.05999999999999961}, {"pitch": 99, "velocity": 39, "start": 6.4299999999999855, "duration": 0.040000000000000036}, {"pitch": 61, "velocity": 39, "start": 6.689999999999985, "duration": 0.040000000000000036}, {"pitch": 108, "velocity": 99, "start": 6.839999999999986, "duration": 0.0600000000000005}, {"pitch": 104, "velocity": 49, "start": 6.869999999999986, "duration": 0.0600000000000005}, {"pitch": 62, "velocity": 39, "start": 6.979999999999986, "duration": 0.21999999999999975}, {"pitch": 75, "velocity": 29, "start": 7.209999999999986, "duration": 0.0600000000000005}, {"pitch": 64, "velocity": 89, "start": 7.239999999999986, "duration": 0.0600000000000005}, {"pitch": 77, "velocity": 39, "start": 7.269999999999986, "duration": 0.040000000000000036}, {"pitch": 66, "velocity": 69, "start": 7.2999999999999865, "duration": 0.05999999999999961}, {"pitch": 93, "velocity": 29, "start": 7.2999999999999865, "duration": 0.05999999999999961}, {"pitch": 78, "velocity": 39, "start": 7.319999999999986, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 39, "start": 7.409999999999986, "duration": 0.040000000000000036}]}</script> | |
| <h3>Shared-scale spectrogram comparison</h3><img src="en/spectrogram.png" alt="English: target, baseline, dictionary and refined spectrograms"> | |
| </section> | |
| <section> | |
| <h2>Chinese · 7.60 s</h2> | |
| <p>117 MIDI notes · log-band error 0.4480 → 0.3923 (12.4% reduction).</p> | |
| <div class="players"><label>Target speech (common RMS)<audio controls preload="metadata" src="zh/target.wav"></audio></label><label>Spectral baseline<audio controls preload="metadata" src="zh/baseline.wav"></audio></label><label>Fitted piano<audio controls preload="metadata" src="zh/refined.wav" data-piano=zh></audio></label></div> | |
| <details><summary>Reveal transcript</summary><p lang="zh">清晨的阳光照进窗户,微风轻轻吹过。请仔细听,钢琴正在模仿我说话。</p></details> | |
| <p><a href="zh/refined.mid">Download MIDI</a> · <a href="zh/source.wav">Original Qwen output</a> · <a href="zh/metrics.json">Metrics</a></p> | |
| <h3>MIDI piano roll</h3><p>Play the fitted piano to follow the cursor. Click the roll to seek. Colors show velocity; rectangles show key-hold duration, not release tails.</p> | |
| <p class="velocity-key">Velocity: 1 <span aria-hidden="true"></span> 127</p> | |
| <canvas data-roll="zh" role="img" aria-label="Chinese MIDI piano roll"></canvas> | |
| <noscript><img src="zh/piano-roll.png" alt="Chinese piano roll"></noscript> | |
| <script type="application/json" id="notes-zh">{"seconds": 8.1, "notes": [{"pitch": 62, "velocity": 39, "start": 0.12000000000000001, "duration": 0.04000000000000002}, {"pitch": 101, "velocity": 49, "start": 0.1, "duration": 0.060000000000000026}, {"pitch": 61, "velocity": 39, "start": 0.15000000000000002, "duration": 0.06}, {"pitch": 104, "velocity": 49, "start": 0.15000000000000002, "duration": 0.06}, {"pitch": 103, "velocity": 69, "start": 0.25, "duration": 0.06}, {"pitch": 98, "velocity": 49, "start": 0.27, "duration": 0.06}, {"pitch": 59, "velocity": 109, "start": 0.26, "duration": 0.24}, {"pitch": 97, "velocity": 49, "start": 0.41000000000000003, "duration": 0.12}, {"pitch": 58, "velocity": 49, "start": 0.33, "duration": 0.24000000000000005}, {"pitch": 75, "velocity": 39, "start": 0.52, "duration": 0.06000000000000005}, {"pitch": 80, "velocity": 69, "start": 0.53, "duration": 0.06000000000000005}, {"pitch": 56, "velocity": 109, "start": 0.51, "duration": 0.1200000000000001}, {"pitch": 81, "velocity": 39, "start": 0.5700000000000001, "duration": 0.06000000000000005}, {"pitch": 104, "velocity": 49, "start": 0.5700000000000001, "duration": 0.06000000000000005}, {"pitch": 83, "velocity": 29, "start": 0.7000000000000002, "duration": 0.06000000000000005}, {"pitch": 87, "velocity": 49, "start": 0.7400000000000002, "duration": 0.1200000000000001}, {"pitch": 78, "velocity": 69, "start": 0.7900000000000003, "duration": 0.08000000000000007}, {"pitch": 83, "velocity": 39, "start": 0.7600000000000002, "duration": 0.14000000000000012}, {"pitch": 103, "velocity": 39, "start": 0.8500000000000003, "duration": 0.06000000000000005}, {"pitch": 59, "velocity": 99, "start": 0.7300000000000002, "duration": 0.2200000000000002}, {"pitch": 102, "velocity": 39, "start": 1.0000000000000004, "duration": 0.06000000000000005}, {"pitch": 59, "velocity": 69, "start": 1.0500000000000005, "duration": 0.040000000000000036}, {"pitch": 78, "velocity": 39, "start": 1.0600000000000005, "duration": 0.040000000000000036}, {"pitch": 83, "velocity": 39, "start": 1.0400000000000005, "duration": 0.06000000000000005}, {"pitch": 82, "velocity": 49, "start": 1.0700000000000005, "duration": 0.06000000000000005}, {"pitch": 92, "velocity": 29, "start": 1.0800000000000005, "duration": 0.06000000000000005}, {"pitch": 55, "velocity": 39, "start": 1.2200000000000006, "duration": 0.040000000000000036}, {"pitch": 107, "velocity": 99, "start": 1.0200000000000005, "duration": 0.2400000000000002}, {"pitch": 103, "velocity": 49, "start": 1.2200000000000006, "duration": 0.06000000000000005}, {"pitch": 57, "velocity": 39, "start": 1.1100000000000005, "duration": 0.2400000000000002}, {"pitch": 97, "velocity": 39, "start": 1.3000000000000007, "duration": 0.06000000000000005}, {"pitch": 98, "velocity": 39, "start": 1.3400000000000007, "duration": 0.06000000000000005}, {"pitch": 104, "velocity": 49, "start": 1.3500000000000008, "duration": 0.06000000000000005}, {"pitch": 83, "velocity": 39, "start": 1.3800000000000008, "duration": 0.06000000000000005}, {"pitch": 87, "velocity": 39, "start": 1.4100000000000008, "duration": 0.040000000000000036}, {"pitch": 59, "velocity": 59, "start": 1.3800000000000008, "duration": 0.1200000000000001}, {"pitch": 61, "velocity": 39, "start": 1.4800000000000009, "duration": 0.06000000000000005}, {"pitch": 108, "velocity": 79, "start": 1.3100000000000007, "duration": 0.2400000000000002}, {"pitch": 79, "velocity": 39, "start": 1.4100000000000008, "duration": 0.2400000000000002}, {"pitch": 68, "velocity": 39, "start": 1.630000000000001, "duration": 0.040000000000000036}, {"pitch": 81, "velocity": 39, "start": 1.550000000000001, "duration": 0.1200000000000001}, {"pitch": 54, "velocity": 59, "start": 1.620000000000001, "duration": 0.06000000000000005}, {"pitch": 52, "velocity": 39, "start": 1.650000000000001, "duration": 0.040000000000000036}, {"pitch": 104, "velocity": 49, "start": 2.490000000000001, "duration": 0.06000000000000005}, {"pitch": 60, "velocity": 59, "start": 2.4400000000000013, "duration": 0.11999999999999966}, {"pitch": 59, "velocity": 29, "start": 2.530000000000001, "duration": 0.05999999999999961}, {"pitch": 103, "velocity": 49, "start": 2.530000000000001, "duration": 0.05999999999999961}, {"pitch": 107, "velocity": 49, "start": 2.6000000000000005, "duration": 0.06000000000000005}, {"pitch": 80, "velocity": 29, "start": 2.6700000000000004, "duration": 0.05999999999999961}, {"pitch": 60, "velocity": 99, "start": 2.7, "duration": 0.03999999999999959}, {"pitch": 79, "velocity": 49, "start": 2.71, "duration": 0.05999999999999961}, {"pitch": 59, "velocity": 29, "start": 2.8099999999999996, "duration": 0.06000000000000005}, {"pitch": 61, "velocity": 39, "start": 2.9999999999999996, "duration": 0.040000000000000036}, {"pitch": 107, "velocity": 79, "start": 2.9499999999999997, "duration": 0.23999999999999977}, {"pitch": 102, "velocity": 49, "start": 3.1399999999999997, "duration": 0.05999999999999961}, {"pitch": 105, "velocity": 49, "start": 3.1399999999999997, "duration": 0.05999999999999961}, {"pitch": 96, "velocity": 29, "start": 3.269999999999999, "duration": 0.05999999999999961}, {"pitch": 95, "velocity": 39, "start": 3.279999999999999, "duration": 0.05999999999999961}, {"pitch": 62, "velocity": 39, "start": 3.3499999999999983, "duration": 0.05999999999999961}, {"pitch": 107, "velocity": 79, "start": 3.2899999999999987, "duration": 0.11999999999999922}, {"pitch": 80, "velocity": 39, "start": 3.3499999999999983, "duration": 0.07999999999999963}, {"pitch": 61, "velocity": 39, "start": 3.1899999999999995, "duration": 0.25999999999999845}, {"pitch": 99, "velocity": 39, "start": 3.399999999999998, "duration": 0.05999999999999961}, {"pitch": 59, "velocity": 59, "start": 3.519999999999998, "duration": 0.05999999999999961}, {"pitch": 69, "velocity": 39, "start": 3.5599999999999974, "duration": 0.040000000000000036}, {"pitch": 54, "velocity": 39, "start": 3.5499999999999976, "duration": 0.05999999999999961}, {"pitch": 108, "velocity": 49, "start": 4.069999999999998, "duration": 0.05999999999999961}, {"pitch": 104, "velocity": 49, "start": 4.579999999999997, "duration": 0.05999999999999872}, {"pitch": 61, "velocity": 29, "start": 4.599999999999997, "duration": 0.05999999999999872}, {"pitch": 81, "velocity": 39, "start": 4.6199999999999966, "duration": 0.05999999999999872}, {"pitch": 63, "velocity": 39, "start": 4.589999999999997, "duration": 0.09999999999999787}, {"pitch": 55, "velocity": 29, "start": 4.769999999999995, "duration": 0.05999999999999872}, {"pitch": 56, "velocity": 39, "start": 4.789999999999995, "duration": 0.05999999999999872}, {"pitch": 100, "velocity": 49, "start": 4.809999999999994, "duration": 0.05999999999999872}, {"pitch": 107, "velocity": 79, "start": 5.049999999999993, "duration": 0.05999999999999961}, {"pitch": 59, "velocity": 59, "start": 4.919999999999993, "duration": 0.23999999999999932}, {"pitch": 103, "velocity": 39, "start": 5.119999999999992, "duration": 0.040000000000000036}, {"pitch": 104, "velocity": 39, "start": 5.119999999999992, "duration": 0.05999999999999961}, {"pitch": 102, "velocity": 49, "start": 4.949999999999993, "duration": 0.23999999999999844}, {"pitch": 61, "velocity": 29, "start": 5.109999999999992, "duration": 0.11999999999999922}, {"pitch": 59, "velocity": 99, "start": 5.919999999999991, "duration": 0.03999999999999915}, {"pitch": 83, "velocity": 39, "start": 5.919999999999991, "duration": 0.03999999999999915}, {"pitch": 78, "velocity": 69, "start": 5.929999999999991, "duration": 0.03999999999999915}, {"pitch": 95, "velocity": 39, "start": 5.909999999999991, "duration": 0.05999999999999872}, {"pitch": 93, "velocity": 39, "start": 5.95999999999999, "duration": 0.040000000000000036}, {"pitch": 80, "velocity": 49, "start": 5.94999999999999, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 39, "start": 5.99999999999999, "duration": 0.040000000000000036}, {"pitch": 56, "velocity": 59, "start": 6.20999999999999, "duration": 0.1200000000000001}, {"pitch": 108, "velocity": 109, "start": 6.41999999999999, "duration": 0.05999999999999961}, {"pitch": 60, "velocity": 69, "start": 6.4499999999999895, "duration": 0.040000000000000036}, {"pitch": 61, "velocity": 49, "start": 6.42999999999999, "duration": 0.05999999999999961}, {"pitch": 77, "velocity": 39, "start": 6.55999999999999, "duration": 0.03999999999999915}, {"pitch": 80, "velocity": 49, "start": 6.589999999999989, "duration": 0.1200000000000001}, {"pitch": 79, "velocity": 39, "start": 6.679999999999989, "duration": 0.040000000000000036}, {"pitch": 55, "velocity": 49, "start": 6.609999999999989, "duration": 0.1200000000000001}, {"pitch": 86, "velocity": 39, "start": 6.729999999999989, "duration": 0.05999999999999961}, {"pitch": 57, "velocity": 109, "start": 6.56999999999999, "duration": 0.23999999999999844}, {"pitch": 60, "velocity": 109, "start": 6.849999999999988, "duration": 0.05999999999999961}, {"pitch": 108, "velocity": 49, "start": 6.869999999999988, "duration": 0.05999999999999961}, {"pitch": 84, "velocity": 39, "start": 6.709999999999989, "duration": 0.23999999999999755}, {"pitch": 80, "velocity": 29, "start": 6.719999999999989, "duration": 0.23999999999999755}, {"pitch": 79, "velocity": 69, "start": 6.849999999999988, "duration": 0.11999999999999833}, {"pitch": 55, "velocity": 39, "start": 6.979999999999986, "duration": 0.0600000000000005}, {"pitch": 51, "velocity": 59, "start": 7.0099999999999865, "duration": 0.0600000000000005}, {"pitch": 81, "velocity": 29, "start": 6.849999999999988, "duration": 0.23999999999999844}, {"pitch": 94, "velocity": 49, "start": 7.079999999999987, "duration": 0.05999999999999961}, {"pitch": 107, "velocity": 79, "start": 7.099999999999986, "duration": 0.05999999999999961}, {"pitch": 108, "velocity": 79, "start": 7.139999999999986, "duration": 0.05999999999999872}, {"pitch": 81, "velocity": 39, "start": 7.209999999999985, "duration": 0.05999999999999961}, {"pitch": 61, "velocity": 39, "start": 7.349999999999984, "duration": 0.03999999999999915}, {"pitch": 80, "velocity": 49, "start": 7.329999999999984, "duration": 0.05999999999999872}, {"pitch": 79, "velocity": 39, "start": 7.369999999999983, "duration": 0.03999999999999915}, {"pitch": 85, "velocity": 39, "start": 7.349999999999984, "duration": 0.05999999999999872}, {"pitch": 58, "velocity": 59, "start": 7.1799999999999855, "duration": 0.23999999999999666}, {"pitch": 84, "velocity": 69, "start": 7.379999999999983, "duration": 0.03999999999999915}, {"pitch": 87, "velocity": 39, "start": 7.399999999999983, "duration": 0.03999999999999915}, {"pitch": 93, "velocity": 49, "start": 7.419999999999982, "duration": 0.05999999999999961}]}</script> | |
| <h3>Shared-scale spectrogram comparison</h3><img src="zh/spectrogram.png" alt="Chinese: target, baseline, dictionary and refined spectrograms"> | |
| </section> | |
| <footer>All players share the target amplitude calibration. Piano WAVs include 0.5 seconds of release tail beyond the speech duration; that extra tail is excluded from spectral metrics.</footer> | |
| <script> | |
| const players = Array.from(document.querySelectorAll('audio')); | |
| for (const audio of players) audio.addEventListener('play', () => { | |
| for (const other of players) if (other !== audio) other.pause(); | |
| }); | |
| for (const canvas of document.querySelectorAll('canvas[data-roll]')) { | |
| const name = canvas.dataset.roll; | |
| const {seconds, notes} = JSON.parse(document.getElementById('notes-' + name).textContent); | |
| const audio = document.querySelector('audio[data-piano="' + name + '"]'); | |
| const low = Math.min(...notes.map(n => n.pitch)) - 2; | |
| const high = Math.max(...notes.map(n => n.pitch)) + 2; | |
| const left = 48, top = 14, bottom = 30, right = 14; | |
| let frame = null; | |
| function draw() { | |
| const w = canvas.clientWidth, h = canvas.clientHeight; | |
| const scale = window.devicePixelRatio || 1; | |
| canvas.width = Math.round(w * scale); canvas.height = Math.round(h * scale); | |
| const c = canvas.getContext('2d'); c.scale(scale, scale); | |
| const pw = w - left - right, ph = h - top - bottom; | |
| const x = time => left + time / seconds * pw; | |
| const y = pitch => top + (high - pitch) / (high - low) * ph; | |
| c.fillStyle = '#fff'; c.fillRect(0, 0, w, h); | |
| c.font = '12px system-ui'; c.textAlign = 'right'; | |
| for (let pitch = Math.ceil(low); pitch <= high; pitch++) { | |
| if ([1,3,6,8,10].includes(pitch % 12)) { | |
| c.fillStyle = '#f2f5f8'; c.fillRect(left, y(pitch + .5), pw, ph / (high - low)); | |
| } | |
| if (pitch % 12 === 0) { | |
| c.fillStyle = '#475569'; c.fillText('C' + (pitch / 12 - 1), left - 6, y(pitch) + 4); | |
| } | |
| } | |
| c.textAlign = 'center'; | |
| for (let t = 0; t <= seconds; t++) { | |
| c.strokeStyle = '#dae2ec'; c.beginPath(); c.moveTo(x(t), top); c.lineTo(x(t), h-bottom); c.stroke(); | |
| c.fillStyle = '#475569'; c.fillText(t + 's', x(t), h - 9); | |
| } | |
| for (const n of notes) { | |
| c.fillStyle = `hsl(${240 - n.velocity / 127 * 195} 72% 46%)`; | |
| c.fillRect(x(n.start), y(n.pitch + .4), Math.max(1, n.duration / seconds * pw), .8 * ph / (high-low)); | |
| } | |
| c.strokeStyle = '#e11d48'; c.lineWidth = 2; c.beginPath(); | |
| c.moveTo(x(audio.currentTime), top); c.lineTo(x(audio.currentTime), h-bottom); c.stroke(); | |
| } | |
| function animate() { draw(); frame = audio.paused ? null : requestAnimationFrame(animate); } | |
| audio.addEventListener('play', () => { if (frame === null) animate(); }); | |
| for (const event of ['timeupdate', 'seeked', 'loadedmetadata', 'ended']) audio.addEventListener(event, draw); | |
| canvas.addEventListener('click', event => { | |
| if (!Number.isFinite(audio.duration)) return; | |
| const bounds = canvas.getBoundingClientRect(); | |
| audio.currentTime = Math.max(0, Math.min(audio.duration, | |
| (event.clientX - bounds.left - left) / (bounds.width - left - right) * seconds)); | |
| draw(); | |
| }); | |
| new ResizeObserver(draw).observe(canvas); | |
| draw(); | |
| } | |
| </script> | |
| </html> | |