mirror of https://github.com/nealey/vail.git
parent
1d861b75e4
commit
72f2df5d6c
|
@ -0,0 +1,50 @@
|
||||||
|
import * as time from "./time.mjs"
|
||||||
|
|
||||||
|
const defaultIcon = "default"
|
||||||
|
|
||||||
|
class Icon {
|
||||||
|
/**
|
||||||
|
* @param {Number} timeoutDuration Duration of timeout
|
||||||
|
*/
|
||||||
|
constructor(timeoutDuration = 2*time.Second) {
|
||||||
|
this.timeoutDuration = timeoutDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the icon type
|
||||||
|
*
|
||||||
|
* @param {String} iconType Icon to set to
|
||||||
|
*/
|
||||||
|
Set(iconType=defaultIcon) {
|
||||||
|
if (iconType != defaultIcon) {
|
||||||
|
clearTimeout(this.cleanupTimer)
|
||||||
|
this.cleanupTimer = setTimeout(() => this.Set(), this.timeoutDuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let e of document.querySelectorAll("link[rel=icon]")) {
|
||||||
|
if (! e.dataset[defaultIcon]) {
|
||||||
|
e.dataset[defaultIcon] = e.href
|
||||||
|
}
|
||||||
|
let url = e.dataset[iconType]
|
||||||
|
if (url) {
|
||||||
|
e.href = url
|
||||||
|
} else {
|
||||||
|
console.warn(`No data-${iconType} attribute`, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set icon at the provided time.
|
||||||
|
*
|
||||||
|
* @param {String} iconType Icon to set to
|
||||||
|
* @param {Number} when Time to set the value
|
||||||
|
*/
|
||||||
|
SetAt(iconType, when=null) {
|
||||||
|
setTimeout(() => this.Set(iconType), when - Date.now())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
Icon,
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a noise generator with a low pass filter
|
||||||
|
*
|
||||||
|
* @param {AudioContext} context Audio context
|
||||||
|
* @param {Number} lowpassFreq Low-pass filter frequency (Hz)
|
||||||
|
* @returns {GainNode} Gain object for noise
|
||||||
|
*/
|
||||||
|
function Noise(context, lowpassFreq = 100) {
|
||||||
|
let bufferSize = 17 * context.sampleRate
|
||||||
|
let noiseBuffer = context.createBuffer(1, bufferSize, context.sampleRate)
|
||||||
|
let output = noiseBuffer.getChannelData(0)
|
||||||
|
for (let i = 0; i < bufferSize; i++) {
|
||||||
|
output[i] = Math.random() * 2 - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let whiteNoise = context.createBufferSource();
|
||||||
|
whiteNoise.buffer = noiseBuffer;
|
||||||
|
whiteNoise.loop = true;
|
||||||
|
whiteNoise.start(0);
|
||||||
|
|
||||||
|
let filter = context.createBiquadFilter()
|
||||||
|
filter.type = "lowpass"
|
||||||
|
filter.frequency.value = lowpassFreq
|
||||||
|
|
||||||
|
let gain = context.createGain()
|
||||||
|
gain.gain.value = 0.1
|
||||||
|
|
||||||
|
whiteNoise.connect(filter)
|
||||||
|
filter.connect(gain)
|
||||||
|
|
||||||
|
return gain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import * as Chart from "./chart.mjs"
|
||||||
import * as I18n from "./i18n.mjs"
|
import * as I18n from "./i18n.mjs"
|
||||||
import * as time from "./time.mjs"
|
import * as time from "./time.mjs"
|
||||||
import * as Music from "./music.mjs"
|
import * as Music from "./music.mjs"
|
||||||
|
import * as Icon from "./icon.mjs"
|
||||||
|
|
||||||
const DefaultRepeater = "General"
|
const DefaultRepeater = "General"
|
||||||
|
|
||||||
|
@ -45,6 +46,7 @@ class VailClient {
|
||||||
// Outputs
|
// Outputs
|
||||||
this.outputs = new Outputs.Collection(globalAudioContext)
|
this.outputs = new Outputs.Collection(globalAudioContext)
|
||||||
this.outputs.connect(globalAudioContext.destination)
|
this.outputs.connect(globalAudioContext.destination)
|
||||||
|
this.icon = new Icon.Icon()
|
||||||
|
|
||||||
// Keyers
|
// Keyers
|
||||||
this.straightKeyer = new Keyers.Keyers.straight(this)
|
this.straightKeyer = new Keyers.Keyers.straight(this)
|
||||||
|
@ -165,21 +167,9 @@ class VailClient {
|
||||||
document.querySelector("#keyer-rate").dispatchEvent(new Event("input"))
|
document.querySelector("#keyer-rate").dispatchEvent(new Event("input"))
|
||||||
}
|
}
|
||||||
|
|
||||||
setIconType(iconType="silent") {
|
|
||||||
for (let e of document.querySelectorAll("link[rel=icon]")) {
|
|
||||||
if (! e.dataset.silent) {
|
|
||||||
e.dataset.silent = e.href
|
|
||||||
}
|
|
||||||
e.href = e.dataset[iconType]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Buzz() {
|
Buzz() {
|
||||||
this.outputs.Buzz(false)
|
this.outputs.Buzz(false)
|
||||||
|
this.icon.Set("rx")
|
||||||
clearTimeout(this.activityTimeout)
|
|
||||||
this.activityTimeout = setTimeout(() => this.setIconType(), 2*time.Second)
|
|
||||||
this.setIconType("rx")
|
|
||||||
|
|
||||||
if (this.rxChart) this.rxChart.Set(1)
|
if (this.rxChart) this.rxChart.Set(1)
|
||||||
}
|
}
|
||||||
|
@ -192,7 +182,13 @@ class VailClient {
|
||||||
BuzzDuration(tx, when, duration) {
|
BuzzDuration(tx, when, duration) {
|
||||||
this.outputs.BuzzDuration(tx, when, duration)
|
this.outputs.BuzzDuration(tx, when, duration)
|
||||||
|
|
||||||
let chart = tx?this.txChart:this.rxChart
|
let chart
|
||||||
|
if (tx) {
|
||||||
|
chart = this.txChart
|
||||||
|
} else {
|
||||||
|
chart = this.rxChart
|
||||||
|
this.icon.SetAt("rx", when)
|
||||||
|
}
|
||||||
if (chart) {
|
if (chart) {
|
||||||
chart.SetAt(1, when)
|
chart.SetAt(1, when)
|
||||||
chart.SetAt(0, when+duration)
|
chart.SetAt(0, when+duration)
|
||||||
|
|
Loading…
Reference in New Issue