![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
проблема с DirectSound [Delphi, DirectSound]
Kobik © (2005-07-07 18:46:00)Занялся звуками в игре и столкнулся с непонятным глюком: на одном компе все нормально работает, а на другом (на котором делаю) выдает ошибку.
Т.е сообщение "Unable to set Coopeative Level1" и дальше естественно звуки не работают
вот процедурка создания главного буфера (место ошибки выделенно жирным):
procedure AppCreateWritePrimaryBuffer(const Handle:HWND);
var BufferDesc : TDSBUFFERDESC_DX8;
// Caps : DSBCaps;
PCM : TWaveFormatEx;
begin
FillChar(BufferDesc, SizeOf(TDSBUFFERDESC_DX8),0);
FillChar(PCM, SizeOf(TWaveFormatEx),0);
with BufferDesc do
begin
PCM.wFormatTag:=WAVE_FORMAT_PCM;
PCM.nChannels:=2;
PCM.nSamplesPerSec:=22050;
PCM.nBlockAlign:=4;
PCM.nAvgBytesPerSec:=PCM.nSamplesPerSec * PCM.nBlockAlign;
PCM.wBitsPerSample:=16;
PCM.cbSize:=0;
dwSize:=SizeOf(TDSBUFFERDESC_DX8);
dwFlags:=DSBCAPS_PRIMARYBUFFER;
dwBufferBytes:=0;
lpwfxFormat:=nil;
end;
if DirectSound1.SetCooperativeLevel(Handle,DSSCL_WRITEPRIMARY) <> DS_OK
then Raise Exception.Create('Unable to set Coopeative Level1');
if DirectSound1.CreateSoundBuffer(BufferDesc,DirectSoundBuffer,nil) <> DS_OK
then Raise Exception.Create('Create Sound Buffer failed');
if DirectSoundBuffer.SetFormat(PCM) <> DS_OK
then Raise Exception.Create('Unable to Set Format ');
if DirectSound1.SetCooperativeLevel(Handle,DSSCL_NORMAL) <> DS_OK
then Raise Exception.Create('Unable to set Coopeative Level2');
end;
Естественно до этого DirectSound1 создается DirectSoundCreate8(nil, DirectSound1, nil)... там ошибки не возникает.
Из-за чего вообще такое может быть? Звуковуха вроде на месте :)
Kobik (2005-07-08 17:00:00) [1]Ок, попробую. Большое спасибо за помощь.
XProger (2005-07-08 15:32:00) [2]Kobik, создавай базовый набор сэмплов, а также массив каналов (64-128 штук) - каждый из который содержит указатель на буфер.
При вызове проигрыша одного из сэмплов дублируй его в один из свободных каналов:
ids.DuplicateSoundBuffer(sample[i].Buffer, Channel[i].Buffer);
А затемChannel[i].Buffer.Play(0, 0, 0);
Только не забывай постоянно проверять каналы на "живучесть". Т.е. по окончании проигрывания ниль буфер:
hr := Channel[i].Buffer.GetStatus(Status);
if (hr = DS_OK) and (status and DSBSTATUS_PLAYING = 0) then
begin
Channel[i].Buffer.Restore;
Channel[i].buffer := nil;
end
P.S. как видишь, без дублирования никак :)
A22 (2005-07-08 15:01:00) [3]20 буферов, ничего у меня не тормозило...
Kobik (2005-07-08 14:57:00) [4]>>каждый новый звук - новый буфер
Эээ. Можно поконкретнее что вы имеете ввиду?
То что на каждый тип выстрела свой буфер это итак понятно.
Или вы имеете ввиду что чел выстрелил 20 раз - надо 20 буферов создавать? Это ж наверно сильно тормозить будет...
A22 (2005-07-08 11:03:00) [5]каждый новый звук - новый буфер
Kobik (2005-07-08 07:08:00) [6]Хмм. DSSCL_EXCLUSIVE действительно подошло :)
Собственно этот кусок я взял из единственного примера, который удалось найти в инете. Комментариев там нет. Без SetCooperativeLevel(Handle,DSSCL_NORMAL) вроде все также работает.
Вот еще вопросик такой есть:
Когда юнит стреляет делаю SSB_fire.Play(0,0,0); //(SSB_fire: IDirectSoundBuffer)
Если промежуток между выстрелами короче времени звука (примерно одна секунда), то второго выстрела не слышно. Третий снова слышно, четвертый неслышно и т.д. :)
Попробовал сделать
begin
SSB.Stop;
SSB.Play(0,0,0);
end;
Тогда второй выстрел звучит с какими-то глюками.
А хочется вообще, чтобы следующий выстрел не останавливал первый, а наклаывался на него. Как это сделать? У меня только есть идея сделать несколько буферов с одинаковыми звуками, но как-то это криво...
XProger (2005-07-07 22:44:00) [7]У меня возникали ошибки на карточках SB Life. Обновление драйвера помогало...
А DSSCL_EXCLUSIVE не подходит?
И что за SetCooperativeLevel(Handle,DSSCL_NORMAL) в конце?