Use doit as leading build system rather than CMake

This commit is contained in:
Daniel Wolf 2024-12-17 12:30:42 +01:00
parent 260c22c7ed
commit 79c923b916
14 changed files with 200 additions and 133 deletions

View File

@ -29,16 +29,33 @@ jobs:
BOOST_ROOT: ${{ github.workspace }}/lib/boost
BOOST_URL: https://sourceforge.net/projects/boost/files/boost/1.86.0/boost_1_86_0.tar.bz2/download
steps:
- name: Install Deno
uses: denoland/setup-deno@v2
- name: Deactivate EOL conversion
shell: bash
run: |
git config --global core.autocrlf false
git config --global core.eol lf
- name: Checkout repository
uses: actions/checkout@v4
with:
lfs: true
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install Python wheels
shell: bash
run: pip install -r requirements.txt
- name: Restore Boost from cache
uses: actions/cache@v4
id: cache-boost
with:
path: ${{ env.BOOST_ROOT }}
key: ${{ env.BOOST_URL }}
- name: Lint
shell: bash
run: doit check-formatted
- name: Download Boost
if: steps.cache-boost.outputs.cache-hit != 'true'
shell: bash
@ -49,28 +66,29 @@ jobs:
fi
mkdir -p $BOOST_ROOT
curl --insecure -L $BOOST_URL | tar -xj --strip-components=1 -C $BOOST_ROOT
- name: Build Rhubarb
- name: Build and package
shell: bash
run: |
JAVA_HOME=$JAVA_HOME_11_X64
mkdir build
cd build
cmake ${{ matrix.cmakeOptions }} ..
cmake --build . --config Release --target package
mkdir rhubarb/build
(cd rhubarb/build && cmake ${{ matrix.cmakeOptions }} ..)
doit package
- name: Run tests
shell: bash
run: |
if [ "$RUNNER_OS" == "Windows" ]; then
./build/rhubarb/Release/runTests.exe
./rhubarb/build/Release/runTests.exe
else
./build/rhubarb/runTests
./rhubarb/build/runTests
fi
- name: Upload artifacts
if: ${{ matrix.publish }}
uses: actions/upload-artifact@v4
with:
name: 'binaries ${{ matrix.description }}'
path: build/*.zip
path: |
artifacts/*.zip
artifacts/*.tar.gz
release:
needs: build
runs-on: ubuntu-latest
@ -82,6 +100,8 @@ jobs:
uses: softprops/action-gh-release@v2
with:
draft: true
files: '*.zip'
files: |
'*.zip'
'*.tar.gz'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.vs/
.vscode/
*.user
artifacts/
build/
venv/

View File

@ -1,38 +0,0 @@
cmake_minimum_required(VERSION 3.2)
include(app-info.cmake)
project(${appName})
# Build and install main executable
add_subdirectory(rhubarb)
# Build and install extras
add_subdirectory("extras/adobe-after-effects")
add_subdirectory("extras/magix-vegas")
add_subdirectory("extras/esoteric-software-spine")
# Install misc. files
install(FILES README.adoc LICENSE.md CHANGELOG.md DESTINATION .)
# Configure CPack
function(get_short_system_name variable)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
set(${variable} "macOS" PARENT_SCOPE)
else()
set(${variable} "${CMAKE_SYSTEM_NAME}" PARENT_SCOPE)
endif()
endfunction()
set(CPACK_PACKAGE_NAME ${appName})
string(REPLACE " " "-" CPACK_PACKAGE_NAME "${CPACK_PACKAGE_NAME}")
get_short_system_name(CPACK_SYSTEM_NAME)
set(CPACK_PACKAGE_VERSION_MAJOR ${appVersionMajor})
set(CPACK_PACKAGE_VERSION_MINOR ${appVersionMinor})
set(CPACK_PACKAGE_VERSION_PATCH ${appVersionPatch})
set(CPACK_PACKAGE_VERSION ${appVersion})
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
set(CPACK_GENERATOR ZIP)
# Run CPack
include(CPack)

View File

@ -1,8 +0,0 @@
cmake_minimum_required(VERSION 3.2)
set(appName "Rhubarb Lip Sync")
set(appVersionMajor 1)
set(appVersionMinor 13)
set(appVersionPatch 0)
set(appVersionSuffix "")
set(appVersion "${appVersionMajor}.${appVersionMinor}.${appVersionPatch}${appVersionSuffix}")

4
app-info.toml Normal file
View File

@ -0,0 +1,4 @@
appName = "Rhubarb Lip Sync"
# Can be any valid SemVer version, including suffixes
appVersion = "1.13.0"

123
dodo.py
View File

@ -6,10 +6,14 @@ from functools import cache
from gitignore_parser import parse_gitignore
from typing import Dict, Optional, List
from enum import Enum
from shutil import rmtree, copy, copytree, make_archive
import platform
import tomllib
root_dir = Path(__file__).parent
rhubarb_dir = root_dir / 'rhubarb'
rhubarb_build_dir = rhubarb_dir / 'build'
extras_dir = root_dir / 'extras'
def task_format():
@ -48,8 +52,11 @@ class Formatter(Enum):
def format(files: List[Path], formatter: Formatter, *, check_only: bool = False):
match formatter:
case Formatter.CLANG_FORMAT:
# Pass relative paths to avoid exceeding the maximum command line length
relative_paths = [file.relative_to(root_dir) for file in files]
subprocess.run(
['clang-format', '--dry-run' if check_only else '-i', '--Werror', *files],
['clang-format', '--dry-run' if check_only else '-i', '--Werror', *relative_paths],
cwd=root_dir,
check=True,
)
case Formatter.GERSEMI:
@ -71,6 +78,100 @@ def format(files: List[Path], formatter: Formatter, *, check_only: bool = False)
raise ValueError(f'Unknown formatter: {formatter}')
def task_configure_rhubarb():
"""Configure CMake for the Rhubarb binary"""
def configure_rhubarb():
ensure_dir(rhubarb_build_dir)
subprocess.run(['cmake', '..'], cwd=rhubarb_build_dir, check=True)
return {'basename': 'configure-rhubarb', 'actions': [configure_rhubarb]}
def task_build_rhubarb():
"""Build the Rhubarb binary"""
def build_rhubarb():
subprocess.run(
['cmake', '--build', '.', '--config', 'Release'], cwd=rhubarb_build_dir, check=True
)
return {'basename': 'build-rhubarb', 'actions': [build_rhubarb]}
def task_build_spine():
"""Build Rhubarb for Spine"""
def build_spine():
onWindows = platform.system() == 'Windows'
subprocess.run(
['gradlew.bat' if onWindows else './gradlew', 'build'],
cwd=extras_dir / 'esoteric-software-spine',
check=True,
shell=onWindows,
)
return {'basename': 'build-spine', 'actions': [build_spine]}
def task_package():
"""Package all artifacts into an archive file"""
with open(root_dir / 'app-info.toml', 'rb') as file:
appInfo = tomllib.load(file)
os_name = 'macOS' if platform.system() == 'Darwin' else platform.system()
file_name = f"{appInfo['appName'].replace(' ', '-')}-{appInfo['appVersion']}-{os_name}"
artifacts_dir = ensure_empty_dir(root_dir / 'artifacts')
tree_dir = ensure_dir(artifacts_dir.joinpath(file_name))
def collect_artifacts():
# Misc. files
copy(root_dir / 'README.adoc', tree_dir)
copy(root_dir / 'LICENSE.md', tree_dir)
copy(root_dir / 'CHANGELOG.md', tree_dir)
copytree(root_dir / 'img', tree_dir / 'img')
# Rhubarb
subprocess.run(
['cmake', '--install', '.', '--prefix', tree_dir], cwd=rhubarb_build_dir, check=True
)
# Adobe After Effects script
src = extras_dir / 'adobe-after-effects'
dst_extras_dir = ensure_dir(tree_dir / 'extras')
dst = ensure_dir(dst_extras_dir / 'adobe-after-effects')
copy(src / 'README.adoc', dst)
copy(src / 'Rhubarb Lip Sync.jsx', dst)
# Rhubarb for Spine
src = extras_dir / 'esoteric-software-spine'
dst = ensure_dir(dst_extras_dir / 'esoteric-software-spine')
copy(src / 'README.adoc', dst)
for file in (src / 'build' / 'libs').iterdir():
copy(file, dst)
# Magix Vegas
src = extras_dir / 'magix-vegas'
dst = ensure_dir(dst_extras_dir / 'magix-vegas')
copy(src / 'README.adoc', dst)
copy(src / 'Debug Rhubarb.cs', dst)
copy(src / 'Debug Rhubarb.cs.config', dst)
copy(src / 'Import Rhubarb.cs', dst)
copy(src / 'Import Rhubarb.cs.config', dst)
def pack_artifacts():
zip_base_name = tree_dir
format = 'gztar' if platform.system() == 'Linux' else 'zip'
make_archive(zip_base_name, format, tree_dir)
return {
'actions': [collect_artifacts, pack_artifacts],
'task_dep': ['build-rhubarb', 'build-spine'],
}
@cache
def get_files_by_formatters() -> Dict[Formatter, List[Path]]:
"""Returns a dict with all formattable code files grouped by formatter."""
@ -81,7 +182,7 @@ def get_files_by_formatters() -> Dict[Formatter, List[Path]]:
return path.name.startswith('.')
def is_third_party(path: Path):
return path.is_relative_to(rhubarb_dir / 'lib') or path.name == 'gradle'
return path.name == 'lib' or path.name == 'gradle'
result = {formatter: [] for formatter in Formatter}
@ -115,3 +216,19 @@ def get_formatter(path: Path) -> Optional[Formatter]:
return Formatter.PRETTIER
case '.py':
return Formatter.RUFF
def ensure_dir(dir: Path) -> Path:
"""Makes sure the given directory exists."""
if not dir.exists():
dir.mkdir()
return dir
def ensure_empty_dir(dir: Path) -> Path:
"""Makes sure the given directory exists and is empty."""
if dir.exists():
rmtree(dir)
return ensure_dir(dir)

View File

@ -1,5 +0,0 @@
cmake_minimum_required(VERSION 3.2)
set(afterEffectsFiles "Rhubarb Lip Sync.jsx" "README.adoc")
install(FILES ${afterEffectsFiles} DESTINATION "extras/adobe-after-effects")

View File

@ -1,13 +0,0 @@
cmake_minimum_required(VERSION 3.2)
add_custom_target(
rhubarbForSpine
ALL
"./gradlew" "build"
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Building Rhubarb for Spine through Gradle."
)
install(DIRECTORY "build/libs/" DESTINATION "extras/esoteric-software-spine")
install(FILES README.adoc DESTINATION "extras/esoteric-software-spine")

View File

@ -8,13 +8,9 @@ plugins {
fun getVersion(): String {
// Dynamically read version from CMake file
val file = File(rootDir.parentFile.parentFile, "app-info.cmake")
val file = File(rootDir.parentFile.parentFile, "app-info.toml")
val text = file.readText()
val major = Regex("""appVersionMajor\s+(\d+)""").find(text)!!.groupValues[1]
val minor = Regex("""appVersionMinor\s+(\d+)""").find(text)!!.groupValues[1]
val patch = Regex("""appVersionPatch\s+(\d+)""").find(text)!!.groupValues[1]
val suffix = Regex("""appVersionSuffix\s+"(.*?)"""").find(text)!!.groupValues[1]
return "$major.$minor.$patch$suffix"
return Regex("""appVersion\s*=\s*"(.*?)"(?:)""").find(text)!!.groupValues[1]
}
group = "com.rhubarb_lip_sync"

View File

@ -1,11 +0,0 @@
cmake_minimum_required(VERSION 3.2)
set(vegasFiles
"Debug Rhubarb.cs"
"Debug Rhubarb.cs.config"
"Import Rhubarb.cs"
"Import Rhubarb.cs.config"
"README.adoc"
)
install(FILES ${vegasFiles} DESTINATION "extras/magix-vegas")

View File

@ -1,6 +0,0 @@
#!/bin/sh
rm -rf build
mkdir build
cd build
cmake .. -G Xcode
cmake --build . --config Release --target package

View File

@ -1,5 +0,0 @@
rmdir /s /q build
mkdir build
cd build
cmake .. -G "Visual Studio 16 2019"
cmake --build . --config Release --target package

View File

@ -1,6 +1,13 @@
cmake_minimum_required(VERSION 3.10)
include("../app-info.cmake")
# Parse app info
file(READ "../app-info.toml" tomlContent)
string(REGEX MATCH "appName *= *\"[^\"]+\"" appName "${tomlContent}")
string(REGEX REPLACE ".*\"([^\"]+)\"" "\\1" appName "${appName}")
string(REGEX MATCH "appVersion *= *\"[^\"]+\"" appVersion "${tomlContent}")
string(REGEX REPLACE ".*\"([^\"]+)\"" "\\1" appVersion "${appVersion}")
project("${appName}")
# Support legacy OS X versions
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.10" CACHE STRING "Minimum OS X deployment version")
@ -94,6 +101,7 @@ set_target_properties(pocketSphinx PROPERTIES FOLDER lib)
include_directories(SYSTEM "lib/tclap-1.2.1/include")
# ... Google Test
set(INSTALL_GTEST OFF) # Prevent library files from ending up in our artifacts
add_subdirectory("lib/googletest")
target_compile_options(gmock PRIVATE ${disableWarningsFlags})
set_target_properties(gmock PROPERTIES FOLDER lib)
@ -327,7 +335,7 @@ target_link_libraries(
)
# ... rhubarb-core
configure_file(src/core/app-info.cpp.in app-info.cpp ESCAPE_QUOTES)
configure_file(src/core/app-info.cpp.in app-info.cpp)
add_library(
rhubarb-core
${CMAKE_CURRENT_BINARY_DIR}/app-info.cpp
@ -560,7 +568,4 @@ endfunction()
copy_and_install("lib/pocketsphinx-rev13216/model/en-us/*" "res/sphinx")
copy_and_install("lib/cmusphinx-en-us-5.2/*" "res/sphinx/acoustic-model")
copy_and_install("tests/resources/*" "tests/resources")
install(TARGETS rhubarb RUNTIME DESTINATION .)

View File

@ -1,13 +1,28 @@
#include <gmock/gmock.h>
#include <filesystem>
#include "audio/wave-file-reader.h"
#include "tools/platform-tools.h"
using namespace testing;
using std::filesystem::path;
path getResourcesDirectory() {
path p = getBinDirectory();
// Search up for resources directory
while (true) {
path resourcesDirectory = p / "tests/resources";
if (std::filesystem::exists(resourcesDirectory)) return resourcesDirectory;
p = p.parent_path();
}
}
TEST(getWaveFormatInfo, float32FromAudacity) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-float32-audacity.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-float32-audacity.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -18,7 +33,7 @@ TEST(getWaveFormatInfo, float32FromAudacity) {
TEST(getWaveFormatInfo, float32FromAudition) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-float32-audition.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-float32-audition.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -29,7 +44,7 @@ TEST(getWaveFormatInfo, float32FromAudition) {
TEST(getWaveFormatInfo, float32FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-float32-ffmpeg.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-float32-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -39,9 +54,8 @@ TEST(getWaveFormatInfo, float32FromFfmpeg) {
}
TEST(getWaveFormatInfo, float32FromSoundforge) {
auto formatInfo = getWaveFormatInfo(
getBinDirectory() / "tests/resources/sine-triangle-float32-soundforge.wav"
);
auto formatInfo =
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-float32-soundforge.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -52,7 +66,7 @@ TEST(getWaveFormatInfo, float32FromSoundforge) {
TEST(getWaveFormatInfo, float64FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-float64-ffmpeg.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-float64-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -63,7 +77,7 @@ TEST(getWaveFormatInfo, float64FromFfmpeg) {
TEST(getWaveFormatInfo, int16FromAudacity) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int16-audacity.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int16-audacity.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -74,7 +88,7 @@ TEST(getWaveFormatInfo, int16FromAudacity) {
TEST(getWaveFormatInfo, int16FromAudition) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int16-audition.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int16-audition.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -84,8 +98,7 @@ TEST(getWaveFormatInfo, int16FromAudition) {
}
TEST(getWaveFormatInfo, int16FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int16-ffmpeg.wav");
auto formatInfo = getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int16-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -96,7 +109,7 @@ TEST(getWaveFormatInfo, int16FromFfmpeg) {
TEST(getWaveFormatInfo, int16FromSoundforge) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int16-soundforge.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int16-soundforge.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -107,7 +120,7 @@ TEST(getWaveFormatInfo, int16FromSoundforge) {
TEST(getWaveFormatInfo, int24FromAudacity) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int24-audacity.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int24-audacity.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -118,7 +131,7 @@ TEST(getWaveFormatInfo, int24FromAudacity) {
TEST(getWaveFormatInfo, int24FromAudition) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int24-audition.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int24-audition.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -128,8 +141,7 @@ TEST(getWaveFormatInfo, int24FromAudition) {
}
TEST(getWaveFormatInfo, int24FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int24-ffmpeg.wav");
auto formatInfo = getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int24-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -140,7 +152,7 @@ TEST(getWaveFormatInfo, int24FromFfmpeg) {
TEST(getWaveFormatInfo, int24FromSoundforge) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int24-soundforge.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int24-soundforge.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -150,8 +162,7 @@ TEST(getWaveFormatInfo, int24FromSoundforge) {
}
TEST(getWaveFormatInfo, int32FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int32-ffmpeg.wav");
auto formatInfo = getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int32-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -162,7 +173,7 @@ TEST(getWaveFormatInfo, int32FromFfmpeg) {
TEST(getWaveFormatInfo, int32FromSoundforge) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-int32-soundforge.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-int32-soundforge.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -173,7 +184,7 @@ TEST(getWaveFormatInfo, int32FromSoundforge) {
TEST(getWaveFormatInfo, uint8FromAudition) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-uint8-audition.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-uint8-audition.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -183,8 +194,7 @@ TEST(getWaveFormatInfo, uint8FromAudition) {
}
TEST(getWaveFormatInfo, uint8FromFfmpeg) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-uint8-ffmpeg.wav");
auto formatInfo = getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-uint8-ffmpeg.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);
@ -195,7 +205,7 @@ TEST(getWaveFormatInfo, uint8FromFfmpeg) {
TEST(getWaveFormatInfo, uint8FromSoundforge) {
auto formatInfo =
getWaveFormatInfo(getBinDirectory() / "tests/resources/sine-triangle-uint8-soundforge.wav");
getWaveFormatInfo(getResourcesDirectory() / "sine-triangle-uint8-soundforge.wav");
EXPECT_EQ(formatInfo.frameRate, 48000);
EXPECT_EQ(formatInfo.frameCount, 480000);
EXPECT_EQ(formatInfo.channelCount, 2);