में सरणी डेटा से ध्वनि चलाने का सबसे आसान तरीका क्या है कोई आसान कार्य है? मैं कुछडेल्फी
प्ले (@डेटा, 44000, 100 {समय}) की तरह कुछ खोज रहा हूं;
में सरणी डेटा से ध्वनि चलाने का सबसे आसान तरीका क्या है कोई आसान कार्य है? मैं कुछडेल्फी
प्ले (@डेटा, 44000, 100 {समय}) की तरह कुछ खोज रहा हूं;
माइक्रोसॉफ्ट के पास Knowledge Base article है जो आपको बता रहा है कि आप एमसीआई का उपयोग करके स्मृति से ध्वनि कैसे खेल सकते हैं। आपको शायद अपनी सरणी में तरंग फ़ाइल हेडर रखना होगा, या फिर पहले पढ़ने के दौरान सही डेटा में प्रतिलिपि बनाना होगा, लेकिन इसके अलावा यह बंदरगाह पर काफी आसान होना चाहिए।
Wave Audio Package में TLiveAudioPlayer घटक है। यह बफर से ऑडियो बजाता है।
Win32 API PlaySound फ़ंक्शन अपने SND_MEMORY
ध्वज का उपयोग करके मेमोरी ब्लॉक से मानक आरआईएफएफ-एन्कोडेड ऑडियो (जैसे डब्ल्यूएवी ऑडियो) चला सकता है। वैकल्पिक रूप से, यदि ऑडियो ऐप के संसाधनों में है, तो आप इसके बजाय SND_RESOURCE
ध्वज का उपयोग कर सकते हैं।
मैंने पीसीएम ऑडियो मैनिपुलेशन के साथ काफी काम किया है। मैं हमेशा जब कस्टम तरंग ऑडियो डेटा की कमी दृश्यों खेलने इस फ़ंक्शन का उपयोग:
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;
मैं आपको पीसीएम के बारे में और पूछना चाहता हूं। यह मेरा ई-एक्स [email protected] है, मुझे आपकी मदद चाहिए। – XBasic3000
हाँ, यह मेरे लिए भी काम करते हैं। और इसकी अच्छी बात, कोई बाहरी घटक जैसे bass.dll lame.exe आदि – XBasic3000
मुझे लगता है कि यह उत्तर सबसे अच्छा के रूप में चिह्नित किया जाना चाहिए था। – Javid