about summary refs log tree commit diff
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2024-10-01T19·37+0200
committerProfpatsch <mail@profpatsch.de>2024-10-05T13·49+0000
commit9c1e3687fe90bb30129b40c89bb7ea29d648c4d1 (patch)
tree03311ee2ec5a0e01130c57dd517e96f787586b82
parent92ad57febe5247816d8fadc1b29d0772536d4a67 (diff)
feat(users/Profpatsch/lyric): add tapping & improve silence warning r/8769
Add a tapping command that does not quantize the timestamps.

For the silence warning, we make it BPM-dependent (defaulting to
120BPM as everywhere else), meaning for slower songs we give a higher
possible time difference before we display a warning.

Change-Id: Idefc44166639b23c2105a1a810ac22ed84457225
Reviewed-on: https://cl.tvl.fyi/c/depot/+/12563
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
-rw-r--r--users/Profpatsch/lyric/extension/package.json5
-rw-r--r--users/Profpatsch/lyric/extension/src/extension.ts80
2 files changed, 67 insertions, 18 deletions
diff --git a/users/Profpatsch/lyric/extension/package.json b/users/Profpatsch/lyric/extension/package.json
index 78e2eb1c3cf6..73bf53e812fc 100644
--- a/users/Profpatsch/lyric/extension/package.json
+++ b/users/Profpatsch/lyric/extension/package.json
@@ -31,6 +31,11 @@
         "category": "LRC"
       },
       {
+        "command": "extension.tapBpm",
+        "title": "Add bpm header by tapping to the song",
+        "category": "LRC"
+      },
+      {
         "command": "extension.quantizeToEigthNote",
         "title": "Quantize timestamps to nearest eighth note",
         "category": "LRC"
diff --git a/users/Profpatsch/lyric/extension/src/extension.ts b/users/Profpatsch/lyric/extension/src/extension.ts
index 55b8f9e49e3d..417dc42e1851 100644
--- a/users/Profpatsch/lyric/extension/src/extension.ts
+++ b/users/Profpatsch/lyric/extension/src/extension.ts
@@ -11,6 +11,7 @@ export function activate(context: vscode.ExtensionContext) {
     vscode.commands.registerCommand('extension.jumpToLrcPosition', jumpToLrcPosition),
     vscode.commands.registerCommand('extension.shiftLyricsDown', shiftLyricsDown),
     vscode.commands.registerCommand('extension.shiftLyricsUp', shiftLyricsUp),
+    vscode.commands.registerCommand('extension.tapBpm', tapBpm),
     vscode.commands.registerCommand('extension.quantizeToEigthNote', quantizeToEigthNote),
     vscode.commands.registerCommand(
       'extension.fineTuneTimestampDown100MsAndPlay',
@@ -40,7 +41,7 @@ function jumpToLrcPosition() {
   const editor = vscode.window.activeTextEditor;
 
   if (!editor) {
-    vscode.window.showInformationMessage('No active editor found.');
+    vscode.window.showErrorMessage('No active editor found.');
     return;
   }
 
@@ -90,7 +91,7 @@ async function shiftLyricsDown() {
   const editor = vscode.window.activeTextEditor;
 
   if (!editor) {
-    vscode.window.showInformationMessage('No active editor found.');
+    vscode.window.showErrorMessage('No active editor found.');
     return;
   }
 
@@ -141,7 +142,7 @@ async function shiftLyricsUp() {
   const editor = vscode.window.activeTextEditor;
 
   if (!editor) {
-    vscode.window.showInformationMessage('No active editor found.');
+    vscode.window.showErrorMessage('No active editor found.');
     return;
   }
 
@@ -182,25 +183,44 @@ async function shiftLyricsUp() {
   });
 }
 
+/**
+ * Tap the BPM of the track and write it to the header of the active text editor.
+ * @remarks
+ * This function requires the following dependencies:
+ * - `vscode` module for accessing the active text editor and displaying messages.
+ */
+async function tapBpm() {
+  const editor = vscode.window.activeTextEditor;
+
+  if (!editor) {
+    vscode.window.showErrorMessage('No active editor found.');
+    return;
+  }
+
+  const ext = new Ext(editor.document);
+  const startBpm = ext.findBpmHeader();
+
+  const bpm = await timeInputBpm(startBpm);
+
+  if (bpm === undefined) {
+    return;
+  }
+
+  await ext.writeHeader('bpm', bpm.toString());
+}
+
 /** first ask the user for the BPM of the track, then quantize the timestamps in the active text editor to the closest eighth note based on the given BPM */
 async function quantizeToEigthNote() {
   const editor = vscode.window.activeTextEditor;
 
   if (!editor) {
-    vscode.window.showInformationMessage('No active editor found.');
+    vscode.window.showErrorMessage('No active editor found.');
     return;
   }
 
   const ext = new Ext(editor.document);
 
-  const startBpmStr = ext.findHeader('bpm')?.value;
-  let startBpm;
-  if (startBpmStr !== undefined) {
-    startBpm = parseInt(startBpmStr, 10);
-    if (isNaN(startBpm)) {
-      startBpm = undefined;
-    }
-  }
+  const startBpm = ext.findBpmHeader();
   const bpm = await timeInputBpm(startBpm);
 
   if (bpm === undefined) {
@@ -250,7 +270,7 @@ function fineTuneTimestampAndPlay(amountMs: number) {
     const editor = vscode.window.activeTextEditor;
 
     if (!editor) {
-      vscode.window.showInformationMessage('No active editor found.');
+      vscode.window.showErrorMessage('No active editor found.');
       return;
     }
 
@@ -371,7 +391,7 @@ async function uploadToLrclibDotNet() {
   const editor = vscode.window.activeTextEditor;
 
   if (!editor) {
-    vscode.window.showInformationMessage('No active editor found.');
+    vscode.window.showErrorMessage('No active editor found.');
     return;
   }
 
@@ -518,7 +538,7 @@ async function uploadToLrclibDotNet() {
   }
 }
 
-// If the difference to the timestamp on the next line is larger than 10 seconds, underline the next line and show a warning message on hover
+// If the difference to the timestamp on the next line is larger than 10 seconds (for 120 BPM), underline the next line and show a warning message on hover
 export function registerCheckLineTimestamp(_context: vscode.ExtensionContext) {
   const changesToCheck: Set<vscode.TextDocument> = new Set();
   const everSeen = new Set<vscode.TextDocument>();
@@ -590,19 +610,30 @@ function doEditorChecks(
   }
 }
 
-/** Warn if the difference to the timestamp on the next line is larger than 10 seconds */
+/** Warn if the difference to the timestamp on the next line is larger than
+ * * 10 seconds at 120 BPM
+ * * 5 seconds at 240 BPM
+ * * 20 seconds at 60 BPM
+ * * etc
+ */
 function timeDifferenceTooLarge(ext: Ext, line: number): string | undefined {
+  const bpm = ext.findBpmHeader() ?? 120;
+  const maxTimeDifference = 10000 * (120 / bpm);
   const timeDifference = ext.getTimeDifferenceToNextLineTimestamp(
     new vscode.Position(line, 0),
   );
   if (
     !timeDifference ||
     timeDifference.thisLineIsEmpty ||
-    timeDifference.difference <= 10000
+    timeDifference.difference <= maxTimeDifference
   ) {
     return;
   }
-  return `Time difference to next line is ${formatTimestamp(timeDifference.difference)}`;
+  return `Time difference to next line is ${formatTimestamp(
+    timeDifference.difference,
+  )}, should there be silence here? At ${bpm} BPM, we assume anything more than ${(
+    maxTimeDifference / 1000
+  ).toFixed(2)} seconds is a mistake.`;
 }
 
 /** Warn if the timestamp on the next line is smaller or equal to the current timestamp */
@@ -675,6 +706,19 @@ class Ext {
     }
   }
 
+  /** Find the bpm header and return the bpm as number, if any */
+  findBpmHeader() {
+    const startBpmStr = this.findHeader('bpm')?.value;
+    let bpm;
+    if (startBpmStr !== undefined) {
+      bpm = parseInt(startBpmStr, 10);
+      if (isNaN(bpm)) {
+        bpm = undefined;
+      }
+    }
+    return bpm;
+  }
+
   // check if the given line is a header line
   isHeaderLine(line: string) {
     return (