PlaySound - tocando sons da memória
Como carregar arquivos wav e tocá-los repetidamente

Na matéria “Usando sons em jogos Delphi” mostramos as duas formas clássicas de executar arquivos wav, em um programa ou jogo. Agora iremos ilustrar uma outra alternativa, em função de situações específicas como o caso dos sons repetidos.

Determinados tipos de sons, como os clicks das teclas, bips, poings, etc, são usados com uma freqüência nos jogos tal que o carregamento (load) do arquivo, a cada execução, pode tornar-se proibitivo e influir, por exemplo, nas animações. Então, a saída mais óbvia seria carregar e manter esses sons na memória.

A primeira coisa a fazer é incluir a declaração MMSystem, na seção uses inicial:

uses
  Windows, Messages, SysUtils, Classes, Graphics,
  Controls, Forms, Dialogs, MMSystem;

Usamos o formato Stream para carregar o arquivo wave para a memória, criando uma função para executar esta operação:

function AbrirSom(Arq: string): pointer;
var
  Str: TFileStream;
begin
  Str:= TFileStream.create(Arq,
  fmOpenRead or fmShareDenyNone);
  Str.position:= 0;
  GetMem(result, Str.size); //pega a memória
  Str.Read(result^, Str.size);
  Str.free;
end;

Criamos em seguida uma procedure para executar o tal som, sempre que desejarmos:

procedure TocarSom(Som: pointer;
  Loop: boolean = false; Async: boolean = true);
var
  Ops: cardinal;
begin
  Ops:= SND_MEMORY;
  if Loop then Ops:= Ops + SND_LOOP;
  if Async then Ops:= Ops + SND_ASYNC;
  PlaySound(Som, 0, Ops);
end;

Uma procedure para interromper a execução do som, caso isso seja necessário:

procedure PararSom;
begin
  PlaySound(nil, 0, SND_PURGE);
end;

E uma última procedure para remover o som da memória:

procedure FecharSom(var Som: pointer);
begin
  if Som <> nil then FreeMem(Som);
  Som:= nil;
end;

Para executar waves em nossos jogos, a seqüência é simples: abrir o som, executá-lo e liberar a memória usada. Podemos inserir a abertura dos sons no evento OnCreate do Form1 e a liberação da memória no evento OnDestroy, criando uma variável (ou variáveis) global do tipo pointer, para cada arquivo a ser executado:

var
  Form1: TForm1;
  Som: pointer;

Como exemplo, vamos carregar um som para a memória e executá-lo sempre que o usuário clicar em qualquer parte do form1. Enquanto mantiver o botão do mouse clicado, o som é executado. Ao soltar o botão, o som é interrompido:

procedure TForm1.FormCreate(Sender: TObject);
begin
  Som1:= AbrirSom('teste.wav');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FecharSom(Som1);
end;

procedure TForm1.FormMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  TocarSom(Som1, true, true);
end;

procedure TForm1.FormMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState;
  X, Y: Integer);
begin
  PararSom;
end;

Agora é usar e abusar desses recursos...

Qualquer dúvida quanto aos fontes, baixe o pacote zipado no link abaixo e bons estudos.


Download...
Clique no link para fazer o download dos arquivos. Se sua assinatura está para terminar, clique aqui e saiba como renová-la.

Fontes do exemplo
 
online