diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..46f94bab --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,79 @@ +name: build + +on: + push: + pull_request: + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 20.04 + os: ubuntu-20.04 + install_dir: ~/rubberband + cmake_extras: -DCMAKE_BUILD_TYPE=RelWithDebInfo + - name: macOS 10.15 + os: macos-10.15 + install_dir: ~/rubberband + cmake_extras: -DCMAKE_BUILD_TYPE=RelWithDebInfo + - name: Windows 2019 + os: windows-2019 + install_dir: C:\rubberband + cmake_extras: >- + -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake + -DCMAKE_PREFIX_PATH=C:\vcpkg\installed\x64-windows-static + cmake_config: --config RelWithDebInfo + ctest_config: --build-config RelWithDebInfo + + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + steps: + - name: Check out Git repository + uses: actions/checkout@v2 + - name: "[Ubuntu] Install dependencies" + if: startsWith(matrix.os, 'ubuntu') + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends fftw3-dev libsamplerate-dev + - name: "[macOS] Install dependencies" + if: startsWith(matrix.os, 'macos') + run: brew install fftw libsamplerate + - name: "[Windows] Set up vcpkg cache" + uses: actions/cache@v2 + if: runner.os == 'Windows' + with: + path: C:\Users\runneradmin\AppData\Local\vcpkg\archives + key: vcpkg-${{ github.head_ref }}-${{ github.run_number }} + restore-keys: | + vcpkg-${{ github.head_ref }} + vcpkg + - name: "[Windows] Install dependencies" + if: startsWith(matrix.os, 'windows') + run: vcpkg install fftw3 libsamplerate + env: + VCPKG_DEFAULT_TRIPLET: x64-windows-static + - name: Configure + run: cmake + -DCMAKE_INSTALL_PREFIX=${{ matrix.install_dir }} + ${{ matrix.cmake_extras }} + -DUSE_FFTW=ON + -DUSE_LIBSAMPLERATE=ON + -S . -B build + - name: Build + run: cmake --build build ${{ matrix.cmake_config }} + env: + CMAKE_BUILD_PARALLEL_LEVEL: 2 + - name: Install + run: cmake --install build ${{ matrix.cmake_config }} + - name: Run Tests + run: ctest ${{ matrix.ctest_config }} --output-on-failure + working-directory: build + env: + CTEST_PARALLEL_LEVEL: 2 + - name: Upload Build Artifact + uses: actions/upload-artifact@v2 + with: + name: ${{ matrix.name }} rubberband build + path: ${{ matrix.install_dir }} diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..675aae22 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,196 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) +project(rubberband VERSION 2.1.1) + +option(BUILD_EXECUTABLE "Build the Rubberband executable" OFF) +option(BUILD_JNI "Build the Java Native Interface (JNI)" OFF) +option(OPTIMIZE "Build Rubberband optimized for the build machine's CPU" OFF) +option(USE_FFTW "Use FFTW instead of KISS FFT" OFF) +option(USE_LIBSAMPLERATE "Use libsamplerate instead of Speex" ON) + +add_library(rubberband + src/RubberBandStretcher.cpp + src/StretchCalculator.cpp + src/StretcherChannelData.cpp + src/StretcherImpl.cpp + src/StretcherProcess.cpp + src/audiocurves/CompoundAudioCurve.cpp + src/audiocurves/ConstantAudioCurve.cpp + src/audiocurves/HighFrequencyAudioCurve.cpp + src/audiocurves/PercussiveAudioCurve.cpp + src/audiocurves/SilentAudioCurve.cpp + src/audiocurves/SpectralDifferenceAudioCurve.cpp + src/base/Profiler.cpp + src/dsp/AudioCurveCalculator.cpp + src/dsp/FFT.cpp + src/dsp/Resampler.cpp + src/rubberband-c.cpp + src/system/Allocators.cpp + src/system/Thread.cpp + src/system/VectorOpsComplex.cpp + src/system/sysutils.cpp +) + +if(BUILD_JNI) + add_library(rubberband-jni src/jni/RubberBandStretcherJNI.cpp) + target_include_directories(rubberband-jni PRIVATE src) + + find_package(JNI REQUIRED) + target_include_directories(rubberband-jni PRIVATE ${JNI_INCLUDE_DIRS}) + target_link_libraries(rubberband-jni PRIVATE ${JNI_LIBRARIES}) +endif() + + +# +# Dependencies +# + +# Threads +find_package(Threads REQUIRED) +target_link_libraries(rubberband PRIVATE Threads::Threads) + +# FFTW / KissFFT +if(USE_FFTW) + message(STATUS "Using FFT library: fftw") + find_path(FFTW3_INCLUDEDIR fftw3.h REQUIRED) + find_library(FFTW3_LIBRARY fftw fftw3 fftw-3.3 REQUIRED) + target_include_directories(rubberband PRIVATE ${FFTW3_INCLUDEDIR}) + target_link_libraries(rubberband PUBLIC ${FFTW3_LIBRARY}) + target_compile_definitions(rubberband PRIVATE HAVE_FFTW3 FFTW_DOUBLE_ONLY) +else() + message(STATUS "Using resampling library: kissfft") + target_compile_definitions(rubberband PRIVATE USE_KISSFFT) + target_sources(rubberband PRIVATE src/kissfft/kiss_fft.c src/kissfft/kiss_fftr.c) +endif() + +# libsamplerate / Speex +if(USE_LIBSAMPLERATE) + message(STATUS "Using resampling library: libsamplerate") + find_path(SAMPLERATE_INCLUDEDIR samplerate.h REQUIRED) + find_library(SAMPLERATE_LIBRARY samplerate samplerate-0 libsamplerate libsamplerate-0 REQUIRED) + target_include_directories(rubberband PRIVATE ${SAMPLERATE_INCLUDEDIR}) + target_link_libraries(rubberband PUBLIC ${SAMPLERATE_LIBRARY}) + target_compile_definitions(rubberband PRIVATE HAVE_LIBSAMPLERATE) +else() + message(STATUS "Using resampling library: speex") + target_compile_definitions(rubberband PRIVATE USE_SPEEX) + target_sources(rubberband PRIVATE src/speex/resample.c) +endif() + +# +# Handle general flags, include paths, etc. +# +include(CheckCXXCompilerFlag) + +if(OPTIMIZE) + check_cxx_compiler_flag("-march=native" MARCH_NATIVE_SUPPORTED) + if(MARCH_NATIVE_SUPPORTED AND NOT MSVC) + target_compile_options(rubberband PRIVATE -march=native) + endif() +endif() + +include(GNUInstallDirs) +target_include_directories(rubberband + PUBLIC + $ + $ + PRIVATE + $ + $ +) + +target_compile_definitions(rubberband + PRIVATE + $<$:USE_PTHREADS> + MALLOC_IS_ALIGNED + NO_THREAD_CHECKS + NO_TIMING +) + +if(APPLE) + if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_LESS 10.11) + message(FATAL_ERROR "macOS deployment target must be >= 10.11") + endif() + target_compile_definitions(rubberband PRIVATE HAVE_VDSP) + + find_library(ACCELERATE_FRAMEWORK NAMES Accelerate REQUIRED) + target_link_libraries(rubberband PUBLIC ${ACCELERATE_FRAMEWORK}) +elseif(WIN32) + target_compile_definitions(rubberband PRIVATE _WINDOWS) + if(CMAKE_SIZEOF_VOID_P EQUAL 4) + target_compile_definitions(rubberband PRIVATE WIN32) + endif() + + if(MSVC) + target_compile_definitions(rubberband PRIVATE + __MSVC__ + _LIB + NOMINMAX + _USE_MATH_DEFINES + $<$:NDEBUG> + $<$:_DEBUG NO_TIMING NO_THREAD_CHECKS> + ) + set_target_properties(rubberband PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) + endif() +endif() + +# +# Command-Line Program +# +if(BUILD_EXECUTABLE) + find_library(SNDFILE_LIBRARY sndfile REQUIRED) + add_executable(rubberband-program main/main.cpp) + target_include_directories(rubberband-program PRIVATE src Threads::Threads) + target_link_libraries(rubberband-program PRIVATE rubberband ${SNDFILE_LIBRARY}) +endif() + +# +# Installation +# +install( + TARGETS rubberband + EXPORT rubberband-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +# Header files +install( + DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/rubberband" + TYPE INCLUDE +) + +# pkg-config file +if(UNIX) + set(PREFIX "${CMAKE_INSTALL_PREFIX}") + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/rubberband.pc.in" "${CMAKE_CURRENT_BINARY_DIR}/rubberband.pc" @ONLY) + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/rubberband.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + ) +endif() + +# CMake config +include(CMakePackageConfigHelpers) +set(RUBBERBAND_INSTALL_CMAKEDIR "lib/cmake/rubberband") +install( + EXPORT rubberband-targets + FILE rubberband-targets.cmake + NAMESPACE rubberband:: + DESTINATION "${RUBBERBAND_INSTALL_CMAKEDIR}" +) +configure_package_config_file(rubberband-config.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/rubberband-config.cmake" + INSTALL_DESTINATION "${RUBBERBAND_INSTALL_CMAKEDIR}" +) +write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/rubberband-config-version.cmake" + VERSION "${CMAKE_PROJECT_VERSION}" + COMPATIBILITY SameMajorVersion +) +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/rubberband-config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/rubberband-config-version.cmake" + DESTINATION "${RUBBERBAND_INSTALL_CMAKEDIR}" +) diff --git a/Makefile.in b/Makefile.in index 78a7bae3..20c6ba91 100644 --- a/Makefile.in +++ b/Makefile.in @@ -195,7 +195,7 @@ install: all ln -s $(LIBNAME)$(DYNAMIC_EXTENSION).$(DYNAMIC_FULL_VERSION) $(DESTDIR)$(INSTALL_LIBDIR)/$(LIBNAME)$(DYNAMIC_EXTENSION).$(DYNAMIC_ABI_VERSION) ln -s $(LIBNAME)$(DYNAMIC_EXTENSION).$(DYNAMIC_FULL_VERSION) $(DESTDIR)$(INSTALL_LIBDIR)/$(LIBNAME)$(DYNAMIC_EXTENSION) test -f $(JNI_TARGET) && cp -fp $(JNI_TARGET) $(DESTDIR)$(INSTALL_LIBDIR)/$(JNINAME)$(DYNAMIC_EXTENSION) || true - sed "s,%PREFIX%,$(PREFIX)," rubberband.pc.in \ + sed "s,@PREFIX@,$(PREFIX)," rubberband.pc.in \ > $(DESTDIR)$(INSTALL_PKGDIR)/rubberband.pc ifeq ($(WITH_PROGRAMS), yes) $(MKDIR) -p $(DESTDIR)$(INSTALL_BINDIR) diff --git a/Makefile.macos b/Makefile.macos index 02795744..1a587063 100644 --- a/Makefile.macos +++ b/Makefile.macos @@ -177,7 +177,7 @@ install: default cp $(LADSPA_TARGET) $(DESTDIR)$(INSTALL_LADSPADIR) cp ladspa/ladspa-rubberband.cat $(DESTDIR)$(INSTALL_LADSPADIR) cp ladspa/ladspa-rubberband.rdf $(DESTDIR)$(INSTALL_LRDFDIR) - sed "s,%PREFIX%,$(PREFIX)," rubberband.pc.in \ + sed "s,@PREFIX@,$(PREFIX)," rubberband.pc.in \ > $(DESTDIR)$(INSTALL_PKGDIR)/rubberband.pc clean: diff --git a/Makefile.macos-universal b/Makefile.macos-universal index 719fc028..cff91b67 100644 --- a/Makefile.macos-universal +++ b/Makefile.macos-universal @@ -177,7 +177,7 @@ install: default cp $(LADSPA_TARGET) $(DESTDIR)$(INSTALL_LADSPADIR) cp ladspa/ladspa-rubberband.cat $(DESTDIR)$(INSTALL_LADSPADIR) cp ladspa/ladspa-rubberband.rdf $(DESTDIR)$(INSTALL_LRDFDIR) - sed "s,%PREFIX%,$(PREFIX)," rubberband.pc.in \ + sed "s,@PREFIX@,$(PREFIX)," rubberband.pc.in \ > $(DESTDIR)$(INSTALL_PKGDIR)/rubberband.pc clean: diff --git a/rubberband-config.cmake.in b/rubberband-config.cmake.in new file mode 100644 index 00000000..6bb96c23 --- /dev/null +++ b/rubberband-config.cmake.in @@ -0,0 +1,15 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +if(@USE_FFTW@) + find_dependency(FFTW3) +endif() + +if(@USE_LIBSAMPLERATE@) + find_dependency(samplerate) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/rubberband-targets.cmake") + +check_required_components(rubberband) diff --git a/rubberband.pc.in b/rubberband.pc.in index ac96edd2..89da225b 100644 --- a/rubberband.pc.in +++ b/rubberband.pc.in @@ -1,4 +1,4 @@ -prefix=%PREFIX% +prefix=@PREFIX@ exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include