在delphi中从数组数据中播放声音的最简单方法是什么?

在delphi中从数组数据中播放声音的最简单方法是什么?,第1张

概述有什么简单的功能吗?我正在寻找类似的东西 播放(@data,44000,100 {时间}); 我在PCM音频 *** 作方面做了很多工作.在播放自定义波形音频数据的短序列时,我总是使用此功能: var PlaySoundStopper: PBoolean; SoundPlayerActive: boolean = false;procedure PlaySound(const Sound: T 有什么简单的功能吗?我正在寻找类似的东西

播放(@data,44000,100 {时间});

解决方法 我在PCM音频 *** 作方面做了很多工作.在播放自定义波形音频数据的短序列时,我总是使用此功能:
var  PlaySoundStopper: PBoolean;  SoundplayerActive: boolean = false;procedure PlaySound(const Sound: TASSound);var  hWave: HWAVEOUT;  hdr: TWaveHdr;  buf: PAnsiChar;  fmt: TWaveFormatEx;  i: Integer;  n: Integer;begin  try    with fmt do    begin      wFormatTag := WAVE_FORMAT_PCM;      nChannels := length(Sound.Channels);      nSamplesPerSec := Sound.SampleRate;      wBitsPerSample := 32;      nAvgBytesPerSec := nChannels * nSamplesPerSec * wBitsPerSample div 8;      nBlockAlign := nChannels * wBitsPerSample div 8;      cbSize := 0;    end;    GetMem(buf,fmt.nChannels * length(Sound.Channels[0]) * sizeof(TASWaveformSample));    if length(Sound.Channels) = 1 then      copyMemory(buf,@(Sound.Channels[0,0]),length(Sound.Channels[0]) * sizeof(TASWaveformSample))    else      for i := 0 to high(Sound.Channels[0]) do        for n := 0 to high(Sound.Channels) do          copyMemory(buf + sizeof(TASWaveformSample) * (i * fmt.nChannels + n),@(Sound.Channels[n,i]),sizeof(TASWaveformSample));    if waveOutopen(@hWave,WAVE_MAPPER,@fmt,CALLBACK_NulL) <> MMSYSERR_NOERROR then      raise Exception.Create('SoundplayerThread.Execute: waveOutopen Failed: ' + SysErrorMessage(GetLastError));    ZeroMemory(@hdr,sizeof(hdr));    with hdr do    begin      lpData := buf;      DWBufferLength := fmt.nChannels * length(Sound.Channels[0]) * sizeof(TASWaveformSample);      DWFlags := 0;    end;    try      SoundplayerActive := true;      waveOutPrepareheader(hWave,@hdr,sizeof(hdr));      waveOutWrite(hWave,sizeof(hdr));      sleep(500);      while waveOutUnprepareheader(hWave,sizeof(hdr)) = WAVERR_STILLPLAYING do        if PlaySoundStopper^ then        begin          waveOutPause(hWave);          waveOutUnprepareheader(hWave,sizeof(hdr));          break;        end        else          sleep(100);    finally      SoundplayerActive := false;      waveOutClose(hWave);      FreeMem(buf);    end;  except    on E: Exception do MessageBox(0,PChar(E.Classname + ': ' + E.Message),'Sound Playback Error',MB_ICONERROR);  end;end;

哪里

type  TASWaveformSample = integer; // signed 32-bit; -2147483648..2147483647  TASWaveformSamples = packed array of TASWaveformSample; // one channel  PASSound = ^TASSound;  TASSound = record    Channels: packed array of TASWaveformSamples;    SampleRate: cardinal;  end;

也许更好的方法是使用线程进行播放.然后我做

var  OwnerForm: HWND; // = 0;  SndSource: PASSound; // = nil;  Threadplaying: boolean; // = false;type  TSoundplayerThread = class(TThread)  private    { Private declarations }  protected    procedure Execute; overrIDe;  end;

实施为

procedure TSoundplayerThread.Execute;var  hWave: HWAVEOUT;  hdr: TWaveHdr;  buf: PAnsiChar;  fmt: TWaveFormatEx;  i: Integer;  n: Integer;begin  Threadplaying := true;  try   try      if not Assigned(SndSource) then        Exit;      with fmt do      begin        wFormatTag := WAVE_FORMAT_PCM;        nChannels := length(SndSource^.Channels);        nSamplesPerSec := SndSource^.SampleRate;        wBitsPerSample := 32;        nAvgBytesPerSec := nChannels * nSamplesPerSec * wBitsPerSample div 8;        nBlockAlign := nChannels * wBitsPerSample div 8;        cbSize := 0;      end;      GetMem(buf,fmt.nChannels * length(SndSource^.Channels[0]) * sizeof(TASWaveformSample));      if length(SndSource^.Channels) = 1 then        copyMemory(buf,@(SndSource^.Channels[0,length(SndSource^.Channels[0]) * sizeof(TASWaveformSample))      else        for i := 0 to high(SndSource^.Channels[0]) do          for n := 0 to high(SndSource^.Channels) do            copyMemory(buf + sizeof(TASWaveformSample) * (i * fmt.nChannels + n),@(SndSource^.Channels[n,sizeof(TASWaveformSample));      if waveOutopen(@hWave,CALLBACK_NulL) <> MMSYSERR_NOERROR then        raise Exception.Create('SoundplayerThread.Execute: waveOutopen Failed: ' + SysErrorMessage(GetLastError));      ZeroMemory(@hdr,sizeof(hdr));      with hdr do      begin        lpData := buf;        DWBufferLength := fmt.nChannels * length(SndSource^.Channels[0]) * sizeof(TASWaveformSample);        DWFlags := 0;      end;      waveOutPrepareheader(hWave,sizeof(hdr)) = WAVERR_STILLPLAYING do      begin        sleep(100);        if Terminated then          waveOutreset(hWave);      end;      waveOutClose(hWave);      FreeMem(buf);    except      on E: Exception do MessageBox(0,'TSoundplayerThread',MB_ICONERROR);    end;  finally    Threadplaying := false;  end;end;
总结

以上是内存溢出为你收集整理的在delphi中从数组数据中播放声音的最简单方法是什么?全部内容,希望文章能够帮你解决在delphi中从数组数据中播放声音的最简单方法是什么?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1279727.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存