Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Мультимедиа
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 13.05.2011, 23:42
At3iSt At3iSt вне форума
Прохожий
 
Регистрация: 03.05.2011
Сообщения: 3
Версия Delphi: Delphi2007win32
Репутация: 10
Вопрос 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.
по идее, при завершении трека, управление должно передаваться процедуре ChannelEndSync... однако этого не происходит.

Прошу Вашей помощи.
Ответить с цитированием
  #2  
Старый 14.05.2011, 11:27
Аватар для ryderx34
ryderx34 ryderx34 вне форума
Активный
 
Регистрация: 22.01.2010
Сообщения: 211
Версия Delphi: 7, 2010
Репутация: 1349
По умолчанию

Цитата:
Note that some MOD musics never reach the end; they may jump to another position first. If the BASS_MUSIC_STOPBACK flag is used with a MOD music (through BASS_MusicLoad or BASS_ChannelFlags), then this sync will also be called when a backward jump effect is played.
Код:
Melody := BASS_MusicLoad(False, MODFile, 0, 0, BASS_MUSIC_STOPBACK, 0);
Ответить с цитированием
  #3  
Старый 15.05.2011, 12:31
At3iSt At3iSt вне форума
Прохожий
 
Регистрация: 03.05.2011
Сообщения: 3
Версия Delphi: Delphi2007win32
Репутация: 10
По умолчанию

Проблему решил, и для тех, кому возможно с подобным столкнётся, выкладываю решение.

Поскольку мне было необходимо в игре реализовать фоновое звучание только трекерной музыки, то я взял библиотеку 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.

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


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:41.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter