2010-08-11 17 views
7

में सरणी डेटा से ध्वनि चलाने का सबसे आसान तरीका क्या है कोई आसान कार्य है? मैं कुछडेल्फी

प्ले (@डेटा, 44000, 100 {समय}) की तरह कुछ खोज रहा हूं;

उत्तर

2

माइक्रोसॉफ्ट के पास Knowledge Base article है जो आपको बता रहा है कि आप एमसीआई का उपयोग करके स्मृति से ध्वनि कैसे खेल सकते हैं। आपको शायद अपनी सरणी में तरंग फ़ाइल हेडर रखना होगा, या फिर पहले पढ़ने के दौरान सही डेटा में प्रतिलिपि बनाना होगा, लेकिन इसके अलावा यह बंदरगाह पर काफी आसान होना चाहिए।

4

Wave Audio Package में TLiveAudioPlayer घटक है। यह बफर से ऑडियो बजाता है।

+0

हाँ, यह मेरे लिए भी काम करते हैं। और इसकी अच्छी बात, कोई बाहरी घटक जैसे bass.dll lame.exe आदि – XBasic3000

+0

मुझे लगता है कि यह उत्तर सबसे अच्छा के रूप में चिह्नित किया जाना चाहिए था। – Javid

2

Win32 API PlaySound फ़ंक्शन अपने SND_MEMORY ध्वज का उपयोग करके मेमोरी ब्लॉक से मानक आरआईएफएफ-एन्कोडेड ऑडियो (जैसे डब्ल्यूएवी ऑडियो) चला सकता है। वैकल्पिक रूप से, यदि ऑडियो ऐप के संसाधनों में है, तो आप इसके बजाय SND_RESOURCE ध्वज का उपयोग कर सकते हैं।

7

मैंने पीसीएम ऑडियो मैनिपुलेशन के साथ काफी काम किया है। मैं हमेशा जब कस्टम तरंग ऑडियो डेटा की कमी दृश्यों खेलने इस फ़ंक्शन का उपयोग:

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; 

जहां

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, 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

मैं आपको पीसीएम के बारे में और पूछना चाहता हूं। यह मेरा ई-एक्स [email protected] है, मुझे आपकी मदद चाहिए। – XBasic3000