loukai-app 0.4.0 → 0.4.2

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.
Files changed (29) hide show
  1. package/README.md +5 -5
  2. package/package.json +2 -2
  3. package/src/main/creator/conversionService.js +5 -5
  4. package/src/main/creator/pythonRunner.js +3 -2
  5. package/src/main/creator/stemBuilder.js +9 -9
  6. package/src/main/handlers/fileHandlers.js +1 -1
  7. package/src/main/handlers/libraryHandlers.js +3 -0
  8. package/src/main/webServer.js +2 -2
  9. package/src/renderer/components/creator/CreateTab.jsx +6 -6
  10. package/src/renderer/dist/assets/{kaiPlayer-CoMx__a_.js → kaiPlayer-DSaY7TxC.js} +2 -2
  11. package/src/renderer/dist/assets/kaiPlayer-DSaY7TxC.js.map +1 -0
  12. package/src/renderer/dist/assets/songLoaders-CcYVonLu.js +2 -0
  13. package/src/renderer/dist/assets/{songLoaders-BaTgGib4.js.map → songLoaders-CcYVonLu.js.map} +1 -1
  14. package/src/renderer/dist/renderer.css +1 -1
  15. package/src/renderer/dist/renderer.js +11 -51
  16. package/src/renderer/dist/renderer.js.map +1 -1
  17. package/src/renderer/js/kaiPlayer.js +9 -7
  18. package/src/renderer/lib/cdgraphics.js +0 -1
  19. package/src/shared/services/creatorService.js +2 -2
  20. package/src/shared/services/libraryService.js +4 -1
  21. package/src/utils/m4aLoader.js +1 -1
  22. package/src/web/dist/assets/index-CGbmW1VG.js +11 -0
  23. package/src/web/dist/assets/{index-0H-RnRrV.js.map → index-CGbmW1VG.js.map} +1 -1
  24. package/src/web/dist/assets/index-GLKJK41r.css +1 -0
  25. package/src/web/dist/index.html +2 -2
  26. package/src/renderer/dist/assets/kaiPlayer-CoMx__a_.js.map +0 -1
  27. package/src/renderer/dist/assets/songLoaders-BaTgGib4.js +0 -2
  28. package/src/web/dist/assets/index-0H-RnRrV.js +0 -51
  29. package/src/web/dist/assets/index-DYW2zB0u.css +0 -1
@@ -673,10 +673,12 @@ export class KAIPlayer extends PlayerInterface {
673
673
  startAudioSources() {
674
674
  if (!this.audioContexts.PA || !this.audioContexts.IEM) return;
675
675
 
676
- // Sync start time for both outputs - add small delay to ensure synchronization
677
- const scheduleTime =
678
- Math.max(this.audioContexts.PA.currentTime, this.audioContexts.IEM.currentTime) + 0.1;
679
- this.startTime = scheduleTime;
676
+ // Schedule per context each AudioContext has its own local clock, so a single
677
+ // shared scheduleTime would bake in a skew equal to |PA.currentTime - IEM.currentTime|.
678
+ const lead = 0.1;
679
+ const paStart = this.audioContexts.PA.currentTime + lead;
680
+ const iemStart = this.audioContexts.IEM.currentTime + lead;
681
+ this.startTime = paStart; // getCurrentPosition() measures elapsed against PA's clock
680
682
 
681
683
  this.mixerState.stems.forEach((stem) => {
682
684
  // Skip mixdown stems - they contain the full mix and would overlap with individual stems
@@ -701,7 +703,7 @@ export class KAIPlayer extends PlayerInterface {
701
703
  const iemSource = this.audioContexts.IEM.createBufferSource();
702
704
  iemSource.buffer = audioBuffer;
703
705
  iemSource.connect(iemGainNode);
704
- iemSource.start(scheduleTime, offset);
706
+ iemSource.start(iemStart, offset);
705
707
  this.outputNodes.IEM.sourceNodes.set(stem.name, iemSource);
706
708
 
707
709
  // Also create PA source for backup:PA feature (muted by default via vocalsPAGain)
@@ -716,7 +718,7 @@ export class KAIPlayer extends PlayerInterface {
716
718
  this.micEngine.connectMusicSource(paSource);
717
719
  }
718
720
 
719
- paSource.start(scheduleTime, offset);
721
+ paSource.start(paStart, offset);
720
722
  this.outputNodes.PA.sourceNodes.set(stem.name + '_vocalsPA', paSource);
721
723
  }
722
724
  } else {
@@ -735,7 +737,7 @@ export class KAIPlayer extends PlayerInterface {
735
737
  this.micEngine.connectMusicSource(paSource);
736
738
  }
737
739
 
738
- paSource.start(scheduleTime, offset);
740
+ paSource.start(paStart, offset);
739
741
  this.outputNodes.PA.sourceNodes.set(stem.name, paSource);
740
742
 
741
743
  // Add onended handler as backup to position monitoring
@@ -246,7 +246,6 @@ class W {
246
246
  for (
247
247
  this.pc > s && ((this.pc = -1), (o.isRestarting = !0));
248
248
  this.pc < s && this.pc < this.numPackets;
249
-
250
249
  ) {
251
250
  this.pc++;
252
251
  const i = this.pc * 24,
@@ -330,7 +330,7 @@ export function stopConversion() {
330
330
 
331
331
  /**
332
332
  * Repair a stem file to fix NI Stems metadata
333
- * @param {string} filePath - Path to .stem.m4a file
333
+ * @param {string} filePath - Path to .stem.mp4 file
334
334
  * @returns {Promise<Object>} Repair result
335
335
  */
336
336
  export async function repairStem(filePath) {
@@ -345,7 +345,7 @@ export async function repairStem(filePath) {
345
345
 
346
346
  /**
347
347
  * Batch repair multiple stem files
348
- * @param {string[]} filePaths - Array of paths to .stem.m4a files
348
+ * @param {string[]} filePaths - Array of paths to .stem.mp4 files
349
349
  * @returns {Promise<Object>} Batch repair results
350
350
  */
351
351
  export async function repairStems(filePaths) {
@@ -322,7 +322,10 @@ export async function getSongInfo(mainApp, filePath) {
322
322
  // Not in cache, extract metadata directly
323
323
  const lowerPath = filePath.toLowerCase();
324
324
  const format =
325
- lowerPath.endsWith('.stem.m4a') || lowerPath.endsWith('.m4a') || lowerPath.endsWith('.mp4')
325
+ lowerPath.endsWith('.stem.mp4') ||
326
+ lowerPath.endsWith('.stem.m4a') ||
327
+ lowerPath.endsWith('.m4a') ||
328
+ lowerPath.endsWith('.mp4')
326
329
  ? 'm4a-stems'
327
330
  : lowerPath.endsWith('.kar') || lowerPath.endsWith('.zip')
328
331
  ? 'cdg-archive'
@@ -49,7 +49,7 @@ class M4ALoader {
49
49
 
50
50
  /**
51
51
  * Load M4A Stems format with karaoke extensions
52
- * @param {string} m4aPath - Path to .stem.m4a file
52
+ * @param {string} m4aPath - Path to .stem.mp4 file
53
53
  * @returns {Promise<Object>} M4A data object compatible with KAI structure
54
54
  */
55
55
  static async load(m4aPath) {