Compare commits

...

5 Commits

Author SHA1 Message Date
Attila Uygun 655c0a7b71 Update android build
Upgrade to gradle 8.0
Compile and target sdk 33
Min sdk 24
Upgrade to Google Mobile Ads SDK 22.0
Enable c++20 and fix compilation issues
2023-05-09 22:22:02 +02:00
Attila Uygun 97271835b0 Remove gn 2023-05-05 08:22:51 +02:00
Attila Uygun 4bab472ed1 Enable extra warnings for all but third-party 2023-05-04 23:21:32 +02:00
Attila Uygun 653c283758 Use std::counting_semaphore 2023-05-04 18:07:30 +02:00
Attila Uygun 771f8a3d78 Update SincResampler 2023-05-03 20:21:26 +02:00
48 changed files with 5002 additions and 5557 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
build/android/.gradle
build/android/*.apk
build/android/*.idsig
build/android/app/.cxx
build/android/app/build
build/android/build

2
.gn
View File

@ -1,2 +0,0 @@
# The location of the build configuration file.
buildconfig = "//build/gn/BUILDCONFIG.gn"

View File

@ -1,5 +0,0 @@
group("kaliber") {
deps = [
"//src/demo",
]
}

View File

@ -1,5 +1,5 @@
A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers.
Supports Linux and Android (lolipop+) platforms.
Supports Linux and Android platforms.
This is a personal hobby project. I've published a little game on
[Google Play](https://play.google.com/store/apps/details?id=com.woom.game)
based on this engine. Full game code and assets are included in this repository.
@ -14,11 +14,6 @@ Android:
cd build/android
./gradlew :app:assembleRelease
```
GN (linux only for now):
```text
gn gen --args='is_debug=false' out/release
ninja -C out/release
```
#### Third-party libraries:
[glew](https://github.com/nigels-com/glew),
[jsoncpp](https://github.com/open-source-parsers/jsoncpp),

View File

@ -14,7 +14,8 @@
# limitations under the License.
#
cmake_minimum_required(VERSION 3.4.1)
cmake_minimum_required(VERSION 3.22.1)
project(kaliber)
# OBOE Library
set (OBOE_DIR ../../../src/third_party/oboe)
@ -36,9 +37,9 @@ add_library(native_app_glue STATIC
# now build app's shared lib
if (CMAKE_BUILD_TYPE MATCHES Debug)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Werror -D_DEBUG -DVK_USE_PLATFORM_ANDROID_KHR")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Werror -Wno-unused-but-set-variable -Wno-deprecated-enum-enum-conversion -Wno-unused-parameter -Wno-unsequenced -D_DEBUG -DVK_USE_PLATFORM_ANDROID_KHR")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Werror -DVK_USE_PLATFORM_ANDROID_KHR")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20 -Wall -Werror -Wno-unused-but-set-variable -Wno-deprecated-enum-enum-conversion -Wno-unused-parameter -Wno-unsequenced -DVK_USE_PLATFORM_ANDROID_KHR")
endif ()
@ -141,6 +142,7 @@ add_library(kaliber SHARED
../../../src/third_party/minizip/ioapi.c
../../../src/third_party/minizip/unzip.c
../../../src/third_party/spirv-reflect/spirv_reflect.c
../../../src/third_party/stb/stb_image.c
../../../src/third_party/texture_compressor/dxt_encoder_internals.cc
../../../src/third_party/texture_compressor/dxt_encoder.cc
../../../src/third_party/texture_compressor/texture_compressor_etc1.cc

View File

@ -1,13 +1,13 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
ndkVersion '21.3.6528147'
compileSdk 33
ndkVersion '25.1.8937393'
defaultConfig {
applicationId = 'com.woom.game'
minSdkVersion 21
targetSdkVersion 29
minSdk 24
targetSdk 33
externalNativeBuild {
cmake {
arguments '-DANDROID_STL=c++_static'
@ -29,7 +29,7 @@ android {
}
externalNativeBuild {
cmake {
version '3.10.2'
version '3.22.1'
path 'CMakeLists.txt'
}
}
@ -39,11 +39,12 @@ android {
assets.srcDirs = ['../../../assets']
}
}
namespace 'com.woom.game'
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.gms:play-services-ads:19.1.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.gms:play-services-ads:22.0.0'
}

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.woom.game"
android:versionCode="16"
android:versionName="1.0.1">
@ -20,6 +19,7 @@
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:exported="true"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:8.0.1'
}
}

View File

@ -9,9 +9,13 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
android.defaults.buildfeatures.buildconfig=true
android.enableJetifier=true
android.nonFinalResIds=false
android.nonTransitiveRClass=false
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
android.native.buildOutput=verbose
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip

View File

@ -1,2 +1,2 @@
jarsigner -keystore ~/key_store/apk_key_store.jks -storepass xxx -keypass xxx -signedjar app-release.apk ./app/build/outputs/apk/release/app-release-unsigned.apk upload
zipalign -f 4 ./app-release.apk ./app-release-aligned.apk
~/Android/Sdk/build-tools/31.0.0/zipalign -p -f 4 ./app/build/outputs/apk/release/app-release-unsigned.apk ./app-release-aligned.apk
~/Android/Sdk/build-tools/31.0.0/apksigner sign -ks ~/key_store/apk_key_store.jks --ks-key-alias upload --ks-pass stdin ./app-release-aligned.apk

View File

@ -1,40 +0,0 @@
config("compiler_defaults") {
if (current_os == "linux") {
cflags = [
"-fPIC",
"-pthread",
"-g",
]
cflags_cc = [
"-std=c++17",
"-I../../src",
]
}
}
config("executable_ldconfig") {
ldflags = [
"-Wl,-rpath=\$ORIGIN/",
"-Wl,-rpath-link=",
]
}
config("debug") {
defines = [ "_DEBUG" ]
if (current_os == "linux") {
if (current_cpu == "x64") {
defines += [ "_GLIBCXX_DEBUG=1" ]
}
}
}
config("release") {
cflags = []
defines = [ "NDEBUG" ]
if (current_os == "linux") {
cflags += [ "-Ofast" ]
}
}

View File

@ -1,41 +0,0 @@
declare_args() {
is_debug = false
}
if (target_os == "") {
target_os = host_os
}
if (target_cpu == "") {
target_cpu = host_cpu
}
if (current_cpu == "") {
current_cpu = target_cpu
}
if (current_os == "") {
current_os = target_os
}
_compiler_default_config = [ "//build/gn:compiler_defaults" ]
# Debug/release-related defines.
if (is_debug) {
_compiler_default_config += [ "//build/gn:debug" ]
} else {
_compiler_default_config += [ "//build/gn:release" ]
}
set_defaults("executable") {
configs = _compiler_default_config
configs += [ "//build/gn:executable_ldconfig" ]
}
set_defaults("static_library") {
configs = _compiler_default_config
}
set_defaults("shared_library") {
configs = _compiler_default_config
}
set_defaults("source_set") {
configs = _compiler_default_config
}
set_default_toolchain("//build/gn/toolchain:clang")

View File

@ -1,151 +0,0 @@
toolchain("clang") {
tool("cc") {
depfile = "{{output}}.d"
command = "clang -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CC {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
}
tool("cxx") {
depfile = "{{output}}.d"
command = "clang++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CXX {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
}
tool("alink") {
rspfile = "{{output}}.rsp"
command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"
description = "AR {{target_output_name}}{{output_extension}}"
rspfile_content = "{{inputs}}"
outputs =
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
default_output_extension = ".a"
output_prefix = "lib"
}
tool("solink") {
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
sofile = "{{output_dir}}/$soname"
rspfile = soname + ".rsp"
command = "clang++ -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
description = "SOLINK $soname"
# Use this for {{output_extension}} expansions unless a target manually
# overrides it (in which case {{output_extension}} will be what the target
# specifies).
default_output_extension = ".so"
# Use this for {{output_dir}} expansions unless a target manually overrides
# it (in which case {{output_dir}} will be what the target specifies).
default_output_dir = "{{root_out_dir}}"
outputs = [ sofile ]
link_output = sofile
depend_output = sofile
output_prefix = "lib"
}
tool("link") {
outfile = "{{target_output_name}}{{output_extension}}"
rspfile = "$outfile.rsp"
command = "clang++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
description = "LINK $outfile"
default_output_dir = "{{root_out_dir}}"
rspfile_content = "{{inputs}}"
outputs = [ outfile ]
}
tool("stamp") {
command = "touch {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "cp -af {{source}} {{output}}"
description = "COPY {{source}} {{output}}"
}
}
toolchain("gcc") {
tool("cc") {
depfile = "{{output}}.d"
command = "gcc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CC {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
}
tool("cxx") {
depfile = "{{output}}.d"
command = "g++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CXX {{output}}"
outputs =
[ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ]
}
tool("alink") {
rspfile = "{{output}}.rsp"
command = "rm -f {{output}} && ar rcs {{output}} @$rspfile"
description = "AR {{target_output_name}}{{output_extension}}"
rspfile_content = "{{inputs}}"
outputs =
[ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ]
default_output_extension = ".a"
output_prefix = "lib"
}
tool("solink") {
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
sofile = "{{output_dir}}/$soname"
rspfile = soname + ".rsp"
command = "g++ -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
description = "SOLINK $soname"
# Use this for {{output_extension}} expansions unless a target manually
# overrides it (in which case {{output_extension}} will be what the target
# specifies).
default_output_extension = ".so"
# Use this for {{output_dir}} expansions unless a target manually overrides
# it (in which case {{output_dir}} will be what the target specifies).
default_output_dir = "{{root_out_dir}}"
outputs = [ sofile ]
link_output = sofile
depend_output = sofile
output_prefix = "lib"
}
tool("link") {
outfile = "{{target_output_name}}{{output_extension}}"
rspfile = "$outfile.rsp"
command = "g++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
description = "LINK $outfile"
default_output_dir = "{{root_out_dir}}"
rspfile_content = "{{inputs}}"
outputs = [ outfile ]
}
tool("stamp") {
command = "touch {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "cp -af {{source}} {{output}}"
description = "COPY {{source}} {{output}}"
}
}

View File

@ -32,8 +32,8 @@ LDFLAGS = -lX11 -lGL -pthread -lasound -ldl
# Always enable debug information.
CFLAGS += -g
# Make all warnings into errors.
CFLAGS += -Werror
# Enable extra warnings and make all warnings into errors.
CFLAGS += -Wextra -Werror
# Flags to generate dependency information.
CFLAGS += -MD -MP -MT $@
@ -75,15 +75,26 @@ app_exe = $(OUTPUT_DIR)/$(1)_$(ARCH)_$(BUILD)
objs_from_src = $(patsubst $(SRC_ROOT)/%, $(BUILD_DIR)/%.o, $(basename $(1)))
objs_from_src_in = $(call objs_from_src, $(shell find $(1) -name "*.cc" -o -name "*.cpp" -o -name "*.c"))
# --- Engine ---
# --- Base ---
ENGINE_SRC := \
BASE_SRC := \
$(SRC_ROOT)/base/collusion_test.cc \
$(SRC_ROOT)/base/log.cc \
$(SRC_ROOT)/base/sinc_resampler.cc \
$(SRC_ROOT)/base/task_runner.cc \
$(SRC_ROOT)/base/thread_pool.cc \
$(SRC_ROOT)/base/timer.cc \
$(SRC_ROOT)/base/timer.cc
BASE_LIB := $(BUILD_DIR)/libengine.a
BASE_OBJS := $(call objs_from_src, $(BASE_SRC))
LIBS += $(BASE_LIB)
OBJS += $(BASE_OBJS)
$(BASE_LIB): $(BASE_OBJS)
# --- Engine ---
ENGINE_SRC := \
$(SRC_ROOT)/engine/animatable.cc \
$(SRC_ROOT)/engine/animator.cc \
$(SRC_ROOT)/engine/audio/audio_alsa.cc \
@ -113,7 +124,25 @@ ENGINE_SRC := \
$(SRC_ROOT)/engine/shader_source.cc \
$(SRC_ROOT)/engine/solid_quad.cc \
$(SRC_ROOT)/engine/sound_player.cc \
$(SRC_ROOT)/engine/sound.cc \
$(SRC_ROOT)/engine/sound.cc
ENGINE_LIB := $(BUILD_DIR)/libengine.a
ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC))
LIBS += $(ENGINE_LIB)
OBJS += $(ENGINE_OBJS)
$(ENGINE_LIB): $(ENGINE_OBJS)
# --- Third-party ---
# Ignore warnings.
THIRD_PARTY_CFLAGS = $(CFLAGS)
THIRD_PARTY_CFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CFLAGS))
THIRD_PARTY_CXXFLAGS = $(CXXFLAGS)
THIRD_PARTY_CXXFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CXXFLAGS))
THIRD_PARTY_SRC := \
$(SRC_ROOT)/third_party/glew/glew.c \
$(SRC_ROOT)/third_party/glslang/glslang/CInterface/glslang_c_interface.cpp \
$(SRC_ROOT)/third_party/glslang/glslang/GenericCodeGen/CodeGen.cpp \
@ -160,6 +189,7 @@ ENGINE_SRC := \
$(SRC_ROOT)/third_party/glslang/StandAlone/ResourceLimits.cpp \
$(SRC_ROOT)/third_party/jsoncpp/jsoncpp.cpp \
$(SRC_ROOT)/third_party/spirv-reflect/spirv_reflect.c \
$(SRC_ROOT)/third_party/stb/stb_image.c \
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder_internals.cc \
$(SRC_ROOT)/third_party/texture_compressor/dxt_encoder.cc \
$(SRC_ROOT)/third_party/texture_compressor/texture_compressor_etc1.cc \
@ -176,12 +206,24 @@ ENGINE_SRC := \
$(SRC_ROOT)/third_party/vulkan/loader/unknown_ext_chain.c \
$(SRC_ROOT)/third_party/vulkan/loader/wsi.c
ENGINE_LIB := $(BUILD_DIR)/libengine.a
ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC))
LIBS += $(ENGINE_LIB)
OBJS += $(ENGINE_OBJS)
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.c
@mkdir -p $(@D)
$(HUSH_COMPILE) $(CC) -c $(THIRD_PARTY_CFLAGS) -o $@ $<
$(ENGINE_LIB): $(ENGINE_OBJS)
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cc
@mkdir -p $(@D)
$(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $<
$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cpp
@mkdir -p $(@D)
$(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $<
THIRD_PARTY_LIB := $(BUILD_DIR)/libthirdparty.a
THIRD_PARTY_OBJS := $(call objs_from_src, $(THIRD_PARTY_SRC))
LIBS += $(THIRD_PARTY_LIB)
OBJS += $(THIRD_PARTY_OBJS)
$(THIRD_PARTY_LIB): $(THIRD_PARTY_OBJS)
# --- demo application ---

View File

@ -1,35 +0,0 @@
source_set("base") {
sources = [
"closure.h",
"collusion_test.cc",
"collusion_test.h",
"file.h",
"hash.h",
"interpolation.h",
"log.cc",
"log.h",
"mem.h",
"misc.h",
"random.h",
"sinc_resampler.cc",
"sinc_resampler.h",
"task_runner.cc",
"task_runner.h",
"thread_pool.cc",
"thread_pool.h",
"timer.cc",
"timer.h",
"vecmath.h",
]
# ldflags = []
# libs = []
if (target_os == "linux") {
# ldflags += [ "-L/usr/X11R6/lib" ]
# libs += [ "X11", "rt", "pthread" ]
}
deps = []
}

View File

@ -1,41 +0,0 @@
#ifndef BASE_SEMAPHORE_H
#define BASE_SEMAPHORE_H
#include <condition_variable>
#include <mutex>
#include "base/log.h"
namespace base {
class Semaphore {
public:
Semaphore(int count = 0) : count_(count) {}
void Acquire() {
std::unique_lock<std::mutex> scoped_lock(mutex_);
cv_.wait(scoped_lock, [&]() { return count_ > 0; });
--count_;
DCHECK(count_ >= 0);
}
void Release() {
{
std::lock_guard<std::mutex> scoped_lock(mutex_);
++count_;
}
cv_.notify_one();
}
private:
std::condition_variable cv_;
std::mutex mutex_;
int count_ = 0;
Semaphore(Semaphore const&) = delete;
Semaphore& operator=(Semaphore const&) = delete;
};
} // namespace base
#endif // BASE_SEMAPHORE_H

View File

@ -11,7 +11,7 @@
// <--------------------------------------------------------->
// r0_ (during first load)
//
// kKernelSize / 2 kKernelSize / 2 kKernelSize / 2 kKernelSize / 2
// kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 2 kernel_size_ / 2
// <---------------> <---------------> <---------------> <--------------->
// r1_ r2_ r3_ r4_
//
@ -22,8 +22,8 @@
// <------------------ ... ----------------->
// r0_ (during second load)
//
// On the second request r0_ slides to the right by kKernelSize / 2 and r3_, r4_
// and block_size_ are reinitialized via step (3) in the algorithm below.
// On the second request r0_ slides to the right by kernel_size_ / 2 and r3_,
// r4_ and block_size_ are reinitialized via step (3) in the algorithm below.
//
// These new regions remain constant until a Flush() occurs. While complicated,
// this allows us to reduce jitter by always requesting the same amount from the
@ -31,26 +31,27 @@
//
// The algorithm:
//
// 1) Allocate input_buffer of size: request_frames_ + kKernelSize; this ensures
// 1) Allocate input_buffer of size: request_frames_ + kernel_size_; this
// ensures
// there's enough room to read request_frames_ from the callback into region
// r0_ (which will move between the first and subsequent passes).
//
// 2) Let r1_, r2_ each represent half the kernel centered around r0_:
//
// r0_ = input_buffer_ + kKernelSize / 2
// r0_ = input_buffer_ + kernel_size_ / 2
// r1_ = input_buffer_
// r2_ = r0_
//
// r0_ is always request_frames_ in size. r1_, r2_ are kKernelSize / 2 in
// r0_ is always request_frames_ in size. r1_, r2_ are kernel_size_ / 2 in
// size. r1_ must be zero initialized to avoid convolution with garbage (see
// step (5) for why).
//
// 3) Let r3_, r4_ each represent half the kernel right aligned with the end of
// r0_ and choose block_size_ as the distance in frames between r4_ and r2_:
//
// r3_ = r0_ + request_frames_ - kKernelSize
// r4_ = r0_ + request_frames_ - kKernelSize / 2
// block_size_ = r4_ - r2_ = request_frames_ - kKernelSize / 2
// r3_ = r0_ + request_frames_ - kernel_size_
// r4_ = r0_ + request_frames_ - kernel_size_ / 2
// block_size_ = r4_ - r2_ = request_frames_ - kernel_size_ / 2
//
// 4) Consume request_frames_ frames into r0_.
//
@ -62,9 +63,9 @@
//
// 7) If we're on the second load, in order to avoid overwriting the frames we
// just wrapped from r4_ we need to slide r0_ to the right by the size of
// r4_, which is kKernelSize / 2:
// r4_, which is kernel_size_ / 2:
//
// r0_ = r0_ + kKernelSize / 2 = input_buffer_ + kKernelSize
// r0_ = r0_ + kernel_size_ / 2 = input_buffer_ + kernel_size_
//
// r3_, r4_, and block_size_ then need to be reinitialized, so goto (3).
//
@ -127,7 +128,9 @@ class ScopedSubnormalFloatDisabler {
#endif
};
double SincScaleFactor(double io_ratio) {
} // namespace
static double SincScaleFactor(double io_ratio, int kernel_size) {
// |sinc_scale_factor| is basically the normalized cutoff frequency of the
// low-pass filter.
double sinc_scale_factor = io_ratio > 1.0 ? 1.0 / io_ratio : 1.0;
@ -136,19 +139,17 @@ double SincScaleFactor(double io_ratio) {
// windowing it the transition from pass to stop does not happen right away.
// So we should adjust the low pass filter cutoff slightly downward to avoid
// some aliasing at the very high-end.
// TODO(crogers): this value is empirical and to be more exact should vary
// depending on kKernelSize.
sinc_scale_factor *= 0.9;
// Note: these values are derived empirically.
if (kernel_size == SincResampler::kMaxKernelSize) {
sinc_scale_factor *= 0.92;
} else {
DCHECK(kernel_size == SincResampler::kMinKernelSize);
sinc_scale_factor *= 0.90;
}
return sinc_scale_factor;
}
int CalculateChunkSize(int block_size_, double io_ratio) {
return block_size_ / io_ratio;
}
} // namespace
// If we know the minimum architecture at compile time, avoid CPU detection.
void SincResampler::InitializeCPUSpecificFeatures() {
#if defined(_M_ARM64) || defined(__aarch64__)
@ -170,26 +171,39 @@ void SincResampler::InitializeCPUSpecificFeatures() {
#endif
}
static int CalculateChunkSize(int block_size_, double io_ratio) {
return block_size_ / io_ratio;
}
// Static
int SincResampler::KernelSizeFromRequestFrames(int request_frames) {
// We want the kernel size to *more* than 1.5 * `request_frames`.
constexpr int kSmallKernelLimit = kMaxKernelSize * 3 / 2;
return request_frames <= kSmallKernelLimit ? kMinKernelSize : kMaxKernelSize;
}
SincResampler::SincResampler(double io_sample_rate_ratio, int request_frames)
: io_sample_rate_ratio_(io_sample_rate_ratio),
: kernel_size_(KernelSizeFromRequestFrames(request_frames)),
kernel_storage_size_(kernel_size_ * (kKernelOffsetCount + 1)),
io_sample_rate_ratio_(io_sample_rate_ratio),
request_frames_(request_frames),
input_buffer_size_(request_frames_ + kKernelSize),
input_buffer_size_(request_frames_ + kernel_size_),
// Create input buffers with a 32-byte alignment for SIMD optimizations.
kernel_storage_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
kernel_pre_sinc_storage_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
kernel_window_storage_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * kKernelStorageSize))),
base::AlignedAlloc<32>(sizeof(float) * kernel_storage_size_))),
input_buffer_(static_cast<float*>(
base::AlignedAlloc<32>(sizeof(float) * input_buffer_size_))),
r1_(input_buffer_.get()),
r2_(input_buffer_.get() + kKernelSize / 2) {
CHECK(request_frames > kKernelSize * 3 / 2)
r2_(input_buffer_.get() + kernel_size_ / 2) {
CHECK(request_frames > kernel_size_ * 3 / 2)
<< "request_frames must be greater than 1.5 kernels to allow sufficient "
"data for resampling";
// This means that after the first call to Flush we will have
// block_size_ > kKernelSize and r2_ < r3_.
// block_size_ > kernel_size_ and r2_ < r3_.
InitializeCPUSpecificFeatures();
DCHECK(convolve_proc_);
@ -197,11 +211,11 @@ SincResampler::SincResampler(double io_sample_rate_ratio, int request_frames)
Flush();
memset(kernel_storage_.get(), 0,
sizeof(*kernel_storage_.get()) * kKernelStorageSize);
sizeof(*kernel_storage_.get()) * kernel_storage_size_);
memset(kernel_pre_sinc_storage_.get(), 0,
sizeof(*kernel_pre_sinc_storage_.get()) * kKernelStorageSize);
sizeof(*kernel_pre_sinc_storage_.get()) * kernel_storage_size_);
memset(kernel_window_storage_.get(), 0,
sizeof(*kernel_window_storage_.get()) * kKernelStorageSize);
sizeof(*kernel_window_storage_.get()) * kernel_storage_size_);
InitializeKernel();
}
@ -210,10 +224,10 @@ SincResampler::~SincResampler() = default;
void SincResampler::UpdateRegions(bool second_load) {
// Setup various region pointers in the buffer (see diagram above). If we're
// on the second load we need to slide r0_ to the right by kKernelSize / 2.
r0_ = input_buffer_.get() + (second_load ? kKernelSize : kKernelSize / 2);
r3_ = r0_ + request_frames_ - kKernelSize;
r4_ = r0_ + request_frames_ - kKernelSize / 2;
// on the second load we need to slide r0_ to the right by kernel_size_ / 2.
r0_ = input_buffer_.get() + (second_load ? kernel_size_ : kernel_size_ / 2);
r3_ = r0_ + request_frames_ - kernel_size_;
r4_ = r0_ + request_frames_ - kernel_size_ / 2;
block_size_ = r4_ - r2_;
chunk_size_ = CalculateChunkSize(block_size_, io_sample_rate_ratio_);
@ -234,19 +248,20 @@ void SincResampler::InitializeKernel() {
// Generates a set of windowed sinc() kernels.
// We generate a range of sub-sample offsets from 0.0 to 1.0.
const double sinc_scale_factor = SincScaleFactor(io_sample_rate_ratio_);
const double sinc_scale_factor =
SincScaleFactor(io_sample_rate_ratio_, kernel_size_);
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
const float subsample_offset =
static_cast<float>(offset_idx) / kKernelOffsetCount;
for (int i = 0; i < kKernelSize; ++i) {
const int idx = i + offset_idx * kKernelSize;
for (int i = 0; i < kernel_size_; ++i) {
const int idx = i + offset_idx * kernel_size_;
const float pre_sinc =
base::kPiFloat * (i - kKernelSize / 2 - subsample_offset);
base::kPiFloat * (i - kernel_size_ / 2 - subsample_offset);
kernel_pre_sinc_storage_[idx] = pre_sinc;
// Compute Blackman window, matching the offset of the sinc().
const float x = (i - subsample_offset) / kKernelSize;
const float x = (i - subsample_offset) / kernel_size_;
const float window =
static_cast<float>(kA0 - kA1 * cos(2.0 * base::kPiDouble * x) +
kA2 * cos(4.0 * base::kPiDouble * x));
@ -272,10 +287,11 @@ void SincResampler::SetRatio(double io_sample_rate_ratio) {
// Optimize reinitialization by reusing values which are independent of
// |sinc_scale_factor|. Provides a 3x speedup.
const double sinc_scale_factor = SincScaleFactor(io_sample_rate_ratio_);
const double sinc_scale_factor =
SincScaleFactor(io_sample_rate_ratio_, kernel_size_);
for (int offset_idx = 0; offset_idx <= kKernelOffsetCount; ++offset_idx) {
for (int i = 0; i < kKernelSize; ++i) {
const int idx = i + offset_idx * kKernelSize;
for (int i = 0; i < kernel_size_; ++i) {
const int idx = i + offset_idx * kernel_size_;
const float window = kernel_window_storage_[idx];
const float pre_sinc = kernel_pre_sinc_storage_[idx];
@ -312,13 +328,13 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
// We'll compute "convolutions" for the two kernels which straddle
// |virtual_source_idx_|.
const float* k1 = kernel_storage_.get() + offset_idx * kKernelSize;
const float* k2 = k1 + kKernelSize;
const float* k1 = kernel_storage_.get() + offset_idx * kernel_size_;
const float* k2 = k1 + kernel_size_;
// Ensure |k1|, |k2| are 32-byte aligned for SIMD usage. Should always
// be true so long as kKernelSize is a multiple of 32.
DCHECK(0u == reinterpret_cast<uintptr_t>(k1) & 0x1F);
DCHECK(0u == reinterpret_cast<uintptr_t>(k2) & 0x1F);
DCHECK(0u == (reinterpret_cast<uintptr_t>(k1) & 0x1F));
DCHECK(0u == (reinterpret_cast<uintptr_t>(k2) & 0x1F));
// Initialize input pointer based on quantized |virtual_source_idx_|.
const float* input_ptr = r1_ + source_idx;
@ -326,15 +342,16 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
// Figure out how much to weight each kernel's "convolution".
const double kernel_interpolation_factor =
virtual_offset_idx - offset_idx;
*destination++ =
convolve_proc_(input_ptr, k1, k2, kernel_interpolation_factor);
*destination++ = convolve_proc_(kernel_size_, input_ptr, k1, k2,
kernel_interpolation_factor);
// Advance the virtual index.
virtual_source_idx_ += io_sample_rate_ratio_;
if (!--remaining_frames)
if (!--remaining_frames) {
return;
}
}
}
// Wrap back around to the start.
DCHECK(virtual_source_idx_ > block_size_);
@ -342,11 +359,12 @@ void SincResampler::Resample(int frames, float* destination, ReadCB read_cb) {
// Step (3) -- Copy r3_, r4_ to r1_, r2_.
// This wraps the last input frames back to the start of the buffer.
memcpy(r1_, r3_, sizeof(*input_buffer_.get()) * kKernelSize);
memcpy(r1_, r3_, sizeof(*input_buffer_.get()) * kernel_size_);
// Step (4) -- Reinitialize regions if necessary.
if (r0_ == r2_)
if (r0_ == r2_) {
UpdateRegions(true);
}
// Step (5) -- Refresh the buffer with more input.
read_cb(request_frames_, r0_);
@ -381,7 +399,12 @@ double SincResampler::BufferedFrames() const {
return buffer_primed_ ? request_frames_ - virtual_source_idx_ : 0;
}
float SincResampler::Convolve_C(const float* input_ptr,
int SincResampler::KernelSize() const {
return kernel_size_;
}
float SincResampler::Convolve_C(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor) {
@ -390,7 +413,7 @@ float SincResampler::Convolve_C(const float* input_ptr,
// Generate a single output sample. Unrolling this loop hurt performance in
// local testing.
int n = kKernelSize;
int n = kernel_size;
while (n--) {
sum1 += *input_ptr * *k1++;
sum2 += *input_ptr++ * *k2++;
@ -402,7 +425,8 @@ float SincResampler::Convolve_C(const float* input_ptr,
}
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
float SincResampler::Convolve_SSE(const float* input_ptr,
float SincResampler::Convolve_SSE(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor) {
@ -413,13 +437,13 @@ float SincResampler::Convolve_SSE(const float* input_ptr,
// Based on |input_ptr| alignment, we need to use loadu or load. Unrolling
// these loops hurt performance in local testing.
if (reinterpret_cast<uintptr_t>(input_ptr) & 0x0F) {
for (int i = 0; i < kKernelSize; i += 4) {
for (int i = 0; i < kernel_size; i += 4) {
m_input = _mm_loadu_ps(input_ptr + i);
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
}
} else {
for (int i = 0; i < kKernelSize; i += 4) {
for (int i = 0; i < kernel_size; i += 4) {
m_input = _mm_load_ps(input_ptr + i);
m_sums1 = _mm_add_ps(m_sums1, _mm_mul_ps(m_input, _mm_load_ps(k1 + i)));
m_sums2 = _mm_add_ps(m_sums2, _mm_mul_ps(m_input, _mm_load_ps(k2 + i)));
@ -444,6 +468,7 @@ float SincResampler::Convolve_SSE(const float* input_ptr,
}
__attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
@ -456,13 +481,13 @@ __attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
// these loops has not been tested or benchmarked.
bool aligned_input = (reinterpret_cast<uintptr_t>(input_ptr) & 0x1F) == 0;
if (!aligned_input) {
for (size_t i = 0; i < kKernelSize; i += 8) {
for (size_t i = 0; i < static_cast<size_t>(kernel_size); i += 8) {
m_input = _mm256_loadu_ps(input_ptr + i);
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
}
} else {
for (size_t i = 0; i < kKernelSize; i += 8) {
for (size_t i = 0; i < static_cast<size_t>(kernel_size); i += 8) {
m_input = _mm256_load_ps(input_ptr + i);
m_sums1 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k1 + i), m_sums1);
m_sums2 = _mm256_fmadd_ps(m_input, _mm256_load_ps(k2 + i), m_sums2);
@ -490,7 +515,8 @@ __attribute__((target("avx2,fma"))) float SincResampler::Convolve_AVX2(
return result;
}
#elif defined(_M_ARM64) || defined(__aarch64__)
float SincResampler::Convolve_NEON(const float* input_ptr,
float SincResampler::Convolve_NEON(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor) {
@ -498,7 +524,7 @@ float SincResampler::Convolve_NEON(const float* input_ptr,
float32x4_t m_sums1 = vmovq_n_f32(0);
float32x4_t m_sums2 = vmovq_n_f32(0);
const float* upper = input_ptr + kKernelSize;
const float* upper = input_ptr + kernel_size;
for (; input_ptr < upper;) {
m_input = vld1q_f32(input_ptr);
input_ptr += 4;

View File

@ -16,32 +16,40 @@ namespace base {
class SincResampler {
public:
// The kernel size can be adjusted for quality (higher is better) at the
// expense of performance. Must be a multiple of 32.
// TODO(dalecurtis): Test performance to see if we can jack this up to 64+.
static constexpr int kKernelSize = 32;
// expense of performance. Must be a multiple of 32. We aim for 64 for
// perceptible audio quality (see crbug.com/1407622), but fallback to 32 in
// cases where `request_frames_` is too small (e.g. 10ms of 8kHz audio).
// Use SincResampler::KernelSize() to check which size is being used.
static constexpr int kMaxKernelSize = 64;
static constexpr int kMinKernelSize = 32;
// Default request size. Affects how often and for how much SincResampler
// calls back for input. Must be greater than kKernelSize.
// calls back for input. Must be greater than 1.5 * `kernel_size_`.
static constexpr int kDefaultRequestSize = 512;
// A smaller request size, which still allows higher quality resampling, by
// guaranteeing we will use kMaxKernelSize.
static constexpr int kSmallRequestSize = kMaxKernelSize * 2;
// The kernel offset count is used for interpolation and is the number of
// sub-sample kernel shifts. Can be adjusted for quality (higher is better)
// at the expense of allocating more memory.
static constexpr int kKernelOffsetCount = 32;
static constexpr int kKernelStorageSize =
kKernelSize * (kKernelOffsetCount + 1);
// Callback type for providing more data into the resampler. Expects |frames|
// of data to be rendered into |destination|; zero padded if not enough frames
// are available to satisfy the request.
typedef std::function<void(int frames, float* destination)> ReadCB;
// Returns the kernel size which will be used for a given `request_frames`.
static int KernelSizeFromRequestFrames(int request_frames);
// Constructs a SincResampler with the specified |read_cb|, which is used to
// acquire audio data for resampling. |io_sample_rate_ratio| is the ratio
// of input / output sample rates. |request_frames| controls the size in
// frames of the buffer requested by each |read_cb| call. The value must be
// greater than 1.5*kKernelSize. Specify kDefaultRequestSize if there are no
// request size constraints.
// greater than 1.5*`kernel_size_`. Specify kDefaultRequestSize if there are
// no request size constraints.
SincResampler(double io_sample_rate_ratio, int request_frames);
SincResampler(const SincResampler&) = delete;
@ -52,10 +60,10 @@ class SincResampler {
// Resample |frames| of data from |read_cb_| into |destination|.
void Resample(int frames, float* destination, ReadCB read_cb);
// The maximum size in frames that guarantees Resample() will only make a
// single call to |read_cb_| for more data. Note: If PrimeWithSilence() is
// The maximum size in output frames that guarantees Resample() will only make
// a single call to |read_cb_| for more data. Note: If PrimeWithSilence() is
// not called, chunk size will grow after the first two Resample() calls by
// kKernelSize / (2 * io_sample_rate_ratio). See the .cc file for details.
// `kernel_size_` / (2 * io_sample_rate_ratio). See the .cc file for details.
int ChunkSize() const { return chunk_size_; }
// Returns the max number of frames that could be requested (via multiple
@ -77,13 +85,19 @@ class SincResampler {
// Resample() is in progress.
void SetRatio(double io_sample_rate_ratio);
float* get_kernel_for_testing() { return kernel_storage_.get(); }
// Return number of input frames consumed by a callback but not yet processed.
// Since input/output ratio can be fractional, so can this value.
// Zero before first call to Resample().
double BufferedFrames() const;
// Return the actual kernel size used by the resampler. Should be
// kMaxKernelSize most of the time, but varies based on `request_frames_`;
int KernelSize() const;
float* get_kernel_for_testing() { return kernel_storage_.get(); }
int kernel_storage_size_for_testing() { return kernel_storage_size_; }
private:
void InitializeKernel();
void UpdateRegions(bool second_load);
@ -92,21 +106,25 @@ class SincResampler {
// linearly interpolated using |kernel_interpolation_factor|. On x86, the
// underlying implementation is chosen at run time based on SSE support. On
// ARM, NEON support is chosen at compile time based on compilation flags.
static float Convolve_C(const float* input_ptr,
static float Convolve_C(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor);
#if defined(_M_X64) || defined(__x86_64__) || defined(__i386__)
static float Convolve_SSE(const float* input_ptr,
static float Convolve_SSE(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor);
static float Convolve_AVX2(const float* input_ptr,
static float Convolve_AVX2(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor);
#elif defined(_M_ARM64) || defined(__aarch64__)
static float Convolve_NEON(const float* input_ptr,
static float Convolve_NEON(const int kernel_size,
const float* input_ptr,
const float* k1,
const float* k2,
double kernel_interpolation_factor);
@ -116,6 +134,9 @@ class SincResampler {
// using SincResampler.
void InitializeCPUSpecificFeatures();
const int kernel_size_;
const int kernel_storage_size_;
// The ratio of input / output sample rates.
double io_sample_rate_ratio_;
@ -139,9 +160,9 @@ class SincResampler {
// The size (in samples) of the internal buffer used by the resampler.
const int input_buffer_size_;
// Contains kKernelOffsetCount kernels back-to-back, each of size kKernelSize.
// The kernel offsets are sub-sample shifts of a windowed sinc shifted from
// 0.0 to 1.0 sample.
// Contains kKernelOffsetCount kernels back-to-back, each of size
// `kernel_size_`. The kernel offsets are sub-sample shifts of a windowed sinc
// shifted from 0.0 to 1.0 sample.
AlignedMemPtr<float[]> kernel_storage_;
AlignedMemPtr<float[]> kernel_pre_sinc_storage_;
AlignedMemPtr<float[]> kernel_window_storage_;
@ -150,10 +171,8 @@ class SincResampler {
AlignedMemPtr<float[]> input_buffer_;
// Stores the runtime selection of which Convolve function to use.
using ConvolveProc = float (*)(const float*,
const float*,
const float*,
double);
using ConvolveProc =
float (*)(const int, const float*, const float*, const float*, double);
ConvolveProc convolve_proc_;
// Pointers to the various regions inside |input_buffer_|. See the diagram at

View File

@ -1,5 +1,7 @@
#include "base/task_runner.h"
#include <thread>
#include "base/log.h"
namespace {
@ -33,7 +35,7 @@ TaskRunner* TaskRunner::GetThreadLocalTaskRunner() {
void TaskRunner::PostTask(const Location& from, Closure task) {
DCHECK(task) << LOCATION(from);
task_count_.fetch_add(1, std::memory_order_relaxed);
task_count_.fetch_add(1, std::memory_order_release);
std::lock_guard<std::mutex> scoped_lock(lock_);
queue_.emplace_back(from, std::move(task));
}
@ -68,7 +70,7 @@ void TaskRunner::MultiConsumerRun() {
#endif
task_cb();
task_count_.fetch_sub(1, std::memory_order_relaxed);
task_count_.fetch_sub(1, std::memory_order_release);
}
}
@ -90,16 +92,13 @@ void TaskRunner::SingleConsumerRun() {
#endif
task_cb();
task_count_.fetch_sub(1, std::memory_order_relaxed);
task_count_.fetch_sub(1, std::memory_order_release);
}
cv_.notify_one();
}
void TaskRunner::WaitForCompletion() {
std::unique_lock<std::mutex> scoped_lock(lock_);
cv_.wait(scoped_lock, [&]() -> bool {
return task_count_.load(std::memory_order_relaxed) == 0;
});
while (task_count_.load(std::memory_order_acquire) > 0)
std::this_thread::yield();
}
} // namespace base

View File

@ -2,7 +2,6 @@
#define BASE_TASK_RUNNER_H
#include <atomic>
#include <condition_variable>
#include <deque>
#include <memory>
#include <mutex>
@ -74,7 +73,6 @@ class TaskRunner {
std::deque<Task> queue_;
mutable std::mutex lock_;
std::condition_variable cv_;
std::atomic<size_t> task_count_{0};
static thread_local std::unique_ptr<TaskRunner> thread_local_task_runner;

View File

@ -33,7 +33,7 @@ void ThreadPool::Shutdown() {
return;
quit_.store(true, std::memory_order_relaxed);
semaphore_.Release();
semaphore_.release(threads_.size());
for (auto& thread : threads_)
thread.join();
@ -44,7 +44,7 @@ void ThreadPool::PostTask(const Location& from, Closure task) {
DCHECK((!threads_.empty()));
task_runner_.PostTask(from, std::move(task));
semaphore_.Release();
semaphore_.release();
}
void ThreadPool::PostTaskAndReply(const Location& from,
@ -53,17 +53,15 @@ void ThreadPool::PostTaskAndReply(const Location& from,
DCHECK((!threads_.empty()));
task_runner_.PostTaskAndReply(from, std::move(task), std::move(reply));
semaphore_.Release();
semaphore_.release();
}
void ThreadPool::WorkerMain() {
for (;;) {
semaphore_.Acquire();
semaphore_.acquire();
if (quit_.load(std::memory_order_relaxed)) {
semaphore_.Release();
if (quit_.load(std::memory_order_relaxed))
return;
}
task_runner_.MultiConsumerRun();
}

View File

@ -2,11 +2,11 @@
#define BASE_THREAD_POOL_H
#include <atomic>
#include <semaphore>
#include <thread>
#include <vector>
#include "base/closure.h"
#include "base/semaphore.h"
#include "base/task_runner.h"
namespace base {
@ -36,13 +36,13 @@ class ThreadPool {
std::function<void(ReturnType)> reply) {
task_runner_.PostTaskAndReplyWithResult(from, std::move(task),
std::move(reply));
semaphore_.Release();
semaphore_.release();
}
private:
std::vector<std::thread> threads_;
Semaphore semaphore_;
std::counting_semaphore<> semaphore_{0};
std::atomic<bool> quit_{false};
base::TaskRunner task_runner_;

View File

@ -1,25 +0,0 @@
executable("demo") {
sources = [
"credits.cc",
"credits.h",
"damage_type.h",
"demo.cc",
"demo.h",
"enemy.cc",
"enemy.h",
"hud.cc",
"hud.h",
"menu.cc",
"menu.h",
"player.cc",
"player.h",
"sky_quad.cc",
"sky_quad.h",
]
deps = [
"//src/base",
"//src/engine",
"//src/third_party",
]
}

View File

@ -127,7 +127,7 @@ class Menu {
Button toggle_music_;
Button toggle_vibration_;
int high_score_value_ = 0;
size_t high_score_value_ = 0;
eng::ImageQuad high_score_;
eng::Animator high_score_animator_;

View File

@ -1,105 +0,0 @@
source_set("engine") {
sources =
[
"animatable.cc",
"animatable.h",
"animator.cc",
"animator.h",
"audio/audio_base.cc",
"audio/audio_base.h",
"audio/audio_forward.h",
"audio/audio.h",
"drawable.cc",
"drawable.h",
"engine.cc",
"engine.h",
"font.cc",
"font.h",
"game_factory.h",
"game.h",
"image_quad.cc",
"image_quad.h",
"image.cc",
"image.h",
"input_event.h",
"mesh.cc",
"mesh.h",
"persistent_data.cc",
"persistent_data.h",
"platform/asset_file.cc",
"platform/asset_file.h",
"platform/platform.cc",
"platform/platform.h",
"renderer/geometry.cc",
"renderer/geometry.h",
"renderer/opengl/opengl.h",
"renderer/opengl/render_command.cc",
"renderer/opengl/render_command.h",
"renderer/opengl/renderer_opengl.cc",
"renderer/opengl/renderer_opengl.h",
"renderer/render_resource.h",
"renderer/renderer_types.cc",
"renderer/renderer_types.h",
"renderer/renderer.h",
"renderer/shader.cc",
"renderer/shader.h",
"renderer/texture.cc",
"renderer/texture.h",
"renderer/vulkan/renderer_vulkan_linux.cc",
"renderer/vulkan/renderer_vulkan.cc",
"renderer/vulkan/vulkan_context_linux.cc",
"renderer/vulkan/vulkan_context.cc",
"shader_source.cc",
"shader_source.h",
"solid_quad.cc",
"solid_quad.h",
"sound_player.cc",
"sound_player.h",
"sound.cc",
"sound.h",
]
defines = [
"VK_USE_PLATFORM_XLIB_KHR",
"VULKAN_NON_CMAKE_BUILD",
"SYSCONFDIR=\"/etc\"",
"FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
"FALLBACK_CONFIG_DIRS=\"/etc/xdg\"",
"HAVE_SECURE_GETENV",
]
ldflags = [] libs = []
if (target_os == "linux") {
sources +=
[
"audio/audio_alsa.cc",
"audio/audio_alsa.h",
"platform/asset_file_linux.cc",
"platform/platform_linux.cc",
"platform/platform_linux.h",
"renderer/opengl/renderer_opengl_linux.cc",
]
#ldflags += ["-L/usr/X11R6/lib"]
libs += [ "X11", "GL", "asound", "pthread" ]
}
if (target_os == "android") {
sources += [
"audio/audio_oboe.cc",
"audio/audio_oboe.h",
"platform/asset_file_android.cc",
"platform/platform_android.cc",
"platform/platform_android.h",
"renderer/renderer_android.cc",
]
#ldflags += ["-L/usr/X11R6/lib"]
#libs += ["X11", "rt", "pthread"]
}
deps = []
}

View File

@ -1,4 +1,4 @@
#include "animator.h"
#include "engine/animator.h"
#include "base/interpolation.h"
#include "base/log.h"

View File

@ -206,7 +206,7 @@ class Engine {
PersistentData replay_data_;
bool recording_ = false;
bool replaying_ = false;
int replay_index_ = 0;
unsigned int replay_index_ = 0;
base::Randomf random_;

View File

@ -120,8 +120,8 @@ bool Image::CreateMip(const Image& other) {
} else {
const uint32_t* s = reinterpret_cast<const uint32_t*>(other.buffer_.get());
uint32_t* d = reinterpret_cast<uint32_t*>(buffer_.get());
for (size_t y = 0; y < height_; ++y) {
for (size_t x = 0; x < width_; ++x) {
for (int y = 0; y < height_; ++y) {
for (int x = 0; x < width_; ++x) {
*d++ = Mix4(s[0], s[1], s[other.width_], s[other.width_ + 1]);
s += 2;
}

View File

@ -107,7 +107,7 @@ float ImageQuad::GetFrameHeight() const {
}
// Return the uv offset for the given frame.
Vector2f ImageQuad::GetUVOffset(int frame) const {
Vector2f ImageQuad::GetUVOffset(size_t frame) const {
DCHECK(frame < GetNumFrames())
<< "asset: " << asset_name_ << " frame: " << frame;
return {(float)(frame % num_frames_[0]), (float)(frame / num_frames_[0])};

View File

@ -70,7 +70,7 @@ class ImageQuad : public Animatable {
float GetFrameWidth() const;
float GetFrameHeight() const;
base::Vector2f GetUVOffset(int frame) const;
base::Vector2f GetUVOffset(size_t frame) const;
};
} // namespace eng

View File

@ -106,7 +106,7 @@ bool Mesh::Load(const std::string& file_name) {
vertices_ = std::make_unique<char[]>(vertex_buffer_size);
char* dst = vertices_.get();
int i = 0;
unsigned int i = 0;
while (i < vertices.size()) {
for (auto& attr : vertex_description_) {
auto [attrib_type, data_type, num_elements, type_size] = attr;

View File

@ -11,11 +11,18 @@ import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdError;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;
import com.google.android.gms.ads.FullScreenContentCallback;
import com.google.android.gms.ads.LoadAdError;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.google.android.gms.ads.interstitial.InterstitialAd;
import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback;
import com.woom.game.R;
import java.io.File;
@ -35,7 +42,13 @@ public class KaliberActivity extends NativeActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInterstitialAd = newInterstitialAd();
MobileAds.initialize(this, new OnInitializationCompleteListener() {
@Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
Log.d("kaliber", "MobileAds initialization complete.");
}
});
loadInterstitialAd();
}
@ -52,44 +65,13 @@ public class KaliberActivity extends NativeActivity {
});
}
private InterstitialAd newInterstitialAd() {
InterstitialAd interstitialAd = new InterstitialAd(this);
interstitialAd.setAdUnitId(getString(R.string.interstitial_ad_unit_id));
interstitialAd.setAdListener(new AdListener() {
@Override
public void onAdLoaded() {
Log.w("kaliber", "Ad loaded.");
}
@Override
public void onAdFailedToLoad(int errorCode) {
Log.w("kaliber", "Ad failed to load. errorCode: " + errorCode);
sHandler.postDelayed(new Runnable() {
@Override
public void run() {
if (!mInterstitialAd.isLoaded())
loadInterstitialAd();
}
}, 1000 * 10);
}
@Override
public void onAdClosed() {
loadInterstitialAd();
onShowAdResult(true);
}
});
return interstitialAd;
}
public void showInterstitialAd() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
if (mInterstitialAd != null) {
mInterstitialAd.show(KaliberActivity.this);
} else {
loadInterstitialAd();
onShowAdResult(false);
}
}
@ -123,10 +105,49 @@ public class KaliberActivity extends NativeActivity {
}
private void loadInterstitialAd() {
if (!mInterstitialAd.isLoading()) {
AdRequest adRequest = new AdRequest.Builder()
.setRequestAgent("android_studio:ad_template").build();
mInterstitialAd.loadAd(adRequest);
}
AdRequest adRequest = new AdRequest.Builder().build();
InterstitialAd.load(this, getString(R.string.interstitial_ad_unit_id), adRequest,
new InterstitialAdLoadCallback() {
@Override
public void onAdLoaded(@NonNull InterstitialAd interstitialAd) {
Log.d("kaliber", "Ad loaded.");
mInterstitialAd = interstitialAd;
interstitialAd.setFullScreenContentCallback(
new FullScreenContentCallback() {
@Override
public void onAdDismissedFullScreenContent() {
Log.d("kaliber", "The ad was dismissed.");
mInterstitialAd = null;
loadInterstitialAd();
onShowAdResult(true);
}
@Override
public void onAdFailedToShowFullScreenContent(AdError adError) {
Log.d("kaliber", "The ad failed to show.");
mInterstitialAd = null;
loadInterstitialAd();
onShowAdResult(false);
}
@Override
public void onAdShowedFullScreenContent() {
Log.d("kaliber", "The ad was shown.");
}
});
}
@Override
public void onAdFailedToLoad(@NonNull LoadAdError loadAdError) {
Log.d("kaliber", "Ad failed to load. errorCode: " + loadAdError);
mInterstitialAd = null;
sHandler.postDelayed(new Runnable() {
@Override
public void run() {
loadInterstitialAd();
}
}, 1000 * 10);
}
});
}
}

View File

@ -184,7 +184,7 @@ void RendererOpenGL::SetUniform(uint64_t resource_id,
void RendererOpenGL::Present() {
EnqueueCommand(std::make_unique<CmdPresent>());
#ifdef THREADED_RENDERING
draw_complete_semaphore_.Acquire();
draw_complete_semaphore_.acquire();
#endif // THREADED_RENDERING
fps_++;
}

View File

@ -13,9 +13,8 @@
#include <deque>
#include <future>
#include <mutex>
#include <semaphore>
#include <thread>
#include "base/semaphore.h"
#endif // THREADED_RENDERING
#include "engine/renderer/opengl/opengl.h"
@ -147,7 +146,7 @@ class RendererOpenGL : public Renderer {
std::thread render_thread_;
bool terminate_render_thread_ = false;
base::Semaphore draw_complete_semaphore_;
std::counting_semaphore<> draw_complete_semaphore_{0};
base::TaskRunner* main_thread_task_runner_;
#endif // THREADED_RENDERING

View File

@ -58,7 +58,7 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) {
return;
}
#ifdef THREADED_RENDERING
draw_complete_semaphore_.Release();
draw_complete_semaphore_.release();
#endif // THREADED_RENDERING
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0;

View File

@ -55,7 +55,7 @@ void RendererOpenGL::HandleCmdPresent(RenderCommand* cmd) {
if (display_) {
glXSwapBuffers(display_, window_);
#ifdef THREADED_RENDERING
draw_complete_semaphore_.Release();
draw_complete_semaphore_.release();
#endif // THREADED_RENDERING
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
active_shader_id_ = 0;

View File

@ -295,7 +295,7 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr<Mesh> mesh) {
// Transfer mesh ownership to the background thread.
std::unique_ptr<Mesh> own(mesh);
});
semaphore_.Release();
semaphore_.release();
return last_resource_id_;
}
@ -387,7 +387,7 @@ void RendererVulkan::UpdateTexture(uint64_t resource_id,
// Transfer image ownership to the background thread.
std::unique_ptr<Image> own(image);
});
semaphore_.Release();
semaphore_.release();
}
void RendererVulkan::DestroyTexture(uint64_t resource_id) {
@ -619,7 +619,7 @@ void RendererVulkan::ActivateShader(uint64_t resource_id) {
vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline);
}
for (int i = 0; i < it->second.desc_set_count; ++i) {
for (size_t i = 0; i < it->second.desc_set_count; ++i) {
if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) {
active_descriptor_sets_[i] = penging_descriptor_sets_[i];
vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer,
@ -735,7 +735,7 @@ bool RendererVulkan::InitializeInternal() {
allocator_info.instance = context_.GetInstance();
vmaCreateAllocator(&allocator_info, &allocator_);
for (int i = 0; i < frames_.size(); i++) {
for (size_t i = 0; i < frames_.size(); i++) {
// Create command pool, one per frame is recommended.
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
@ -867,12 +867,12 @@ void RendererVulkan::Shutdown() {
DestroyAllResources();
quit_.store(true, std::memory_order_relaxed);
semaphore_.Release();
semaphore_.release();
setup_thread_.join();
vkDeviceWaitIdle(device_);
for (int i = 0; i < frames_.size(); ++i) {
for (size_t i = 0; i < frames_.size(); ++i) {
FreePendingResources(i);
vkDestroyCommandPool(device_, frames_[i].setup_command_pool, nullptr);
vkDestroyCommandPool(device_, frames_[i].draw_command_pool, nullptr);
@ -1081,7 +1081,7 @@ bool RendererVulkan::AllocateStagingBuffer(uint32_t amount,
FlushSetupBuffer();
// Clear the whole staging buffer.
for (int i = 0; i < staging_buffers_.size(); i++) {
for (size_t i = 0; i < staging_buffers_.size(); i++) {
staging_buffers_[i].frame_used = 0;
staging_buffers_[i].fill_amount = 0;
}
@ -1115,9 +1115,9 @@ bool RendererVulkan::AllocateStagingBuffer(uint32_t amount,
// executed.
vkDeviceWaitIdle(device_);
for (int i = 0; i < staging_buffers_.size(); i++) {
for (size_t i = 0; i < staging_buffers_.size(); i++) {
// Clear all blocks but the ones from this frame.
int block_idx =
size_t block_idx =
(i + current_staging_buffer_) % staging_buffers_.size();
if (staging_buffers_[block_idx].frame_used == frames_drawn_) {
break; // We reached something from this frame, abort.
@ -1621,7 +1621,7 @@ bool RendererVulkan::CreatePipelineLayout(
break;
}
for (int i = 0; i < binding_count; ++i) {
for (size_t i = 0; i < binding_count; ++i) {
const SpvReflectDescriptorBinding& binding = *bindings[i];
DLOG << __func__ << " name: " << binding.name
@ -1735,7 +1735,7 @@ bool RendererVulkan::CreatePipelineLayout(
// Use the same layout for all decriptor sets.
std::vector<VkDescriptorSetLayout> desc_set_layouts;
for (int i = 0; i < binding_count; ++i)
for (size_t i = 0; i < binding_count; ++i)
desc_set_layouts.push_back(descriptor_set_layout_);
VkPipelineLayoutCreateInfo pipeline_layout_create_info;
@ -1877,14 +1877,14 @@ void RendererVulkan::SetupThreadMain(int preallocate) {
}
for (;;) {
semaphore_.Acquire();
semaphore_.acquire();
if (quit_.load(std::memory_order_relaxed))
break;
task_runner_.SingleConsumerRun();
}
for (int i = 0; i < staging_buffers_.size(); i++) {
for (size_t i = 0; i < staging_buffers_.size(); i++) {
auto [buffer, allocation] = staging_buffers_[i].buffer;
vmaDestroyBuffer(allocator_, buffer, allocation);
}

View File

@ -3,6 +3,7 @@
#include <atomic>
#include <memory>
#include <semaphore>
#include <string>
#include <thread>
#include <tuple>
@ -11,7 +12,6 @@
#include "engine/renderer/vulkan/vulkan_context.h"
#include "base/semaphore.h"
#include "base/task_runner.h"
#include "engine/renderer/renderer.h"
#include "third_party/vma/vk_mem_alloc.h"
@ -113,7 +113,7 @@ class RendererVulkan : public Renderer {
std::unique_ptr<char[]> push_constants;
size_t push_constants_size = 0;
std::vector<std::string> sampler_uniform_names;
int desc_set_count = 0;
size_t desc_set_count = 0;
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
VkPipeline pipeline = VK_NULL_HANDLE;
};
@ -181,7 +181,7 @@ class RendererVulkan : public Renderer {
std::thread setup_thread_;
base::TaskRunner task_runner_;
base::Semaphore semaphore_;
std::counting_semaphore<> semaphore_{0};
std::atomic<bool> quit_{false};
bool InitializeInternal();

View File

@ -39,7 +39,7 @@ std::array<std::unique_ptr<T[]>, 2> Deinterleave(size_t num_channels,
// Deinterleave into separate channels.
channels[0] = std::make_unique<T[]>(num_samples);
channels[1] = std::make_unique<T[]>(num_samples);
for (int i = 0, j = 0; i < num_samples * 2; i += 2) {
for (size_t i = 0, j = 0; i < num_samples * 2; i += 2) {
channels[0].get()[j] = static_cast<T>(input_buffer[i]);
channels[1].get()[j++] = static_cast<T>(input_buffer[i + 1]);
}
@ -230,7 +230,7 @@ void Sound::Preprocess(std::unique_ptr<float[]> input_buffer,
} else {
size_t num_resampled_samples = resampler_[0]->ChunkSize();
DCHECK(num_resampled_samples ==
(int)(((float)hw_sample_rate_ / (float)sample_rate_) *
(size_t)(((float)hw_sample_rate_ / (float)sample_rate_) *
samples_per_channel));
if (!back_buffer_[0]) {
@ -243,7 +243,7 @@ void Sound::Preprocess(std::unique_ptr<float[]> input_buffer,
num_samples_back_ = num_resampled_samples;
// Resample to match the system sample rate.
for (int i = 0; i < num_channels_; ++i) {
for (size_t i = 0; i < num_channels_; ++i) {
resampler_[i]->Resample(num_resampled_samples, back_buffer_[i].get(),
[&](int frames, float* destination) {
memcpy(destination, channels[i].get(),

View File

@ -1,225 +0,0 @@
source_set("third_party") {
sources = [
"jsoncpp/json.h",
"jsoncpp/jsoncpp.cpp",
"minimp3/minimp3_ex.h",
"minimp3/minimp3.h",
"stb/stb_image.h",
"stb/stb_truetype.h",
"texture_compressor/dxt_encoder_implementation_autogen.h",
"texture_compressor/dxt_encoder_internals.cc",
"texture_compressor/dxt_encoder_internals.h",
"texture_compressor/dxt_encoder.cc",
"texture_compressor/dxt_encoder.h",
"texture_compressor/texture_compressor_etc1.cc",
"texture_compressor/texture_compressor_etc1.h",
"texture_compressor/texture_compressor.cc",
"texture_compressor/texture_compressor.h",
"glslang/glslang/CInterface/glslang_c_interface.cpp",
"glslang/glslang/GenericCodeGen/CodeGen.cpp",
"glslang/glslang/GenericCodeGen/Link.cpp",
"glslang/glslang/MachineIndependent/attribute.cpp",
"glslang/glslang/MachineIndependent/Constant.cpp",
"glslang/glslang/MachineIndependent/glslang_tab.cpp",
"glslang/glslang/MachineIndependent/InfoSink.cpp",
"glslang/glslang/MachineIndependent/Initialize.cpp",
"glslang/glslang/MachineIndependent/Intermediate.cpp",
"glslang/glslang/MachineIndependent/intermOut.cpp",
"glslang/glslang/MachineIndependent/IntermTraverse.cpp",
"glslang/glslang/MachineIndependent/iomapper.cpp",
"glslang/glslang/MachineIndependent/limits.cpp",
"glslang/glslang/MachineIndependent/linkValidate.cpp",
"glslang/glslang/MachineIndependent/parseConst.cpp",
"glslang/glslang/MachineIndependent/ParseContextBase.cpp",
"glslang/glslang/MachineIndependent/ParseHelper.cpp",
"glslang/glslang/MachineIndependent/PoolAlloc.cpp",
"glslang/glslang/MachineIndependent/preprocessor/Pp.cpp",
"glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp",
"glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp",
"glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp",
"glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp",
"glslang/glslang/MachineIndependent/propagateNoContraction.cpp",
"glslang/glslang/MachineIndependent/reflection.cpp",
"glslang/glslang/MachineIndependent/RemoveTree.cpp",
"glslang/glslang/MachineIndependent/Scan.cpp",
"glslang/glslang/MachineIndependent/ShaderLang.cpp",
"glslang/glslang/MachineIndependent/SymbolTable.cpp",
"glslang/glslang/MachineIndependent/Versions.cpp",
"glslang/glslang/OSDependent/Unix/ossource.cpp",
"glslang/OGLCompilersDLL/InitializeDll.cpp",
"glslang/SPIRV/CInterface/spirv_c_interface.cpp",
"glslang/SPIRV/disassemble.cpp",
"glslang/SPIRV/doc.cpp",
"glslang/SPIRV/GlslangToSpv.cpp",
"glslang/SPIRV/InReadableOrder.cpp",
"glslang/SPIRV/Logger.cpp",
"glslang/SPIRV/SpvBuilder.cpp",
"glslang/SPIRV/SpvPostProcess.cpp",
"glslang/SPIRV/SPVRemapper.cpp",
"glslang/SPIRV/SpvTools.cpp",
"glslang/StandAlone/ResourceLimits.cpp",
"spirv-reflect/spirv_reflect.c",
"vma/vk_mem_alloc.cpp",
]
defines = [
"VK_USE_PLATFORM_XLIB_KHR",
"VULKAN_NON_CMAKE_BUILD",
"SYSCONFDIR=\"/etc\"",
"FALLBACK_DATA_DIRS=\"/usr/local/share:/usr/share\"",
"FALLBACK_CONFIG_DIRS=\"/etc/xdg\"",
"HAVE_SECURE_GETENV",
]
# ldflags = []
# libs = []
if (target_os == "linux") {
sources += [
"glew/glew.c",
"glew/glew.h",
"glew/glxew.h",
"vulkan/loader/cJSON.c",
"vulkan/loader/debug_utils.c",
"vulkan/loader/dev_ext_trampoline.c",
"vulkan/loader/extension_manual.c",
"vulkan/loader/loader.c",
"vulkan/loader/murmurhash.c",
"vulkan/loader/phys_dev_ext.c",
"vulkan/loader/trampoline.c",
"vulkan/loader/unknown_ext_chain.c",
"vulkan/loader/wsi.c",
]
# ldflags += [ "-L/usr/X11R6/lib" ]
libs = [ "dl" ]
}
if (target_os == "android") {
sources += [
"android/gl3stub.c",
"android/gl3stub.h",
"android/GLContext.cpp",
"android/GLContext.h",
"minizip/ioapi.c",
"minizip/ioapi.h",
"minizip/unzip.c",
"minizip/unzip.h",
"oboe/include/oboe/AudioStream.h",
"oboe/include/oboe/AudioStreamBase.h",
"oboe/include/oboe/AudioStreamBuilder.h",
"oboe/include/oboe/AudioStreamCallback.h",
"oboe/include/oboe/Definitions.h",
"oboe/include/oboe/LatencyTuner.h",
"oboe/include/oboe/Oboe.h",
"oboe/include/oboe/ResultWithValue.h",
"oboe/include/oboe/StabilizedCallback.h",
"oboe/include/oboe/Utilities.h",
"oboe/include/oboe/Version.h",
"oboe/src/aaudio/AAudioLoader.cpp",
"oboe/src/aaudio/AAudioLoader.h",
"oboe/src/aaudio/AudioStreamAAudio.cpp",
"oboe/src/aaudio/AudioStreamAAudio.h",
"oboe/src/common/AudioClock.h",
"oboe/src/common/AudioSourceCaller.cpp",
"oboe/src/common/AudioSourceCaller.h",
"oboe/src/common/AudioStream.cpp",
"oboe/src/common/AudioStreamBuilder.cpp",
"oboe/src/common/DataConversionFlowGraph.cpp",
"oboe/src/common/DataConversionFlowGraph.h",
"oboe/src/common/FilterAudioStream.cpp",
"oboe/src/common/FilterAudioStream.h",
"oboe/src/common/FixedBlockAdapter.cpp",
"oboe/src/common/FixedBlockAdapter.h",
"oboe/src/common/FixedBlockReader.cpp",
"oboe/src/common/FixedBlockReader.h",
"oboe/src/common/FixedBlockWriter.cpp",
"oboe/src/common/FixedBlockWriter.h",
"oboe/src/common/LatencyTuner.cpp",
"oboe/src/common/MonotonicCounter.h",
"oboe/src/common/OboeDebug.h",
"oboe/src/common/QuirksManager.cpp",
"oboe/src/common/QuirksManager.h",
"oboe/src/common/SourceFloatCaller.cpp",
"oboe/src/common/SourceFloatCaller.h",
"oboe/src/common/SourceI16Caller.cpp",
"oboe/src/common/SourceI16Caller.h",
"oboe/src/common/StabilizedCallback.cpp",
"oboe/src/common/Trace.cpp",
"oboe/src/common/Trace.h",
"oboe/src/common/Utilities.cpp",
"oboe/src/common/Version.cpp",
"oboe/src/fifo/FifoBuffer.cpp",
"oboe/src/fifo/FifoBuffer.h",
"oboe/src/fifo/FifoController.cpp",
"oboe/src/fifo/FifoController.h",
"oboe/src/fifo/FifoControllerBase.cpp",
"oboe/src/fifo/FifoControllerBase.h",
"oboe/src/fifo/FifoControllerIndirect.cpp",
"oboe/src/fifo/FifoControllerIndirect.h",
"oboe/src/flowgraph/ClipToRange.cpp",
"oboe/src/flowgraph/ClipToRange.h",
"oboe/src/flowgraph/FlowGraphNode.cpp",
"oboe/src/flowgraph/FlowGraphNode.h",
"oboe/src/flowgraph/ManyToMultiConverter.cpp",
"oboe/src/flowgraph/ManyToMultiConverter.h",
"oboe/src/flowgraph/MonoToMultiConverter.cpp",
"oboe/src/flowgraph/MonoToMultiConverter.h",
"oboe/src/flowgraph/RampLinear.cpp",
"oboe/src/flowgraph/RampLinear.h",
"oboe/src/flowgraph/resampler/HyperbolicCosineWindow.h",
"oboe/src/flowgraph/resampler/IntegerRatio.cpp",
"oboe/src/flowgraph/resampler/IntegerRatio.h",
"oboe/src/flowgraph/resampler/KaiserWindow.h",
"oboe/src/flowgraph/resampler/LinearResampler.cpp",
"oboe/src/flowgraph/resampler/LinearResampler.h",
"oboe/src/flowgraph/resampler/MultiChannelResampler.cpp",
"oboe/src/flowgraph/resampler/MultiChannelResampler.h",
"oboe/src/flowgraph/resampler/PolyphaseResampler.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResampler.h",
"oboe/src/flowgraph/resampler/PolyphaseResamplerMono.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResamplerMono.h",
"oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.cpp",
"oboe/src/flowgraph/resampler/PolyphaseResamplerStereo.h",
"oboe/src/flowgraph/resampler/SincResampler.cpp",
"oboe/src/flowgraph/resampler/SincResampler.h",
"oboe/src/flowgraph/resampler/SincResamplerStereo.cpp",
"oboe/src/flowgraph/resampler/SincResamplerStereo.h",
"oboe/src/flowgraph/SampleRateConverter.cpp",
"oboe/src/flowgraph/SampleRateConverter.h",
"oboe/src/flowgraph/SinkFloat.cpp",
"oboe/src/flowgraph/SinkFloat.h",
"oboe/src/flowgraph/SinkI16.cpp",
"oboe/src/flowgraph/SinkI16.h",
"oboe/src/flowgraph/SinkI24.cpp",
"oboe/src/flowgraph/SinkI24.h",
"oboe/src/flowgraph/SourceFloat.cpp",
"oboe/src/flowgraph/SourceFloat.h",
"oboe/src/flowgraph/SourceI16.cpp",
"oboe/src/flowgraph/SourceI16.h",
"oboe/src/flowgraph/SourceI24.cpp",
"oboe/src/flowgraph/SourceI24.h",
"oboe/src/opensles/AudioInputStreamOpenSLES.cpp",
"oboe/src/opensles/AudioInputStreamOpenSLES.h",
"oboe/src/opensles/AudioOutputStreamOpenSLES.cpp",
"oboe/src/opensles/AudioOutputStreamOpenSLES.h",
"oboe/src/opensles/AudioStreamBuffered.cpp",
"oboe/src/opensles/AudioStreamBuffered.h",
"oboe/src/opensles/AudioStreamOpenSLES.cpp",
"oboe/src/opensles/AudioStreamOpenSLES.h",
"oboe/src/opensles/EngineOpenSLES.cpp",
"oboe/src/opensles/EngineOpenSLES.h",
"oboe/src/opensles/OpenSLESUtilities.cpp",
"oboe/src/opensles/OpenSLESUtilities.h",
"oboe/src/opensles/OutputMixerOpenSLES.cpp",
"oboe/src/opensles/OutputMixerOpenSLES.h",
"texture_compressor/dxt_encoder_neon.cc",
"texture_compressor/dxt_encoder_neon.h",
"texture_compressor/texture_compressor_etc1_neon.cc",
"texture_compressor/texture_compressor_etc1_neon.h",
]
}
deps = []
}

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <assert.h>
#include <math.h>
#include "IntegerRatio.h"
#include "PolyphaseResampler.h"

View File

@ -16,6 +16,8 @@
#include "PolyphaseResamplerMono.h"
#include <assert.h>
using namespace resampler;
#define MONO 1

View File

@ -16,6 +16,8 @@
#include "PolyphaseResamplerStereo.h"
#include <assert.h>
using namespace resampler;
#define STEREO 2

View File

@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <assert.h>
#include <math.h>
#include "SincResampler.h"

View File

@ -18,6 +18,8 @@
#include "SincResamplerStereo.h"
#include <assert.h>
using namespace resampler;
#define STEREO 2

4673
src/third_party/stb/stb_image.c vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff