お知らせ

電子会議

ライブラリ

パレット

Delphi FAQ検索

Delphi FAQ一覧

サンプル蔵





FDelphi FAQ
16番会議室「玉石混淆みんなで作るSample蔵」に寄せられたサンプル

"WAVファイルの再生>waveOut***関数"



 こんにちは、かぼちゃの馬車です。
    

 APIを使ってWAVファイルの再生するサンプルです。
 過去ログを検索してみたらこの手のサンプルが少ないので発言させていただ
きました。

unit Unit1;

interface

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

const
  HEAP_ZERO_MEMORY = $00000008;
  WM_END_WAVEOUT = WM_USER + 1;

type

  TWavOut = class(TForm)
    OpenDialog1: TOpenDialog;
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button2Click(Sender: TObject);
  private
      Fhmmio: HMMIO;
      FSubchunkSize: DWORD;
      FDataSize:  DWORD;
      FhWavOut: HWAVEOUT;

      FmmckinfoParent: MMCKINFO;
      FmmckinfoSubchunk: MMCKINFO;

      FpWavEhdr: PWAVEHDR;
      FpSubchunk: pChar;
      FpData: pChar;
     // FWaveFmt: tWAVEFORMATEX;  //データ情報

    function LoadFromFile(Const FileName: String): Boolean;
    procedure FileWaveOut;
    procedure HeapFreeProc;
    procedure CloseWaveOut;
    procedure WMEndWaveout(var Msg: TMessage); Message WM_END_WAVEOUT;
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  WavOut: TWavOut;

implementation

{$R *.DFM}

//  WAVEOUT デバイスが投げるメッセージへのハンドラ
//  このハンドラ内では使用できる関数が限られる。
// WAVEの再生状況を受け取るコールバック関数
procedure waveOutProc( hwo: HWAVEOUT; uMsg: UINT; dwInstance,
dwParam1, dwParam2: DWORD); stdcall;
begin
   //このコールバック関数はあまりにも単純なのでアプリにあわせた改良
   //を する必要がある。

   if uMsg = WOM_DONE then
      PostMessage(WavOut.Handle, WM_END_WAVEOUT , 0, dwParam1);
end;

procedure TWavOut.WMEndWaveout(var Msg: TMessage);
begin
   CloseWaveOut;
   ShowMessage('再生終了');
end;

//再生する
procedure TWavOut.FileWaveOut;
var
   mmres: MMRESULT;
begin
// mmres := waveOutOpen(@FhWavOut, WAVE_MAPPER, PWaveFormatEx
(FpSubchunk),
DWORD(Handle), 0, CALLBACK_WINDOW);
   mmres := waveOutOpen(@FhWavOut, WAVE_MAPPER, PWaveFormatEx
(FpSubchunk),
   DWORD(@waveOutProc), 0, CALLBACK_FUNCTION);
   if mmres <> MMSYSERR_NOERROR then
   begin
      HeapFree(GetProcessHeap, 0, FpSubchunk);
      HeapFree(GetProcessHeap, 0, FpData);
      MessageDlg('ERROR "waveOutOpen" ', mtError, [mbOK], 0);
      Exit;
   end;

   // WAVEHDRバッファの割り当て
   FpWavEhdr := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, SizeOf
(WAVEHDR));

  FpWavEhdr.lpData := FpData;
  FpWavEhdr.dwBufferLength := FDataSize;
  FpWavEhdr.dwFlags := 0;
  FpWavEhdr.dwLoops := 0;

  waveOutPrepareHeader(FhWavOut, FpWavEhdr, SizeOf(WAVEHDR));
  waveOutWrite(FhWavOut, FpWavEhdr, SizeOf(WAVEHDR));
  waveOutUnPrepareHeader(FhWavOut, FpWavEhdr, SizeOf(WAVEHDR));

//WAVEデバイスを閉じる
//   CloseWaveOut;
end;

//WAVEデバイスを閉じる
procedure TWavOut.CloseWaveOut;
Begin
   waveOutReset(FhWavOut);
   waveOutUnprepareHeader(FhWavOut, FpWavEhdr, SizeOf(WAVEHDR));
   waveOutClose(FhWavOut);
end;

procedure TWavOut.HeapFreeProc;
begin
   //メモリの開放
   if FpSubchunk <> nil then
   Begin
//   ShowMessage('FpSubchunk HeapFree');
      HeapFree(GetProcessHeap, 0, FpSubchunk);
   end;
  if FpData <> nil then
   Begin
//   ShowMessage('FpData HeapFree');
      HeapFree(GetProcessHeap, 0, FpData);
end;

  if FpWavEhdr <> nil then
  Begin
 //  ShowMessage('FpWavEhdr HeapFree');
      HeapFree(GetProcessHeap, 0, FpWavEhdr);
   end;
end;

procedure TWavOut.Button1Click(Sender: TObject);
begin
   if OpenDialog1.Execute then
      if LoadFromFile(OpenDialog1.FileName) then
         FileWaveOut;
end;

procedure TWavOut.FormCloseQuery(Sender: TObject; var CanClose:
Boolean);
begin
   HeapFreeProc; //メモリの開放
end;

function TWavOut.LoadFromFile(Const FileName: String): Boolean;
var
   mmres: MMRESULT;
begin
   Result := true;

  Fhmmio := mmioOpen(PChar(FileName), nil, MMIO_READ);
  if Fhmmio = 0 then
   begin
      MessageDlg('ERROR "not WAVEFile Open"',mtError, [mbOK], 0);
      Result := False;
      Exit;
  end;

  // ファイル先頭へシーク
  mmioSeek(Fhmmio, 0, SEEK_SET);
  FmmckinfoParent.fccType := mmioStringToFOURCC(PChar('WAVE'), 0);
  mmres := mmioDescend(Fhmmio, @FmmckinfoParent, nil, MMIO_FINDRIFF);
  if mmres <> MMSYSERR_NOERROR then
  begin
      MessageDlg('ERROR! "not WAVE format" ', mtError, [mbOK], 0);
      Result := False;
      Exit;
  end;

  // fmtチャンク
  FmmckinfoSubchunk.ckid := mmioStringToFOURCC(PChar('fmt '), 0);
  mmres := mmioDescend(Fhmmio, @FmmckinfoSubchunk, @FmmckinfoParent,
MMIO_FINDCHUNK);
  if mmres <> MMSYSERR_NOERROR then
  begin
      MessageDlg('ERROR! "not fmt format" ', mtError, [mbOK], 0);
      Result := False;
      Exit;
  end;

  FSubchunkSize := FmmckinfoSubchunk.cksize;
  FpSubchunk := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY,
FSubchunkSize);
  if (mmioRead(Fhmmio, FpSubchunk, FSubchunkSize) <> LongInt
(FSubchunkSize)) then
  begin
      MessageDlg('ERROR! "Reading fmt chunk" ', mtError, [mbOK], 0);
      Result := False;
      HeapFree(GetProcessHeap, 0, FpSubchunk);
      Exit;
  end;

  mmioAscend(Fhmmio, @FmmckinfoSubchunk, 0);
  // dataチャンク
  FmmckinfoSubchunk.ckid := mmioStringToFOURCC(PChar('data'), 0);
  mmres := mmioDescend(Fhmmio, @FmmckinfoSubchunk, @FmmckinfoParent,
MMIO_FINDCHUNK);
  if mmres <> MMSYSERR_NOERROR then
  begin
      MessageDlg('ERROR "not data format" ', mtError, [mbOK], 0);
      Result := False;
      HeapFree(GetProcessHeap, 0, FpSubchunk);
      Exit;
  end;

  // dataチャンク用のバッファの割り当て
  FDataSize := FmmckinfoSubchunk.cksize;
  FpData := HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, FDataSize);
  if (mmioRead(Fhmmio, FpData, FDataSize) <> LongInt(FDataSize)) then
  begin
      MessageDlg('ERROR! "Reading data chunk" ', mtError, [mbOK], 0);
      Result := False;
      HeapFree(GetProcessHeap, 0, FpSubchunk);
      HeapFree(GetProcessHeap, 0, FpData);
      Exit;
  end;

  // WAVファイルのクローズ
  mmioClose(Fhmmio, 0);
end;

procedure TWavOut.Button2Click(Sender: TObject);
begin
   FileWaveOut;
end;

end.
                         By かぼちゃの馬車

Original document by かぼちゃの馬車  氏 ID:(MXF01374)


ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum の16番会議室「玉石混淆みんなで作るSample蔵」に投稿されたサンプルです。これらのサンプルはボーランド株式会社がサポートする公式のものではありません。また、必ずしも動作が検証されているものではありません。これらのサンプルを使用したことに起因するいかなる損害も投稿者、およびフォーラムスタッフはその責めを負いません。使用者のリスクの範疇でご使用下さい。

Copyright 1996-2002 Delphi Users' Forum