Add support for the DECPS escape sequence #11929

Closed
opened 2026-01-31 03:01:21 +00:00 by claunia · 40 comments
Owner

Originally created by @j4james on GitHub (Dec 31, 2020).

Description of the new feature/enhancement

The DECPS (Play Sound) escape sequence was first introduced on the DEC VT520 terminals, and provides applications with a way to play a sequence of musical notes. The supported functionality is fairly rudimentary, but it's good enough for generating basic sound effects in games, making your build scripts play a little jingle when they complete successfully, or having your login MOTD wish you a happy birthday every year.

Here's a little video demonstrating the sort of effects you can achieve (this is using a proof-of-concept implementation I've been experimenting with in conhost). Make sure the video player is not muted, otherwise you're obviously not going to hear anything.

https://user-images.githubusercontent.com/4181424/103430785-8957c700-4bbf-11eb-966c-14e916fbd03a.mp4

Proposed technical implementation details (optional)

My current implementation is using the Windows midi APIs to generate the notes, and I thought the square wave synth was probably the most appropriate instrument to match the kind of sounds that would be produced by terminals from that era.

I'm still working out some of the details, but I'd be keen to submit a PR at some point if this is something you might be willing to include.

Originally created by @j4james on GitHub (Dec 31, 2020). # Description of the new feature/enhancement The `DECPS` (_Play Sound_) escape sequence was first introduced on the DEC VT520 terminals, and provides applications with a way to play a sequence of musical notes. The supported functionality is fairly rudimentary, but it's good enough for generating basic sound effects in games, making your build scripts play a little jingle when they complete successfully, or having your login MOTD wish you a happy birthday every year. Here's a little video demonstrating the sort of effects you can achieve (this is using a proof-of-concept implementation I've been experimenting with in conhost). Make sure the video player is not muted, otherwise you're obviously not going to hear anything. https://user-images.githubusercontent.com/4181424/103430785-8957c700-4bbf-11eb-966c-14e916fbd03a.mp4 # Proposed technical implementation details (optional) My current implementation is using the Windows midi APIs to generate the notes, and I thought the square wave synth was probably the most appropriate instrument to match the kind of sounds that would be produced by terminals from that era. I'm still working out some of the details, but I'd be keen to submit a PR at some point if this is something you might be willing to include.
claunia added the Issue-FeatureResolution-Fix-CommittedArea-VTProduct-Terminal labels 2026-01-31 03:01:21 +00:00
Author
Owner

@zadjii-msft commented on GitHub (Jan 4, 2021):

This is fantastic, I love it.

:shipit:

@zadjii-msft commented on GitHub (Jan 4, 2021): This is fantastic, I love it. :shipit:
Author
Owner

@skyline75489 commented on GitHub (Jan 5, 2021):

All those VT sequences keep surprising me.

@skyline75489 commented on GitHub (Jan 5, 2021): All those VT sequences keep surprising me.
Author
Owner

@DHowett commented on GitHub (Jan 28, 2021):

Holy heck, I love this. I see no reason not to support it.

@DHowett commented on GitHub (Jan 28, 2021): Holy _heck_, I love this. I see no reason not to support it.
Author
Owner

@j4james commented on GitHub (Feb 5, 2021):

In case anyone is curious about the status, I did actually have a PR ready to submit for this, but while writing up the details, I was reading over the docs again, and it occurred to me that I might not have interpreted the buffering mechanism correctly.

I only know of two other terminals that support this sequence, and I don't think either of them are correct either. So I really need to get hold of a real DEC terminal to test with if I want to be sure I'm getting it right.

So for now I'm putting my PR on hold. But if anyone reading this happens to have access to a real VT520 or VT525 terminal that they can test with, I'd love to hear from you.

@j4james commented on GitHub (Feb 5, 2021): In case anyone is curious about the status, I did actually have a PR ready to submit for this, but while writing up the details, I was reading over the docs again, and it occurred to me that I might not have interpreted the buffering mechanism correctly. I only know of two other terminals that support this sequence, and I don't think either of them are correct either. So I really need to get hold of a real DEC terminal to test with if I want to be sure I'm getting it right. So for now I'm putting my PR on hold. But if anyone reading this happens to have access to a real VT520 or VT525 terminal that they can test with, I'd love to hear from you.
Author
Owner

@jerch commented on GitHub (Oct 4, 2021):

@j4james Is DECPS blocking on terminal side until the playback finished or is it possible to stack tones to chords by entering multiple sequences at once?

@jerch commented on GitHub (Oct 4, 2021): @j4james Is DECPS blocking on terminal side until the playback finished or is it possible to stack tones to chords by entering multiple sequences at once?
Author
Owner

@j4james commented on GitHub (Oct 4, 2021):

@jerch I'm fairly certain it wasn't possible to play multiple sequences at once. This is a direct quote from the VT525 manual:

The terminal’s sound buffer can store 16 notes of specified volume and duration. Additional sound controls are held in the communications input buffer invoking receive data flow control as needed.

I'm just not entirely sure if they mean you can play one DECPS sequence with up to 16 notes (and the next DECPS would block until the first is finished), or you could potentially send up to 16 DECPS sequences, as long as each only contained a single note.

This is probably not that big a deal for most people, but I was hoping to use the buffering as a way to do synchronized animations (like the demo above), and it's kind of essential that we get the behaviour correct for that.

@j4james commented on GitHub (Oct 4, 2021): @jerch I'm fairly certain it wasn't possible to play multiple sequences at once. This is a direct quote from the VT525 manual: > The terminal’s sound buffer can store 16 notes of specified volume and duration. Additional sound controls are held in the communications input buffer invoking receive data flow control as needed. I'm just not entirely sure if they mean you can play one `DECPS` sequence with up to 16 notes (and the next `DECPS` would block until the first is finished), or you could potentially send up to 16 `DECPS` sequences, as long as each only contained a single note. This is probably not that big a deal for most people, but I was hoping to use the buffering as a way to do synchronized animations (like the demo above), and it's kind of essential that we get the behaviour correct for that.
Author
Owner

@jerch commented on GitHub (Oct 5, 2021):

Hmm not sure either. Esp. the "can store 16 notes of specified volume and duration" sounds weird, almost like it is not a FIFO sample buffer, but a lookup table for pre-rendered wave forms, which you can only choose from in a timely fashion, while others would further block on the input buffer (due to needed rendering?). Maybe I am reading too much into it.

@jerch commented on GitHub (Oct 5, 2021): Hmm not sure either. Esp. the "can store 16 notes of specified volume and duration" sounds weird, almost like it is not a FIFO sample buffer, but a lookup table for pre-rendered wave forms, which you can only choose from in a timely fashion, while others would further block on the input buffer (due to needed rendering?). Maybe I am reading too much into it.
Author
Owner

@j4james commented on GitHub (Oct 5, 2021):

"16 notes of specified volume and duration" just refers the fact that the DECPS sequence takes one volume parameter, one duration parameter, and then multiple note parameters that are played with that volume and duration. If you want each note played at a different volume, or using a different duration, then you need a separate DECPS per note, but if you're playing a run of notes with the same volume and duration, you can do that with one DECPS and save a few bytes (and possibly also avoid the buffer being blocked).

@j4james commented on GitHub (Oct 5, 2021): "16 notes of specified volume and duration" just refers the fact that the `DECPS` sequence takes one volume parameter, one duration parameter, and then multiple note parameters that are played with that volume and duration. If you want each note played at a different volume, or using a different duration, then you need a separate `DECPS` per note, but if you're playing a run of notes with the same volume and duration, you can do that with one `DECPS` and save a few bytes (and possibly also avoid the buffer being blocked).
Author
Owner

@jerch commented on GitHub (Oct 5, 2021):

Multiple notes in one sequence? I only looked it up in EK-VT520-RM, seems I cannot find any trace of multiple notes in one sequence there. Where did you get that from?

@jerch commented on GitHub (Oct 5, 2021): Multiple notes in one sequence? I only looked it up in EK-VT520-RM, seems I cannot find any trace of multiple notes in one sequence there. Where did you get that from?
Author
Owner

@j4james commented on GitHub (Oct 5, 2021):

Yeah, I know it's not obvious - they mostly just show the one note parameter when documenting DECPS - but there's a section in the Set-Up chapter (2.17 Sound, page 2-60), which describes the multiple-note capabilities. In my pdf edition it's on page 92.

@j4james commented on GitHub (Oct 5, 2021): Yeah, I know it's not obvious - they mostly just show the one note parameter when documenting `DECPS` - but there's a section in the _Set-Up_ chapter (2.17 Sound, page 2-60), which describes the multiple-note capabilities. In my pdf edition it's on page 92.
Author
Owner

@jerch commented on GitHub (Oct 5, 2021):

Yepp found it, thx. Now reading all again the buffer description is not more obvious to me. The "16 ... of specified volume and duration" now kinda sounds like the buffer can only hold one volume/duration setting up to 16 notes?

Note the phrasing they use in that sentence:

Additional sound controls are held in the communications input buffer invoking receive data flow control as needed.

Do they refer to one volume/duration setting as "sound control"? Not clear to me. If so, I'd say any new sequence would not enter the buffer until it was drained, because every sequence carries a volume/duration setting, thus a "sound control". Ofc this might be the same as in the prev seq, but prolly gets not evaluated before the buffer is free? At least that would be my guess from that phrasing. It further would imply, that excess notes beyond 16 in one seq would be ignored. Not sure whats the CSI param limit of vt500+, imho they can only use up to 16 at all, thus you could effectively only fill the buffer up to 14 notes (16 - Pvolume - Pduration)? Well lots of guessing here...

Edit: I think the right buffer semantics is not that important here beside the blocking times, for proper emulation with correct micro timings (which ofc is needed with sound stuff) it might be enough to simulate the user experienced behavior.

Edit2: I still have one of those vt525 boxes I grabbed from our data center 15ys ago. But not sure if that still works (not even sure if it supports this particular sequence). Will see how that goes...

@jerch commented on GitHub (Oct 5, 2021): Yepp found it, thx. Now reading all again the buffer description is not more obvious to me. The "16 ... of specified volume and duration" now kinda sounds like the buffer can only hold one volume/duration setting up to 16 notes? Note the phrasing they use in that sentence: > Additional sound controls are held in the communications input buffer invoking receive data flow control as needed. Do they refer to one volume/duration setting as "sound control"? Not clear to me. If so, I'd say any new sequence would not enter the buffer until it was drained, because every sequence carries a volume/duration setting, thus a "sound control". Ofc this might be the same as in the prev seq, but prolly gets not evaluated before the buffer is free? At least that would be my guess from that phrasing. It further would imply, that excess notes beyond 16 in one seq would be ignored. Not sure whats the CSI param limit of vt500+, imho they can only use up to 16 at all, thus you could effectively only fill the buffer up to 14 notes (16 - Pvolume - Pduration)? Well lots of guessing here... Edit: I think the right buffer semantics is not that important here beside the blocking times, for proper emulation with correct micro timings (which ofc is needed with sound stuff) it might be enough to simulate the user experienced behavior. Edit2: I still have one of those vt525 boxes I grabbed from our data center 15ys ago. But not sure if that still works (not even sure if it supports this particular sequence). Will see how that goes...
Author
Owner

@j4james commented on GitHub (Oct 5, 2021):

kinda sounds like the buffer can only hold one volume/duration setting up to 16 notes?

Yeah, that's the conclusion I came to as well. But I had initially implemented it another way, so I wasn't that keen to rewrite everything until I was certain of the correct behaviour. At the time I was hoping to pick up a VT525 from somewhere, but then covid happened, and I've been barricading myself from the zombies apocalypse ever since.

Do they refer to one volume/duration setting as "sound control"?

They generally refer to escape sequences as control functions, so I figured "sound control" meant the DECPS sequence.

I'd say any new sequence would not enter the buffer until it was drained, because every sequence carries a volume/duration setting, thus a "sound control".

Yeah, that's my thinking too.

Not sure whats the CSI param limit of vt500+, imho they can only use up to 16 at all, thus you could effectively only fill the buffer up to 14 notes

I wondered about that as well. The DEC STD-070 specs says 16 is required, but the maximum is implementation defined, so it's reasonable to suppose the VT525 might have more than 16.

I still have one of those vt525 boxes I grabbed from our data center 15ys ago.

If you could get that working that would be fantastic!

@j4james commented on GitHub (Oct 5, 2021): > kinda sounds like the buffer can only hold one volume/duration setting up to 16 notes? Yeah, that's the conclusion I came to as well. But I had initially implemented it another way, so I wasn't that keen to rewrite everything until I was certain of the correct behaviour. At the time I was hoping to pick up a VT525 from somewhere, but then covid happened, and I've been barricading myself from the zombies apocalypse ever since. > Do they refer to one volume/duration setting as "sound control"? They generally refer to escape sequences as control functions, so I figured "sound control" meant the `DECPS` sequence. > I'd say any new sequence would not enter the buffer until it was drained, because every sequence carries a volume/duration setting, thus a "sound control". Yeah, that's my thinking too. > Not sure whats the CSI param limit of vt500+, imho they can only use up to 16 at all, thus you could effectively only fill the buffer up to 14 notes I wondered about that as well. The DEC STD-070 specs says 16 is required, but the maximum is implementation defined, so it's reasonable to suppose the VT525 might have more than 16. > I still have one of those vt525 boxes I grabbed from our data center 15ys ago. If you could get that working that would be fantastic!
Author
Owner

@jerch commented on GitHub (Oct 5, 2021):

@j4james Just tried to replicate their tuning scheme, but kinda cannot figure out, what they used here. For equal midi tuning the frequency values are too low (more like based on 420Hz), and too narrow (the highest value is more than 50Hz off). Do you have a clue about the tuning they used? To me it seems that the values are not really in tune to any standard system.

Edit: Ok had an midikey offset by one, the closest I get is without that error actually is this:

        	docs		equal tuning with 447
D#5		632		632
G#5		847		843
A#5		944		947
C#6		1047		1126

To me the last one seems totally off, like the docs got the wrong frequency number or denoting the wrong note (C6 is much closer). The other tiny differences can be explained by a different tuning scale (not a big deal).

@jerch commented on GitHub (Oct 5, 2021): @j4james Just tried to replicate their tuning scheme, but kinda cannot figure out, what they used here. For equal midi tuning the frequency values are too low (more like based on 420Hz), and too narrow (the highest value is more than 50Hz off). Do you have a clue about the tuning they used? To me it seems that the values are not really in tune to any standard system. Edit: Ok had an midikey offset by one, the closest I get is without that error actually is this: ``` docs equal tuning with 447 D#5 632 632 G#5 847 843 A#5 944 947 C#6 1047 1126 ``` To me the last one seems totally off, like the docs got the wrong frequency number or denoting the wrong note (C6 is much closer). The other tiny differences can be explained by a different tuning scale (not a big deal).
Author
Owner

@j4james commented on GitHub (Oct 5, 2021):

To me the last one seems totally off, like the docs got the wrong frequency number or denoting the wrong note

Yeah, I assumed that was a mistake in the documentation, which isn't that uncommon for these manuals. I just used the standard note numbers and ignored the frequency values. If I remember correctly, the other terminals I tried were doing the same thing, although I think one shifted everything an octave lower.

FYI, I'm using MIDI for this, so for DECPS note numbers 1 to 25, the corresponding MIDI values are 72 to 96.

@j4james commented on GitHub (Oct 5, 2021): > To me the last one seems totally off, like the docs got the wrong frequency number or denoting the wrong note Yeah, I assumed that was a mistake in the documentation, which isn't that uncommon for these manuals. I just used the standard note numbers and ignored the frequency values. If I remember correctly, the other terminals I tried were doing the same thing, although I think one shifted everything an octave lower. FYI, I'm using MIDI for this, so for `DECPS` note numbers 1 to 25, the corresponding MIDI values are 72 to 96.
Author
Owner

@jerch commented on GitHub (Oct 5, 2021):

Yeah I basically do the same, but tuned to 447 Hz. Well I have no ready-to-go MIDI backend, thus have to set up the oscillators myself (simple sine wave for now).

@jerch commented on GitHub (Oct 5, 2021): Yeah I basically do the same, but tuned to 447 Hz. Well I have no ready-to-go MIDI backend, thus have to set up the oscillators myself (simple sine wave for now).
Author
Owner

@jerch commented on GitHub (Oct 6, 2021):

@j4james Another question - how did you map the volume levels? I currently map them equally into 0 .. 1 gain, but thats not quite right in terms of perceived "flat" volume steps (for that an exponential adjustment would be needed).

(I will not get home to grab the device before 2 weeks, so maybe you have an informed guess here?)

@jerch commented on GitHub (Oct 6, 2021): @j4james Another question - how did you map the volume levels? I currently map them equally into 0 .. 1 gain, but thats not quite right in terms of perceived "flat" volume steps (for that an exponential adjustment would be needed). (I will not get home to grab the device before 2 weeks, so maybe you have an informed guess here?)
Author
Owner

@j4james commented on GitHub (Oct 6, 2021):

how did you map the volume levels?

I'm just taking the volume number in the range 0 to 7 and mapping that to a MIDI velocity in the range 0 to 127, using volume * 127 / 7. It's been a long time since I worked on this, but I vaguely remember experimenting with some sort of exponential scale and deciding in the end that it sounded best this way. But I don't know whether that's just because of the way that MIDI velocity is interpreted, so I'm not sure this is very helpful to you.

That said, I'm happy to adjust whatever I'm doing if it turns out that the real VT525 works differently.

@j4james commented on GitHub (Oct 6, 2021): > how did you map the volume levels? I'm just taking the volume number in the range 0 to 7 and mapping that to a MIDI velocity in the range 0 to 127, using `volume * 127 / 7`. It's been a long time since I worked on this, but I vaguely remember experimenting with some sort of exponential scale and deciding in the end that it sounded best this way. But I don't know whether that's just because of the way that MIDI velocity is interpreted, so I'm not sure this is very helpful to you. That said, I'm happy to adjust whatever I'm doing if it turns out that the real VT525 works differently.
Author
Owner

@jerch commented on GitHub (Oct 7, 2021):

Changed it to a 2^n mapping on the gain, which sounds good to me in terms of dynamics discrimination. If I get the maths right behind it, that roughly covers a range of 48dB, as gain works a factor on the amplitude, where doubling accounts for ~6dB. (Well the range is a bit lower, as I had to use a compressor to get the crossfading of the oscillators clicking free.)

My early take on the sequence: https://github.com/xtermjs/xterm.js/pull/3494
(The implementation is certainly wrong in the blocking semantics, it currently blocks on every note for its playing time.)

@jerch commented on GitHub (Oct 7, 2021): Changed it to a 2^n mapping on the gain, which sounds good to me in terms of dynamics discrimination. If I get the maths right behind it, that roughly covers a range of 48dB, as gain works a factor on the amplitude, where doubling accounts for ~6dB. (Well the range is a bit lower, as I had to use a compressor to get the crossfading of the oscillators clicking free.) My early take on the sequence: https://github.com/xtermjs/xterm.js/pull/3494 (The implementation is certainly wrong in the blocking semantics, it currently blocks on every note for its playing time.)
Author
Owner

@mintty commented on GitHub (Oct 14, 2021):

@j4james, would you mind uploading your mspacman.txt test file, please?

@mintty commented on GitHub (Oct 14, 2021): @j4james, would you mind uploading your mspacman.txt test file, please?
Author
Owner

@j4james commented on GitHub (Oct 14, 2021):

@mintty I'd rather not do that yet, as that animation is based on my initial implementation that I'm almost sure is wrong. I don't want you (or anyone else) to try and be compatible with that if it's going to end up making your implementation incorrect too. Hopefully @jerch will be able to confirm the correct behaviour in the near future, and then I'll be happy to regenerate some proper test cases.

In the meantime, though, if you just want some test music (without the animations), I've got a few that I can probably add to a gist.

@j4james commented on GitHub (Oct 14, 2021): @mintty I'd rather not do that yet, as that animation is based on my initial implementation that I'm almost sure is wrong. I don't want you (or anyone else) to try and be compatible with that if it's going to end up making your implementation incorrect too. Hopefully @jerch will be able to confirm the correct behaviour in the near future, and then I'll be happy to regenerate some proper test cases. In the meantime, though, if you just want some test music (without the animations), I've got a few that I can probably add to a gist.
Author
Owner

@j4james commented on GitHub (Oct 14, 2021):

Actually it turns out I already these as a bunch of printf statements which you should just be able to paste into a bash shell. I'm afraid they're kind of crap, but it's at least something to test with.

Ms Pac-Man Theme
printf "\e[3;2;1;3;5,~\e[3;8;6;10;8;11,~\e[3;4;10;11;13;10,~\e[3;8;8;11,~\e[3;4;10;11;13;10;11;13;15;17,~\e[3;8;18;17;18,~"

In the Hall of the Mountain King
printf "\e[3;8;1;3;4;6;8;4,~\e[3;16;8,~\e[3;8;7;3,~\e[3;16;7,~\e[3;8;6;2,~\e[3;16;6,~\e[3;8;1;3;4;6;8;4;8;13;11;8;4;8,~\e[3;32;11,~\e[3;8;8;10;12;13;15;12,~\e[3;16;15,~\e[3;8;16;12,~\e[3;16;16,~\e[3;8;15;12,~\e[3;16;15,~\e[3;8;8;10;12;13;15;12,~\e[3;16;15,~\e[3;8;16;12,~\e[3;16;16,~\e[3;32;15,~\e[3;8;13;15;16;18;20;16,~\e[3;16;20,~\e[3;8;19;15,~\e[3;16;19,~\e[3;8;18;14,~\e[3;16;18,~\e[3;8;13;15;16;18;20;16;20;25;23;20;16;20,~\e[3;32;23,~"

Jingle Bells
printf "\e[3;8;12;12,~\e[3;16;12,~\e[3;8;12;12,~\e[3;16;12,~\e[3;8;12;15,~\e[3;12;8,~\e[3;4;10,~\e[3;24;12,~\e[3;8;0;13;13,~\e[3;12;13,~\e[3;4;13,~\e[3;8;13;12;12,~\e[3;4;12;12,~\e[3;8;15;15;13;10,~\e[3;24;8,~\e[3;8;0,~"

Happy Birthday
printf "\e[3;10;8,~\e[3;5;8,~\e[3;15;10;8;13,~\e[3;30;12,~\e[3;10;8,~\e[3;5;8,~\e[3;15;10;8;15,~\e[3;30;13,~\e[3;10;8,~\e[3;5;8,~\e[3;15;20;17;13;12,~\e[3;30;10,~\e[3;10;18,~\e[3;5;18,~\e[3;15;17;13;15,~\e[3;30;13,~"

Harry Potter Theme
printf "\e[3;12;3,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;8,~\e[3;12;15,~\e[3;36;13;10,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;7,~\e[3;12;9,~\e[3;60;3,~\e[3;12;3,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;8,~\e[3;12;15,~\e[3;24;18,~\e[3;12;17,~\e[3;24;16,~\e[3;12;12,~\e[3;18;16,~\e[3;6;15,~\e[3;12;14,~\e[3;24;2,~\e[3;12;11,~\e[3;60;8,~"

Indiana Jones Theme
printf "\e[3;9;5,~\e[3;3;6,~\e[3;6;8,~\e[3;30;13,~\e[3;9;3,~\e[3;3;5,~\e[3;36;6,~\e[3;9;8,~\e[3;3;10,~\e[3;6;12,~\e[3;30;18,~\e[3;9;10,~\e[3;3;12,~\e[3;12;13;15;17,~\e[3;9;5,~\e[3;3;6,~\e[3;6;8,~\e[3;30;13,~\e[3;9;15,~\e[3;3;17,~\e[3;36;18,~\e[3;9;8,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;18,~\e[3;9;17,~\e[3;3;15,~\e[3;48;13,~"

Star Wars: Imperial March
printf "\e[3;20;7;7;7,~\e[3;15;3,~\e[3;5;10,~\e[3;20;7,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~\e[3;20;14;14;14,~\e[3;15;15,~\e[3;5;10,~\e[3;20;6,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~\e[3;20;19;7;19,~\e[3;10;18;17,~\e[3;5;16;15,~\e[3;10;16;0;8,~\e[3;20;13,~\e[3;10;12;11,~\e[3;5;10;9,~\e[3;10;10;0;3,~\e[3;20;6,~\e[3;15;3,~\e[3;5;10,~\e[3;20;7,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~"

Cavalry Charge (Bugle Call)
printf "\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;36;1,~"

Reveille (Bugle Call)
printf "\e[3;8;1;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;6,~\e[3;16;10,~\e[3;8;6;1;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;1,~\e[3;24;6,~\e[3;8;10;10;10;10;10,~\e[3;16;13,~\e[3;8;10;6;10;6;10;6,~\e[3;16;10,~\e[3;8;6;10;10;10;10;10,~\e[3;16;13,~\e[3;8;10;6;10;6;1;1,~\e[3;24;6,~"

@j4james commented on GitHub (Oct 14, 2021): Actually it turns out I already these as a bunch of `printf` statements which you should just be able to paste into a bash shell. I'm afraid they're kind of crap, but it's at least something to test with. Ms Pac-Man Theme ```printf "\e[3;2;1;3;5,~\e[3;8;6;10;8;11,~\e[3;4;10;11;13;10,~\e[3;8;8;11,~\e[3;4;10;11;13;10;11;13;15;17,~\e[3;8;18;17;18,~"``` In the Hall of the Mountain King ```printf "\e[3;8;1;3;4;6;8;4,~\e[3;16;8,~\e[3;8;7;3,~\e[3;16;7,~\e[3;8;6;2,~\e[3;16;6,~\e[3;8;1;3;4;6;8;4;8;13;11;8;4;8,~\e[3;32;11,~\e[3;8;8;10;12;13;15;12,~\e[3;16;15,~\e[3;8;16;12,~\e[3;16;16,~\e[3;8;15;12,~\e[3;16;15,~\e[3;8;8;10;12;13;15;12,~\e[3;16;15,~\e[3;8;16;12,~\e[3;16;16,~\e[3;32;15,~\e[3;8;13;15;16;18;20;16,~\e[3;16;20,~\e[3;8;19;15,~\e[3;16;19,~\e[3;8;18;14,~\e[3;16;18,~\e[3;8;13;15;16;18;20;16;20;25;23;20;16;20,~\e[3;32;23,~"``` Jingle Bells ```printf "\e[3;8;12;12,~\e[3;16;12,~\e[3;8;12;12,~\e[3;16;12,~\e[3;8;12;15,~\e[3;12;8,~\e[3;4;10,~\e[3;24;12,~\e[3;8;0;13;13,~\e[3;12;13,~\e[3;4;13,~\e[3;8;13;12;12,~\e[3;4;12;12,~\e[3;8;15;15;13;10,~\e[3;24;8,~\e[3;8;0,~"``` Happy Birthday ```printf "\e[3;10;8,~\e[3;5;8,~\e[3;15;10;8;13,~\e[3;30;12,~\e[3;10;8,~\e[3;5;8,~\e[3;15;10;8;15,~\e[3;30;13,~\e[3;10;8,~\e[3;5;8,~\e[3;15;20;17;13;12,~\e[3;30;10,~\e[3;10;18,~\e[3;5;18,~\e[3;15;17;13;15,~\e[3;30;13,~"``` Harry Potter Theme ```printf "\e[3;12;3,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;8,~\e[3;12;15,~\e[3;36;13;10,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;7,~\e[3;12;9,~\e[3;60;3,~\e[3;12;3,~\e[3;18;8,~\e[3;6;11,~\e[3;12;10,~\e[3;24;8,~\e[3;12;15,~\e[3;24;18,~\e[3;12;17,~\e[3;24;16,~\e[3;12;12,~\e[3;18;16,~\e[3;6;15,~\e[3;12;14,~\e[3;24;2,~\e[3;12;11,~\e[3;60;8,~"``` Indiana Jones Theme ```printf "\e[3;9;5,~\e[3;3;6,~\e[3;6;8,~\e[3;30;13,~\e[3;9;3,~\e[3;3;5,~\e[3;36;6,~\e[3;9;8,~\e[3;3;10,~\e[3;6;12,~\e[3;30;18,~\e[3;9;10,~\e[3;3;12,~\e[3;12;13;15;17,~\e[3;9;5,~\e[3;3;6,~\e[3;6;8,~\e[3;30;13,~\e[3;9;15,~\e[3;3;17,~\e[3;36;18,~\e[3;9;8,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;17,~\e[3;9;15,~\e[3;3;8,~\e[3;12;18,~\e[3;9;17,~\e[3;3;15,~\e[3;48;13,~"``` Star Wars: Imperial March ```printf "\e[3;20;7;7;7,~\e[3;15;3,~\e[3;5;10,~\e[3;20;7,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~\e[3;20;14;14;14,~\e[3;15;15,~\e[3;5;10,~\e[3;20;6,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~\e[3;20;19;7;19,~\e[3;10;18;17,~\e[3;5;16;15,~\e[3;10;16;0;8,~\e[3;20;13,~\e[3;10;12;11,~\e[3;5;10;9,~\e[3;10;10;0;3,~\e[3;20;6,~\e[3;15;3,~\e[3;5;10,~\e[3;20;7,~\e[3;15;3,~\e[3;5;10,~\e[3;40;7,~"``` Cavalry Charge (Bugle Call) ```printf "\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;1,~\e[3;3;0;1,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;6;8,~\e[3;3;0;5,~\e[3;36;1,~"``` Reveille (Bugle Call) ```printf "\e[3;8;1;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;6,~\e[3;16;10,~\e[3;8;6;1;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;10;6,~\e[3;4;10;6,~\e[3;8;1;1,~\e[3;24;6,~\e[3;8;10;10;10;10;10,~\e[3;16;13,~\e[3;8;10;6;10;6;10;6,~\e[3;16;10,~\e[3;8;6;10;10;10;10;10,~\e[3;16;13,~\e[3;8;10;6;10;6;1;1,~\e[3;24;6,~"```
Author
Owner

@jerch commented on GitHub (Oct 14, 2021):

@j4james Nice programming work (I guess you did that manually). There are only 2 or 3 glitches (notes and timings) as far as I remember those themes. 😸

Edit: Time to write a to/from MIDI converter? (jk)

@jerch commented on GitHub (Oct 14, 2021): @j4james Nice programming work (I guess you did that manually). There are only 2 or 3 glitches (notes and timings) as far as I remember those themes. :smile_cat: Edit: Time to write a to/from MIDI converter? (jk)
Author
Owner

@j4james commented on GitHub (Oct 14, 2021):

Yeah it was done manually. The simple ones I think I just copied directly from sheet music, but converting an orchestral score for a movie into a single channel of beeps was a little more complicated. 😊 To make things easier, I looked for some beginner piano renditions on youtube, and from there I just selected the subset of notes that I thought best represented the theme. Obviously not always with great results, but I think they're still fun to play with.

@j4james commented on GitHub (Oct 14, 2021): Yeah it was done manually. The simple ones I think I just copied directly from sheet music, but converting an orchestral score for a movie into a single channel of beeps was a little more complicated. 😊 To make things easier, I looked for some beginner piano renditions on youtube, and from there I just selected the subset of notes that I thought best represented the theme. Obviously not always with great results, but I think they're still fun to play with.
Author
Owner

@mintty commented on GitHub (Oct 18, 2021):

@j4james, thanks for the printf examples, but how should they be interpreted? DECPS only defines 3 parameter per CSI sequence.

@mintty commented on GitHub (Oct 18, 2021): @j4james, thanks for the printf examples, but how should they be interpreted? DECPS only defines 3 parameter per CSI sequence.
Author
Owner

@j4james commented on GitHub (Oct 18, 2021):

@mintty See the comments above: https://github.com/microsoft/terminal/issues/8687#issuecomment-934215722

@j4james commented on GitHub (Oct 18, 2021): @mintty See the comments above: https://github.com/microsoft/terminal/issues/8687#issuecomment-934215722
Author
Owner

@ghost commented on GitHub (Jul 6, 2022):

:tada:This issue was addressed in #13208, which has now been successfully released as Windows Terminal Preview v1.15.186.🎉

Handy links:

@ghost commented on GitHub (Jul 6, 2022): :tada:This issue was addressed in #13208, which has now been successfully released as `Windows Terminal Preview v1.15.186`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.15.186) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Author
Owner

@al20878 commented on GitHub (Feb 19, 2023):

DECPS can only play one note at a time.
DECPS_EK-VT520-RM_VT520_VT525_Programmer_Information_Jul94.pdf
This has been verified in the real hardware (VT520). Even though a sequence with multiple notes was shown elsewhere in the manual, it seems to be in error, and the multiple notes of the same volume and duration cannot be played by the same escape sequence. Each note must be programmed individually by its own escape sequence. If more than one notes specified, only the first one is actually played, and the remaining are simply ignored (without any added delay for the would-be duration).

@al20878 commented on GitHub (Feb 19, 2023): DECPS can only play one note at a time. [DECPS_EK-VT520-RM_VT520_VT525_Programmer_Information_Jul94.pdf](https://github.com/microsoft/terminal/files/10775972/DECPS_EK-VT520-RM_VT520_VT525_Programmer_Information_Jul94.pdf) This has been verified in the real hardware (VT520). Even though a sequence with multiple notes was shown elsewhere in the manual, it seems to be in error, and the multiple notes of the same volume and duration cannot be played by the same escape sequence. Each note must be programmed individually by its own escape sequence. If more than one notes specified, only the first one is actually played, and the remaining are simply ignored (without any added delay for the would-be duration).
Author
Owner

@j4james commented on GitHub (Feb 19, 2023):

@al20878 Thanks for pointing that out, but we were aware of that. It was discussed in the thread here: https://github.com/jerch/xterm.js/issues/1#issuecomment-966387953. But ultimately I decided it was worth keeping multiple note support as an extension. Quoting myself from that thread:

Thinking about this some more, I'm inclined to leave in support for multiple notes even if the VT525 didn't actually support that. It is at least part of the official documentation, it's not likely to break backwards compatibility with apps that are limiting themselves to one note at a time, and there are already a number of modern terminals supporting multiple notes.

@j4james commented on GitHub (Feb 19, 2023): @al20878 Thanks for pointing that out, but we were aware of that. It was discussed in the thread here: https://github.com/jerch/xterm.js/issues/1#issuecomment-966387953. But ultimately I decided it was worth keeping multiple note support as an extension. Quoting myself from that thread: > Thinking about this some more, I'm inclined to leave in support for multiple notes even if the VT525 didn't actually support that. It is at least part of the official documentation, it's not likely to break backwards compatibility with apps that are limiting themselves to one note at a time, and there are already a number of modern terminals supporting multiple notes.
Author
Owner

@al20878 commented on GitHub (Feb 19, 2023):

https://github.com/jerch/xterm.js/issues/1#issuecomment-966387953.

Thanks, that's good to know! And that's exactly how I noticed it, too: the sample "melodies" up from this thread won't play on VT520. BTW, the comment seems to be unsure whether the last note would be playing -- while in fact VT520 plays only the first one, skipping all the rest from the same escape sequence -- verified.

So as implemented, the feature is an extended and backward compatible version of DECPS (would play output designed for VT52x), but it's not forward compatible. Thanks for making it clear now!

@al20878 commented on GitHub (Feb 19, 2023): > https://github.com/jerch/xterm.js/issues/1#issuecomment-966387953. Thanks, that's good to know! And that's exactly how I noticed it, too: the sample "melodies" up from this thread won't play on VT520. BTW, the comment seems to be unsure whether the last note would be playing -- while in fact VT520 plays only the first one, skipping all the rest from the same escape sequence -- verified. So as implemented, the feature is an extended and backward compatible version of DECPS (would play output designed for VT52x), but it's not forward compatible. Thanks for making it clear now!
Author
Owner

@j4james commented on GitHub (Feb 19, 2023):

So as implemented, the feature is an extended and backward compatible version of DECPS (would play output designed for VT52x), but it's not forward compatible.

@al20878 Yeah, that was the plan for now. Eventually I'm hoping we'll be able to gives users the option to specify exactly which terminal type they want to emulate, and then we can be more strict in terms of what we support, and disable the proprietary extensions like this. For now, though, I'm just going for backwards compatibility.

Btw, do you actually have a VT520 of your own that you're testing with? And if so, would you be willing to help us out with some additional testing? Right now I'm looking at the horizontal margin functionality, and I've created a bunch test cases I was hoping to persuade someone to run (see https://github.com/microsoft/terminal/issues/14876#issuecomment-1435959985). A VT520 would be perfect for that, but it's not essential if you don't the time.

@j4james commented on GitHub (Feb 19, 2023): > So as implemented, the feature is an extended and backward compatible version of DECPS (would play output designed for VT52x), but it's not forward compatible. @al20878 Yeah, that was the plan for now. Eventually I'm hoping we'll be able to gives users the option to specify exactly which terminal type they want to emulate, and then we can be more strict in terms of what we support, and disable the proprietary extensions like this. For now, though, I'm just going for backwards compatibility. Btw, do you actually have a VT520 of your own that you're testing with? And if so, would you be willing to help us out with some additional testing? Right now I'm looking at the horizontal margin functionality, and I've created a bunch test cases I was hoping to persuade someone to run (see https://github.com/microsoft/terminal/issues/14876#issuecomment-1435959985). A VT520 would be perfect for that, but it's not essential if you don't the time.
Author
Owner

@al20878 commented on GitHub (Feb 19, 2023):

@j4james I do have the real VT320, 330, 420, 520 (and 525 temporarily, I think). The terminals are connected to ancient OS's (like RSX11M or RSTS/E), and unfortunately don't fare will with Linux (because of the buffer overrun issues in the USB-UART port drivers, when software flow control is used -- it's a long story worth a long discussion). Your script seems to be written in Python, which my older (and well-behaving) OS's do not know (it wasn't invented back then). I can try running it on Linux, though, but because of the above-mentioned serial port issues, there's no guarantee of the correct results, however.

@al20878 commented on GitHub (Feb 19, 2023): @j4james I do have the real VT320, 330, 420, 520 (and 525 temporarily, I think). The terminals are connected to ancient OS's (like RSX11M or RSTS/E), and unfortunately don't fare will with Linux (because of the buffer overrun issues in the USB-UART port drivers, when software flow control is used -- it's a long story worth a long discussion). Your script seems to be written in Python, which my older (and well-behaving) OS's do not know (it wasn't invented back then). I can try running it on Linux, though, but because of the above-mentioned serial port issues, there's no guarantee of the correct results, however.
Author
Owner

@j4james commented on GitHub (Feb 19, 2023):

@al20878 Wow! That's an impressive collection. Don't stress if you can't my test running, though. If I don't get a response from anyone else I can always try rewriting it in C.

@j4james commented on GitHub (Feb 19, 2023): @al20878 Wow! That's an impressive collection. Don't stress if you can't my test running, though. If I don't get a response from anyone else I can always try rewriting it in C.
Author
Owner

@al20878 commented on GitHub (Mar 6, 2023):

Hi @j4james !
I had some spare time this weekend and was able to make a serial cable to connect VT520 to Linux (RPi). Then I downloaded your .py script and ran it. It runs pretty long, so I had to cancel it at some point (esp. when it was filling up the screen with letters and doing some text cutting), but I did notice output in reverse meaning (according to the opening comments in the source code) that some assumptions were not met. Anyways, I'm not exactly sure how to share the results with you. I can take a video on my phone and then send you a link. Also, I can try running the same thing (now that the cable is there) on VT420...

@al20878 commented on GitHub (Mar 6, 2023): Hi @j4james ! I had some spare time this weekend and was able to make a serial cable to connect VT520 to Linux (RPi). Then I downloaded your .py script and ran it. It runs pretty long, so I had to cancel it at some point (esp. when it was filling up the screen with letters and doing some text cutting), but I did notice output in reverse meaning (according to the opening comments in the source code) that some assumptions were not met. Anyways, I'm not exactly sure how to share the results with you. I can take a video on my phone and then send you a link. Also, I can try running the same thing (now that the cable is there) on VT420...
Author
Owner

@j4james commented on GitHub (Mar 6, 2023):

Thanks for testing @al20878. I've replied to your message in issue #14876 where this functionality is being tracked.

@j4james commented on GitHub (Mar 6, 2023): Thanks for testing @al20878. I've replied to your message in issue #14876 where this functionality is being tracked.
Author
Owner

@christianparpart commented on GitHub (May 23, 2023):

@al20878 Thanks for pointing that out, but we were aware of that. It was discussed in the thread here: jerch/xterm.js#1 (comment). But ultimately I decided it was worth keeping multiple note support as an extension. Quoting myself from that thread:

We (Contour terminal) do also support the mutliple notes notation (played sequentially). I wonder how many other modernish terminals can actually interpret DECPS apart from Windows Terminal and Contour. 🤔

@christianparpart commented on GitHub (May 23, 2023): > @al20878 Thanks for pointing that out, but we were aware of that. It was discussed in the thread here: [jerch/xterm.js#1 (comment)](https://github.com/jerch/xterm.js/issues/1#issuecomment-966387953). But ultimately I decided it was worth keeping multiple note support as an extension. Quoting myself from that thread: We (Contour terminal) do also support the mutliple notes notation (played sequentially). I wonder how many other modernish terminals can actually interpret DECPS apart from Windows Terminal and Contour. 🤔
Author
Owner

@mintty commented on GitHub (May 23, 2023):

I wonder how many other modernish terminals can actually interpret DECPS

Mintty does, and offers a choice of sounds, produced with libao.

@mintty commented on GitHub (May 23, 2023): > I wonder how many other modernish terminals can actually interpret DECPS Mintty does, and offers a choice of sounds, produced with libao.
Author
Owner

@j4james commented on GitHub (May 23, 2023):

@christianparpart That's excellent news!

Regarding other terminals, I believe ANSICON and RLogin both had some form of DECPS support long before we added it to Windows Terminal. And I think Mintty and Xterm.js added support around the same time as us. So with Contour joining the club, that's now at least 6 that I know of. That's not a bad level of support for a feature that most people probably haven't heard of.

Edit: Just double checking Xterm.js, and it looks to me like they never actually shipped their sound addon (https://github.com/xtermjs/xterm.js/pull/3494). That's a bit disappointing.

Edit2: I've also now realized you actually added DECPS support ages ago. I thought that was a new thing. I don't know how I missed the initial release.

@j4james commented on GitHub (May 23, 2023): @christianparpart That's excellent news! Regarding other terminals, I believe [ANSICON](https://github.com/adoxa/ansicon) and [RLogin](https://github.com/kmiya-culti/RLogin/) both had some form of `DECPS` support long before we added it to Windows Terminal. And I think Mintty and Xterm.js added support around the same time as us. So with Contour joining the club, that's now at least 6 that I know of. That's not a bad level of support for a feature that most people probably haven't heard of. Edit: Just double checking Xterm.js, and it looks to me like they never actually shipped their sound addon (https://github.com/xtermjs/xterm.js/pull/3494). That's a bit disappointing. Edit2: I've also now realized you actually added `DECPS` support ages ago. I thought that was a new thing. I don't know how I missed the initial release.
Author
Owner

@al20878 commented on GitHub (May 23, 2023):

Mintty does, and offers a choice of sounds, produced with libao.
Cool @mintty! Just tried my test file for VT52x -- in Cygwin, it played the right notes (DECPS programmed one note at a time, suitable for the real HW) but rather choppy (audible gaps in between) -- and also the "cat" command (used to output the file) visually completed even before the terminal started playing (the OS prompt popped up) -- again, it's not what the real terminal does -- it is processing the output strictly sequentially -- that is, the last note has to finish playing before the OS prompt appears (even though the "cat" command could have exited way earlier when it was done with the output to stdout). Though, this is probably way off-topic for this MS terminal thread...

@al20878 commented on GitHub (May 23, 2023): > Mintty does, and offers a choice of sounds, produced with libao. Cool @mintty! Just tried my test file for VT52x -- in Cygwin, it played the right notes (DECPS programmed one note at a time, suitable for the real HW) but rather choppy (audible gaps in between) -- and also the "cat" command (used to output the file) visually completed even before the terminal started playing (the OS prompt popped up) -- again, it's not what the real terminal does -- it is processing the output strictly sequentially -- that is, the last note has to finish playing before the OS prompt appears (even though the "cat" command could have exited way earlier when it was done with the output to stdout). Though, this is probably way off-topic for this MS terminal thread...
Author
Owner

@j4james commented on GitHub (May 23, 2023):

@al20878 Unfortunately not everyone handles the buffering correctly. From my past notes, I think ANSICON and Xterm.js got it right, but Mintty and RLogin don't block, and can sometimes drop notes (as you've noticed). It's not really a problem for apps that can handle the timing themselves with a manual delay, but it means you can't create simple text file animations that synchronize with the sound. That's actually one of the test cases I was hoping to create for you at some point, but I'm still blocked on the DECSTGLT stuff at the moment.

@j4james commented on GitHub (May 23, 2023): @al20878 Unfortunately not everyone handles the buffering correctly. From my past notes, I think ANSICON and Xterm.js got it right, but Mintty and RLogin don't block, and can sometimes drop notes (as you've noticed). It's not really a problem for apps that can handle the timing themselves with a manual delay, but it means you can't create simple text file animations that synchronize with the sound. That's actually one of the test cases I was hoping to create for you at some point, but I'm still blocked on the `DECSTGLT` stuff at the moment.
Author
Owner

@mintty commented on GitHub (May 23, 2023):

For mintty, please install the package libao in addition (mentioned in the manual). Without it, mintty falls back to a simplified beep-style playing, with artefacts as you noticed.

@mintty commented on GitHub (May 23, 2023): For mintty, please install the package `libao` in addition (mentioned in the manual). Without it, mintty falls back to a simplified beep-style playing, with artefacts as you noticed.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11929