[GreenKeys] Precise baud timing

Zach Tumbusch zach.tumbusch at gmail.com
Wed Nov 12 15:22:13 EST 2025


Sending again because I lost the last part of my message when doing the
copy paste.. I went through a few iterations testing with Node, PHP, and C#
but settled on this example. The bigger challenge was sorting the popping
on the fast frequency transition. I tested this up to 9600 baud with my
ST-8000. The bit stream is 8 bit characters  "A": "01100011" 11000 with 1
start bit and 2 stop bits. The actual bitrate at 45.45 baud is around 22ms.
but since I am directly converting points to a wav file I keep track of
that based on how many samples. Prints well on all my machines. Model 28 /
UGC-136BX / Hal. See the working example. https://w8zjt.net/itty I
understand this is not exactly what you're looking for and maybe not
helpful at all, since you're not using a modem but sending rs232
directly..  Maybe the logic will spur some ideas!

73, de W8ZJT

    async generateAFSKWav(bitstream: string, baud, mark, space): Promise<
Blob> {
        const sampleRate = 16000;  // Sample rate in Hz
        const fadeDuration = 50;   // Number of samples for smooth
frequency transition
        const samplesPerBit = Math.round(sampleRate / baud);
        const totalSamples = bitstream.length * samplesPerBit;
        let audioSamples: Float32Array = new Float32Array(totalSamples);
        let phase = 0.0;
        let currentFreq = bitstream[0] === "1" ? mark : space;
        let currentPhaseIncrement = (2 * Math.PI * currentFreq) / sampleRate
;

        for (let bitIndex = 0; bitIndex < bitstream.length; bitIndex++) {
            const newFreq = bitstream[bitIndex] === "1" ? mark : space;
            const newPhaseIncrement = (2 * Math.PI * newFreq) / sampleRate;

            for (let i = 0; i < samplesPerBit; i++) {
                if (i < fadeDuration) {
                    // Smooth frequency transition (interpolation)
                    const fadeFactor = i / fadeDuration;
                    const interpolatedFreq = currentFreq * (1 - fadeFactor)
+ newFreq * fadeFactor;
                    currentPhaseIncrement = (2 * Math.PI * interpolatedFreq)
/ sampleRate;
                } else {
                    currentPhaseIncrement = newPhaseIncrement;
                }

                // Generate waveform sample
                audioSamples[bitIndex * samplesPerBit + i] = Math.sin(phase
);
                phase += currentPhaseIncrement;

                if (phase >= 2 * Math.PI) {
                    phase -= 2 * Math.PI;
                }
            }

            currentFreq = newFreq;
        }
        // Convert to WAV format
        const wavBuffer = await WavEncoder.encode({
            sampleRate: sampleRate,
            channelData: [audioSamples] // Mono channel
        });

On Wed, Nov 12, 2025 at 1:41 PM Windows XD <antech6586856 at gmail.com> wrote:

> I really think its an issue with the board not being fast enough to decode
> the serial inputs, I'm gonna mess with the settings to see if I can
> optimize the code.
>
> On Wed, Nov 12, 2025, 1:32 PM Harold Hallikainen via GreenKeys <
> greenkeys at mailman.qth.net> wrote:
>
>>
>>
>> On Wed, November 12, 2025 10:41 am, Jim Cooper wrote:
>> > On 12 Nov 2025 at 9:45, Harold Hallikainen via GreenKeys
>> > wrote:
>> >
>> >
>> >> However, if the printer loses sync,
>> >> it seems like the 31 ms stop bit allows the printer to resync more
>> quickly
>> >> than a 22 ms stop bit.
>> >
>> > Exactly right.   The 22ms stop bit was
>> > mostly used by Western Union, who figured it would increase data
>> throughput
>> > by a significant percentage on heavily used circuits.
>> >
>> > The longer stop bit assures that the shaft comes
>> > to a rotational stop and WAITS for the next start bit.
>> >
>> > w2jc
>>
>> Thanks! With a 22 ms stop bit, I'd expect the shaft to stop rotating and
>> wait 11 ms to start rotating on the next start bit. If the stop bit is 31
>> ms, I think the shaft would wait 20 ms before starting rotation again on
>> the leading edge of the next start bit. Of course, when hand typing, the
>> "stop bit" can be any length of at least 22 ms.
>>
>> Harold
>> https://w6iwi.org
>>
>>
>>
>> --
>> https://w6iwi.org
>> ______________________________________________________________
>> GreenKeys mailing list
>> Home: http://mailman.qth.net/mailman/listinfo/greenkeys
>> Help: http://mailman.qth.net/mmfaq.htm
>> Post: mailto:GreenKeys at mailman.qth.net
>>
>> >>> Jordan Spencer Cunningham's GreenKeys Search Tool:
>> https://teletype.net/gksearch
>> >>> 2002-to-present greenkeys archive:
>> http://mailman.qth.net/pipermail/greenkeys/
>> >>> 1998-to-2001 greenkeys archive:
>> http://mailman.qth.net/archive/greenkeys/greenkeys.html
>> >>> Randy Guttery's 2001-to-2009 GreenKeys Search Tool:
>> http://comcents.com/tty/greenkeyssearch.html
>>
>> This list hosted by: http://www.qsl.net
>> Please help support this email list: http://www.qsl.net/donate.html
>> Message delivered to antech6586856 at gmail.com
>>
> ______________________________________________________________
> GreenKeys mailing list
> Home: http://mailman.qth.net/mailman/listinfo/greenkeys
> Help: http://mailman.qth.net/mmfaq.htm
> Post: mailto:GreenKeys at mailman.qth.net
>
> >>> Jordan Spencer Cunningham's GreenKeys Search Tool:
> https://teletype.net/gksearch
> >>> 2002-to-present greenkeys archive:
> http://mailman.qth.net/pipermail/greenkeys/
> >>> 1998-to-2001 greenkeys archive:
> http://mailman.qth.net/archive/greenkeys/greenkeys.html
> >>> Randy Guttery's 2001-to-2009 GreenKeys Search Tool:
> http://comcents.com/tty/greenkeyssearch.html
>
> This list hosted by: http://www.qsl.net
> Please help support this email list: http://www.qsl.net/donate.html
> Message delivered to zach.tumbusch at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.qth.net/pipermail/greenkeys/attachments/20251112/130122be/attachment.html>


More information about the GreenKeys mailing list