Gemerkt wurde nur, was gefunden wurde. Eine Staffel ohne Abspann — es gibt genug davon — sah damit bei jedem Scan aus wie eine, in der noch niemand nachgesehen hat, und wurde wieder abgetastet: jede Tonspur jeder Folge noch einmal von der Platte, für immer, ohne Ertrag. Bei sechstausend Folgen ist das kein Schönheitsfehler. Jetzt steht auch „gesucht und nichts gefunden" in der Datenbank, je Staffel und Art. Ausgelöst wird ein zweiter Lauf von der Folgenzahl: kommt eine Folge dazu, gibt es etwas Neues zu vergleichen, sonst nicht. Ein Zeitstempel allein täte das nicht — eine Staffel, die sich nie ändert, hat nie einen Grund für einen zweiten Lauf. Dazu der Knopf, der ausdrücklich doch noch einmal rechnet: die Uhr auf der Serienseite sucht ab jetzt immer neu. Von selbst läuft die Suche nach jedem Scan und überspringt dort das Abgesuchte; wer hier drückt, will genau das Gegenteil. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
3.0 KiB
C#
86 lines
3.0 KiB
C#
using Flaro.Media;
|
|
|
|
namespace Flaro.Media.Tests;
|
|
|
|
/// <summary>Die Ausgabe von <c>fpcalc -raw</c> lesen.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// <b>Ohne das Programm selbst.</b> Ob Chromaprint rechnen kann, ist nicht
|
|
/// unsere Frage; ob wir seine Ausgabe richtig verstehen, schon. Die Zahlen
|
|
/// kommen mit Vorzeichen, gemeint sind die Bitmuster — wer das verwechselt,
|
|
/// bekommt einen Abdruck, der nie zu einem zweiten passt.
|
|
/// </remarks>
|
|
public class TonabdruckleserTests
|
|
{
|
|
[Test]
|
|
public void Die_Zahlen_werden_als_Bitmuster_gelesen()
|
|
{
|
|
var abdruck = Tonabdruckleser.Lesen("DURATION=120\nFINGERPRINT=1,-1,2147483647,-2147483648\n");
|
|
|
|
Assert.That(abdruck, Is.EqualTo(new uint[] { 1u, 0xFFFFFFFFu, 0x7FFFFFFFu, 0x80000000u }));
|
|
}
|
|
|
|
[Test]
|
|
public void Ohne_Abdruckzeile_kommt_nichts()
|
|
{
|
|
Assert.That(Tonabdruckleser.Lesen("DURATION=120\n"), Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void Eine_leere_Zeile_ergibt_keinen_Abdruck()
|
|
{
|
|
Assert.That(Tonabdruckleser.Lesen("FINGERPRINT=\n"), Is.Empty);
|
|
}
|
|
|
|
/// <summary>Eine Zeitscheibe ist rund 124 Millisekunden.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// Daran hängt jede Zeitangabe, die aus einem Abdruck entsteht. Stimmt
|
|
/// die Zahl nicht, liegt jede Marke um denselben Faktor daneben — und
|
|
/// das sähe aus wie ein Fehler in der Erkennung.
|
|
/// </remarks>
|
|
[Test]
|
|
public void Eine_Zeitscheibe_dauert_124_Millisekunden()
|
|
{
|
|
Assert.That(Tonabdruckleser.SekundenJeAbdruck, Is.EqualTo(0.1238).Within(0.0005));
|
|
}
|
|
}
|
|
|
|
/// <summary>Was fpcalc wirklich kann — nachgemessen, nicht angenommen.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// <b>Der Anlass ist ein Fehler, der im Betrieb stand.</b> Hier wurde
|
|
/// <c>-ts 0</c> übergeben, in der Annahme, das sei ein Startpunkt. Es ist
|
|
/// ein Schalter („gib Zeitstempel aus"), und die Null las fpcalc als
|
|
/// zweiten Dateinamen: Code 2, „No such file or directory" — über Dateien,
|
|
/// die da waren. Einen Startpunkt gibt es bei fpcalc nicht.
|
|
///
|
|
/// Gemessen am Binärprogramm aus dem Abbild, an einer Datei von 2700
|
|
/// Sekunden: <c>-length 0</c> ergibt 21 786 Werte, also 0,1239 Sekunden je
|
|
/// Wert; <c>-length 120</c> bricht nach 948 Werten ab.
|
|
/// </remarks>
|
|
public class TonabdruckRateTests
|
|
{
|
|
[Test]
|
|
public void Die_Rate_stimmt_mit_der_Messung_ueberein()
|
|
{
|
|
// 21 786 Werte für 2700 Sekunden.
|
|
var gemessen = 2700.0 / 21786;
|
|
Assert.That(Math.Abs(gemessen - Tonabdruckleser.SekundenJeAbdruck), Is.LessThan(0.0005));
|
|
}
|
|
|
|
/// <summary>Eine Stunde Abdruck passt in eine überschaubare Reihe.</summary>
|
|
///
|
|
/// <remarks>
|
|
/// Damit niemand auf die Idee kommt, den Abdruck einer ganzen Folge für
|
|
/// zu gross zu halten und wieder in Ausschnitten zu lesen: eine Stunde
|
|
/// sind knapp 29 000 Werte, also 116 Kilobyte.
|
|
/// </remarks>
|
|
[Test]
|
|
public void Eine_Stunde_sind_rund_29000_Werte()
|
|
{
|
|
var werte = (int)(3600 / Tonabdruckleser.SekundenJeAbdruck);
|
|
Assert.That(werte, Is.InRange(28500, 29500));
|
|
}
|
|
}
|