Utilisateur anonyme
-
1 mai 2008 à 00:23
L_art_ment
Messages postés302Date d'inscriptionvendredi 21 septembre 2007StatutMembreDernière intervention 6 février 2013
-
2 mai 2008 à 08:34
Salut à tous,
Je suis entrain de faire de sauvegarder et ouvrir des records dans un fichier. Au niveau de l'enregistrement je n'ai aucun problemes (j'ai vérifié ) par contre au niveau de l'ouverture j'ai un décalage que je ne capte pas. Ca fait 6heures que je suis dessus et ca commence à me rendre dingue cette histoire .
Ecriture
Procedure Write_PatternFile(FileName:String);
Var
IndexStr,IndexKey:Cardinal;
FS:TFileStream;
SizeRef1,SizeRef2: Cardinal;
Info:String;
Begin
FS:=TFileStream.Create(FileName,fmCreate);
Try
For IndexStr:=8 To High(Form1.PatternMidi.Instruments) Do
FS.Write(Form1.PatternMidi.Instruments[IndexStr],SizeOf(Form1.PatternMidi.Instruments[IndexStr]));
SizeRef1:=FS.Size;
For IndexStr:=0 To High(Form1.PatternMidi.Instruments) Do
For IndexKey:=0 To (Form1.PatternMidi.NbCases-1) Do
FS.Write(Form1.PatternMidi.Partition[IndexStr,IndexKey],SizeOf(Form1.PatternMidi.Partition[IndexStr,IndexKey]));
SizeRef2:=FS.Size-SizeRef1;
Info:=Format('%d-%d-%d-%d|',[SizeRef1,SizeRef2,High(Form1.PatternMidi.Instruments),Form1.PatternMidi.NbCases-1]);
FS.Seek(-Length(Info),soFromBeginning);
FS.Position:=0;
FS.Write(PChar(Info)^,Length(Info));
Finally
FS.Free;
End;
End;
Ouverture :
Procedure Read_PatternFile(FileName:String);
var
FS : TFileStream;
Instrument:TInstrument;
SizeRef1,SizeRef2,LenghtInfo: Cardinal;
ALine:array[0..255] of char;
Info:String;
ActiveKey:Boolean;
NbInstr,NbKey,IndexInstr,IndexKey:Cardinal;
begin
FS:=TFileStream.create(FileName,fmOpenRead);
try
FS.Read(ALine,Length(ALine));
Info:=string(ALine);
LenghtInfo:=Length(Copy(Info,1,Pos('|',Info)));
SizeRef1:=StrToInt(Copy(Info,1,Pos('-',Info)-1));
Delete(Info,1,Pos('-',Info));
SizeRef2:=StrToInt(Copy(Info,1,Pos('-',Info)-1));
Delete(Info,1,Pos('-',Info));
NbInstr:=StrToInt(Copy(Info,1,Pos('-',Info)-1));
Delete(Info,1,Pos('-',Info));
NbKey:=StrToInt(Copy(Info,1,Pos('|',Info)-1));
IndexInstr:=0;
IndexKey:=0;
FS.Position:=LenghtInfo;
while FS.Position<>LenghtInfo+SizeRef1 do
Begin
FS.Read (Instrument, SizeOf(Instrument));
Form1.PatternMidi.Add_Instrument(Instrument.Instrument,Instrument.Channel,Instrument.Note);
With Form1.PatternMidi Do
Begin
Instruments[High(Instruments)].Active:=Instrument.Active;
Instruments[High(Instruments)].Volume:=Instrument.Volume;
Instruments[High(Instruments)].Velocity:=Instrument.Velocity;
Instruments[High(Instruments)].PitchBend:=Instrument.PitchBend;
Instruments[High(Instruments)].ChannelPressure:=Instrument.ChannelPressure;
Instruments[High(Instruments)].Modulation:=Instrument.Modulation;
Instruments[High(Instruments)].PortamentoTime:=Instrument.PortamentoTime;
Instruments[High(Instruments)].PortamentoSwitch:=Instrument.PortamentoSwitch;
Instruments[High(Instruments)].PortamentoNote:=Instrument.PortamentoNote;
Instruments[High(Instruments)].Resonance:=Instrument.Resonance;
Instruments[High(Instruments)].Pan:=Instrument.Pan;
Instruments[High(Instruments)].Expression:=Instrument.Expression;
Instruments[High(Instruments)].Sustain:=Instrument.Sustain;
Instruments[High(Instruments)].Reverb:=Instrument.Reverb;
End;
end;
FS.Position:=LenghtInfo+SizeRef1;
while FS.Position<>FS.Size do
Begin
FS.Read(ActiveKey,SizeOf(ActiveKey));
Form1.PatternMidi.Partition[IndexInstr,IndexKey]:=ActiveKey;
Inc(IndexKey);
If IndexKey>NbKey Then
Begin
IndexKey:=0;
Inc(IndexInstr);
End;
End;
finally
FS.Free;
Form1.PatternMidi.Refresh;
end;
End;
Si une ame charitable pouvait sauver le seul cheveux qui me reste .
Arfff j'ai oublié l'essentiel : C'est dans la seconde partie que j'ai un probleme
FS.Position:=LenghtInfo+SizeRef1;
while FS.Position<>FS.Size do
Begin
FS.Read(ActiveKey,SizeOf(ActiveKey));
Form1.PatternMidi.Partition[IndexInstr,IndexKey]:=ActiveKey;
Inc(IndexKey);
If IndexKey>NbKey Then
Begin
IndexKey:=0;
Inc(IndexInstr);
End;
End;
Vous n’avez pas trouvé la réponse que vous recherchez ?
type
pItemTrucMachin = ^TItemTrucMachin; // toujours, au cas ou...
TItemTrucMachin = record
itemscount : longword;
filesize : longword;
itemsize : longword;
end;
...
const
SizeOf_TItemTrucMachin = SizeOf(TItemTrucMachin); // une fois pour toute
...
writebuffer(ItemTrucMachin, SizeOf_TItemTrucMachin);
C'était un probleme d'offset : j'ai pas tout compris le pourquoi du comment mais j'ai fais un truc qui fonctionne
Procedure Write_PatternFile(FileName:String);
Var
IndexStr,IndexKey:Cardinal;
MS:TMemoryStream;
SizeRef1,SizeRef2: Cardinal;
Info:String;
Begin
With Form1.PatternMidi Do
Begin
MS:=TMemoryStream.Create;
Try
For IndexStr:=0 To High(Form1.PatternMidi.Instruments) Do
For IndexKey:=0 To (Form1.PatternMidi.NbCases-1) Do
MS.Write(Partition[IndexStr,IndexKey],SizeOf(Partition[IndexStr,IndexKey]));
SizeRef1:=MS.Size;
For IndexStr:=0 To High(Form1.PatternMidi.Instruments) Do
MS.Write(Instruments[IndexStr],SizeOf(Instruments[IndexStr]));
SizeRef2:=MS.Size;
Info := Format('|%d-%d-%d',[SizeRef1,SizeRef2,NbCases]);
MS.Write(PChar(Info)^,Length(Info));
MS.SaveToFile(FileName);
Finally
MS.Free;
End;
End;
End;
Procedure Read_PatternFile(FileName:String);
var
FS : TFileStream;
Instrument:TInstrument;
SizeRef1,SizeRef2: Cardinal;
ALine:array[0..50] of char;
Info:String;
ActiveKey:Boolean;
NbInstr,NbKey,CountInstr,CountKey:Cardinal;
begin
FS:=TFileStream.Create(FileName,fmOpenRead);
Try
FS.Position:=FS.Size-SizeOf(ALine);
FS.Read(ALine,Length(ALine));
Info:=Copy(ALine,Pos('|',ALine)+1,Length(ALine));
SizeRef1:=StrToInt(Copy(Info,1,Pos('-',Info)-1));
Delete(Info,1,Pos('-',Info));
SizeRef2:=StrToInt(Copy(Info,1,Pos('-',Info)-1));
Delete(Info,1,Pos('-',Info));
NbKey:=StrToInt(Info);
FS.Position:=SizeRef1;
CountInstr:=1;
while FS.Position<>SizeRef2 do
Begin
FS.Read (Instrument, SizeOf(Instrument));
If CountInstr>8 Then
Form1.PatternMidi.Add_Instrument(Instrument.Instrument,Instrument.Channel,Instrument.Note);
With Form1.PatternMidi Do
Begin
Instruments[CountInstr-1].Active:=Instrument.Active;
Instruments[CountInstr-1].Volume:=Instrument.Volume;
Instruments[CountInstr-1].Velocity:=Instrument.Velocity;
Instruments[CountInstr-1].PitchBend:=Instrument.PitchBend;
Instruments[CountInstr-1].ChannelPressure:=Instrument.ChannelPressure;
Instruments[CountInstr-1].Modulation:=Instrument.Modulation;
Instruments[CountInstr-1].PortamentoTime:=Instrument.PortamentoTime;
Instruments[CountInstr-1].PortamentoSwitch:=Instrument.PortamentoSwitch;
Instruments[CountInstr-1].PortamentoNote:=Instrument.PortamentoNote;
Instruments[CountInstr-1].Resonance:=Instrument.Resonance;
Instruments[CountInstr-1].Pan:=Instrument.Pan;
Instruments[CountInstr-1].Expression:=Instrument.Expression;
Instruments[CountInstr-1].Sustain:=Instrument.Sustain;
Instruments[CountInstr-1].Reverb:=Instrument.Reverb;
End;
Inc(CountInstr);
end;
FS.Position:=0;
CountInstr:=1;
CountKey:=1;
while FS.Position<>SizeRef1 do
Begin
FS.Read (ActiveKey, SizeOf(ActiveKey));
Form1.PatternMidi.Partition[CountInstr-1,CountKey-1]:=ActiveKey;
Inc(CountKey);
If CountKey>NbKey Then
Begin
CountKey:=1;
Inc(CountInstr);
End;
End;
finally
FS.Free;
Form1.PatternMidi.Refresh;
end;
End;
Merci f0xi : Effectivement ce n'était pas élégant ces delete et copy mais jamais j'aurais pensé à passer par un record pour faire ca . J'ai appris une nouvelle technique . Merci beaucoup .
With Self.PatternMidi Do
Move(Instruments[CountInstr-1], Instrument, SizeOf(TInstrument));
mais j'ai l'impression que la encore, le francky code a encore frapper...
AddInstrument ne devrait t'il pas prendre en parametres un TInstrument ? ou alors overloader ce Add en version
parametres par parametres et version TInstrument ?
ce qui eviterai de se taper a chaque fois ce nombre improbable d'allocation de valeur ?
on pourrait encore transformer TInstrument en TPersistent pour qu'il contienne des methodes et evenements propre a lui même et surtout la trop fameuse methode Assign / AssignTo ...
Pour l'appel des fiches : Il s'agit juste d'un test que je réalisais. Dans le projet les choses sont un peu différentes .
Pour la procedure Add_Instrument : en fait j'ai fais un pattern style Fruity Loops . Le but est de pouvoir rajouter un instrument dans cette pattern. L'ajout se fait via des valeurs par défauts qui seront modifiables. Donc pas besoin de définir un TInstrument avec ces 150 propriétés puis de faire un
Add(Instrument: TInstrument). Par contre je suis obligé de définir la valeur de la note car pour les percussions, chaque note correspond à une percussion données (Alors que pour un piano par exemple, chaque note correspond à la note lol). Idem pour le channel car par défaut le channel des percussions est définit à 10. Le midi est assez tortueux, pour etre honnette.
Ce projet est un peu complexe : j'en suis pas encore à la phase de finalisation mais de conception donc si il y a des maladresses c'est normal. Une fois finit j'aurais suffisamment de recul pour le remanier comme il faut t'inquete pas .
000 caféine-overdosator
010 repeat 150 nouvelles fonctionnalitées
020 test ? c'est quoi toutes ces lignes de codes ?
030 release pourrave, changer de cerveau ? Y/N