OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
OcAudioLib.c
Go to the documentation of this file.
1
15#include <Guid/AppleVariable.h>
16
17#include <Library/DebugLib.h>
18#include <Library/DevicePathLib.h>
19#include <Library/MemoryAllocationLib.h>
20#include <Library/OcAudioLib.h>
22#include <Library/OcMiscLib.h>
23#include <Library/UefiBootServicesTableLib.h>
24#include <Library/UefiRuntimeServicesTableLib.h>
25
26#include <Protocol/AppleHda.h>
29
30#include "OcAudioInternal.h"
31
32//
33// OC audio protocol must come first in this list.
34//
35STATIC
36EFI_GUID *
43
44STATIC
48 .AudioIo = NULL,
49 .ProviderAcquire = NULL,
50 .ProviderRelease = NULL,
51 .ProviderContext = NULL,
52 .CurrentBuffer = NULL,
53 .PlaybackEvent = NULL,
54 .PlaybackDelay = 0,
55 .Language = AppleVoiceOverLanguageEn,
56 .OutputIndexMask = 0,
58 .OcAudio = {
60 .Connect = InternalOcAudioConnect,
61 .RawGainToDecibels = InternalOcAudioRawGainToDecibels,
62 .SetDefaultGain = InternalOcAudioSetDefaultGain,
63 .SetProvider = InternalOcAudioSetProvider,
64 .PlayFile = InternalOcAudioPlayFile,
65 .StopPlayback = InternalOcAudioStopPlayback,
66 .SetDelay = InternalOcAudioSetDelay
67 },
68 .BeepGen = {
69 .GenBeep = InternalOcAudioGenBeep,
70 },
71 .VoiceOver = {
76 }
77};
78
81 IN BOOLEAN Reinstall,
82 IN BOOLEAN DisconnectHda
83 )
84{
85 EFI_STATUS Status;
86 UINTN Index;
87 VOID *Protocol;
88 EFI_HANDLE NewHandle;
89
90 DEBUG ((DEBUG_INFO, "OCAU: OcAudioInstallProtocols (%u, %u)\n", Reinstall, DisconnectHda));
91
92 if (DisconnectHda) {
94 }
95
96 if (Reinstall) {
97 for (Index = 0; Index < ARRAY_SIZE (mAudioProtocols); ++Index) {
99 if (EFI_ERROR (Status)) {
100 DEBUG ((DEBUG_ERROR, "OCAU: Uninstall %g failed - %r\n", mAudioProtocols[Index], Status));
101 return NULL;
102 }
103 }
104 } else {
105 DEBUG_CODE_BEGIN ();
106 for (Index = 0; Index < ARRAY_SIZE (mAudioProtocols); ++Index) {
107 Status = gBS->LocateProtocol (
108 mAudioProtocols[Index],
109 NULL,
110 &Protocol
111 );
112 DEBUG ((DEBUG_INFO, "OCAU: %g protocol - %r\n", mAudioProtocols[Index], Status));
113 }
114
115 DEBUG_CODE_END ();
116 for (Index = 0; Index < ARRAY_SIZE (mAudioProtocols); ++Index) {
117 Status = gBS->LocateProtocol (
118 mAudioProtocols[Index],
119 NULL,
120 &Protocol
121 );
122 if (!EFI_ERROR (Status)) {
123 if (Index == 0) {
124 return (OC_AUDIO_PROTOCOL *)Protocol;
125 }
126
127 return NULL;
128 }
129 }
130 }
131
132 Status = gBS->CreateEvent (
133 0,
134 TPL_NOTIFY,
135 NULL,
136 NULL,
138 );
139 if (EFI_ERROR (Status)) {
140 DEBUG ((DEBUG_INFO, "OCAU: Unable to create audio completion event - %r\n", Status));
141 return NULL;
142 }
143
144 NewHandle = NULL;
145 Status = gBS->InstallMultipleProtocolInterfaces (
146 &NewHandle,
153 NULL
154 );
155
156 if (EFI_ERROR (Status)) {
157 gBS->CloseEvent (mAudioProtocol.PlaybackEvent);
159 return NULL;
160 }
161
162 return &mAudioProtocol.OcAudio;
163}
164
165VOID
167 OUT UINT8 *RawGain,
168 OUT INT8 *DecibelGain,
169 OUT BOOLEAN *Muted,
170 OUT BOOLEAN *TryConversion
171 )
172{
173 EFI_STATUS Status1;
174 EFI_STATUS Status2;
175 UINTN Size;
176
177 //
178 // Get mute setting and raw codec gain setting (all versions of macOS).
179 //
180 Size = sizeof (*RawGain);
181 Status1 = gRT->GetVariable (
184 NULL,
185 &Size,
186 RawGain
187 );
188 if (!EFI_ERROR (Status1)) {
189 *Muted = (*RawGain & APPLE_SYSTEM_AUDIO_VOLUME_MUTED) != 0;
191 } else {
192 *Muted = FALSE;
193 *RawGain = 0;
194 }
195
196 DEBUG ((
197 DEBUG_INFO,
198 "OCAU: System raw gain 0x%X, audio mute (for chime) %u - %r\n",
199 *RawGain,
200 *Muted,
201 Status1
202 ));
203
204 //
205 // Get dB gain setting, which can be correctly applied to any amp on any codec if available.
206 // (Not present at least in Lion 10.7 and earlier.)
207 //
208 Size = sizeof (*DecibelGain);
209 Status2 = gRT->GetVariable (
212 NULL,
213 &Size,
214 DecibelGain
215 );
216 if (EFI_ERROR (Status2)) {
217 *DecibelGain = OC_AUDIO_DEFAULT_GAIN;
218 }
219
220 DEBUG ((
221 DEBUG_INFO,
222 "OCAU: System decibel gain %d dB%a - %r\n",
223 *DecibelGain,
224 *Muted ? " (probably invalid due to mute)" : "",
225 Status2
226 ));
227
228 //
229 // SystemAudioVolumeDB does not contain sane values when SystemAudioVolume indicates muted, so we have
230 // to fall back to default gain value or conversion; for use with audio assist, which never mutes.
231 //
232 if (*Muted) {
233 *DecibelGain = OC_AUDIO_DEFAULT_GAIN;
234 Status2 = EFI_INVALID_PARAMETER;
235 }
236
237 //
238 // If no saved decibel gain, but saved raw gain, it is worth trying to convert.
239 //
240 *TryConversion = !EFI_ERROR (Status1) && EFI_ERROR (Status2);
241}
EFI_GUID gAppleBeepGenProtocolGuid
EFI_GUID gAppleHighDefinitionAudioProtocolGuid
#define ARRAY_SIZE(Array)
Definition AppleMacEfi.h:34
EFI_GUID gAppleBootVariableGuid
#define APPLE_SYSTEM_AUDIO_VOLUME_VARIABLE_NAME
#define APPLE_SYSTEM_AUDIO_VOLUME_DB_VARIABLE_NAME
#define APPLE_SYSTEM_AUDIO_VOLUME_VOLUME_MASK
#define APPLE_SYSTEM_AUDIO_VOLUME_DB_MIN
#define APPLE_SYSTEM_AUDIO_VOLUME_MUTED
@ AppleVoiceOverLanguageEn
en
EFI_GUID gAppleVOAudioProtocolGuid
DMG_SIZE_DEVICE_PATH Size
EFI_STATUS EFIAPI InternalOcAudioStopPlayback(IN OUT OC_AUDIO_PROTOCOL *This, IN BOOLEAN Wait)
Definition OcAudio.c:464
EFI_STATUS EFIAPI InternalOcAudioPlayFile(IN OUT OC_AUDIO_PROTOCOL *This, IN CONST CHAR8 *BasePath, IN CONST CHAR8 *BaseType, IN BOOLEAN Localised, IN INT8 Gain OPTIONAL, IN BOOLEAN UseGain, IN BOOLEAN Wait)
Definition OcAudio.c:354
EFI_STATUS EFIAPI InternalOcAudioConnect(IN OUT OC_AUDIO_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN UINT8 CodecAddress OPTIONAL, IN UINT64 OutputIndexMask)
Definition OcAudio.c:186
EFI_STATUS EFIAPI InternalOcAudioRawGainToDecibels(IN OUT OC_AUDIO_PROTOCOL *This, IN UINT8 GainParam, OUT INT8 *Gain)
Definition OcAudio.c:322
EFI_STATUS EFIAPI InternalOcAudioSetProvider(IN OUT OC_AUDIO_PROTOCOL *This, IN OC_AUDIO_PROVIDER_ACQUIRE Acquire, IN OC_AUDIO_PROVIDER_RELEASE Release OPTIONAL, IN VOID *Context)
Definition OcAudio.c:269
UINTN EFIAPI InternalOcAudioSetDelay(IN OUT OC_AUDIO_PROTOCOL *This, IN UINTN Delay)
Definition OcAudio.c:554
EFI_STATUS EFIAPI InternalOcAudioSetDefaultGain(IN OUT OC_AUDIO_PROTOCOL *This, IN INT8 Gain)
Definition OcAudio.c:170
EFI_GUID gOcAudioProtocolGuid
#define OC_AUDIO_PROTOCOL_REVISION
Definition OcAudio.h:22
EFI_STATUS EFIAPI InternalOcAudioGenBeep(IN UINT32 ToneCount, IN UINTN ToneLength, IN UINTN SilenceLength)
EFI_STATUS EFIAPI InternalOcAudioVoiceOverPlay(IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, IN UINT8 File)
EFI_STATUS EFIAPI InternalOcAudioVoiceOverGetLanguage(IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, OUT UINT8 *LanguageCode, OUT CONST CHAR8 **LanguageString)
EFI_STATUS EFIAPI InternalOcAudioVoiceOverSetLanguageCode(IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, IN UINT8 LanguageCode)
EFI_STATUS EFIAPI InternalOcAudioVoiceOverSetLanguageString(IN APPLE_VOICE_OVER_AUDIO_PROTOCOL *This, IN CONST CHAR8 *LanguageString)
#define OC_AUDIO_PROTOCOL_PRIVATE_SIGNATURE
STATIC EFI_GUID * mAudioProtocols[]
Definition OcAudioLib.c:37
STATIC OC_AUDIO_PROTOCOL_PRIVATE mAudioProtocol
Definition OcAudioLib.c:46
VOID OcGetAmplifierGain(OUT UINT8 *RawGain, OUT INT8 *DecibelGain, OUT BOOLEAN *Muted, OUT BOOLEAN *TryConversion)
Definition OcAudioLib.c:166
OC_AUDIO_PROTOCOL * OcAudioInstallProtocols(IN BOOLEAN Reinstall, IN BOOLEAN DisconnectHda)
Definition OcAudioLib.c:80
#define OC_AUDIO_DEFAULT_GAIN
Definition OcAudioLib.h:15
EFI_BOOT_SERVICES * gBS
VOID OcDisconnectHdaControllers(VOID)
EFI_STATUS OcUninstallAllProtocolInstances(EFI_GUID *Protocol)
EFI_RUNTIME_SERVICES * gRT
APPLE_BEEP_GEN_PROTOCOL BeepGen
APPLE_VOICE_OVER_AUDIO_PROTOCOL VoiceOver
OC_AUDIO_PROTOCOL OcAudio