Skip to content

Commit

Permalink
OpenCanopy: Basic audio assist support (acidanthera#74)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Belyaev <[email protected]>
Co-authored-by: vit9696 <[email protected]>
  • Loading branch information
3 people authored Dec 16, 2020
1 parent 2b98adf commit d815a83
Show file tree
Hide file tree
Showing 15 changed files with 195 additions and 28 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ OpenCore Changelog
- Updated underlying EDK II package to edk2-stable202011
- Updated builtin firmware versions for SMBIOS and the rest
- Fixed macrecovery server protocol compatibility
- Added basic audio assistant support in OpenCanopy

#### v0.6.4
- Added `BlacklistAppleUpdate` to fix macOS 11 broken update optout
Expand Down
66 changes: 65 additions & 1 deletion Include/Acidanthera/Library/OcBootManagementLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,50 @@ INTN
OUT BOOLEAN *SetDefault OPTIONAL
);


/**
Play audio file for context.
**/
typedef
EFI_STATUS
(EFIAPI *OC_PLAY_AUDIO_FILE) (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File,
IN BOOLEAN Fallback
);

/**
Generate cycles of beep signals for context with silence afterwards, blocking.
**/
typedef
EFI_STATUS
(EFIAPI *OC_PLAY_AUDIO_BEEP) (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 ToneCount,
IN UINT32 ToneLength,
IN UINT32 SilenceLength
);

/**
Play audio entry for context.
**/
typedef
EFI_STATUS
(EFIAPI *OC_PLAY_AUDIO_ENTRY) (
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *Entry
);

/**
Toggle VoiceOver support.
**/
typedef
VOID
(EFIAPI *OC_TOGGLE_VOICE_OVER) (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File OPTIONAL
);

/**
Picker behaviour action.
**/
Expand Down Expand Up @@ -680,6 +724,22 @@ struct OC_PICKER_CONTEXT_ {
//
APPLE_BEEP_GEN_PROTOCOL *BeepGen;
//
// Play audio file function.
//
OC_PLAY_AUDIO_FILE PlayAudioFile;
//
// Play audio beep function.
//
OC_PLAY_AUDIO_BEEP PlayAudioBeep;
//
// Play audio entry function.
//
OC_PLAY_AUDIO_ENTRY PlayAudioEntry;
//
// Toggle VoiceOver function.
//
OC_TOGGLE_VOICE_OVER ToggleVoiceOver;
//
// Recovery initiator if present.
//
EFI_DEVICE_PATH_PROTOCOL *RecoveryInitiator;
Expand Down Expand Up @@ -1234,6 +1294,7 @@ OcRunFirmwareApplication (
@retval EFI_SUCCESS on success or when unnecessary.
**/
EFI_STATUS
EFIAPI
OcPlayAudioFile (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File,
Expand All @@ -1251,6 +1312,7 @@ OcPlayAudioFile (
@retval EFI_SUCCESS on success or when unnecessary.
**/
EFI_STATUS
EFIAPI
OcPlayAudioBeep (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 ToneCount,
Expand All @@ -1259,14 +1321,15 @@ OcPlayAudioBeep (
);

/**
Play audio file for context.
Play audio entry for context.
@param[in] Context Picker context.
@param[in] Entry Entry to play.
@retval EFI_SUCCESS on success or when unnecessary.
**/
EFI_STATUS
EFIAPI
OcPlayAudioEntry (
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *Entry
Expand All @@ -1279,6 +1342,7 @@ OcPlayAudioEntry (
@param[in] File File to play after enabling VoiceOver.
**/
VOID
EFIAPI
OcToggleVoiceOver (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File OPTIONAL
Expand Down
4 changes: 4 additions & 0 deletions Library/OcBootManagementLib/BootAudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <Library/UefiLib.h>

EFI_STATUS
EFIAPI
OcPlayAudioFile (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File,
Expand Down Expand Up @@ -138,6 +139,7 @@ OcPlayAudioFile (
}

EFI_STATUS
EFIAPI
OcPlayAudioBeep (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 ToneCount,
Expand Down Expand Up @@ -170,6 +172,7 @@ OcPlayAudioBeep (
}

EFI_STATUS
EFIAPI
OcPlayAudioEntry (
IN OC_PICKER_CONTEXT *Context,
IN OC_BOOT_ENTRY *Entry
Expand Down Expand Up @@ -207,6 +210,7 @@ OcPlayAudioEntry (
}

VOID
EFIAPI
OcToggleVoiceOver (
IN OC_PICKER_CONTEXT *Context,
IN UINT32 File OPTIONAL
Expand Down
4 changes: 4 additions & 0 deletions OpenCorePkg.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
objects = {

/* Begin PBXBuildFile section */
35081D4A248177E4006EB0EB /* InputSimTextIn.c in Sources */ = {isa = PBXBuildFile; fileRef = 350857D82421373F005A0D86 /* InputSimTextIn.c */; };
35081D4B248177ED006EB0EB /* InputSimAbsPtr.c in Sources */ = {isa = PBXBuildFile; fileRef = 350857D92421373F005A0D86 /* InputSimAbsPtr.c */; };
350857EC24216525005A0D86 /* OcUnicodeLib.c in Sources */ = {isa = PBXBuildFile; fileRef = 35366A95240C213400D54CBB /* OcUnicodeLib.c */; };
350857ED24220712005A0D86 /* GuiApp.c in Sources */ = {isa = PBXBuildFile; fileRef = 350857D42421373F005A0D86 /* GuiApp.c */; };
350857EE2422071A005A0D86 /* OpenCanopy.h in Headers */ = {isa = PBXBuildFile; fileRef = 350857DA2421373F005A0D86 /* OpenCanopy.h */; };
Expand Down Expand Up @@ -1955,6 +1957,7 @@
3511D59323FDB2A800CC3B17 /* OpenCoreMisc.c in Sources */,
35366C04240C213500D54CBB /* DataHub.c in Sources */,
3511D59523FDB2A800CC3B17 /* OpenCoreDevProps.c in Sources */,
35081D4A248177E4006EB0EB /* InputSimTextIn.c in Sources */,
35366CCC240C213500D54CBB /* OcXmlLib.c in Sources */,
35366CC1240C213500D54CBB /* FileProtocol.c in Sources */,
35366C95240C213500D54CBB /* OcAppleDiskImageLib.c in Sources */,
Expand Down Expand Up @@ -2046,6 +2049,7 @@
35366C00240C213500D54CBB /* OcPng.c in Sources */,
35366C27240C213500D54CBB /* Sha1.c in Sources */,
35366C91240C213500D54CBB /* AIM.c in Sources */,
35081D4B248177ED006EB0EB /* InputSimAbsPtr.c in Sources */,
35366CE1240C213500D54CBB /* OcAppleRamDiskLib.c in Sources */,
35366CC7240C213500D54CBB /* AppleCpuSupport.c in Sources */,
35366CC3240C213500D54CBB /* LocateFileSystem.c in Sources */,
Expand Down
2 changes: 0 additions & 2 deletions Platform/OpenCanopy/GuiApp.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,6 @@ InternalContextConstruct (
+ Context->BackgroundColor.Pixel.Blue * 114U) >= 186000;
}

Context->BootEntry = NULL;

Status = EFI_SUCCESS;

for (Index = 0; Index < ICON_NUM_TOTAL; ++Index) {
Expand Down
5 changes: 4 additions & 1 deletion Platform/OpenCanopy/GuiApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ typedef struct _BOOT_PICKER_GUI_CONTEXT {
BOOLEAN Refresh;
BOOLEAN LightBackground;
BOOLEAN DoneIntroAnimation;
BOOLEAN ReadyToBoot;
UINT8 Scale;
UINT32 CursorDefaultX;
UINT32 CursorDefaultY;
INT32 AudioPlaybackTimeout;
OC_PICKER_CONTEXT *PickerContext;
} BOOT_PICKER_GUI_CONTEXT;

EFI_STATUS
Expand All @@ -95,7 +98,7 @@ BootPickerViewInitialize (
EFI_STATUS
BootPickerEntriesAdd (
IN OC_PICKER_CONTEXT *Context,
IN CONST BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN BOOT_PICKER_GUI_CONTEXT *GuiContext,
IN OC_BOOT_ENTRY *Entry,
IN BOOLEAN Default
);
Expand Down
39 changes: 39 additions & 0 deletions Platform/OpenCanopy/OcBootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ OcShowMenuByOc (

*ChosenBootEntry = NULL;
mGuiContext.BootEntry = NULL;
mGuiContext.ReadyToBoot = FALSE;
mGuiContext.HideAuxiliary = BootContext->PickerContext->HideAuxiliary;
mGuiContext.Refresh = FALSE;
mGuiContext.PickerContext = BootContext->PickerContext;
mGuiContext.AudioPlaybackTimeout = -1;

Status = GuiLibConstruct (
BootContext->PickerContext,
Expand All @@ -67,6 +70,13 @@ OcShowMenuByOc (
//
gST->ConOut->TestString (gST->ConOut, OC_CONSOLE_MARK_CONTROLLED);

//
// Do not play intro animation for blind.
//
if (BootContext->PickerContext->PickerAudioAssist) {
mGuiContext.DoneIntroAnimation = TRUE;
}

Status = BootPickerViewInitialize (
&mDrawContext,
&mGuiContext,
Expand All @@ -90,6 +100,35 @@ OcShowMenuByOc (
}
}

GuiRedrawAndFlushScreen (&mDrawContext);

if (BootContext->PickerContext->PickerAudioAssist) {
BootContext->PickerContext->PlayAudioFile (
BootContext->PickerContext,
OcVoiceOverAudioFileChooseOS,
FALSE
);
for (Index = 0; Index < BootContext->BootEntryCount; ++Index) {
BootContext->PickerContext->PlayAudioEntry (
BootContext->PickerContext,
BootEntries[Index]
);
if (BootContext->PickerContext->TimeoutSeconds > 0 && BootContext->DefaultEntry->EntryIndex - 1 == Index) {
BootContext->PickerContext->PlayAudioFile (
BootContext->PickerContext,
OcVoiceOverAudioFileDefault,
FALSE
);
}
}
BootContext->PickerContext->PlayAudioBeep (
BootContext->PickerContext,
OC_VOICE_OVER_SIGNALS_NORMAL,
OC_VOICE_OVER_SIGNAL_NORMAL_MS,
OC_VOICE_OVER_SILENCE_NORMAL_MS
);
}

GuiDrawLoop (&mDrawContext, BootContext->PickerContext->TimeoutSeconds);
ASSERT (mGuiContext.BootEntry != NULL || mGuiContext.Refresh);

Expand Down
41 changes: 28 additions & 13 deletions Platform/OpenCanopy/OpenCanopy.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ typedef struct {
UINT32 MaxY;
} GUI_DRAW_REQUEST;

//
// Variables to assign the picked volume automatically once menu times out
//
extern BOOT_PICKER_GUI_CONTEXT mGuiContext;
extern GUI_VOLUME_PICKER mBootPicker;

//
// I/O contexts
//
Expand Down Expand Up @@ -1143,13 +1137,14 @@ GuiDrawLoop (
CONST LIST_ENTRY *AnimEntry;
CONST GUI_ANIMATION *Animation;
UINT64 LoopStartTsc;
UINT64 LastTsc;
UINT64 NewLastTsc;

ASSERT (DrawContext != NULL);

mNumValidDrawReqs = 0;
HoldObject = NULL;

GuiRedrawAndFlushScreen (DrawContext);
//
// Clear previous inputs.
//
Expand All @@ -1160,7 +1155,7 @@ GuiDrawLoop (
//
// Main drawing loop, time and derieve sub-frequencies as required.
//
LoopStartTsc = mStartTsc = AsmReadTsc ();
LastTsc = LoopStartTsc = mStartTsc = AsmReadTsc ();
do {
if (mPointerContext != NULL) {
//
Expand Down Expand Up @@ -1252,17 +1247,37 @@ GuiDrawLoop (
//
GuiFlushScreen (DrawContext);

NewLastTsc = AsmReadTsc ();

if (DrawContext->GuiContext->AudioPlaybackTimeout >= 0
&& DrawContext->GuiContext->PickerContext->PickerAudioAssist) {
DrawContext->GuiContext->AudioPlaybackTimeout -= (INT32) (DivU64x32 (
GetTimeInNanoSecond (NewLastTsc - LastTsc),
1000000
));
if (DrawContext->GuiContext->AudioPlaybackTimeout <= 0) {
DrawContext->GuiContext->PickerContext->PlayAudioFile (
DrawContext->GuiContext->PickerContext,
OcVoiceOverAudioFileSelected,
FALSE
);
DrawContext->GuiContext->PickerContext->PlayAudioEntry (
DrawContext->GuiContext->PickerContext,
DrawContext->GuiContext->BootEntry
);
}
}

//
// Exit early if reach timer timeout and timer isn't disabled due to key event
//
if (TimeOutSeconds > 0
&& GetTimeInNanoSecond (AsmReadTsc () - LoopStartTsc) >= TimeOutSeconds * 1000000000ULL) {
//
// FIXME: There should be view function or alike.
//
mGuiContext.BootEntry = mBootPicker.SelectedEntry->Context;
&& GetTimeInNanoSecond (NewLastTsc - LoopStartTsc) >= TimeOutSeconds * 1000000000ULL) {
DrawContext->GuiContext->ReadyToBoot = TRUE;
break;
}

LastTsc = NewLastTsc;
} while (!DrawContext->ExitLoop (DrawContext->GuiContext));
}

Expand Down
17 changes: 11 additions & 6 deletions Platform/OpenCanopy/OpenCanopy.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,12 @@ struct GUI_DRAWING_CONTEXT_ {
//
// Scene objects
//
GUI_OBJ *Screen;
GUI_CURSOR_GET_IMAGE GetCursorImage;
GUI_EXIT_LOOP ExitLoop;
LIST_ENTRY Animations;
VOID *GuiContext;
UINT8 Scale;
GUI_OBJ *Screen;
GUI_CURSOR_GET_IMAGE GetCursorImage;
GUI_EXIT_LOOP ExitLoop;
LIST_ENTRY Animations;
BOOT_PICKER_GUI_CONTEXT *GuiContext;
UINT8 Scale;
};

EFI_STATUS
Expand Down Expand Up @@ -250,6 +250,11 @@ GuiViewCurrentCursor (
IN OUT GUI_DRAWING_CONTEXT *DrawContext
);

VOID
GuiRedrawAndFlushScreen (
IN OUT GUI_DRAWING_CONTEXT *DrawContext
);

VOID
GuiDrawLoop (
IN OUT GUI_DRAWING_CONTEXT *DrawContext,
Expand Down
Loading

0 comments on commit d815a83

Please sign in to comment.