提交 34f180af 编写于 作者: V vit9696

OpenCoreAudio: Implement mp3 decoding support

上级 f9abab42
......@@ -16,6 +16,7 @@ OpenCore Changelog
- Added `SetupDelay` to configure audio setup delay
- Reworked LogoutHook.command to support older macOS
- Improved Duet USB legacy management for supported controllers
- Implemented MP3 audio decoding for audio assistant support
#### v0.6.4
- Added `BlacklistAppleUpdate` to fix macOS 11 broken update optout
......
......@@ -5638,14 +5638,15 @@ functioning. Feature highlights:
Audio support provides a way for upstream protocols to interact with the
selected hardware and audio resources. All audio resources should reside
in \texttt{\textbackslash EFI\textbackslash OC\textbackslash Resources\textbackslash Audio}
directory. Currently the only supported audio file format is WAVE PCM. While it is
directory. Currently the supported audio file formats are MP3 and WAVE PCM. While it is
driver-dependent which audio stream format is supported, most common audio cards
support 16-bit signed stereo audio at 44100 or 48000 Hz.
Audio file path is determined by audio type, audio localisation, and audio path. Each filename
looks as follows: \texttt{[audio type]\_[audio localisation]\_[audio path].wav}. For unlocalised
files filename does not include the language code and looks as follows:
\texttt{[audio type]\_[audio path].wav}.
looks as follows: \texttt{[audio type]\_[audio localisation]\_[audio path].[audio ext]}.
For unlocalised files filename does not include the language code and looks as follows:
\texttt{[audio type]\_[audio path].[audio ext]}. Audio extension can either be \texttt{mp3}
or \texttt{wav}.
\begin{itemize}
\tightlist
......@@ -5659,7 +5660,7 @@ functioning. Feature highlights:
\href{https://github.com/acidanthera/OpenCorePkg/blob/master/Include/Apple/Protocol/AppleVoiceOver.h}{\texttt{APPLE\_VOICE\_OVER\_AUDIO\_FILE} definition}.
For OpenCore audio paths refer to
\href{https://github.com/acidanthera/OpenCorePkg/blob/master/Include/Acidanthera/Protocol/OcAudio.h}{\texttt{OC\_VOICE\_OVER\_AUDIO\_FILE} definition}.
The only exception is OpenCore boot chime file, which is \texttt{OCEFIAudio\_VoiceOver\_Boot.wav}.
The only exception is OpenCore boot chime file, which is \texttt{OCEFIAudio\_VoiceOver\_Boot.mp3}.
\end{itemize}
Audio localisation is determined separately for macOS bootloader and OpenCore.
......
\documentclass[]{article}
%DIF LATEXDIFF DIFFERENCE FILE
%DIF DEL PreviousConfiguration.tex Thu Dec 31 17:45:46 2020
%DIF ADD ../Configuration.tex Fri Jan 1 00:20:20 2021
%DIF DEL PreviousConfiguration.tex Wed Dec 16 19:38:04 2020
%DIF ADD ../Configuration.tex Sat Jan 2 07:28:05 2021
\usepackage{lmodern}
\usepackage{amssymb,amsmath}
......@@ -5698,14 +5698,16 @@ functioning. Feature highlights:
Audio support provides a way for upstream protocols to interact with the
selected hardware and audio resources. All audio resources should reside
in \texttt{\textbackslash EFI\textbackslash OC\textbackslash Resources\textbackslash Audio}
directory. Currently the only supported audio file format is WAVE PCM. While it is
directory. Currently the \DIFdelbegin \DIFdel{only }\DIFdelend supported audio file \DIFdelbegin \DIFdel{format is }\DIFdelend \DIFaddbegin \DIFadd{formats are MP3 and }\DIFaddend WAVE PCM. While it is
driver-dependent which audio stream format is supported, most common audio cards
support 16-bit signed stereo audio at 44100 or 48000 Hz.
Audio file path is determined by audio type, audio localisation, and audio path. Each filename
looks as follows: \texttt{[audio type]\_[audio localisation]\_[audio path].wav}. For unlocalised
files filename does not include the language code and looks as follows:
\texttt{[audio type]\_[audio path].wav}.
looks as follows: \texttt{[audio type]\_[audio localisation]\_[audio path].\DIFdelbegin \DIFdel{wav}\DIFdelend \DIFaddbegin [\DIFadd{audio ext}]\DIFaddend }.
For unlocalised files filename does not include the language code and looks as follows:
\texttt{[audio type]\_[audio path].\DIFdelbegin \DIFdel{wav}\DIFdelend \DIFaddbegin [\DIFadd{audio ext}]\DIFaddend }. \DIFaddbegin \DIFadd{Audio extension can either be }\texttt{\DIFadd{mp3}}
\DIFadd{or }\texttt{\DIFadd{wav}}\DIFadd{.
}\DIFaddend
\begin{itemize}
\tightlist
......@@ -5719,7 +5721,7 @@ functioning. Feature highlights:
\href{https://github.com/acidanthera/OpenCorePkg/blob/master/Include/Apple/Protocol/AppleVoiceOver.h}{\texttt{APPLE\_VOICE\_OVER\_AUDIO\_FILE} definition}.
For OpenCore audio paths refer to
\href{https://github.com/acidanthera/OpenCorePkg/blob/master/Include/Acidanthera/Protocol/OcAudio.h}{\texttt{OC\_VOICE\_OVER\_AUDIO\_FILE} definition}.
The only exception is OpenCore boot chime file, which is \texttt{OCEFIAudio\_VoiceOver\_Boot.wav}.
The only exception is OpenCore boot chime file, which is \texttt{OCEFIAudio\_VoiceOver\_Boot.\DIFdelbegin \DIFdel{wav}\DIFdelend \DIFaddbegin \DIFadd{mp3}\DIFaddend }.
\end{itemize}
Audio localisation is determined separately for macOS bootloader and OpenCore.
......
/** @file
Copyright (C) 2021, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_WAVE_LIB_H
#define OC_WAVE_LIB_H
#include <Protocol/AudioIo.h>
/**
Decode WAVE audio to PCM audio.
@param[in] Buffer Buffer with mp3 audio data.
@param[in] BufferSize Buffer size in bytes.
@param[out] RawBuffer Decoded PCM data pointing to Buffer.
@param[out] RawBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on success.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
EFI_STATUS
OcDecodeWave (
IN UINT8 *Buffer,
IN UINTN BufferSize,
OUT UINT8 **RawBuffer,
OUT UINT32 *RawBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
);
#endif // OC_WAVE_LIB_H
/** @file
Copyright (C) 2021, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef EFI_AUDIO_DECODE_H
#define EFI_AUDIO_DECODE_H
#include <Uefi.h>
#include <Protocol/AudioIo.h>
/**
Audio decoding protocol GUID.
**/
#define EFI_AUDIO_DECODE_PROTOCOL_GUID \
{ 0xAF3F6C23, 0x8132, 0x4880, \
{ 0xB3, 0x29, 0x04, 0x8D, 0xF7, 0x1D, 0xD8, 0x6A } }
typedef struct EFI_AUDIO_DECODE_PROTOCOL_ EFI_AUDIO_DECODE_PROTOCOL;
/**
Decode any supported audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data allocated from pool (needs to be freed).
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_AUDIO_DECODE_ANY) (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
);
/**
Decode WAVE audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data.
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@param[in] InPlace Do not allocate OutBuffer, but reuse InBuffer.
Otherwise allocated from pool and needs to be freed.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_AUDIO_DECODE_WAVE) (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels,
IN BOOLEAN InPlace
);
/**
Decode MP3 audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data allocated from pool (needs to be freed).
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_AUDIO_DECODE_MP3) (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
);
/**
Protocol struct.
**/
struct EFI_AUDIO_DECODE_PROTOCOL_ {
EFI_AUDIO_DECODE_ANY DecodeAny;
EFI_AUDIO_DECODE_WAVE DecodeWave;
EFI_AUDIO_DECODE_MP3 DecodeMp3;
};
extern EFI_GUID gEfiAudioDecodeProtocolGuid;
#endif // EFI_AUDIO_DECODE_H
......@@ -15,6 +15,7 @@
#ifndef OC_AUDIO_PROTOCOL_H
#define OC_AUDIO_PROTOCOL_H
#include <Protocol/AudioIo.h>
#include <Protocol/AppleVoiceOver.h>
#include <Protocol/DevicePath.h>
......@@ -138,6 +139,9 @@ EFI_STATUS
@paran[in] LanguageCode Language code for the file.
@param[out] Buffer Pointer to buffer.
@param[out] BufferSize Pointer to buffer size.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on successful file lookup.
**/
......@@ -148,7 +152,10 @@ EFI_STATUS
IN UINT32 File,
IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode,
OUT UINT8 **Buffer,
OUT UINT32 *BufferSize
OUT UINT32 *BufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
);
/**
......
......@@ -279,10 +279,8 @@ InternalOcAudioPlayFile (
{
EFI_STATUS Status;
OC_AUDIO_PROTOCOL_PRIVATE *Private;
UINT8 *Buffer;
UINT32 BufferSize;
UINT8 *RawBuffer;
UINTN RawBufferSize;
UINT32 RawBufferSize;
EFI_AUDIO_IO_PROTOCOL_FREQ Frequency;
EFI_AUDIO_IO_PROTOCOL_BITS Bits;
UINT8 Channels;
......@@ -299,18 +297,6 @@ InternalOcAudioPlayFile (
Private->ProviderContext,
File,
Private->Language,
&Buffer,
&BufferSize
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAU: PlayFile has no file %d for lang %d - %r\n", File, Private->Language, Status));
return EFI_NOT_FOUND;
}
Status = InternalGetRawData (
Buffer,
BufferSize,
&RawBuffer,
&RawBufferSize,
&Frequency,
......@@ -318,6 +304,11 @@ InternalOcAudioPlayFile (
&Channels
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAU: PlayFile has no file %d for lang %d - %r\n", File, Private->Language, Status));
return EFI_NOT_FOUND;
}
DEBUG ((
DEBUG_INFO,
"OCAU: File %d for lang %d is %d %d %d (%u) - %r\n",
......@@ -333,7 +324,7 @@ InternalOcAudioPlayFile (
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OCAU: PlayFile has invalid file %d for lang %d - %r\n", File, Private->Language, Status));
if (Private->ProviderRelease != NULL) {
Private->ProviderRelease (Private->ProviderContext, Buffer);
Private->ProviderRelease (Private->ProviderContext, RawBuffer);
}
return EFI_NOT_FOUND;
}
......@@ -341,7 +332,7 @@ InternalOcAudioPlayFile (
This->StopPlayback (This, Wait);
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Private->CurrentBuffer = Buffer;
Private->CurrentBuffer = RawBuffer;
Status = Private->AudioIo->SetupPlayback (
Private->AudioIo,
......
......@@ -135,15 +135,4 @@ InternalOcAudioVoiceOverGetLanguage (
OUT CONST CHAR8 **LanguageString
);
EFI_STATUS
InternalGetRawData (
IN UINT8 *Buffer,
IN UINTN BufferSize,
OUT UINT8 **RawBuffer,
OUT UINTN *RawBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
);
#endif // OC_AUDIO_INTERNAL_H
......@@ -36,7 +36,6 @@
OcAudioLib.c
OcAudioInternal.h
OcAudioVoiceOver.c
OcAudioWave.c
[Packages]
MdePkg/MdePkg.dec
......
/** @file
Copyright (C) 2018, John Davis. All rights reserved.
Copyright (C) 2020, vit9696. All rights reserved.
Copyright (C) 2020-2021, vit9696. All rights reserved.
All rights reserved.
......@@ -13,32 +13,23 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <IndustryStandard/Riff.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcAudioLib.h>
#include <Library/OcDevicePathLib.h>
#include <Library/OcGuardLib.h>
#include <Library/OcMiscLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/AppleHda.h>
#include <Protocol/AppleBeepGen.h>
#include <Protocol/AppleVoiceOver.h>
#include <Protocol/HdaIo.h>
#include "OcAudioInternal.h"
#include <Library/OcWaveLib.h>
EFI_STATUS
InternalGetRawData (
OcDecodeWave (
IN UINT8 *Buffer,
IN UINTN BufferSize,
OUT UINT8 **RawBuffer,
OUT UINTN *RawBufferSize,
OUT UINT32 *RawBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
......
## @file
#
# Component description file for OcWaveLib.
#
# Copyright (C) 2021, vit9696. All rights reserved.<BR>
#
# All rights reserved.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = OcWaveLib
FILE_GUID = 585C334C-B904-4101-9D87-83E5FECF5E45
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = OcWaveLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER
# VALID_ARCHITECTURES = IA32 X64
[Packages]
OpenCorePkg/OpenCorePkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
UefiLib
OcGuardLib
[Sources]
OcWaveLib.c
......@@ -462,7 +462,10 @@
gMicrosoftVariableGuid = { 0x77FA9ABD, 0x0359, 0x4D32, { 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B }}
[Protocols]
## Include/Acidanthera/Protocol/Audio.h
## Include/Acidanthera/Protocol/AudioDecode.h
gEfiAudioDecodeProtocolGuid = { 0xAF3F6C23, 0x8132, 0x4880, { 0xB3, 0x29, 0x04, 0x8D, 0xF7, 0x1D, 0xD8, 0x6A }}
## Include/Acidanthera/Protocol/AudioIo.h
gEfiAudioIoProtocolGuid = { 0xF05B559C, 0x1971, 0x4AF5, { 0xB2, 0xAE, 0xD6, 0x08, 0x08, 0xF7, 0x4F, 0x70 }}
## Include/Acidanthera/Protocol/HdaCodecInfo.h
......@@ -877,6 +880,9 @@
## @libraryclass
OcVirtualFsLib|Include/Acidanthera/Library/OcVirtualFsLib.h
## @libraryclass
OcWaveLib|Include/Acidanthera/Library/OcWaveLib.h
## @libraryclass
OcXmlLib|Include/Acidanthera/Library/OcXmlLib.h
......
......@@ -108,6 +108,7 @@
OcUnicodeCollationEngGenericLib|OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngGenericLib.inf
OcUnicodeCollationEngLocalLib|OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngLocalLib.inf
OcVirtualFsLib|OpenCorePkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf
OcWaveLib|OpenCorePkg/Library/OcWaveLib/OcWaveLib.inf
OcXmlLib|OpenCorePkg/Library/OcXmlLib/OcXmlLib.inf
OcPeCoffLib|OpenCorePkg/Library/OcPeCoffLib/OcPeCoffLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
......@@ -227,6 +228,7 @@
OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngGenericLib.inf
OpenCorePkg/Library/OcUnicodeCollationEngLib/OcUnicodeCollationEngLocalLib.inf
OpenCorePkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf
OpenCorePkg/Library/OcWaveLib/OcWaveLib.inf
OpenCorePkg/Library/OcXmlLib/OcXmlLib.inf
OpenCorePkg/Library/OcPeCoffLib/OcPeCoffLib.inf
OpenCorePkg/Platform/CrScreenshotDxe/CrScreenshotDxe.inf
......
......@@ -59,6 +59,7 @@
gOcVendorVariableGuid
[Protocols]
gEfiAudioDecodeProtocolGuid ## SOMETIMES_CONSUMES
gEfiDevicePathProtocolGuid ## CONSUMES
gEfiDevicePathProtocolGuid ## CONSUMES
gEfiLoadedImageProtocolGuid ## CONSUMES
......
......@@ -17,6 +17,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/AppleVariable.h>
#include <Guid/OcVariable.h>
#include <Guid/GlobalVariable.h>
#include <Protocol/AudioDecode.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
......@@ -57,52 +58,35 @@ STATIC OC_AUDIO_FILE mOcAudioFiles[OcVoiceOverAudioFileMax - OcVoiceOverAudioFi
// Reconsider it when we resolve lags with AudioDxe.
//
STATIC BOOLEAN mEnableAudioCaching = FALSE;
STATIC EFI_AUDIO_DECODE_PROTOCOL *mAudioDecodeProtocol = NULL;
STATIC
EFI_STATUS
EFIAPI
OcAudioAcquireFile (
IN VOID *Context,
CONST CHAR8 *
OcAudioGetFilePath (
IN UINT32 File,
IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode,
OUT UINT8 **Buffer,
OUT UINT32 *BufferSize
OUT CHAR8 *TmpPath,
OUT UINT32 TmpPathSize,
OUT CONST CHAR8 **BaseType,
OUT BOOLEAN *Localised
)
{
EFI_STATUS Status;
CHAR8 IndexPath[8];
CHAR16 FilePath[OC_STORAGE_SAFE_PATH_MAX];
OC_STORAGE_CONTEXT *Storage;
CONST CHAR8 *BaseType;
CONST CHAR8 *BasePath;
BOOLEAN Localised;
OC_AUDIO_FILE *CacheFile;
EFI_STATUS Status;
CONST CHAR8 *BasePath;
Storage = (OC_STORAGE_CONTEXT *) Context;
Localised = TRUE;
CacheFile = NULL;
*Localised = TRUE;
if (File >= OcVoiceOverAudioFileBase && File < OcVoiceOverAudioFileMax) {
if (mEnableAudioCaching) {
CacheFile = &mOcAudioFiles[File - OcVoiceOverAudioFileBase];
if (CacheFile->Buffer != NULL) {
*Buffer = CacheFile->Buffer;
*BufferSize = CacheFile->Size;
return EFI_SUCCESS;
}
}
BaseType = "OCEFIAudio";
*BaseType = "OCEFIAudio";
if (File > OcVoiceOverAudioFileIndexBase && File <= OcVoiceOverAudioFileIndexMax) {
Status = OcAsciiSafeSPrint (
IndexPath,
sizeof (IndexPath),
TmpPath,
TmpPathSize,
"%a%c",
File >= OcVoiceOverAudioFileIndexAlphabetical ? "Letter" : "",
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[File - OcVoiceOverAudioFileIndexBase]
);
ASSERT_EFI_ERROR (Status);
BasePath = IndexPath;
BasePath = TmpPath;
} else {
switch (File) {
case OcVoiceOverAudioFileAbortTimeout:
......@@ -188,17 +172,8 @@ OcAudioAcquireFile (
break;
}
}
} else if (File < AppleVoiceOverAudioFileMax) {
if (mEnableAudioCaching) {
CacheFile = &mAppleAudioFiles[File];
if (CacheFile->Buffer != NULL) {
*Buffer = CacheFile->Buffer;
*BufferSize = CacheFile->Size;
return EFI_SUCCESS;
}
}
BaseType = "AXEFIAudio";
} else {
*BaseType = "AXEFIAudio";
switch (File) {
case AppleVoiceOverAudioFileVoiceOverOn:
BasePath = "VoiceOverOn";
......@@ -222,84 +197,212 @@ OcAudioAcquireFile (
BasePath = "AccountLocked";
break;
case AppleVoiceOverAudioFileVoiceOverBoot:
BaseType = "OCEFIAudio";
BasePath = "VoiceOver_Boot";
Localised = FALSE;
*BaseType = "OCEFIAudio";
BasePath = "VoiceOver_Boot";
*Localised = FALSE;
break;
case AppleVoiceOverAudioFileVoiceOverBoot2:
BasePath = "VoiceOver_Boot";
Localised = FALSE;
*Localised = FALSE;
break;
case AppleVoiceOverAudioFileClick:
BasePath = "Click";
Localised = FALSE;
*Localised = FALSE;
break;
case AppleVoiceOverAudioFileBeep:
BasePath = "Beep";
Localised = FALSE;
*Localised = FALSE;
break;
default:
BasePath = NULL;
break;
}
} else {
BasePath = NULL;
}
if (BasePath == NULL) {
DEBUG ((DEBUG_INFO, "OC: Unknown Wave %d\n", File));
return EFI_NOT_FOUND;
}
return BasePath;
}
STATIC
VOID *
OcAudioGetFileContents (
IN OC_STORAGE_CONTEXT *Storage,
IN CONST CHAR8 *BaseType,
IN CONST CHAR8 *BasePath,
IN CONST CHAR8 *Extension,
IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode,
IN BOOLEAN Localised,
OUT UINT32 *BufferSize
)
{
EFI_STATUS Status;
CHAR16 FilePath[OC_STORAGE_SAFE_PATH_MAX];
VOID *Buffer;
if (Localised) {
Status = OcUnicodeSafeSPrint (
FilePath,
sizeof (FilePath),
OPEN_CORE_AUDIO_PATH "%a_%a_%a.wav",
OPEN_CORE_AUDIO_PATH "%a_%a_%a.%a",
BaseType,
OcLanguageCodeToString (LanguageCode),
BasePath
BasePath,
Extension
);
ASSERT_EFI_ERROR (Status);
if (!OcStorageExistsFileUnicode (Context, FilePath)) {
if (!OcStorageExistsFileUnicode (Storage, FilePath)) {
Status = OcUnicodeSafeSPrint (
FilePath,
sizeof (FilePath),
OPEN_CORE_AUDIO_PATH "%a_%a_%a.wav",
OPEN_CORE_AUDIO_PATH "%a_%a_%a.%a",
BaseType,
OcLanguageCodeToString (AppleVoiceOverLanguageEn),
BasePath
BasePath,
Extension
);
ASSERT_EFI_ERROR (Status);
if (!OcStorageExistsFileUnicode (Storage, FilePath)) {
return NULL;
}
}
} else {
Status = OcUnicodeSafeSPrint (
FilePath,
sizeof (FilePath),
OPEN_CORE_AUDIO_PATH "%a_%a.wav",
OPEN_CORE_AUDIO_PATH "%a_%a.%a",
BaseType,
BasePath
BasePath,
Extension
);
ASSERT_EFI_ERROR (Status);
}
DEBUG ((DEBUG_INFO, "OC: Wave %s was requested\n", FilePath));
if (!OcStorageExistsFileUnicode (Storage, FilePath)) {
return NULL;
}
}
*Buffer = OcStorageReadFileUnicode (
Buffer = OcStorageReadFileUnicode (
Storage,
FilePath,
BufferSize
);
if (*Buffer == NULL) {
DEBUG ((
DEBUG_INFO,
"OC: Wave %s cannot be found!\n",
FilePath
));
if (Buffer == NULL) {
return NULL;
}
return Buffer;
}
STATIC
EFI_STATUS
EFIAPI
OcAudioAcquireFile (
IN VOID *Context,
IN UINT32 File,
IN APPLE_VOICE_OVER_LANGUAGE_CODE LanguageCode,
OUT UINT8 **Buffer,
OUT UINT32 *BufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
)
{
EFI_STATUS Status;
CHAR8 TmpPath[8];
OC_STORAGE_CONTEXT *Storage;
CONST CHAR8 *BaseType;
CONST CHAR8 *BasePath;
UINT8 *FileBuffer;
UINT32 FileBufferSize;
BOOLEAN Localised;
OC_AUDIO_FILE *CacheFile;
Storage = (OC_STORAGE_CONTEXT *) Context;
CacheFile = NULL;
if (File >= OcVoiceOverAudioFileBase && File < OcVoiceOverAudioFileMax) {
if (mEnableAudioCaching) {
CacheFile = &mOcAudioFiles[File - OcVoiceOverAudioFileBase];
if (CacheFile->Buffer != NULL) {
*Buffer = CacheFile->Buffer;
*BufferSize = CacheFile->Size;
return EFI_SUCCESS;
}
}
} else if (File < AppleVoiceOverAudioFileMax) {
if (mEnableAudioCaching) {
CacheFile = &mAppleAudioFiles[File];
if (CacheFile->Buffer != NULL) {
*Buffer = CacheFile->Buffer;
*BufferSize = CacheFile->Size;
return EFI_SUCCESS;
}
}
} else {
DEBUG ((DEBUG_INFO, "OC: Invalid wave index %d\n", File));
return EFI_NOT_FOUND;
}
BasePath = OcAudioGetFilePath (
File,
TmpPath,
sizeof (TmpPath),
&BaseType,
&Localised
);
if (BasePath == NULL) {
DEBUG ((DEBUG_INFO, "OC: Unknown Wave %d\n", File));
return EFI_NOT_FOUND;
}
FileBuffer = OcAudioGetFileContents (
Storage,
BaseType,
BasePath,
"mp3",
LanguageCode,
Localised,
&FileBufferSize
);
if (FileBuffer == NULL) {
FileBuffer = OcAudioGetFileContents (
Storage,
BaseType,
BasePath,
"wav",
LanguageCode,
Localised,
&FileBufferSize
);
}
if (FileBuffer == NULL) {
DEBUG ((DEBUG_INFO, "OC: Wave %a cannot be found!\n", BasePath));
return EFI_NOT_FOUND;
}
ASSERT (mAudioDecodeProtocol != NULL);
Status = mAudioDecodeProtocol->DecodeAny (
mAudioDecodeProtocol,
FileBuffer,
FileBufferSize,
(VOID **) Buffer,
BufferSize,
Frequency,
Bits,
Channels
);
FreePool (FileBuffer);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OC: Wave %a cannot be decoded - %r!\n", BasePath, Status));
return EFI_UNSUPPORTED;
}
if (CacheFile != NULL) {
CacheFile->Buffer = *Buffer;
CacheFile->Size = *BufferSize;
......@@ -385,6 +488,16 @@ OcLoadUefiAudioSupport (
return;
}
Status = gBS->LocateProtocol (
&gEfiAudioDecodeProtocolGuid,
NULL,
(VOID **) &mAudioDecodeProtocol
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "OC: Cannot locate audio decoder protocol - %r\n", Status));
return;
}
VolumeLevel = OcGetVolumeLevel (Config->Uefi.Audio.VolumeAmplifier, &Muted);
DevicePath = NULL;
......
/*
* File: AudioDxe.c
*
* Copyright (c) 2021 vit9696
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include "AudioDxe.h"
#include <Library/OcMp3Lib.h>
#include <Library/OcWaveLib.h>
/**
Decode WAVE audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data.
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@param[in] InPlace Do not allocate OutBuffer, but reuse InBuffer.
Otherwise allocated from pool and needs to be freed.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
STATIC
EFI_STATUS
EFIAPI
AudioDecodeWave (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels,
IN BOOLEAN InPlace
)
{
EFI_STATUS Status;
Status = OcDecodeWave (
(UINT8 *) InBuffer,
InBufferSize,
(UINT8 **) OutBuffer,
OutBufferSize,
Frequency,
Bits,
Channels
);
if (EFI_ERROR (Status)) {
return Status;
}
if (!InPlace) {
*OutBuffer = AllocateCopyPool (*OutBufferSize, *OutBuffer);
if (*OutBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
}
return EFI_SUCCESS;
}
/**
Decode MP3 audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data allocated from pool (needs to be freed).
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
STATIC
EFI_STATUS
EFIAPI
AudioDecodeMp3 (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
)
{
EFI_STATUS Status;
Status = OcDecodeMp3 (
InBuffer,
InBufferSize,
OutBuffer,
OutBufferSize,
Frequency,
Bits,
Channels
);
return Status;
}
/**
Decode any supported audio to PCM audio.
@param[in] This Audio decode protocol instance.
@param[in] InBuffer Buffer with audio data.
@param[in] InBufferSize InBuffer size in bytes.
@param[out] OutBuffer Decoded PCM data allocated from pool (needs to be freed).
@param[out] OutBufferSize Decoded PCM data size in bytes.
@param[out] Frequency Decoded PCM frequency.
@param[out] Bits Decoded bit count.
@param[out] Channels Decoded amount of channels.
@retval EFI_SUCCESS on success.
@retval EFI_INVALID_PARAMETER for null pointers.
@retval EFI_UNSUPPORTED on format mismatch.
@retval EFI_OUT_OF_RESOURCES on memory allocation failure.
**/
STATIC
EFI_STATUS
EFIAPI
AudioDecodeAny (
IN EFI_AUDIO_DECODE_PROTOCOL *This,
IN CONST VOID *InBuffer,
IN UINT32 InBufferSize,
OUT VOID **OutBuffer,
OUT UINT32 *OutBufferSize,
OUT EFI_AUDIO_IO_PROTOCOL_FREQ *Frequency,
OUT EFI_AUDIO_IO_PROTOCOL_BITS *Bits,
OUT UINT8 *Channels
)
{
EFI_STATUS Status;
Status = AudioDecodeMp3 (
This,
InBuffer,
InBufferSize,
OutBuffer,
OutBufferSize,
Frequency,
Bits,
Channels
);
if (EFI_ERROR (Status)) {
Status = AudioDecodeWave (
This,
InBuffer,
InBufferSize,
OutBuffer,
OutBufferSize,
Frequency,
Bits,
Channels,
FALSE
);
}
return Status;
}
/**
Protocol definition.
**/
EFI_AUDIO_DECODE_PROTOCOL
gEfiAudioDecodeProtocol = {
.DecodeAny = AudioDecodeAny,
.DecodeWave = AudioDecodeWave,
.DecodeMp3 = AudioDecodeMp3
};
......@@ -57,8 +57,8 @@ gHdaCodecDriverBinding = {
EFI_STATUS
EFIAPI
AudioDxeInit(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
......@@ -91,8 +91,20 @@ AudioDxeInit(
&gHdaCodecComponentName2
);
ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status)) {
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&ImageHandle,
&gEfiAudioDecodeProtocolGuid,
&gEfiAudioDecodeProtocol,
NULL
);
ASSERT_EFI_ERROR (Status);
if (EFI_ERROR (Status)) {
return Status;
}
......
......@@ -46,6 +46,7 @@
//
// Proctols that are consumed/produced.
//
#include <Protocol/AudioDecode.h>
#include <Protocol/AudioIo.h>
#include <Protocol/DevicePath.h>
#include <Protocol/DevicePathUtilities.h>
......@@ -64,5 +65,6 @@
// Driver Bindings.
extern EFI_DRIVER_BINDING_PROTOCOL gHdaControllerDriverBinding;
extern EFI_DRIVER_BINDING_PROTOCOL gHdaCodecDriverBinding;
extern EFI_AUDIO_DECODE_PROTOCOL gEfiAudioDecodeProtocol;
#endif // EFI_AUDIODXE_H
......@@ -41,7 +41,9 @@
DevicePathLib
MemoryAllocationLib
OcHdaDevicesLib
OcMp3Lib
OcStringLib
OcWaveLib
PcdLib
UefiBootServicesTableLib
UefiDriverEntryPoint
......@@ -53,6 +55,7 @@
gEfiHdaIoProtocolGuid # PRODUCES
gEfiHdaCodecInfoProtocolGuid # PRODUCES
gEfiAudioIoProtocolGuid # PRODUCES
gEfiAudioDecodeProtocolGuid # PRODUCES
gVMwareHdaProtocolGuid # SOMETIMES_CONSUMES
[Sources]
......@@ -69,5 +72,6 @@
HdaController/HdaControllerHdaIo.c
HdaController/HdaController.h
HdaController/HdaController.c
AudioDecode.c
AudioDxe.h
AudioDxe.c
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册