播放(@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中从数组数据中播放声音的最简单方法是什么?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)