NodeJS - Converting MTC (Midi Timecode) "quater message" into a full timecode string - javascript

So here's my problem. I'm working on a script in NodeJS, that will take an MTC, or MIDI Timecode signal, and eventually, trigger different things off of certain points in said timecode.
The issue I'm having currently is that the current Timecode clock program I am using, sends the MIDI timecode message as what is known as a "quarter frame" message. Put simply, it sends, in hex, eight consecutive messages, that altogether make up the hh:mm:ss:ff (hour, minute, second, frame) format. If the first message is 00, that means that the units digit of the frames number is 0 (still in hex), if the second message is 15, from the 1, that means that the frames tens digit is 5. That's a super dodgy explanation, so here is the only valid documentation I could find to explain it.
I managed to find another StackOverflow question that is the same, except the code provided is in C#, and I don't know how to translate that over to JavaScript with my limited knowledge. Here is that question.
Thanks in advance

There is a library named JZZ.js that, among other things, allows to convert sequential MTC into a time code.
A code snippet is available at https://jazz-soft.net/doc/JZZ/smpte.html#read
code:
var master = JZZ.SMPTE(); // master clock
var slave = JZZ.SMPTE(); // slave clock
var sender = JZZ.Widget(); // sending port
var receiver = JZZ.Widget(); // receiving port
receiver._receive = function(msg) {
if (slave.read(msg)) // print and consume the MTC messages
console.log(master.toString(), ' ==> ', msg.toString(), ' ==> ', slave.toString());
else _emit(msg); // forward all other MIDI messages
};
sender.connect(receiver);
master.reset(24, 7, 39, 59); // 7:40 it arrives...
for (var n = 0; n < 25; n++) {
sender.mtc(master);
master.incrQF();
}
output:
07:39:59:00 ==> f1 00 -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 10 -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 2b -- MIDI Time Code ==> 00:00:00:00
07:39:59:00 ==> f1 33 -- MIDI Time Code ==> 00:00:00:00
07:39:59:01 ==> f1 47 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 52 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 67 -- MIDI Time Code ==> 00:00:00:01
07:39:59:01 ==> f1 70 -- MIDI Time Code ==> 00:00:00:01
07:39:59:02 ==> f1 02 -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 10 -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 2b -- MIDI Time Code ==> 07:39:59:02
07:39:59:02 ==> f1 33 -- MIDI Time Code ==> 07:39:59:02
07:39:59:03 ==> f1 47 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 52 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 67 -- MIDI Time Code ==> 07:39:59:03
07:39:59:03 ==> f1 70 -- MIDI Time Code ==> 07:39:59:03
07:39:59:04 ==> f1 04 -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 10 -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 2b -- MIDI Time Code ==> 07:39:59:04
07:39:59:04 ==> f1 33 -- MIDI Time Code ==> 07:39:59:04
07:39:59:05 ==> f1 47 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 52 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 67 -- MIDI Time Code ==> 07:39:59:05
07:39:59:05 ==> f1 70 -- MIDI Time Code ==> 07:39:59:05
07:39:59:06 ==> f1 06 -- MIDI Time Code ==> 07:39:59:06

Related

What is LdaKeyedProperty in V8 byte code?

This is a sample V8 byte code.
984 E> 00000318BA8792D3 # 41 : 29 02 07 LdaKeyedProperty a0, [7]
"Ld" means "load" (from memory)
"a" means "to the accumulator register" (as most bytecodes)
"KeyedProperty" means it's for JS code like obj[index] (as opposed to a "named property" like obj.foo).

How can I parse a string with a date calculation like now + 1 days into a date object?

I'm currently using Cucumber to define our test cases in string based feature files. The integration tests will run against a wiremock stub which has date calculations like: "{{now offset='+15 minutes'}}"
I want to validate that the date and time I'm getting from the wiremock stub are displayed correctly, that the date and time are correct and that the table is ordered properly based on that date and time.
We currently have our own implementation to get now +/- X days. That uses some regex and only supports days. I can expand that code and add minutes to that but I would much rather use a library or a standardized piece of code that can parse all date calculations. I haven't been able to find it and would love some suggestions on how to solve this.
To give you an idea of what I'm working with at the moment:
function stringReplaceNow(string) {
var regex = /<now:([A-Z-]+):?((\+|-)([0-9]+))?>/gi;
return string.replace(regex, function (match, format, shouldModify, modification, modAmount) {
if (modification === '+') {
return moment().add(modAmount, 'days').format(format);
} else if (modification === '-') {
return moment().subtract(modAmount, 'days').format(format);
}
return moment().format(format);
});
}
In our cucumber tests it gets used like this, it will get the current date and subtract the days accordingly:
| Name | Datetime | State |
| Johnson | <now:DD-MM-YYYY:-2> | Processing |
| Minter | <now:DD-MM-YYYY:-3> | Processing |
| Brown | <now:DD-MM-YYYY:-5> | Done |
There are no standards for date calculations so I doubt you'll find a library for it. However you can use parts of the existing standards so simplify your custom date calculations.
In this instance, rather then developing your own format consider using the ISO-8601 duration format. You can then use existing libraries to parse the duration format and add it to the current time.
Examples:
"PT20.345S" -- parses as "20.345 seconds"
"PT15M" -- parses as "15 minutes" (where a minute is 60 seconds)
"PT10H" -- parses as "10 hours" (where an hour is 3600 seconds)
"P2D" -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
"P2DT3H4M" -- parses as "2 days, 3 hours and 4 minutes"
"PT-6H3M" -- parses as "-6 hours and +3 minutes"
"-PT6H3M" -- parses as "-6 hours and -3 minutes"
"-PT-6H+3M" -- parses as "+6 hours and -3 minutes"
Try using DayJs. Its is light weight and having more features than momentjs.

momentjs time comparison with timezone

I am trying to compare two times:
Time A : A datetime which I know is in 'America/Chicago' timezone
Time B : A datetime for current time which I want to convert to 'America/Chicago' and compare to Time A.
I am doing this simple test and unable to understand why all the below give the same result:
moment('05/31/2018 03:25:00').tz('America/Chicago').diff(moment().tz('America/Phoenix'), 'minutes')
Result: 111
moment('05/31/2018 03:25:00').tz('America/Chicago').diff(moment().tz('America/Los_Angeles'), 'minutes')
Result: 110
moment('05/31/2018 03:25:00').tz('America/Chicago').diff(moment().tz('America/Chicago'), 'minutes')
Result: 110
moment('05/31/2018 03:25:00').diff(moment().tz('America/Chicago'), 'minutes')
Result: 110
Note: my system current time is 01:25 PST. So, I believe moment().tz('America/Los_Angeles') should mean 01:25 PST.
Please correct where I am going wrong. I am basically trying to compare a time in CST with current time in PST and find out what's the difference in minutes in real time.

Timezone parsing inferno

I have this ISO date:
var v = '2013-07-09T13:27:29.000Z';
If I do this:
var g = moment(v).format();
Console gives me g value as the correct local time 2013-07-08T17:25:08-03:00
But if I do this to get the time ago:
console.log(moment(g).startOf('day').fromNow());
Moments calculates the time ago using original v ISO instead of the formatted g.
Why?
Edit: I have tested another time plugin (jquery.timeago) and the same error parsing to local time happens when passing the original v value.
What am I doing wrong here? This code is being executed on client side, so all plugins were supposed to return the correct local time for the user.
Edit 2: More relevant info on what I'm trying to do:
var v = notifs.ntime; //2013-07-09T13:27:29.000Z
var m = moment(v).zone(v).format(); // 2013-07-09T13:27:29+00:00 (wrong local)
var m2 = moment(v).format(); // 2013-07-09 10:27:29 (correct local)
var r = moment(v).zone(v).startOf('day').fromNow() // 21 hours ago (wrong)
var r2 = moment(v).startOf('day').fromNow() // 18 hours ago (wrong)
console.log(v);
console.log(m);
console.log(m2);
console.log(r);
console.log(r2);
console.log('-------------------');
/*
2013-07-09T13:27:29.000Z
2013-07-09T13:27:29+00:00
2013-07-09T10:27:29-03:00
21 hours ago
18 hours ago
-------------------
I expected "8 hours ago" as now is 18:10 and (v) was set on 10:27 (m2)
*/
I'm not quite sure I follow what you're looking for.
By using your g variable, you are essentially doing this:
moment(moment(v).format()).startOf('day').fromNow()
That is a bit redundant. It is the exact same thing as this:
moment(v).startOf('day').fromNow()
That will tell you how much time has passed between now and the start of the local day that v fell on.
If you are looking for how much time as passed between now and the start of the UTC day that v fell on, then use this instead:
moment.utc(v).startOf('day').fromNow()
Or using a slightly different syntax, but identical in effect:
moment(v).utc().startOf('day').fromNow()
If you were looking for something else, please clarify.
Walkthrough
Let's walk through what happens when I run your original code on my computer. I am in Arizona, USA, which is at UTC-7 with no daylight saving time.
// we'll start with the string you provided
var v = '2013-07-09T13:27:29.000Z';
// and the redundant moment, but we'll take a look at the formatting
var g = moment(v).format();
console.log(g); // 2013-07-09T06:27:29-07:00
console.log(moment(g).format()) // 2013-07-09T06:27:29-07:00 (it didn't change)
// start of the local day is midnight in the local time zone
console.log(moment(g).startOf('day').format()) // 2013-07-09T00:00:00-07:00
// here's my time right now
console.log(moment().format()) // 2013-07-09T13:56:54-07:00
// and your final bit of code
console.log(moment(g).startOf('day').fromNow()); // 14 hours ago
As you can see it is performing correctly, using the local time zone when determining the start of day. Of course, when you run this in a different time zone, it is going to return different results. That's because every time zone has it's own concept of each day. If you wanted consistent output, then you would remove the startOf('day') call.
Recommendation
After your last update stating that you expected 8 hours, then it seems you didn't really want the time from the startOf('day') at all. Just do this:
moment(v).fromNow()
There's no need to involve the .zone() either.

javascript Date().valueOf() is working on development PC but not on page served by server

The IE9 debugger (F12 developer tools -> script debugger) shows the following in the Locals window when I step through the code when the page is launched from the server:
midnight Fri Mar 15 00:00:00 EDT 2013 Object, (Date)
myDate Fri Mar 15 00:00:00 EDT 2013 Object, (Date)
and yet the following conditional test for equality of value resolves to false:
if (midnight.valueOf() === myDate.valueOf() ) {
// these lines of code are never reached
.
.
.
}
The odd thing, the === test resolves to true on my development PC. I cannot figure out why it resolves to false on the page served up by the server. The debugger clearly indicates it should resolve to true.
The document is in "IE9 Standards" mode.
The valueOf method returns the primitive value of a Date object as a number data type, the number of milliseconds since midnight 01 January, 1970 UTC.
The debugger only shows you the seconds so the variables may actually be different.

Categories