Есть несколько демонстрационных примеров аркадных игр с аудио классами, которые вы можете использовать. Смотри https://github.com/Embarcadero/DelphiArcadeGames
Вы также можете увидеть этот вопрос stackoverflow Есть ли альтернатива TMediaPlayer для многоплатформенных быстрых звуковых эффектов? для описания некоторых проблем, возникающих на Android с классом управления звуком в этих демонстрациях.
С последней версией аудио-менеджера, представленной в примерах игр, разработчик просто удаляет все уведомления / проверяет, что аудио-файл действительно загружен и готов к воспроизведению. Мне лично не понравилась идея просто ожидать, что аудио будет готово для воспроизведения.
Мои классы управления аудио слишком сложны, чтобы просто публиковать их, но, если вам нужна эта функциональность, надеюсь, этот кусочек псевдокода может дать некоторые подсказки о том, как я исправил недостатки «AudioManager», представленные в демонстрационных версиях игры. Идея состоит в том, чтобы создать обратный вызов в моем основном приложении, который вызывается, когда аудиофайл готов к воспроизведению. С помощью небольшого поиска в Интернете я обнаружил, что следующие ссылки являются полезными для моей реализации:
https://developer.android.com/reference/android/media/SoundPool
https://www.101apps.co.za/articles/using-android-s-soundpool-class-a-tutorial.html
1 - Определите тип уведомления, который предоставит достаточную информацию о аудиофайле, который готов к воспроизведению. Моя выглядит так:
TSoundLoadedEvent = procedure(Sender: TObject; ASoundID: integer; AStatus: Integer) of object;
2 - В соответствии с документацией определите класс, который обрабатывает JSoundPool OnLoadCompleteListener. Обратите внимание, что класс использует наше пользовательское событие, определенное как TSoundLoadedEvent, что означает, что AudioManager должен будет реализовать этот обратный вызов.
TMyAudioLoadedListener = class(TJavaLocal, JSoundPool_OnLoadCompleteListener)
private
FSoundPool : JSoundPool;
FOnJLoadCompleted : TSoundLoadedEvent;
public
procedure onLoadComplete(soundPool: JSoundPool; sampleId,status: Integer); cdecl;
property OnLoadCompleted: TSoundLoadedEvent read FOnJLoadCompleted write FOnJLoadCompleted;
property SoundPool: JSoundPool read FSoundPool;
end;
...
procedure TMyAudioLoadedListener.onLoadComplete(soundPool: JSoundPool; sampleId, status: Integer);
begin
FSoundPool := soundPool;
if Assigned(FOnJLoadCompleted) then
FOnJLoadCompleted(Self, sampleID, status);
end;
3 - Изменить класс аудио-менеджера для реализации слушателя. :
TAudioManager = Class
Private
fAudioMgr : JAudioManager;
fSoundPool : JSoundPool;
fmyAudioLoadedListener : TMyAudioLoadedListener;
fOnPlatformLoadComplete : TSoundLoadedEvent;
Public
Constructor Create; override;
...
procedure DoOnLoadComplete(Sender: TObject; sampleId: Integer; status: Integer);
...
property OnLoadComplete: TSoundLoadedEvent read fOnPlatformLoadComplete write fOnPlatformLoadComplete;
4 - Реализовать прослушиватель JSoundPool и подключить обратный вызов от прослушивателя к нашему AudioManager:
constructor TAudioManger.Create;
begin
...
//create our listener
fmyAudioLoadedListener := TMyAudioLoadedListener.Create;
// set the listener callback
fmyAudioLoadedListener.OnLoadCompleted := DoOnLoadComplete;
// inform JSoundPool that we have a listener
fSoundPool.setOnLoadCompleteListener( fmyAudioLoadedListener );
...
И
procedure TAudioManager.DoOnLoadComplete(Sender: TObject; sampleId: Integer; status: Integer);
begin
if Succeeded(status) then //remove this if you want all notifications
begin
if Assigned(Self.fOnPlatformLoadComplete) then
fOnPlatformLoadComplete( self, sampleID, status );
end;
end;
5 - Последнее, что нужно сделать для обратного вызова в основном приложении
TMainForm = class(TForm)
...
fAudioMgr : TAudioManager;
...
procedure OnSoundLoaded(Sender: TObject; ASoundID: integer; AStatus: integer);
Затем при создании AudioManager назначьте новый TSoundLoadedEvent локальной процедуре, которую я вызвал OnSoundLoaded.
TMainForm.FormCreate(Sender: TObject);
...
begin
...
fAudioMgr := TAudioManager.Create;
fAudioMgr.OnSoundLoaded := OnSoundLoaded;
Теперь, когда аудиофайл готов к воспроизведению, вы должны получить уведомление.
procedure TMainForm.OnSoundLoaded(Sender: TObject; ASoundID: integer; AStatus: integer);
begin
// track IDs when loading sounds to identify which one is ready
// check status to confirm that the audio was loadded successfully
end;
Это определенно только кусочки, но, надеюсь, может быть полезным.