Entwickler-Ecke

Open Source Units - Klassenkapselung der Bass.Dll [v1.2]


glotzer - Di 17.05.11 20:38
Titel: Klassenkapselung der Bass.Dll [v1.2]
BassLib
Die Klasse kapselt die "bass.dll" und ihre Erweiterungen in mehreren Klassen. Sie ist der direkte Nachfahre von TBassSound allerdings in keinsterweise kompatible.

(veraltet)TBassSound
Die Klasse kapselt die "bass.dll" und ihre Erweiterungen in einer einfach zu nutzenden Klasse.
Ein größer Dank geht an Daniel Gaußmann für sein Tutorial hier [http://delphi-treff.de/tutorials/sonstiges/mein-einfacher-mp3-player/].

Unterstützung
getested wurde nur mit Delphi XE 2, es sollte aber ohne Probleme bis Delphi 7(ab version 0.4) oder Delphi 2009(ab 1.0, wegen Generics, das könnte man jedoch ändern, dann sollte es bis Delphi 7 laufen) funktionieren.
Mit Lazarus geht es (noch) nicht, eventuell fällt mir noch was kluges ein.

Bekannte Bugs:
*BassOptions.OutputBufferLength funktioniert nicht. Da weiß ich nochnicht woher der Bug kommt. Wenn wer ne Idee hat, immer her damit.

ToDo:
*Bugfixes
*unterstützung für *.mod musik
*kleine bugs verschwinden lassen die entstehen wenn man z.b. bei BassURLSound versucht vor/zurück zu springen


Zusätzlich benötigt:
bass.dll und Header-Unit (erhältlich hier [http://www.un4seen.com/bass.html])

Downloads:
Leider gibt es aufgrund einer Größenbeschränkung der Anhänge hier nur den Quelltext als Anhang, Binarys nur external gehostet.



Zitat:

Changelog

----17.05.2011 0.1
*Erste Version

----18.05.2011 0.2
*Dynamisches Laden der bass.dll ist jetzt möglich
*Bessere Funktion unter älteren Delphis

----20.08.2011 0.3
*Kleine Bugfixe
*Fehler in den Datumsangaben der Versionsgeschichte behoben
*Rückgabewert der funktion "InitBassPlugins" war fehlerhaft, jetzt gefixt
*Verbessete Lazaruskompatibilität
*CPU-Belastung durch Soundausgabe kann jetzt abgefragt werden

----26.08.2011 0.4
*Events "OnLoad", "OnPlay", "OnStop", "OnPause", "OnVolumeChange" hinzugefügt
*Kleine Fehlerbehebungen und Optimierungen
*Die Events "OnProgressChange", "OnEnd", "OnStatusChange" hinzugefügt, allerdings nur verfügbar wenn der Unit das Application.OnIdle event abfragen darf.

----18.09.2011 0.5
*Bug gefixt: "LoadFromStream" funktioniert jetzt
*Neue property: Loop (gibt an ob die datei wiederholt werden soll)
*Auslösen der Change events verbessert
*Fehler im Beispielprogramm behoben
*Fehler in LoadFromStream behoben

----20.09.2011 0.6
*OnEnd verbessert, es verwendet jetzt die BASS syncs dafür
*LoadFromResource hinzugefügt
*LoadFromMemory hinzugefügt
*LoadFromStream in LoadFromBufferdStream umbenannt
*LoadFromStream neu eingeführt, die procedure lädt jett nichtmehr die ganze Datei in den Speicher
*Fehler im Speichermanagment behoben der einen Bluescreen verursachen konnte
*Mehrere Fehler mit AnsiString/String behoben

----09.12.2011 1.0
*Komplette überarbeitung der Klasse
*Aufteilung auf mehrere Klassen
*Events benötigen kein Application.OnIdle mehr
*Events müssen jetzt Thread-save sein
*Beispielprogramm erweitert
*Die GUI des Beispielprogramm verbessert
*Manche Sachen, besonders das Device handeling ist noch buggy.
*Recording geht noch nicht

----05.3.2011 1.1
*Output devices funktionieren jetzt, channeln können jetzt zur Laufzeit andere Ausgänge verwenden.
*Beispielprojekt verbessert um alle neuen Features zu verwenden.
*Viele Compiler Warnungen behoben

----31.8.2011 1.2
*Sehr viele Fehler behoben
*Mit Recordingunterstützung angefangen
*DeviceManager überarbeited und jetzt voll funktionsfähig
*BassCallbackSound hinzugefügt


jaenicke - Mi 18.05.11 06:04

user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
Die Klasse kapselt die "bass.dll" und ihre erweiterungen in einer einfach zu nutzenden Klasse.
Ja, sie ist sehr klein und dadurch für Einsteiger leichter zu verstehen als die großen Wrapperklassen [http://www.torry.net/quicksearchd.php?String=bass&Title=Yes], die teilweise [http://www.delphipraxis.net/46916-%5Bkomponente%5D-bass-player-komponente-tbassdllplayer-demos.html] auch nicht mehr für neuere Delphiversionen funktionieren.

Delphi habe ich gerade nicht zur Hand, deshalb kann ich es gerade nicht ausprobieren, aber der Aufbau der Klasse sieht gut aus. :zustimm:

user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
getested wurde nur mit Delphi XE, es sollte aber ohne Probleme bis Delphi 3 funktionieren,
Nein, dort wird es nicht gehen. Bei Delphi 5 fallen mir zwei Sachen auf:

Delphi-Quelltext
1:
2:
  TBassSoundStatus = (BSS_STOPPED = 0, BSS_PLAYING = 1, BSS_STALLED = 2, BSS_PAUSED  = 3);
IncludeTrailingPathDelimiter
Werte für die Enumerationskonstanten vorzugeben, ging erst ab Delphi 6 oder 7.
Bei Delphi 5 gab es auch nur IncludeTrailingBackslash, da hat man noch nicht an andere Plattformen gedacht.
Mehr fällt mir da nicht auf, wenn man das ändert, sollte es kompilieren.

Bei Delphi 3 fehlen Int64, LongWord (ersetzbar durch DWORD, das gab es schon) sowie dynamische Arrays (CodingHistory) bereits in der bass.pas selbst. Zusätzlich gehen bei deinem Quelltext auch keine Standardwerte für Methodenparameter. Und IncludeTrailingBackslash gab es da noch gar nicht.

user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
prinzipiel sollte es auch mit Lazarus gehen.
Nein, denn implizite Pointer funktionieren so nicht und Rückgabewerte müssen auch bei der Implementierung der Methode angegeben werden. Wobei ich die fehlenden Rückgabewerte auch unter Delphi für extrem unsauber halte...
user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
function TBassSound.GetStatus;
begin

// ...
        for a := 0 to Info.formatc - 1 do
        begin
          // Filter erweitern
          Filter := Filter + Info.Formats[a].exts;
        end;
Die Pointer müssen bei Lazarus explizit geschrieben werden. Das mache ich im Übrigen auch bei Delphi so, damit man auch sieht, dass es welche sind:

Delphi-Quelltext
1:
2:
3:
4:
5:
        for a := 0 to Info^.formatc - 1 do
        begin
          // Filter erweitern
          Filter := Filter + Info^.Formats^[a].exts;
        end;
Dennoch lässt sich beides nachahmen, wenn man in den Delphimode schaltet, denn sollte es ohne Änderungen gehen. Aber ich würde es lieber richtig schreiben.

Die bass.pas geht aber schon aufgrund dieses Konstrukts nicht:

Delphi-Quelltext
1:
2:
3:
4:
const
  // special STREAMPROCs
  STREAMPROC_DUMMY : STREAMPROC = STREAMPROC(0);  // "dummy" stream
  STREAMPROC_PUSH  : STREAMPROC = STREAMPROC(-1); // push stream
Eine Funktionskonstante, die als Wert einen gecasteten Integerwert bekommt...

Das geht so gar nicht, auch nicht im Delphimodus. Da ich es gerade nicht testen kann, weiß ich nicht, ob es an der Stelle eine Alternative gibt.

Fazit:
Lazarus geht nur mit Änderungen an der bass.pas selbst, Delphi ab Version 5 mit kleinen Änderungen und ab Delphi 6 oder 7 ohne Änderungen.

Wie wäre es eigentlich, wenn du die dynamische Version der Bass-Unit unterstützt? Die liegt im Bass-Paket unter dynamic oder so und erlaubt die dynamische Einbindung der DLL, so dass man im Programm darauf reagieren kann, wenn diese nicht da ist, statt dass das Programm nicht startet.

Dafür fehlt im Grunde nur das Laden der DLL mit Load_BASSDLL und das Entladen mit Unload_BASSDLL, sowie die entsprechende Fehlerbehandlung. Und ich denke, dass das schon viele interessieren wird. :zwinker:


glotzer - Mi 18.05.11 16:38

Danke für das Feedback,
klingt alles sehr gut, werd mich später mal drann setzen und es alles einbauen :D


glotzer - Mi 18.05.11 19:07

Neue Version online, ich glaub ich hab alle Ideen von dir drinnen,
morgen bau ich dann noch die Tags ein, allerdings in einer abgeleiteten Klasse,
da ich die "Basisklasse" so klein wie möglich und aud fas wirklich nötigste reduzierrt lassen will.

Edit: fast, die pointer sind mir entgangen, das kommt in der nächsten Version.


ALF - So 22.05.11 00:40

Find ich auch sehr gut!
Nur ne Frage, oder Vorschlag.
In Deiner

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
class procedure TBassSound.InitBass{$IFDEF DYNAMIC_BASS_LOAD}(const DLLName:String = 'bass.dll'){$ENDIF};
begin
....
....
....
   if not BASS_Init(-14410000nilthen    
    .....
....
.... 
end;

Gibt es keine Auswahlmöglichkeit, falls man 2 Soundkarten hat oder wenn man mehrere LP, also 7.1 ansteuern will.
Gut kann man auch selber noch machen, währe doch aber ein Futures wert 8)

Gruss ALf


glotzer - So 22.05.11 01:10

danke für das feedback, die idee klingt gut,
bei zeiten werd ich mich drumm kümmern


herr-master - Di 31.05.11 18:19

Schau dir den anhang mal an das ist eine dynamische bass.pas wo die bass.dll nicht benötigt wird.
Leider nicht für delphi xe angepasst sollte aber schnell gemacht sein.


glotzer - Di 31.05.11 18:39

hmmmmm das sieht toll aus, hat nur leider ein paar Probleme:
das laden von Plugins ist damit nicht möglich,
bin mir nicht sicher ob es Probleme mit dem Copyright gibt.
aber ich werd mal schauen obs was wird.

Sorry das es mit den Updates so lange dauert, aber das real-life macht zurzeit viel Arbeit...


herr-master - Di 31.05.11 18:45

Das laden ist möglich nur muss man dan für fast jedes plugin eine dynamische pas erstellen was bei den ersten 5 - 8 plugins noch geht
bei bass_enc geht es leider nicht.
Da man erst die bass.dll vor allem anderen laden muss was die dllloader.pas leider nicht unterstützt.
Was ist mit bass_musicload willst du das noch einbauen?
Sonst sieht es sehr gut aus was du da erstellt hast.


glotzer - Di 31.05.11 19:11

Mir ist noch nicht ganz klar wofür man bass_musicload eigentlich braucht.
Falls ich das noch rausfinde werd ichs entscheiden :p


ALF - Di 31.05.11 19:19

user profile iconglotzer hat folgendes geschrieben Zum zitierten Posting springen:
Mir ist noch nicht ganz klar wofür man bass_musicload eigentlich braucht.
Falls ich das noch rausfinde werd ichs entscheiden :p


Look http://en.wikipedia.org/wiki/MOD_(file_format)

Gruss ALf


herr-master - Di 31.05.11 19:23

Hier BASS_MusicLoad Loads a MOD music file; MO3 / IT / XM / S3M / MTM / MOD / UMX formats.
Diese formate werden oft in keyg..... oder pat.... benutzt , ich schreibe die zweich sachen nicht aus da ich glaube das verstößt hier gegen die forum regeln.Man kann diese sachen auch z.b benutzen wenn man beim start der mainform einen sound hören will oder im about da diese tracker nicht sehr groß sind und nur max 2 min lang sind.
Hm leider scheint mich deine unit nicht zu mögen ich bekomme bei diesem code hier immer eine zugriffsverletzungs msg zu sehen.

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:
procedure TForm1.btnLoadClick(Sender: TObject);
begin
if dlgOpensong.Execute then
sound.LoadFromFile(dlgOpensong.FileName);

end;

procedure TForm1.btnPlayClick(Sender: TObject);
begin
sound.Play(False);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
sound.Create;
sound.InitBass();
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
sound.Free;
sound.DeInitBass;
end;

hier die meldung:
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 004B7865 in Modul 'test.exe'. Schreiben von Adresse 0000000C'. Prozess test.exe (3824)


glotzer - Di 31.05.11 19:26

Das klingt nicht so als ob es jemals irgendjemand brauchen würde :p
ich schau mal wieviel arbeit es wäre


herr-master - Do 23.06.11 18:44

Da musst du doch nicht viel anpassen wenn ich mir den source so anschaue.
Hier mal wie man es machen könnte:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TbassSound.MusicLoad(Path:Ansistring);
var
f:Pansichar;
begin
freeSound;
FFreeMemAfter := false;
f:=Pansichar(path);
handle:=BASS_MusicLoad(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE{$ENDIF},Nil);
if Handle = 0 then BassError(BASS_ErrorGetCode);
FSource:=BSSo_File;
end;


glotzer - Do 23.06.11 19:04

yep das sieht gut aus :D irgendwann hat ich mal vor das ganze weiter zu entwickeln, aber zurzeit bin ich mit was anderen beschäftigt, wrd wohl noch ein bischen dauern


glotzer - Do 23.06.11 19:40

gerade erst gesehen, sorry
user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:


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:
procedure TForm1.btnLoadClick(Sender: TObject);
begin
if dlgOpensong.Execute then
sound.LoadFromFile(dlgOpensong.FileName);

end;

procedure TForm1.btnPlayClick(Sender: TObject);
begin
sound.Play(False);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
sound.Create;
sound.InitBass();
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
sound.Free;
sound.DeInitBass;
end;

hier die meldung:
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EAccessViolation mit Meldung 'Zugriffsverletzung bei Adresse 004B7865 in Modul 'test.exe'. Schreiben von Adresse 0000000C'. Prozess test.exe (3824)



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm1.btnLoadClick(Sender: TObject);
begin
  if dlgOpensong.Execute then
  sound.LoadFromFile(dlgOpensong.FileName);
end;

procedure TForm1.btnPlayClick(Sender: TObject);
begin
  sound.Play(False);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  TBassSound.InitBass();
  sound := TBassSound.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  sound.Free;
  TBassSound.DeInitBass;
end;

ungetested, sollte aber gehen


herr-master - Do 23.06.11 21:53

Werde es gleich mal testen und das was ich hinzugefügt habe auch.Ich schaue mal ob ich sie für mich auch weiter entwickeln kann deine
klassenkapselung.
Weil wie gesagt ist recht gut aufgebaut und sehr leicht zu benutzen weitere sachen einzubauen sollte allso nicht so schwer sein.
Es geht allso so spielt die unit von glotzer(fastracker module ab)

Delphi-Quelltext
1:
sound.musicload(opendialog.filename);                    


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TbassSound.MusicLoad(Path:string);
var
f:Pchar;
begin
freeSound;
FFreeMemAfter := false;
f:=Pchar(path);
handle:=BASS_MusicLoad(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE{$ENDIF},0); //NIL ist hier falsch
if Handle = 0 then BassError(BASS_ErrorGetCode);
FSource:=BSSo_File;
end;

Und hier noch eine veränderung.

Delphi-Quelltext
1:
357  Filter := 'mp3;*.mp2;*.mp1;*.ogg;*.wav*;*.aif;*.it;*.xm;*.mod,*.s3m';                    

Und hier ein weiteres future von mir für diese unit:

Delphi-Quelltext
1:
2:
3:
4:
5:
//----Getcpu-------
function TbassSound.cpu:string;
begin
result:=FloatToStrF(BASS_GetCPU,ffFixed, 42) + '%';   //gibt an wie viel cpu verwendet wird.
end;


glotzer - Sa 27.08.11 01:32

sooo, nach langer Zeit gibt es mal ein Update:

Zitat:

----20.08.2011 0.3
*Kleine Bugfixe
*Fehler in den Datumsangaben der Versionsgeschichte behoben
*Rückgabewert der funktion "InitBassPlugins" war fehlerhaft, jetzt gefixt
*Verbessete Lazaruskompatibilität
*CPU-Belastung durch Soundausgabe kann jetzt abgefragt werden

----26.08.2011 0.4
*Events "OnLoad", "OnPlay", "OnStop", "OnPause", "OnVolumeChange" hinzugefügt
*Kleine Fehlerbehebungen und Optimierungen
*Die Events "OnProgressChange", "OnEnd", "OnStatusChange" hinzugefügt, allerdings nur verfügbar wenn der Unit das Application.OnIdle event abfragen darf.


Zusätzlich gibt es jetzt auch ein Beispielprogramm.

Hat noch wer Ideen/wünsche was in die Klasse nach reinsollte? Wäre üver Feedback dankbar.


herr-master - Sa 17.09.11 19:46

Hm deine änderungen haben die basssound.pas er ruiniert da sie jetzt nicht mal mehr die sounds lädt.
Das ligt an dem raiseplay <-- raise ist ein fehler in delphi allso raise excption da hin kommt man doch erst wenn irgend wo im code raise exception auftritt.
Oder muss ich erst {$define HookAppIdleEvent} in meine form schreiben das er was abspielt.
Selbst deine sound test demo spielt kein sound ab.
Ich benutze die neuste bass.pas(2.4.8.1).


glotzer - Sa 17.09.11 20:02

Das klingt irgendwie komisch. ich schau mir das in so einer stunde mal genau an. Hab grad keine Zeit.


herr-master - Sa 17.09.11 20:30

Und das hier stimmt nicht

Delphi-Quelltext
1:
Sound.LoadFromFile(Edit1.Text);                    

Da kommt bei mir couldn't open file soll man da etwa den namen eingeben selbst wenn ich den namen eingebe von der sound datei geht es nicht.Es sollte woll er so ausehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
type
OpenDialog1: TOpenDialog;
procedure TForm1.Button7Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  Sound.LoadFromFile(Edit1.Text);
end;

Und bei fromfilestream bekomme ich eine zugriffs verletzung bei adresse 00404EA8 in modul 'soundtest.exe'.Lesen von adresse 0574c080


glotzer - Sa 17.09.11 21:14

Also, hab mir das genze gerade nochmal angeschaut:



user profile iconherr-master hat folgendes geschrieben:
650449)
Das ligt an dem raiseplay <-- raise ist ein fehler in delphi allso raise excption da hin kommt man doch erst wenn irgend wo im code raise exception auftritt.

Das Raiseplay feuert nur eine eventuell bei "OnPlay" registriertes Event. Es hat NICHTS mit exceptions zu tun. Der Name ist vieleicht nicht ganz gelungen.

user profile iconherr-master hat folgendes geschrieben:
650449)
Oder muss ich erst {$define HookAppIdleEvent} in meine form schreiben das er was abspielt.
Selbst deine sound test demo spielt kein sound ab.

{$define HookAppIdleEvent} Ist nur für leute die nicht wollen das die Klasse sich in Application.OnIdle reinhängt. einfach alles lassen wie es ist


user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Und das hier stimmt nicht

Delphi-Quelltext
1:
Sound.LoadFromFile(Edit1.Text);                    

Da kommt bei mir couldn't open file soll man da etwa den namen eingeben selbst wenn ich den namen eingebe von der sound datei geht es nicht.Es sollte woll er so ausehen:

Das war der ursprüngliche Plan, ist wohl auch nicht ganz gelungen. Neue Version des Demoprogramms ist im ersten post (in max 5 min) Edit: ist da


user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Und bei fromfilestream bekomme ich eine zugriffs verletzung bei adresse 00404EA8 in modul 'soundtest.exe'.Lesen von adresse 0574c080

Ja das ist mir bekannt, nur hab ich es leider nicht hier reingeschrieben, das liegt daran das LoadFromStream noch nicht funktioniert. Das ändert sich mit 0.3


Wie genau startest du die Demo? nimmst du die .exe aus dem Archiev oder erstellst du sie aus dem code selbst? Welche Delphi version? welches Windows?

Alles in allem: danke für das feedback, es freut mich dass sich wer für meine Klasse interesiert :D

Moderiert von user profile iconNarses: Zitat repariert.


herr-master - Sa 17.09.11 22:30

Ich starte die exe nicht aus dem archiv ich erstelle sie mir selbst , und meine delphi version ist xe.
Windows benutze ich xp pro mit sp3.
Klar intressiere ich mich für die klasse hab versucht meine procedure für musicload(fasttracker) einzufügen dan sagt mir der compiler aber tbasssound hat keine classe musicload.


glotzer - So 18.09.11 20:54

könntest du bitte die beigelegte exe aus der neuen Version ausprobieren und mir sagen ob die auchn icht geht? Wär sehr hilfreich. Falls es nicht geht: kommen irgendwelche Fehlermeldungen?


glotzer - So 18.09.11 21:58

----18.09.2011 0.5
*Bug gefixt: "LoadFromStream" funktioniert jetzt
*Neue property: Loop (gibt an ob die datei wiederholt werden soll)
*Auslösen der Change events verbessert
*Fehler im Beispielprogramm behoben
*Fehler in LoadFromStream behoben


Neue version des Beispielprogramms und des Units im ersten post


herr-master - Mo 19.09.11 11:49

Ja es geht soweit die zeit wird jetzt auch richtig angezeigt nur bei fromfilestream bekomme ich immer noch eine zugriffsverletzung bei adresse 00404EA8 in Modul'Soundtest.exe'.Lesen von adresse BEFFFFFC.
Repeat geht auch einwandfrei ich kann nur sagen mach weiter so.
Wenn ich das hier einbaue bekomme ich bestimmt so an die 40 msg boxen mit zugriffsverletzungen zu sehen die popen alle nach einander auf.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TBassSound.MusikLoad(Path:string);
var
f:PChar;
begin
freeSound;
  FFreeMemAfter := false;
  f := PChar(Path);
  Handle := BASS_Musicload(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE {$ENDIF},0);
  if not Ready then BassError(BASS_ErrorGetCode);
  FSource := BSSo_File;
  RaiseLoad; 
  end;

Ich hab es mal im debugger gestartet und er breakt an dieser stelle

Delphi-Quelltext
1:
raise EBassError.Create('Couldn''t load '+DLLName);                    

Dabei lade ich die bass.dll nicht dynamic mit {$define DYNAMIC_BASS_LOAD}
Das ist der error den ich im debugger zu sehen bekomme.
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EBassError mit Meldung 'Couldn't load bass.dll'. Prozess SoundTest.exe (3340)
Und ja die bass.dll liegt im gleichen verzeichnis wie soundtest.exe.
Selbst wenn ich das hier mache

Delphi-Quelltext
1:
2:
3:
4:
5:
var
dll:string;
begin
dll:='..\bass.dll'//dafür hab ich doch das angeben das er sie findet.
OpenDialog1.Filter := TBassSound.InitBassPlugins(dll);

Startet er die exe nicht weil sie nicht im gleichen verzeichnis ist?


glotzer - Di 20.09.11 23:23

user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Ja es geht soweit die zeit wird jetzt auch richtig angezeigt nur bei fromfilestream bekomme ich immer noch eine zugriffsverletzung bei adresse 00404EA8 in Modul'Soundtest.exe'.Lesen von adresse BEFFFFFC.

Sollte mit der neuen Version gehen. (hoffe ich)

user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Repeat geht auch einwandfrei ich kann nur sagen mach weiter so.
Wenn ich das hier einbaue bekomme ich bestimmt so an die 40 msg boxen mit zugriffsverletzungen zu sehen die popen alle nach einander auf

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TBassSound.MusikLoad(Path:string);
var
f:PChar;
begin
freeSound;
  FFreeMemAfter := false;
  f := PChar(Path);
  Handle := BASS_Musicload(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE {$ENDIF},0);
  if not Ready then BassError(BASS_ErrorGetCode);
  FSource := BSSo_File;
  RaiseLoad; 
  end;

versuchs mal so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TBassSound.MusikLoad(Path:string);
var
f:PChar;
begin
  freeSound;
  f := PChar(Path);
  Handle := BASS_Musicload(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE {$ENDIF},0);
  if not Ready then BassError(BASS_ErrorGetCode);
  FSource := BSSo_File;
  RaiseLoad; 
end;

ich glaube allerdings das MusicLoad einfach nicht mit den anderen funktionen kompatible ist. Werde das später noch genauer testen.


user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Ich hab es mal im debugger gestartet und er breakt an dieser stelle

Delphi-Quelltext
1:
raise EBassError.Create('Couldn''t load '+DLLName);                    

Dabei lade ich die bass.dll nicht dynamic mit {$define DYNAMIC_BASS_LOAD}
Das ist der error den ich im debugger zu sehen bekomme.
Erste Gelegenheit für Exception bei $7C812AFB. Exception-Klasse EBassError mit Meldung 'Couldn't load bass.dll'. Prozess SoundTest.exe (3340)
Und ja die bass.dll liegt im gleichen verzeichnis wie soundtest.exe.
Selbst wenn ich das hier mache

Delphi-Quelltext
1:
2:
3:
4:
5:
var
dll:string;
begin
dll:='..\bass.dll'//dafür hab ich doch das angeben das er sie findet.
OpenDialog1.Filter := TBassSound.InitBassPlugins(dll);

Startet er die exe nicht weil sie nicht im gleichen verzeichnis ist?

hier lieg ein Fehler vor:
TBassSound.InitBassPlugins lädt nur die Plugins, NICHT die bass.dll selbst. Das passiert davor mit InitBass.
versuch mal das:

Delphi-Quelltext
1:
InitBass ('..\bass.dll');                    




Neue Version:


----20.09.2011 0.6
*OnEnd verbessert, es verwendet jetzt die BASS syncs dafür
*LoadFromResource hinzugefügt
*LoadFromMemory hinzugefügt
*LoadFromStream in LoadFromBufferdStream umbenannt
*LoadFromStream neu eingeführt, die procedure lädt jett nichtmehr die ganze Datei in den Speicher
*Fehler im Speichermanagment behoben der einen Bluescreen verursachen konnte
*Mehrere Fehler mit AnsiString/String behoben

Leider kann ich das Beispielprogramm nichtmehr anhängen, da es gepackt genau 2081kb hätte und das Forum nicht mehr als 2 mb erlaubt. Das liebt daran das jetzt eine funktion "LoadFromResource" dabei ist, und diese Sounddaten lassen die .exe leider auf 4 mb anwachsen. Der Code hängt weiterhin an, muss man sich halt selber erstellen.


herr-master - Mi 21.09.11 18:25

Das scheint wirklich nicht mit den anderen sachen kompatibel zu sein hier ein bug rebot.txt von madexcept erstellt dan weisst du auch wo der fehler liegt.
So sieht der code aus:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button10Click(Sender: TObject);
begin
sound.MusikLoad(Edit1.Text);
end;


Delphi-Quelltext
1:
BASS_ERROR_NOTAVAIL     : raise EBassError.Create('Requested data is not available!');//Und das ist der error                    

Die procedure hab ich so eingebaut wie du gepostet hast musst aber noch das hier anpassen damit er das format erkennt:

Delphi-Quelltext
1:
Filter := '*.mp3;*.mp2;*.mp1;*.ogg;*.oga;*.ogx;*.ogg;*.spx;*.wav*;*.aif;*.aiff;*.aifc,*.it;*.xm;*.mod,*.s3m';                    

Der spielt zwar die musik ab aber ich bekomme dauernt diese exception message :'Requested data is not available.'
Ich finde das from buffered den sound extrem leise abspielt oder ist das so gewollt?
Und könntest du bitte die rc datei mit hochladen oder posten wie der inhalt aussieht.


glotzer - Mi 21.09.11 18:38

user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Der spielt zwar die musik ab aber ich bekomme dauernt diese exception message :'Requested data is not available.'

Aus dem Bug report seh ich leider das das daher kommt wenn das Programm versucht Sound.Progress zu lesen, ich denke das es grundsätzlich nicht möglich ist das funktionierend zu machen, auf jedenfall nicht alle Attribute/Funktionen der Klasse. Dafür schreib ich wohl mal eine eigene Klasse.

user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Ich finde das from buffered den sound extrem leise abspielt oder ist das so gewollt?

hmmm an der Lautstärke wird da nichts geändert, die Soundfile wird nur in dem Speicher geladen. Werd dem mal nachgehen.


user profile iconherr-master hat folgendes geschrieben Zum zitierten Posting springen:
Und könntest du bitte die rc datei mit hochladen oder posten wie der inhalt aussieht.

In etwa 5 min lad ich mal alle Daten auf eine externe Seite, da es im Forum leider nicht möglich ist
Edit: ist im 1. Post


herr-master - Mi 21.09.11 20:07

Für die wo 4 warnungen bekommen hier die lösung:
1:{$M+}{$TYPEINFO ON} //das hinzufügen
2:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TBassSound.LoadFromResource (Instance: THandle; const ResName: string);
var
  stream: TStream;
begin
  try
    stream := TResourceStream.Create(Instance,ResName,RT_RCDATA);
    LoadFromBufferdStream(Stream);
    FSource := BSSo_Resource;
  finally
              //aber kommischer weise wenn es hier ist kommt W1036: Variable '%s' might not have been initialized
  end;
  Stream.Free //ja ich weiss das gehört da nicht hin
end;


glotzer - Mi 21.09.11 20:13

1 wird in der nächsten Version hinzugefügt, ich werde auch noch schauen ob ich es mit XE2 und 64bit win compatible bekomm.


glotzer - Fr 09.12.11 22:38

----09.12.2011 1.0
*Komplette überarbeitung der Klasse
*Aufteilung auf mehrere Klassen
*Events benötigen kein Application.OnIdle mehr
*Events müssen jetzt Thread-save sein
*Beispielprogramm erweitert
*Die GUI des Beispielprogramm verbessert
*Manche Sachen, besonders das Device handeling ist noch buggy.
*Recording geht noch nicht

neue Version im ersten posting.
Die neue Version ist in KEINSTER WEISE kompatible mit der alten.
noch funktionieren eine menge Sachen nicht, aber das kommt bald noch, ich wollte jetzt nur mal wieder ein Update posten.
Das Beispielprogramm ist auch noch nicht ganz fertig, es kannn zur Zeit NUR Musik aus Dateien, nich von urls/Streams/irgendetwas wiedergegeben werden. Die entsprechenden Buttons gibt es leider noch nicht.
Ein neues Beispielprogramm liegt auch bei.


herr-master - Mo 05.03.12 13:35

Da ist noch ein bug in der version 1.0 und zwar wenn man outputdevice einen eintrag über das feld mit drag&drop zieht steht da bass_init has not been successfull called.
Hier ein screenshot dazu:
user defined image


glotzer - Mo 05.03.12 18:25

schau ich mir gleich mal an, danke ;)

edit:

lokal schon gefixt, hab die neue Version nur noch nicht online. 1.1 wird wohl ziemlich bald kommen. Nur als Randnotiz: das war wohl einer der Sachen die bei der Version noch nicht gingen, lokal schon fertig waren und ich "irgend wann mal" raufladne wollte und das dann verpennt hab... sorry dafür aber ein großes Lob dass es jemanden aufgefallen ist. Ist ja schön wenn das ganze noch wen nützt/interesiert :D


herr-master - Mo 05.03.12 19:58

Ich schaue immer mal rein ob es schon eine neue version gibt du hast auch den {$m+} switch vergessen.
Das bekomme ich bei puplished zu sehen.
Bin ich mal gespannt was du so in die neue version eingebaut hast.
Das du noch andere projecte am laufen hast hindert dich bestimmt daran die meisten projecte up to date zu halten.
Aber das ist nicht schlimm so lange das dieses project nicht im www nichts untergeht.


glotzer - Mo 05.03.12 20:12

----05.3.2011 1.1
*Output devices funktionieren jetzt, channeln können jetzt zur Laufzeit andere Ausgänge verwenden.
*Beispielprojekt verbessert um alle neuen Features zu verwenden.
*Viele Compiler Warnungen behoben

neue Version im ersten Post, sorry das es so lang gedauert hat,
nur gewisse bb-code Spezialitäten von ineinander geschachtelten Listen haben mich ein bischen aufgehalten :p
seit neuesten gibt es jetzt auch eine ToDo List. Wenn es da Wünsche gibt, bitte melden.

edit: upload spinnt grad bisal, Beispiel kommt später


herr-master - Mo 05.03.12 20:50

Hier bin aber nicht sicher ob es so geht:
Bassfilesound.pas:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
type
  TBassFileSound = class(TBassSound)
    public
      procedure LoadFromFile(FilePath: String);
    procedure MusicLoad(FilePath:string);//neu
  end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
procedure TBassFileSound.MusicLoad(FilePath:string);
var
 f: PChar;//ich meine hier müsste man pansichar verwenden weil es ja fasttracker module sind.
begin
  FreeSound;
  f := PChar(FilePath);
  Handle := BASS_MusicLoad(False,f,0,0,0{$IFDEF UNICODE} or BASS_UNICODE{$ENDIF},Nil);
  if not Ready then BassError(BASS_ErrorGetCode);
  AfterLoaded;
  RaiseLoad;
end;

Könntest du das mal testen. Wo ist eigentlich der filter in der neuen version in welcher datei?


glotzer - Mo 05.03.12 21:36

Kurze Rückmeldung: der Hoster spinnt noch immer, ich werd mir da mal was neues suchen...

zu deinen Fragen:

PChar ist richtig, damit wird nur der Datenname üergeben, was das jetzt sind (ob Module, Äpfel oder sonst was) ist egal.
Auf Unicode wird mit {$IFDEF UNICODE} or BASS_UNICODE{$ENDIF} schon geachtet.

Wenn du mit "filter" die Liste mit den Datenendungen meinst, die sind jetzt hier:



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
type
  TBassDllManager = class
    private
      FOptions: TBassOptions;
      FDeviceManager: TBassDeviceManager;
      FFileExtensionFilter: String;
    protected
      function GetOptions: TBassOptions;
      function GetDeviceManager: TBassDeviceManager;
      function GetCpuUssage: float;
    public
      property CPUUssage: float read GetCpuUssage;
      property FileExtensionFilter: String read FFileExtensionFilter;
      property Options: TBassOptions read GetOptions;
      property DeviceManager: TBassDeviceManager read GetDeviceManager;
    public
      constructor Create(DllPath: String=''{use '' to look in the application dir});
      destructor Destroy; override;
  end;


Algemein zu "MusicLoad": Das hab ich schonmal probiert, aber leider geht es nicht ganz so einfach, da dort ein paar Sachen anders/nicht funktionieren. Besonders ein Fortschrittsbalken ist dabei nicht möglich, heißt wenn die entsprechenden Propertys abgefragt werden fleigt einfach eine exception. Eine entsprechende Klasse kommt aber noch, bin halt noch auf der Suche nach brauchbaren Testdaten.


Sinspin - Mo 05.03.12 22:48

Hi,

ich kenne MusicLoad nicht (bzw. die Bass.dll kaum) was meinst du mit Testdaten? Musikdateien in Moduleformaten? Es gibt eine ganze ordentliche Anzahl von Webseiten und Servern mit (das muss man ja Heutzutage mit dazuschreiben schreiben : Copyright freier) Musik. Meine Hauptquellen zur Versorgung mit neuer Musik sind http://ftp.Modland.com und Modarchive.org.


glotzer - Mo 05.03.12 23:29

Danke dafür, werd mir das in nächster Zeit mal anschauen


herr-master - Di 06.03.12 17:20

fortschitss balken scheint möglich zu sein schau dir mal xmplay an ist ein player für fasttracker module und da ist auch ein fortschitss balken sowie track infos dabei.Und so weit ich das sehe benutzt der auch nur die bass.dll.
Wie wäre es noch mit tacks für mp3/4 ,wav usw halt die meisten formate wo so geläufig sind.
Testdaten ich rippe mir meine fasttracker musik immer aus keygen's oder crackmes oder gehe auf diese seite:
http://keygenmusic.net/?page=team&teamname=again&lang=de
Da findest du von den bekanntsten cracker crews die musik aus ihren keygens/cracks.
Ich kann dir das ganse archiv von chiptunes.org geben wenn du willst(1644 dateien).
Ps:der download vom bsp 1.1 geht nicht richtig das archiv kann nicht gelesen werden.


glotzer - Mi 07.03.12 19:15

ups... da hat doch wer quote anstelle von edit gedrückt... bitte diesen post ignorieren


glotzer - Do 19.04.12 17:53

kurze Info: der Download der Binarys geht jetzt, da mir eine Bekannte netter Weise etwas Speicher auf ihrer Homepage zu Verfügung gestellt hat.
Ich arbeite gerade noch an der Wiedergabe der Musikdaten und der Aufnahme, dauert aber wohl noch ein bischen.


glotzer - Di 31.07.12 18:58

----31.8.2011 1.2
*Sehr viele Fehler behoben
*Mit Recordingunterstützung angefangen
*DeviceManager überarbeited und jetzt voll funktionsfähig
*BassCallbackSound hinzugefügt


Hoffe ich hab nicht zu viele Bugs eingebaut, wurde eigentlich ausgiebig getestet aber man weiß ja nie...