PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : HowTo: Wir bauen einen billigen MP3 Patch



Miroku
03.04.2006, 22:03
Hallo Leute,

der MP3 Patch von Ineluki ist schon sehr alt, aber wird immer noch sehr oft verwendet. Dennoch verrate ich euch heute wie ihr euren eigenen MP3 Patch schreibt!

----------
Was ihr benötigt:
RPG Maker 2k
Delphi 5 aufwärts
Dependency Walker (optional) (http://www.dependencywalker.com/)

----------
Wie alles begann (bei Ineluki ;] )

Ineluki hat herausgefunden, das Sound und Musikdateien über die Harmony.dll abgespielt werden.

Er wusste, das es sich um eine Einsprungs-DLL handelte. Das heißt, Funktionen dieser Bibiliothek können von jedem Programm benutzt werden.

Das funktioniert über das API (application programming interface). Das ist eine Programmiererschnittstelle.

Wie Programmierer die kernel32.dll oder auf andere DLLs über das API zugreifen können, so müsste der Zugriff logischerweiße auch auf die eine "Harmony.dll" funktionieren.

Damit ein Programmierer auf eine Funktion einer DLL zugreifen kann, wird der Funktionsname oder Einsprungs-Punkt benötigt, sowie alle Parameter die übergeben werden, wie Text oder Zahlen.

Ineluki war aber so schlau und suchte im Internet einfach nach den Funktionsparametern. Und tatsächlich er hatte alle gefunden! Auf einer ausländischen Seite die es heute leider nicht mehr gibt.

Danach war das Problem das Ineluki alle Funktion ja nachschreiben müsste! Viel zuviel Arbeit war das, dass wusste er genau, darum hat er folgenden Geniestreich angewandt:

Er nannte die originale Harmony.dll einfach oldHarmony.dll und hat jede Funktion einfach standardmäßig auf die Funktionen der "oldHarmony.dll" weitergeleitet.

Somit konnte er leicht abfangen, ob es sich um eine MP3 Datei hält, und konnte diese dann abspielen.

----------

Das war im ungefähren die Geschichte von Ineluki. Um ein billigen MP3 Patch zu schreiben benötigt man nicht mal eine Stunde ;) ihr braucht allerdings ein wenig Programmiererfahrung, wobei ich in Delphi auch keinen Schimmer vom Syntax habe XD.

1. Dependency Walker (Optionaler Schritt)
Damit wir an die Funktionen kommen, die in der "Harmony.dll" vorhanden sind, benötigen wir den Dependency Walker. Öffnet damit die DLL einfach und ihr bekommt alle Funktionen sofort im Überblick:

http://www.xpzone.de/temp/dw.jpg

Selektiert alle mit Strg+A und dann kopiert sie mit Strg+C.

2. Delphi
- Delphi kaufen und starten.
- Geht im Menü unter: "File - New - Other"
- Im neuen Fenster auf "DLL Wizard" klicken

Jetzt nur noch das Projekt mit einen beliebigen Namen abspeichern.
Ok da Ineluki ja die Harmony.dll in oldHarmony.dll getauft haben, nennen wir mal die original DLL in sound.dll um.

Also erstellt schnell mit den RPG Maker ein neues Game, setzt die StartPosition auf irgendeiner begehbaren Fläche, speichert dieses und setzt die Original "Harmony.dll" mit unseren neuen Namen "sound.dll" ins Game Directory.

Ok zurück zu Delphi. Ihr habt nun folgenden Code (ohne Kommentare)



library Project2;

uses
SysUtils,
Classes;

{$R *.res}

begin
end.


So gut hab ich mir Gedacht. Bei "uses" werden anscheinend die Bibliotheken miteingebunden. Ok also binden wir doch mal ein paar mehr ein:



Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, mmsystem, Dialogs;


Naja wer mehr Bibliotheken braucht kann die gerne Einbinden, habe da leider zu wenig Erfahrung.

Auf jeden Fall ist "mmsystem" die Bibliothek, die "mcisendstring" zur Verfügung stellt, diese hilft uns MP3s abzuspielen :)

Jetzt müssen wir in Delphi angeben welche Funktion (wenns fertig ist) als Einsprungsfunktion zur Verfügung gestellt werden soll.

Sprich:



library Project2;

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, mmsystem, Dialogs;

{$R *.res}


exports
HarmonyGetMidiTick,
HarmonyCancelSound,
HarmonyReserveSound,
HarmonyCacheSound,
HarmonyStopSound,
HarmonyPlaySoundEx,
HarmonyPlaySound,
HarmonyGetMusicLooping,
HarmonyGetMusicPlaying,
HarmonyStopMusic,
HarmonyPlayMusic,
HarmonySetMusicPanpot,
HarmonySetMusicSpeed,
HarmonySetMusicVolume,
HarmonyFadeOutMusic,
HarmonyFadeInMusic,
HarmonyCheckValidWave,
HarmonyCheckValidMidi,
HarmonyTermWave,
HarmonyTermMidi,
HarmonyInitWave,
HarmonyInitMidi,
HarmonyRelease,
HarmonyCreate,
HarmonyGetVersion;
begin
end.


Erinnert ihr euch noch das wir diese Liste mit dem Dependency Walker kopiert haben? Dann einfach nur noch mit STRG+V einfügen, echt ein Kinderspiel :)

So jetzt nur noch die Funktionen schreiben :), wie man die Parameter herausfindet bleibt aber nicht geheim. Ich habe die Funktionen so oft mit neuen Parameter bestückt, bis VB (ja in VB gemacht xD) keine Fehler mehr ausgab.

Sprich:



library Project2;

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, mmsystem, Dialogs;

{$R *.res}

function HarmonyGetVersion(): Integer; stdcall;
begin
HarmonyGetVersion := False;
end;

function HarmonyCreate(): Boolean; stdcall;
begin
HarmonyCreate := HCreate;
end;

function HarmonyRelease(): Boolean; stdcall;
begin
HarmonyRelease := HRelease;
end;

function HarmonyInitMidi(): Boolean; stdcall;
begin
HarmonyInitMidi := HInitMidi;
end;

function HarmonyInitWave(): Boolean; stdcall;
begin
HarmonyInitWave:= HInitWave;
end;

function HarmonyTermMidi(): Boolean; stdcall;
begin
HarmonyTermMidi:= False;
end;

function HarmonyTermWave(): Boolean; stdcall;
begin
HarmonyTermWave := False;
end;

function HarmonyCheckValidMidi(): Boolean; stdcall;
begin
HarmonyCheckValidMidi := False;
end;

function HarmonyCheckValidWave(): Boolean; stdcall;
begin
HarmonyCheckValidWave := False;
end;

function HarmonyFadeInMusic(Sekunden: Integer): Boolean; stdcall;
begin
HarmonyFadeInMusic := False;
end;

function HarmonyFadeOutMusic(Sekunden: Integer): Boolean; stdcall;
begin
HarmonyFadeOutMusic := False;
end;

function HarmonySetMusicVolume(Volumne: Integer): Boolean; stdcall;
begin
HarmonySetMusicVolume := False;
end;

function HarmonySetMusicSpeed(Speed: Integer): Boolean; stdcall;
begin
HarmonySetMusicSpeed := False;
end;

function HarmonySetMusicPanpot(Panpot: Integer): Boolean; stdcall;
begin
HarmonySetMusicPanpot := False;
end;

function HarmonyPlayMusic(Musik: PChar): Boolean; stdcall;
HarmonyPlayMusic := False;
end;

function HarmonyStopMusic(): Boolean; stdcall;
begin
HarmonyStopMusic := False;
end;

function HarmonyGetMusicPlaying(): Boolean; stdcall;
begin
HarmonyGetMusicPlaying:= False;
end;

function HarmonyGetMusicLooping(): Boolean; stdcall;
begin
HarmonyGetMusicLooping := False;
end;

function HarmonyPlaySound(Sound: Pchar): Boolean; stdcall;
begin
HarmonyPlaySound := False;
end;

function HarmonyPlaySoundEx(Sound: PChar; s1,s2,s3 : integer): Boolean; stdcall;
begin
HarmonyPlaySoundEx := False;
end;

function HarmonyStopSound(): Boolean; stdcall;
begin
HarmonyStopSound := False;
end;

function HarmonyCacheSound(Value :String): Boolean; stdcall;
begin
HarmonyCacheSound:= False;
end;

function HarmonyReserveSound(Value :Pchar): Boolean; stdcall;
begin
HarmonyReserveSound:= False;
end;

function HarmonyCancelSound(Value :Integer): Boolean; stdcall;
begin
HarmonyCancelSound:= False;
end;

function HarmonyGetMidiTick(): Integer; stdcall;
begin
HarmonyGetMidiTick := 0;
end;

exports
HarmonyGetMidiTick,
HarmonyCancelSound,
HarmonyReserveSound,
HarmonyCacheSound,
HarmonyStopSound,
HarmonyPlaySoundEx,
HarmonyPlaySound,
HarmonyGetMusicLooping,
HarmonyGetMusicPlaying,
HarmonyStopMusic,
HarmonyPlayMusic,
HarmonySetMusicPanpot,
HarmonySetMusicSpeed,
HarmonySetMusicVolume,
HarmonyFadeOutMusic,
HarmonyFadeInMusic,
HarmonyCheckValidWave,
HarmonyCheckValidMidi,
HarmonyTermWave,
HarmonyTermMidi,
HarmonyInitWave,
HarmonyInitMidi,
HarmonyRelease,
HarmonyCreate,
HarmonyGetVersion;
begin

end.


Und eigentlich fertig :)
Ihr hättet auch die Parameter herausfinden können, in dem ihr einfach immer rumrätselt, das Projekt kompiliert und die DLL mit den Game ausführt. Die Fehler würden euch dann die Richtung weisen XD

Ok also STRG+F9 drücken um das Projekt zu kompilieren oder einfach im Menü -> Projekt -> Compile Projekt

Danach geht ihr auf Projekt -> Build Projekt
Im Ordner, wo ihr die Projektdateien sind, ist jetzt eine kleine DLL namens Project2.dll. Diese haut ihr einfach in den vorhin erstellten Game-Ordner und nennt sie natürlich "Harmony.dll"

Es müsste jetzt alles fehlerfrei laufen.
Halt fehlt da noch was? Ja XD die ganzen Funktionen machen ja noch gar nichts außer einen wahren Wert zu übermitteln.

Gut wir machens wie Ineluki und benutzen unsere "sound.dll".
Jetzt müssen wir aber noch die Funktionen dieser DLL explizit deklarieren in Delphi. Das geht wie folgt:



function HGetVersion(): Integer; stdcall; external 'sound.dll' name 'HarmonyGetVersion';
function HCreate(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCreate';
function HRelease(): Boolean; stdcall; external 'sound.dll' name 'HarmonyRelease';
function HInitMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyInitMidi';
function HInitWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyInitWave';
function HTermMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyTermMidi';
function HTermWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyTermWave';
function HCheckValidMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCheckValidMidi';
function HCheckValidWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCheckValidWave';
function HFadeInMusic(Sekunden: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyFadeInMusic';
function HFadeOutMusic(Sekunden: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyFadeOutMusic';
function HSetMusicVolume(Volumne: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicVolume';
function HSetMusicSpeed(Speed: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicSpeed';
function HSetMusicPanpot(Panpot: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicPanpot';
function HPlayMusic(Musik: string): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlayMusic';
function HStopMusic(): Boolean; stdcall; external 'sound.dll' name 'HarmonyStopMusic';
function HGetMusicPlaying(): Boolean; stdcall; external 'sound.dll' name 'HarmonyGetMusicPlaying';
function HGetMusicLooping(): Boolean; stdcall; external 'sound.dll' name 'HarmonyGetMusicLooping';
function HPlaySound(Sound: string): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlaySound';
function HPlaySoundEx(Sound: string; s1,s2,s3 : integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlaySoundEx';
function HStopSound(): Boolean; stdcall; external 'sound.dll' name 'HarmonyStopSound';
function HCacheSound(Value:String): Boolean; stdcall; external 'sound.dll' name 'HarmonyCacheSound';
function HReserveSound(Value:String): Boolean; stdcall; external 'sound.dll' name 'HarmonyReserveSound';
function HCancelSound(Value:Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyCancelSound';


Kleiner Tipp am Rande: Ihr könnt die Funktion auch voll ausschreiben, dann müsst ihr nicht doppelte Funktionen machen!

Im KlarText wir müssen ja nur das Abfangen wo wir brauchen, aber egal, in diesen Tutorial wollen wir ja mal auf alles zugreifen können.

Ok jetzt müssen wir unsere Funktionen alle umschreiben, damit diese die weitergeleiteten Funktionen aufrufen.

Das geht so:



function HarmonyGetVersion(): Integer; stdcall;
begin
HarmonyGetVersion := HGetVersion;
end;


Nachdem ihr fertig seid, könnt ihr das ganze Projekt noch mal neu erstellen und ausprobieren. Ihr wird sehen das jetzt wieder Sounds Musik usw. funktionieren ;)

3. Wie manipuliere ich was?
Ganz einfach, übergibt im Rückgabewert was ihr wollt. Z.B:



function HarmonyGetMidiTick(): Integer; stdcall;
begin
HarmonyGetMidiTick := 365;
end;


Und jetzt fragt doch mal den Midi-Tick Count ab ;) geil!
Jeah und jetzt ist es noch einfach einen MP3 Patch daraus zu machen.

Geht in den Musik Ordner und erstellt zwei Dateien:
test.wav (leere 0 bytes datei)
test.mp3 (originale mp3)

Die test.wav ist nur dazu da, damit wir überhaupt den Sound auswählen können. Ihr fragt euch sicherlich, wieso wir nicht einfach die MP3 in .wav umbenennen und abspielen?! Begründung: Die Funktion die ich zum abspielen hernehme "MciSendString" will eine richtige Dateiendung.

Ok nun erstellt im Projekt ein Event wo die Test.wav Musik ausgeführt wird, und eins das die Musik wieder stoppt (ich glaube da brauch ich nicht näher ins Detail)

So und jetzt quick und dirty unser MP3 Patch:

4. Der MP3 Patch

Erstmal brauchen wir eine globale Variable, in der wir den aktuellen Pfad der MP3 Datei zwischenspeichern:



var
sfile: PChar;


Und dann ändern wir logischerweise unsere Funktionen
- function HarmonyPlayMusic(Musik: PChar): Boolean; stdcall;
und
- function HarmonyStopMusic(): Boolean; stdcall;

Also einmal um Abzuspielen und einmal zum Stoppen.

Bei Play nehmen wir diesen Code:



function HarmonyPlayMusic(Musik: PChar): Boolean; stdcall;
var i : Integer;
begin
i := Length(Musik)-3;
sfile := PChar(Copy(Musik, 1, i));
sfile := PChar(sfile + 'mp3');
mcisendstring(pchar('play ' + sfile), nil, 0, 0);
HarmonyPlayMusic := TRUE;
//HarmonyPlayMusic := HPlayMusic(Musik);
end;


Ok ziemlich einfach gehalten. Wir bekommen den Pfad der wav Datei aus der Variable Musik. Da schneiden wir mit der Copy Funktion die 3 letzten Buchstaben ab und ersetzen diese mit "mp3". Danach rufen wir die mcisendstrin Funktion auf und tata :)

Ihr seht schon, es wird nicht überprüft ob es sich um eine "wav" Datei handelt, also wäre ne Abfrage noch sinnvoll XD und dann eben auf HPlayMusic weiterleiten.

Und um das ganze zu stoppen:



function HarmonyStopMusic(): Boolean; stdcall;
begin
mcisendstring(pchar('stop ' + sfile), nil, 0, 0);
HarmonyStopMusic := TRUE
//HarmonyStopMusic := HStopMusic;
end;


Einfach wieder die Funktion mcisendstring genommen. Ihr seht schon, hier ist auch keine Abfrage für wav Dateien XD also only MP3 Patch.

Nachdem ihr das Programmiert habt kompiliert die DLL und rebuildet sie. Dann wieder in unsern Game Ordner schmeißen und typischerweise wieder in "Harmony.dll" umbenennen.

Dann das Game starten und freuen ;) jeah und Bingo es kommt lalalie lalala ^^ und das ist ja mal ein geringer Aufwand.
Allerdings müsst ihr noch eine Unterscheidung einbauen, ob es sich doch um eine wav Datei handelt, könnt ja das Problem mit Inelukis Trick ".mp3.wav" beheben. Dafür hatte ich heute kein Bock mehr.

Ok hier noch mal der komplette Code:



library Project2;

uses
Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, mmsystem, Dialogs;

{$R *.res}

var
sfile: PChar;

function HGetVersion(): Integer; stdcall; external 'sound.dll' name 'HarmonyGetVersion';
function HCreate(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCreate';
function HRelease(): Boolean; stdcall; external 'sound.dll' name 'HarmonyRelease';
function HInitMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyInitMidi';
function HInitWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyInitWave';
function HTermMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyTermMidi';
function HTermWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyTermWave';
function HCheckValidMidi(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCheckValidMidi';
function HCheckValidWave(): Boolean; stdcall; external 'sound.dll' name 'HarmonyCheckValidWave';
function HFadeInMusic(Sekunden: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyFadeInMusic';
function HFadeOutMusic(Sekunden: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyFadeOutMusic';
function HSetMusicVolume(Volumne: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicVolume';
function HSetMusicSpeed(Speed: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicSpeed';
function HSetMusicPanpot(Panpot: Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonySetMusicPanpot';
function HPlayMusic(Musik: string): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlayMusic';
function HStopMusic(): Boolean; stdcall; external 'sound.dll' name 'HarmonyStopMusic';
function HGetMusicPlaying(): Boolean; stdcall; external 'sound.dll' name 'HarmonyGetMusicPlaying';
function HGetMusicLooping(): Boolean; stdcall; external 'sound.dll' name 'HarmonyGetMusicLooping';
function HPlaySound(Sound: string): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlaySound';
function HPlaySoundEx(Sound: string; s1,s2,s3 : integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyPlaySoundEx';
function HStopSound(): Boolean; stdcall; external 'sound.dll' name 'HarmonyStopSound';
function HCacheSound(Value:String): Boolean; stdcall; external 'sound.dll' name 'HarmonyCacheSound';
function HReserveSound(Value:String): Boolean; stdcall; external 'sound.dll' name 'HarmonyReserveSound';
function HCancelSound(Value:Integer): Boolean; stdcall; external 'sound.dll' name 'HarmonyCancelSound';


function HarmonyGetVersion(): Integer; stdcall;
begin
HarmonyGetVersion := HGetVersion;
end;

function HarmonyCreate(): Boolean; stdcall;
begin
HarmonyCreate := HCreate;
end;

function HarmonyRelease(): Boolean; stdcall;
begin
HarmonyRelease := HRelease;
end;

function HarmonyInitMidi(): Boolean; stdcall;
begin
HarmonyInitMidi := HInitMidi;
end;

function HarmonyInitWave(): Boolean; stdcall;
begin
HarmonyInitWave:= HInitWave;
end;

function HarmonyTermMidi(): Boolean; stdcall;
begin
HarmonyTermMidi:= HTermMidi;
end;

function HarmonyTermWave(): Boolean; stdcall;
begin
HarmonyTermWave := HTermWave;
end;

function HarmonyCheckValidMidi(): Boolean; stdcall;
begin
HarmonyCheckValidMidi := HCheckValidMidi;
end;

function HarmonyCheckValidWave(): Boolean; stdcall;
begin
HarmonyCheckValidWave := HCheckValidWave;
end;

function HarmonyFadeInMusic(Sekunden: Integer): Boolean; stdcall;
begin
HarmonyFadeInMusic := HFadeInMusic(Sekunden);
end;

function HarmonyFadeOutMusic(Sekunden: Integer): Boolean; stdcall;
begin
HarmonyFadeOutMusic := HFadeOutMusic(Sekunden);
end;

function HarmonySetMusicVolume(Volumne: Integer): Boolean; stdcall;
begin
HarmonySetMusicVolume := HSetMusicVolume(Volumne);
end;

function HarmonySetMusicSpeed(Speed: Integer): Boolean; stdcall;
begin
HarmonySetMusicSpeed := HSetMusicSpeed(Speed);
end;

function HarmonySetMusicPanpot(Panpot: Integer): Boolean; stdcall;
begin
HarmonySetMusicPanpot := HSetMusicPanpot(Panpot);
end;

function HarmonyPlayMusic(Musik: PChar): Boolean; stdcall;
var i : Integer;
begin
i := Length(Musik)-3;
sfile := PChar(Copy(Musik, 1, i));
sfile := PChar(sfile + 'mp3');
mcisendstring(pchar('play ' + sfile), nil, 0, 0);
HarmonyPlayMusic := TRUE;
//HarmonyPlayMusic := HPlayMusic(Musik);
end;

function HarmonyStopMusic(): Boolean; stdcall;
begin
mcisendstring(pchar('stop ' + sfile), nil, 0, 0);
HarmonyStopMusic := TRUE
//HarmonyStopMusic := HStopMusic;
end;

function HarmonyGetMusicPlaying(): Boolean; stdcall;
begin
HarmonyGetMusicPlaying:= HGetMusicPlaying;
end;

function HarmonyGetMusicLooping(): Boolean; stdcall;
begin
HarmonyGetMusicLooping := HGetMusicLooping;
end;

function HarmonyPlaySound(Sound: Pchar): Boolean; stdcall;
begin
HarmonyPlaySound := HPlaySound(Sound);
end;

function HarmonyPlaySoundEx(Sound: PChar; s1,s2,s3 : integer): Boolean; stdcall;
begin
HarmonyPlaySoundEx := HPlaySoundEx(Sound,s1,s2,s3);
end;

function HarmonyStopSound(): Boolean; stdcall;
begin
HarmonyStopSound := HStopSound;
end;

function HarmonyCacheSound(Value :String): Boolean; stdcall;
begin
HarmonyCacheSound:= HCacheSound(Value);
end;

function HarmonyReserveSound(Value :Pchar): Boolean; stdcall;
begin
HarmonyReserveSound:= HReserveSound(Value);
end;

function HarmonyCancelSound(Value :Integer): Boolean; stdcall;
begin
HarmonyCancelSound:= HCancelSound(Value);
end;

function HarmonyGetMidiTick(): Integer; stdcall;
begin
HarmonyGetMidiTick := 365;
end;

exports
HarmonyGetMidiTick,
HarmonyCancelSound,
HarmonyReserveSound,
HarmonyCacheSound,
HarmonyStopSound,
HarmonyPlaySoundEx,
HarmonyPlaySound,
HarmonyGetMusicLooping,
HarmonyGetMusicPlaying,
HarmonyStopMusic,
HarmonyPlayMusic,
HarmonySetMusicPanpot,
HarmonySetMusicSpeed,
HarmonySetMusicVolume,
HarmonyFadeOutMusic,
HarmonyFadeInMusic,
HarmonyCheckValidWave,
HarmonyCheckValidMidi,
HarmonyTermWave,
HarmonyTermMidi,
HarmonyInitWave,
HarmonyInitMidi,
HarmonyRelease,
HarmonyCreate,
HarmonyGetVersion;
begin

end.


Vielen Dank fürs Lesen. Seit nicht sauer wenn die Anleitung ein wenig flüchtig geschrieben ist. Ich werde sie am Wochenende vielleicht noch überarbeiten. Besorgt euch besser die Programme :)
Vielleicht stelle ich noch eine paar Demo-Dateien zur Verfügung.

Die Rechtschreibfehler dürt ihr wie immer behalten, habe nicht kontrolliert und hab auch kein Word atm installiert.

Und denkt daran dieses Tutorial ist Copyright by Miroku :) und ich sehs schon kommen wie tausend neue MP3 Patches entstehen.

Aber ich glaube wir sind Ineluki immer noch treu (hey leute der rpg maker 2k is scho veraltet ( aba immer noch geil *g*)).

Gruß Miroku

EDIT:

Hier noch eine kleine Bildergallery:
Zur Bilder Gallery (http://www.xpzone.de/temp/Pictures/)

YoshiGreen
03.04.2006, 22:14
Hmmm... die Anleitung an sich bewerte ich einfach mal nicht, da ich mich mit dem nerdigen Stuff nicht auskenne.
Aber ich frage mich gerade mich, was ein neuer Patch bringen soll. Also welches umwerfenden neuen Features bringt es uns, dieses Ding selber zu schreiben und wird es trotzdem noch so bedienfreundlich sein?

Wenn nicht ist das Thread trotz allem vielleicht im Programmierforum ganz gut aufgehoben, weil ich mal behaupte, dass sowas für Maker (die mehr Skripter als Progger sind) zu komplex ist.

Dingsi
03.04.2006, 22:20
Wusste ich eigentlich alles schon. Hab das komplette Interface der Harmony.dll hier liegen und wüsste auch wie ich selbst dran komme. ^^ Jaja, Protz, Protz, ich weiß.
Aber dieser Dependecy Walker, den kannte ich noch nicht. Der ist cool. Nicht ganz so cool, wie ich dachte, aber cool. Ich hab nämlich anfangs gedacht, dass der auch Parameter rausfindet, bis ich dann gelesen hab, dass du die auch nur gebruteforced hast. Schade. :/
Aber trotzdem danke für das nette Programm.

Miroku
03.04.2006, 22:22
Ich möchte mein Wissen nur teilen ;)
Ja vielleicht sinnvoller im Programmiererforum aber ich bin immer so Community - berufen xD

derBenny
03.04.2006, 22:25
Wow! o_O"
Du erinnerst mich an den maskierten Magier, der die ganzen Tricks von David Copperfield und Co. verraten hat. Pass bloß auf, dass du nicht von Ineluki gelyncht wirst. ^^

Nein, im Ernst, danke für die Erklärung. Ich habe sie zwar nur überflogen, bin aber sicher, dass viele Leute das gut gebrauchen können, denn wenn man erstmal den Trick raus hat, kann man damit sicher noch mehr machen als nur Mp3-Patches.

YoshiGreen
03.04.2006, 22:34
denn wenn man erstmal den Trick raus hat, kann man damit sicher noch mehr machen als nur Mp3-Patches.
Hast natürlich recht, daran hab ich nicht gedacht ;)


aber ich bin immer so Community - berufen xD
Sehr gut Soldat! Weitermachen! ;)

Skydea
03.04.2006, 22:40
Delphi <3.
Lernen wir grade in der Schule...
Ergo ich kann was mit dem Zeugs anfangen :D"...

Ich verschwinde mal,...
Schaue es mir in den nächsten Tagen genauer an und kuck mal was man da noch alles manipulieren kann *lach...ganz arg krank lach* : [)


Sky

Ineluki
03.04.2006, 23:01
Och ich lynche ihn schon nicht ...
Ich habe ja oft genug bereits geschrieben, wie ich meinen Patch gemacht habe ...
Eigentlich brauchst du auch den Dependency Walker nicht, die Funktionsnamen bekommst du auch mit einem standardprogramm von Windows, der Schnellansicht.

Allerdings wird man mit dem Patch von dir frueher oder Spaeter arge Probleme bekommen. Das ging mir auch am anfang so, denn bei einigen hats funktioniert, und bei anderen schwere Ausnahmefehler verursacht. Da braucht es schon noch ein paar Tricks dazu.

Einer der wichtigsten Tricks dabei: KEIN String als Parameter verwenden, sondern IMMER PChar.

Zudem kannst du mit der Version des MCI STrings, die du angegeben hast, die Abspielgeschwindigkeit und Lautstaerke sowie die Balance der MP3 nicht veraendern. Um das zu bewerkstelligen, braucht es schon etwas mehr ...

Und dann wird es auch noch probleme zwischen Windows mit 9x Kernel geben und Windows mit NT Kernel, da die beiden unterschiedliche Treiber fuers MCI Subsystem fuer MP3s benutzen muessen ...

Na ja .. halt viele kleinigkeiten, die man erst einmal rausfinden muss. Alles in Allem schoene Arbeit. Allerdings habe ich gerade die Parameter und Deklarationen nie oeffentlich gemacht, um eine unauthorisierte Patchwelle zu verhindern. Was wird wohl passieren, wenn jeder seinen eignen (fehlerbehafteten) Patch schreibt, die alle zueinander noch inkompatibel sind ? Und um genau das zu vermeiden, hab ich die Codes nie im Internet veroeffentlicht ...

Na ja .. wir werden sehen, was wird ...
Wenns Hart auf Hart kommt, fuehren wir halt ein QualitaetsZertifikat "Luki Inside" ein ^__-

Miroku
03.04.2006, 23:15
Danke Ineluki für die Insider Informationen.
Naja Patch-Welle glaube ich weniger, da das Thema MP3 Patch und TastenPatch ja schon mehr als abgegraben ist und dir der volle Ruhm gebührt!

Dieses "Wissen" will ich hiermit nur weitergeben um das Potenzial der Leser zu erweitern. Es ist bstimmt interessant zu Erfahren, wie das wirklich funktioniert.

An Ineluki:
Jo Ineluki, Schnell-Ansicht. Ein super Windows-Freature das ich nie standardmäßig installiert habe XD

Hattest du nicht vor eine Ineluki Patch Kollektion zu Erstellen? Oder gibts die schon, bzw. noch in der Entwicklungsphase?

Naja und die Leute, die wirklich einen MP3 Patch hätten schreiben wollen, bräuchten dazu nicht dieses Tutorial.

Gruß Miroku

Demonking
03.04.2006, 23:33
Was wird wohl passieren, wenn jeder seinen eignen (fehlerbehafteten) Patch schreibt, die alle zueinander noch inkompatibel sind ? Und um genau das zu vermeiden, hab ich die Codes nie im Internet veroeffentlicht ...

Na ja .. wir werden sehen, was wird ...
Wenns Hart auf Hart kommt, fuehren wir halt ein QualitaetsZertifikat "Luki Inside" ein ^__-
bleibt die frage ob welche solche quellcodes jemals zustande bringen ;) da ist schon mehr als nur bissle delphi kenntnisse erforderlich :)
Naja werden ja sehen wie das sich ausweiten wird =)

V_182
04.04.2006, 11:28
für jemanden wie mich, der keine ahnung davon hat, ist es mal ganz interessant, tiefer in die materie zu schauen. vllt probier ich das mal aus und schaue, wie weit ich komme. :D
aber ich habe ja schon nen mp3-patch mit "Luki Inside" (die bezeichnung sollte man wirklich einführen ;) ), da brauch ich nicht unbedingt selbst einen erstellen.


Und denkt daran dieses Tutorial ist Copyright by Miroku

traurig, das soetwas wegen gewisser "blitz-studio"-leute extra erwähnt werden muss.

Corti
04.04.2006, 12:20
Wo ost denn da nun der Knackpunkt in Sachen Codec, ich mein wo muss man ansetzen um zB OGG und AAC2 abspielbar zu machen?

Dingsi
04.04.2006, 12:57
Wo ost denn da nun der Knackpunkt in Sachen Codec, ich mein wo muss man ansetzen um zB OGG und AAC2 abspielbar zu machen?In den Funktionen HarmonyPlayMusic und HarmonyStopMusic. Anstatt dort die MCI aufzurufen könnte man einfach eine andere Musik-Bibliothek benutzen (à la FMOD, OpenAL, etc.)

Aldinsys
04.04.2006, 18:44
Habs mir mal genauer angeschaut und ist sehr interessant,obwohl ich in Delphi nicht so bewandert bin wie in anderen Sprachen.
@OT: Hatte Sepiroththe23 nicht einmal erwähnt,dass es für den RPG MAKER XP eine .dll gibt,welche SPC Unterstützung bietet? Das wäre auch sehr interessant.