scheduler setting
what should be the scheduler setting?
I'm running experiment with date over udp, audio recording as well as 4 cameras recording.

And for audio setting? anything to change?

Thanks!
Default values are fine.
Are you experiencing any bottleneck or performance issue with your patch currently? If not then there's nothing to fix! If yes then can you be more specific about what those issues are? Different issues might lead to different preference tweaking, or maybe even just patch optimization.
To get a better sense of what the Scheduler settings (as well as vector sizes and SIAI - Scheduler in Audio Interrupt) do, you need to understand threading. For this you can check:
this tutorial from 2016 (the [min.threadcheck] external they use can now be replaced by the built-in [threadcheck])
network and video should not require the scheduler at all.
Are you experiencing any bottleneck or performance issue with your patch currently?
I have this code that constantly looking for lsl data, and when it is not receiving any (close) I got endlessly printing messages to the max console and I think this what cause my max to crash. Is that possible?
// lsl_get_vals.js
// ES Module version.
// - Creates an LSL outlet
// - Streams continuously at 125 Hz
// - Keeps sending the latest "currentSample"
// - Max can update that sample by sending a list
//
// Works both in Max (`node.script`) and in plain Node (`node lsl_get_vals.js`).
// In plain Node, we simulate Max's API so it doesn't crash.
import { StreamInfo, StreamOutlet } from 'node-labstreaminglayer';
// 0. Try to load max-api (only available inside Max).
// If not found (normal Node), fall back to a shim.
let MaxAPI;
try {
MaxAPI = await import('max-api');
MaxAPI = MaxAPI.default ?? MaxAPI; // handle default export shape
} catch (err) {
// Fallback shim so the script doesn't die in normal Node.js
MaxAPI = {
post: (...args) => {
console.log(args.join(' '));
},
addHandler: (name, fn) => {
console.log(`[shim] Registered handler "${name}" (not active outside Max).`);
// Simulate inputs in plain Node for basic testing.
if (name === 'list') {
// Simulate random numeric lists every 500 ms
setInterval(() => {
const dummy = [];
for (let i = 0; i < CHANNEL_COUNT; i++) {
dummy.push(Math.random());
}
fn(...dummy);
}, 500);
}
if (name === 'marker' || name === 'mark') {
// Simulate occasional markers every 2 s
setInterval(() => {
const tag = `shim_marker_${Math.floor(Date.now()/1000)}`;
fn(tag);
}, 2000);
}
if (name === 'stop') {
// no-op in plain Node
}
}
};
}
// Small helper so we don't repeat `MaxAPI.post(...)`
function log(...args) {
MaxAPI.post(args.join(' '));
}
// 1. Stream configuration
const STREAM_NAME = 'MaxData';
const STREAM_TYPE = 'Mixed';
const CHANNEL_COUNT = 13; // number of channels per sample
const SAMPLE_RATE_HZ = 125; // nominal sample rate metadata only
const CHANNEL_FORMAT = 'float32';
const SOURCE_ID = 'uniqueid123';
// Marker stream configuration (irregular string markers)
const MARKER_STREAM_NAME = 'MaxMarkers';
const MARKER_STREAM_TYPE = 'Markers';
const MARKER_CHANNEL_COUNT = 1; // single string channel
const MARKER_SAMPLE_RATE_HZ = 0; // 0 = irregular
const MARKER_CHANNEL_FORMAT = 'string';
const MARKER_SOURCE_ID = 'uniqueid123_markers';
// 2. Create and announce the LSL outlets
// Continuous data outlet
const info = new StreamInfo(
STREAM_NAME,
STREAM_TYPE,
CHANNEL_COUNT,
SAMPLE_RATE_HZ,
CHANNEL_FORMAT,
SOURCE_ID
);
// Add channel labels BEFORE creating the outlet
const desc = info.desc();
const chs = desc.appendChild("channels");
const labels = [
"Player 1 X.1", "Player 1 Y.1", "Player 1 touch ID.1",
"Player 2 X.1", "Player 2 Y.1", "Player 2 touch ID.1",
"Player 1 X>0.5", "Player 2 X>0.5",
"Click", "Player 1 Click", "Player 2 Click", "Change Tempo Every N Beats", "BPM"
];
if (labels.length !== CHANNEL_COUNT) {
log(`WARNING: labels (${labels.length}) != CHANNEL_COUNT (${CHANNEL_COUNT})`);
}
for (const label of labels) {
const ch = chs.appendChild("channel");
ch.appendChildValue("label", label);
ch.appendChildValue("type", "Touch");
}
const outlet = new StreamOutlet(info);
// Marker outlet (string, irregular)
const markerInfo = new StreamInfo(
MARKER_STREAM_NAME,
MARKER_STREAM_TYPE,
MARKER_CHANNEL_COUNT,
MARKER_SAMPLE_RATE_HZ,
MARKER_CHANNEL_FORMAT,
MARKER_SOURCE_ID
);
const markerOutlet = new StreamOutlet(markerInfo);
log(
'LSL outlets created:',
`${STREAM_NAME} (${CHANNEL_COUNT} ch @ ${SAMPLE_RATE_HZ}Hz)`,
'and',
`${MARKER_STREAM_NAME} (markers)`
);
// 3. The buffer we keep streaming
// starts as zeros
let currentSample = new Array(CHANNEL_COUNT).fill(0.0);
// 4. Update function (called whenever Max sends us a new list)
function updateCurrentSample(newVals) {
// Coerce incoming values to numbers (Max sometimes sends strings)
const numericVals = newVals.map(v => Number(v));
// if (numericVals.length !== CHANNEL_COUNT) {
// log(
// 'WARNING: got',
// numericVals.length,
// 'values but expected',
// CHANNEL_COUNT
// );
// }
// Copy/pad/truncate into currentSample
for (let i = 0; i < CHANNEL_COUNT; i++) {
currentSample[i] = Number(numericVals[i] ?? 0.0);
}
// log('updated sample ->', currentSample);
}
// 4b. Push a marker immediately to the marker outlet
function pushMarker(label) {
const text = Array.isArray(label) ? label.filter(v => v !== undefined).map(String).join(' ') : String(label);
if (!text || text.length === 0) {
return;
}
try {
markerOutlet.pushSample([text]);
log('marker:', text);
} catch (e) {
log('ERROR pushing marker:', e?.message ?? e);
}
}
// 5. Start continuous streaming at ~100 Hz
const intervalMs = 1000 / SAMPLE_RATE_HZ;
log('Starting continuous LSL streaming loop...');
const intervalHandle = setInterval(() => {
outlet.pushSample(currentSample);
// comment this out if it's too spammy
// log('sent:', currentSample);
}, intervalMs);
// 6. Hook Max messages
MaxAPI.addHandler('list', (...vals) => {
updateCurrentSample(vals);
});
// Markers: send any symbol(s) after 'marker' into the outlet, e.g., [message] marker trial_start
MaxAPI.addHandler('marker', (...atoms) => {
pushMarker(atoms);
});
// Short alias
MaxAPI.addHandler('mark', (...atoms) => {
pushMarker(atoms);
});
// Optional stop message from Max: send the symbol 'stop' into node.script
MaxAPI.addHandler('stop', () => {
clearInterval(intervalHandle);
log('Stopped streaming loop.');
});This has nothing to do with your first questions... This is a typical example of the XY problem.
And you provide so little context, it's hard to understand what this code is supposed to do.
What is LSL data?
when it is not receiving any (close) I got endlessly printing messages to the max console and I think this what cause my max to crash. Is that possible?
I don't know, but you can try by yourself: what happens if you comment the line responsible for that logging? Does it still crash? If yes then the logging has nothing to do with the crashes.
Do you see the RAM usage consistently increasing until crash? If yes then it might lead to some memory management issue, possibly in your code.
Do you see the RAM usage consistently increasing until crash? If yes then it might lead to some memory management issue, possibly in your code.
Is this possible to monitor in max or do you mean the RAM indicator on Windows?
What is LSL data?
It is data coming from eeg caps. I think the issue I'm facing is related to that so I will try to fix that before I make more xy problems...
Is this possible to monitor in max or do you mean the RAM indicator on Windows?
The Windows Task Manager should be enough. Since you are using [node.script], not sure if the leakage, if any, would come from Max or a node subprocess. But just monitoring the overall RAM usage should tell you if the crashes you get are related to memory issue or not. Also, maybe you get some crash report that you could share here?