Générer un son à la volée

Description

J'ai adapté différents bouts de codes trouvés ça et là sur la toile afin de pondre un petit programme qui génère un simple LA à 440 Hz. C'est la note de référence du diapason. Mon but était aussi de comprendre comment générer différentes formes d'ondes de bases, à la volée, sans utiliser aucun fichier de data préformaté. Le programme peut donc jouer les 4 types de courbes classiques : sinusoïde, carré, triangle et dent de scie. Le tout réalisé sous Turbo Delphi 2006 Explorer Edition sans aucun composant additionnel et aucune DLL externe. Le code doit pouvoir être compilé sous la plupart des versions de Delphi étant donné que je n'utilise que des bibliothèques standards.

Source / Exemple :


procedure TFRMMain.MakeSound(Waveform, Frequency, Duration: Integer; Volume: Integer);
var
  WaveFormatEx: TWaveFormatEx;
  MS: TMemoryStream;
  i, TempInt, DataCount, RiffCount: integer;
  SoundValue: byte;
  t: double;
const
  Mono: Word = $0001;
  SampleRate: Integer = 44100;
  RiffId: string = 'RIFF';
  WaveId: string = 'WAVE';
  FmtId: string = 'fmt ';
  DataId: string = 'data';
begin
  with WaveFormatEx do
  begin
    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
    DataCount := (Duration * SampleRate) div 1000;
    RiffCount := Length(WaveId) + Length(FmtId) + SizeOf(DWORD) +
    SizeOf(TWaveFormatEx) + Length(DataId) + SizeOf(DWORD) + DataCount;

    Write(RiffId[1], 4);
    Write(RiffCount, SizeOf(DWORD));
    Write(WaveId[1], Length(WaveId));
    Write(FmtId[1], Length(FmtId));

    TempInt := SizeOf(TWaveFormatEx);

    Write(TempInt, SizeOf(DWORD));
    Write(WaveFormatEx, SizeOf(TWaveFormatEx));
    Write(DataId[1], Length(DataId));
    Write(DataCount, SizeOf(DWORD));

    for i := 0 to DataCount - 1 do
    begin
      t := (i * Frequency / SampleRate);

      //sinusoide
      if (Waveform = 1) then SoundValue := 127 + trunc(Volume * sin(2 * pi * t));
      //carre
      if (Waveform = 2) then SoundValue := 127 + trunc(Volume * sign(sin(2 * pi * t)));
      //triangle
      if (Waveform = 3)  then SoundValue := 127 + trunc(Volume * (2 * abs(2 * t - 2 * floor(t) - 1 ) - 1));
      //dent de scie
      if (Waveform = 4)  then SoundValue := 127 + trunc(Volume * (2 * (t - floor(t + 0.5))));

      Write(SoundValue, SizeOf(Byte));
    end;

    sndPlaySound(MS.Memory, SND_MEMORY or SND_SYNC);
    MS.Free;
  end;
end;

Conclusion :


J'espère que ce modeste code source, aussi minimaliste soit-il, pourra servir de base à d'autres qu'à moi-même pour la réalisation de programmes sonores un peu plus évolués...

Codes Sources

A voir également

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.