Comment mélanger un tableau ?

Résolu
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 14 janv. 2006 à 10:31
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 - 16 janv. 2006 à 23:16
Je me suis fait un petit player mp3, et alors que j'ajoutais des fonctions, paf l'idée saugrenue defaire un "shuffle" d'une playlist, à savoir la foutre en bordel, modifier aléatoirement l'ordre des morceaux.

A l'interieur du prog,cette playlist est un Array of tfilename.

Quelle est la meilleur soluce : Au lieu de passer au morceau suivant, je loade un morceau pris au hasard dans la playlist (risque de lire plusieures fois le meme fichier), ou je me tape l'ecriture d'une fonction qui va effectivement me modifier cette playlist, et dans ce cas, qqun aurait-il un pitit algo vite fait pour que 1, ca prenne pas deux heures, 2 ca soit relativement aléatoire ?

19 réponses

cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
15 janv. 2006 à 16:39
"si je tape SPLS:=
TStrings.Create; j'ai droit a plein de messages du compilateur, alors
qu'avec SPLS:= TStringList.Create; (SPLS etant un Tstrings) pas un mot
du compilo ???"
Extrait de l'aide en ligne : " TStrings contient des méthodes abstraites ou,dans la terminologie C++,virtuelles pures et ne doit pas être instanciée directement. "
Si tu regardes la hiérarchie des composants de la VCL, tu t'apercevras que TStrings est une classe abstraite qui ne sert qu'à déclarer des méthodes abstraites devant être implémentées par ses descendants : TStringList et TStringGridStrings.
Comme tu le sais, on ne peut pas instancier une classe abstraite et le compilateur t'en avertit à juste titre.
Comme la méthode Sort n'aurait pas de sens à ce niveau d'abstraction, elle n'est déclarée qu'à partir de la classe TStringList.

"créer un objet Tstrings dans un prog n'est pas tres bien vu, dans l'aide delphi"
Ah bon ? Pourtant, c'est autrement plus performant qu'un tableau de chaines ne disposant d'aucune méthode, plus respectueux de l'utilisation de la mémoire, etc. Je suis très étonné.

Pour finir :
- soit tu déclares un TStringList si tu n'as pas besoin d'utiliser le polymorphisme directement.
- soit tu déclares un TStrings et, quand tu en as besoin, tu forces le type (opérateur as ) et tu fais appel à la méthode Sort dessus.
Dans ton cas, ce serait apparemment plus simple de déclarer et d'utiliser directement un TStringList. Inutil ede t'embrouiller !

<hr color ="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
3
florenth Messages postés 1023 Date d'inscription dimanche 1 août 2004 Statut Membre Dernière intervention 17 août 2008 3
14 janv. 2006 à 10:51
type
TPlayList = array of TFileName;

procedure RandomizePlaylist(var List: TPlayList);
var
Idx1, Idx2, I: Integer;
FN: TFileName;
begin
Randomize;

{ On va inverser des chansons "Length(List) div 3" fois. }
for I := 1 to Length(List) div 3 do
begin
{ Choix de deux chansons à inverser. }
Idx1 : = RandomRange(Low(List), High(List));
repeat
Idx2 := RandomRange(Low(List), High(List));
until Idx1 <> Idx2;

{ Echange. }
FN : = List[Idx1];
List[Idx1] := List[Idx2];
List[Idx2] := FN;
end;
end;

Voila une petite procédure simpe qui met en désordre ton tableau.
Penses à ajouter "Math" dans les uses.

++

Si tu ne te plantes pas ......
tu ne pousseras jamais
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
14 janv. 2006 à 16:08
a la place du Array of TFileName tu peux utiliser un TStrings qui te permet plus de chose

un exemple sur la base de Florenth ( avec la correction du Bug RandomRange par WhiteHippo)

Var
PlayList : TStrings;
Function RandomRangeEx(Const AFrom, ATo: Integer): Integer;
Begin
If AFrom > ATo Then
Result := Random(AFrom - ATo + 1) + ATo
Else
Result : = Random(ATo - AFrom + 1) + AFrom;
End;


procedure RandomizePlaylist(var List: TStrings);
var
Idx1, Idx2, I: Integer;
FN: String;
begin
Randomize;


{ On va inverser des chansons "Length(List) div 3" fois. }
for I := 0 to List.Count - 1 div 3 do
begin
{ Choix de deux chansons à inverser. }
Idx1 : = RandomRangeEx(0, List.Count - 1);
repeat
Idx2 := RandomRangeEx(0, List.Count - 1);
until Idx1 <> Idx2;


{ Echange. }
List.Exchange(Idx1, Idx2);
end;
end;



@+
Cirec
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
14 janv. 2006 à 17:09
"Bordeliser", "foutre en bordel", c'est quoi ce langage ?
Comment mélanger un tableau me semble plus correct et adapté.
Pour devenir programmeur, li n'y a pas besoin d'être grossier.
<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
14 janv. 2006 à 20:57
Dans les codes sources tu peu regarder, dans mes codes sources en particulier.

Un moteur pour lecteur multimedia créé j'ai, PlopEngine ce dernier s'apel.

Une fonction Shuffle pour playlist et d'autre chose tu y trouveras.

Le liens vers ce dernier voici : Plop Engine

ps : En cas de probleme me contacter sur delphifr tu peux.

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
15 janv. 2006 à 15:53
Sorry pour l'emploi d'un terme "grossier" (enfin bon...) A propos des
Tstrings, j'ai l'impression que créer un objet Tstrings dans un prog n'est pas tres bien vu, dans l'aide delphi...

Deja si je tape SPLS:= TStrings.Create; j'ai droit a plein de messages du compilateur, alors qu'avec SPLS:= TStringList.Create; (SPLS etant un Tstrings) pas un mot du compilo ???

Ma question concerne le tri d'un tel Tstrings. Trier en quicksort un tableau dynamique de strings ne pose pas de problème (ou un Tstrings sur le meme principe), mais je me demande si une telle possibilité existe pour les Tstrings ? J'ai lu l'aide et la méthode n'existe pas, mais puisque je crée (create) un Tstrings en appelant le create d'un TstringList, serait-il possible d'utiliser la méthode sort de TstringList pour trier mon Tstrings ?

J'ai des ces idées parfois....
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
15 janv. 2006 à 19:03
Ouch ca fait loooooontemps que je me suis pas remis a la gymnastique des classes et autres joyeusetés objet.... ( 1999 pour etre precis) J'ai posté alors que je cafouillais encore un poil , c'est le "ne doit pas etre instancié directement" qui m'a enduit d'erreur.


Mais comment j'ai fais pour avoir un DEA d'info moi..... Faut croire qu'écrire du shell et du cobol pour le monde bancaire, ca ruine les neurones....

C'est clair, le polymorphisme, pas besoin, donc TstringList pour tout le monde.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
15 janv. 2006 à 20:55
En fait dans mon Exemple je déclare la variable comme ceci : Var PlayList : TStrings;
Mais quand je la crée je fait PlayList := TStringList.Create

Désolé pour ce manque de précision


@+
Cirec
0
cs_Delphiprog Messages postés 4297 Date d'inscription samedi 19 janvier 2002 Statut Membre Dernière intervention 9 janvier 2013 32
15 janv. 2006 à 21:51
@DeltaFx a écrit : "Faut croire qu'écrire du shell et du cobol pour le monde bancaire, ca ruine les neurones"
Je confirme. J'ai des exemples encore vivants autour de moi. mdr
N'as-tu jamais essayé le cobol objet ?

@cirec : je ne comprends pas bien l'intérêt de passer List en paramètre var dans :
procedure RandomizePlaylist(var List: TStrings);
List est une référence, autrement dit un pointeur caché. Ajouter var n'apporte rien il me semble. Si ça avait été const à la place, là ça se comprendrait (dans un autre contexte bien sûr).
En revanche, quand Florenth écrit :
procedure RandomizePlaylist(var List: TPlayList)
Là, c'est justifié puisque il s'agit d'une variable tableau que l'on veut pouvoir modifier à l'intérieur de la procédure.
<hr color="#008000">Pensez à cliquer sur Réponse acceptée lorsque la réponse vous convient.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
15 janv. 2006 à 21:58
>>DelphiProg , ma première victime du copier coller . En effet j'ai fait une copie du code de Florenth je l'ai modifier rapidement et j'ai pas fait attention du tout à celà.



@+
Cirec
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 01:51
bon je reitere ma reponse vus qu'elle a l'air d'etre passée inaperçue ...

tu telecharge PlopEngine.

tu ne prend que "Plopengine.pas" pour ton projet.

et tu fait par exemple :

ShufflePlaylist(Listbox1);

ou

NewTrack := ShufflePlaylist(Listbox1);

La fonction est elaborée de tel maniere a ce qu'une piste ne sois jamais relue avant que toute les autres soit lues au moins 1 fois et ce que la liste soit petite ou grande.

ShufflePlaylist accepte tout les composants derivé de TCustomListBox.

sinon il faudrat utiliser la fonction ShuffleAPC

NextTrack := ShuffleAPC(StringList.Count,PisteEnCours);

> lire les commentaires dans l'unité plopengine...

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 02:00
voila le code pour les curieux (et ceux qui ne veulent pas telecharger le zip) :


// -------------------------------------------------------------------------------------------------
// SHUFFLE {INTERNAL USE ONLY} ---------------------------------------------------------------------
var
_SHUF_OldTracks : array of integer;

function _SHUFOT(const index : integer) : boolean;
var x : integer;
begin
for x : = 0 to length(_SHUF_OldTracks)-1 do begin
if index = _SHUF_OldTracks[x] then begin
result := true;
exit;
end;
end;
result := false;
end;

function _SHUFRANGE(AFrom,ATo : integer) : integer;
begin
if AFrom > ATo then
Result : = Random(AFrom - ATo + 1 ) + ATo
else
Result := Random(ATo - AFrom + 1 ) + AFrom;
end;

// -------------------------------------------------------------------------------------------------
// SHUFFLEAPC -------------------------------------------------------------------------------------
function ShuffleAPC(const PlaylistCount,CurrentTrackIndex : integer) : integer;
var NewIndex,WX : integer;
begin
result : = -1;
if PlayListCount = 0 then exit;
result := 0;
if PlayListCount = 1 then exit;

if VShuffleMethod = smRandom then begin
SetLength(_SHUF_OldTracks,0);
result := _SHUFRANGE(0,PlayListCount-1);
end else begin
SetLength(_SHUF_OldTracks,Length(_SHUF_OldTracks)+1);
if Length(_SHUF_OldTracks) > PlayListCount+1 then SetLength(_SHUF_OldTracks,1);
_SHUF_OldTracks[Length(_SHUF_OldTracks)-1] := CurrentTrackIndex;

NewIndex := _SHUFRANGE(0,playlistCount-1);
WX := 0;
while _SHUFOT(NewIndex) do begin
NewIndex := _SHUFRANGE(0,playlistCount-1);
if WX > PlayListCount then Break;
inc(WX);
end;
Result := NewIndex;
end;
end;

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 02:03
hola, j'oubliais, pour utiliser un simple random
la variable globale VShuffleMethod doit etre parametrée a smRandom et pour utiliser le random avancé il faut la mettre a smTrueShuffle (valeur par defaut)

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
16 janv. 2006 à 10:40
Si si j'avais bien vu plopengine. T'inquiètes, meme si je ne m'en sers pas pour l'instant, je le garde sous le coude.
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
16 janv. 2006 à 12:13
ça fait beaucoup de code juste pour melanger un tableau non ?



@+
Cirec
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 18:53
oui Cirec, mais ce n'est pas n'importe quel tableau!

vus que pour un conford maximum de lecture d'une playliste il faut eviter au maximum de relire une piste deja lue tant que toute les autres ne l'on pas ete.
c'est a cela que sert le tableau dynamique et il est vidé dés que toutes les pistes ont ete lues puis on recommence la selection aleatoire (controllée).

car il ne s'agit pas de faire un simple random meme un minimum controlé... il faut réellement prendre en compte le controle total de la selection aleatoire en excluant les pistes deja lues.

donc, oui beaucoup de code, mais cela est justifié et relativement necessecaire pour obtenir un resultat probant.

car les solutions proposée, bien qu'efficace, ne font que "mettre le bordel" (^^) dans la playlist sans vraiment de control sur la methode, ce qui n'empecheras donc pas a une piste d'etre relue plusieurs fois durant l'ecoute.
de plus ces methodes change l'ordre des items (visuellement) et cela est genant et carrement inpropre a une playlist.

bien sur je ne dis pas que ma methode est la meilleure, loin de la, mais elle a au moins l'avantage d'etre réelement prevue pour la lecture aleatoire d'une playlist en prenant en compte les conditions speciales d'une playlist d'un lecteur multimedia, c'est d'ailleur pour cela que j'ai créer PlopEngine.
D'ailleur, j'en profite, cela me ferait vraiment plaisir que certains d'entre vous jette au moins un oeuil a mon travail, en particulier cirec, jlen, florenth, delphiprog et autre car je sais qu'avec vous le travail serat correctement critiqué dans le but de l'ameliorer (notement sur la partie graphique des composants, je doute que mes routines soit des plus parfaites), voir que vous preniez par au projet car j'aimerais vraiment en faire quelque chose de concret et utile ... seul cela risque d'etre plus difficile...

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
16 janv. 2006 à 22:27
Moi ce qui me boterait bien ca serait un composant qui me fournirait les meme capacité qu'un Tmediaplayer( pas plus, je veux pas d'usine à gaz), à base de bass.dll (pask'il reste un sale bug dans leTmediaplayer, il se met en vrac si le nom complet path+filename dépasse une certaine longueur, j'ai du importer l'activeX deWMP, mais à boulot identique, ca bouffe 6 fois plus de ressources)

Et comme bass.dll peut comprendre et utiliser les AVS de winamp et sonique, ca ferait un remplaçant ideal pour TmediaPlayer. Et j'aurais pas a me poser de question sur la plate forme de l'utilisateur (WMP 6.7,7.1, 8,9,10...)

Un jour, je l'aurais !
0
f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 35
16 janv. 2006 à 23:05
tu fait bien d'en parler parce que je bosse la dessus en ce moment (un composant de son basé sur Bass et/ou FMod)
mais c'est tellement de boulot que pour l'instant ça traine un peu.

La theorie c'est quand on sait tout, mais que rien ne fonctionne.
La pratique c'est quand tout fonctionne, mais que personne ne sait pourquoi.
<hr>
0
DeltaFX Messages postés 449 Date d'inscription lundi 19 avril 2004 Statut Membre Dernière intervention 8 avril 2009 2
16 janv. 2006 à 23:16
Les grands esprit se rencontrent (mmmmpffff, oui j'ai les chevilles qui enflent). Je parlais de bass.dll parce que outre la gestion des AVS et des visio sonique( un à-coté plaisant, je dois etre le dernier à utiliser Sonique 1.96), et la puissance du truc, y a foison de codes Delphi sur le site.... Quand je suis tombé dessus, je me suis mis a chercher des midichlorelles sous mon écran, tellement ca ressemblait à une vergeance de la Force...

Dum Dum Dum Dum Dadum, Dum Dadum....
0
Rejoignez-nous