Compare commits
12 Commits
master
...
trying_thi
Author | SHA1 | Date |
---|---|---|
Casper Jeukendrup | 04bb125b93 | |
Casper Jeukendrup | 60c090244f | |
Casper Jeukendrup | 1173233f95 | |
Casper Jeukendrup | b03f759279 | |
Casper Jeukendrup | 1d21d81be8 | |
Casper Jeukendrup | f0d99f763e | |
Casper Jeukendrup | bfad6640e3 | |
Casper Jeukendrup | 68674bd1ba | |
Casper Jeukendrup | 553cd881ef | |
Casper Jeukendrup | ca6fb026ca | |
Casper Jeukendrup | 74d79500d5 | |
Casper Jeukendrup | f10f241ded |
|
@ -30,10 +30,10 @@ jobs:
|
|||
build_mu4_x64:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
# - name: Cancel Previous Runs
|
||||
# uses: styfle/cancel-workflow-action@0.11.0
|
||||
# with:
|
||||
# access_token: ${{ github.token }}
|
||||
- name: Clone repository (default)
|
||||
uses: actions/checkout@v3
|
||||
if: ${{ github.event_name != 'schedule' || github.event.schedule == '0 3 */1 */1 *' }}
|
||||
|
@ -109,7 +109,7 @@ jobs:
|
|||
DO_PUBLISH='false'
|
||||
fi
|
||||
|
||||
ADD_INFO="_${GITHUB_REF#refs/heads/}"
|
||||
ADD_INFO="_${GITHUB_REF#refs/heads/}_Release"
|
||||
if [ "${{ github.event_name }}" == "schedule" ] && [ "${{ github.event.schedule }}" == "0 5 */1 */1 *" ]; then ADD_INFO="_${CURRENT_RELEASE_BRANCH}"; fi
|
||||
if [ "${{ github.event_name }}" == "pull_request" ]; then ADD_INFO="_${{ github.event.pull_request.number }}_${pull_request_title}"; fi
|
||||
UPLOAD_ARTIFACT_NAME="$(tr '":<>|*?/\\' '_' <<<"MU4_${BUILD_NUMBER}_Win${ADD_INFO}")"
|
||||
|
@ -186,25 +186,25 @@ jobs:
|
|||
IF ${{ secrets.WIN_SIGN_CERTIFICATE_PASSWORD != 0 }} == true ( SET S_P=${{ secrets.WIN_SIGN_CERTIFICATE_PASSWORD }} ) ELSE ( SET S_P="''" )
|
||||
IF ${{ env.BUILD_MODE }} == stable_build ( SET GUID=${{ secrets.WIN_MSI_STABLE_MU4_GUID }} ) ELSE ( SET GUID=${{ secrets.WIN_MSI_TESTING_MU4_GUID }} )
|
||||
build\ci\windows\package.bat --signsecret %S_S% --signpass %S_P% --guid %GUID%
|
||||
- name: Checksum
|
||||
if: env.DO_BUILD == 'true'
|
||||
run: |
|
||||
bash ./build/ci/tools/checksum.sh
|
||||
# - name: Checksum
|
||||
# if: env.DO_BUILD == 'true'
|
||||
# run: |
|
||||
# bash ./build/ci/tools/checksum.sh
|
||||
- name: Upload dump symbols
|
||||
if: env.DO_UPLOAD_SYMBOLS == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
bash ./build/ci/tools/sentry_syms_upload.sh -t ${{ secrets.SENTRY_AUTH_TOKEN }} -p ${SENTRY_PROJECT}
|
||||
- name: Publish package
|
||||
if: env.DO_PUBLISH == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
bash ./build/ci/tools/osuosl/publish.sh -s ${{ secrets.OSUOSL_SSH_ENCRYPT_SECRET }} --os windows -v 4
|
||||
- name: AppCast
|
||||
if: env.DO_BUILD == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
bash ./build/ci/tools/sparkle_appcast_gen.sh -p windows
|
||||
# - name: Publish package
|
||||
# if: env.DO_PUBLISH == 'true'
|
||||
# shell: bash
|
||||
# run: |
|
||||
# bash ./build/ci/tools/osuosl/publish.sh -s ${{ secrets.OSUOSL_SSH_ENCRYPT_SECRET }} --os windows -v 4
|
||||
# - name: AppCast
|
||||
# if: env.DO_BUILD == 'true'
|
||||
# shell: bash
|
||||
# run: |
|
||||
# bash ./build/ci/tools/sparkle_appcast_gen.sh -p windows
|
||||
- name: Upload artifacts on GitHub
|
||||
if: ${{ always() }}
|
||||
uses: actions/upload-artifact@v3
|
||||
|
@ -216,10 +216,10 @@ jobs:
|
|||
build_portable:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@0.11.0
|
||||
with:
|
||||
access_token: ${{ github.token }}
|
||||
# - name: Cancel Previous Runs
|
||||
# uses: styfle/cancel-workflow-action@0.11.0
|
||||
# with:
|
||||
# access_token: ${{ github.token }}
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
|
@ -281,15 +281,15 @@ jobs:
|
|||
shell: cmd
|
||||
run: |
|
||||
build\ci\windows\package.bat --portable ON
|
||||
- name: Checksum
|
||||
if: env.DO_BUILD == 'true'
|
||||
run: |
|
||||
bash ./build/ci/tools/checksum.sh
|
||||
- name: Publish package
|
||||
if: env.DO_PUBLISH == 'true'
|
||||
run: |
|
||||
build\ci\windows\publish.bat --secret ${{ secrets.OSUOSL_SSH_ENCRYPT_SECRET }}
|
||||
shell: cmd
|
||||
# - name: Checksum
|
||||
# if: env.DO_BUILD == 'true'
|
||||
# run: |
|
||||
# bash ./build/ci/tools/checksum.sh
|
||||
# - name: Publish package
|
||||
# if: env.DO_PUBLISH == 'true'
|
||||
# run: |
|
||||
# build\ci\windows\publish.bat --secret ${{ secrets.OSUOSL_SSH_ENCRYPT_SECRET }}
|
||||
# shell: cmd
|
||||
- name: Upload artifacts on GitHub
|
||||
if: env.DO_BUILD == 'true'
|
||||
uses: actions/upload-artifact@v3
|
||||
|
|
|
@ -32,8 +32,6 @@ if (MUSESCORE_UNSTABLE)
|
|||
endif (git_date)
|
||||
endif (MUSESCORE_UNSTABLE)
|
||||
|
||||
SET(CPACK_NSIS_COMPRESSOR "/FINAL /SOLID lzma")
|
||||
|
||||
IF(MINGW OR MSVC)
|
||||
SET(CPACK_PACKAGE_INSTALL_DIRECTORY ${MUSESCORE_NAME_VERSION})
|
||||
SET(CPACK_PACKAGE_NAME ${MUSESCORE_NAME})
|
||||
|
@ -42,30 +40,10 @@ IF(MINGW OR MSVC)
|
|||
# There is a bug in NSI that does not handle full unix paths properly. Make
|
||||
# sure there is at least one set of four (4) backslashes.
|
||||
SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/build/packaging\\\\installer_head_nsis.bmp")
|
||||
SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\${MSCORE_EXECUTABLE_NAME}.exe,0")
|
||||
SET(CPACK_NSIS_DISPLAY_NAME "${MUSESCORE_NAME} ${MUSESCORE_VERSION_FULL}")
|
||||
SET(CPACK_NSIS_HELP_LINK "https://www.musescore.org/")
|
||||
SET(CPACK_NSIS_URL_INFO_ABOUT "https://www.musescore.org/")
|
||||
SET(CPACK_NSIS_CONTACT "info@musescore.org")
|
||||
SET(CPACK_NSIS_MODIFY_PATH OFF)
|
||||
SET(CPACK_STRIP_FILES "${MSCORE_EXECUTABLE_NAME}.exe")
|
||||
|
||||
# File types association:
|
||||
message(STATUS "[Packaging.cmake] PACKAGE_FILE_ASSOCIATION: ${MUE_ENABLE_FILE_ASSOCIATION}")
|
||||
IF (MUE_ENABLE_FILE_ASSOCIATION)
|
||||
SET(CPACK_NSIS_DEFINES "!include ${PROJECT_SOURCE_DIR}/build/packaging\\\\FileAssociation.nsh")
|
||||
|
||||
SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "
|
||||
\\\${registerExtension} \\\"MuseScore File\\\" \\\".mscz\\\" \\\"\\\$INSTDIR\\\\bin\\\\${MSCORE_EXECUTABLE_NAME}.exe\\\"
|
||||
\\\${registerExtension} \\\"MuseScore Uncompressed File\\\" \\\".mscx\\\" \\\"\\\$INSTDIR\\\\bin\\\\${MSCORE_EXECUTABLE_NAME}.exe\\\"
|
||||
\\\${registerExtension} \\\"MuseScore Uncompressde File\\\" \\\".mscs\\\" \\\"\\\$INSTDIR\\\\bin\\\\${MSCORE_EXECUTABLE_NAME}.exe\\\"
|
||||
")
|
||||
SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "
|
||||
\\\${unregisterExtension} \\\".mscz\\\" \\\"MuseScore File\\\"
|
||||
\\\${unregisterExtension} \\\".mscx\\\" \\\"MuseScore Uncompressed File\\\"
|
||||
\\\${unregisterExtension} \\\".mscs\\\" \\\"MuseScore Uncompressed File\\\"
|
||||
")
|
||||
|
||||
list(APPEND CPACK_WIX_CANDLE_EXTRA_FLAGS -dCPACK_WIX_FILE_ASSOCIATION=ON)
|
||||
ELSE(MUE_ENABLE_FILE_ASSOCIATION)
|
||||
list(APPEND CPACK_WIX_CANDLE_EXTRA_FLAGS -dCPACK_WIX_FILE_ASSOCIATION=OFF)
|
||||
|
|
|
@ -27,14 +27,14 @@ IF NOT %TARGET_PROCESSOR_BITS% == 64 (
|
|||
)
|
||||
|
||||
SET /p BUILD_MODE=<%ARTIFACTS_DIR%\env\build_mode.env
|
||||
SET "MUSESCORE_BUILD_MODE=dev"
|
||||
IF %BUILD_MODE% == devel_build ( SET "MUSESCORE_BUILD_MODE=dev" ) ELSE (
|
||||
IF %BUILD_MODE% == nightly_build ( SET "MUSESCORE_BUILD_MODE=dev" ) ELSE (
|
||||
IF %BUILD_MODE% == testing_build ( SET "MUSESCORE_BUILD_MODE=testing" ) ELSE (
|
||||
IF %BUILD_MODE% == stable_build ( SET "MUSESCORE_BUILD_MODE=release" ) ELSE (
|
||||
ECHO "error: unknown BUILD_MODE: %BUILD_MODE%"
|
||||
EXIT /b 1
|
||||
))))
|
||||
SET "MUSESCORE_BUILD_MODE=release"
|
||||
@REM IF %BUILD_MODE% == devel_build ( SET "MUSESCORE_BUILD_MODE=dev" ) ELSE (
|
||||
@REM IF %BUILD_MODE% == nightly_build ( SET "MUSESCORE_BUILD_MODE=dev" ) ELSE (
|
||||
@REM IF %BUILD_MODE% == testing_build ( SET "MUSESCORE_BUILD_MODE=testing" ) ELSE (
|
||||
@REM IF %BUILD_MODE% == stable_build ( SET "MUSESCORE_BUILD_MODE=release" ) ELSE (
|
||||
@REM ECHO "error: unknown BUILD_MODE: %BUILD_MODE%"
|
||||
@REM EXIT /b 1
|
||||
@REM ))))
|
||||
|
||||
ECHO "MUSESCORE_BUILD_MODE: %MUSESCORE_BUILD_MODE%"
|
||||
ECHO "BUILD_NUMBER: %BUILD_NUMBER%"
|
||||
|
|
|
@ -52,17 +52,17 @@ IF %BUILD_MODE% == stable_build ( SET PACKAGE_TYPE="msi") ELSE (
|
|||
)))))
|
||||
|
||||
SET DO_SIGN=OFF
|
||||
IF %PACKAGE_TYPE% == "msi" (
|
||||
SET DO_SIGN=ON
|
||||
IF %SIGN_CERTIFICATE_ENCRYPT_SECRET% == "" (
|
||||
SET DO_SIGN=OFF
|
||||
ECHO "warning: not set SIGN_CERTIFICATE_ENCRYPT_SECRET"
|
||||
)
|
||||
IF %SIGN_CERTIFICATE_PASSWORD% == "" (
|
||||
SET DO_SIGN=OFF
|
||||
ECHO "warning: not set SIGN_CERTIFICATE_PASSWORD"
|
||||
)
|
||||
)
|
||||
@REM IF %PACKAGE_TYPE% == "msi" (
|
||||
@REM SET DO_SIGN=ON
|
||||
@REM IF %SIGN_CERTIFICATE_ENCRYPT_SECRET% == "" (
|
||||
@REM SET DO_SIGN=OFF
|
||||
@REM ECHO "warning: not set SIGN_CERTIFICATE_ENCRYPT_SECRET"
|
||||
@REM )
|
||||
@REM IF %SIGN_CERTIFICATE_PASSWORD% == "" (
|
||||
@REM SET DO_SIGN=OFF
|
||||
@REM ECHO "warning: not set SIGN_CERTIFICATE_PASSWORD"
|
||||
@REM )
|
||||
@REM )
|
||||
|
||||
SET /p BUILD_VERSION=<%ARTIFACTS_DIR%\env\build_version.env
|
||||
SET /p BUILD_NUMBER=<%ARTIFACTS_DIR%\env\build_number.env
|
||||
|
@ -147,24 +147,20 @@ IF %BUILD_MODE% == stable_build (
|
|||
SET PACKAGE_FILE_ASSOCIATION=ON
|
||||
)
|
||||
cd "%BUILD_DIR%"
|
||||
cmake -DMUE_ENABLE_FILE_ASSOCIATION=%PACKAGE_FILE_ASSOCIATION% ..
|
||||
@REM cmake -DMUE_ENABLE_FILE_ASSOCIATION=%PACKAGE_FILE_ASSOCIATION% ..
|
||||
|
||||
SET PATH=%WIX_DIR%;%PATH%
|
||||
cmake --build . --target package || GOTO END_ERROR
|
||||
cd ..
|
||||
|
||||
ECHO "Create logs dir"
|
||||
MKDIR %ARTIFACTS_DIR%\logs
|
||||
MKDIR %ARTIFACTS_DIR%\logs\WIX
|
||||
MKDIR %ARTIFACTS_DIR%\CPack_Packages
|
||||
|
||||
SET WIX_LOG_DIR=win64
|
||||
IF %TARGET_PROCESSOR_BITS% == 32 ( SET WIX_LOG_DIR=win32 )
|
||||
SET WIX_LOGS_PATH="%BUILD_DIR%\_CPack_Packages"
|
||||
ECHO "Copy from %WIX_LOGS_PATH% to %ARTIFACTS_DIR%\CPack_Packages"
|
||||
|
||||
SET WIX_LOGS_PATH="%BUILD_DIR%\_CPack_Packages\%WIX_LOG_DIR%\WIX"
|
||||
ECHO "Copy from %WIX_LOGS_PATH% to %ARTIFACTS_DIR%\logs\WIX"
|
||||
|
||||
ECHO .msi > excludedmsi.txt
|
||||
XCOPY /Y /EXCLUDE:excludedmsi.txt %WIX_LOGS_PATH% %ARTIFACTS_DIR%\logs\WIX
|
||||
::ECHO .msi > excludedmsi.txt
|
||||
XCOPY /Y/E/H/C/I %WIX_LOGS_PATH% %ARTIFACTS_DIR%\CPack_Packages
|
||||
|
||||
:: find the MSI file without the hardcoded version
|
||||
for /r %%i in (%BUILD_DIR%\*.msi) do (
|
||||
|
@ -188,6 +184,8 @@ IF %DO_SIGN% == ON (
|
|||
|
||||
bash ./build/ci/tools/make_artifact_name_env.sh %ARTIFACT_NAME%
|
||||
|
||||
GOTO PACK_7z
|
||||
|
||||
GOTO END_SUCCESS
|
||||
|
||||
:: ============================
|
||||
|
|
|
@ -87,7 +87,9 @@ function do_build() {
|
|||
-DCMAKE_SKIP_RPATH="${MUSESCORE_NO_RPATH}" \
|
||||
|
||||
|
||||
ninja -j $JOBS
|
||||
cat CMakeCache.txt
|
||||
echo "================================================================================================"
|
||||
ninja -v -j $JOBS
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,22 +22,39 @@
|
|||
|
||||
#include "wasapiaudioclient.h"
|
||||
|
||||
#include "defer.h"
|
||||
#include "log.h"
|
||||
|
||||
using namespace mu;
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Windows::Media::Devices;
|
||||
using namespace winrt::Windows::Devices::Enumeration;
|
||||
|
||||
#define EEEE_IMPL(c) \
|
||||
auto funcname________ = FUNCNAME(FUNC_INFO); \
|
||||
LOGI() << "enter " << c << " " << funcname________; \
|
||||
DEFER { \
|
||||
LOGI() << "survived " << c << " " << funcname________; \
|
||||
};
|
||||
|
||||
#define EEEE_EMPTY
|
||||
|
||||
#define EEEEE EEEE_IMPL("")
|
||||
#define EEEE_TRY EEEE_IMPL("try")
|
||||
#define EEEE_CATCH EEEE_IMPL("catch")
|
||||
|
||||
WasapiAudioClient::WasapiAudioClient(HANDLE clientStartedEvent, HANDLE clientFailedToStartEvent, HANDLE clientStoppedEvent)
|
||||
: m_clientStartedEvent(clientStartedEvent), m_clientFailedToStartEvent(clientFailedToStartEvent), m_clientStoppedEvent(
|
||||
clientStoppedEvent)
|
||||
{
|
||||
EEEEE;
|
||||
check_hresult(MFStartup(MF_VERSION, MFSTARTUP_LITE));
|
||||
}
|
||||
|
||||
WasapiAudioClient::~WasapiAudioClient()
|
||||
{
|
||||
EEEEE;
|
||||
MFShutdown();
|
||||
}
|
||||
|
||||
|
@ -100,6 +117,8 @@ unsigned int WasapiAudioClient::channelCount() const
|
|||
|
||||
DeviceInformationCollection WasapiAudioClient::availableDevices() const
|
||||
{
|
||||
EEEEE;
|
||||
|
||||
// Get the string identifier of the audio renderer
|
||||
hstring AudioSelector = MediaDevice::GetAudioRenderSelector();
|
||||
|
||||
|
@ -109,9 +128,13 @@ DeviceInformationCollection WasapiAudioClient::availableDevices() const
|
|||
DeviceInformationCollection deviceInfoCollection = nullptr;
|
||||
|
||||
try {
|
||||
EEEE_TRY;
|
||||
deviceInfoCollection = deviceRequest.get();
|
||||
} catch (...) {
|
||||
LOGE() << to_string(hresult_error(to_hresult()).message());
|
||||
EEEE_CATCH;
|
||||
auto e = to_hresult();
|
||||
LOGI() << "survived to_hresult";
|
||||
LOGE() << to_string(hresult_error(e).message());
|
||||
}
|
||||
|
||||
return deviceInfoCollection;
|
||||
|
@ -119,12 +142,15 @@ DeviceInformationCollection WasapiAudioClient::availableDevices() const
|
|||
|
||||
hstring WasapiAudioClient::defaultDeviceId() const
|
||||
{
|
||||
EEEEE;
|
||||
return MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
|
||||
}
|
||||
|
||||
void WasapiAudioClient::asyncInitializeAudioDevice(const hstring& deviceId, bool useClosestSupportedFormat) noexcept
|
||||
{
|
||||
LOGI() << "enter";
|
||||
try {
|
||||
EEEE_TRY;
|
||||
// This call can be made safely from a background thread because we are asking for the IAudioClient3
|
||||
// interface of an audio device. Async operation will call back to
|
||||
// IActivateAudioInterfaceCompletionHandler::ActivateCompleted, which must be an agile interface implementation
|
||||
|
@ -134,10 +160,21 @@ void WasapiAudioClient::asyncInitializeAudioDevice(const hstring& deviceId, bool
|
|||
m_deviceState = DeviceState::Uninitialized;
|
||||
|
||||
com_ptr<IActivateAudioInterfaceAsyncOperation> asyncOp;
|
||||
check_hresult(ActivateAudioInterfaceAsync(m_deviceIdString.c_str(), __uuidof(IAudioClient3), nullptr, this, asyncOp.put()));
|
||||
|
||||
LOGI() << "before ActivateAudioInterfaceAsync";
|
||||
auto hres = ActivateAudioInterfaceAsync(m_deviceIdString.c_str(), __uuidof(IAudioClient3), nullptr, this, asyncOp.put());
|
||||
LOGI() << "after ActivateAudioInterfaceAsync, before check_hresult";
|
||||
|
||||
check_hresult(hres);
|
||||
LOGI() << "after check_hresult";
|
||||
} catch (...) {
|
||||
setStateAndNotify(DeviceState::Error, to_hresult());
|
||||
EEEE_CATCH;
|
||||
auto e = to_hresult();
|
||||
LOGI() << "survived to_hresult";
|
||||
setStateAndNotify(DeviceState::Error, e);
|
||||
}
|
||||
|
||||
LOGI() << "survived";
|
||||
}
|
||||
|
||||
static void logWAVEFORMATEX(WAVEFORMATEX* format)
|
||||
|
@ -159,39 +196,60 @@ static void logWAVEFORMATEX(WAVEFORMATEX* format)
|
|||
//
|
||||
HRESULT WasapiAudioClient::ActivateCompleted(IActivateAudioInterfaceAsyncOperation* operation) noexcept
|
||||
{
|
||||
EEEEE;
|
||||
|
||||
try {
|
||||
EEEE_TRY;
|
||||
if (m_deviceState != DeviceState::Uninitialized) {
|
||||
LOGI() << "not uninitialized";
|
||||
throw hresult_error(E_NOT_VALID_STATE);
|
||||
}
|
||||
|
||||
LOGI() << "survived uninitialized";
|
||||
|
||||
// Check for a successful activation result
|
||||
HRESULT hrActivateResult = S_OK;
|
||||
com_ptr<::IUnknown> punkAudioInterface;
|
||||
check_hresult(operation->GetActivateResult(&hrActivateResult, punkAudioInterface.put()));
|
||||
|
||||
LOGI() << "before operation->GetActivateResult(&hrActivateResult, punkAudioInterface.put())";
|
||||
auto hr = operation->GetActivateResult(&hrActivateResult, punkAudioInterface.put());
|
||||
LOGI() << "going to check hresult of operation->GetActivateResult(&hrActivateResult, punkAudioInterface.put())";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived hresult of operation->GetActivateResult(&hrActivateResult, punkAudioInterface.put())";
|
||||
check_hresult(hrActivateResult);
|
||||
LOGI() << "survived check_hresult(hrActivateResult)";
|
||||
|
||||
// Remember that we have been activated, but don't raise the event yet.
|
||||
setState(DeviceState::Activated);
|
||||
LOGI() << "survived setState(DeviceState::Activated);";
|
||||
|
||||
// Get the pointer for the Audio Client
|
||||
m_audioClient = punkAudioInterface.as<IAudioClient3>();
|
||||
LOGI() << "survived m_audioClient = punkAudioInterface.as<IAudioClient3>();";
|
||||
|
||||
// Configure user defined properties
|
||||
check_hresult(configureDeviceInternal());
|
||||
LOGI() << "survived check_hresult(configureDeviceInternal());";
|
||||
|
||||
// Initialize the AudioClient in Shared Mode with the user specified buffer
|
||||
if (!m_isLowLatency) {
|
||||
check_hresult(m_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
||||
m_hnsBufferDuration,
|
||||
0,
|
||||
m_mixFormat.get(),
|
||||
nullptr));
|
||||
auto h = m_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
||||
m_hnsBufferDuration,
|
||||
0,
|
||||
m_mixFormat.get(),
|
||||
nullptr);
|
||||
LOGI() << "survived m_audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED,";
|
||||
check_hresult(h);
|
||||
LOGI() << "survived check_hresult(m_audioClient->initialize";
|
||||
} else {
|
||||
check_hresult(m_audioClient->InitializeSharedAudioStream(AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||
m_minPeriodInFrames,
|
||||
m_mixFormat.get(),
|
||||
nullptr));
|
||||
LOGI() << "survived m_audioClient->InitializeSharedAudioStream(AUDCLNT_STREAMFLAGS_EVENTCALLBACK,";
|
||||
auto h = m_audioClient->InitializeSharedAudioStream(AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||
m_minPeriodInFrames,
|
||||
m_mixFormat.get(),
|
||||
nullptr);
|
||||
check_hresult(h);
|
||||
LOGI() << "survived check_hresult(m_audioClient->InitializeSharedAudioStream";
|
||||
}
|
||||
|
||||
LOGI() << "Initialized WASAPI audio endpoint with: ";
|
||||
|
@ -204,25 +262,41 @@ HRESULT WasapiAudioClient::ActivateCompleted(IActivateAudioInterfaceAsyncOperati
|
|||
LOGI() << "Min period in frames: " << m_minPeriodInFrames;
|
||||
|
||||
// Get the maximum size of the AudioClient Buffer
|
||||
check_hresult(m_audioClient->GetBufferSize(&m_bufferFrames));
|
||||
hr = m_audioClient->GetBufferSize(&m_bufferFrames);
|
||||
LOGI() << "survived m_audioClient->GetBufferSize(&m_bufferFrames);";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived check_hresult(m_audioClient->GetBufferSize(&m_bufferFrames);";
|
||||
|
||||
// Get the render client
|
||||
m_audioRenderClient.capture(m_audioClient, &IAudioClient::GetService);
|
||||
LOGI() << "survived m_audioRenderClient.capture(m_audioClient, &IAudioClient::GetService);";
|
||||
|
||||
// Create Async callback for sample events
|
||||
check_hresult(MFCreateAsyncResult(nullptr, &m_sampleReadyCallback, nullptr, m_sampleReadyAsyncResult.put()));
|
||||
hr = MFCreateAsyncResult(nullptr, &m_sampleReadyCallback, nullptr, m_sampleReadyAsyncResult.put());
|
||||
LOGI() << "survived MFCreateAsyncResult(nullptr, &m_sampleReadyCallback, nullptr, m_sampleReadyAsyncResult.put());";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived check_hresult(MFCreateAsyncResult(nullptr, &m_sampleReadyCallback, nullptr, m_sampleReadyAsyncResult.put());";
|
||||
|
||||
// Sets the event handle that the system signals when an audio buffer is ready to be processed by the client
|
||||
check_hresult(m_audioClient->SetEventHandle(m_sampleReadyEvent.get()));
|
||||
m_audioClient->SetEventHandle(m_sampleReadyEvent.get());
|
||||
LOGI() << "survived m_audioClient->SetEventHandle(m_sampleReadyEvent.get())";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survivied check_hresult(m_audioClient->SetEventHandle(m_sampleReadyEvent.get())";
|
||||
|
||||
// Everything succeeded
|
||||
setStateAndNotify(DeviceState::Initialized, S_OK);
|
||||
LOGI() << "survivied setStateAndNotify(DeviceState::Initialized, S_OK);";
|
||||
|
||||
startPlayback();
|
||||
LOGI() << "survived startPlayback";
|
||||
|
||||
return S_OK;
|
||||
} catch (...) {
|
||||
setStateAndNotify(DeviceState::Error, to_hresult());
|
||||
EEEE_CATCH;
|
||||
auto e = to_hresult();
|
||||
LOGI() << "survvied to_hresult";
|
||||
setStateAndNotify(DeviceState::Error, e);
|
||||
LOGI() << "survived setStateAndNotify(Error";
|
||||
|
||||
m_audioClient = nullptr;
|
||||
m_audioRenderClient = nullptr;
|
||||
|
@ -242,6 +316,7 @@ HRESULT WasapiAudioClient::ActivateCompleted(IActivateAudioInterfaceAsyncOperati
|
|||
//
|
||||
UINT32 WasapiAudioClient::getBufferFramesPerPeriod() noexcept
|
||||
{
|
||||
EEEEE;
|
||||
REFERENCE_TIME defaultDevicePeriod = 0;
|
||||
REFERENCE_TIME minimumDevicePeriod = 0;
|
||||
|
||||
|
@ -255,7 +330,9 @@ UINT32 WasapiAudioClient::getBufferFramesPerPeriod() noexcept
|
|||
|
||||
// Get the audio device period
|
||||
HRESULT hr = m_audioClient->GetDevicePeriod(&defaultDevicePeriod, &minimumDevicePeriod);
|
||||
LOGI() << "survived m_audioClient->GetDevicePeriod";
|
||||
if (FAILED(hr)) {
|
||||
LOGI() << "it failed though";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -270,7 +347,32 @@ UINT32 WasapiAudioClient::getBufferFramesPerPeriod() noexcept
|
|||
//
|
||||
HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
||||
{
|
||||
LOGI() << "Entering configureDeviceInternal; doing some tests first";
|
||||
try
|
||||
{
|
||||
LOGI() << "Throw runtime error";
|
||||
throw std::runtime_error("");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOGI() << "Caught runtime error";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
LOGI() << "Throw hresult error";
|
||||
check_hresult(AUDCLNT_E_UNSUPPORTED_FORMAT);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
LOGI() << "Caught hresult";
|
||||
HRESULT h = to_hresult();
|
||||
LOGI() << "Converted hresult: " << h;
|
||||
}
|
||||
|
||||
EEEEE;
|
||||
try {
|
||||
EEEE_TRY;
|
||||
if (m_deviceState != DeviceState::Activated) {
|
||||
return E_NOT_VALID_STATE;
|
||||
}
|
||||
|
@ -286,7 +388,10 @@ HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
|||
}
|
||||
|
||||
LOGI() << "WASAPI: Settings device client properties";
|
||||
check_hresult(m_audioClient->SetClientProperties(&audioProps));
|
||||
auto hr = m_audioClient->SetClientProperties(&audioProps);
|
||||
LOGI() << "survived m_audioClient->SetClientProperties(&audioProps)";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived check_hresult(m_audioClient->SetClientProperties(&audioProps));";
|
||||
|
||||
// If application already has a preferred source format available,
|
||||
// it can test whether the format is supported by the device:
|
||||
|
@ -304,7 +409,10 @@ HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
|||
|
||||
// This sample opens the device is shared mode so we need to find the supported WAVEFORMATEX mix format
|
||||
LOGI() << "WASAPI: Getting device mix format";
|
||||
check_hresult(m_audioClient->GetMixFormat(m_mixFormat.put()));
|
||||
hr = m_audioClient->GetMixFormat(m_mixFormat.put());
|
||||
LOGI() << "survived m_audioClient->GetMixFormat(m_mixFormat.put())";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived check_hersult(m_audioClient->GetMixFormat(m_mixFormat.put()))";
|
||||
|
||||
LOGI() << "WASAPI: Mix format after getting from audio client:";
|
||||
logWAVEFORMATEX(m_mixFormat.get());
|
||||
|
@ -320,8 +428,10 @@ HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
|||
logWAVEFORMATEX(m_mixFormat.get());
|
||||
|
||||
if (m_useClosestSupportedFormat) {
|
||||
LOGI() << "m_useClosestSupportedFormat";
|
||||
unique_cotaskmem_ptr<WAVEFORMATEX> closestSupported;
|
||||
m_audioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, m_mixFormat.get(), closestSupported.put());
|
||||
LOGI() << "survived m_audioClient->IsFormatSupported";
|
||||
|
||||
logWAVEFORMATEX(closestSupported.get());
|
||||
m_mixFormat = std::move(closestSupported);
|
||||
|
@ -331,16 +441,22 @@ HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
|||
LOGI() << "WASAPI: Getting shared mode engine period";
|
||||
// The wfx parameter below is optional (Its needed only for MATCH_FORMAT clients). Otherwise, wfx will be assumed
|
||||
// to be the current engine format based on the processing mode for this stream
|
||||
check_hresult(m_audioClient->GetSharedModeEnginePeriod(m_mixFormat.get(), &m_defaultPeriodInFrames,
|
||||
&m_fundamentalPeriodInFrames,
|
||||
&m_minPeriodInFrames, &m_maxPeriodInFrames));
|
||||
auto h = m_audioClient->GetSharedModeEnginePeriod(m_mixFormat.get(), &m_defaultPeriodInFrames,
|
||||
&m_fundamentalPeriodInFrames,
|
||||
&m_minPeriodInFrames, &m_maxPeriodInFrames);
|
||||
LOGI() << "survived m_audioClient->GetSharedModeEnginePeriod";
|
||||
check_hresult(h);
|
||||
LOGI() << "survived check_hresult(m_audioClient->GetSharedModeEnginePeriod)";
|
||||
}
|
||||
|
||||
LOGI() << "WASAPI: Device successfully configured";
|
||||
|
||||
return S_OK;
|
||||
} catch (...) {
|
||||
return to_hresult();
|
||||
EEEE_CATCH;
|
||||
auto r = to_hresult();
|
||||
LOGI() << "survived to_hresult";
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,6 +468,7 @@ HRESULT WasapiAudioClient::configureDeviceInternal() noexcept
|
|||
//
|
||||
void WasapiAudioClient::validateBufferValue()
|
||||
{
|
||||
EEEEE;
|
||||
if (!m_isHWOffload) {
|
||||
// If we aren't using HW Offload, set this to 0 to use the default value
|
||||
m_hnsBufferDuration = 0;
|
||||
|
@ -361,7 +478,12 @@ void WasapiAudioClient::validateBufferValue()
|
|||
REFERENCE_TIME hnsMinBufferDuration;
|
||||
REFERENCE_TIME hnsMaxBufferDuration;
|
||||
|
||||
check_hresult(m_audioClient->GetBufferSizeLimits(m_mixFormat.get(), true, &hnsMinBufferDuration, &hnsMaxBufferDuration));
|
||||
auto hr = m_audioClient->GetBufferSizeLimits(m_mixFormat.get(), true, &hnsMinBufferDuration, &hnsMaxBufferDuration);
|
||||
LOGI() << "survived m_audioClient->GetBufferSizeLimits(m_mixFormat.get(), true, &hnsMinBufferDuration, &hnsMaxBufferDuration)";
|
||||
check_hresult(hr);
|
||||
LOGI() <<
|
||||
"survived check_hresult(m_audioClient->GetBufferSizeLimits(m_mixFormat.get(), true, &hnsMinBufferDuration, &hnsMaxBufferDuration))";
|
||||
|
||||
if (m_hnsBufferDuration < hnsMinBufferDuration) {
|
||||
// using MINIMUM size instead
|
||||
m_hnsBufferDuration = hnsMinBufferDuration;
|
||||
|
@ -379,24 +501,31 @@ void WasapiAudioClient::validateBufferValue()
|
|||
//
|
||||
void WasapiAudioClient::startPlayback() noexcept
|
||||
{
|
||||
EEEEE;
|
||||
try {
|
||||
EEEE_TRY;
|
||||
switch (m_deviceState) {
|
||||
// We should be stopped if the user stopped playback, or we should be
|
||||
// initialized if this is the first time through getting ready to playback.
|
||||
case DeviceState::Stopped:
|
||||
case DeviceState::Initialized:
|
||||
case DeviceState::Initialized: {
|
||||
setStateAndNotify(DeviceState::Starting, S_OK);
|
||||
check_hresult(MFPutWorkItem2(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, 0, &m_startPlaybackCallback, nullptr));
|
||||
auto hr = MFPutWorkItem2(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, 0, &m_startPlaybackCallback, nullptr);
|
||||
LOGI() << "survived MFPutWorkItem2(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, 0, &m_startPlaybackCallback, nullptr)";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survived check_hresult(MFPutWorkItem2(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, 0, &m_startPlaybackCallback, nullptr))";
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
// Otherwise something else happened
|
||||
throw hresult_error(E_FAIL);
|
||||
}
|
||||
} catch (...) {
|
||||
EEEE_CATCH;
|
||||
hresult error = to_hresult();
|
||||
LOGI() << "survived to_hresult";
|
||||
setStateAndNotify(DeviceState::Error, error);
|
||||
|
||||
LOGI() << "survived setStateAndNotify";
|
||||
SetEvent(m_clientFailedToStartEvent);
|
||||
}
|
||||
}
|
||||
|
@ -408,24 +537,40 @@ void WasapiAudioClient::startPlayback() noexcept
|
|||
//
|
||||
HRESULT WasapiAudioClient::onStartPlayback(IMFAsyncResult*) noexcept
|
||||
{
|
||||
EEEEE;
|
||||
try {
|
||||
EEEE_TRY;
|
||||
// Pre-Roll the buffer with silence
|
||||
onAudioSampleRequested(true);
|
||||
LOGI() << "survived onAurioSampleRequested";
|
||||
|
||||
// Set the initial volume.
|
||||
//SetAudioClientChannelVolume();
|
||||
|
||||
// Actually start the playback
|
||||
check_hresult(m_audioClient->Start());
|
||||
auto hr = m_audioClient->Start();
|
||||
LOGI() << "survived m_audioClient->Start()";
|
||||
check_hresult(hr);
|
||||
LOGI() << "survivied check_hresult(m_audioClient->Start());";
|
||||
|
||||
setStateAndNotify(DeviceState::Playing, S_OK);
|
||||
check_hresult(MFPutWaitingWorkItem(m_sampleReadyEvent.get(), 0, m_sampleReadyAsyncResult.get(), &m_sampleReadyKey));
|
||||
LOGI() << "survived setStateAndNotify";
|
||||
|
||||
hr = MFPutWaitingWorkItem(m_sampleReadyEvent.get(), 0, m_sampleReadyAsyncResult.get(), &m_sampleReadyKey);
|
||||
LOGI() << "survived MFPutWaitingWorkItem(m_sampleReadyEvent.get(), 0, m_sampleReadyAsyncResult.get(), &m_sampleReadyKey)";
|
||||
check_hresult(hr);
|
||||
LOGI() <<
|
||||
"survived check_hresult(MFPutWaitingWorkItem(m_sampleReadyEvent.get(), 0, m_sampleReadyAsyncResult.get(), &m_sampleReadyKey))";
|
||||
|
||||
SetEvent(m_clientStartedEvent);
|
||||
|
||||
return S_OK;
|
||||
} catch (...) {
|
||||
setStateAndNotify(DeviceState::Error, to_hresult());
|
||||
EEEE_CATCH;
|
||||
hresult error = to_hresult();
|
||||
LOGI() << "survived to_hresult";
|
||||
setStateAndNotify(DeviceState::Error, error);
|
||||
LOGI() << "survived setStateAndNotify";
|
||||
|
||||
SetEvent(m_clientFailedToStartEvent);
|
||||
|
||||
|
@ -441,6 +586,7 @@ HRESULT WasapiAudioClient::onStartPlayback(IMFAsyncResult*) noexcept
|
|||
//
|
||||
HRESULT WasapiAudioClient::stopPlaybackAsync() noexcept
|
||||
{
|
||||
EEEEE;
|
||||
if ((m_deviceState != DeviceState::Playing)
|
||||
&& (m_deviceState != DeviceState::Paused)
|
||||
&& (m_deviceState != DeviceState::Error)) {
|
||||
|
@ -459,6 +605,7 @@ HRESULT WasapiAudioClient::stopPlaybackAsync() noexcept
|
|||
//
|
||||
HRESULT WasapiAudioClient::onStopPlayback(IMFAsyncResult*)
|
||||
{
|
||||
EEEEE;
|
||||
// Stop playback by cancelling Work Item
|
||||
// Cancel the queued work item (if any)
|
||||
|
||||
|
@ -489,7 +636,9 @@ HRESULT WasapiAudioClient::onStopPlayback(IMFAsyncResult*)
|
|||
//
|
||||
HRESULT WasapiAudioClient::onSampleReady(IMFAsyncResult*)
|
||||
{
|
||||
EEEEE;
|
||||
try {
|
||||
EEEE_TRY;
|
||||
onAudioSampleRequested(false);
|
||||
|
||||
// Re-queue work item for next sample
|
||||
|
@ -499,6 +648,7 @@ HRESULT WasapiAudioClient::onSampleReady(IMFAsyncResult*)
|
|||
|
||||
return S_OK;
|
||||
} catch (...) {
|
||||
EEEE_CATCH;
|
||||
hresult error = to_hresult();
|
||||
setStateAndNotify(DeviceState::Error, error);
|
||||
return error;
|
||||
|
@ -512,7 +662,9 @@ HRESULT WasapiAudioClient::onSampleReady(IMFAsyncResult*)
|
|||
//
|
||||
void WasapiAudioClient::onAudioSampleRequested(bool IsSilence)
|
||||
{
|
||||
EEEEE;
|
||||
try {
|
||||
EEEE_TRY;
|
||||
auto guard = slim_lock_guard(m_lock);
|
||||
|
||||
// Get padding in existing buffer
|
||||
|
@ -546,6 +698,7 @@ void WasapiAudioClient::onAudioSampleRequested(bool IsSilence)
|
|||
}
|
||||
catch (hresult_error const& error)
|
||||
{
|
||||
EEEE_CATCH;
|
||||
if (error.code() != AUDCLNT_E_RESOURCES_INVALIDATED) {
|
||||
throw;
|
||||
}
|
||||
|
@ -564,6 +717,7 @@ void WasapiAudioClient::onAudioSampleRequested(bool IsSilence)
|
|||
|
||||
void WasapiAudioClient::getSamples(uint32_t framesAvailable)
|
||||
{
|
||||
EEEEE;
|
||||
uint8_t* data;
|
||||
|
||||
uint32_t actualFramesToRead = framesAvailable;
|
||||
|
@ -587,6 +741,7 @@ void WasapiAudioClient::setState(const DeviceState newState)
|
|||
|
||||
void WasapiAudioClient::setStateAndNotify(const DeviceState newState, hresult resultCode)
|
||||
{
|
||||
LOGI() << "entering";
|
||||
if (m_deviceState == newState) {
|
||||
return;
|
||||
}
|
||||
|
@ -674,6 +829,7 @@ void WasapiAudioClient::setStateAndNotify(const DeviceState newState, hresult re
|
|||
break;
|
||||
|
||||
case S_OK:
|
||||
errMsg = "S_OK";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue