@@ -8,6 +8,19 @@ namespace OpenAL {
88
99static ALCdevice* AlcDevice = 0 ;
1010static ALCcontext* AlcContext = 0 ;
11+ static bool IsReopenSupported = false ;
12+ #if ALC_SOFT_system_events
13+ static LPALCEVENTCALLBACKSOFT EventCallBackFunc = 0 ;
14+ static LPALCEVENTCONTROLSOFT EventControlFunc = 0 ;
15+ #endif
16+ #if ALC_SOFT_reopen_device
17+ static LPALCREOPENDEVICESOFT ReopenSoftFunc = 0 ;
18+ #endif
19+ void AL_APIENTRY DefaultDeviceChangedEventCallback (
20+ ALCenum eventType, ALCenum deviceType, ALCdevice* device, ALCsizei length,
21+ const ALCchar* message, void * userParam) {
22+ *(bool *)userParam = true ;
23+ }
1124
1225bool AudioBackend::Init () {
1326 AlcDevice = alcOpenDevice (NULL );
@@ -16,10 +29,41 @@ bool AudioBackend::Init() {
1629 " Could not create OpenAL device\n " );
1730 return false ;
1831 }
32+ AlcContext = alcCreateContext (AlcDevice, NULL );
33+ if (!AlcContext || !alcMakeContextCurrent (AlcContext)) {
34+ ImpLog (LogLevel::Fatal, LogChannel::Audio,
35+ " Failed to create OpenAL context\n " );
36+ alcCloseDevice (AlcDevice);
37+ return false ;
38+ }
1939 if (alIsExtensionPresent (" AL_EXT_float32" ) == AL_FALSE ) {
2040 ImpLog (LogLevel::Error, LogChannel::Audio,
2141 " No floating-point audio support, some decoders may fail\n " );
2242 }
43+ InitAlextFunctions ();
44+ return true ;
45+ }
46+
47+ bool AudioBackend::Reinit () {
48+ DeviceChanged = false ;
49+ #if ALC_SOFT_reopen_device
50+ if (IsReopenSupported) {
51+ if (ReopenSoftFunc) {
52+ return ReopenSoftFunc (AlcDevice, NULL , NULL );
53+ } else {
54+ ImpLog (LogLevel::Error, LogChannel::Audio,
55+ " Reopen support is present but function was not found falling "
56+ " back to manual reopen\n " );
57+ }
58+ }
59+ #endif
60+ Shutdown ();
61+ AlcDevice = alcOpenDevice (NULL );
62+ if (!AlcDevice) {
63+ ImpLog (LogLevel::Fatal, LogChannel::Audio,
64+ " Could not create OpenAL device\n " );
65+ return false ;
66+ }
2367 AlcContext = alcCreateContext (AlcDevice, NULL );
2468 if (!AlcContext || !alcMakeContextCurrent (AlcContext)) {
2569 ImpLog (LogLevel::Fatal, LogChannel::Audio,
@@ -35,6 +79,49 @@ void AudioBackend::Shutdown() {
3579 if (AlcDevice) alcCloseDevice (AlcDevice);
3680}
3781
82+ bool AudioBackend::DidDeviceChanged () { return DeviceChanged; }
83+
84+ bool AudioBackend::ReopenSupported () {
85+ #if ALC_SOFT_reopen_device
86+ return IsReopenSupported && ReopenSoftFunc && EventControlFunc &&
87+ EventCallBackFunc;
88+ #else
89+ return false ;
90+ #endif
91+ }
92+
93+ void AudioBackend::InitAlextFunctions () {
94+ #if ALC_SOFT_system_events
95+ if (alcIsExtensionPresent (AlcDevice, " ALC_SOFT_system_events" ) == AL_TRUE ) {
96+ EventControlFunc = (LPALCEVENTCONTROLSOFT )alcGetProcAddress (
97+ AlcDevice, " alcEventControlSOFT" );
98+ if (EventControlFunc) {
99+ const ALCenum eventType{ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT };
100+ EventControlFunc (1 , &eventType, AL_TRUE );
101+ }
102+
103+ EventCallBackFunc = (LPALCEVENTCALLBACKSOFT )alcGetProcAddress (
104+ AlcDevice, " alcEventCallbackSOFT" );
105+ if (EventCallBackFunc) {
106+ EventCallBackFunc ((ALCEVENTPROCTYPESOFT )DefaultDeviceChangedEventCallback,
107+ &DeviceChanged);
108+ }
109+ #if ALC_SOFT_reopen_device
110+ if (alcIsExtensionPresent (AlcDevice, " ALC_SOFT_reopen_device" ) ==
111+ AL_FALSE ) {
112+ ImpLog (LogLevel::Error, LogChannel::Audio,
113+ " No device reopen support,will be done manually\n " );
114+ } else {
115+ IsReopenSupported = true ;
116+ ReopenSoftFunc = (LPALCREOPENDEVICESOFT )alcGetProcAddress (
117+ AlcDevice, " alcReopenDeviceSOFT" );
118+ if (!ReopenSoftFunc) IsReopenSupported = false ;
119+ }
120+ #endif
121+ }
122+ #endif
123+ }
124+
38125}; // namespace OpenAL
39126}; // namespace Audio
40127}; // namespace Impacto
0 commit comments