Annonces Google
Serveur IRC
Serveur : irc.portlane.se
Canal : #AmigaNG
Activité du Site

Pages vues depuis 25/07/2007 : 24 894 619

  • Nb. de membres 186
  • Nb. d'articles 1 269
  • Nb. de forums 19
  • Nb. de sujets 20
  • Nb. de critiques 24

Top 10  Statistiques

Index du forum »»  Création-Développement »» *Urgent* besoin d'aide pour Datatype Audio.

*Urgent* besoin d'aide pour Datatype Audio.#1478

4Contributeur(s)
AmiDARKzzd10hthellierElwood
3 Modérateur(s)
K-LElwoodcorto
AmiDARK AmiDARKicon_post
Bon.
J'ai exposé mon soucis dans les forums amigaworld.net & amigans.net au cas où :p
Je l'expose ici aussi :

Au vu de sa structure, l'AmiDARK Engine fonctionne par instructions (non bloquantes).
J'ai donc par exemple :

1. Fonction pour charger un objet audio : DELoadSound( File, ID )
2. Fonctions pour jouer, pauser, résumer, stopper un son : DEPlaySound( ID ), DEPauseSound( ID ), DEResumeSound( ID ), DEStopSound( ID )
3. Fonction pour supprimer le son : DEDeleteSound( ID )

Je peux charger donc un son et le supprimer en utilisant les datatypes et ce sans problèmes.
Le problème est pour la lecture du son (et l'écoute donc :p)

Voici les 2 fonctions, celle de chargement et celle de lecture :
[quote]
void DELoadSound( char *szFilename, int iID ){
// ULONG res;
// uint32 longueur ;
if ( iID > 0 ){
if ( iID < 257 ){
if ( DESoundExist( iID ) == 0 ){
if( DEFileExist( szFilename ) == TRUE ){
AESound[ iID ].ObjectPTR = IDataTypes->NewDTObject( (STRPTR)szFilename,
DTA_SourceType, DTST_FILE,
DTA_GroupID, GID_SOUND,
SDTA_Volume, 63,
// SDTA_SignalTask, (ULONG)IExec->FindTask(NULL),
// SDTA_SignalBitMask, END_SOUND_SIGNAL,
TAG_END );
if ( AESound[ iID ].ObjectPTR != NULL ){
AESound[ iID ].Exist = TRUE;
AESound[ iID ].Loop = FALSE;
AESound[ iID ].Playing = 0;
AESound[ iID ].FileName = LCreateString( 256 );
LCopyString( szFilename, AESound[ iID ].FileName );
AESound[ iID ].Audio3D = 0 ; // This sound IS NOT a 3D Audio sound.
}else{
printf( "DELoadSound Warning : Object not created\n" );
AESound[ iID ].Exist = FALSE;
}
}
}
}
}
}

void DEPlaySound( int iID ){
if ( DESoundExist( iID ) == 1 ){
if ( AESound[ iID ].Playing != 0 ){
DEStopSound( iID );
}
mydtt.MethodID = DTM_TRIGGER;
mydtt.dtt_GInfo = NULL;
mydtt.dtt_Function = STM_PLAY;
mydtt.dtt_Data = NULL;
AESound[ iID ].dores = IDataTypes->DoDTMethodA( AESound[ iID ].ObjectPTR, NULL, NULL, (Msg)&mydtt );
IExec->Wait( SIGBREAKF_CTRL_C );
AESound[ iID ].Playing = 1;
}
}
[/quote]
Tout se compile sans défaut.
ma librairie libAmiDARK.a se compile sans problèmes.

Maintenant le soucis est le suivant :
1. Si je supprime la ligne avec le IExec->Wait( SIGBREAKF_CTRL_C )
Aucun son ne fonctionne. le DEPlaySound ne restitue rien !

2. Si je ne supprime pas la ligne IExec->Wait( SIGBREAKF_CTRL_C )
Le son se joue bien à la demande de l'utilisateur (voir exemple qui suit).
Mais le problème reste bloqué (apparemment dans le Wait) indéfiniment (même CTRL+C ou un clic dans le gadget de fermeture de fenêtre ne fait rien du tout).
Programme bloqué. Ca ne plante pas l'Amiga cependant !!!

Voici le code source de l'exemple "AmiDARK Engine" utilisé pour tester les commandes/fonctions audio :
[quote]
#!include! "libamidark.h"
int InKey;
void DarkLoop( void ){
// Setup Display.
DESetDisplayMode( 640, 480, 32 );
DESyncOn();
DESyncRate( 60 );
// Load the 4 samples using DataTypes.
DELoadSound( "Medias/oceanwave.wav", 1 );
DELoadSound( "Medias/break.wav", 2 );
DELoadSound( "Medias/DREAM.WAV", 3 );
DELoadSound( "Medias/electricarc.wav", 4 );
DELoadImageEx( "Medias/AmiDARK_Engine_Logo v2.png", 1, 1 );
InKey = 0;
while( !DELoop() ){
DECls();
DESetCursor( 0, 0 );
DEPrint( "AmiDARK Engine now play Audio Sounds using DATATYPES" );
DEPrint( "Press default QUIT KEY to stop this demonstration example." );
DEPrint( " " );
DEPrint( "Press 1 to play OceanWave.wav" );
DEPrint( "Press 2 to play Break.wav" );
DEPrint( "Press 3 to play Dream.wav" );
DEPrint( "Press 4 to play ElectricArc.wav" );
// Keyboard key 1 to 4 start replay of a sound.
InKey = DEScancode(); InKey--;
if ( InKey > 0 ){
if ( InKey < 5 ){
DEPlaySound( InKey );
}
}
DEPasteImageEx( 1, DEBitmapWidth( 0 ) - ( DEImageWidth( 1 ) + 4 ), 4, 1 );
DESync();
}
// We delete sounds from memory.
for ( InKey = 0; InKey < 5; InKey++ ){
DEStopSound( InKey );
DEDeleteSound( InKey );
}
}
[/quote]
Comme l'on peut le voir, je charge 4 instruments.
Et lorsque l'on utilise une touche clavier de 1 à 4, un des instruments est joué.
Donc, si je lance mon application, et quitte ... elle se quitte comme il faut.
Mais si je lance l'application et demande à jouer un son, j'obtiens les résultats cités plus haut en 1 (pas d'audio) & 2 (audio mais application bloquée).

L'objectif est de n'avoir AUCUN Wait car le principe même de la librairie est de permettre de tout faire en fond.
Je sais qu'il doit exister une solution, pour preuve, lorsque je charge l'objet, si je mets en attributs SDTA_Continuous, TRUE, les 4 sons se jouent en simultané au lancement de l'application et ce sans blocage. Je peux même quitter l'application avant la fin de lecture des sons, mes DEDeleteSound arrêtent et suppriment les objets sons correctement, aucun plantage.
J'ai essayé d'utiliser SDTA_Continuous en tant que paramètre avec SetDTAttrs pour modifier le son lorsque l'on demande la lecture ... sans succès ...

Quelqu'un aurait-il une idée pour solutionner ceci ?
Je me demande comment le logiciel MultiView fait pour ne pas bloquer pdt la lecture d'un audio ...

Merci par avance.
@+
zzd10h zzd10hicon_post
C'est peut-être pas propre mais pourquoi ne pas utiliser un programme externe pour lire tes sons et lui envoyer, à ce "lecteur" externe, des signaux sur un port de message pour stopper le son quand tu le souhaites.

Bref pourquoi ne pas te servir de Datatype_Sound qu'on a fait avec Alain (sur le dépot) pour jouer tes sons (en externe) et les controler par signaux avec DataType_Sound_Break ?

Sinisrus l'utilise pour son KeyRythMe et ça marche très bien, pas de blocage de son programme pendant la lecture !

Est-ce que ça pourrait répondre à ton besoin (même si la solution ne te plait pas) ?

Mais bon, vu que tu avais suivi la file de discussion de DataType_Sound, tu as du déjà regarder...

Bon courage
thellier thelliericon_post
Bonsoir

j attendais que zzd10h te reponde car moi je connais pas les datatypes plus que ca...
Sans wait: je pense que tu detruis ton objet datatype avant que le son commence a se jouer

avec wait: pas d idee = faudrait voir jusqu ou le prog avance je veut dire il bloque peut etre pas dans le wait mais freeze peut etre sur une instruction apres...

Alain
thellier thelliericon_post
(passé sur le PC pour mieux taper)
Bon dans ce genre de cas de debuggage où je comprends rien de la bug,
où mes yeux ne voyent plus les problèmes et où ça me gave je fais ainsi:

au début de chaque ligne je rajoute LL de cette façon

LL mydtt.MethodID = DTM_TRIGGER;
LL mydtt.dtt_GInfo = NULL;
LL mydtt.dtt_Function = STM_PLAY;
LL mydtt.dtt_Data = NULL;
LL AESound[ iID ].dores = IDataTypes->DoDTMethodA( AESound[ iID ].ObjectPTR, NULL, NULL, (Msg)&mydtt );
LL IExec->Wait( SIGBREAKF_CTRL_C );
LL AESound[ iID ].Playing = 1;

avec LL juste défini ainsi

#define LL printf("Line:%ld\n",__LINE__);


Ainsi ça m'imprime le numéro de la ligne avant le freeze/crash


Note: avec LL faire gaffe aux if() genre:
LL if(truc==NULL)
LL return;


J'ai même un LLL qui fais du pas à pas :

#define LLL debugprintf("Line:%ld\n",__LINE__); OSAlert("OK");

/*==================================================================*/
void OSAlert(void *p1)
{
UBYTE *t=p1;
void *Data=&t+1L;
struct EasyStruct EasyStruct;
ULONG IDCMPFlags;

EasyStruct.es_StructSize=sizeof(struct EasyStruct);
EasyStruct.es_Flags=0L;
EasyStruct.es_Title=(void *)"Message:";
EasyStruct.es_TextFormat=(void*)t;
EasyStruct.es_GadgetFormat=(void*)"OK";

IDCMPFlags=0L;
(void)EasyRequestArgs(NULL,&EasyStruct,&IDCMPFlags,Data);
return;
}


Si le datatype joue "en parallele" de ton prog alors il faudrait voir si il existe un mecanisme de l4OS (interruption survenant une fois son joué ? hook d'action à faire quand survenant une fois son joué ? etcc..) qui peut supprimer ton datatype juste une fois le son joué


Bon courage

Alain



AmiDARK AmiDARKicon_post
zzd10h :
Ben en fait, je ne peux pas faire appel à un programme externe, sauf si il s'agit d'une .library.
Et si ton prog on le mets en library, l'appel de fonction ne rendra pas la main ... donc c'est pas utilisable non plus ...

Thellier :
Je sais exactement ce qui bloque, c'est le IExec->Wait( ..., ... ) qui bloque
si je l'utilise pas le prog tourne sans bloquage mais pas d'ouput audio.
Si je l'utilise un printf juste avant le Wait s'affiche et celui juste après ne s'affiche pas. donc, le Wait bloque bien ;)

@+
AmiDARK
Elwood Elwoodicon_post
il "bloque" ou simplement il attend ? Car c'est son boulot justement d'attendre jusqu'à ce que les signaux que tu as définis arrivent.
--
Philippe Ferrucci
Avec une Sam460 et AmigaOS 4.1, je suis eco-responsable. Cool !
AmiDARK AmiDARKicon_post
Tout à fait Elwood, il attends.

En fait, il n'existe pas réellement (enfin, je n'ai pas trouvé) au niveau de l'OS4, une fonction qui permette de dire "j'attends que les interruptions systèmes et processus aient fait le travail pour cette synchro verticale" ...
Je suis obligé soit d'attendre que j'ai demandé un break (CTRL+C), une fermeture d'application

Après, ce que j'aimerais savoir c'est qu'est ce que cette fonction "Wait" appel dans le système qui fait que le son fonctionne alors qu'il fonctionne pas si je ne l'appelle pas.
Dans d'autres exemples, ils utilisent un Delay() ... J'ai testé ... pas de sons ...

Donc y a vraiment un truc zarb la dedans ...
thellier thelliericon_post
>Je sais exactement ce qui bloque, c'est le IExec->Wait

Là tu vois je devrais le prendre mal et te dire "si tu sais si bien ce qui bloque pourquoi tu nous le demande ?"
Mais je sais ce que c'est de bloquer sur une bug :-)
1) je parle par experience : on crois souvent voir/cerner la cause d'un bug tout en se trompant...
2) et je pense que ton wait() est innofensif et que si le son se joue pas sans wait() c'est car tu lui laisse pas le temps de se jouer comme dit ici

http://groups.google.com/group/comp.sys.amiga.programmer/browse_thread/thread/4de468687819bdda/7da2c775ced7128d%3Fhl%3Den%26q%3D%2522josep%2Brubiralta%2522%237da2c775ced7128d&ei=iGwTS6eaOpW8Qpmqic0O&sa=t&ct=res&cd=5&source=groups&usg=AFQjCNF-HrtLu5qpY6Ua6_Di8uVRj52jGA

Donc ou tu attends la fin du son avec un Delay(durée_du_son)
comme ici

http://cd.textfiles.com/amigaformat/aformat-21-199711/-Seriously_Amiga-/Shareware/Sound/IFX/AmigaE/play/play_dt.e


Ou tu mets en place une interruption soft du timer-device qui se déclenchera après durée_du_son et fera les StopSound(); et DeleteSound();
http://amiga.sourceforge.net/amidevhelp/FUNCTIONS/AmigaOS/timer.device/ex03_timer.device.c

Alain

Message édité par : thellier / 03-03-2013 17:33
AmiDARK AmiDARKicon_post
En Fait Thellier, tu n'as "pas" à prendre mal ma question.
Car savoir ce qui bloque ne signifie pas conna?tre la solution pour éviter le blocage ;)

En fait, un gars de amigans (whose) m'a envoyé quelques informations en privé et il préconise l'utilisation de la fonction CheckIO() au lieu du WaitIO() ... C'est un début de solution mais la solution complète nécessitera quelques ajouts dans l'initialisation de l'AmiDARK Engine et, au vu de quelques informations que j'ai eu ... je trouve AHI de plus en plus merdique... Bon malheureusement ... je ne saurais pas faire mieux :(

Le Delay n'est pas utilisable de part la structure de l'AmiDARK Engine
(c'est comme si l'AMOS bloquait lorsque tu joues un son en attendant que le son soit fini ...)
N'oubliez jamais que l'AmiDARK Engine est un peu comme l'AMOS, DarkBASIC Pro, DarkGDK ...

la 2ème solution est intéressante pas ne sera pas nécessaire. Whose a commencé à me donner quelques explications (j'ai du lui fournir tout le principe de fonctionnement de l'AmiDARK Engine (initialisations, !refresh!s, etc.)) pour qu'il puisse m'aider.
Je dois recevoir assez rapidement un autre e-mail de sa part avec plus d'informations.

@+
AmiDARK
Petites Annonces

0 annonce(s) publiée(s)

Consulter

AmigaOS 4.1

Laissez-vous tenter par
AmigaOS 4.1
AmiTheme

AmiTheme