2010-08-11 6 views

Antwort

2

Microsoft hat eine Knowledge Base article, die Ihnen mitteilt, wie Sie mit MCI Ton aus dem Speicher wiedergeben können. Wahrscheinlich müssen Sie den Header der Wave-Datei in Ihrem Array haben oder auf andere Weise die richtigen Daten während des ersten Lesevorgangs kopieren, ansonsten sollte die Portierung relativ einfach sein.

4

Wave Audio Package hat TLiveAudioPlayer-Komponente. Es spielt Audio vom Puffer ab.

+0

Ja es auch für mich arbeiten. und die gute Sache davon, keine externen Komponenten wie Bass.dll lame.exe usw. – XBasic3000

+0

Ich denke, diese Antwort sollte als die beste markiert worden sein. – Javid

2

Die Funktion Win32 API PlaySound kann RIFF-codiertes Standardaudio (z. B. WAV-Audio) von einem Speicherblock mit dem Flag SND_MEMORY wiedergeben. Wenn das Audio in den Ressourcen der App enthalten ist, können Sie alternativ stattdessen das Flag SND_RESOURCE verwenden.

7

Ich habe ziemlich viel mit PCM Audio Manipulation gearbeitet. Ich habe immer diese Funktion verwenden, wenn kurze Sequenzen von benutzerdefinierter Wellenform Audiodaten spielen:

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, 0, 0, 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, @hdr, sizeof(hdr)); 
     sleep(500); 

     while waveOutUnprepareHeader(hWave, @hdr, sizeof(hdr)) = WAVERR_STILLPLAYING do 
     if PlaySoundStopper^ then 
     begin 
      waveOutPause(hWave); 
      waveOutUnprepareHeader(hWave, @hdr, 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; 

wo

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; 

Eines vielleicht besseren Weg, ist ein Gewinde für das Spiel zu verwenden. Dann mache ich

var 
    OwnerForm: HWND; // = 0; 
    SndSource: PASSound; // = nil; 
    ThreadPlaying: boolean; // = false; 

type 
    TSoundPlayerThread = class(TThread) 
    private 
    { Private declarations } 
    protected 
    procedure Execute; override; 
    end; 

implementiert als

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, 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, i]), sizeof(TASWaveformSample)); 

     if waveOutOpen(@hWave, WAVE_MAPPER, @fmt, 0, 0, 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, @hdr, sizeof(hdr)); 
     waveOutWrite(hWave, @hdr, sizeof(hdr)); 
     sleep(500); 

     while waveOutUnprepareHeader(hWave, @hdr, 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, PChar(E.ClassName + ': ' + E.Message), 'TSoundPlayerThread', MB_ICONERROR); 
    end; 

    finally 
    ThreadPlaying := false; 
    end; 
end; 
+0

Ich möchte Sie mehr über PCMs fragen. das ist mein E-Add [email protected] Ich brauche deine Hilfe. – XBasic3000

Verwandte Themen