Autor |
Beitrag |
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 02.05.11 12:37
galagher hat folgendes geschrieben : | Muss ich die in jedem Fall mitgeben, also auch dann, wenn ich die Sounds als Dateien lade? |
Ja, natürlich.
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mo 02.05.11 13:09
Es gibt ebend Vor- und Nachteile
Benutzt Du nur das mmsystem und die Audiodateien im Res,brauchst Du zwar nix mitliefern, kannst aber nur global die Lautstärke ändern!
Mit Bass.DLL kannst Du viele tolle sachen machen, must sie aber mit ausliefern sonst kommt kein sound.
Naja gut, kann man auch in eine res packen, dann extraieren und auf Platte speichern. Aber das muss jeder für sich selbst entscheiden, wie transportabel er sein Prog schreibt.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
galagher
Beiträge: 2522
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Di 03.05.11 17:29
mySong:= TResourceStream.CreateFromID(hInstance, ResourceID, 'SOUND'); verursacht immer eine Zugriffsverletzung, und turboPASCAL's Beispiel kann ich nicht anwenden, weil ich die SoundFX.pas nicht habe.
Aber egal, wie gesagt, der ganze Aufwand, nur um die Lautstärke anwendungsbezogen ändern zu können, zahlt sich nicht aus, daher bleibe ich bei den Sounds als Resourcen.
Überlegenswert ist das Laden beim Programmstart aber allemal!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Di 03.05.11 17:56
galagher hat folgendes geschrieben : | mySong:= TResourceStream.CreateFromID(hInstance, ResourceID, 'SOUND'); verursacht immer eine Zugriffsverletzung,.. |
Dann stimmt Deine RC Datei nicht bzw der ResEditor macht was falsch?
Versuche es mal mit dem mmsystem und resource.
Beispiel meiner rc:
1 SOUND "E:\Programme\Borland\Delphi7\Projects\Bimel 2x.wav"
Delphi-Quelltext 1: 2:
| PlaySound(PChar(1),hInstance, snd_ASync or snd_Memory or snd_Resource); |
Wenn es dann nicht funct machst Du was falsch
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
galagher
Beiträge: 2522
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mi 04.05.11 17:15
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mi 04.05.11 17:30
Upps, ResourceID = integer hätte ich vielleicht erwähnen sollen. Da ich nur die ID benutzte, zwecks Arrays, macht sich leichter im gesamten Programm
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
galagher
Beiträge: 2522
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mi 04.05.11 17:43
ALF hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean); begin Bass_Stop; Bass_Free; FreeMem(myMem); mySong.Free;
end; | |
Sollte man nicht zumindest mySong und mymem jedesmal freigeben, nachdem der Sound abgespielt wurde?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 04.05.11 18:07
Nein, denn hier geht es ja gerade darum den selben Song mehrfach abzuspielen. Da macht es natürlich wenig Sinn die Daten bei jedem Abspielen neu in den Speicher zu laden. Denn genau das macht das Abspielen dann ja wieder langsamer.
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Mi 04.05.11 18:09
Jaein, wenn Du sie die ganze Zeit benötigst, ist es unnutz die ganze laderrei der sounds von vorn durchzuführen. So hast Du sie und kannst nun an allen Stellen wo du sie benötigst sofort starten ohne das Du jedesmal den ladevorgang ausführst.
Edit: Hier noch mal eine Entscheidungshilfe für Dich, wenn Du nun doch mit der Bass.DDL arbeitetst!
Wenn Du das Spiel weitegeben willst must Du die Bass.DLL mitgeben!
Wenn Du sie nicht als Res mit einpackst in Deiner Exe und dann wieder ertsellst wenn das Spiel gestartet wird,
brauchst Du auch Deine Sounds nicht in Res packen! Sparst dir somit den ganzen Aufwand mit MEM MySong usw.
Mit der herkömlichen Methode von der Platte, geht das
abspielen genauso schnell als wenn Du sie im Speicher hast!
Gruss ALf
mist der chef war schneller
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
galagher
Beiträge: 2522
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Do 05.05.11 19:00
Ich verstehe nicht ganz! Da ich resourceID verschiedene Werte zuweisen muss, um verschiedene Soundeffekte abzuspielen, kann ich das so nicht brauchen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| procedure TForm1.FormCreate(Sender: TObject); begin resourceID:= 1; mySong:= TResourceStream.CreateFromID(hInstance, ResourceID, 'SOUND'); GetMem(myMem, mySong.Size); mysong.Read(myMem^, mySong.Size); end;
procedure TForm1.Button1Click(Sender: TObject); begin myVolume:= 0.2; myPlay:= BASS_StreamCreateFile(True, myMem , 0, mySong.Size, BASS_STREAM_AUTOFREE); BASS_ChannelSetAttribute(myPlay, BASS_ATTRIB_VOL, myVolume); BASS_ChannelPlay(myPlay, False) end; |
Ich brauche eine eigene Prozedur zum Abspielen der Sounds, es muss daher alles in einer Prozedur sein:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure TForm1.PlaySound(iResID: Integer); begin resourceID := iResID; mySong:= TResourceStream.CreateFromID(hInstance, ResourceID, 'SOUND'); GetMem(myMem, mySong.Size); mysong.Read(myMem^, mySong.Size);
myVolume:= 0.2; myPlay:= BASS_StreamCreateFile(True, myMem , 0, mySong.Size, BASS_STREAM_AUTOFREE); BASS_ChannelSetAttribute(myPlay, BASS_ATTRIB_VOL, myVolume); BASS_ChannelPlay(myPlay, False) end; |
Wenn ich alles in einer Prozedur habe, belegt GetMem doch immer mehr Speicher, oder? Ich meine, bei 20 - 30 Soundeffekten, die laufend abgespielt werden sollen, rufe ich doch sehr oft die Prozedur PlaySound auf, die jedesmal Speicher reserviert, den aber nicht mehr freigibt, oder sehe ich das falsch?
Ich meine, die Sounds sind ja schon im Speicher (wenn ich eine .res einbinde). Ich muss sie ja nur noch "holen" und abspielen!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
glotzer
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: Do 05.05.11 19:04
Lade die Datei genau EINMAL am Anfang in den Speicher und ruf sie dann nurnoch auf.
Vieleicht mit einer "array of pointer" oder nimm gleich "TList"
_________________ ja, ich schreibe grundsätzlich alles klein und meine rechtschreibfehler sind absicht
|
|
ALF
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Do 05.05.11 20:38
galagher hat folgendes geschrieben : | ...doch immer mehr Speicher, oder? Ich meine, bei 20 - 30 Soundeffekten, die laufend abgespielt werden sollen, rufe ich doch sehr oft die Prozedur PlaySound auf, die jedesmal Speicher reserviert, den aber nicht mehr freigibt, oder sehe ich das falsch?
! |
ne Du darfst die nur im Create laden ! der rest ist nur das Handle was darauf zeigt!!!
Kleiner Tip, hatt ich doch schon mal geschrieben
Du bist der, der weis wieviele Sounds Du verwendest
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: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
| Private mySong: Array[1..bisx] of TResourceStream; pChan: Array[1..bisx] of HStream; myVolume: Array[1..bix] of float; myMem: Array[1..bisx] of pointer For i:= 1 to bisx do begin mySong[i]:= TResourceStream.CreateFromID(hInstance, i, 'SOUND'); GetMem(myMem[i], mySong[i].Size); mySong[i].Read(myMem[i]^, mySong[i].Size); end;
myVolume[1]:= 0.2;myVolume[2]:= 0.7; .... ...
procedure Mplay(playid: integer); var setvolume: float; begin if volume <> myVolume[playid] then setvolume:= volume else setvolume:= myVolume[playid]; pChan[playid]:= BASS_StreamCreateFile(True, myMem[playid] , 0, mySong[playid].Size, BASS_STREAM_AUTOFREE); BASS_ChannelSetAttribute(pChan[playid], BASS_ATTRIB_VOL, setvolume); BASS_ChannelPlay(pChan[playid], False);
end; |
nun kannst Du aus jeder xbeliebigen Stelle deines Progs dies Proc aufrufen
Mplay(1, 0.2) währe ein Schuss
Mplay(2, 0.5) währe eine Klingel
oder auch
myplay(1, 0.02); Schuss sehr leise also weit entfernt
myplay(1, 0.5); Schuss relativ laut also sehr nah
wenn der Schuss lauter werden soll, weil der Gegener näher kommt
Warum ich die Arrays mit 1 anfangenlasse, ist begründet durch die Resource.
Die fängt nun mal mit 1 an und nicht mit 0! Somit merk ich es mir besser für alle Arrays
Edit:
Hier noch ne kleine spielerei wenn der Gegner von links kommt:
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: 26: 27:
| private myPan Array[1..bisx] of float;
Mplay(playid: integer; volume, pan: float);var ...... setpan: float; begin ..... ..... ..... if pan <> myPan[playid] then setpan:= pan else setpan:= myPan[playid]; ..... ..... BASS_ChannelSetAttribute(pChan[playid], BASS_ATTRIB_VOL, setvolume); BASS_ChannelSetAttribute(pChan[playid], BASS_ATTRIB_PAN, setpan); BASS_ChannelPlay(pChan[playid], False); end; |
Wenn Du das ganze noch schöner machen willst Suround(7.1), dann sollte das ganze in eine Klasse oder Objekt sein, der Du nur die xyz Werte vom Spieler und Gegner übergibst und die Soundid. Der Rest wird dann dort errechnet von wo nun der sound kommt. So als Zugabe deines vorhabens
Wenn es Dir aber so ausreicht, ist das oben ne gute Lösung.
Nachtrag:
Allerdings sind 20-30 Soundeffekte im Speicher nicht Notwendig!
Da solltest Du Fallunterschiede machen.
Szenische-Sounds und Event-Sounds.
Event-Sound brauchst Du nicht im Speicher vorhalten! Die werden geladen wenn sie gebraucht werden und danach wieder freigegeben!
Überdenke dies nochmal! 20-30 wavedateien können mehr als 1,5 GB speicher fressen!!!!(je nach grösse)
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
TAKTER
Hält's aus hier
Beiträge: 1
|
Verfasst: Fr 28.12.12 00:06
Hey,
man kann das Ganze auch noch kürzer gestalten...
Der Stream beinhaltet schon einen Zeiger und eine Size:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| var sh:HStream; sd:TResourceStream;
sd:=TResourceStream.Create(HInstance,'sound','mp3'); sr:=BASS_StreamCreateFile(True,sd.Memory,0, sd.Size,BASS_STREAM_AUTOFREE); |
Moderiert von Narses: Delphi-Tags hinzugefügt
|
|
FrEaKY
Beiträge: 235
D7
|
Verfasst: Fr 28.12.12 19:24
Ich finde es eine Frechheit, wie Micro$hit alle 2-3 Jährchen sein neustes fehlerhaftes Betriebssystem rausbringt. Wir sollen das als Endnutzer dann finanzieren, und als Entwickler uns auch noch jedes Mal neu anpassen. Abwärtskompatibilität ist nur eine Farce. Deswegen es dieses Unternehmen auch irgendwann nicht mehr geben. Die Monopolmacht kommt ja heute schon langsam ins Bröckeln.
Ich unterstütze das schon lange nicht mehr, benutze auch noch XP. Ihr könnt ruhig lachen, ist mir egal.
|
|
jaenicke
Beiträge: 19284
Erhaltene Danke: 1742
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 29.12.12 02:51
|
|
Gausi
Beiträge: 8538
Erhaltene Danke: 475
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Sa 29.12.12 10:07
FrEaKY hat folgendes geschrieben : | Abwärtskompatibilität ist nur eine Farce. Deswegen es dieses Unternehmen auch irgendwann nicht mehr geben. Die Monopolmacht kommt ja heute schon langsam ins Bröckeln. |
Sorry fürs OT, können wir ggf. auch in einem extra Topic weiterführen. Aber was Abwärtskompatibilität angeht, ist Windows spitze. Windows XP kam vor über 10 Jahren raus, und noch immer laufen fast alle Programme auch auf diesem System. Es mag an der einen oder anderen Stelle Einschränkungen oder kleinere Probleme geben (wenn z.B. ein Programm ins eigene Verzeichnis schreiben will und/oder Admin-Rechte voraussetzt), aber im Großen und Ganzen ist MS in der Hinsicht vorbildlich. Was auch ein guter Grund für die enorme Verbreitung sein dürfte.
Wenn du über Abwärtskompatibilität mecken willst, geh zu Apple. Da ist das wirklich ein Krampf. Aber Apple hat ja dafür so ein super benutzerfreundliches Interface. Da kann man sogar an allen Seitenrändern die Größe der Fenster verändern, nicht nur unten rechts. Oh, warte, verwechselt. Das war andersrum.
_________________ We are, we were and will not be.
|
|
galagher
Beiträge: 2522
Erhaltene Danke: 44
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Do 16.05.13 17:20
markus5766h hat folgendes geschrieben : |
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: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56:
| function GetMasterVolume(Mixer: hMixerObj): Word; var MasterVolume : TMixerControl; Details : TMixerControlDetails; UnsignedDetails : TMixerControlDetailsUnsigned; Code : MMResult; begin Result := 0;
Code := _VolumeControl(Mixer, MasterVolume); if Code = MMSYSERR_NOERROR then begin with Details do begin cbStruct := SizeOf(Details); dwControlID := MasterVolume.dwControlID; cChannels := 1; cMultipleItems := 0; cbDetails := SizeOf(UnsignedDetails); paDetails := @UnsignedDetails; end; Code := mixerGetControlDetails(Mixer, @Details, MIXER_GETCONTROLDETAILSF_VALUE);
Result := UnsignedDetails.dwValue; end; if Code <> MMSYSERR_NOERROR then raise Exception.CreateFmt('GetMasterVolume failure, '+ 'multimedia system error #%d', [Code]); end;
procedure SetMasterVolume(Mixer: hMixerObj; Value: Word); var MasterVolume : TMixerControl; Details : TMixerControlDetails; UnsignedDetails : TMixerControlDetailsUnsigned; Code : MMResult; begin Code := _VolumeControl(Mixer, MasterVolume); if Code = MMSYSERR_NOERROR then begin with Details do begin cbStruct := SizeOf(Details); dwControlID := MasterVolume.dwControlID; cChannels := 1; cMultipleItems := 0; cbDetails := SizeOf(UnsignedDetails); paDetails := @UnsignedDetails; end; UnsignedDetails.dwValue := Value; Code := mixerSetControlDetails(Mixer, @Details, MIXER_SETCONTROLDETAILSF_VALUE); end; if Code <> MMSYSERR_NOERROR then raise Exception.CreateFmt('SetMasterVolume failure, '+ 'multimedia system error #%d', [Code]); end; |
läuft auf XP
Vista - keine Ahnung, hab ich nie gehabt
Win7 - definitiv nein |
Hallo!
Ist jetzt zwar schon ein Weilchen her, aber jetzt habe ich deinen Code erfolgreich mit Windows 7 getestet. Sound lauter und leiser funktioniert wie gewünscht!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|