Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

проблема с 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) в конце?


Наверх

Титульная страница Поиск, карта сайта Написать письмо