IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Jouer un son contenu dans un TMemoryStream


Sujet :

Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 55
    Points : 63
    Points
    63
    Par défaut Jouer un son contenu dans un TMemoryStream
    Salut à tous,

    Pour la réalisation d'une application je charge un fichier wav dans un MemoryStream. Je souhaite pouvoir jouer le son contenu dans le MemoryStream sans utiliser de composant. Je n'ai rien trouvé ni dans les API, ni de codes me permettant de réaliser une telle opération. Quelqu'un aurait il une solution à me proposer ?

    Merci d'avance

    @+

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 55
    Points : 63
    Points
    63
    Par défaut
    problème résolu

  3. #3
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 54
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Salut
    Excuses moi d'arriver après la bataille, j'étais parti en Week-end, loin de mon PC

    C'est une FAQ qui sera dans la prochaine mise à jour de la FAQ, Celà utilise le principe du fichier wav stocké dans un TMemoryStream


    (ça se trouve, ça peu encore t'aider )

    __________________________________
    Auteur : d'après une idée de Phuphus
    Catégorie : 13.8. Son

    Référence de la source : Ce message posté sur notre Forum

    [QR] Comment Jouer une Note sur la carte son

    Cette procedure permet de jouer une Note de musique en fonction de sa fréquence et de sa durée, non pas sur le speaker interne comme la procedure Windows.Beep(), mais sur la carte son.

    Après avoir donné les propriétés du wav (Dans WaveFormatEx : nombre de voies, fréquence d'échantillonage, bits par échantillon etc.), la structure est écrite dans un MemoryStream qui est ensuite passé en paramètre à sndPlaysound en spécifiant la lecture d'un flux mémoire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    uses
      MMSystem;
     
    type
      TVolumeLevel = 0..127;
     
    procedure MakeSound(Frequency{Hz}, Duration{mSec}: Integer; Volume: TVolumeLevel);
      //écrit la tonalité dans un flux mémoire puis la joue}
    var
      WaveFormatEx: TWaveFormatEx;
      MS: TMemoryStream;
      i, TempInt, DataCount, RiffCount: integer;
      SoundValue: byte;
      w: double; // omega=2*pi*fréquence
    const
      Mono: Word = $0001; //Son Mono
      SampleRate: Integer = 11025; // autres taux d'échantillonnage possibles 8000, 11025, 22050, or 44100
     
      //Champs de l'en-tête d'un fichier .WAV
      RiffId: string = 'RIFF';
      WaveId: string = 'WAVE';
      FmtId: string = 'fmt ';
      DataId: string = 'data';
    begin
      //si la fréquence de la note est trop élevée par rapport au taux d'échantillonnage
      if Frequency > (0.6 * SampleRate) then
      begin
        //... on considère que la note sera injouable.
        ShowMessage(Format('Un taux d''échantillonage de %d est trop bas pour jouer une tonalité de %dHz',
          [SampleRate, Frequency]));
        Exit;
      end;
      with WaveFormatEx do
      begin
       //Paramètres d'un en-tête de fichier WAV au format PCM
        wFormatTag := WAVE_FORMAT_PCM;
        nChannels := Mono;
        nSamplesPerSec := SampleRate;
        wBitsPerSample := $0008;
        nBlockAlign := (nChannels * wBitsPerSample) div 8;
        nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
        cbSize := 0;
      end;
      MS := TMemoryStream.Create;
      with MS do
      begin
        //Calcule la longueur des données du son à jouer et celle du fichier WAV qui en découle
        DataCount := (Duration * SampleRate) div 1000; // sound data
        RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
          SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount; // données du fichier
        //écriture de l'en-tête du fichier WAV dans le flux mémoire
        Write(RiffId[1], 4); // 'RIFF'
        Write(RiffCount, SizeOf(DWORD)); // taille du fichier
        Write(WaveId[1], Length(WaveId)); // 'WAVE'
        Write(FmtId[1], Length(FmtId)); // 'fmt '
        TempInt := SizeOf(TWaveFormatEx);
        Write(TempInt, SizeOf(DWORD)); // taille de TWaveFormat
        Write(WaveFormatEx, SizeOf(TWaveFormatEx)); // taille d'un enregistrement WaveFormatEx
        Write(DataId[1], Length(DataId)); // 'data'
        Write(DataCount, SizeOf(DWORD)); // taille des données du son
        //calcule et écrit le signal sonore
        // calcul des valeurs qui composent le son, 
        // c'est une courbe sinusoïdale dont les valeurs sont comprises entre 0 et 255, 
        //donc l'axe médian de la sinusoïde est en y=127)
        w := 2 * Pi * Frequency; // omega
        for i := 0 to DataCount - 1 do
        begin
          SoundValue := 127 + trunc(Volume * sin(i * w / SampleRate));  // explication : wt = w * i / SampleRate
         //on écrit notre "point" de la courbe dans notre fichier WAV
          Write(SoundValue, SizeOf(Byte));
        end;
        //Maintenant on joue le son en disant à Windows :
        //-SND_MEMORY : c'est un son écrit dans un flux mémoire
        //-SND_SYNC : de jouer le son de façon synchrone (tant que le son n'est pas terminé, le code ne se déroule plus. Ainsi, un deuxième appel consécutif à notre procédure ne "coupera pas le sifflet" du premier appel.
        sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
        MS.Free;
      end;
    end;
    Exemple, un La3 (La 440) qui dure une seconde :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      MakeSound(440, 1000, 60);
    end;
    Petits rappels pratiques :
    Une note de musique est caractérisée par 3 paramètres : sa hauteur, son amplitude et son timbre.
    • la hauteur, ou encore fréquence de la note : plus la fréquence est basse, plus la note sera grave.
      Musicalement, pour augmenter une note d'une octave, il faut multiplier sa fréquence par 2.
    • l'amplitude : C'est la puissance sonore, ou encore plus communément appelé "Volume". Notre fichier WAV n'utilise pas la notion de décibels, mais une valeur comprise entre 0 (silence) et 127 (le plus fort possible).
      Le résultat final en décibels, dépend de la puissance de vos enceintes et du réglage du bouton de volume de ces dernières.
    • Le timbre est le paramètre qui caractérise le son. C'est lui qui permet différencier 2 instruments de musiques différents jouant la même note (une flûte et un piano par exemple, ou plus subtil, un violon "lambda" et un "Stradivarius").
      Il est lié à la forme de notre courbe périodique. Dans notre code, celà se caractérise par le rendu d'une courbe (onde) sinusoïdale. Nous aurions pu ,par exemple, calculer une courbe en triangles, en dents de scie, etc...
    Quelques Fréquences (approximatives) de notes de musique :
    Octave n°3 :
    • Do : 264 Hz
    • Ré : 297 Hz
    • Mi : 330 Hz
    • Fa : 352 Hz
    • Sol : 396 Hz
    • La : 440 Hz (Le LA du diapason)
    • Si : 495 Hz
    • Do4 : 528 Hz
    Pour aller plus loin :

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 55
    Points : 63
    Points
    63
    Par défaut
    Merci à toi

    @+

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 04/07/2007, 19h18
  2. Lire seulement le son contenu dans une AVI
    Par pointer dans le forum Delphi
    Réponses: 4
    Dernier message: 01/02/2007, 12h08
  3. [Debutant]jouer un son midi dans un programme Java
    Par Ghurdyl dans le forum Multimédia
    Réponses: 2
    Dernier message: 14/12/2006, 17h57
  4. Réponses: 5
    Dernier message: 27/05/2006, 12h06
  5. Ouvrir une feuille excel et mettre son contenu dans VB6
    Par bb62 dans le forum VB 6 et antérieur
    Réponses: 18
    Dernier message: 17/01/2006, 09h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo