Morse pour MacOS

CeetixCeetix Membre
février 2009 modifié dans Vos applications #1
Bonsoir bonsoir !

Je vous présente une petite application que je dois réaliser pour mon école et à  rendre en juin. Notre groupe devait réaliser une application permettant de coder du texte en morse et vice-vers-ca. On peut écrire directement ou charger un fichier .txt.
Je vous laisse découvrir l'application et me donner vos idées et/ou commentaires pour améliorer. Je planche déjà  sur le problème des bips que l'on ne peut pas arrêter en cours :) .

Si vous voulez en voir un peu plus sur le projet : Le site du projet .

L'application Morse

Merci !  ;)

p.s: oui le morse est mort mais c'est le sujet proposé ^^
«1

Réponses

  • tabliertablier Membre
    20:26 modifié #2
    non, je pense que le morse n'est pas mort, même s'il n'est plus couramment utilisé à  ce jour.
    C'est un moyen de transmission qui passe dans les pires conditions atmosphériques et qui n'a besoin que d'un émetteur radio très simple avec une modulation des plus sommaire!
    Bon, j'ai jeté un oe“il au programme et au projet.
    Le projet, tel qu'il est décrit sur le site n'indique pas les formes de réception/émission du morse: audio? texte en point tiret? autre?
    Pour le programme lui-même, je trouve les '/' peu adaptés à  la séparation des caractères: trop d'impact visuel. Je pense qu'il faudrait permettre de régler la taille des caractères dans la fenêtre du morse car les points traits sont vraiment petits.
    Sur mon G4, le clic sur "BIP" bloque le programme et ne sort aucun son.

    Et je signe:  _  ._  _...  ._..  ..  .  ._.
  • CeetixCeetix Membre
    20:26 modifié #3
    Merci pour ces remontées Tablier.
    Je vais essayer mettre l'espace alors plutôt que des /  et une option d'affichage.
    Pour les sons, j'ai des soucis, en effet ca bloque bien le programme. Par contre les sons marchent normalement.
  • CeetixCeetix Membre
    20:26 modifié #4
    Je viens d'y repenser mais si les / disparaissent, comment apres savoir si je suis a la fin d'un mot pour la traduction inverse?
  • tabliertablier Membre
    20:26 modifié #5
    Tu pourrais séparer chaque caractère par un espace et ne mettre un '/' qu'entre les mots (par exemple).
    Regarde cette adresse: http://radioamateur.f1rfn.online.fr/jcm_divers3.htm#%A74cm

    Tablier et ceetix  s'écrirait:
    _ ._ _... ._.. .. . ._. / . _ / _._. . . _ .. _.._

    Une autre solution serait de créer une fonte spécifique (à  largeur variable) et de ne mettre un espace qu'entre les mots. Je sais que cela s'est déjà  fait, mais je ne trouve plus ou !

    je te confirme que sur mon PowerBook G4 je n'ai aucun son.
  • CeetixCeetix Membre
    20:26 modifié #6
    En effet pas con ^^.
    Je le ferai dans les jours à  venir car on a une reunion avec notre prof suiveur demain et j'ai pas envie de refaire iphone,mac, C# et flash:) mais c'est clair que c'est mieux.
    Apres pour le son c'est bizar, ce sont des .aif mais normalement quand on release ça met tout dedans non?

    Sinon pour améliorer le truc, apres le code par souris on pensait faire avec juste la touche espace en fonction du temps d'appuie sur celle-ci.
  • schlumschlum Membre
    20:26 modifié #7
    dans 1233776522:

    Tu pourrais séparer chaque caractère par un espace et ne mettre un '/' qu'entre les mots (par exemple).
    Regarde cette adresse: http://radioamateur.f1rfn.online.fr/jcm_divers3.htm#%A74cm

    Tablier et ceetix   s'écrirait:
    _ ._ _... ._.. .. . ._. / . _ / _._. . . _ .. _.._

    Une autre solution serait de créer une fonte spécifique (à  largeur variable) et de ne mettre un espace qu'entre les mots. Je sais que cela s'est déjà  fait, mais je ne trouve plus ou !

    je te confirme que sur mon PowerBook G4 je n'ai aucun son.


    C'est peu lisible comme ça... En général on utilise plutôt un "/" entre les lettres et deux "//" entre les mots.
  • CeetixCeetix Membre
    20:26 modifié #8
    eh bien là  j'utilise le / pour fin de lettre et le caractere espace _/   
    s o s donne : .../_/---/_/.../
  • tabliertablier Membre
    20:26 modifié #9
    Oui, c'est ce qui est préconisé sur certain site. Je n'aime pas vraiment car en écoute de traffic réel, il n'y a pas réellement d'interruption entre les caractères et bien souvent pas entre les mots (ou très très faible). Enfin, il y a 45 ans que je n'en ai pas fait!!
    Pou info, si cela n'a pas changé, le SOS se lance en continu et sans interruption, c'est à  dire que l'on envoie:  SOSOSOSOSOSOSOSO..........san fin car ça urge!
    ce qui à  l'oreille fait ti ti ti ta ta ta ti ti ti ta ta ta ti ti ti ta ta ta ..... etc

    Pour la fonte que je préconisais, comme les caractères peuvent être de n'importe quelle largeur il suffit d'ajouter un / ou un | à  la fin du dessin de chaque caractère et le tour est joué. Il reste à  ajouter un  / ou un | supplémentaire entre chaque mot. J'ai essayer de faire des caractères avec FonteForge et InkScape. Assez facile et surtout gratuit!

    Tablier et ceetix  s'écrirait alors:
    _/._/_.../._../.././._.//./_ //_._./././_/../_.._//
    ou bien
    _|._|_...|._..|..|.|._.||.|_||_._.|.|.|_|..|_.._||  ce que je préferrai presque!
  • CeetixCeetix Membre
    20:26 modifié #10
    J'avoue que la barre c'est pas mal du tout. PAr contre j'ai pas trop compris ton histoire de FontForge et InkScape, je connais pas :( .
  • tabliertablier Membre
    20:26 modifié #11
    Inkscape est un logiciel de dessin vectoriel de bon niveau (libre et en +sieurs langues).
    télécharger à : http://tavmjong.free.fr/INKSCAPE/
    FonteForge est un éditeur de fontes de bon niveau et libre également.
    télécharger à : http://fontforge.sourceforge.net/

    Dans le tutorial de FonteForge tout les explications existent pour le création de fontes ou pour  la re-édition de fontes existantes.
    Pour essai, jai créé une nouvelle fonte, dessiné un caractère Morse dans Inkscape et introduit ce caractère dans la fonte. La seule précaution que j'ai pris est d'avoir créé un dessin-modèle séparé qui ne contient qu'un point, un trait, et une barre de séparation. Pour chaque caractère morse, je crée un nouveau dessin et je Copie/colle les points/traits depuis le modèle ce qui me gagne du temps car cela m'évite de re-dessiné.

    Mon avis: Ces programmes sont bons, avec comme bémol qu'ils ne sont pas nativement Mac et que les Aides ne sont pas incluses dans les logiciels (donc pour lire les explications il faut être connecté. C'est correct pour un poste fixe, pas pour un mobile)
  • CeetixCeetix Membre
    20:26 modifié #12
    ok je vais voir ca alors. Merci pour ces explications. Piouf j'ai du boulot ^^
  • tabliertablier Membre
    20:26 modifié #13
    Il y a longtemps (~ 40 ans) que je n'ai plus transmis du morse. De ce que je me souviens, le manipulateur (ou le vibro) doit être solide, car il faut utiliser pas mal de force pour accélèrer la cadence au delà  de 30 mots/minute. J'ai des doutes quand à  l'utilisation de la touche espace pour cela. Je pense que la solution est d'utiliser un vrai manipulateur que tu branches en parallèle sur un des contact d'une souris USB.
    En ce qui concerne la fonte "morse", j'en ai fait une "pour voir". Voir le dossier joint et les explications à  l'intérieur. Après installation (livre des polices), ça marche assez bien dans TextEdit.
  • CeetixCeetix Membre
    20:26 modifié #14
    Hello !

    Bon je j'up ce post car je m'arrache les cheveux sur un bug de mon application, à  savoir jouer des bips.
    En effet j'émets  des sons plus ou moin long en fonction du code.
    Le problème c'est que quand je commence à  jouer je suis obligé d'attendre la fin pour que mon programme réponde enfin à  mes actions. Or j'aimerai mettre une action stop, qui stop les sons en pleine lecture.
    Je n'y arrive pas.

    Voici mon code :

    Classe SoundEffect

    .h

    <br />#import &lt;Cocoa/Cocoa.h&gt;<br />#import &lt;AudioToolbox/AudioServices.h&gt;<br /><br />@interface SoundEffect : NSObject {<br />	<br />	SystemSoundID soundID;<br />	<br />}<br /><br />-(void)play;<br />- (id)initWithContentsOfFile:(NSString *)path;<br />@end<br />
    


    .m

    <br />#import &quot;SoundEffect.h&quot;<br /><br /><br />@implementation SoundEffect<br /><br />- (id)initWithContentsOfFile:(NSString *)path <br />{<br />	self = [super init];<br />	if (self != nil) {<br />		NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];<br />		AudioServicesCreateSystemSoundID((CFURLRef)filePath, &amp;soundID);<br />	}<br />	return self;<br />}<br />-(void)play {<br />	<br />	AudioServicesPlaySystemSound(soundID);<br />}<br /><br />@end<br />
    


    Classe où j'utilise les sons avec le code

    .h

    <br />#import &lt;Cocoa/Cocoa.h&gt;<br />#import &lt;QuartzCore/QuartzCore.h&gt;<br /><br />@class SoundEffect;<br /><br />@interface Foo : NSObject {<br />	SoundEffect *soundEffect;<br />	SoundEffect *soundEffect2;<br />	<br />	NSString *traduc;<br />}<br /><br />-(IBAction)beep:(id)sender;<br /><br />@end<br />
    


    .m

    <br />-(IBAction)beep:(id)sender<br />{<br />	<br />	int x,i;	<br />	x = traduc.length;&nbsp; // ma chaine de code<br />	<br />	for(i=0 ; i&lt;x; i++)<br />	{<br />		if(i == 0)<br />		{<br />			<br />			<br />		}<br />		<br />		if([traduc characterAtIndex:i] == &#39;.&#39;)<br />		{<br />			[soundEffect play];<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.9]];<br />		}<br />		else if([traduc characterAtIndex:i] == &#39;-&#39;)<br />		{<br />			[soundEffect2 play];<br />			<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.1]];<br />		}<br />		else if(i == (x-1)) // Pour ne pas cumuler deux animations longue en fin de chaine (x-i) et revenir directement à  l&#39;application<br />		{<br />		}<br />		<br />		else if([traduc characterAtIndex:i] == &#39;/&#39;) // Espace entre lettre, n&#39;affiche rien.<br />		{<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.7]];<br />		}<br />	<br />	}<br />	<br />}<br />
    



    J'aimerai qu'en appuyant sur un bouton "Stop" tout s'arrête ...

    Merci pour votre aide !
  • schlumschlum Membre
    20:26 modifié #15
    Threads...
  • CeetixCeetix Membre
    20:26 modifié #16
    Oui je me doutais très fortement que le problème venait d'ici surtout avec "sleepUntilDate" mais je vois pas (bien qu'il y en ai une) les autres manières ... :(
  • CeetixCeetix Membre
    20:26 modifié #17
    personne?
  • CeetixCeetix Membre
    20:26 modifié #18
    Bon j'ai repris mon code. Je ne me sert plus de la classe SoundEffect.
    Juste de ma classe principale.

    .h

    #import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface maClass : NSObject {<br />	NSSound *sound1;<br />	NSSound *sound2;<br />	<br />	NSString *maChaine;<br />}<br />- (IBAction)play:(id)sender;<br />- (IBAction)stop:(id)sender;<br />@end
    


    .m

    #import &quot;maClass.h&quot;<br />@implementation maClass<br /><br />- (IBAction)play:(id)sender {<br />	<br />	<br />	int x,i;	<br />	x = maChaine.length;&nbsp; // ma chaine de code<br />	<br />	for(i=0 ; i&lt;x; i++)<br />	{<br />		if(i == 0)<br />		{<br />		}<br />		if([maChaine characterAtIndex:i] == &#39;.&#39;)<br />		{<br />			[sound1 play];<br />		}<br />		else if([maChaine characterAtIndex:i] == &#39;-&#39;)<br />		{<br />			[sound2 play];<br />		}<br />		else if(i == (x-1)) // Pour ne pas cumuler deux animations longue en fin de chaine (x-i) et revenir directement à  l&#39;application<br />		{<br />		}<br />		<br />		else if([maChaine characterAtIndex:i] == &#39;/&#39;) // Espace entre lettre, n&#39;affiche rien.<br />		{<br />			//Attente ....<br />		}<br />		<br />	}<br /><br />}<br /><br />- (IBAction)stop:(id)sender {<br />	[sound1 stop];<br />	[sound2 stop];<br />}<br /><br /><br />-(void)awakeFromNib{<br />	NSBundle *mainBundle = [NSBundle mainBundle];<br />	maChaine = @&quot;.-../&quot;;<br />	sound1 = [[NSSound alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;court&quot; ofType:@&quot;aif&quot;] byReference:YES];<br />	sound2 = [[NSSound alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;long&quot; ofType:@&quot;aif&quot;] byReference:YES];<br />}<br />@end<br />
    


    J'arrive donc bien à  stopper les sons quand j'appuis sur mon bouton "stop" mais les sons se jouent trop rapidement ce qui fait qu'on n'entend que le dernier. J'aimerai entendre chaque son et qu'une fois que celui-ci à  fini de se jouer, le suivant se joue etc... Il faut passer par un NSTimer non? Mais je vois pas comment agencer tout ça.
    :(
  • schlumschlum Membre
    20:26 modifié #19
    ça voulait dire qu'il faut que tu crées un autre thread.
  • CeetixCeetix Membre
    20:26 modifié #20
    Le truc c'est que je vois pas trop ce que c'est un thread.
  • schlumschlum Membre
    20:26 modifié #21
    Un peu ennuyeux pour un programmeur  :P

    Un peu de lecture...
    http://developer.apple.com/DOCUMENTATION/Cocoa/Conceptual/CocoaFundamentals/AddingBehaviortoaCocoaProgram/chapter_4_section_6.html

    " Cocoa par la pratique ", ça pourrait être un bon investissement aussi pour apprendre comment la mémoire et les threads fonctionnent  ;)
  • schlumschlum Membre
    20:26 modifié #22
    Sinon, en gros un thread c'est quelque chose qui permet d'exécuter deux choses à  la fois, donc par exemple une lecture de son sans bloquer l'interface.
    C'est un truc génial mais qui a pas mal de contraintes au niveau de la gestion de la mémoire, donc il faut connaà®tre tout ça sur le bout des doigts (NSThread, NSLock, @synchronized...)
  • CeetixCeetix Membre
    20:26 modifié #23
    disons qu'en cours on code en C et qu'on a pas vu ça. Après je fais ça plutot en "hobby" donc doucement mais surement ^^. avec la pratique ca va venir (j'espere).
    Je vais regarder ta doc mais il n'y a pas un moyen de faire avec un NSTimer?

    EDIT : Merci pour ton explication, hum sur le bout des doigts ... c'est pas gagné.
  • schlumschlum Membre
    20:26 modifié #24
    Ce qu'il faut connaà®tre sur le bout des doigts, ce sont surtout les risques, sinon on s'expose à  des plantages quasi-inexplicables ou des bugs qu'on met des heures à  comprendre.

    Avec Cocoa par exemple, il faut savoir que certains Frameworks ne supportent pas le multithreading (QuickTime par exemple), et que tout ce qui est graphique doit être fait dans le thread principal ("- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait")
  • CeetixCeetix Membre
    20:26 modifié #25
    Merci pour tes indications. Je vois tjs pas comment faire pour ne pas bloquer mon interface en utilisant un thread.
  • schlumschlum Membre
    20:26 modifié #26
    dans 1236690490:

    Merci pour tes indications. Je vois tjs pas comment faire pour ne pas bloquer mon interface en utilisant un thread.


    http://www.projectomega.org/article.php?lg=fr&php=oreilly_cocoa17&p=1

    Je te conseille ce tuto... La page 5 présente une solution de multi-threading.
    (d'ailleurs, il risque de te dire quelque chose  :P)
  • CeetixCeetix Membre
    20:26 modifié #27
    Lol pour les animation en effet ça me dit bien un truc  ::) .
    J'ai essayé de mettre en action les explications de ProjetOmega (je le pensais fermé) mais je suis tjs bloqué lol. Je suis chauve maintenant .
  • CeetixCeetix Membre
    mars 2009 modifié #28
    Mes cheveux commencent à  repousser.
    J'ai reussi a lire mes sons sans bloqué l'interface, maintenant je peux cliquer sur les boutons environnant ^^.
    Par contre quand je veux stoper ca ne marche pas.

    -(void)beep<br />{<br />	<br />	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];<br /><br />	int x,i;	<br />	x = maChaine.length;&nbsp; // ma chaine de code<br />	<br />	for(i=0 ; i&lt;x; i++)<br />	{<br />		if(i == 0)<br />		{<br />		}<br />		if([maChaine characterAtIndex:i] == &#39;.&#39;)<br />		{<br />			[sound1 play];<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.9]];<br /><br />		}<br />		else if([maChaine characterAtIndex:i] == &#39;-&#39;)<br />		{<br />			[sound2 play];<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.1]];<br /><br /><br />		}<br />		else if(i == (x-1)) // Pour ne pas cumuler deux animations longue en fin de chaine (x-i) et revenir directement à  l&#39;application<br />		{<br />		}<br />		<br />		else if([maChaine characterAtIndex:i] == &#39;/&#39;) // Espace entre lettre, n&#39;affiche rien.<br />		{<br />			[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.7]];<br /><br /><br />			//Attente ....<br />		}<br />		<br />	}<br /><br />	[pool release];<br />	<br />	<br />}<br /><br />- (IBAction)play:(id)sender {<br />	[NSThread detachNewThreadSelector:@selector(beep) toTarget:self withObject:nil];<br />	}<br /><br />- (IBAction)stop:(id)sender {<br />	[sound1 stop];<br />	[sound2 stop];<br />}<br /><br /><br />-(void)awakeFromNib{<br />	NSBundle *mainBundle = [NSBundle mainBundle];<br />	maChaine = @&quot;.-../&quot;;<br />	sound1 = [[NSSound alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;court&quot; ofType:@&quot;aif&quot;] byReference:YES];<br />	sound2 = [[NSSound alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;long&quot; ofType:@&quot;aif&quot;] byReference:YES];<br />}
    


    Tu aurais un idée?
    J'ai essayé [NSTread exit] mais ca fait planter...
    Sinon mon stop coupe bien le son en train de se jouer mais pas les suivants...

    EDIT : en mettnt une variable global BOOL etat. Quand je clique sur play etat = YES; et stop etat = NO; et un if dans ma fonction beep qui regarde etat. Ca peut le faire non?
  • schlumschlum Membre
    20:26 modifié #29
    Héhé, c'est là  qu'il faut commencer à  voir la communication entre threads...
    Il te faut une variable partagée "stop" qui dans le thread "beep" sort de la boucle si elle est à  true, et qui dans le thread "principal" devient true quand on appuie sur le bouton "stop".

    Si c'est juste un booléen (donc une variable scalaire), toute action dessus est appelée "atomique", et donc on n'a pas à  se soucier des problèmes de "thread-safe" avec.
  • CeetixCeetix Membre
    20:26 modifié #30
    Je viens justement de le faire ^^. Mais pas de changements  ???

    dans mon .h j'ai :

    BOOL etat;

    @property(nonatomic,assign)BOOL etat


    et dans mon .m
    je synthetize,
    quand je clique sur stop je met etat à  NO.
    Dans ma fonction beep

    if(etat == YES) je joue ma fonction sinon je fais rien.
    Et je reste au meme stade, comme si mon état n'était pas lu.
  • schlumschlum Membre
    20:26 modifié #31
    Mais ce "if(etat == YES)", il est dans la boucle ?
    Tu l'as fait afficher à  chaque passage pour voir ?
Connectez-vous ou Inscrivez-vous pour répondre.