Skip to content

Commit

Permalink
spectrogram plugin: fix for hi-dpi displays and independent height (#…
Browse files Browse the repository at this point in the history
…2509)

* Improved behavior on retina displays

* Update Spectrogram example with `height`

* Update changelog
  • Loading branch information
mjrond authored May 16, 2022
1 parent addd2b3 commit 2e64ec1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
9 changes: 8 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ wavesurfer.js changelog
6.2.0 (unreleased)
------------------
- Fix `clientWidth` error in responsive mode (#2498)
- Fix `TypeError` when `showTime: undefined` in cursor plugin (#2501)
- Cursor plugin:
- Fix `TypeError` when `showTime: undefined` (#2501)
- Spectrogram plugin:
- Fix to have consistent CSS height regardless of device pixel ratio (#2507)
- Added `height` configuration option to control CSS height of the view,
which will scale to fill
- Frequency label display is `fixed` instead of `absolute` to enable
consistent size on hi-dpi displays

6.1.0 (31.03.2022)
------------------
Expand Down
4 changes: 3 additions & 1 deletion example/spectrogram/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ function initAndLoadSpectrogram(colorMap) {
WaveSurfer.spectrogram.create({
container: '#wave-spectrogram',
labels: true,
colorMap: colorMap
colorMap: colorMap,
fftSamples: 1024,
height: 256
})
]
};
Expand Down
6 changes: 4 additions & 2 deletions example/spectrogram/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ <h4>Quick Start</h4>
WaveSurfer.spectrogram.create({
wavesurfer: wavesurfer,
container: "#wave-spectrogram",
labels: true
labels: true,
height: 256,
})
]
});
Expand All @@ -95,7 +96,8 @@ <h4>Options</h4>
<ul class="markdown-body">
<li><code>wavesurfer</code> - <em>required</em> - a WaveSurfer instance.</li>
<li><code>container</code> - <em>required</em> - the element in which to place the spectrogram, or a CSS selector to find it.</li>
<li><code>fftSamples</code> - number of FFT samples (<code>512</code> by default). Number of spectral lines and height of the spectrogram will be a half of this parameter.</li>
<li><code>fftSamples</code> - number of FFT samples (<code>512</code> by default). Number of spectral lines and default height of the spectrogram will be a half of this parameter.</li>
<li><code>height</code> - height of the spectrogram view in CSS pixels (<code>fftSamples/2</code> by default).</li>
<li><code>frequencyMin</code> - Min frequency to scale spectrogram(<code>0</code> by default).</li>
<li><code>frequencyMax</code> - Max frequency to scale spectrogram(<code>12000</code> by default). Set this to samplerate/2 to draw whole range of spectrogram.</li>
<li><code>splitChannels</code> - Render with separate spectrograms for the channels of the audio</li>
Expand Down
24 changes: 14 additions & 10 deletions src/plugin/spectrogram/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import FFT from './fft';
* a power of 2.
* @property {boolean} splitChannels=false Render with separate spectrograms for
* the channels of the audio
* @property {number} height=fftSamples/2 Height of the spectrogram view in CSS
* pixels
* @property {boolean} labels Set to true to display frequency labels.
* @property {number} noverlap Size of the overlapping window. Must be <
* fftSamples. Auto deduced from canvas size by default.
Expand Down Expand Up @@ -128,7 +130,7 @@ export default class SpectrogramPlugin {
this.pixelRatio = this.params.pixelRatio || ws.params.pixelRatio;
this.fftSamples =
this.params.fftSamples || ws.params.fftSamples || 512;
this.height = this.fftSamples / 2;
this.height = this.params.height || this.fftSamples / 2;
this.noverlap = params.noverlap;
this.windowFunc = params.windowFunc;
this.alpha = params.alpha;
Expand Down Expand Up @@ -185,11 +187,10 @@ export default class SpectrogramPlugin {
const labelsEl = (this.labelsEl = document.createElement('canvas'));
labelsEl.classList.add('spec-labels');
this.drawer.style(labelsEl, {
left: 0,
position: 'absolute',
position: 'fixed',
zIndex: 9,
height: `${this.height * this.channels / this.pixelRatio}px`,
width: `${55 / this.pixelRatio}px`
height: `${this.height * this.channels}px`,
width: `55px`
});
this.wrapper.appendChild(labelsEl);
this.loadLabels(
Expand All @@ -209,7 +210,7 @@ export default class SpectrogramPlugin {
position: 'relative',
userSelect: 'none',
webkitUserSelect: 'none',
height: `${this.height * this.channels / this.pixelRatio}px`
height: `${this.height * this.channels}px`
});

if (wsParams.fillParent || wsParams.scrollParent) {
Expand Down Expand Up @@ -256,8 +257,9 @@ export default class SpectrogramPlugin {
updateCanvasStyle() {
const width = Math.round(this.width / this.pixelRatio) + 'px';
this.canvas.width = this.width;
this.canvas.height = this.height * this.channels;
this.canvas.height = this.fftSamples / 2 * this.channels;
this.canvas.style.width = width;
this.canvas.style.height = this.height + 'px';
}

drawSpectrogram(frequenciesData, my) {
Expand All @@ -267,7 +269,7 @@ export default class SpectrogramPlugin {
}

const spectrCc = my.spectrCc;
const height = my.height;
const height = my.fftSamples / 2;
const width = my.width;
const freqFrom = my.buffer.sampleRate / 2;
const freqMin = my.frequencyMin;
Expand Down Expand Up @@ -404,8 +406,10 @@ export default class SpectrogramPlugin {

// prepare canvas element for labels
const ctx = this.labelsEl.getContext('2d');
this.labelsEl.height = this.height * this.channels;
this.labelsEl.width = bgWidth;
const dispScale = window.devicePixelRatio;
this.labelsEl.height = this.height * this.channels * dispScale;
this.labelsEl.width = bgWidth * dispScale;
ctx.scale(dispScale, dispScale);

if (!ctx) {
return;
Expand Down

0 comments on commit 2e64ec1

Please sign in to comment.