AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte erweiterte Demo für BASSMIDI.DLL
Thema durchsuchen
Ansicht
Themen-Optionen

erweiterte Demo für BASSMIDI.DLL

Ein Thema von Delfiano · begonnen am 9. Nov 2020 · letzter Beitrag vom 22. Feb 2021
Antwort Antwort
Delphi.Narium

Registriert seit: 27. Nov 2017
2.555 Beiträge
 
Delphi 7 Professional
 
#1

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 21. Nov 2020, 10:50
Zitat von Delfiano:
- der missglückte Versuch, Lyrics sauber (also komplett) aus Midis zu extrahieren, falls vorhanden
ProcessMarkText sieht bei mir so aus:
Delphi-Quellcode:
function ProcessMarkText(CaptionText, MarkText : string) : string;
begin
  if Length(MarkText) > 0 then begin
    case MarkText[1] of
      '@'     : Result := CaptionText;
      '\'     : Result := #13#10 + Copy(MarkText, 2, pred(Length(MarkText)));
      '/','<' : Result := CaptionText + #13#10 + Copy(MarkText, 2, Length(MarkText));
      '*'     : Result := CaptionText + #13#10 + MarkText + #13#10;
      #13 : Result := CaptionText + #13#10;
    else
      Result := CaptionText + MarkText;
    end;
  end else begin
    Result := CaptionText;
  end;
end;
Sofern bei Deinem Delphi bei Lyrics_Memo WordWrap auf true stehen sollte, ändere das bitte auf false, sonst stimmen die Zeilenumbrüche in der erstellten Datei nicht, dito. bei lbLyrics.

Edit:

Durch die unterschiedliche Breite der beiden Memos und eingeschaltetem WordWrap passt der Vergleich in der Routine lbLyricsChange
Delphi-Quellcode:
    IF Lyrics_Memo.Lines[Lyrics_Memo.Lines.count-1]<>lbLyrics.Lines[lbLyrics.Lines.count-2]
    THEN BEGIN
nicht zwingend, da durch unterschiedliche Zeilenbreiten andere Zeilenumbrüche erfolgen.

Geändert von Delphi.Narium (21. Nov 2020 um 11:41 Uhr) Grund: Text erweitert
  Mit Zitat antworten Zitat
Delfiano

Registriert seit: 13. Jul 2020
61 Beiträge
 
#2

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 21. Nov 2020, 21:35
Danke für die Antwort, aber das Probem besteht leider weiter.

Ich hab das jetzt noch paar mal durchgetestet, mal mit wordwrap, mal ohne, mal mit dem ursprünglichen ProcessMarkText und mal mit Deiner übersichtlicheren Version.

Die Ergebnisse sind identisch, ausser dass beider Deiner Version von ProcessMarkText am Dateiende noch eine zusätzliche Leerzeile drangehängt wird. Daraufhin werde ich mir das noch mal genauer ansehen.

Das Problem ist nach wie vor, dass immer die letzte Zeile eines Absatzes geschluckt wird, weil ich doch die vorletzte Zeile auswerte, damit nur vollständige Zeilen geschrieben werden. Ich weiss nicht, wie ich an die letzte (vollständige) Zeile komme, bevor neuer Text eingelesen wird.

Als ich es mal anders machte und wirklich jede Änderung in die Datei schrieb, waren diese letzten Zeilen der Asbätze zwar enthalten, aber dafür jede Menge unbrauchbaren Zeilen.

Mal hier die so erzeugten letzten Zeilen des ersten Absatzes von "achy-breaky-heart" (Midi-Datei im Anhang zur Kontrolle)

But Mr. DJ, please
I'm beggin' on my knees
I just can't take no
But Mr. DJ, please
I'm beggin' on my knees
I just can't take no more
But Mr. DJ, please
I'm beggin' on my knees
I just can't take no more of
But Mr. DJ, please
I'm beggin' on my knees
I just can't take no more of Bil
But Mr. DJ, please
I'm beggin' on my knees
I just can't take no more of Billy
But Mr. DJ, please
I'm beggin' on my knees
I just can't take no more of Billy Ray

Bei der von mir im Prog benutzten Methode, nur vollständige Zeilen zu schreiben, fehlt die letzte, also "I just can't take no more of Billy Ray" und das ist bei allen Absätzen so.

Auch hab ich probiert, erst alles intern (wie oben gezeigt) zwischenzuspeichern und dann auszuwerten, aber auch das ist mißglückt.

Das Problem ist ganz einfach, dass die Texte bruchstückweise erscheinen, damit sie zur jeweiligen Stelle der Musik passen und ich einfach nicht weiss, wie ich sie sauber und vollständig zu einer ganzen Zeile zusammenfassen und speichern kann, bevor die nächste beginnt und alles vorherige löscht.

Ergänzung

Wie weitere Tests ergaben, sind Lyrics in Midi-Dateien absolut nie einheitlich integriert. Mit der ProcessMarkText-Version von Delphi.Narium werden bei einigen saubere Zeilenumbrüche erzeugt, die es bei der Original-Version von un4seen.com nicht gibt. Da klebt manches direkt aneinander.

Aber leider gibt es (je nach Midi-Datei) auch mit der Version von Delphi.Narium Probleme.

Ich häng hier mal noch einen Link zu einer Website mit Karaoke-Midi-Dateien an. Interessanterweise sind da auch die Texte nochmal komplett angegeben, was den Vergleich mit dem erlaubt, was durch das Prog angezeigt bzw. gespeichert wird.

http://www.karaokeden.com/karaoke
Angehängte Dateien
Dateityp: zip achy-breaky-heart.zip (29,3 KB, 10x aufgerufen)

Geändert von Delfiano (22. Nov 2020 um 00:04 Uhr) Grund: Link zu Website mit Karaoke-Midi-Dateien hinzugefügt
  Mit Zitat antworten Zitat
Delfiano

Registriert seit: 13. Jul 2020
61 Beiträge
 
#3

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 22. Nov 2020, 09:41
Gerade habe ich meine wahrscheinlich letzte Version 0.8b vom 21.11.2020 in den Startbeitrag hochgeladen. Der Vorschlag von Delphi.Narium ist dabei aber noch nicht enthalten. Die ZIP-Datei enthält nur die EXE-Datei und die geänderte Hauptunit.

Leider bin ich nicht so gut im Beschreiben. Weil es mir gesundheitlich nicht gut geht, ist das wahrscheinlich auch meine letzte Version überhaupt.

Gedanklich bin ich auch so unkonzentriert, dass mir nicht mal geglückt ist, dem Programm Parameter zu übergeben, weil es dann gleich Fehler wegen einem Listenindex von -1 gibt. Wahrscheinlich war es von Anfang an falsch, auf fremden Vorgaben aufzubauen, statt erst ein stabiles Grundgerüst zu erstellen und erst danach die anderen Sachen zu integrieren.

Wer möchte, kann, darf und sollte meine paar nützlichen Features gerne jederzeit ungefragt in eigene Projekt übernehmen oder dieses hier nach eigenen Vorstellungen weiterentwickeln oder völlig umbauen.

Was mir noch auffiel, obwohl es keine unmittelbare Auswirkungen hat:

Weil ich statt einem TLabel für die Lyrics ein TMemo nahm, wären vielleicht diese Korrekturen sinnvoll:

LyricSync:
//TLabel(user).Caption := ProcessMarkText(TLabel(user).Caption, Mark.text);
TMemo(user).Text := ProcessMarkText(TMemo(user).Text, Mark.text);

TextSync:
//TLabel(user).Caption := ProcessMarkText(TLabel(user).Caption, Mark.text);
TMemo(user).Text := ProcessMarkText(TMemo(user).Text, Mark.text);

EndSync:
//TLabel(user).Caption := '';
TMemo(user).Text := '';

Geändert von Delfiano (22. Nov 2020 um 09:45 Uhr) Grund: ergänzender Hinweis
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.555 Beiträge
 
Delphi 7 Professional
 
#4

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 22. Nov 2020, 10:12
Ausgehend vom textlichen Inhalt bei Midi-Dateien herrscht da wohl eher ein absolutes Chaos vor.

Hast Du eine Midi, bei der nix klapp und Du passt Deine Routine an, bis es klapp, dann klappt es für diese Midi. Nimmst Du nun eine andere und Du passt die Routine an ..., wird es bei der ersten Midi meist nicht mehr klappen.

Du brauchst "nur" eine Lösung, die meist in Ordnung ist.

Letzte Zeile:

Der Text wird immer im OnChange des lbLyrics (lbLyricsChange) übernommen. Dort wird immer der bisher vorhandene Text in den Gesamttext übernommen. Beim letzten (bisherigen) OnChange wird also alles bis zur vorletzten Zeile übernommen. Um die letzte Zeile zu bekommen, musst Du (höchstwahrscheinlich) das OnChange noch einmal "händisch" aufrufen, z. B. beim Beenden der Wiedergabe.

In EndSync setzt Du Caption auf ''. Dies dürfte das lbLyrics leeren, hier müsstest Du aber noch die letzte Zeile übernehmen die zwar schon in lbLyrics enthalten ist, deren Übernahme in die Ausgabe aber noch fehlt.

Ändere das bitte mal um z. B. so:
Delphi-Quellcode:
procedure EndSync(Handle : HSYNC; Stream : HSTREAM; data : DWORD; user : Pointer); stdcall;
begin
  // Hierdurch müsste das Ereignis lbLyricsChange zweimal ausgelöst werden.
  // Beim ersten mal kann dort die letzte Zeile übernommen werden.
  // Beim zweiten Mal wird lbLyrics gelehrt.
  // Da bei der bisherigen Logik immer die letzte Zeile fehlt, wäre die nun
  // fehlende letzte Zeile halt '--- Ende ---', das können wir verschmerzen ;-)
  TLabel(user).Caption := ProcessMarkText(TLabel(user).Caption, '\--- Ende ---');
  TLabel(user).Caption := '';
  // bzw.
  TMemo(user).Text := ProcessMarkText(TMemo(user).Text, '\--- Ende ---');
  TMemo(user).Text := '';
end; {EndSync}
Ist halt 'nen Versuch wert, habe es aber nicht getestet.

Bzgl. TLabel(user).Caption und TMemo(user).Text hat mich gewundert, dass die erste Variante überhaupt funktioniert hat
  Mit Zitat antworten Zitat
Delfiano

Registriert seit: 13. Jul 2020
61 Beiträge
 
#5

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 23. Nov 2020, 00:31
Danke, Delphi.Narium für die aufmunternden Worte.

Aber ich hab's mittlerweile aufgegeben. Leider funktioniert Dein Vorschlag bzgl. EndSync auch nicht.

Ansonsten: Ja, es stimmt. Bei den Methoden, wie Texte in Midi-Dateien eingebunden sind, herrscht absolutes Chaos. Bei einigen Midi-Dateien meiner Sammlung erscheinen diese zwar innerhalb von lbLyrics ( egal ob ich es beim ursprüngichen Label belassen habe oder das Memo draus gemacht habe ) aber werden nicht übernommen. Bei Deiner Variante von ProcessMarkText wird immerhin bei einigen wenigstes etwas zurück geliefert, aber bei anderen fehlt dafür jede erste Zeile.

Die Art und Weise wie ich lbLyricsChange konstruiert habe, ist einfach falsch. Korrekt wäre, jede Zeile solange aktiv zu halten, bis sich deren Inhalt nicht mehr ändert und sie dann zu übernehmen. Aber dafür fehlt mir einfach das Verständnis, wie man da vorgehen muss.

Ich hatte das bisher noch nie, dass Zeilen nach und nach gefüllt werden. Im Grunde müsste man immer den Text einer Zeile einlesen, in eine andere kopieren, beide miteinander vergleichen und erst wenn es keine Unterschiede mehr gibt, in Lyrics_Memo.Lines übernehmen. Das kommt einem zwar einfach vor, aber ich kann's einfach nicht.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#6

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 23. Nov 2020, 00:35
Versuch es mal mit meiner MidiLyricsClass
Oder versuch mal das hier weil in der Pas noch Abhängigkeiten fehlen.

Geändert von venice2 ( 1. Dez 2020 um 15:05 Uhr)
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.555 Beiträge
 
Delphi 7 Professional
 
#7

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 23. Nov 2020, 09:41
Habe mir mal etliche Midis im Hexeditor angeschaut. Als Zeilenumbruch kommt auch noch #10 in Frage (was eigentlich naheliegend ist - für die Unixwelt). Daher hab' ich meine Routine mal ein bisserl angepasst:
Delphi-Quellcode:
function ProcessMarkText(CaptionText, MarkText : string) : string;
begin
  if Length(MarkText) > 0 then begin
    case MarkText[1] of
      '@'     : Result := CaptionText;
      '\'     : Result := #13#10 + Copy(MarkText, 2, pred(Length(MarkText)));
      '/','<' : Result := CaptionText + #13#10 + Copy(MarkText, 2, Length(MarkText));
      '*'     : Result := CaptionText + #13#10 + MarkText + #13#10;
      #10 : Result := CaptionText + #13#10;
      #13 : Result := CaptionText + #13#10;
    else
      Result := CaptionText + MarkText;
    end;
  end else begin
    Result := CaptionText;
  end;
end;
Ob's damit besser wird, weiß ich nicht, hatte noch keine Zeit im Zusammenhang mit Deinem Programm zu testen. Bei meinem scheint es das Ergebnis aber etwas zu verbessern. Blöd wird es nur, wenn in 'ner Midi nun #13#10 als Zeilenvorschub geliefert wird, dann haben wir ggfls. 'ne Leerzeile zuviel.
Delphi-Quellcode:
function ProcessMarkText(CaptionText, MarkText : string) : string;
begin
  if Length(MarkText) > 0 then begin
    case MarkText[1] of
      '@'     : Result := CaptionText;
      '\'     : Result := #13#10 + Copy(MarkText, 2, pred(Length(MarkText)));
      '/','<' : Result := CaptionText + #13#10 + Copy(MarkText, 2, Length(MarkText));
      '*'     : Result := CaptionText + #13#10 + MarkText + #13#10;
      #10 : Result := CaptionText + #13#10;
      #13 : case MarkText[2] of
                  #10 : Copy(MarkText, 3, Length(MarkText) - 2);
                else
                  Result := CaptionText + #13#10;
                end;
    else
      Result := CaptionText + MarkText;
    end;
  end else begin
    Result := CaptionText;
  end;
end;
Keine Ahnung, ob's so noch besser wird (oder das Ergebnis eher kontraproduktiv ist).

Der Quelltext von venice2 hat einen anderen (dafür aber funktionierenden) Ansatz: Die Mdiddatei wird auf Texte / Lyrics geparst und diese werden dann ausgegeben. Will man "nur" an die Texte kommen, um sie zu speichern und benötigt keine zur Wiedergabe synchrone Anzeige der Texte, erscheint mir das die bessere Lösung zu sein.
  Mit Zitat antworten Zitat
Delfiano

Registriert seit: 13. Jul 2020
61 Beiträge
 
#8

AW: erweiterte Demo für BASSMIDI.DLL

  Alt 23. Nov 2020, 09:54
@Venice2: Vielen Dank, aber ich habe damit grosse Probleme.

Es ist mir leider unmöglich, Deine Unit einzubinden, weil sie auf einem ganz anderen Konzept beruht, als das von un4seen.com, auf dessen Beispielen ich aufgebaut habe.

Mir geht es vor allem drum, mit Soundfonts zu arbeiten. Die Lyrics sind nur ein Nebenaspekt.

Eigentlich würde ich sogar gerne störende Texte (keine Lyrics) entfernen, die von diversen Konvertierungsprogrammen ungefragt in meine eigenen Kompositionen reingeknallt werden.

Dein sehr aufwändiges, vollständig fertiges - aber auf einer anderen Basis aufbauendes - Programm kann ich leider mit meinem Delphi 7 nicht mal ansatzweise compilieren.

Ich hab die fertige Exe-Datei paar mal ausprobiert. Es sieht zwar auf den ersten Blick optisch reizvoll aus, aber dann merkt man schnell, dass es mit für Midi völlig unerheblichen Elementen regelrecht überladen ist. Mal von der absolut unübersichtlichen Bedienbarkeit und diversen seltsamen, nicht näher beschreibbaren Fehlern abgesehen, sind die Lyrics nicht synchron zur Musik und der Aufbau von unten nach oben störend.

Ausserdem werden die Texte auch nicht (wie es mein Ziel ist) letztlich als Ganzes zusammengefasst. Das ist also auch nicht besser als die ursprüngliche Darstellung von un4seen.com, bei der Textteile (wenigstens synchron zur Musik) in einem Label erscheinen.

@Delphi.Narium:
Wie gehabt. Wie das jeweile Zeilenende aussieht, ist anscheinend unerheblich und die Vorgabe-Prozedur EndSync ist meiner Meinung nach völlig unnötig. Ich hab das mal getestet, indem ich gleich nach dem "begin" ein "exit" gesetzt habe. Der Text wird trotzdem gelöscht, auch ohne das man dazu extra eine Anweisung gibt.

Ich bleibe dabei: Mein Versuch, die einzelnen Absätze in "lbLyricsChange" zusammenzufassen, ist schon vom grundsätzlichen Denkansatz her falsch. Eigentlich würde sogar reichen, wenn man es hinbekäme, dass der Inhalt von lbLyrics nicht gelöscht wird, sondern neue Absätze angefügt werden. Aber auch dafür bin ich zu dumm.

Wahrscheinlich werde ich den Lyricsteil ganz weglasse, wenn sich dafür keine überall funktionierende Lösung findet. Mir geht es vor allem um die Nutzbarkeit der Soundfonts. Wenn's nur um das Abspielen von Mididateien ginge, gibt's erhebliche einfachere Sachen - auch mit Lyrics zeilenweise gekleckert und danach verschwindend.

Geändert von Delfiano (23. Nov 2020 um 11:50 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz