Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Muse S2: timestamp jump #70

Open
nuKs opened this issue Jan 22, 2024 · 1 comment
Open

Muse S2: timestamp jump #70

nuKs opened this issue Jan 22, 2024 · 1 comment

Comments

@nuKs
Copy link

nuKs commented Jan 22, 2024

These lines of code seems no longer relevant with Muse 2S (I don't know where the limit lies but it is higher, if the mechanism is still the same).
https://github.com/urish/muse-js/blob/4e864578c55dd7e26d85b429863f47ccabac54a0/src/muse.ts#L233C1-L256C1

As you can see in the screenshot, the index continues to increase in a regular manner. The timestamp drastically jump though.

Screenshot 2024-01-22 at 3 55 53 PM
@nuKs
Copy link
Author

nuKs commented Jan 23, 2024

Limit still triggers when completely disabled.

What's weird is that the index jump seems fine, only the timestamp jump seems to have issue, and thus that bug should likely replicate across all muse device. Not sure what's going out here.

I am testing this as a fix, hopefully will get more insight.

this.firstIndex = [null, null, null, null];
this.firstTimestamp = [null, null, null, null];
this.lastIndex = [null, null, null, null];
this.indexTranslation = [0, 0, 0, 0];

(this.client as any).getTimestamp = (eventIndex: number, samplesPerReading: number, frequency: number) => {
    // We disable timestamp reading, as it seems not reliable. We will
    // handle it ourselves, per electrode.
    return null;
}
this.eegReadings = this.client.eegReadings.pipe(
    map(data => {
        const electrode = data.electrode;
        const index = data.index;

        // Handle first index timestamp initialization.
        if (this.firstIndex[electrode] === null || this.firstTimestamp[electrode] === null) {
            console.info('First index: ', index, index.toString(16), index.toString(2));
            this.firstIndex[electrode] = index;
            this.firstTimestamp[electrode] = new Date().getTime() - READING_DELTA;
            console.info('First timestamp: ', this.firstTimestamp[electrode]);
            console.info('First timestamp diff: ', data.timestamp - this.firstTimestamp[electrode]!);

            // Adapt data timestamp.
            data.timestamp = this.firstTimestamp[electrode]!;

            // Record last index.
            this.lastIndex[electrode] = index;
        }
        // Handle in order index.
        else if (index - this.lastIndex[electrode]! > 0) {
            // Adapt data index & timestamp.
            const translatedIndex = this.indexTranslation[electrode] + index;
            data.timestamp = this.firstTimestamp[electrode]! + READING_DELTA * (translatedIndex - this.firstIndex[electrode]!);
            data.index = translatedIndex;

            // Record last index.
            this.lastIndex[electrode] = index;
        }
        // Handle misordered index: we simply do nothing different if differences of index is below 4096 (* 12 samples) ~= 30s.
        else if (index - this.lastIndex[electrode]! <= 0 && index - this.lastIndex[electrode]! > -0x1000) {
            // Log error.
            console.error('found misordered index for electrode < 4096 (4096*12 samples at 256hz ~= 30s) ', electrode, ': ', index, index.toString(16), index.toString(2), ' previous was: ', this.lastIndex[electrode]!, this.lastIndex[electrode]!.toString(16), this.lastIndex[electrode]!.toString(2));

            // Adapt data index & timestamp.
            const translatedIndex = this.indexTranslation[electrode] + index;
            data.timestamp = this.firstTimestamp[electrode]! + READING_DELTA * (translatedIndex - this.firstIndex[electrode]!);
            data.index = translatedIndex;

            // Record last index.
            this.lastIndex[electrode] = index;
        }
        // Handle misordered index: Otherwise, we assume that the index has been reset, if there was an error or a delay,
        // it should have been sent/corrected by now so it must be a rotation.
        else {
            // Log error.
            console.error('misordered index for electrode >= 4096 (expecting index === 0 due to full number rotation)', electrode, ': ', index, index.toString(16), index.toString(2), ' previous was: ', this.lastIndex[electrode]!, this.lastIndex[electrode]!.toString(16), this.lastIndex[electrode]!.toString(2));

            // Increase index translation, due to rotation.
            this.indexTranslation[electrode] += this.lastIndex[electrode]!;

            // Adapt data index & timestamp.
            const translatedIndex = this.indexTranslation[electrode] + index;
            data.timestamp = this.firstTimestamp[electrode]! + READING_DELTA * (translatedIndex - this.firstIndex[electrode]!);
            data.index = translatedIndex;

            // Record last index.
            this.lastIndex[electrode] = index;
        }

        return data;
    }),
    publish()
) as ConnectableObservable<EEGReading>;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant