Информатика и образование
  Мобильная версия сайта            
               
[Главная] [Новости]
[Статьи]
[Проекты]
[Ссылки]
[Автор]
               
    [Архив новостей]        
               
  [Форум] на форуме можно задать вопрос, посмотреть ответы на часто задаваемые вопросы  
       
  Здравствуйте! Вы попали на информационно-образовательный сайт посвященный информатике, информационным технологиям и компьютерным играм. Подробнее о целях и задачах сайта в разделе Главная. [English version of this page here...]    
       
  [Базовые уроки по DirectX] [Основы DirectMusic на Delphi] [Основы DirectInput8 на Delphi] [Основы DirectSound8 на Delphi]    
  [Разработка компьютерной игры] [Пример игры Donuts3D]    
       
 

12/06/2008 Воспроизведение файлов в форматах *.it, *.xm, *.s3m, *.mod

продолжение...

   
       
  [назад]    
       
 

Теперь рассмотрим код, который должен осуществляться при уничтожении приложения - во время закрытия окна формы в данном примере -

procedure TfrmMain.FormClose

   
       
  FMUSIC_StopAllSongs(); //останавливаем все играющие звуковые файлы
for Index := 0 to MAX_SONGS - 1 do
begin
if FSongs[Index].Module <> nil then
begin
FMUSIC_FreeSong(FSongs[Index].Module);
//освобождаем ресурсы памяти от трекерских файлов и
end
else if FSongs[Index].Stream <> nil then
begin
FSOUND_Stream_Stop(FSongs[Index].Stream);
//файлов-потоков (таких как wav, mp2, mp3, ogg и подобных)
FSOUND_Stream_Close(FSongs[Index].Stream);
end;
end;
FSpectrum.Free;
//удаляем объект спектрального анализатора

FMOD_Unload; //и выгружаем библиотеку fmod.dll из памяти

   
       
 

Мы выяснили что должно происходить во время старта и уничтожения приложения.

Рассмотрим как осуществить загрузку, выгрузку, проигрывание, останов, регулировку позиции текущего паттерна, громкости, организацию одновременного воспроизведения нескольких файлов и прочие особенности.

   
       
 

загрузка - procedure TfrmMain.btnLoadClick

Проверяем сколько файлов уже есть в списке и выводим предупреждение об ошибке если их больше допустимого

SongCount := lbxFiles.Items.Count;

if SongCount = MAX_SONGS then
begin
Application.MessageBox(PChar(Format('Limit of %d songs reached', [MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
Exit;
end;

   
       
 

Для очередного элемента открытых файлов -

Пробуем открыть файл как трек, а затем как поток

Stream := nil;
Module := FMUSIC_LoadSong(PChar(dlgOpen.Files[Index]));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(dlgOpen.Files[Index]), FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

Если никак не удалось - снова предупреждение

if (Module = nil) and (Stream = nil) then
begin
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Load error', MB_OK or MB_ICONHAND);
Continue;
end;

   
       
 

Если трек загрузился, то установить громкость для данного трека на максимум, а шаг панорамы на 15%

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD) or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

   
       
 

Присваиваем полученные обработчики трека и потока данному элементу массива воспроизводимых файлов, индикатор проигрывания сброшен

FSongs[SongCount].Module := Module;
FSongs[SongCount].Stream := Stream;
FSongs[SongCount].Playing := False;

lbxFiles.Items.Add(ExtractFileName(dlgOpen.Files[Index])); //эта особенность актуальна лишь для примера testbed.dpr
lbxFiles.ItemIndex := SongCount;
//имя файла добавляется в список и текущим в списке становится данный файл

   
       
 

После этого вызывается псевдо-щелчок по файлу. Это приводит к считыванию текущих параметров из модуля (потока) данного файла, но это уже более актуально для примера testbed.dpr, хотя что-то может пригодиться и в игровом приложении

{...}

lbxFilesClick(nil);

   
       
 

выгрузка мелодии из памяти -

procedure TfrmMain.btnDeleteClick

определяем текущий элемент списка и останавливаем,

Index := lbxFiles.ItemIndex;
if Index < 0 then
Exit;

btnStopClick(nil);

   
       
 

а затем удаляем его -

lbxFiles.Items.Delete(Index);
// сдвигаем нижележащие элементы на освободившуюся позицию
if lbxFiles.Items.Count > 0 then
begin
if Index < lbxFiles.Items.Count - 1 then
begin
for Index2 := Index to lbxFiles.Items.Count - 2 do
FSongs[Index2] := FSongs[Index2 + 1];
end;
if Index < lbxFiles.Items.Count then
lbxFiles.ItemIndex := Index
else
lbxFiles.ItemIndex := lbxFiles.Items.Count - 1;
end;
lbxFilesClick(nil); //оcвежаем параметры для нового текущего файла

   
       
 

Воспроизведение мелодии -

procedure TfrmMain.btnPlayClick

Выбранная мелодия останавливается, если она уже играла

Index := lbxFiles.ItemIndex;

if Index < 0 then
Exit;

if FSongs[Index].Playing then
btnStopClick(Sender);

Включаем воспроизведение текущей мелодии списка

if FSongs[Index].Module <> nil then
begin
FSongs[Index].Playing := FMUSIC_PlaySong(FSongs[Index].Module);
if not FSongs[Index].Playing then
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Play song', MB_OK or MB_ICONHAND);
end

   
       
 

или потока, если это поток

else if FSongs[Index].Stream <> nil then
begin
FSongs[Index].Channel := FSOUND_Stream_Play(FSOUND_FREE, FSongs[Index].Stream);
FSongs[Index].Playing := FSongs[Index].Channel >= 0;
if not FSongs[Index].Playing then
begin
Application.MessageBox(FMOD_ErrorString(FSOUND_GetError), 'Play stream', MB_OK or MB_ICONHAND);
end

   
       
 

если звуковой поток уже играет, то включить воспроизведение стерео, громкость на максимум

else
begin
FSOUND_SetPan(FSongs[Index].Channel, FSOUND_STEREOPAN);
FSOUND_SetVolume(FSongs[Index].Channel, 255);
end;

   
       
 

Остановка воспроизведения -

procedure TfrmMain.btnStopClick

Определяем текущую мелодию

Index := lbxFiles.ItemIndex;

if Index < 0 then
Exit;

Если это трекерский модуль - применяем команду остановки для него

if FSongs[Index].Module <> nil then
FMUSIC_StopSong(FSongs[Index].Module)

если это потоковое аудио - применяем другую команду остановки
else if FSongs[Index].Stream <> nil then
FSOUND_Stream_Stop(FSongs[Index].Stream);

Текущий канал потока - неопределен, индикатор проигрывания сброшен
FSongs[Index].Channel := -1;
FSongs[Index].Playing := False;

   
       
 

Регулировка громкости текущей мелодии -

Если не установка регулятора глобальной громкости

if not FSettingMasterVolume then
begin

Определяем текущую композицию
Index := lbxFiles.ItemIndex;
if Index > -1 then
begin

для модуля применяем свою команду
if FSongs[Index].Module <> nil then
begin
FMUSIC_SetMasterVolume(FSongs[Index].Module, trkMasterVolume.Position);
lblSongMasterVolume.Caption := Format('%3.3d', [trkMasterVolume.Position]);
//это актуально для элемента управления

//регулятором
end
else if FSongs[Index].Stream <> nil then

для потока - свою
begin
FSOUND_SetVolume(FSongs[Index].Channel, trkMasterVolume.Position);
lblSongMasterVolume.Caption := Format('%3.3d', [trkMasterVolume.Position]);
//это актуально для элемента управления

//регулятором
end;
end;
end;

   
       
 

Регулировка текущего воспроизводимого паттерна в трекерском модуле -

переход к предыдущему паттерну порядка воспроизведения -

procedure TfrmMain.btnPrevOrderClick(Sender: TObject);
var
Index: Integer;
Order: DWORD;
begin

считываем текущий модуль
Index := lbxFiles.ItemIndex;
if Index < 0 then
Exit;

если это трекерский модуль - считываем текущий индекс элемента порядка воспроизведения и уменьшаем его на 1
if FSongs[Index].Module = nil then
Exit;
Order := FMUSIC_GetOrder(FSongs[Index].Module);
if Order > 0 then
FMUSIC_SetOrder(FSongs[Index].Module, Order - 1);
end;

   
       
 

для переключения на следующий паттерн всё аналогично кроме строк -

т.е. приращаем индекс на +1

if Order < FMUSIC_GetNumOrders(FSongs[Index].Module) then
FMUSIC_SetOrder(FSongs[Index].Module, Order + 1);

   
       
 

внутри метода периодической работы таймера представлены ряд интересных команд -

procedure TfrmMain.tmrMainTimer(Sender: TObject);
var
Index: Integer;
begin

для игрового проекта это по большому счету не особо нужная информация, но все-таки полезна
lblCPU.Caption := Format('%.1f%%', [FSOUND_GetCPUUsage]);
//например можно определять загруженность процессора
lblChannels.Caption := Format('%3.3d', [FSOUND_GetChannelsPlaying]);
//музыкой и количество занятых звуковых каналов

//это полезно, т.к. для музыки не существует такого понятия как FPS, зато вышеуказанные параметры могут служить в какой-то мере для целей оценки быстродействия работающего проекта
Index := lbxFiles.ItemIndex;
if Index > -1 then
begin
ShowSpectrum;
ShowDynamicSongInfo(Index);
//данный метод будет полезен с точки зрения наблюдения за текущей позицией воспроизведения
if FMUSIC_IsFinished(FSongs[Index].Module) and chkPlaylist.Checked then
//если мелодия кончилась и установлен индикатор работы в режиме плей-листа - т.е. списка воспроизведения, то переход к следующей мелодии
begin
btnStopClick(nil);
Inc(Index);
if Index >= lbxFiles.Items.Count then
Index := 0;
lbxFiles.ItemIndex := Index;
lbxFilesClick(nil);
btnPlayClick(nil);
end;
end;
{ ... }

end;

   
       
 

Конфигурирование - выбор драйвера и параметров фильтрации -

Настройки конфигурирования происходят в модуле формы TfrmConfig -

С точки зрения наших задач заслуживает внимания метод модуля config.pas -

Считываются параметры установленные в окне формы конфигуратора и применяются к объекту FSOUND.

procedure TfrmConfig.btnOkClick(Sender: TObject);
var
Flags: Cardinal;
begin
FSOUND_SetOutput(OutputTypes[cbxOutputType.ItemIndex]);
FSOUND_SetDriver(cbxOutputDevice.ItemIndex);
FSOUND_SetMixer(TFSoundMixerTypes(cbxMixerType.ItemIndex));
Flags := 0;
if chkSoftwareMIDI.Checked then
Flags := Flags or FSOUND_INIT_USEDEFAULTMIDISYNTH;
if chkGlobalFocus.Checked then
Flags := Flags or FSOUND_INIT_GLOBALFOCUS;
FSOUND_Init(OutputRates[cbxOutputRate.ItemIndex], 128, Flags);
end;

   
       
  Оставшиеся нерассмотренными здесь методы, я думаю, Вы разберете самостоятельно.    
       
  Теперь переходим к практическим упражнениям - реализации использования FMOD 3.75 для воспроизведения музыки и звуков в трекерских и потоковых форматах.    
       
 

Файл fmod.dll размещаем в папке проекта, в настройках проекта указываем ссылку на интерфейсы в delphi-исходниках - fmod375;

В секции interface

uses

добавляем ссылку на fmodtypes

В секции implementation

uses

добавляем ссылки на fmod, fmoderrors

 

Внутри класса приложения объявляем 2 метода -

//music functions
procedure InitMusicLib;
procedure FreeMusicLib;

   
       
 

Пишем реализацию данных методов -

procedure TD3DGameApp.InitMusicLib;
var
Index: Integer;
begin
FMOD_Load(nil);

{ Check version numbers }
if FMOD_VERSION > FSOUND_GetVersion then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('API version %3.2f is newer than DLL version %3.2f', [FMOD_VERSION, FSOUND_GetVersion])), 'Version mismatch', MB_OK or MB_ICONERROR);
Halt;
end;

{ Initialize FSOUND }
try
if not FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND) then
raise Exception.Create('FSOUND_SetOutput failed');
if not FSOUND_SetDriver(0) then
raise Exception.Create('FSOUND_SetDriver failed');
if not FSOUND_SetMixer(FSOUND_MIXER_QUALITY_AUTODETECT) then
raise Exception.Create('FSOUND_SetMixer failed');
if not FSOUND_SetHWND(g_d3dApp.m_hWnd) then
raise Exception.Create('FSOUND_SetHWND failed');
except
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError), 'Initialization', MB_OK or MB_ICONHAND);
raise;
end;

if not FSOUND_Init(22050, 128, 0) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError), 'FSOUND_Init', MB_OK or MB_ICONHAND);
Halt;
end;

{ Initialize song list to empty }
for Index := 0 to MAX_SONGS - 1 do
begin
FSongs[Index].Module := nil;
FSongs[Index].Stream := nil;
FSongs[Index].Channel := -1;
end;

FTrackNumber := 0;
FNumTracks := 0;

LoadPlaylist(DefaultThemes); //данный метод будет реализован далее (см. ниже)

end;

   
       
 

procedure TD3DGameApp.FreeMusicLib;
var
Index: Integer;
begin
FMUSIC_StopAllSongs;
for Index := 0 to MAX_SONGS - 1 do
begin
if FSongs[Index].Module <> nil then
begin
FMUSIC_FreeSong(FSongs[Index].Module);
end
else if FSongs[Index].Stream <> nil then
begin
FSOUND_Stream_Stop(FSongs[Index].Stream);
FSOUND_Stream_Close(FSongs[Index].Stream);
end;
end;

FreePlayList; //данный метод будет реализован далее (см. ниже)

FMOD_Unload;
end;

   
       
  Как видим нам почти ничего даже переделывать не пришлось, только опустили кое-какой код и изменили вызовы MessageBox.    
       
 

Я организую вызов данных методов внутри TD3DGameApp.CreateSoundObjects и TD3DGameApp.DestroySoundObjects.

Где будете делать это Вы - решать Вам. Можете поступить аналогично. Следует иметь в виду, что метод InitMusicLib должен вызываться только после того, как окно приложения будет создано и обработчик окна - m_hWnd в нашем случае обретет своё действительное значение - в противном случае будут только ошибки... ошибки... и ошибки...

 

   
       
  Теперь реализуем загрузку нужных мелодий в список. Для удобства и наименьших изменений кода можно сделать это организовав загрузку требуемого списка мелодий из обычного текстового файла, где бы каждая строка соответствовала полному имени файла внутри дистрибутива игры. Таким способом и Вы и Ваши пользователи будут вольны не только слушать в игре то что было предопределено ее дистрибутивом, но и любые другие файлы мелодий поддерживаемых форматов.    
       
  Единственным ограничением списка воспроизведения является количество файлов в нем - не более 512, но это ограничение легко обойти использовав столько плей-листов сколько нужно. Конечно же в каждый момент времени работа будет осуществляться только с выбранным списком.    
       
 

Загрузка списка мелодий из текстового файла const DefaultThemes = 'Media\Music\muzon_themes.txt'; -

Код уже должен быть Вам знаком по предыдущему повествованию, особо нового ничего нет

procedure TD3DGameApp.LoadPlaylist(PlayList: string);
var
Index: Integer;
Module: PFMusicModule;
Stream: PFSoundStream;
SongCount: Integer;
begin

создаем список строк будущего плей-листа и загружаем
FTMSPlayList := TStringList.Create;
try
FTMSPlayList.LoadFromFile(PlayList);
except
MessageBox(g_d3dApp.m_hWnd, PChar('Playlist '+PlayList+' not found!'),
'Playlist load Error', MB_OK or MB_ICONHAND);
end;

SongCount := FTMSPlayList.Count;

предупредить, если мелодий в списке больше допустимого!

if SongCount = MAX_SONGS then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('Limit of %d songs reached',
[MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
Exit;
end;

загружаем файлы списка в массив FSongs

for Index := 0 to SongCount - 1 do begin
Stream := nil;
Module := FMUSIC_LoadSong(PChar(FTMSPlayList[Index]));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(FTMSPlayList[Index]),
FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

if (Module = nil) and (Stream = nil) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Load error', MB_OK or MB_ICONHAND);
Continue;
end;

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD)
or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

FSongs[Index].Module := Module;
FSongs[Index].Stream := Stream;
FSongs[Index].Playing := False;
end;
end;

   
       
 

Метод FreePlaylist выглядит совсем просто -

procedure TD3DGameApp.FreePlaylist;
begin
FreeAndNil(FTMSPlayList);
end;

   
       
 

Воспроизводим и останавливаем нужный трэк или поток по его номеру в массиве FSongs -

procedure TD3DGameApp.PlayItem(Index: Integer);
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;


if FSongs[Index].Playing then
StopItem(Index);

if FSongs[Index].Module <> nil then
begin
FSongs[Index].Playing := FMUSIC_PlaySong(FSongs[Index].Module);
if not FSongs[Index].Playing then
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Play song', MB_OK or MB_ICONHAND);
end
else if FSongs[Index].Stream <> nil then
begin
FSongs[Index].Channel := FSOUND_Stream_Play(FSOUND_FREE,
FSongs[Index].Stream);
FSongs[Index].Playing := FSongs[Index].Channel >= 0;
if not FSongs[Index].Playing then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Play stream', MB_OK or MB_ICONHAND);
end
else
begin
FSOUND_SetPan(FSongs[Index].Channel, FSOUND_STEREOPAN);
FSOUND_SetVolume(FSongs[Index].Channel, 255);
end;
end;
end;

procedure TD3DGameApp.StopItem(Index: Integer);
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;

if FSongs[Index].Module <> nil then
FMUSIC_StopSong(FSongs[Index].Module)
else if FSongs[Index].Stream <> nil then
FSOUND_Stream_Stop(FSongs[Index].Stream);
FSongs[Index].Channel := -1;
FSongs[Index].Playing := False;
end;

   
       
 

Для того, чтобы не выгружать весь плей-лист ради одной лишь песни реализуем методы удаления и добавления отдельных композиций списка.

Сначала реализуем удаление -

   
       
  procedure TD3DGameApp.DeleteSong(Index: Integer);
var
Index2: Integer;
begin
if (Index < 0) or (Index > FTMSPlayList.Count-1) then
Exit;

StopItem(Index);
FTMSPlayList.Delete(Index);
// Move all following items up one position
if FTMSPlayList.Count > 0 then
begin
if Index < FTMSPlayList.Count - 1 then
begin
for Index2 := Index to FTMSPlayList.Count - 2 do
FSongs[Index2] := FSongs[Index2 + 1];
end;
end;
end;

   
       
 

Теперь добавление -

function TD3DGameApp.AddSong(Filename: string): Integer;
var
Module: PFMusicModule;
Stream: PFSoundStream;
SongCount: Integer;
begin
SongCount := FTMSPlayList.Count;

if SongCount = MAX_SONGS then
begin
MessageBox(g_d3dApp.m_hWnd, PChar(Format('Limit of %d songs reached',
[MAX_SONGS])), 'Load error', MB_OK or MB_ICONHAND);
result := -1;
Exit;
end;


Stream := nil;
Module := FMUSIC_LoadSong(PChar(Filename));
if Module = nil then
begin
Stream := FSOUND_Stream_Open(PChar(Filename),
FSOUND_NORMAL or FSOUND_LOOP_NORMAL, 0, 0);
end;

if (Module = nil) and (Stream = nil) then
begin
MessageBox(g_d3dApp.m_hWnd, FMOD_ErrorString(FSOUND_GetError),
'Load error', MB_OK or MB_ICONHAND);
result := -1;
Exit;
end;

if Module <> nil then
begin
FMUSIC_SetMasterVolume(Module, 255);
if (FMUSIC_GetType(Module) = FMUSIC_TYPE_MOD)
or (FMUSIC_GetType(Module) = FMUSIC_TYPE_S3M) then
FMUSIC_SetPanSeperation(Module, 0.15); // 15% crossover
end;

result := FTMSPlayList.Add(Filename);

FSongs[result].Module := Module;
FSongs[result].Stream := Stream;
FSongs[result].Playing := False;

end;

   
       
 

Регулируем громкость - значения громкости 0 - тишина, 255 - максимум

procedure TD3DGameApp.Volume(SongIndex: Integer; Value: Byte);
begin
if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module <> nil then
FMUSIC_SetMasterVolume(FSongs[SongIndex].Module, Value)
else if FSongs[SongIndex].Stream <> nil then
FSOUND_SetVolume(FSongs[SongIndex].Channel, Value);

end;

   
       
 

Регулировка позиции воспроизведения модуля по паттернам - переход к следующему/предыдущему паттерну -

function TD3DGameApp.Go2NextPattern(SongIndex: Integer): Integer;
begin
result := -1;

if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module = nil then
Exit;
result := FMUSIC_GetOrder(FSongs[SongIndex].Module);
if result < FMUSIC_GetNumOrders(FSongs[SongIndex].Module) then begin
result := result + 1;
FMUSIC_SetOrder(FSongs[SongIndex].Module, result);
end;
end;

function TD3DGameApp.Go2PrevPattern(SongIndex: Integer): Integer;
begin
result := -1;

if (SongIndex < 0) or (SongIndex > FTMSPlayList.Count-1) then
Exit;

if FSongs[SongIndex].Module = nil then
Exit;
result := FMUSIC_GetOrder(FSongs[SongIndex].Module);
if result < FMUSIC_GetNumOrders(FSongs[SongIndex].Module) then begin
result := result - 1;
FMUSIC_SetOrder(FSongs[SongIndex].Module, result);
end;
end;

   
       
 

Для целей отладки будет полезно получать параметры производительности системы FMOD -

var
Index: Integer;
begin
SS_CPUUsage := Format('%.1f%%', [FSOUND_GetCPUUsage]);
SS_Channels := Format('%3.3d', [FSOUND_GetChannelsPlaying]);

if CurrentSongIndex > -1 then
begin
if FMUSIC_IsFinished(FSongs[CurrentSongIndex].Module) and PlaylistMode then
begin
StopItem(CurrentSongIndex);
Index := CurrentSongIndex;
Inc(Index);
if Index >= FTMSPlayList.Count then
Index := 0;
CurrentSongIndex := Index;
PlayItem(Index);
end
else if FMUSIC_IsFinished(FSongs[CurrentSongIndex].Module) and
not PlaylistMode then begin
PlayItem(CurrentSongIndex);
end;
end;

данный метод должен вызываться периодически (аналогично FrameMove). Здесь также проверяется режим плей-листа. Если он установлен, то будет проигрываться следующий файл списка, в противном случае будет бесконечно воспроизводиться композиция с индексом CurrentSongIndex.

   
       
  Если Ваш игровой проект будет поддерживать в опции настроек установку каких-либо аудио-параметров - выбор драйвера, параметры фильтрации и т.п., то можете реализовать их установку по аналогии с тем, как это выполнено в рассмотренном нами выше примере.    
       
 

На этом пожалуй и закруглимся. Заметим лишь, что созданные методы теперь могут вызываться в различных частях Вашего приложения, чтобы например, для одной сцены играла одна музыка, для другой - другая. Одновременного воспроизведения нескольких файлов можно добиться простым вызовом метода PlayItem с нужными индексами.

Сделать чтобы несколько файлов играли одновременно и бесконечно - это Вы, я думаю сможете самостоятельно, но на первых порах это вряд ли Вам понадобится.

   
 

 

   
  [Назад] [Все уроки]    
       
 

Обновления и новости о развитии Delphi DirectX проекта
смотри на сайтах:

http://www.megainformaticsite.pochta.ru

http://www.megainformatic.boom.ru

http://www.megainformatic.narod.ru

 

   
       
 

Cвои пожелания, вопросы или заметки отправляйте на:

megainformatic@mail.ru

 
     
   Обмен ссылками  
     
     
             
 
 
         
(с) МЕГА ИНФОРМАТИК 2006-2009
Hosted by uCoz