这个组件源码。
//waveComp.pas
unit WaveComp;interfaceuses Windows, Messages, Classes, SysUtils, Controls, MMSystem, WaveConsts;type
  TWave = class;
  
  TWaveFileStream = class(TObject)
  private
    FReadEof: Boolean;
    FFormat: TWaveFormatEx;
    FStream: TFileStream;
    FDataPosition: Integer;
    FReadPos: Integer;
    FWritePos: Integer;
    FFileName: string;
    FOwner: TWave;
    procedure ReadFormat;
    function GetSize: Integer;
    procedure InternatSaveFile;
    procedure SetFileName(const Value: string);
  public
    constructor Create(FileName: string; AOwner: TWave);
    destructor Destroy; override;
    procedure ClearWave;
    function ReadWave(var Buffer; Count: Integer): Integer;
    function WriteWave(const Buffer; Count: Integer): Integer;
    procedure SaveToFile(const FileName: string);
    property Size: Integer read GetSize;
    property Format: TWaveFormatEx read FFormat write FFormat;
    property FileName: string read FFileName write SetFileName;
    property ReadPos: Integer read FReadPos;
    property WritePos: Integer read FWritePos;
  end;  EWaveFileException = class(Exception);  TWave = class(TWinControl)
  private
    FActive: Boolean;
    FFormat: TWaveFormatEx;
    FHeaderList: TList;
    FWaveStream: TWaveFileStream;
    procedure AddBuffer(Header: PWaveHdr);
    procedure DeleteBuffer(var Header: PWaveHdr);
    procedure CheckActive;
    procedure SetFileName(const Value: string);
    function GetBitsperSample: TBitsperSample;
    function GetChannels: TChannels;
    function GetSamplesPerSec: TSamplesPerSec;
    procedure SetBitsperSample(const Value: TBitsperSample);
    procedure SetChannels(const Value: TChannels);
    procedure SetSamplesPerSec(const Value: TSamplesPerSec);
    function GetActive: Boolean;
    procedure SetFormat(const Value: TWaveFormatEx);
    procedure FreeHeaderBuffer;
  protected
    function GetFileName: string; virtual;
    procedure CheckError(msg: string);
    procedure SetActive(Value: Boolean); virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure Close;
    procedure Open;
    property Format: TWaveFormatEx read FFormat write SetFormat;
    property WaveStream: TWaveFileStream read FWaveStream write FWaveStream;
  published
    property Active: Boolean read GetActive write SetActive;
    { Channels: 单声/立体声}
    property Channels: TChannels read GetChannels write SetChannels;
    { SamplesPerSec: 声音频率 }
    property SamplesPerSec: TSamplesPerSec read GetSamplesPerSec write SetSamplesPerSec;
    { SamplesPerSec: 声音位:8位/16位}
    property BitsperSample: TBitsperSample read GetBitsperSample write SetBitsperSample;
    property FileName: string read GetFileName write SetFileName;
  end;  EWaveException = class(Exception);  TWaveIn = class(TWave)
  private
    FWaveID: PHWaveIn;
    FDataSize: Integer;
    FBufferSize: Integer;
    FAutoSaveFile: Boolean;
    FOnData: TWaveInEvent;
    procedure AddPrepareBuffer;
    procedure DoDataEvent(Data: Pointer; Count: Integer);
    procedure DoAutoSaveFile(Data: Pointer; Count: Integer);
    procedure WaveInCallback (var msg:TMessage); message MM_WIM_DATA;
    procedure SetAutoSaveFile(const Value: Boolean);
    procedure DoCheckWaveFormat;
  protected
    procedure CheckError(Res: Integer);
    procedure SetActive(Value: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    procedure Start;
    procedure Stop;
  published
    property OnData: TWaveInEvent read FOnData write FOnData;
    property BufferSize: Integer read FBufferSize write FBufferSize default 3;
    property AutoSaveFile: Boolean read FAutoSaveFile write SetAutoSaveFile;
  end;  TWaveOut = class(TWave)
  private
    FWaveID: PHWaveOut;
    FAutoPlayFile: Boolean;
    procedure WaveOutCallback(var msg: TMessage); message MM_WOM_DONE;
    procedure VolumeProc(Add: Boolean);
    procedure SetAutoPlayFile(const Value: Boolean);
    procedure DoCheckWaveFormat;
    procedure DoAutoPlayFile;
    procedure AutoPlayBuffer;
  protected
    procedure CheckError(Res: Integer);
    procedure SetActive(Value: Boolean); override;
    procedure IncVolume;
    procedure DecVolume;
  public
    constructor Create(AOwner: TComponent); override;
    procedure PlayBack(Data: Pointer; Count: Integer);
    procedure Pause;
    procedure ReStart;
  published
    property AutoPlayFile: Boolean read FAutoPlayFile write SetAutoPlayFile;  
  end;implementationconst
  OpenType: array [Boolean] of Integer = (fmCreate, fmOpenReadWrite or fmShareDenyNone);procedure MakeWaveFormat(var Format: TWaveFormatEx;
  Channels, SamplesPerSec, BitsperSample: DWORD);
begin
  with Format do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := Channels;
    nSamplesPerSec := SamplesPerSec;
    wBitsperSample := BitsperSample;
    nBlockAlign := nChannels * (wBitsperSample div 8);
    nAvgBytesPerSec := nBlockAlign * nSamplesPerSec;
    cbSize := 0;
  end;
end;function GetLen(S: string): Integer;
var
  Len: Integer;
begin
  Result := 1;
  Len := Length(S);
  while not (S[Result] = #0) and (Result < Len) do Inc(Result);
end;procedure FreePointer(var P: Pointer);
begin
  FreeMem(P);
  P := nil;
end;function IsDesign(Control: TComponent): Boolean;
begin
  Result := csDesigning in Control.ComponentState;
end;procedure TWaveFileStream.ClearWave;
begin
  FReadPos := FDataPosition;
  FWritePos := FDataPosition;
  FStream.Size := FDataPosition;
end;procedure TWaveFileStream.SetFileName(const Value: string);
begin
  FFileName := Value;
  if Assigned(FStream) then
    FreeAndNil(FStream);
  FStream := TFileStream.Create(FFileName, OpenType[FileExists(FFileName)]);
  ReadFormat;
end;constructor TWaveFileStream.Create(FileName: string; AOwner: TWave);
begin
  inherited Create;
  FOwner := AOwner;
  FFileName := FileName;
  FStream := TFileStream.Create(FileName, OpenType[FileExists(FFileName)]);
  ReadFormat;
end;destructor TWaveFileStream.Destroy;
begin
  InternatSaveFile;
  FStream.Free;
  inherited Destroy;
end;function TWaveFileStream.GetSize: Integer;
begin
  Result := FStream.Size - FDataPosition;
end;procedure TWaveFileStream.ReadFormat;
var
  I: Integer;
  Chunk: TWaveChunkHeader;
  Header: TWaveFileHeader;
begin
  I := 0;
  FillChar(Header, SizeOf(Header), 0);
  FillChar(Chunk, SizeOf(Chunk), 0);
  if FStream.Size = 0 then
  begin
    FFormat := PCMFormat;
    { Header, ID_FMT(contain Format), ID_FACT, ID_DATA }
    FStream.WriteBuffer(Header, SizeOf(Header));
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
    FStream.WriteBuffer(FFormat, SizeOf(FFormat));
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
    FStream.WriteBuffer(I, SizeOf(I));
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
    FDataPosition := FStream.Position;
    FReadPos := FDataPosition;
    FWritePos := FDataPosition;
    Exit;
  end;  FStream.ReadBuffer(Header, SizeOf(Header));
  if (Header.FType <> ID_RIFF) and (Header.RType <> ID_WAVE) then
    raise EWaveFileException.Create(SInvalidWaveFile);
  FStream.ReadBuffer(Chunk, SizeOf(Chunk));
  while Chunk.CType <> 0 do
  begin
    case Chunk.CType of
      ID_FMT:
        FStream.ReadBuffer(FFormat, Chunk.Size);
      ID_DATA:
      begin
        FDataPosition := FStream.Position;
        break;
      end;
      ID_FACT:  { save data size }
        FStream.Seek(Chunk.Size, soFromCurrent);
    else
      FStream.Seek(Chunk.Size, soFromCurrent);
    end;
    FillChar(Chunk, SizeOf(Chunk), 0);
    FStream.ReadBuffer(Chunk, SizeOf(Chunk));
  end;
  FReadPos := FDataPosition;
  FWritePos := FDataPosition;
end;procedure TWaveFileStream.InternatSaveFile;
var
  Header: TWaveFileHeader;
  Chunk: TWaveChunkHeader;
  Count: Integer;
begin
  { Header => Chunk(FMT(Format)->FACT->DATA) }
  FStream.Position := 0;
  Count := Self.Size;
  with Header do
  begin
    FType := ID_RIFF;
    Size := Count;
    RType := ID_WAVE;
  end;
  FStream.WriteBuffer(Header, SizeOf(Header));
  with Chunk do
  begin
    { ID_FMT and Format }
    CType := ID_FMT;
    Size := SizeOf(FFormat);
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
    FStream.WriteBuffer(FFormat, SizeOf(FFormat));
    { ID_FACT and wave data size }
    CType := ID_FACT;
    Size := SizeOf(Integer);
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
    FStream.WriteBuffer(Count, SizeOf(Count));
    { ID_DATA }
    CType := ID_DATA;
    Size := Count;
    FStream.WriteBuffer(Chunk, SizeOf(Chunk));
  end;  
end;function TWaveFileStream.ReadWave(var Buffer; Count: Integer): Integer;
begin
  Result := -1;
  if Count <= 0 then Exit;
  FStream.Position := FReadPos;
  Result := FStream.Read(Buffer, Count);
  Inc(FReadPos, Result);
  FReadEof := FStream.Size = FReadPos;
end;function TWaveFileStream.WriteWave(const Buffer; Count: Integer): Integer;
begin
  Result := -1;
  if Count <= 0 then Exit;
  FStream.Position := FWritePos;
  Result := FStream.Write(Buffer, Count);
  Inc(FWritePos, Result);
end;procedure TWaveFileStream.SaveToFile(const FileName: string);  function Confirm(S: string): Boolean;
  begin
    Result := MessageBox(0, PChar(S), PChar(SConfirm), MB_YESNO + MB_ICONWARNING) = IDYES;
  end;var
  RetVal, Count: Integer;
  Buffer: Pointer;
begin
  if FileExists(FileName) and not Confirm(SOverlay) then Exit;
  InternatSaveFile;
  with TFileStream.Create(FileName, fmCreate) do
  try
    FStream.Position := 0;
    Count := 1024000;        { 1M }
    GetMem(Buffer, Count);   { FStream may be huge }
    try
      RetVal := FStream.Read(Buffer^, Count);
      while RetVal > 0 do
      begin
        WriteBuffer(Buffer^, RetVal);
        RetVal := FStream.Read(Buffer^, Count);
      end;
    finally
      FreeMem(Buffer, 0);
    end;
  finally
    Free;
  end;
end;{ TWave }procedure TWave.Close;
begin
  SetActive(False);
end;constructor TWave.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Parent := TWinControl(AOwner);
  FFormat := PCMFormat;
  FActive := False;
  FHeaderList := TList.Create;
  FWaveStream := nil;
end;destructor TWave.Destroy;
begin
  Close;
  FreeHeaderBuffer;
  FHeaderList.Free;
  if Assigned(FWaveStream) then
    FreeAndNil(FWaveStream);
  inherited Destroy;
end;procedure TWave.Open;
begin
  SetActive(True);
end;procedure TWave.SetActive(Value: Boolean);
begin
  FActive := Value;
end;function TWave.GetBitsperSample: TBitsperSample;
begin
  Result := bs8Bit;
  if FFormat.wBitsPerSample = BitsPerSampleValue[bs16Bit] then
    Result := bs16Bit;
end;function TWave.GetChannels: TChannels;
begin
  Result := ctMono;
  if FFormat.nChannels = ChannelValue[ctStereo] then
    Result := ctStereo;
end;function TWave.GetSamplesPerSec: TSamplesPerSec;
begin
  Result := sp11k;
  while FFormat.nSamplesPerSec <> SamplesPerSecValue[Result] do
    Inc(Result);
end;procedure TWave.SetBitsperSample(const Value: TBitsperSample);
begin
  if BitsPerSample = Value then Exit;
  MakeWaveFormat(FFormat, ChannelValue[Channels],
    SamplesPerSecValue[SamplesPerSec], BitsPerSampleValue[Value]);
  SetFormat(FFormat);
end;procedure TWave.SetChannels(const Value: TChannels);
begin
  if Channels  = Value then Exit;
  MakeWaveFormat(FFormat, ChannelValue[Value], SamplesPerSecValue[SamplesPerSec],
    BitsPerSampleValue[BitsPerSample]);
  SetFormat(FFormat);
end;procedure TWave.SetSamplesPerSec(const Value: TSamplesPerSec);
begin
  if SamplesPerSec = Value then Exit;
  MakeWaveFormat(FFormat, ChannelValue[Channels],
    SamplesPerSecValue[Value], BitsPerSampleValue[BitsPerSample]);
  SetFormat(FFormat);
end;function TWave.GetActive: Boolean;
begin
  Result := FActive;
end;procedure TWave.SetFormat(const Value: TWaveFormatEx);
var
  Connected: Boolean;
begin
  Connected := FActive;
  SetActive(False);
  FFormat := Value;
  SetActive(Connected);
end;procedure TWave.FreeHeaderBuffer;
var
  I: Integer;
begin
  for I := 0 to FHeaderList.Count - 1 do
  begin
    FreeMem(PWaveHdr(FHeaderList[I])^.lpData);
    FreeMem(FHeaderList[I]);
  end;
end;procedure TWave.AddBuffer(Header: PWaveHdr);
begin
  if FHeaderList.IndexOf(Header) <> -1 then
    FHeaderList.Add(Header);
end;procedure TWave.DeleteBuffer(var Header: PWaveHdr);
begin
  if FHeaderList.IndexOf(Header) <> -1 then
  begin
    FHeaderList.Delete(FHeaderList.IndexOf(Header));
    FreePointer(Pointer(Header^.lpData));
    FreePointer(Pointer(Header));
  end;
end;function TWave.GetFileName: string;
begin
  Result := ExtractFilePath(ParamStr(0)) + 'Temp.wav';
  if Assigned(FWaveStream) and (FWaveStream.FileName <> '') then
    Result := FWaveStream.FileName;
end;procedure TWave.SetFileName(const Value: string);
begin
  if Assigned(FWaveStream) then FWaveStream.FileName := Value;
end;procedure TWave.CheckError(msg: string);
begin
  SetLength(msg, GetLen(msg));
  raise EWaveException.Create(msg); 
end;{ TWaveIn }procedure TWaveIn.AddPrepareBuffer;
var
  Data: Pointer;
  Header: PWaveHdr;
begin
  GetMem(Data, FDataSize);
  New(Header);
  FillChar(Header^, SizeOf(Header), 0);
  with Header^ do
  begin
    lpData := Data;
    dwBufferLength := FDataSize;
  end;
  AddBuffer(Header);
  CheckError(waveInPrepareHeader(FWaveID^, Header, SizeOf(TWaveHdr)));
  CheckError(waveInAddBuffer(FWaveID^, Header, SizeOf(TWaveHdr)));
end;procedure TWaveIn.DoCheckWaveFormat;
begin
  if FAutoSaveFile then
    FFormat := FWaveStream.Format;
end;constructor TWaveIn.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWaveID := nil;
  FDataSize := 0;
  FBufferSize := 3;
end;procedure TWaveIn.DoDataEvent(Data: Pointer; Count: Integer);
begin
  if Assigned(FOnData) then FOnData(Data, Count);
end;procedure TWaveIn.DoAutoSaveFile(Data: Pointer; Count: Integer);
begin
  if FAutoSaveFile and Assigned(FWaveStream) then
    FWaveStream.WriteWave(Data^, Count);
end;procedure TWaveIn.SetActive(Value: Boolean);
var
  I: Integer;
begin
  if FActive = Value then Exit;
  FActive := Value;
  if FActive then
  begin
    if not Assigned(FWaveID) and not IsDesign(Self)  then
    try
      New(FWaveID);
      DoCheckWaveFormat;
      CheckError(WaveInOpen(FWaveID, 0, @FFormat, Handle, 0, CALLBACK_WINDOW or WAVE_MAPPED));
      FDataSize := FFormat.nAvgBytesPerSec;
      for I := 0 to FBufferSize - 1 do AddPrepareBuffer;
      CheckError(waveInStart(FWaveID^));
    except
      FActive := False;
      if Assigned(FWaveID) then
      try
        waveInReset(FWaveID^);
      finally
        FreeHeaderBuffer;
        waveInClose(FWaveID^);
        FreePointer(Pointer(FWaveID));
      end;
      raise;
    end;
  end else
  begin
    if Assigned(FWaveID) then
    try
      WaveInReset(FWaveID^);
    finally
      FreeHeaderBuffer;
      WaveInClose(FWaveID^);
      FreePointer(Pointer(FWaveID));
    end;
  end;
end;procedure TWaveIn.SetAutoSaveFile(const Value: Boolean);
begin
  if FAutoSaveFile = Value then Exit;
  FAutoSaveFile := Value;
  if FAutoSaveFile then
    FWaveStream := TWaveFileStream.Create(FileName, Self)
  else if Assigned(FWaveStream) then
    FreeAndNil(FWaveStream);
end;procedure TWaveIn.Start;
begin
  CheckActive;
  waveInStart(FWaveID^);
end;procedure TWaveIn.Stop;
begin
  CheckActive;
  waveInStop(FWaveID^);
end;procedure TWaveIn.WaveInCallback(var msg: TMessage);
var
  Header: PWaveHdr;
begin
  Header := PWaveHdr(msg.lparam);
  if FActive then
  begin
    CheckError(WaveInUnPrepareHeader(FWaveID^, Header, SizeOf(TWavehdr)));
    with Header^ do
    begin
      DoDataEvent(lpData, dwBytesRecorded);
      DoAutoSaveFile(lpData, dwBytesRecorded);
    end;
    with Header^ do
    begin
      FillMemory(lpData, FDataSize, 0);
      dwBufferLength := FDataSize;
      dwBytesRecorded := 0;
      dwUser := 0;
      dwFlags := 0;
      dwLoops := 0;
    end;
    CheckError(WaveInPrepareHeader(FWaveID^, Header, SizeOf(TWavehdr)));
    CheckError(WaveInAddBuffer(FWaveID^, Header, SizeOf(TWaveHdr)));
  end else
    DeleteBuffer(Header);
end;procedure TWaveIn.CheckError(Res: Integer);
var
  S: string;
begin
  if Res <> 0 then
  begin
    SetLength(S, MAXERRORLENGTH);
    waveInGetErrorText(Res, PChar(S), MAXERRORLENGTH);
    inherited CheckError(S);
  end;
end;{ TWaveOut }constructor TWaveOut.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FWaveID := nil;
  FAutoPlayFile := False;
end;procedure TWaveOut.WaveOutCallback(var msg: TMessage);
var
  Header: PWaveHdr;
begin
  Header := PWaveHdr(msg.LParam);
  try
    if FActive then
    begin
      CheckError(WaveOutUnPrepareHeader(FWaveID^, Header, SizeOf(TWaveHdr)));
      AutoPlayBuffer;
    end;
  finally
    DeleteBuffer(Header);
  end;
end;procedure TWaveOut.PlayBack(Data: Pointer; Count: Integer);
var
  Buffer: Pointer;
  Header: PWaveHdr;
begin
  if Count = 0 then Exit;
  CheckActive;
  if Assigned(FWaveID) then
  begin
    GetMem(Buffer, Count);
    Move(Data^, Buffer^, Count);
    New(Header);
    FillChar(Header^, SizeOf(TWaveHdr), 0);
    with Header^ do
    begin
      lpData:= Buffer;
      dwBufferLength := Count;
      dwBytesRecorded := Count;
    end;
    AddBuffer(Header);
    CheckError(WaveOutPrepareHeader(FWaveID^, Header, SizeOf(TWaveHdr)));
    CheckError(WaveOutWrite(FWaveID^, Header, SizeOf(TWaveHdr)));
  end;
end;procedure TWaveOut.SetAutoPlayFile(const Value: Boolean);
begin
  if FAutoPlayFile = Value then Exit;
  FAutoPlayFile := Value;
  if FAutoPlayFile then
    FWaveStream := TWaveFileStream.Create(FileName, Self)
  else if Assigned(FWaveStream) then
    FreeAndNil(FWaveStream);
end;procedure TWaveOut.AutoPlayBuffer;
var
  Buffer: Pointer;
  RetVal, Count: Integer;
begin
  if FWaveStream.FReadEof then Exit;
  Count := C_PlayBufferSize;
  if FWaveStream.Size - FWaveStream.ReadPos <= C_PlayBufferSize then
    Count := FWaveStream.Size - FWaveStream.ReadPos;
  GetMem(Buffer, Count);
  try
    RetVal := FWaveStream.ReadWave(Buffer^, Count);
    if RetVal > 0 then
      PlayBack(Buffer, RetVal);
  finally
    FreeMem(Buffer);
  end;
end;procedure TWaveOut.DoAutoPlayFile;
begin
  if FAutoPlayFile then
  begin
    AutoPlayBuffer;
    AutoPlayBuffer;
  end;  
end;procedure TWaveOut.DoCheckWaveFormat;
begin
  if FAutoPlayFile then
    FFormat := FWaveStream.Format;
end;procedure TWaveOut.SetActive(Value: Boolean);
begin
  if FActive = Value then Exit;
  FActive := Value;
  if FActive then
  begin
    if not Assigned(FWaveID) and not IsDesign(Self) then
    try
      New(FWaveID);
      DoCheckWaveFormat;
      CheckError(WaveOutOpen(FWaveID, 0, @FFormat, Handle, 0, CALLBACK_WINDOW or WAVE_MAPPED));
      DoAutoPlayFile;
    except
      FActive := False;
      if Assigned(FWaveID) then
        FreePointer(Pointer(FWaveID));
      raise;
    end;
  end else
  begin
    if Assigned(FWaveID) then
    try
      WaveOutReset(FWaveID^);
    finally
      FreeHeaderBuffer;
      WaveOutClose(FWaveID^);
      FreePointer(Pointer(FWaveID));
    end;
  end;
end;procedure TWaveOut.Pause;
begin
  CheckActive;
  waveOutPause(FWaveID^);
end;procedure TWaveOut.ReStart;
begin
  CheckActive;
  waveOutRestart(FWaveID^);
end;procedure TWave.CheckActive;
begin
  if not Active then
    CheckError(SNotActive);
end;procedure TWaveOut.DecVolume;
begin
  VolumeProc(False);
end;procedure TWaveOut.IncVolume;
begin
  VolumeProc(True);
end;procedure TWaveOut.VolumeProc(Add: Boolean);
const
  StepValue: array [Boolean] of Integer = (100, -100);
var
  Value, CurrVolume: Integer;
begin
  CheckActive;
  waveOutGetVolume(FWaveID^, @CurrVolume);
  Value := CurrVolume div $FFFF;
  CurrVolume := Value + StepValue[Add] + Value * Value;
  waveOutSetVolume(FWaveID^, CurrVolume);
end;procedure TWaveOut.CheckError(Res: Integer);
var
  S: string;
begin
  if Res <> 0 then
  begin
    SetLength(S, MAXERRORLENGTH);
    waveOutGetErrorText(Res, PChar(S), MAXERRORLENGTH);
    inherited CheckError(S);
  end;
end;end.
 

解决方案 »

  1.   

    随便写了个调用的OpenDialog1: TOpenDialog;
    Button1: TButton;//录音开始
    BUtton2: TButton;//录音结束//选择新的wave文件,加入到ListBox中,可以找几个wave文件来试试
    procedure TForm1.miSelectClick(Sender: TObject);
    var
      I: Integer;
    begin
      with OpenDialog1 do
        if Execute then
          for I := 0 to Files.Count - 1 do
            if ListBox1.Items.IndexOf(Files[I])= -1 then
              ListBox1.Items.Add(Files[I]);
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      FWaveOut := TWaveOut.Create(Self);
      FWaveOut.AutoPlayFile := True;  //AutoPlayFile是TWaveOut组件自己控制播放的一个属性,如果你在自己PlayBlack,那就看我原来的例子。
      FWaveIn := TWaveIn.Create(Self);
      FWaveIn.AutoSaveFile := True;  //自己保存到一个文件中:default:当前exe目录的temp.wav
    end;//双击ListBox1事件,进行播放指定的wave文件。
    procedure TForm1.miPlayClick(Sender: TObject);
    var
      Index: Integer;
    begin
      Index := ListBox1.ItemIndex;
      if Index = -1 then Exit;
      if FWaveOut.Active then FWaveOut.Close;
      FWaveOut.FileName := ListBox1.Items[Index];
      FWaveOut.Open
    end;//用winamp播放一首mp3,然后开始录音,结束后,用FWaveOut来放,试试效果。
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      FWaveIn.Open;  //录音开始
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      FWaveIn.Close;  //录音结束
    end;
    是不是比原来的好多了。:)原来的在:
    http://www.csdn.net/expert/topic/490/490089.shtm 
      

  2.   

    wave文件,我们可以新建一个wave文件,用右键-》新建。
    新建的文件是58个字节。它的内容是:Header:
      TWaveFileHeader = packed record
        FType: Integer;  //固定:ID_RIFF
        Size: Longint;   // 当前wave文件的size(可选)
        RType: Integer;  //固定:ID_WAVE
      end;  //wave文件Chunk头格式(CType= ID_FMT/ID_FACT/ID_DATA)
      TWaveChunkHeader = packed record
        CType: Longint;  
        Size: Longint;
      end;
      
      FileHeader读完后就是ChunkHeader,分三种,如上ID_FMT,ID_FACT(可选),ID_DATA
      用Stream的read方法可以读出它的格式。
      ID_FMT说明wave文件的中声音的格式,占用字节为: ChunkHeader.Size
         然后读出它的Format: TWaveFormatEx,字节数为:ChunkHeader.Size
     
      ID_FACT可以忽略,它是记录当前wave文件中声音的数据流的字节。
      
      ID_DATA,数据流,可以将它用maveOutWrite播放的wave数据流。写一个wave文件正好是反操作,不过要注意写入ID_FMT/ID_DATA的数据流的Size,最好你先不要对ID_FACT的操作,熟悉后再对它操作。:)各位明白了吧。
      

  3.   

    这是以前写的readme.txt,先看看,不明白的再问  这是用MMSystem.pas中wave的录音和播放的一个组件,    TACMWave是基类,Active:激活组件,Format:声音的格式配置,下面的属性是关于Format的:    { Channels: 单声/立体声}
        property Channels: TChannels read GetChannels write SetChannels;
        { SamplesPerSec: 声音频率 }
        property SamplesPerSec: TSamplesPerSec read GetSamplesPerSec write SetSamplesPerSec;
        { SamplesPerSec: 声音位:8位/16位}
        property BitsperSample: TBitsperSample read GetBitsperSample write SetBitsperSample;    记住这些值越高,录出来的声音越好,不过产生出来的文件也越大。    TACMWaveIn是进行录音功能的,当你Open时,就开始录音了,请配置好它的Format: TWaveFormatEx属性,
    如果有录音的流过来,会触发OnData(Data: Pointer; Count: Integer)事件,那么你可以根据需要,是将它存储
    到文件流中还是将它发送出去(网络语音,爽),有这个功能,做成网络方面的功能应该很简单了,只要触发这
    个事件(OnData),那么用TCP/UDP控件将它发送出去,然后用TACMWaveOut接收播放就完了,这就是什么什么网络语音吧。    TACMWaveOut是将TACMWaveIn录出来的声音进行播放的,它的用法很简单了,像对其它组件用法,Open后再
    PlayBack(播放),请将它的Format请和TACMWaveIn的Format请设为一样,这样才不会使声音失帧。函数:
    1:  procedure SaveStreamToWaveFile(FileName: string; Format: TWaveFormatEx; Stream: TStream);
    2:  procedure OpenWaveFileToStream(FileName: string; var Format: TWaveFormatEx; Stream: TStream);  第一个函数是将TACMWaveIn的录音后的文件流保存为一个*.wav的文件,它可以为winamp或其它播放器所
    认识的格式,在Demo中那个Edit1就是当前的数据流转成edit1.Text所指的wave文件。
      第二个是反操作,是将*.wav格式的文件转成TACMWaveOut所认识的文件流(其实就是提取wave文件的数据流),
    然后在本程序中播放。在Demo中,就是用它来播放那个Edit1.Text所指的任何wave文件。