+ Ultimatic

This commit is contained in:
Neale Pickett 2022-05-08 14:49:41 -06:00
parent 4950042e6c
commit 5f78339faa
2 changed files with 60 additions and 24 deletions

View File

@ -12,9 +12,9 @@ const PAUSE_WORD = -7
const PAUSE_LETTER = -3 const PAUSE_LETTER = -3
/** Silent period between dits and dash */ /** Silent period between dits and dash */
const PAUSE = -1 const PAUSE = -1
/** Duration of a dit */ /** Length of a dit */
const DIT = 1 const DIT = 1
/** Duration of a dah */ /** Length of a dah */
const DAH = 3 const DAH = 3
/** /**
@ -107,6 +107,25 @@ function not(ditdah) {
return DIT return DIT
} }
/**
* Queue Set: A Set you can shift and pop.
*
* Performance of this implementation may be bad for large sets.
*/
class QSet extends Set {
shift() {
let r = [...this].shift()
this.delete(r)
return r
}
pop() {
let r = [...this].pop()
this.delete(r)
return r
}
}
/** /**
* A callback to start or stop transmission * A callback to start or stop transmission
* *
@ -301,6 +320,22 @@ class ElBugKeyer extends BugKeyer {
this.beginPulsing() this.beginPulsing()
} }
/**
* Computes transmission duration for a given key.
*
* @param {number} key Key to calculate
* @returns {Duration} Duration of transmission
*/
keyDuration(key) {
switch (key) {
case 0:
return DIT * this.ditDuration
case 1:
return DAH * this.ditDuration
}
return 0
}
/** /**
* Calculates the duration of the next transmission to send. * Calculates the duration of the next transmission to send.
* *
@ -309,13 +344,10 @@ class ElBugKeyer extends BugKeyer {
* @returns {Duration} Duration of next transmission * @returns {Duration} Duration of next transmission
*/ */
nextTxDuration() { nextTxDuration() {
switch (this.lastPressed) { if (!this.keyPressed.some(Boolean)) {
case 0: return 0
return this.ditDuration * DIT
case 1:
return this.ditDuration * DAH
} }
return 0 return this.keyDuration(this.lastPressed)
} }
pulse() { pulse() {
@ -324,15 +356,10 @@ class ElBugKeyer extends BugKeyer {
// This keyer only drives one transmit relay // This keyer only drives one transmit relay
if (this.TxClosed()) { if (this.TxClosed()) {
// If we're transmitting at all, pause // If we're transmitting at all, pause
this.Tx(0, false)
nextPulse = this.ditDuration nextPulse = this.ditDuration
} else if (this.keyPressed.some(Boolean)) { this.Tx(0, false)
// If there's a key down, transmit. } else if ((nextPulse = this.nextTxDuration()) > 0) {
//
// Wait until here to ask for next duration, so things with memories
// don't flush that memory for a pause.
this.Tx(0, true) this.Tx(0, true)
nextPulse = this.nextTxDuration()
} }
if (nextPulse) { if (nextPulse) {
@ -352,25 +379,34 @@ class ElBugKeyer extends BugKeyer {
class SingleDotKeyer extends ElBugKeyer { class SingleDotKeyer extends ElBugKeyer {
Reset() { Reset() {
super.Reset() super.Reset()
this.queue = [] this.queue = new QSet()
} }
Key(key, pressed) { Key(key, pressed) {
super.Key(key, pressed) if (pressed && (key == 0)) {
if (pressed && (key == 0) && this.keyPressed[1]) { this.queue.add(0)
this.queue = [DIT]
} }
super.Key(key, pressed)
} }
nextTxDuration() { nextTxDuration() {
if (this.queue.length) { let key = this.queue.shift()
let dits = this.queue.shift() if (key != null) {
return dits * this.ditDuration return this.keyDuration(key)
} }
return super.nextTxDuration() return super.nextTxDuration()
} }
} }
class UltimaticKeyer extends SingleDotKeyer {
Key(key, pressed) {
if (pressed) {
this.queue.add(key)
}
super.Key(key, pressed)
}
}
/** /**
* Keyer class. This handles iambic and straight key input. * Keyer class. This handles iambic and straight key input.
* *
@ -643,4 +679,4 @@ class OldKeyer {
} }
} }
export {StraightKeyer, CootieKeyer, BugKeyer, ElBugKeyer, SingleDotKeyer} export {StraightKeyer, CootieKeyer, BugKeyer, ElBugKeyer, SingleDotKeyer, UltimaticKeyer}

View File

@ -43,7 +43,7 @@ class VailClient {
this.lamp = new Buzzer.Lamp() this.lamp = new Buzzer.Lamp()
this.buzzer = new Buzzer.ToneBuzzer() this.buzzer = new Buzzer.ToneBuzzer()
this.straightKeyer = new Keyer.StraightKeyer(() => this.beginTx(), () => this.endTx()) this.straightKeyer = new Keyer.StraightKeyer(() => this.beginTx(), () => this.endTx())
this.keyer = new Keyer.SingleDotKeyer(() => this.beginTx(), () => this.endTx()) this.keyer = new Keyer.UltimaticKeyer(() => this.beginTx(), () => this.endTx())
this.roboKeyer = new Keyer.ElBugKeyer(() => this.Buzz(), () => this.Silence()) this.roboKeyer = new Keyer.ElBugKeyer(() => this.Buzz(), () => this.Silence())
// Set up various input methods // Set up various input methods