spessoplayer 0.7.6-beta → 0.7.8-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/audioBuffer.mjs CHANGED
@@ -51,6 +51,9 @@ function writeLittleEndianIndexed(dataArray, number, byteTarget) {
51
51
  dataArray[dataArray.currentIndex++] = number >> i * 8 & 255;
52
52
  }
53
53
  }
54
+ function writeDword(dataArray, dword) {
55
+ writeLittleEndianIndexed(dataArray, dword, 4);
56
+ }
54
57
  function writeRIFFChunkParts(header, chunks, isList = false) {
55
58
  let dataOffset = 8;
56
59
  let headerWritten = header;
@@ -113,7 +116,7 @@ function writeRIFFChunkRaw(header, data, addZeroByte = false, isList = false) {
113
116
  * @param {Number} audioData.length - Audio length in samples, essentially the sample count
114
117
  * @param {Number} audioData.numChannels - How many channels the audio has
115
118
  * @param {Number} sampleRate - Sample rate of the audio
116
- * @param {Object} options - Optional, adds loop timestamps and more
119
+ * @param {Object} [options=DEFAULT_WAV_WRITE_OPTIONS] - Optional, adds loop timestamps and more
117
120
  * @returns {Uint8Array} the wav header
118
121
  */
119
122
  function getWavHeader({ length, numChannels }, sampleRate, options = DEFAULT_WAV_WRITE_OPTIONS) {
package/cli.mjs CHANGED
@@ -22,6 +22,16 @@
22
22
  import { join, basename, parse } from "path"
23
23
  import { log, Options } from "./utils/utils.mjs"
24
24
 
25
+ /** @type {(Promise<String[]>|String[])} */
26
+ let argvWithoutFileExts = new Promise(resolve => {
27
+ const newArguments = [...new Set(process.argv.slice(2)).values()],
28
+ newArgumentsLength = newArguments.length;
29
+ for (let i = 0; i < newArgumentsLength; i++) {
30
+ const parsedElement = parse(newArguments[i]);
31
+ newArguments[i] = join(parsedElement.dir, parsedElement.name);
32
+ }
33
+ resolve(newArguments)
34
+ });
25
35
  const regexes = {
26
36
  help: /^(?:--help|\/help|-h|\/h|\/\?)$/,
27
37
  version: /^(?:--version|\/version|-V|\/V)$/,
@@ -121,6 +131,11 @@ const testFunctions = {
121
131
  logFile: i => regexes.logFile.test(i)
122
132
  };
123
133
 
134
+ /**
135
+ * Retrieves the first 20 bytes of a file
136
+ * @param {String} path path of file
137
+ * @return {Promise<String>} - first 20 bytes of file
138
+ */
124
139
  async function get20BytesFromFile(path) {
125
140
  let fileMagicNumber;
126
141
  await new Promise(resolve => {
@@ -136,15 +151,21 @@ async function get20BytesFromFile(path) {
136
151
  })
137
152
  return fileMagicNumber;
138
153
  }
154
+ const setFilePromises = [];
139
155
  /**
140
156
  * Sets necessary variables in Options class for main.mjs
141
- * @param {Array} args - The process.argv to analyse
157
+ * @param {String[]} args - The process.argv to analyse
142
158
  * @throws {ReferenceError} - if the next argument doesn't exist
143
159
  */
144
160
  const actUpOnPassedArgs = async (args) => {
145
161
  let lastParam,
146
162
  lastIndex;
147
163
  let newArguments = args.slice(2);
164
+ const newArgumentsSet = new Set(newArguments),
165
+ noDuplicates = [...newArgumentsSet.values()],
166
+ /** @type {Map<String, (String|Symbol)>} */
167
+ doneFileList = new Map(newArgumentsSet.entries()),
168
+ doneSymbol = Symbol("ALREADY_DONE");
148
169
  if (newArguments.length === 0) {
149
170
  await help()
150
171
  process.exit()
@@ -198,8 +219,12 @@ const actUpOnPassedArgs = async (args) => {
198
219
  log(1, performance.now().toFixed(2), `Using variable DEBUG_FILE_SPESSO=${process.env["DEBUG_FILE_SPESSO"]}`)
199
220
  }
200
221
 
201
- const setFilePromises = [],
202
- effectsStdoutFunctions = [];
222
+ function clearLastVariables() {
223
+ lastParam = undefined,
224
+ lastIndex = undefined;
225
+ }
226
+ let indexOfSetFile = 0,
227
+ lastAutomaticFile;
203
228
  for (const arg of newArguments) {
204
229
  switch (arg) {
205
230
  case regexes.wav.test(arg) && arg: {
@@ -309,13 +334,25 @@ const actUpOnPassedArgs = async (args) => {
309
334
  case (lastParam === "input" || lastParam === undefined)
310
335
  && regexes.fileCheck.test(basename(arg))
311
336
  && arg: {
337
+ if (doneFileList.get(arg) === doneSymbol) {
338
+ if (lastParam === "input") clearLastVariables()
339
+ break;
340
+ }
341
+ doneFileList.set(arg, doneSymbol)
342
+
343
+ if (!global.fs) {
344
+ const fs = await import("node:fs");
345
+ global.fs = fs;
346
+ }
312
347
  setFilePromises.push(
313
348
  setFile({
314
- lastParam, lastIndex,
315
- newArguments, arg
349
+ indexOfSetFile: indexOfSetFile++,
350
+ lastParam, lastIndex, lastAutomaticFile,
351
+ newArguments: noDuplicates, arg
316
352
  })
317
353
  )
318
- if (lastParam === "input") lastParam = undefined;
354
+ if (!lastParam) lastAutomaticFile = arg;
355
+ if (lastParam === "input") clearLastVariables()
319
356
  break;
320
357
  }
321
358
 
@@ -323,35 +360,35 @@ const actUpOnPassedArgs = async (args) => {
323
360
  switch (lastParam) {
324
361
  case "loop":
325
362
  setLoop(arg, lastIndex)
326
- lastParam = undefined;
363
+ clearLastVariables()
327
364
  break;
328
365
  case "loop-start":
329
366
  setLoopStart(arg, lastIndex)
330
- lastParam = undefined;
367
+ clearLastVariables()
331
368
  break;
332
369
  case "loop-end":
333
370
  setLoopEnd(arg, lastIndex)
334
- lastParam = undefined;
371
+ clearLastVariables()
335
372
  break;
336
373
  case "sample-rate":
337
374
  setSampleRate(arg, lastIndex, newArguments)
338
- lastParam = undefined;
375
+ clearLastVariables()
339
376
  break;
340
377
  case "format":
341
- setFormat(arg, lastIndex)
342
- lastParam = undefined;
378
+ setFormat(arg)
379
+ clearLastVariables()
343
380
  break;
344
381
  case "volume":
345
382
  setVolume(arg, lastIndex)
346
- lastParam = undefined;
383
+ clearLastVariables()
347
384
  break;
348
385
  case "reverb":
349
- effectsStdoutFunctions.push(getReverb(arg, lastIndex))
350
- lastParam = undefined;
386
+ setReverb(arg, lastIndex)
387
+ clearLastVariables()
351
388
  break;
352
389
  case "effects":
353
- effectsStdoutFunctions.push(getEffects(arg, lastIndex))
354
- lastParam = undefined;
390
+ setEffects(arg, lastIndex)
391
+ clearLastVariables()
355
392
  break;
356
393
 
357
394
  default:
@@ -366,17 +403,21 @@ const actUpOnPassedArgs = async (args) => {
366
403
  }
367
404
  }
368
405
  }
369
- // Needs to be done here because otherwise the functions
370
- // wouldn't always know if it's stdout mode
371
- if (effectsStdoutFunctions.length > 0) {
372
- const isStdout = Options.all.toStdout,
373
- setFunction = i => i(isStdout);
374
- effectsStdoutFunctions.forEach(setFunction)
375
- }
376
- // Adds files to the list asynchronously/in parallel
377
- await Promise.all(setFilePromises)
378
- if (!Options.all.files
379
- || !Object.keys(Options.all.files).length > 0) {
406
+ /*
407
+ Adds files to the list asynchronously/in parallel
408
+ by chaining each function to the previous one
409
+ so that they stay syncronized and up to date.
410
+
411
+ This means there's no performance loss because of
412
+ the async nature of them and it remains in
413
+ a sequential order regardless of execution timings.
414
+
415
+ (e.g. sort order is the same like in process.argv
416
+ because each returned Promise waits before
417
+ actually adding the file)
418
+ */
419
+ await Promise.all(await Promise.all(setFilePromises))
420
+ if (!Object.keys(Options.all.files ?? []).length) {
380
421
  console.error(`${red}Missing required files${normal}`);
381
422
  process.exit(1)
382
423
  }
@@ -385,163 +426,165 @@ const actUpOnPassedArgs = async (args) => {
385
426
  /**
386
427
  * Sets a supported file inside a group in Options class
387
428
  * @param {Object} passedVariables - variables injected with this object
429
+ * @param {Number} passedVariables.indexOfSetFile - index of the current function inside setFilePromises
388
430
  * @param {String} passedVariables.lastParam - last parameter that has been used last time
389
- * @param {String} passedVariables.lastIndex - last index that has been set last time
390
- * @param {String} passedVariables.newArguments - arguments passed from the terminal
431
+ * @param {Object} passedVariables.lastIndex - last index object
432
+ * @param {String} [passedVariables.lastIndex.index] - last index that has been set last time
433
+ * @param {String} passedVariables.lastAutomaticFile - last file that has been set automatically
434
+ * @param {String[]} passedVariables.newArguments - arguments passed from the terminal
391
435
  * @param {String} passedVariables.arg - argument passed to this function that is also a file path
392
- * @return {(true|false)}
393
- * true if it needs to break,
394
- * false if it needs to fallthrough the switch
395
- * (See "case regexes.fileCheck.test(basename(arg)) && arg")
436
+ * @return {Promise<Promise|undefined>}
396
437
  */
397
438
  const setFile = async ({
398
- lastParam, lastIndex,
439
+ indexOfSetFile,
440
+ lastParam, lastIndex, lastAutomaticFile,
399
441
  newArguments, arg
400
442
  }) => {
401
- function doesSetHave(setOfFiles, path, isMidi = true) {
443
+ /**
444
+ * Checks for the same basename as the path given inside process.argv
445
+ * @param {String} path - full file path to compare with another one
446
+ * @inner
447
+ * @private
448
+ * @memberof module:cli
449
+ * @return {Boolean} - whether or not it has found a similar file inside process.argv
450
+ */
451
+ function checkForIdenticalName(path) {
452
+ const indexOfPath = newArguments.indexOf(path);
402
453
  const pathUpToName = join(parse(path).dir, parse(path).name);
403
- if (isMidi) {
404
- return setOfFiles?.has(pathUpToName+".sf2")
405
- || setOfFiles?.has(pathUpToName+".dls");
406
- }
407
- return setOfFiles?.has(pathUpToName+".mid");
408
- }
409
- function checkForIdenticalNames(path, isMidi = true) {
410
- const pathUpToName = join(parse(path).dir, parse(path).name);
411
- if (isMidi) {
412
- return newArguments.includes(pathUpToName+".sf2")
413
- || newArguments.includes(pathUpToName+".dls");
414
- }
415
- return newArguments.includes(pathUpToName+".mid");
416
- }
417
- if (lastParam !== undefined && lastParam !== "input") return false;
454
+ const noExtNewArguments = [...argvWithoutFileExts];
455
+
456
+ delete noExtNewArguments[indexOfPath]
457
+ return noExtNewArguments.includes(pathUpToName);
458
+ }
459
+ /**
460
+ * Returns either a new Promise or attaches a .then Promise to an older one
461
+ * @param {Function} func function to run within a Promise
462
+ * @inner
463
+ * @private
464
+ * @memberof module:cli
465
+ * @return {(Promise|undefined)} - a new Promise that'll fulfill when the given function returns
466
+ */
467
+ function createPromise(func) {
468
+ const lastSetFilePromise = setFilePromises[indexOfSetFile-1];
469
+ return (!lastSetFilePromise)
470
+ ? func()
471
+ : lastSetFilePromise.then(() => func());
472
+ }
473
+ if (lastParam !== undefined && lastParam !== "input") return;
418
474
 
419
- if (!global.fs) {
420
- const fs = await import("node:fs");
421
- global.fs = fs;
422
- }
423
475
  const fileMagicNumber = await get20BytesFromFile(arg);
424
-
425
- // -- MIDI files --
426
- if (fileMagicNumber.includes("MThd")) {
427
- const inputIndex = Number(lastIndex?.index ?? 0);
428
- const indexesAndKeys = (Options.all.files ?? [[]]).map((e, i) => [i, e]);
429
- for (const infos of indexesAndKeys) {
430
- let index, setOfFiles;
431
- if (infos) {
432
- [index, setOfFiles] = infos;
433
- } else continue;
434
-
435
- if (setOfFiles instanceof Set
436
- && doesSetHave(setOfFiles, arg)
437
- && !lastIndex?.index && !lastParam) {
438
- Options.files(index, arg);
439
- log(1, performance.now().toFixed(2), `Set midi file to "${arg}" at index ${index}`)
440
- return true;
441
- }
442
- }
443
- for (const infos of indexesAndKeys) {
444
- let index, setOfFiles;
445
- if (infos) {
446
- [index, setOfFiles] = infos;
447
- } else continue;
448
-
449
- if (index === indexesAndKeys.length-1
450
- && inputIndex !== index) {
451
- if (checkForIdenticalNames(arg)
452
- && !lastIndex?.index && !lastParam) {
453
- Options.files(indexesAndKeys.length, arg)
454
- log(1, performance.now().toFixed(2), `Set midi file to "${arg}" at index ${indexesAndKeys.length}`)
455
- return true;
456
- }
457
- Options.files(inputIndex, arg)
458
- log(1, performance.now().toFixed(2), `Set midi file to "${arg}" at index ${inputIndex}`)
459
- return true;
460
- }
461
- if (index !== inputIndex) continue;
462
-
463
- if (checkForIdenticalNames(arg)
464
- && !lastIndex?.index && !lastParam) {
465
- Options.files(indexesAndKeys.length, arg)
466
- log(1, performance.now().toFixed(2), `Set midi file to "${arg}" at index ${indexesAndKeys.length}`)
467
- return true;
468
- }
469
- Options.files(index, arg);
470
- log(1, performance.now().toFixed(2), `Set midi file to "${arg}" at index ${index}`)
471
- return true;
472
- }
476
+ let typeOfFile;
477
+ switch (true) {
478
+ case fileMagicNumber.includes("MThd"):
479
+ typeOfFile = true;
480
+ break;
481
+ case fileMagicNumber.includes("sfbk"):
482
+ case fileMagicNumber.includes("DLS"):
483
+ typeOfFile = false;
484
+ break;
485
+
486
+ default:
487
+ // Incompatible file
488
+ return;
473
489
  }
474
- // -- End of MIDI files --
475
490
 
476
- // Soundfont and downloadable sounds files
477
- if (fileMagicNumber.includes("sfbk")
478
- || fileMagicNumber.includes("DLS")) {
479
- const inputIndex = Number(lastIndex?.index ?? 0);
480
- const indexesAndKeys = (Options.all.files ?? [[]]).map((e, i) => [i, e]);
481
- for (const infos of indexesAndKeys) {
482
- let index, setOfFiles;
483
- if (infos) {
484
- [index, setOfFiles] = infos;
485
- } else continue;
486
-
487
- if (setOfFiles instanceof Set
488
- && doesSetHave(setOfFiles, arg, false)
489
- && !lastIndex?.index && !lastParam) {
490
- Options.files(index, arg, true);
491
- log(1, performance.now().toFixed(2), `Set soundfont file to "${arg}" at index ${index}`)
492
- return true;
493
- }
491
+ const inputIndex = Number(lastIndex?.index ?? 0);
492
+ const logMessages = {
493
+ getMessage(type, arg, index) {
494
+ return (type)
495
+ ? `Set midi file to "${arg}" at index ${index}`
496
+ : `Set soundfont file to "${arg}" at index ${index}`;
497
+ },
498
+ getReplacedSoundfont(original, newOne, index) {
499
+ return `Replaced soundfont file from "${original}" to "${newOne}" at index ${index}`;
494
500
  }
495
- for (const infos of indexesAndKeys) {
496
- let index, setOfFiles;
497
- if (infos) {
498
- [index, setOfFiles] = infos;
499
- } else continue;
500
-
501
- if (index === indexesAndKeys.length-1
502
- && index !== inputIndex) {
503
- if (checkForIdenticalNames(arg, false)
504
- && !lastIndex?.index && !lastParam) {
505
- Options.files(indexesAndKeys.length, arg, true)
506
- log(1, performance.now().toFixed(2), `Set soundfont file to "${arg}" at index ${indexesAndKeys.length}`)
507
- return true;
508
- }
509
- Options.files(inputIndex, arg, true);
510
- log(1, performance.now().toFixed(2), `Set soundfont file to "${arg}" at index ${inputIndex}`)
511
- return true;
501
+ };
502
+ if (lastIndex?.index || lastParam) {
503
+ return createPromise(async () => {
504
+ let needsToBeReplaced = false;
505
+
506
+ // Replaces the last soundfont it can reach if it needs to
507
+ if (!typeOfFile) {
508
+ const setOfFiles = Options.all.files[inputIndex];
509
+ const fileMagicNumber = (setOfFiles instanceof Set)
510
+ ? await get20BytesFromFile(setOfFiles.getIndex(0))
511
+ : [];
512
+ if (fileMagicNumber.includes("sfbk")
513
+ || fileMagicNumber.includes("DLS")) needsToBeReplaced = true;
512
514
  }
513
- if (index !== inputIndex) continue;
515
+ Options.files(inputIndex, arg, !typeOfFile, needsToBeReplaced)
516
+ log(1,
517
+ performance.now().toFixed(2),
518
+ logMessages.getMessage(typeOfFile, arg, inputIndex)
519
+ )
520
+ });
521
+ }
522
+
523
+ // --- Automatic addition of files section ---
524
+ return createPromise(async () => {
525
+ /*
526
+ ⏳ if one group inside Options.all
527
+ has the same basename as arg,
528
+ then it adds arg to that group
529
+ ❌ Otherwise it runs the next check below it
530
+ (e.g. index 2 and he needs to add to that,
531
+ that's why it's seperated otherwise it creates
532
+ a new Set when it already exists)
533
+ */
534
+ const pathUpToName = join(parse(arg).dir, parse(arg).name);
535
+ const foundIndex = Options.searchAddedFile(pathUpToName, typeOfFile);
536
+ if (typeof foundIndex === "number") {
537
+ Options.files(foundIndex, arg, !typeOfFile);
538
+ log(1,
539
+ performance.now().toFixed(2),
540
+ logMessages.getMessage(typeOfFile, arg, foundIndex)
541
+ )
542
+ return;
543
+ }
544
+ if (argvWithoutFileExts instanceof Promise) argvWithoutFileExts = await argvWithoutFileExts;
545
+ // Creates new Sets for identical basename files
546
+ if (checkForIdenticalName(arg)) {
547
+ const amountOfGroups = Options.amountOfGroups;
548
+ Options.files(amountOfGroups, arg, !typeOfFile)
549
+ log(1,
550
+ performance.now().toFixed(2),
551
+ logMessages.getMessage(typeOfFile, arg, amountOfGroups)
552
+ )
553
+ return;
554
+ }
555
+ // It just adds to the last Set it can reach
556
+ let lastKnownGroupIndex = Options.lastKnownGroupIndex ?? 0;
557
+ // or maybe to the last automatic group
558
+ // if a file has been added automatically last time
559
+ if (lastAutomaticFile) automaticFileCheck: {
560
+ const pathUpToName = join(parse(lastAutomaticFile).dir, parse(lastAutomaticFile).name);
561
+ const indexOfGroup = Options.searchAddedFile(pathUpToName);
562
+ if (typeof indexOfGroup !== "number") break automaticFileCheck;
514
563
 
515
- if (checkForIdenticalNames(arg, false)
516
- && !lastIndex?.index && !lastParam) {
517
- Options.files(indexesAndKeys.length, arg, true)
518
- log(1, performance.now().toFixed(2), `Set soundfont file to "${arg}" at index ${indexesAndKeys.length}`)
519
- return true;
520
- }
521
- const fileMagicNumber = (setOfFiles instanceof Set)
522
- ? await get20BytesFromFile(setOfFiles.getIndex(0))
523
- : [];
524
- if (fileMagicNumber.includes("sfbk")
525
- || fileMagicNumber.includes("DLS")) {
526
- log(1, performance.now().toFixed(2), `Replaced soundfont file from "${setOfFiles.getIndex(0)}" to "${arg}" at index ${index}`)
527
- Options.files(index, arg, true, true);
528
- return true;
564
+ if (Options.isAutomaticBasenameGroup(argvWithoutFileExts, indexOfGroup)) {
565
+ lastKnownGroupIndex++
566
+ } else {
567
+ lastKnownGroupIndex = indexOfGroup;
529
568
  }
530
- Options.files(index, arg, true);
531
- log(1, performance.now().toFixed(2), `Set soundfont file to "${arg}" at index ${index}`)
532
- return true;
533
569
  }
534
- }
535
- // End of soundfont and downloadable sounds files
570
+ Options.files(lastKnownGroupIndex, arg, !typeOfFile);
571
+ log(1,
572
+ performance.now().toFixed(2),
573
+ logMessages.getMessage(typeOfFile, arg, lastKnownGroupIndex)
574
+ )
575
+ });
576
+ // --- END of automatic addition of files section ---
536
577
  }
537
578
  /**
538
- * Sets the Options.loopN variable
579
+ * Sets the Options.loopAmount variable
539
580
  * @param {String} arg - the loop amount
581
+ * @param {Object} lastIndex - last index object
582
+ * @param {String} [lastIndex.index] - last index that has been set last time
540
583
  */
541
584
  const setLoop = (arg, lastIndex) => {
542
585
  if (typeof Number(arg) === "number"
543
586
  && !regexes.infinity.test(arg)) {
544
- Options.loopN(Number(lastIndex?.index), Number(arg));
587
+ Options.loopAmount(Number(lastIndex?.index), Number(arg));
545
588
  log(1, performance.now().toFixed(2), `Set loop amount to ${Number(arg)} at ${lastIndex?.index} index`)
546
589
  return;
547
590
  }
@@ -555,6 +598,8 @@ const setLoop = (arg, lastIndex) => {
555
598
  /**
556
599
  * Sets the Options.loopStart variable
557
600
  * @param {String} arg - the start of the loop in seconds or in HH:MM:SS:ms format
601
+ * @param {Object} lastIndex - last index object
602
+ * @param {String} [lastIndex.index] - last index that has been set last time
558
603
  */
559
604
  const setLoopStart = (arg, lastIndex) => {
560
605
  if (typeof Number(arg) === "number"
@@ -575,6 +620,8 @@ const setLoopStart = (arg, lastIndex) => {
575
620
  /**
576
621
  * Sets the Options.loopEnd variable
577
622
  * @param {String} arg - the end of the loop in seconds or in HH:MM:SS:ms format
623
+ * @param {Object} lastIndex - last index object
624
+ * @param {String} [lastIndex.index] - last index that has been set last time
578
625
  */
579
626
  const setLoopEnd = (arg, lastIndex) => {
580
627
  if (typeof Number(arg) === "number"
@@ -595,6 +642,9 @@ const setLoopEnd = (arg, lastIndex) => {
595
642
  /**
596
643
  * Sets the Options.sampleRate variable
597
644
  * @param {String} arg - the sample rate to set
645
+ * @param {Object} lastIndex - last index object
646
+ * @param {String} [lastIndex.index] - last index that has been set last time
647
+ * @param {String[]} newArguments - process.argv without 2 starting indexes
598
648
  */
599
649
  const setSampleRate = (arg, lastIndex, newArguments) => {
600
650
  if (typeof Number(arg) === "number" && !arg.startsWith("-")) {
@@ -612,7 +662,7 @@ const setSampleRate = (arg, lastIndex, newArguments) => {
612
662
  }
613
663
  /**
614
664
  * Simply changes how the program should log
615
- * @param {Number} arg - the level of how much it should log
665
+ * @param {String} arg - the level of how much it should log
616
666
  */
617
667
  const setVerboseLevel = async (arg) => {
618
668
  const isFromUser = arg !== undefined;
@@ -661,11 +711,12 @@ const setFormat = arg => {
661
711
  process.exit(1);
662
712
  }
663
713
  /**
664
- * Gives a function that will apply effects from the user's string passed through --effects
714
+ * Applies effects from the user's string passed through --effects
665
715
  * @param {String} arg - the comma-separeted string to parse
666
- * @return {Function} - a function that will set the effects parameter
716
+ * @param {Object} lastIndex - last index object
717
+ * @param {String} [lastIndex.index] - last index that has been set last time
667
718
  */
668
- const getEffects = (arg, lastIndex) => {
719
+ const setEffects = (arg, lastIndex) => {
669
720
  const regexListOfEffects = (
670
721
  "allpass|band|bandpass|bandreject|bass|bend|biquad" +
671
722
  "|chorus|channels|compand|contrast|dcshift|deemph|delay" +
@@ -707,14 +758,9 @@ const getEffects = (arg, lastIndex) => {
707
758
  process.exit(1);
708
759
  }
709
760
 
710
- return isStdout => {
711
- if (isStdout) {
712
- Options.effectsStdout = list;
713
- } else {
714
- Options.effects(Number(lastIndex?.index), list);
715
- }
716
- log(1, performance.now().toFixed(2), `Set list of SoX effects as ${list} at ${lastIndex?.index} index`)
717
- };
761
+ Options.effects(Number(lastIndex?.index), list);
762
+ log(1, performance.now().toFixed(2), `Set list of SoX effects as ${global.effects}`)
763
+ return;
718
764
  }
719
765
  console.error(`${normalRed}The string for SoX effects you passed is not usable${normal}`);
720
766
  process.exit(1);
@@ -722,6 +768,8 @@ const getEffects = (arg, lastIndex) => {
722
768
  /**
723
769
  * Sets the Options.volume variable for the masterGain
724
770
  * @param {String} arg - the volume in either percentage, decibels or decimals
771
+ * @param {Object} lastIndex - last index object
772
+ * @param {String} [lastIndex.index] - last index that has been set last time
725
773
  */
726
774
  const setVolume = (arg, lastIndex) => {
727
775
  if (regexes.areDecibels.test(arg)) {
@@ -746,41 +794,32 @@ const setVolume = (arg, lastIndex) => {
746
794
  process.exit(1);
747
795
  }
748
796
  /**
749
- * Gets the value for the reverb's volume for later use
797
+ * Sets the Options.reverb variable
750
798
  * @param {String} arg - the volume in either percentage, decibels or decimals
751
- * @param {Object} lastIndex - regex named group object
752
- * @return {Function} - function for setting/adding to Options.reverbVolume
799
+ * @param {Object} lastIndex - last index object
800
+ * @param {String} [lastIndex.index] - last index that has been set last time
753
801
  */
754
- const getReverb = (arg, lastIndex) => {
755
- let valueToSet;
802
+ const setReverb = (arg, lastIndex) => {
756
803
  if (regexes.areDecibels.test(arg)) {
757
804
  const dBNumber = Number(arg.match(regexes.decibelNumber)[1]);
758
- valueToSet = dBNumber;
805
+ Options.reverbVolume(Number(lastIndex?.index), dBNumber);
806
+ Options.effects(Number(lastIndex?.index), []);
807
+ log(1, performance.now().toFixed(2), `Set reverb volume to ${Options.all.reverbVolume.find(i => i === dBNumber)} and effects variable to ${lastIndex?.index}`)
759
808
  return;
760
809
  }
761
810
  if (regexes.isPercentage.test(arg)) {
762
811
  const percentage = Number(arg.match(regexes.percentageNumber)[1]);
763
812
  const toDB = 10 * 10**(percentage/100);
764
- valueToSet = toDB;
813
+ Options.reverbVolume(Number(lastIndex?.index), toDB);
814
+ Options.effects(Number(lastIndex?.index), []);
815
+ log(1, performance.now().toFixed(2), `Set reverb volume to ${Options.all.reverbVolume.find(i => i === toDB)} and effects variable to ${lastIndex?.index}`)
765
816
  return;
766
817
  }
767
818
  if (typeof Number(arg) === "number" && !arg.startsWith("-")) {
768
- valueToSet = Number(arg);
769
- }
770
-
771
- if (valueToSet) {
772
- return isStdout => {
773
- if (isStdout) {
774
- Options.reverbVolumeStdout = valueToSet;
775
- } else {
776
- Options.reverbVolume(Number(lastIndex?.index), valueToSet)
777
- }
778
- Options.effects(Number(lastIndex?.index), [])
779
- log(1,
780
- performance.now().toFixed(2),
781
- `Set reverb volume to ${valueToSet} at ${lastIndex?.index} index and effects variable to []`)
782
- return;
783
- };
819
+ Options.reverbVolume(Number(lastIndex?.index), Number(arg));
820
+ Options.effects(Number(lastIndex?.index), []);
821
+ log(1, performance.now().toFixed(2), `Set reverb volume to ${Options.all.reverbVolume.find(i => i === Number(arg))} and effects variable to ${lastIndex?.index}`)
822
+ return;
784
823
  }
785
824
  console.error(`${normalRed}Passed something that wasn't a valid number/dB/percentage${normal}`)
786
825
  process.exit(1);
@@ -790,7 +829,7 @@ const getReverb = (arg, lastIndex) => {
790
829
  * @param {String} arg - Path to the log file
791
830
  */
792
831
  const setLogFilePath = arg => {
793
- Options.logFilePath(arg ?? "./spesso.log");
832
+ Options.logFilePath = arg ?? "./spesso.log";
794
833
  log(1, performance.now().toFixed(2), `Set log file path to ${arg ?? "./spesso.log"}`)
795
834
  }
796
835
  /**
@@ -816,8 +855,8 @@ const uninstall = async () => {
816
855
  }
817
856
  /**
818
857
  * Shows the help text
819
- * @param {Object} errorObject - an object containing additional info that should be printed alongside help
820
- * @param {String} errorObject.errorText - error text that should be printed before helpText
858
+ * @param {Object} [errorObject=""] - an object containing additional info that should be printed alongside help
859
+ * @param {String} [errorObject.errorText] - error text that should be printed before helpText
821
860
  */
822
861
  const help = async ({ errorText } = "") => {
823
862
  const optionalIndex = `${normal}[${dimGray}n${normal}]`;
@@ -890,10 +929,10 @@ const help = async ({ errorText } = "") => {
890
929
  `
891
930
  if (process.env.PAGER) {
892
931
  const { spawnSync } = await import("child_process");
893
- const PAGERCommand = process.env.PAGER.split(" ").slice(0, 1),
932
+ const PAGERCommand = process.env.PAGER.split(" ").slice(0, 1)[0],
894
933
  PAGERArguments = process.env.PAGER.split(" ").slice(1);
895
934
  spawnSync(
896
- ...PAGERCommand,
935
+ PAGERCommand,
897
936
  [...PAGERArguments],
898
937
  {
899
938
  stdio: ["pipe", "inherit", "inherit"],