-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.js
More file actions
135 lines (109 loc) · 4.65 KB
/
content.js
File metadata and controls
135 lines (109 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Content script for playing audio tones
class AudioToneGenerator {
constructor() {
this.audioContext = null;
this.initAudioContext();
}
initAudioContext() {
try {
this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
} catch (error) {
console.warn('Web Audio API not supported:', error);
}
}
// Map file size to frequency (Hz)
sizeToFrequency(sizeBytes) {
// Define size ranges and corresponding frequencies
// Tiny files (0-5KB): 1500-1000 Hz (high pitch)
// Small files (5Kb-10KB): 1000-500 Hz (higher pitch)
// Medium files (10KB-100KB): 500-300 Hz (medium pitch)
// Large files (100-1000KB): 300-200 Hz (lower pitch)
// Extra Large files (1000KB+): 200-100 Hz (low pitch)
const minFreq = 100; // Lowest frequency for very large files
const maxFreq = 1500; // Highest frequency for very small files
// Use logarithmic scale for better distribution
const logSize = Math.log(Math.max(sizeBytes, 1));
const maxLogSize = Math.log(1000000); // 1MB as reference point
// Invert the relationship: smaller files = higher frequency
const normalizedSize = Math.min(logSize / maxLogSize, 1);
const frequency = maxFreq - (normalizedSize * (maxFreq - minFreq));
return Math.max(frequency, minFreq);
}
// Map file size to duration (ms)
sizeToDuration(sizeBytes) {
// Smaller files = shorter duration, larger files = longer duration
const minDuration = 40; // 50ms for very small files
const maxDuration = 400; // 300ms for very large files
const logSize = Math.log(Math.max(sizeBytes, 1));
const maxLogSize = Math.log(1000000); // 1MB as reference
const normalizedSize = Math.min(logSize / maxLogSize, 1);
const duration = minDuration + (normalizedSize * (maxDuration - minDuration));
return duration;
}
playTone(frequency, duration, volume = 0.1) {
if (!this.audioContext) {
this.initAudioContext();
if (!this.audioContext) return;
}
const oscillator = this.audioContext.createOscillator();
const gainNode = this.audioContext.createGain();
// Connect nodes
oscillator.connect(gainNode);
gainNode.connect(this.audioContext.destination);
// Configure oscillator
oscillator.type = 'sine'; // Smooth sine wave
oscillator.frequency.setValueAtTime(frequency, this.audioContext.currentTime);
// Configure volume envelope (fade in/out to avoid clicks)
const now = this.audioContext.currentTime;
const fadeTime = 0.01; // 10ms fade
gainNode.gain.setValueAtTime(0, now);
gainNode.gain.linearRampToValueAtTime(volume, now + fadeTime);
gainNode.gain.linearRampToValueAtTime(volume, now + duration/1000 - fadeTime);
gainNode.gain.linearRampToValueAtTime(0, now + duration/1000);
// Resume audio context if suspended (required by some browsers)
if (this.audioContext.state === 'suspended') {
this.audioContext.resume().then(() => {
console.log('AudioContext resumed');
});
}
// Play the tone
oscillator.start(now);
oscillator.stop(now + duration/1000);
}
playRequestTone(sizeBytes) {
const frequency = this.sizeToFrequency(sizeBytes);
const duration = this.sizeToDuration(sizeBytes);
// Adjust volume based on size (smaller files = quieter)
const logSize = Math.log(Math.max(sizeBytes, 1));
const maxLogSize = Math.log(1000000);
const normalizedSize = Math.min(logSize / maxLogSize, 1);
const volume = 0.05 + (normalizedSize * 0.15); // 0.05 to 0.2 volume range
this.playTone(frequency, duration, volume);
// Log for debugging
console.log(`Playing tone: ${Math.round(frequency)}Hz, ${Math.round(duration)}ms, size: ${this.formatBytes(sizeBytes)}`);
}
formatBytes(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
}
}
// Initialize audio generator
const audioGenerator = new AudioToneGenerator();
// Listen for messages from background script
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === 'PLAY_AUDIO') {
// Play audio tone based on request size
audioGenerator.playRequestTone(message.size);
sendResponse({ success: true });
}
});
// Test tone on page load (optional - can be removed)
window.addEventListener('load', () => {
// Small delay to ensure audio context is ready
setTimeout(() => {
console.log('Windchime extension loaded');
}, 1000);
});