Comment mélanger un tableau ? [Résolu]

DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 14 janv. 2006 à 10:31 - Dernière réponse : DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention
- 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 ?
Afficher la suite 

Votre réponse

20 réponses

Meilleure réponse
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 15 janv. 2006 à 16:39
3
Merci
"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.

Merci cs_Delphiprog 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 102 internautes ce mois-ci

Commenter la réponse de cs_Delphiprog
florenth 1105 Messages postés dimanche 1 août 2004Date d'inscription 17 août 2008 Dernière intervention - 14 janv. 2006 à 10:51
0
Merci
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
Commenter la réponse de florenth
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 14 janv. 2006 à 15:32
0
Merci
ATTENTION au Bug de RandomRange débusqué par [www.delphifr.com/auteurdetail.aspx?ID=323345 WhiteHippo] que vous trouverez ici : BUG RANDOMRANGE



@+
Cirec
Commenter la réponse de Cirec
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 14 janv. 2006 à 16:08
0
Merci
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
Commenter la réponse de Cirec
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 14 janv. 2006 à 17:09
0
Merci
"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.
Commenter la réponse de cs_Delphiprog
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 14 janv. 2006 à 20:57
0
Merci
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>
Commenter la réponse de f0xi
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 15 janv. 2006 à 15:53
0
Merci
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....
Commenter la réponse de DeltaFX
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 15 janv. 2006 à 19:03
0
Merci
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.
Commenter la réponse de DeltaFX
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 15 janv. 2006 à 20:55
0
Merci
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
Commenter la réponse de Cirec
cs_Delphiprog 4580 Messages postés samedi 19 janvier 2002Date d'inscription 9 janvier 2013 Dernière intervention - 15 janv. 2006 à 21:51
0
Merci
@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.
Commenter la réponse de cs_Delphiprog
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 15 janv. 2006 à 21:58
0
Merci
>>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
Commenter la réponse de Cirec
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 16 janv. 2006 à 01:51
0
Merci
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>
Commenter la réponse de f0xi
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 16 janv. 2006 à 02:00
0
Merci
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>
Commenter la réponse de f0xi
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 16 janv. 2006 à 02:03
0
Merci
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>
Commenter la réponse de f0xi
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 16 janv. 2006 à 10:40
0
Merci
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.
Commenter la réponse de DeltaFX
Cirec 4231 Messages postés vendredi 23 juillet 2004Date d'inscription 3 août 2018 Dernière intervention - 16 janv. 2006 à 12:13
0
Merci
ça fait beaucoup de code juste pour melanger un tableau non ?



@+
Cirec
Commenter la réponse de Cirec
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 16 janv. 2006 à 18:53
0
Merci
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>
Commenter la réponse de f0xi
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 16 janv. 2006 à 22:27
0
Merci
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 !
Commenter la réponse de DeltaFX
f0xi 4304 Messages postés samedi 16 octobre 2004Date d'inscription 9 mars 2018 Dernière intervention - 16 janv. 2006 à 23:05
0
Merci
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>
Commenter la réponse de f0xi
DeltaFX 459 Messages postés lundi 19 avril 2004Date d'inscription 8 avril 2009 Dernière intervention - 16 janv. 2006 à 23:16
0
Merci
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....
Commenter la réponse de DeltaFX

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.