|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
BASS.dll и MOD-файл: не удаётся распознать окончание звучания трека
Здравствуйте!
Никак не получается распознать момент завершения трека: Код:
unit BGMusic; interface uses Classes, Windows, SysUtils, BASS; type TMelodies = class(TThread) private { Private declarations } Handle: Cardinal; Folder: String; procedure RunPlay(); procedure Error(msg: string); protected procedure Execute; override; public constructor Create(CreateSuspennded: Boolean; const idHandle: Cardinal; const idPath: string); end; implementation var MODFile: PChar; Melody: HMUSIC; PlaySync: HSYNC; constructor TMelodies.Create(CreateSuspennded: Boolean; const idHandle: Cardinal; const idPath: string); begin inherited Create(CreateSuspennded); Handle := idHandle; Folder := idPath; // check the correct BASS was loaded if (HIWORD(BASS_GetVersion) <> BASSVERSION) then begin MessageBox(0,'An incorrect version of BASS.DLL was loaded',nil,MB_ICONERROR); Halt; end; // Initialize audio - default device, 44100hz, stereo, 16 bits if not BASS_Init(-1, 44100, 0, Handle, nil) then Error('Error initializing audio!'); BASS_Start(); end; procedure TMelodies.Error(msg: string); var s: string; begin s := msg + #13#10 + '(Error code: ' + IntToStr(BASS_ErrorGetCode) + ')'; MessageBox(Handle, PChar(s), nil, 0); end; // Процедура которая будет вызвана по окончанию проигривания файла procedure ChannelEndSync(handle: HSYNC; Stream, data: DWORD; user: Pointer); stdcall; begin // Вот здесь обрабатывайте окончание! // Когда Channel доиграет до конца, то будет вызвана эта процедура // Например освободим этот поток который проигрался // Сперва удалим обработку BASS_ChannelRemoveSync(Stream, handle); // Освободим поток BASS_MusicFree(handle); // Очистим переменные Melody := 0; PlaySync := 0; // Покажем пользователю что файл проигран до конца... MessageBox(Handle, PChar('Файл проигран!'), nil, 0); end; procedure TMelodies.RunPlay(); begin MODFile := PChar(Folder + 'music.mod'); Melody := BASS_MusicLoad(False, MODFile, 0, 0, 0, 0); BASS_ChannelRemoveSync(Melody, PlaySync); PlaySync := BASS_ChannelSetSync(Melody, BASS_SYNC_END, 0, @ChannelEndSync, nil); if not BASS_ChannelPlay(Melody, False) then Error('Error playing music!'); end; procedure TMelodies.Execute; begin { Place thread code here } // while not Terminated do Synchronize(RunPlay); end; end. Прошу Вашей помощи. |
#2
|
||||
|
||||
Цитата:
Код:
Melody := BASS_MusicLoad(False, MODFile, 0, 0, BASS_MUSIC_STOPBACK, 0); |
#3
|
|||
|
|||
Проблему решил, и для тех, кому возможно с подобным столкнётся, выкладываю решение.
Поскольку мне было необходимо в игре реализовать фоновое звучание только трекерной музыки, то я взял библиотеку BASSMOD.dll и вот что получилось: Код:
unit BGMusic; interface uses Classes, Windows, SysUtils, Math, BASSMOD; type TMelodies = class(TThread) private { Private declarations } Handle: Cardinal; procedure Error(msg: string); protected procedure Execute; override; public constructor Create(CreateSuspennded: Boolean; const idHandle: Cardinal); destructor Destroy; override; end; procedure RunPlay(); implementation {$R Melodies.res} var Previous: Byte; MODHandle: Cardinal; MODPointer: Pointer; MODSize: Cardinal; PlaySync: HSYNC; constructor TMelodies.Create(CreateSuspennded: Boolean; const idHandle: Cardinal); begin inherited Create(CreateSuspennded); Handle := idHandle; if BASSMOD_GetVersion <> MAKELONG(2,0) then begin Error('Библиотека BASSMOD.dll не загружена!'); self.Destroy; Halt; end; if not BASSMOD_Init(-1,44100,0) then begin Error('Не возможно инициировать устройство вывода звука'); self.Destroy; Halt; end; end; destructor TMelodies.Destroy; begin BASSMOD_MusicStop; BASSMOD_Free; end; procedure TMelodies.Error(msg: string); var s: string; begin s := msg + #13#10 + '(Error code: ' + IntToStr(BASSMOD_ErrorGetCode) + ')'; MessageBox(Handle, PChar(s), nil, 0); end; // Процедура которая будет вызвана по окончанию проигривания файла procedure ChannelEndSync(handle: HSYNC; data: DWORD; user: Pointer); stdcall; begin BASSMOD_MusicStop; BASSMOD_MusicFree(); RunPlay; end; procedure RunPlay(); var melody: PChar; number: Byte; begin repeat Randomize; number := RandomRange(10, 19); until Previous <> number; {звучала ли мелодия только-что?} melody := PChar('MELODY_' + IntToStr(number)); MODHandle:=FindResource(hInstance, melody, RT_RCDATA); MODPointer:=LockResource(LoadResource(hInstance, MODHandle)); MODSize:=SizeOfResource(hInstance, MODHandle); BASSMOD_MusicLoad(True, MODPointer, 0, 0, BASS_MUSIC_STOPBACK); BASSMOD_MusicRemoveSync(PlaySync); PlaySync := BASSMOD_MusicSetSync(BASS_SYNC_END, 0, @ChannelEndSync, 0); BASSMOD_MusicPlay; end; procedure TMelodies.Execute; begin RunPlay; end; end. Сами мелодии помещены в файл ресурсов, и одна за другой проигрываются в случайном порядке. |