Skip to content

Commit d2c0788

Browse files
committed
Clip detection
1 parent 7f76f80 commit d2c0788

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

chrome/player/ui/audio/AudioChannelMixer.mjs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class AudioChannelMixer extends AbstractAudioModule {
102102
this.renderChannel(this.channelNodes[channel.id], this.mixerChannelElements[channel.id]);
103103
});
104104

105-
this.renderChannel(this.masterNodes, this.masterElements);
105+
this.renderChannel(this.masterNodes, this.masterElements, true);
106106

107107
this.channelNodes.forEach((nodes, i) => {
108108
nodes.equalizer.render();
@@ -113,7 +113,7 @@ export class AudioChannelMixer extends AbstractAudioModule {
113113
this.masterNodes.compressor.render();
114114
}
115115

116-
renderChannel(nodes, els) {
116+
renderChannel(nodes, els, checkClip = false) {
117117
const analyzer = nodes ? nodes.analyzer : null;
118118
if (!analyzer || !els) {
119119
return;
@@ -135,6 +135,13 @@ export class AudioChannelMixer extends AbstractAudioModule {
135135
const newvolume = AudioUtils.getVolume(analyzer);
136136
const volume = Math.max(newvolume, lastVolume - 0.5);
137137
analyzer._lastVolume = volume;
138+
139+
if (checkClip && AudioUtils.isClipping(analyzer)) {
140+
analyzer._isClippingTime = Date.now();
141+
}
142+
143+
const isClipping = checkClip && analyzer._isClippingTime && (Date.now() - analyzer._isClippingTime < 500);
144+
138145
const rectHeight = height / 50;
139146

140147
const minDb = analyzer.minDecibels;
@@ -157,7 +164,7 @@ export class AudioChannelMixer extends AbstractAudioModule {
157164
ctx.fillRect(0, y, width, rectHeight);
158165

159166
const color = `rgb(${Utils.clamp(i * 5, 0, 255)}, ${Utils.clamp(255 - i * 5, 0, 255)}, 0)`;
160-
ctx.fillStyle = color;
167+
ctx.fillStyle = isClipping ? 'rgb(255, 0, 0)' : color;
161168
ctx.fillRect(0, y + 1, width, rectHeight - 2);
162169
}
163170

chrome/player/utils/AudioUtils.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ function get468WeightsForAnalyser(analyser) {
6363
* Utility functions for audio processing and conversions.
6464
*/
6565
export class AudioUtils {
66+
static isClipping(analyser) {
67+
const bufferLength = analyser.frequencyBinCount;
68+
const dataArray = new Uint8Array(bufferLength);
69+
analyser.getByteTimeDomainData(dataArray);
70+
71+
// Check if any sample is at the clipping value (0 or 255)
72+
for (let i = 0; i < bufferLength; i++) {
73+
if (dataArray[i] === 255) {
74+
return true;
75+
}
76+
}
77+
return false;
78+
}
6679
/**
6780
* Calculates the volume in decibels from an AnalyserNode.
6881
* @param {AnalyserNode} analyser - The Web Audio analyser node.

0 commit comments

Comments
 (0)