Autor |
Beitrag |
kissgdr
Beiträge: 21
|
Verfasst: Mo 04.01.21 21:48
Ich benötige Hilfe zur Lösung des folgenden Problems:
Ich möchte ein, in Delphi7 geschriebenes Programm mit kurzen Tonsignalen erweitern.
Die Audio-dateien sind 1-3 Sekunden lang (.wav oder .mp3) und sind in einem Memorystream gespeichert.
Bei .wav-Dateien löst MediaPlayer das Problem leider nicht, da nur externe Dateien verarbeitet werden können (FileName='string').
(Darüber hinaus kann ein .exe-Programm, das MediaPlayer verwendet, in einer Win10-Umgebung nicht ausgeführt werden, da ein 'Exception EMCIDeviceError' wird generiert.)
Ich suche nach einer Lösung, die
- kann Memorystream als Input verwenden
- das erstellte EXE-Modul wird auch in Win10-Umgebung laufen
|
|
Hotte123
Hält's aus hier
Beiträge: 1
|
Verfasst: Mo 04.01.21 23:06
Moin,
schau dir mal die bass.dll an. Nette Beschreibung unter MeMP - Mein einfacher Mp3-Player.
Viel Spaß noch.
Moderiert von Th69: URL-Titel hinzugefügt.
|
|
Th69
Beiträge: 4784
Erhaltene Danke: 1055
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Di 05.01.21 11:14
Es gibt auch die WinAPI-Funktion sndPlaySound (für Waveform-Audio), s.a. Delphi: play sound from memorystream.
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 05.01.21 11:21
Die Funktion kann man auch direkt auf Ressourcen verwenden ohne die Ressource vorher in einen MemoryStream zu kopieren (was ich hier einmal vermute): Playing WAVE Resources
Mit der genannten bass.dll hat man allerdings deutlich mehr Möglichkeiten.
Moderiert von Th69: URL-Titel hinzugefügt.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Di 05.01.21 18:54
Danke für die Ideen. Ich habe bisher keine Software außerhalb des offiziellen Delphi verwendet, ich kenne sie nicht. Ihr Studium dauert länger.
Die kurze Audiosignale derzeit sind im WAV-Format, und wegen das spezielle GSM-WAV-Format sind sie kürzer als das MP3-Format, und die Tonqualität ebenfalls akzeptabel ist. Da ich 10-12 solcher kleinen Audiodateien (jeweils 10-25 KB) verarbeiten möchte, finde ich es benutzerfreundlicher, sie in die EXE-Datei zu integrieren, daher möchte ich Memorystream verwenden.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Mi 06.01.21 14:08
Das empfohlene Beispiel Delphi: play Sound from memorystream verwendet die PlayWaveStream-Prozedur, aber ich habe nur eine C ++ - Beschreibung dafür gefunden.
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 06.01.21 14:21
kissgdr hat folgendes geschrieben : | Das empfohlene Beispiel Delphi: play Sound from memorystream verwendet die PlayWaveStream-Prozedur, aber ich habe nur eine C ++ - Beschreibung dafür gefunden. |
Die Prozedur ist doch dort komplett enthalten in dem Link.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Mi 06.01.21 19:13
leider kann ich es nicht finden.
Signin oder Login ist ständig falsch (Timeout).
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 06.01.21 21:05
Einloggen, um Attachments anzusehen!
|
|
kissgdr
Beiträge: 21
|
Verfasst: Do 07.01.21 16:38
Ich sehe das auch, aber der referenzierte sndPlaySound kann nicht aufgelöst werden.
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 07.01.21 23:21
Eine Suche in den bei Delphi normalerweise mitgelieferten Quelltexten oder bei Google zeigt, dass die Funktion in der Unit Winapi.MMSystem zu finden ist.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 15:03
jaenicke hat folgendes geschrieben : | Eine Suche in den bei Delphi normalerweise mitgelieferten Quelltexten oder bei Google zeigt, dass die Funktion in der Unit Winapi.MMSystem zu finden ist. |
Vielen Dank.
Ich habe dies zuvor in der Delphi7-Help (Windows SDK), gefunden.
Ich habe viele Dokumentátionen durchgelest, leider habe ich bisher nirgends ein Beispiel gefunden, das zeigt, wie eine bestimmte win.api aus einer Delphi-Umgebung aufgerufen werden kann. (Was soll ich dazu tun?)
In meiner bisherigen Arbeit war Delphis eigenes Toolkit ausreichend.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 15:42
jaenicke hat folgendes geschrieben : | Eine Suche in den bei Delphi normalerweise mitgelieferten Quelltexten oder bei Google zeigt, dass die Funktion in der Unit Winapi.MMSystem zu finden ist. |
Nochmal vielen Dank!
Ich habe die Lösung gefunden!! uses MMSystem;
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 08.01.21 17:46
Ach ja, bei Delphi 7 gab es die Namespaces noch nicht, da habe ich nicht dran gedacht. Damals hieß die Unit noch nur MMSystem wie du ja schon gemerkt hast.
Seit einigen Jahren heißt sie der besseren Übersicht halber Winapi.MMSystem.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 21:47
Basierend auf den Ideen, die ich erhalten habe, habe ich ein Testprogramm erstellt, das so funktioniert, wie ich es möchte:
- Kurze WAV-Signale werden von einem MemoryStream abgespielt
- Das Programm funktioniert auch in XP-, Win7- und Win10-Umgebungen
Ich mag diese Lösung wirklich nicht, weil ich das Ende des Streams beim Abspielen nicht kontrollieren kann.
Daher verwende ich eine sehr grobe Lösung.
Leider konnte ich nirgendwo ein Delphi7-Dokument finden, mit dem ich dieses Problem lösen konnte
(wie z.B. in TMediaPlayer die Notify-Properties)
Ich würde mich sehr freuen, wenn ich eine günstigere Lösung finden könnte
Wie kann ich das Testprogram aufladen? (minimum .pas, .dfm, .dpr)
|
|
Gausi
Beiträge: 8538
Erhaltene Danke: 475
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Fr 08.01.21 21:52
Ich hänge mich hier auch mal kurz dran, da ich per Mail dazu eine Anfrage bekommen habe:
Mein Tutorial zur bass.dll geht da ja etwas am Thema vorbei, aber man kann mit der bass.dll wohl auch aus dem Speicher heraus abspielen. Ansätze dazu sollten sich in der Dokumentation zur bass.dll finden. Wie das dort mit Notifications geht, weiß ich leider auch nicht genau.
Ich habe den Thread hier nebenbei verfolgt, und nicht auf die E-Mail geantwortet, da das hier im Topic ja durchaus in eine konstruktive Richtung läuft.
Testprogramm hochladen: am besten zippen und dann per "Dateianhang hinzufügen" an den Beitrag dran hängen.
_________________ We are, we were and will not be.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 22:03
Ich habe gefunden - Dateianhang hinzufügen
Einloggen, um Attachments anzusehen!
|
|
jaenicke
Beiträge: 19285
Erhaltene Danke: 1743
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 08.01.21 22:06
kissgdr hat folgendes geschrieben : | Ich mag diese Lösung wirklich nicht, weil ich das Ende des Streams beim Abspielen nicht kontrollieren kann. |
Möchtest du nur einen Teil des Sounds abspielen und das Ende angeben?
Oder möchtest du wissen wann das Abspielen beendet ist? Das geht sehr einfach, weil sndPlaySound mit dem Flag SND_SYNC erst nach dem Ende des Abspielens zurückkehrt. Wenn du das also in einen Thread packst, kannst du danach ein Event auslösen ohne etwas anderes als den Thread zu blockieren.
// EDIT:
Ich dachte es mir schon, dass das zweite gemeint ist. Einfaches Beispiel (allerdings reagiert die Exe dann während des Abspielens nicht, daher der Hinweis auf einen Thread):
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| procedure PlayWaveStream(Stream: TMemoryStream); begin if Stream = nil then sndPlaySound(nil, SND_SYNC) else sndPlaySound(Stream.Memory, (SND_SYNC or SND_MEMORY)); end;
procedure TForm1.ExitClick(Sender: TObject); begin Close; end;
procedure TForm1.StartClick(Sender: TObject); begin wav_stream:= TMemoryStream.Create; try wav_stream.LoadFromFile('signal_1.wav'); PlayWaveStream(wav_stream); wav_stream.LoadFromFile('signal_2.wav'); PlayWaveStream(wav_stream); finally wav_stream.Free; end; end; |
Halt sollte man nie verwenden. Close schließt das Programm sauber.
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 22:20
Ohne .exe file probiere ich nochmal
Einloggen, um Attachments anzusehen!
|
|
kissgdr
Beiträge: 21
|
Verfasst: Fr 08.01.21 23:16
Ich habe die Testdatei zweimal gesendet, da sowohl Google Chrome als auch Win10 beim Herunterladen aufgrund der EXE-Datei einen Virus gemeldet haben.
Danke für die schnelle Antwort - mit Delphi Code.
Leider kann ich dies aufgrund externer Dateien nicht verwenden.
ich muss sagen, dass ich in meinem Programm viele kleine externe Dateien verwende.
(Graphik von Schachfiguren, Hilfedokumenten und Audiodateien).
Ich speichere diese in einer Containedatei und platziere die erforderliche Segment - bei Bedarf - im Memorystream, aufgrund eine Seriennummer.
Wenn das Programm veröffentlicht wird, installiert der Benutzer zusätzlich zu .exe nur eine Containerdatei.
In meiner groben Lösung kann das Signal länger oder kürzer sein als waiting_for(x), es funktioniert immer gut.
Wenn das Signal länger ist, wird es abgeschaltet, wenn es kürzer ist, dauert es bis zum Ende des Intervalls.
|
|
|