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...
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.