Sampler de PC Speaker et API

Sampler de PC Speaker et API - C++ - Programmation

Marsh Posté le 03-06-2005 à 11:45:42    

'llo  :hello:  
 
Je débute en C/C++ avec DevC++ sous Win XP et je cherche à transposer un programme je j'avais fait en Pascal avec les plus grands moyens du C/C++ (je ne sais même pas vraiment la différence...) :
 
Le programme était un Sampleur de PC Speaker. Je jouais un truc en transformant mon clavier (d'ordi) en piano, j'appuyais sur Echap, il me l'enregistrait et me le répétais indéfiniment (mais pas très en place, à cause des fonctions de temps pas très précises).
 
En C, j'en suis là : j'ai transformé mon clavier en piano, et j'ai fait la boucle qui va bien. Maintenant, il me manque :
 - Les fonctions de Timer, les fonctions de fichier -> je vais certainement trouver tout seul.
 - La fonction pour faire des Beep à fréquence et longueur voulues : je sais qu'une API Windows dans Kernel32.dll le fait mais comment l'utiliser dans mon prgramme ? Puis-je le faire étant donné que celui-ci est éxécuté dans une console DOS ? (Question con ?)
 
Merci !


Message édité par theredled le 03-06-2005 à 12:18:57
Reply

Marsh Posté le 03-06-2005 à 11:45:42   

Reply

Marsh Posté le 03-06-2005 à 14:07:21    

Je pense pas que le fais d'etre dans une console DOS pose vraiment problème. Surtout sur Windows XP où c'est simplement une console DOS émulée ...
 
Pour les beeps, il me semble que la commande Beep() existe et elle est, apparemment, paramétrable.
 
Une recherche google effectuée en moins de 10 secondes donne des sources qui ont l'air plutot très sympa :  
http://www.codeproject.com/dotnet/A_Simple_Beep.asp
 
Et en 30 secondes, car le site de Microsoft est un peu plus lent, on obtient :
http://msdn.microsoft.com/library/ [...] e/beep.asp


Message édité par Worldofdada le 03-06-2005 à 14:11:22
Reply

Marsh Posté le 03-06-2005 à 19:31:03    

Merci ! En fait j'avais trouvé grâce à une petite recherche de "beep" dans les librairies de DevCpp. En fait c'est super simple d'utiliser les API, j'aurais pas cru, c'est plus simple que VB...
 
Sinon je bloque sur d'autres problèmes :  
 - comment créer un tableau de structures dynamique (pour enregistrer chaques paramètres de chaque son) ? J'ai essayé des trucs avec les pointeurs mais ça ne parait pas très souple...(Dois y avoir des liens je sais...)
 
 - explique moi ta méthode pour trouver en 10 secondes les trucs sur Google paske moi j'arrive moyen pour les trucs de prog...
 
 - En Pascal, rien de plus facile que de faire des fichiers formatés : tu déclare le fichier comme type "File of (type de données)". Ca me parait bien plus compliqué en C... Je voudrait faire un fichier avec des structures... Sans rentrer chaque membre un à un.
 
 :??:


Message édité par theredled le 03-06-2005 à 19:32:07
Reply

Marsh Posté le 05-06-2005 à 18:04:06    

pupupupup

Reply

Marsh Posté le 05-06-2005 à 18:09:35    

moi jme demande sil est toujour possible denvoyer du wave vers le pc speaker comme avant (sous dos). Javais essaye avec lapi Beep et 1ms mais le resultat etait tjs degeu
 
 
jme rappelle du son sous pinball fantasies  :love:

Reply

Marsh Posté le 05-06-2005 à 23:27:21    

 :)   C'est marrant que tu parles de pinball fantaisies j'avais oublié qu'on pouvait aller jusque là sans carte son (d'ailleurs je sais pas comment yzont fait :??: :pt1cable: ).
 
  Avec Beep() tu ne peux pas aller plus loin que le son de 4D Stunts (vous savez, la formule 1 qui fait des cascades de ouf à 20 m du sol ! sur des terrains qu'on peut créer soi-même en plus)
 
  Non le problème de l'API Beep c'est qu'on lui fixe une fréquence et une durée, ce qui limite pas mal. Par exemple tu ne peux pas même pas faire une montée du grave vers l'aigu ("ooouit'" ) par exemple, car entre chaque Beep, il y a une coupure.
  A mon avis les fontions sont toujours là, dans le BIOS notamment mais où ?  
 
  Dans Turbo Pascal il y a(vait ?) trois fonctions "Sound", "Delay", "Nosound" pour faire un beep : déja tu peux faire beaucoup plus de choses qu'avec Beep() : glissé, vibrato etc...
 
  Si quelqu'un est calé en pc speaker...

Reply

Marsh Posté le 06-06-2005 à 14:47:58    

theredled a écrit :

Merci ! En fait j'avais trouvé grâce à une petite recherche de "beep" dans les librairies de DevCpp. En fait c'est super simple d'utiliser les API, j'aurais pas cru, c'est plus simple que VB...
 
Sinon je bloque sur d'autres problèmes :  
 - comment créer un tableau de structures dynamique (pour enregistrer chaques paramètres de chaque son) ? J'ai essayé des trucs avec les pointeurs mais ça ne parait pas très souple...(Dois y avoir des liens je sais...)
 
 - explique moi ta méthode pour trouver en 10 secondes les trucs sur Google paske moi j'arrive moyen pour les trucs de prog...
 
 - En Pascal, rien de plus facile que de faire des fichiers formatés : tu déclare le fichier comme type "File of (type de données)". Ca me parait bien plus compliqué en C... Je voudrait faire un fichier avec des structures... Sans rentrer chaque membre un à un.
 
 :??:


 
Il faut faire une classe ordinaire, par exemple : Note.
La classe Note aura 2 attributs : libelle (pour lui donner un nom a cette note), frequence.
Il me semble idiot de stocker la durée puisque celle ci devrait varier en fonction de ta mélodie.
 
Pour la création de tes notes, pourquoi pas une boucle for qui va incrémenter petit à petit ta fréquence ?
Mais sachant que une note est une note (leur fréquence ne bougera jamais), le mieux est à mon avis de fixer ca en dur dans ton code (dans le constructeur de la classe Note).
 
Pour trouver sur google, y'a pas vraiment de miracle ... je connaissais la fonction beep mais en tappant "cpp sound buzzer" tu devrais trouver des trucs.

Reply

Marsh Posté le 06-06-2005 à 14:51:14    

Hum, j'ai eu une meilleure idée pour la création de tes notes.
 
Etant donné qu'une gamme correspond a une fréquence bien précise et quelle reste la meme quelque soit la note, tu n'a qu'a définir tes 7 notes (Do-Ré-Mi-Fa-Sol-La-Si) + tes 5 "dièses".
 
Tu leur donne une fréquence exacte dans une gamme au pif et t'auras plus qu'a ajouter ou enlever la fréquence correspondant a une gamme

Reply

Marsh Posté le 06-06-2005 à 15:54:49    

si j'en crois l'espacement des fretes du manche de ma guitare, il ne faut pas ajouter/enlever mais plutot multiplier/diviser (c'est pas lineaire)

Reply

Marsh Posté le 06-06-2005 à 16:40:25    

je suis d'accord avec nico168, pour passer d'une octave à une autre il est normalement nécessaire de multiplier ou de diviser la fréquence. Et si je ne m'abuse 2 est le chiffre clé... (à vérifier) car on a bien un la en 440 et 880...
 
Mais ça reste quand même à vérifier... ;)

Reply

Marsh Posté le 06-06-2005 à 16:40:25   

Reply

Marsh Posté le 06-06-2005 à 17:49:23    

Oui, c'est fort possible
 
Etant donné qu'il va falloir faire des recherches de fréquences, tu pourras chercher en meme temps cet harmonique (il me semble que le mot harmonique correspond justement à la fréquence de gamme mais je n'en suis pas sur)

Reply

Marsh Posté le 06-06-2005 à 18:53:43    

pour en revenir a pf c simple ils ont utilise le speaker avec des fct ba nivo (out sur un certain port , me rappelle plus mais je faisais ca avant en asm/c)
 
donc maintenant c cuit a moins qu'une api permette de descendre aussi bas nivo
 
ou alors faut se tapper un driver mais bon ca marchera pa chez tout le monde

Reply

Marsh Posté le 06-06-2005 à 22:46:16    

En fait j'avais déja pas mal avancé dans mon projet...
 
 - Pour les fréquences : la formule est :
   FREQREF*(2 ^ (n/12)) -> n = numéro de la note mesurée en demi-tons (par rapport à FREQREF ; FREQREF = fréquence de la note Zéro (par ex 440 Hz)
 -

Citation :

Il me semble idiot de stocker la durée puisque celle ci devrait varier en fonction de ta mélodie.


   Ben pas tellement puisqu'il faut bien que cette note soit placée dans le temps... en fait ce n'est pas la durée de la note mais la distance t par rapport à la référence t0.
   Moi j'ai fait une structure (ouais je navigue entre C et C++ je sais pas trop), puis un tableau, genre :

Code :
  1. struct elnote
  2. {
  3.   int hauteur;  /* numéro de la note, pas fréquence */
  4.   float tps;  /* par rapport à la 1ere note */
  5. }
  6. struct elnote TableauNotes[200];


Et justement j'aurais aimé que ce tableau soit dynamique parce que c'est un peu moche de mettre un nombre max de notes, et parce que j'aimerais bien savoir le faire.
 
D'ailleurs la version 0.0002 du prog est finite, ya plein de fonctions, si vous voulez tester... ça me ferait bien plaisir  :) ...  :heink: le temps que je trouve comment heberger la chose...
 

Citation :

pour en revenir a pf c simple ils ont utilise le speaker avec des fct ba nivo (out sur un certain port , me rappelle plus mais je faisais ca avant en asm/c)  
 
donc maintenant c cuit a moins qu'une api permette de descendre aussi bas nivo  
 
ou alors faut se tapper un driver mais bon ca marchera pa chez tout le monde


 
pourquoi ça ne marcherait plus aujourd'hui ? L'assembleur est mort ?


Message édité par theredled le 06-06-2005 à 22:47:41
Reply

Marsh Posté le 06-06-2005 à 23:14:56    

disont que sous 9x tu peut pa descendre ba nivo comme ca....
 
tout ce qui est interruption ou acces au ports par exemple c interdit (bon ya tjs moyen (ring 0, driver,...) mais directement comme ca non )

Reply

Marsh Posté le 06-06-2005 à 23:42:56    

Ah ok c'est bien bête ça... Ce serait dur à faire un driver simple comme ça ?
 
Sinon voila mon oeuvre est hébergée exactement ici pour ceux que ça interesse...


Message édité par theredled le 06-06-2005 à 23:44:49
Reply

Marsh Posté le 07-06-2005 à 14:49:34    

Tfaçon toulmonde s'en fiche de mon prog  :(

Reply

Marsh Posté le 07-06-2005 à 16:45:08    

Mais non jdéconne jme vexe pas hein  :)  
 
Des news sur les API du HP ?

Reply

Marsh Posté le 07-06-2005 à 16:50:17    

un truc que je capte pa:
pq tu veux absolument passer par le speaker ??

Reply

Marsh Posté le 07-06-2005 à 18:08:01    

Parce que j'aime bien le son, et à l'origine parce que je codais sous DOS.
Et j'aimerais bien en faire un vrai instru avec de vieux PCs : d'ou aussi le fait que j'aimerais bien piloter le HP en Assembleur.
Ceci dit je pourrais essayer de le faire en Midi ou Wave mais ça me parait un poil plus show, non ?

Reply

Marsh Posté le 07-06-2005 à 18:15:55    

pa vraiment , une fois que ta fait 2 ou trois fct qui vont bien
 
en fait avec Beep ca te genere un son toujour identique a savoir une onde sinusoidale
 
si tu manipule la carte son la tu doit la faire toi mm ce qui nest pas tres complexe. Ce qui est bien c que tu peut faire t propres instruments un peu comme sur un synthe
 
jai un bout de code qui traine chez moi pour faire ca facilement sous win32, des que je rentre jeudi jte le file

Reply

Marsh Posté le 07-06-2005 à 18:24:42    

:love:  tu m'interesse vivement jeudax !
 
J'aimais bien justement le coté rrrooots et sinusoïdal du Spk, maintenant on peut faire du roots sans Spk et un onde triangle c'est pas mal rrrooots aussi  :D


Message édité par theredled le 07-06-2005 à 18:25:45
Reply

Marsh Posté le 07-06-2005 à 18:28:30    

Si tu as le temps de tester mon prog : SAMPLERv02.RAR
C'est valable pour tlm en fait

Reply

Marsh Posté le 07-06-2005 à 20:00:16    

j'aime bien ton sampler !
j'ai pas encore matté la v2 mais sinon, c'est sympa
 
Y'aura moyen de récupérer tes sources une fois terminé pour le passer en graphique ? Ca peut etre rigolo ...

Reply

Marsh Posté le 07-06-2005 à 20:27:57    

J'ai peur pour mes droits d'auteur et j'espère que les modos sont pas corrompus et que le thread restera. :non:   :heink:  
 
Pour le mode graphique, en fait je pense faire une version pour les assistés qu'aiment bien les trucs interfacés, et une version rrroots pour les vrais artistes qu'ont pas bsoin de ça  :o  
Déja je trouve ya déjà trop de texte dans ma console DOS  :o  
Mais faut que j'apprenne à faire des interfaces maintenant :) c'est l'occaz
 
Bon je poste les sources sous peu, si vous pouviez me donner des petits conseils de dev vous qu'êtes des pros...
 
Adresse du site : http://membres.lycos.fr/puddingstud  
 
(c) theredled inc

Reply

Marsh Posté le 08-06-2005 à 14:21:12    

Les sources sont arrivées : http://membres.lycos.fr/puddingstud (je met l'URL du site parce qu'on ne peut pas télécharger sans y passer) -> samplerv02src.rar

Reply

Marsh Posté le 08-06-2005 à 15:13:49    

le lien vers les sources ne semble pas marcher

Reply

Marsh Posté le 08-06-2005 à 16:12:05    

Exact, ça me semble bon à présent.

Reply

Marsh Posté le 08-06-2005 à 17:06:17    

Merci beaucoup

Reply

Marsh Posté le 08-06-2005 à 17:43:22    

J'attends vos comentaires, critiques, suggestions avec impatience  :jap:

Reply

Marsh Posté le 08-06-2005 à 19:19:02    

j'y connais rien du tout en musique, alors j'appuie n'importe où et quand j'appuie vaiment trop ca plante.
mais bon je crois que tu peux rien y faire, c'est le tampon qui est saturé...

Reply

Marsh Posté le 08-06-2005 à 23:32:27    

Ben comme je l'ai dit avant dans le topic, j'aimerais bien rentrer chaque note dans un tableau dynamique, mais comme je sais pas faire, j'ai fait un tableau de 200 éléments... Tu peux compter, 200 notes et :pt1cable: . Mais bon des samples de 200 notes, ça fait déja un peu énorme... oublie pas la touche Echap :sarcastic: c'est le but quand même, toute façon tu va galérer pour jouer la lettre à élise
 
Je peux remplacer 200 par 9000 si vous voulez  :)


Message édité par theredled le 08-06-2005 à 23:33:57
Reply

Marsh Posté le 09-06-2005 à 09:57:08    

Ce qu'il faut faire dans ces cas là, c'est pas bien compliqué ....
 
Il faut allouer dynamiquement la mémoire par tranche fixe.
Je m'explique ...
 
Admettons que tu veuilles allouer la mémoire note par note.
Celà veux dire qu'il faudra rajouter un élément a chaque fois dans ton tableau.
Il me semble qu'il existe des fonctions pour modifier la taille d'un tableau mais on m'a toujours dit de créer un tableau de N+1 élément et ensuite de recopier l'ensemble de ton ancien tableau + la nouvellle note.
Et ensuite écraser l'ancienne variable par la nouvelle N+1.
 
Mais celà est très très lourd si tu fais note par note.
La solution est donc de faire la meme chose mais par tranche de 200 par exemple (c'est peut etre mieux 50 quand meme).
 
Tu alloues dynamiquement, dès le départ, 50 éléments dans ton tableau.
Dès que t'arrive au 51ème élément, tu crées un nouveau tableau de 100 élément dans lequel tu recopies tes 50 premiers + le nouveau. Ce nouveau tableau remplacera l'ancien.
 
Et ainsi de suite ....
 
J'ai été assez clair ?

Reply

Marsh Posté le 09-06-2005 à 10:26:35    

je ne sais pas comment tu fais pour lire les touches(j'ai pas de unrar sous la main pour voir tes sources), mais je te conseil d'utiliser une librairie (par exemple SDL) qui te permet de savoir a tout moment quelle touche est enfoncée ou pas (et ainsi donner la possibilité de faire des accords).
pour se qui est de l'allocation memoire,plutot que de recopier dans un tableau plus grand, je ferais une liste chainée. ou une liste chainée dans les 2 sens si tu veux pouvoir naviguer facilement dans ta "partition"
 
http://www.commentcamarche.net/c/cliste.php3


Message édité par nico168 le 09-06-2005 à 10:32:59
Reply

Marsh Posté le 09-06-2005 à 11:37:35    

Ouais je pensait plutôt aux listes chaînées, quoique ça doit être plus difficile à manipuler qu'un tableau (inverser les valeurs etc...). Je vais m'y mettre mais je suis pas trop pressé pour ça vu que un sample fait rarement 5000 notes, c'est plus pour le principe de savoir comment faire un truc dynamique quoi.
 
Pour ce qui est des touches, j'ai utilisé les kbhit()/getch() de <conio.h>, et ça m'interresse de savoir utiliser d'autres librairies plus évoluées pour le clavier. Mais pour les accord, l'API Beep ne peux pas faire plusieurs notes en même temps. Alors en attendant les codes de red faction...  :D  
 
D'ailleurs on est jeudi, red faction ! (ceci n'est pas un ordre mais mais une manifestation de motivation)

Reply

Marsh Posté le 09-06-2005 à 13:58:11    

la liste chainée est un peu plus complexe a gerer qu'un tableau mais c'est beaucoup plus flexible si tu veux pouvoir faire des manipulations comme inserer ou supprimer une note.
Avec un tableau, t'es obliger de tout décaler, alors qu'avec une liste, tu as juste a manipuler 2 pointeurs.
 
Pour se qui est de la gestion du clavier, sdl me semble pas mal, tu trouveras des infos ici http://gpwiki.org/index.php/C:SDL_ [...] Event_Loop
 
de plus SDL se trouve sur une multitude de plateforme


Message édité par nico168 le 09-06-2005 à 14:00:24
Reply

Marsh Posté le 09-06-2005 à 13:59:31    

puisque tu fais tourner ça sous windows utilise les fonctions fournies par l'API windows : getkeystate...
Parce que kbhit/getch c'est moche et pas normalisé.

Reply

Marsh Posté le 09-06-2005 à 16:05:49    

J'ai été voir sur la MSDN, getKeyState me parait assez différent : comment savoir si une touche (n'importe laquelle) a été appuyée ? Avec GetKeyboardState ? Ca me parait un peu bourrin à faire toutes 10 ms...
J'aime bien kbhit() parcequ'elle permet de savoir si une touche a été appuyée sans se soucier de laquelle... et seulement si kbhit()=true, alors on regarde getch(). Qu'y a-t-il d'autre d'aussi pratique ?

Reply

Marsh Posté le 09-06-2005 à 16:28:30    

Ouais c'est vrai que c'est plus simple d'utiliser les listes chainées ...
 
C'est un peu plus complexe mais en meme temps tellement plus simple   :-D  

Reply

Marsh Posté le 10-06-2005 à 20:07:21    

J'apprends les listes chaînées alors...
 
Mon prog ne sort aucun son sous win98 si ce n'est des beep tardifs et monotone (comme si à chaque appel de Beep() il buggait et donc beepait). Je ne l'ai essayé qu'en EXE. A votre avis d'ou ça peut venir? L'API Beep() est présente dans win98 je crois (KERNEL32.DLL) et le reste n'est pas très compliqué...

Reply

Marsh Posté le 11-06-2005 à 10:52:21    

http://msdn.microsoft.com/library/ [...] e/beep.asp
 

dwFreq  
[in] Frequency of the sound, in hertz. This parameter must be in the range 37 through 32,767 (0x25 through 0x7FFF).  
Windows Me/98/95:  The Beep function ignores this parameter.
dwDuration  
[in] Duration of the sound, in milliseconds.  
Windows Me/98/95:  The Beep function ignores this parameter.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed