diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml index 7549f0582..faea9310c 100644 --- a/.github/workflows/compilation.yml +++ b/.github/workflows/compilation.yml @@ -45,7 +45,7 @@ jobs: run: | sudo apt-get update sudo apt-get -y install cmake cmake-data libargtable2-dev libcunit1-dev \ - libopenal-dev libconfuse-dev libenet-dev libsdl2-dev libxmp-dev libpng-dev \ + libsdl2-mixer-dev libconfuse-dev libenet-dev libsdl2-dev libxmp-dev libpng-dev \ clang-tidy ${{ matrix.config.cc }} - name: Build tests @@ -76,7 +76,7 @@ jobs: - name: Install Ubuntu Dependencies run: | sudo apt-get update - sudo apt-get -y install cmake libargtable2-dev libcunit1-dev libopenal-dev \ + sudo apt-get -y install cmake libargtable2-dev libcunit1-dev libsdl2-mixer-dev \ libconfuse-dev libenet-dev libsdl2-dev libxmp-dev libpng-dev - name: Generate Release @@ -107,7 +107,7 @@ jobs: maintainer: ${{ github.repository_owner }} version: 0.6.6-${{ steps.slug.outputs.sha8 }} arch: 'amd64' - depends: 'libargtable2, libopenal, libconfuse, libenet, libsdl2, libxmp, libpng' + depends: 'libargtable2, libsdl2-mixer, libconfuse, libenet, libsdl2, libxmp, libpng' desc: 'One Must Fall 2097 Remake' - name: Upload DEB artifact @@ -121,8 +121,8 @@ jobs: build_macos: needs: [unittest, formatting-check] - name: Build macos-11 - runs-on: macos-11 + name: Build macos-12 + runs-on: macos-12 steps: - uses: actions/checkout@v3 @@ -130,7 +130,7 @@ jobs: - name: Install Mac Dependencies run: | brew update - brew install cmake argtable cunit openal-soft confuse enet sdl2 libxmp libpng + brew install cmake argtable cunit sdl2_mixer confuse enet sdl2 libxmp libpng - name: Generate Release run: | @@ -146,13 +146,13 @@ jobs: - name: Generate ZIP package run: | cd build-release/release - zip -r ${GITHUB_WORKSPACE}/openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos11.zip . + zip -r ${GITHUB_WORKSPACE}/openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos12.zip . - name: Upload artifacts uses: actions/upload-artifact@v3 with: - name: openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos11 - path: openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos11.zip + name: openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos12 + path: openomf_0.6.6-${{ steps.slug.outputs.sha8 }}_macos12.zip # Build windows package, release artifact and update "latest" release if necessary. # ----------------------------------------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index ba359162f..409011d8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,10 +13,6 @@ set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") # Options OPTION(USE_TESTS "Build unittests" OFF) OPTION(USE_TOOLS "Build tools" OFF) -OPTION(USE_OGGVORBIS "Add support for Ogg Vorbis audio" OFF) -OPTION(USE_DUMB "Use libdumb for module playback" OFF) -OPTION(USE_XMP "Use libxmp for module playback" ON) -OPTION(USE_OPENAL "Support OpenAL for audio playback" ON) OPTION(USE_SANITIZERS "Enable Asan and Ubsan" OFF) OPTION(USE_TIDY "Use clang-tidy for checks" OFF) OPTION(USE_FORMAT "Use clang-format for checks" OFF) @@ -46,6 +42,8 @@ endif() # System packages (hard dependencies) find_package(SDL2 REQUIRED) +find_package(SDL2_mixer REQUIRED) +find_package(xmp) find_package(enet) find_package(confuse) find_package(argtable2) @@ -56,29 +54,6 @@ find_package(ZLIB) check_symbol_exists(strdup "string.h" HAVE_STD_STRDUP) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/platform.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/platform.h) -# If USE_DUMB flag is on, turn on libdumb -if(USE_DUMB) - find_package(dumb) - add_definitions(-DUSE_DUMB) - if(MINGW) - add_definitions(-D_FILE_OFFSET_BITS=64) - endif() -endif() - -# If XMP has been selected, attempt to find it -if(USE_XMP) - find_package(xmp) - add_definitions(-DUSE_XMP) -endif() - -# Audio sink selection -if(USE_OPENAL) - find_package(OpenAL) - add_definitions(-DUSE_OPENAL) -else() - message(STATUS "Note! No audio sink selected; Music/sounds will not play.") -endif() - # When building with MingW, do not look for Intl if(MINGW) set(LIBINTL_INCLUDE_DIR "") @@ -87,13 +62,6 @@ else() find_package(Intl) endif() -# If we want to build support for vorbis streaming, find these too -if(USE_OGGVORBIS) - find_package(ogg) - find_package(vorbis) - add_definitions(-DUSE_OGGVORBIS) -endif() - # If tests are enabled, find CUnit if(USE_TESTS) find_package(CUnit) @@ -112,8 +80,10 @@ set(COREINCS src ${CMAKE_CURRENT_BINARY_DIR}/src/ ${SDL2_INCLUDE_DIRS} + ${SDL2_MIXER_INCLUDE_DIRS} ${CONFUSE_INCLUDE_DIR} ${Intl_INCLUDE_DIR} + ${XMP_INCLUDE_DIR} ${ENET_INCLUDE_DIR} ${ARGTABLE2_INCLUDE_DIR} ${PNG_INCLUDE_DIR} @@ -121,37 +91,15 @@ set(COREINCS ) set(CORELIBS - ${SDL2_LIBRARIES} ${CONFUSE_LIBRARY} ${Intl_LIBRARIES} + ${XMP_LIBRARY} ${ENET_LIBRARY} ${ARGTABLE2_LIBRARY} ${PNG_LIBRARY} ${ZLIB_LIBRARY} ) -# Handle module playback libraries -if(USE_DUMB) - set(CORELIBS ${CORELIBS} ${DUMB_LIBRARY}) - set(COREINCS ${COREINCS} ${DUMB_INCLUDE_DIR}) -endif() -if(USE_XMP) - set(CORELIBS ${CORELIBS} ${XMP_LIBRARY}) - set(COREINCS ${COREINCS} ${XMP_INCLUDE_DIR}) -endif() - -# Audio sinks -if(USE_OPENAL) - set(CORELIBS ${CORELIBS} ${OPENAL_LIBRARY}) - set(COREINCS ${COREINCS} ${OPENAL_INCLUDE_DIR}) -endif() - -# If we support ogg vorbis, add library includes etc. -if(USE_OGGVORBIS) - set(COREINCS ${COREINCS} ${OGG_INCLUDE_DIR} ${VORBIS_INCLUDE_DIR}) - set(CORELIBS ${CORELIBS} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY}) -endif() - # MingW build should add mingw32 lib if(MINGW) set(CORELIBS mingw32 ${CORELIBS}) @@ -290,8 +238,9 @@ endif() # Make sure libraries are linked target_link_libraries(openomf ${CORELIBS}) +target_link_libraries(openomf SDL2::Main SDL2::Mixer) foreach(TARGET ${TOOL_TARGET_NAMES}) - target_link_libraries(${TARGET} ${CORELIBS}) + target_link_libraries(${TARGET} ${CORELIBS} SDL2::Main SDL2::Mixer) endforeach() # Testing stuff @@ -309,7 +258,7 @@ if(CUNIT_FOUND) target_compile_definitions(openomf_test_main PRIVATE TESTS_ROOT_DIR="${CMAKE_SOURCE_DIR}/testing") - target_link_libraries(openomf_test_main ${CORELIBS}) + target_link_libraries(openomf_test_main ${CORELIBS} SDL2::Main SDL2::Mixer) if(MINGW) # Always build as a console executable with mingw diff --git a/INSTALL.md b/INSTALL.md index c2923ce41..06379c606 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -47,27 +47,20 @@ Required: * Gettext (if you have problems with libintl) * Enet: http://enet.bespin.org/ * libargtable2: http://argtable.sourceforge.net/ -* libpng: http://www.libpng.org/pub/png/libpng.html (for .PNG screenshots) +* libpng: http://www.libpng.org/pub/png/libpng.html * zlib: http://www.zlib.net/ (for libpng) - -Recommended: -* OpenAL: http://kcat.strangesoft.net/openal.html (for audio) -* libxmp: https://github.com/cmatsuoka/libxmp (for module music) - -Optional: -* libvorbis: https://www.xiph.org/downloads/ -* libogg: https://www.xiph.org/downloads/ -* libdumb (>=2.0.0): https://bitbucket.org/kode54/dumb (for module music) +* SDL2_Mixer (>=2.0.4): https://github.com/libsdl-org/SDL_mixer +* libxmp: https://github.com/cmatsuoka/libxmp On debian, it is possible to pull some libraries using apt-get. ``` -apt-get install libsdl2-dev libopenal-dev libpng-dev libconfuse-dev libenet-dev libargtable2-dev libxmp-dev +apt-get install libsdl2-dev libsdl2-mixer-dev libpng-dev libconfuse-dev libenet-dev libargtable2-dev libxmp-dev ``` On Mac, you can use brew: ``` -brew install argtable openal-soft confuse enet sdl2 libxmp libpng +brew install argtable sdl2_mixer confuse enet sdl2 libxmp libpng ``` ### Acquiring the sources @@ -100,26 +93,12 @@ Some useful CMake flags: |----------------------|-----------------------------------------|-----------------|---------| | CMAKE_BUILD_TYPE | Chooses between build types | -/Debug/Release | - | | CMAKE_INSTALL_PREFIX | Installation path | - | - | -| USE_OGGVORBIS | Selects Vorbis support | On/Off | Off | -| USE_OPENAL | Selects OpenAL support | On/Off | On | -| USE_DUMB | Selects libdumb support | On/Off | Off | -| USE_XMP | Selects libxmp support | On/Off | On | | USE_TESTS | Enables unittests (dev only!) | On/Off | Off | | USE_TOOLS | Enables format editor tools (dev only!) | On/Off | Off | | USE_SANITIZERS | Enables asan and ubsan (dev only!) | On/Off | Off | | USE_FORMAT | Enables clang-format (dev only!) | On/Off | Off | | USE_TIDY | Enables clang-tidy (dev only!) | On/Off | Off | -Ogg Vorbis support is required if you wish to replace original OMF soundtracks with OGG files. -Otherwise, the switch is optional. - -For music playback, select at least one (or more) of the module player libraries. -XMP is recommended due to ease of installation, but DUMB will also work just fine. - -It is technically possible to select more than one audio sink, or none. Currently, only one -audio sink is supported (OpenAL). If all audio sinks are off, then no audio will be played. -This will also of course reduce cpu usage a bit. - Note that when USE_FORMAT is selected, you can run command "make clangformat" to run code formatter to the entire codebase. diff --git a/cmake-scripts/FindSDL2_mixer.cmake b/cmake-scripts/FindSDL2_mixer.cmake new file mode 100644 index 000000000..d562f2efc --- /dev/null +++ b/cmake-scripts/FindSDL2_mixer.cmake @@ -0,0 +1,220 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Copyright 2019 Amine Ben Hassouna +# Copyright 2000-2019 Kitware, Inc. and Contributors +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: + +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# * Neither the name of Kitware, Inc. nor the names of Contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#[=======================================================================[.rst: +FindSDL2_mixer +-------------- + +Locate SDL2_mixer library + +This module defines the following 'IMPORTED' target: + +:: + + SDL2::Mixer + The SDL2_mixer library, if found. + Have SDL2::Core as a link dependency. + + + +This module will set the following variables in your project: + +:: + + SDL2_MIXER_LIBRARIES, the name of the library to link against + SDL2_MIXER_INCLUDE_DIRS, where to find the headers + SDL2_MIXER_FOUND, if false, do not try to link against + SDL2_MIXER_VERSION_STRING - human-readable string containing the + version of SDL2_mixer + +This module responds to the following cache variables: + +:: + + SDL2_MIXER_PATH + Set a custom SDL2_mixer Library path (default: empty) + + SDL2_MIXER_NO_DEFAULT_PATH + Disable search SDL2_mixer Library in default path. + If SDL2_MIXER_PATH (default: ON) + Else (default: OFF) + + SDL2_MIXER_INCLUDE_DIR + SDL2_mixer headers path. + + SDL2_MIXER_LIBRARY + SDL2_mixer Library (.dll, .so, .a, etc) path. + + +Additional Note: If you see an empty SDL2_MIXER_LIBRARY in your project +configuration, it means CMake did not find your SDL2_mixer library +(SDL2_mixer.dll, libsdl2_mixer.so, etc). Set SDL2_MIXER_LIBRARY to point +to your SDL2_mixer library, and configure again. This value is used to +generate the final SDL2_MIXER_LIBRARIES variable and the SDL2::Mixer target, +but when this value is unset, SDL2_MIXER_LIBRARIES and SDL2::Mixer does not +get created. + + +$SDL2MIXERDIR is an environment variable that would correspond to the +./configure --prefix=$SDL2MIXERDIR used in building SDL2_mixer. + +$SDL2DIR is an environment variable that would correspond to the +./configure --prefix=$SDL2DIR used in building SDL2. + + + +Created by Amine Ben Hassouna: + Adapt FindSDL_mixer.cmake to SDL2_mixer (FindSDL2_mixer.cmake). + Add cache variables for more flexibility: + SDL2_MIXER_PATH, SDL2_MIXER_NO_DEFAULT_PATH (for details, see doc above). + Add SDL2 as a required dependency. + Modernize the FindSDL2_mixer.cmake module by creating a specific target: + SDL2::Mixer (for details, see doc above). + +Original FindSDL_mixer.cmake module: + Created by Eric Wing. This was influenced by the FindSDL.cmake + module, but with modifications to recognize OS X frameworks and + additional Unix paths (FreeBSD, etc). +#]=======================================================================] + +# SDL2 Library required +find_package(SDL2 QUIET) +if (NOT SDL2_FOUND) + set(SDL2_MIXER_SDL2_NOT_FOUND "Could NOT find SDL2 (SDL2 is required by SDL2_mixer).") + if (SDL2_mixer_FIND_REQUIRED) + message(FATAL_ERROR ${SDL2_MIXER_SDL2_NOT_FOUND}) + else () + if (NOT SDL2_mixer_FIND_QUIETLY) + message(STATUS ${SDL2_MIXER_SDL2_NOT_FOUND}) + endif () + return() + endif () + unset(SDL2_MIXER_SDL2_NOT_FOUND) +endif () + + +# Define options for searching SDL2_mixer Library in a custom path + +set(SDL2_MIXER_PATH "" CACHE STRING "Custom SDL2_mixer Library path") + +set(_SDL2_MIXER_NO_DEFAULT_PATH OFF) +if (SDL2_MIXER_PATH) + set(_SDL2_MIXER_NO_DEFAULT_PATH ON) +endif () + +set(SDL2_MIXER_NO_DEFAULT_PATH ${_SDL2_MIXER_NO_DEFAULT_PATH} + CACHE BOOL "Disable search SDL2_mixer Library in default path") +unset(_SDL2_MIXER_NO_DEFAULT_PATH) + +set(SDL2_MIXER_NO_DEFAULT_PATH_CMD) +if (SDL2_MIXER_NO_DEFAULT_PATH) + set(SDL2_MIXER_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH) +endif () + +# Search for the SDL2_mixer include directory +find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h + HINTS + ENV SDL2MIXERDIR + ENV SDL2DIR + ${SDL2_MIXER_NO_DEFAULT_PATH_CMD} + PATH_SUFFIXES SDL2 + # path suffixes to search inside ENV{SDL2DIR} + # and ENV{SDL2MIXERDIR} + include/SDL2 include + PATHS ${SDL2_MIXER_PATH} + DOC "Where the SDL2_mixer headers can be found" +) + +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(VC_LIB_PATH_SUFFIX lib/x64) +else () + set(VC_LIB_PATH_SUFFIX lib/x86) +endif () + +# Search for the SDL2_mixer library +find_library(SDL2_MIXER_LIBRARY + NAMES SDL2_mixer + HINTS + ENV SDL2MIXERDIR + ENV SDL2DIR + ${SDL2_MIXER_NO_DEFAULT_PATH_CMD} + PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX} + PATHS ${SDL2_MIXER_PATH} + DOC "Where the SDL2_mixer Library can be found" +) + +# Read SDL2_mixer version +if (SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h") + file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$") + file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$") + string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}") + string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}") + set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH}) + unset(SDL2_MIXER_VERSION_MAJOR_LINE) + unset(SDL2_MIXER_VERSION_MINOR_LINE) + unset(SDL2_MIXER_VERSION_PATCH_LINE) + unset(SDL2_MIXER_VERSION_MAJOR) + unset(SDL2_MIXER_VERSION_MINOR) + unset(SDL2_MIXER_VERSION_PATCH) +endif () + +set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY}) +set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR}) + +include(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer + REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS + VERSION_VAR SDL2_MIXER_VERSION_STRING) + + +mark_as_advanced(SDL2_MIXER_PATH + SDL2_MIXER_NO_DEFAULT_PATH + SDL2_MIXER_LIBRARY + SDL2_MIXER_INCLUDE_DIR) + + +if (SDL2_MIXER_FOUND) + + # SDL2::Mixer target + if (SDL2_MIXER_LIBRARY AND NOT TARGET SDL2::Mixer) + add_library(SDL2::Mixer UNKNOWN IMPORTED) + set_target_properties(SDL2::Mixer PROPERTIES + IMPORTED_LOCATION "${SDL2_MIXER_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${SDL2_MIXER_INCLUDE_DIR}" + INTERFACE_LINK_LIBRARIES SDL2::Core) + endif () +endif () diff --git a/cmake-scripts/Finddumb.cmake b/cmake-scripts/Finddumb.cmake deleted file mode 100644 index 73c8269ec..000000000 --- a/cmake-scripts/Finddumb.cmake +++ /dev/null @@ -1,28 +0,0 @@ - -SET(DUMB_SEARCH_PATHS - /usr/local/ - /usr - /opt -) - -FIND_PATH(DUMB_INCLUDE_DIR dumb.h - HINTS ${DUMB_ROOT} - PATH_SUFFIXES include include/dumb - PATHS ${DUMB_SEARCH_PATHS} -) -FIND_LIBRARY(DUMB_LIBRARY dumb - HINTS ${DUMB_ROOT} - PATH_SUFFIXES lib64 lib - PATHS ${DUMB_SEARCH_PATHS} -) - -IF(DUMB_INCLUDE_DIR AND DUMB_LIBRARY) - SET(DUMB_FOUND TRUE) -ENDIF (DUMB_INCLUDE_DIR AND DUMB_LIBRARY) - - -IF(DUMB_FOUND) - MESSAGE(STATUS "Found Dumb: ${DUMB_LIBRARY}") -ELSE(DUMB_FOUND) - MESSAGE(WARNING "Could not find Dumb") -ENDIF(DUMB_FOUND) diff --git a/cmake-scripts/Findogg.cmake b/cmake-scripts/Findogg.cmake deleted file mode 100644 index e60008def..000000000 --- a/cmake-scripts/Findogg.cmake +++ /dev/null @@ -1,28 +0,0 @@ - -SET(OGG_SEARCH_PATHS - /usr/local/ - /usr - /opt -) - -FIND_PATH(OGG_INCLUDE_DIR ogg/ogg.h - HINTS ${OGG_ROOT} - PATH_SUFFIXES include - PATHS ${OGG_SEARCH_PATHS} -) -FIND_LIBRARY(OGG_LIBRARY ogg - HINTS ${OGG_ROOT} - PATH_SUFFIXES lib64 lib bin - PATHS ${OGG_SEARCH_PATHS} -) - -IF(OGG_INCLUDE_DIR AND OGG_LIBRARY) - SET(OGG_FOUND TRUE) -ENDIF (OGG_INCLUDE_DIR AND OGG_LIBRARY) - - -IF(OGG_FOUND) - MESSAGE(STATUS "Found Ogg: ${OGG_LIBRARY}") -ELSE(OGG_FOUND) - MESSAGE(WARNING "Could not find Ogg") -ENDIF(OGG_FOUND) diff --git a/cmake-scripts/Findvorbis.cmake b/cmake-scripts/Findvorbis.cmake deleted file mode 100644 index 0e84df0f3..000000000 --- a/cmake-scripts/Findvorbis.cmake +++ /dev/null @@ -1,34 +0,0 @@ - -SET(VORBIS_SEARCH_PATHS - /usr/local/ - /usr - /opt -) - -FIND_PATH(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h - HINTS ${VORBIS_ROOT} - PATH_SUFFIXES include - PATHS ${VORBIS_SEARCH_PATHS} -) -FIND_LIBRARY(VORBIS_LIBRARY vorbis - HINTS ${VORBIS_ROOT} - PATH_SUFFIXES lib64 lib bin - PATHS ${VORBIS_SEARCH_PATHS} -) -FIND_LIBRARY(VORBISFILE_LIBRARY vorbisfile - HINTS ${VORBIS_ROOT} - PATH_SUFFIXES lib64 lib bin - PATHS ${VORBIS_SEARCH_PATHS} -) - -IF(VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY) - SET(VORBIS_FOUND TRUE) -ENDIF (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY) - - -IF(VORBIS_FOUND) - MESSAGE(STATUS "Found Vorbis: ${VORBIS_LIBRARY}") - MESSAGE(STATUS "Found Vorbisfile: ${VORBISFILE_LIBRARY}") -ELSE(VORBIS_FOUND) - MESSAGE(WARNING "Could not find Vorbis") -ENDIF(VORBIS_FOUND) diff --git a/packaging/debian/CMakeLists.txt b/packaging/debian/CMakeLists.txt index 4a9071fa3..e48ca76a4 100644 --- a/packaging/debian/CMakeLists.txt +++ b/packaging/debian/CMakeLists.txt @@ -7,7 +7,7 @@ SET(CPACK_PACKAGING_INSTALL_PREFIX "/tmp") SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") SET(CPACK_DEBIAN_PACKAGE_SECTION "extra") SET(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) -SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libsdl2-2.0-0 (>= 2.0.3), libopenal1, libconfuse0, libenet7, libpng16-16, libxmp4") +SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libsdl2-2.0-0 (>= 2.0.3), libsdl2-mixer-2.0-0, libconfuse0, libenet7, libpng16-16, libxmp4") SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tuomas Virtanen ") SET(CPACK_DEB_COMPONENT_INSTALL 1) diff --git a/src/audio/audio.c b/src/audio/audio.c index 403d8029b..795d2ea49 100644 --- a/src/audio/audio.c +++ b/src/audio/audio.c @@ -1,94 +1,324 @@ +#include +#include + +#include +#include +#include + #include "audio/audio.h" -#include "audio/sink.h" -#include "audio/sinks/openal_sink.h" +#include "resources/pathmanager.h" +#include "resources/sounds_loader.h" #include "utils/allocator.h" #include "utils/log.h" -#include -#include +#include "utils/miscmath.h" -typedef struct { - int (*sink_init_fn)(audio_sink *sink); - const char *name; -} sink_info; +#define CHANNEL_MAX 8 -static audio_sink *_global_sink = NULL; +const audio_freq output_freqs[] = { + {11025, 0, "11025Hz"}, + {22050, 0, "22050Hz"}, + {44100, 0, "44100Hz"}, + {48000, 1, "48000Hz"}, + {0, 0, 0 } // Guard +}; -const sink_info sinks[] = { -#ifdef USE_OPENAL - {openal_sink_init, "openal"}, -#endif // USE_OPENAL +const audio_mod_resampler music_resamplers[] = { + {XMP_INTERP_NEAREST, 0, "Nearest"}, + {XMP_INTERP_LINEAR, 1, "Linear" }, + {XMP_INTERP_SPLINE, 0, "Cubic" }, + {0, 0, 0 } // Guard }; -#define SINK_COUNT (sizeof(sinks) / sizeof(sink_info)) -const char *audio_get_first_sink_name() { - if(SINK_COUNT > 0) { - return sinks[0].name; +typedef struct audio_system { + int freq; + Uint16 format; + int channels; + int resampler; + float music_volume; + resource_id music_id; + xmp_context xmp_context; + Mix_Chunk *channel_chunks[CHANNEL_MAX]; +} audio_system; + +static audio_system *audio = NULL; + +static const char *get_sdl_audio_format_string(SDL_AudioFormat format) { + switch(format) { + case AUDIO_U8: + return "AUDIO_U8"; + case AUDIO_S8: + return "AUDIO_S8"; + case AUDIO_U16LSB: + return "AUDIO_U16LSB"; + case AUDIO_S16LSB: + return "AUDIO_S16LSB"; + case AUDIO_U16MSB: + return "AUDIO_U16MSB"; + case AUDIO_S16MSB: + return "AUDIO_S16MSB"; + case AUDIO_S32LSB: + return "AUDIO_S32LSB"; + case AUDIO_S32MSB: + return "AUDIO_S32MSB"; + case AUDIO_F32LSB: + return "AUDIO_F32LSB"; + case AUDIO_F32MSB: + return "AUDIO_F32MSB"; } - return NULL; + return "UNKNOWN"; } -int audio_is_sink_available(const char *sink_name) { - for(unsigned i = 0; i < SINK_COUNT; i++) { - if(strcmp(sink_name, sinks[i].name) == 0) { - return 1; - } +static Mix_Chunk *audio_get_chunk(int id, float volume, float pitch) { + char *src_buf; + int src_len; + Uint8 *dst_buf; + SDL_AudioCVT cvt; + + // Load sample (8000Hz, mono, 8bit) + if(sounds_loader_get(id, &src_buf, &src_len) != 0) { + PERROR("Requested sound sample %d not found", id); + return NULL; + } + if(src_len == 0) { + DEBUG("Requested sound sample %d has nothing to play", id); + return NULL; + } + + // Converter for sound samples. + int src_freq = 8000 * pitch; + if(SDL_BuildAudioCVT(&cvt, AUDIO_U8, 1, src_freq, audio->format, audio->channels, audio->freq) < 0) { + PERROR("Unable to build audio converter: %s", SDL_GetError()); + return NULL; + } + + // Create a buffer that can hold the source data and final converted data. + if((dst_buf = SDL_malloc(src_len * cvt.len_mult + 1)) == NULL) { + PERROR("Unable to allocate memory for sound buffer"); + return NULL; } - return 0; + SDL_memcpy((void *)dst_buf, (void *)src_buf, src_len); + + // Convert! + cvt.buf = dst_buf; + cvt.len = src_len; + if(SDL_ConvertAudio(&cvt) != 0) { + PERROR("Unable to convert audio sample: %s", SDL_GetError()); + return NULL; + } + + Mix_Chunk *chunk = SDL_malloc(sizeof(Mix_Chunk)); + chunk->volume = volume * MIX_MAX_VOLUME; + chunk->abuf = dst_buf; + chunk->alen = cvt.len_cvt; + chunk->allocated = 1; + return chunk; } -void audio_render() { - if(_global_sink != NULL) { - sink_render(_global_sink); +static void audio_sound_finished(int channel) { + assert(audio); + if(audio->channel_chunks[channel] != NULL) { + Mix_FreeChunk(audio->channel_chunks[channel]); + audio->channel_chunks[channel] = NULL; } } -int audio_init(const char *sink_name) { - sink_info si; - memset(&si, 0, sizeof(sink_info)); +static bool audio_load_module(const char *file) { + assert(audio); - // If null sink given, disable audio - if(sink_name == NULL || strlen(sink_name) <= 0) { - INFO("Audio sink NOT initialized; audio not available."); - return 0; + // Load the module file + if(xmp_load_module(audio->xmp_context, (char *)file) < 0) { + PERROR("Unable to open module file"); + goto exit_0; } - // Find requested sink - for(unsigned c = 0; c < SINK_COUNT; ++c) { - if(strcmp(sink_name, sinks[c].name) == 0) { - si = sinks[c]; - break; - } + // Show some information + struct xmp_module_info mi; + xmp_get_module_info(audio->xmp_context, &mi); + DEBUG("Loaded music track %s (%s)", mi.mod->name, mi.mod->type); + + // Start the player + int flags = 0; + if(audio->channels == 1) + flags |= XMP_FORMAT_MONO; + if(xmp_start_player(audio->xmp_context, audio->freq, flags) != 0) { + PERROR("Unable to start module playback"); + goto exit_1; + } + if(xmp_set_player(audio->xmp_context, XMP_PLAYER_INTERP, audio->resampler) != 0) { + PERROR("Unable to set music resampler"); + goto exit_2; + } + if(xmp_set_player(audio->xmp_context, XMP_PLAYER_VOLUME, audio->music_volume * 100) != 0) { + PERROR("Unable to set music volume"); + goto exit_2; + } + return true; + +exit_2: + xmp_end_player(audio->xmp_context); +exit_1: + xmp_release_module(audio->xmp_context); +exit_0: + return false; +} + +// Callback function for SDL_Mixer +void audio_xmp_render(void *userdata, Uint8 *stream, int len) { + assert(audio); + xmp_play_buffer(audio->xmp_context, stream, len, 0); +} + +static void audio_close_module() { + if(is_music(audio->music_id)) { + xmp_end_player(audio->xmp_context); + xmp_release_module(audio->xmp_context); + audio->music_id = NUMBER_OF_RESOURCES; } - if(si.name == NULL) { - PERROR("Requested audio sink was not found!"); - return 1; +} + +bool audio_init(int freq, bool mono, int resampler, float music_volume, float sound_volume) { + if(!(audio = omf_calloc(1, sizeof(audio_system)))) { + PERROR("Unable to allocate audio subsystem"); + goto error_0; + } + if(SDL_InitSubSystem(SDL_INIT_AUDIO) != 0) { + PERROR("Unable to initialize audio subsystem: %s", SDL_GetError()); + goto error_1; + } + if(Mix_Init(0) != 0) { + PERROR("Unable to initialize mixer subsystem: %s", Mix_GetError()); + goto error_2; + } + if((audio->xmp_context = xmp_create_context()) == NULL) { + PERROR("Unable to initialize XMP context."); + goto error_3; } - // Inform user - INFO("Using audio sink '%s'.", si.name); + INFO("Requested audio device with options:"); + INFO(" * Rate: %dHz", freq); + INFO(" * Channels: %d", mono ? 1 : 2); + INFO(" * Format: %s", get_sdl_audio_format_string(AUDIO_S16SYS)); - // Init sink - _global_sink = omf_calloc(1, sizeof(audio_sink)); - sink_init(_global_sink); - if(si.sink_init_fn(_global_sink) != 0) { - omf_free(_global_sink); - return 1; + // Setup audio. We request for configuration, but we're not sure what we get. + if(Mix_OpenAudio(freq, AUDIO_S16SYS, mono ? 1 : 2, 2048) != 0) { + PERROR("Unable to initialize audio device: %s", SDL_GetError()); + goto error_4; } - // Success - INFO("Audio system initialized."); - return 0; + // Initialize playback parameters. + audio_set_sound_volume(sound_volume); + audio_set_music_volume(music_volume); + audio->resampler = resampler; + audio->music_id = NUMBER_OF_RESOURCES; + + Mix_ChannelFinished(audio_sound_finished); + + // Get the actual device configuration we got. + Mix_QuerySpec(&audio->freq, &audio->format, &audio->channels); + INFO("Opened audio device:"); + INFO(" * Rate: %dHz", audio->freq); + INFO(" * Channels: %d", audio->channels); + INFO(" * Format: %s", get_sdl_audio_format_string(audio->format)); + return true; + +error_4: + xmp_free_context(audio->xmp_context); +error_3: + Mix_Quit(); +error_2: + SDL_QuitSubSystem(SDL_INIT_AUDIO); +error_1: + omf_free(audio); +error_0: + audio = NULL; + return false; } void audio_close() { - if(_global_sink != NULL) { - sink_free(_global_sink); - omf_free(_global_sink); - _global_sink = NULL; - INFO("Audio system closed."); + if(audio != NULL) { + audio_close_module(); + if(audio->xmp_context) { + xmp_free_context(audio->xmp_context); + audio->xmp_context = NULL; + } + Mix_ChannelFinished(NULL); + Mix_CloseAudio(); + for(int i = 0; i < CHANNEL_MAX; i++) { + if(audio->channel_chunks[i] != NULL) { + Mix_FreeChunk(audio->channel_chunks[i]); + audio->channel_chunks[i] = NULL; + } + } + omf_free(audio); + audio = NULL; } + Mix_Quit(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); } -audio_sink *audio_get_sink() { - return _global_sink; +void audio_play_sound(int id, float volume, float panning, float pitch) { + assert(audio); + int channel; + float pan_left, pan_right; + + // Anything beyond these are invalid + if(id < 0 || id > 299) + return; + + volume = clampf(volume, VOLUME_MIN, VOLUME_MAX); + panning = clampf(panning, PANNING_MIN, PANNING_MAX); + pitch = clampf(pitch, PITCH_MIN, PITCH_MAX); + pan_left = (panning > 0) ? 1.0f - panning : 1.0f; + pan_right = (panning < 0) ? 1.0f + panning : 1.0f; + + Mix_Chunk *chunk; + if(!(chunk = audio_get_chunk(id, volume, pitch))) + return; + channel = Mix_GroupAvailable(-1); + audio->channel_chunks[channel] = chunk; + Mix_SetPanning(channel, clamp(pan_left * 255, 0, 255), clamp(pan_right * 255, 0, 255)); + if(Mix_PlayChannel(channel, chunk, 0) == -1) { + PERROR("Unable to play sound: %s", Mix_GetError()); + } } + +void audio_play_music(resource_id id) { + assert(audio); + assert(is_music(id)); + if(audio->music_id != id) { + audio_close_module(); + const char *music_file = pm_get_resource_path(id); + if(!audio_load_module(music_file)) { + PERROR("Unable to load music track: %s", music_file); + return; + } + audio->music_id = id; + Mix_HookMusic(audio_xmp_render, NULL); + } +} + +void audio_stop_music() { + assert(audio); + Mix_HaltMusic(); + Mix_HookMusic(NULL, NULL); +} + +void audio_set_music_volume(float volume) { + assert(audio); + audio->music_volume = clampf(volume, VOLUME_MIN, VOLUME_MAX); + xmp_set_player(audio->xmp_context, XMP_PLAYER_VOLUME, audio->music_volume * 100); +} + +void audio_set_sound_volume(float volume) { + assert(audio); + volume = clampf(volume, VOLUME_MIN, VOLUME_MAX); + Mix_Volume(-1, volume * MIX_MAX_VOLUME); +} + +const audio_freq *audio_get_freqs() { + return output_freqs; +} + +const audio_mod_resampler *audio_get_resamplers() { + return music_resamplers; +} \ No newline at end of file diff --git a/src/audio/audio.h b/src/audio/audio.h index 247f07442..d7bc6051d 100644 --- a/src/audio/audio.h +++ b/src/audio/audio.h @@ -1,20 +1,93 @@ #ifndef AUDIO_H #define AUDIO_H -#include "audio/music.h" -#include "audio/sink.h" -#include "audio/sound.h" -#include "audio/source.h" -#include "audio/sources/dumb_source.h" -#include "audio/sources/vorbis_source.h" -#include "audio/stream.h" - -int audio_is_sink_available(const char *sink_name); -const char *audio_get_first_sink_name(); -int audio_init(const char *sink_name); -void audio_render(); +#include + +#include "resources/ids.h" + +#define VOLUME_DEFAULT 1.0f +#define PANNING_DEFAULT 0.0f +#define PITCH_DEFAULT 1.0f + +#define VOLUME_MAX 1.0f +#define PANNING_MAX 1.0f +#define PITCH_MAX 2.0f + +#define VOLUME_MIN 0.0f +#define PANNING_MIN -1.0f +#define PITCH_MIN 0.5f + +typedef struct audio_mod_resampler { + int internal_id; + int is_default; + const char *name; +} audio_mod_resampler; + +typedef struct audio_freq { + int freq; + int is_default; + const char *name; +} audio_freq; + +/** + * Initializes the audio subsystem + * + * @param freq Wanted output frequency (48000 should be fine) + * @param mono True if 1 channel, False for 2. + * @param resampler Music module resampler interpolation + * @param music_volume Initial music volume + * @param sound_volume Initial audio volume + * @return True if initialized, false if not. + */ +bool audio_init(int freq, bool mono, int resampler, float music_volume, float sound_volume); + +/** + * Closes the audio subsystem. + */ void audio_close(); -audio_sink *audio_get_sink(); +/** + * Plays sound with given parameters. + * + * @param id Sound resource identifier + * @param volume Volume 0.0f ... 1.0f + * @param panning Sound panning -1.0f ... 1.0f + * @param pitch Sound pitch 0.0f ... n + */ +void audio_play_sound(int id, float volume, float panning, float pitch); + +/** + * Starts background music playback. If there is something already playing, + * switches to new track. + * @param id Music file resource identifier. + */ +void audio_play_music(resource_id id); + +/** + * Stops music playback. + */ +void audio_stop_music(); + +/** + * Set music volume + * @param volume 0.0f ... 1.0f + */ +void audio_set_music_volume(float volume); + +/** + * Set sound volume 0.0f ... 1.0f + * @param volume + */ +void audio_set_sound_volume(float volume); + +/** + * Get supported audio frequencies list + */ +const audio_freq *audio_get_freqs(); + +/** + * Get supported music resamplers list + */ +const audio_mod_resampler *audio_get_resamplers(); #endif // AUDIO_H diff --git a/src/audio/music.c b/src/audio/music.c deleted file mode 100644 index 0dd4dbf08..000000000 --- a/src/audio/music.c +++ /dev/null @@ -1,222 +0,0 @@ -#include -#include -#ifdef __linux__ -#include // strcasecmp -#endif // __linux__ -#include "audio/audio.h" -#include "audio/music.h" -#include "game/utils/settings.h" -#include "resources/pathmanager.h" -#include "utils/allocator.h" -#include "utils/log.h" - -#include "audio/sources/dumb_source.h" -#include "audio/sources/vorbis_source.h" -#include "audio/sources/xmp_source.h" - -struct music_override_t { - int id; - const char *name; -}; - -#define MUSIC_STREAM_ID 1000 - -#define SOURCE_NONE 0 -#define SOURCE_DUMB 1 -#define SOURCE_XMP 2 - -static unsigned int _music_resource_id = 0; -static float _music_volume = VOLUME_DEFAULT; - -static module_source module_sources[] = { - {SOURCE_NONE, "none"}, -#ifdef USE_DUMB - {SOURCE_DUMB, "dumb"}, -#endif -#ifdef USE_XMP - {SOURCE_XMP, "xmp" }, -#endif - {0, 0 } // Guard -}; - -audio_source_freq default_freqs[] = { - {0, 1, "none"}, - {0, 0 } -}; - -audio_source_resampler default_resamplers[] = { - {0, 1, "default"}, - {0, 0 } -}; - -module_source *music_get_module_sources() { - return module_sources; -} - -const audio_source_freq *music_module_get_freqs(int id) { - switch(id) { -#ifdef USE_DUMB - case SOURCE_DUMB: - return dumb_get_freqs(); -#endif -#ifdef USE_XMP - case SOURCE_XMP: - return xmp_get_freqs(); -#endif - } - return default_freqs; -} - -const audio_source_resampler *music_module_get_resamplers(int id) { - switch(id) { -#ifdef USE_DUMB - case SOURCE_DUMB: - return dumb_get_resamplers(); -#endif -#ifdef USE_XMP - case SOURCE_XMP: - return xmp_get_resamplers(); -#endif - } - return default_resamplers; -} - -const char *get_file_or_override(unsigned int id) { - // Declare music overrides - settings *s = settings_get(); - struct music_override_t overrides[] = { - {PSM_ARENA0, s->sound.music_arena0}, - {PSM_ARENA1, s->sound.music_arena1}, - {PSM_ARENA2, s->sound.music_arena2}, - {PSM_ARENA3, s->sound.music_arena3}, - {PSM_ARENA4, s->sound.music_arena4}, - {PSM_MENU, s->sound.music_menu }, - {PSM_END, s->sound.music_end } - }; - - for(int i = 0; i < 7; i++) { - if(id == overrides[i].id && strlen(overrides[i].name) > 0) { - DEBUG("Overriding %s to %s.", get_resource_name(id), overrides[i].name); - return overrides[i].name; - } - } - - return pm_get_resource_path(id); -} - -int music_play(unsigned int id) { - audio_sink *sink = audio_get_sink(); - - // If there is no sink, do nothing - if(sink == NULL) { - return 0; - } - - // Get audio settings from config file - int channels = settings_get()->sound.music_mono ? 1 : 2; - int freq = settings_get()->sound.music_frequency; - int modlib = settings_get()->sound.music_library; - int resampler = settings_get()->sound.music_resampler; - - // Check if the wanted music is already playing - if(id == _music_resource_id && sink_is_playing(sink, MUSIC_STREAM_ID)) { - return 0; - } - - // ... Okay, it's not. Create a new resource and start loading. - audio_source *music_src = omf_calloc(1, sizeof(audio_source)); - source_init(music_src); - - // Find path & ext - const char *filename = get_file_or_override(id); - const char *ext = strrchr(filename, '.') + 1; - if(ext == NULL || ext == filename) { - PERROR("Couldn't find extension for music file!"); - goto error_0; - } - - // Try to open as module file - int failed = 1; - if(strcasecmp(ext, "psm") == 0) { - switch(modlib) { -#ifdef USE_DUMB - case SOURCE_DUMB: - failed = dumb_source_init(music_src, filename, channels, freq, resampler); - break; -#endif -#ifdef USE_XMP - case SOURCE_XMP: - failed = xmp_source_init(music_src, filename, channels, freq, resampler); - break; -#endif - } - } - - // Try to open as Ogg vorbis -#ifdef USE_OGGVORBIS - if(strcasecmp(ext, "ogg") == 0) { - failed = vorbis_source_init(music_src, filename); - } -#endif // USE_OGGVORBIS - - // Handle opening failure - if(failed) { - PERROR("No suitable music streamer found for format '%s'.", ext); - goto error_0; - } - - // Source settings - source_set_loop(music_src, 1); - - // Stop previous - music_stop(); - - // Start playback - _music_resource_id = id; - sink_play(sink, music_src, MUSIC_STREAM_ID, _music_volume, PANNING_DEFAULT, PITCH_DEFAULT); - - // All done - return 0; - -error_0: - omf_free(music_src); - return 1; -} - -int music_reload() { - unsigned int old_res_id = _music_resource_id; - music_stop(); - return music_play(old_res_id); -} - -void music_set_volume(float volume) { - audio_sink *sink = audio_get_sink(); - if(sink == NULL) { - return; - } - - _music_volume = volume; - if(sink_is_playing(sink, MUSIC_STREAM_ID)) { - sink_set_stream_volume(sink, MUSIC_STREAM_ID, _music_volume); - } -} - -void music_stop() { - audio_sink *sink = audio_get_sink(); - if(sink == NULL) { - return; - } - if(!sink_is_playing(sink, MUSIC_STREAM_ID)) { - return; - } - sink_stop(sink, MUSIC_STREAM_ID); -} - -int music_playing() { - audio_sink *sink = audio_get_sink(); - return sink_is_playing(sink, MUSIC_STREAM_ID); -} - -unsigned int music_get_resource() { - return _music_resource_id; -} diff --git a/src/audio/music.h b/src/audio/music.h deleted file mode 100644 index 8e3c1386e..000000000 --- a/src/audio/music.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef MUSIC_H -#define MUSIC_H - -#include "audio/source.h" - -typedef struct { - int id; - const char *name; -} module_source; - -int music_play(unsigned int id); -/* Equivalent to music_stop() + music_play() */ -int music_reload(); -void music_stop(); -int music_playing(); -void music_set_volume(float volume); -unsigned int music_get_resource(); -module_source *music_get_module_sources(); -const audio_source_freq *music_module_get_freqs(int id); -const audio_source_resampler *music_module_get_resamplers(int id); - -#endif // MUSIC_H diff --git a/src/audio/sink.c b/src/audio/sink.c deleted file mode 100644 index 3ec923e7d..000000000 --- a/src/audio/sink.c +++ /dev/null @@ -1,143 +0,0 @@ -#include "audio/sink.h" -#include "utils/allocator.h" -#include - -audio_stream *sink_get_stream(audio_sink *sink, unsigned int sid) { - if(sid == 0) - return NULL; - if(sink == NULL) - return NULL; - audio_stream **s; - unsigned int len; - if(hashmap_iget(&sink->streams, sid, (void **)&s, &len) != 0) { - return NULL; - } - return *s; -} - -void sink_init(audio_sink *sink) { - sink->userdata = NULL; - sink->close = NULL; - sink->format_stream = NULL; - hashmap_create(&sink->streams, 6); -} - -void sink_format_stream(audio_sink *sink, audio_stream *stream) { - sink->format_stream(sink, stream); -} - -int sink_is_playing(audio_sink *sink, int sid) { - if(sink_get_stream(sink, sid) != NULL) { - return 1; - } - return 0; -} - -void sink_play(audio_sink *sink, audio_source *src, int id, float volume, float panning, float pitch) { - audio_stream *stream = omf_calloc(1, sizeof(audio_stream)); - stream_init(stream, sink, src); - sink_format_stream(sink, stream); - stream->volume = volume; - stream->panning = panning; - stream->pitch = pitch; - stream_play(stream); - hashmap_iput(&sink->streams, id, &stream, sizeof(audio_stream *)); -} - -void sink_stop(audio_sink *sink, int sid) { - // Stop playback && remove stream - audio_stream *s = sink_get_stream(sink, sid); - stream_stop(s); - stream_free(s); - omf_free(s); - hashmap_idel(&sink->streams, sid); -} - -void sink_render(audio_sink *sink) { - iterator it; - hashmap_iter_begin(&sink->streams, &it); - hashmap_pair *pair; - while((pair = iter_next(&it)) != NULL) { - audio_stream *stream = *((audio_stream **)pair->val); - stream_render(stream); - - // If stream is done, free it here. - if(stream_get_status(stream) == STREAM_STATUS_FINISHED) { - stream_stop(stream); - stream_free(stream); - omf_free(stream); - hashmap_delete(&sink->streams, &it); - } - } -} - -void sink_free(audio_sink *sink) { - // Free streams - iterator it; - hashmap_iter_begin(&sink->streams, &it); - hashmap_pair *pair; - while((pair = iter_next(&it)) != NULL) { - audio_stream *stream = *((audio_stream **)pair->val); - stream_stop(stream); - stream_free(stream); - omf_free(stream); - } - hashmap_free(&sink->streams); - - // Close sink - if(sink->close != NULL) { - sink->close(sink); - } -} - -void sink_set_stream_panning(audio_sink *sink, int sid, float panning) { - if(panning < PANNING_MIN || panning > PANNING_MAX) - return; - audio_stream *s = sink_get_stream(sink, sid); - s->panning = panning; - stream_apply(s); -} - -void sink_set_stream_volume(audio_sink *sink, int sid, float volume) { - if(volume < VOLUME_MIN || volume > VOLUME_MAX) - return; - audio_stream *s = sink_get_stream(sink, sid); - s->volume = volume; - stream_apply(s); -} - -void sink_set_stream_pitch(audio_sink *sink, int sid, float pitch) { - if(pitch < PITCH_MIN || pitch > PITCH_MAX) - return; - audio_stream *s = sink_get_stream(sink, sid); - s->pitch = pitch; - stream_apply(s); -} - -float sink_get_stream_panning(audio_sink *sink, int sid) { - return sink_get_stream(sink, sid)->panning; -} - -float sink_get_stream_volume(audio_sink *sink, int sid) { - return sink_get_stream(sink, sid)->volume; -} - -float sink_get_stream_pitch(audio_sink *sink, int sid) { - return sink_get_stream(sink, sid)->pitch; -} - -void sink_set_userdata(audio_sink *sink, void *userdata) { - sink->userdata = userdata; -} - -void *sink_get_userdata(audio_sink *sink) { - return sink->userdata; -} - -void sink_set_close_cb(audio_sink *sink, sink_close_cb cbfunc) { - sink->close = cbfunc; -} - -void sink_set_format_stream_cb(audio_sink *sink, sink_format_stream_cb cbfunc) { - sink->format_stream = cbfunc; -} diff --git a/src/audio/sink.h b/src/audio/sink.h deleted file mode 100644 index 7a791d74a..000000000 --- a/src/audio/sink.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef SINK_H -#define SINK_H - -#include "audio/source.h" -#include "audio/stream.h" -#include "utils/hashmap.h" - -#define VOLUME_DEFAULT 1.0f -#define PANNING_DEFAULT 0.0f -#define PITCH_DEFAULT 1.0f - -#define VOLUME_MAX 1.0f -#define PANNING_MAX 1.0f -#define PITCH_MAX 2.0f - -#define VOLUME_MIN 0.0f -#define PANNING_MIN -1.0f -#define PITCH_MIN 0.5f - -typedef struct audio_sink_t audio_sink; -typedef struct audio_stream_t audio_stream; -typedef struct audio_source_t audio_source; - -typedef void (*sink_format_stream_cb)(audio_sink *sink, audio_stream *stream); -typedef void (*sink_close_cb)(audio_sink *sink); - -struct audio_sink_t { - hashmap streams; - void *userdata; - sink_close_cb close; - sink_format_stream_cb format_stream; -}; - -void sink_init(audio_sink *sink); -void sink_play(audio_sink *sink, audio_source *src, int id, float volume, float panning, float pitch); -void sink_stop(audio_sink *sink, int sid); -void sink_free(audio_sink *sink); -void sink_render(audio_sink *sink); -void sink_format_stream(audio_sink *sink, audio_stream *stream); - -int sink_is_playing(audio_sink *sink, int sid); - -void sink_set_stream_panning(audio_sink *sink, int sid, float panning); -void sink_set_stream_volume(audio_sink *sink, int sid, float volume); -void sink_set_stream_pitch(audio_sink *sink, int sid, float pitch); - -float sink_get_stream_panning(audio_sink *sink, int sid); -float sink_get_stream_volume(audio_sink *sink, int sid); -float sink_get_stream_pitch(audio_sink *sink, int sid); - -void sink_set_userdata(audio_sink *sink, void *userdata); -void *sink_get_userdata(audio_sink *sink); -void sink_set_close_cb(audio_sink *sink, sink_close_cb cbfunc); -void sink_set_format_stream_cb(audio_sink *sink, sink_format_stream_cb cbfunc); - -#endif // SINK_H diff --git a/src/audio/sinks/openal_sink.c b/src/audio/sinks/openal_sink.c deleted file mode 100644 index ecc9c443d..000000000 --- a/src/audio/sinks/openal_sink.c +++ /dev/null @@ -1,69 +0,0 @@ -#ifdef USE_OPENAL - -// On Apple OS (Mac and IOS), al.h and alc.h are in nonstandard locations -#ifdef __APPLE__ -#include -#include -#else -#include -#include -#endif - -#include "audio/sinks/openal_sink.h" -#include "audio/sinks/openal_stream.h" -#include "utils/allocator.h" -#include "utils/log.h" -#include - -typedef struct { - ALCdevice *device; - ALCcontext *context; -} openal_sink; - -void openal_sink_close(audio_sink *sink) { - openal_sink *local = sink_get_userdata(sink); - alcMakeContextCurrent(0); - alcDestroyContext(local->context); - alcCloseDevice(local->device); - omf_free(local); - sink_set_userdata(sink, local); - INFO("OpenAL Sink closed."); -} - -void openal_sink_format_stream(audio_sink *sink, audio_stream *stream) { - openal_stream_init(stream, sink); -} - -int openal_sink_init(audio_sink *sink) { - openal_sink *local = omf_calloc(1, sizeof(openal_sink)); - - // Open device and create context - local->device = alcOpenDevice(0); - if(!local->device) { - PERROR("Could not open audio playback device!"); - omf_free(local); - return 1; - } - local->context = alcCreateContext(local->device, 0); - alcMakeContextCurrent(local->context); - - // Disable distance calculation - // Good for panning - alDistanceModel(AL_NONE); - - // Set callbacks - sink_set_userdata(sink, local); - sink_set_close_cb(sink, openal_sink_close); - sink_set_format_stream_cb(sink, openal_sink_format_stream); - - // Some log stuff - INFO("OpenAL Audio Sink:"); - INFO(" * Vendor: %s", alGetString(AL_VENDOR)); - INFO(" * Renderer: %s", alGetString(AL_RENDERER)); - INFO(" * Version: %s", alGetString(AL_VERSION)); - - // All done - return 0; -} - -#endif // USE_OPENAL diff --git a/src/audio/sinks/openal_sink.h b/src/audio/sinks/openal_sink.h deleted file mode 100644 index 2295c95dc..000000000 --- a/src/audio/sinks/openal_sink.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef OPENAL_SINK_H -#define OPENAL_SINK_H - -#ifdef USE_OPENAL - -#include "audio/sink.h" - -int openal_sink_init(audio_sink *sink); - -#endif // USE_OPENAL - -#endif // OPENAL_SINK_H diff --git a/src/audio/sinks/openal_stream.c b/src/audio/sinks/openal_stream.c deleted file mode 100644 index a87bd1d7f..000000000 --- a/src/audio/sinks/openal_stream.c +++ /dev/null @@ -1,183 +0,0 @@ -#ifdef USE_OPENAL - -// On Apple OS (Mac and IOS), al.h and alc.h are in nonstandard locations -#ifdef __APPLE__ -#include -#include -#else -#include -#include -#endif - -#include "audio/sinks/openal_stream.h" -#include "utils/allocator.h" -#include "utils/log.h" -#include - -#define AUDIO_BUFFER_COUNT 2 -#define AUDIO_BUFFER_SIZE 32768 - -typedef struct { - unsigned int source; - unsigned int buffers[AUDIO_BUFFER_COUNT]; - int format; -} openal_stream; - -void openal_stream_apply(audio_stream *stream) { - openal_stream *local = stream_get_userdata(stream); - - // Handle panning here (only if mono) - if(source_get_channels(stream->src) == 1) { - float pos[] = {stream->panning, 0.0f, -1.0f}; - alSourcefv(local->source, AL_POSITION, pos); - } - - // Volume and pitch - alSourcef(local->source, AL_GAIN, stream->volume); - alSourcef(local->source, AL_PITCH, stream->pitch); -} - -void openal_stream_play(audio_stream *stream) { - openal_stream *local = stream_get_userdata(stream); - - // Fill initial buffers - char buf[AUDIO_BUFFER_SIZE]; - for(int i = 0; i < AUDIO_BUFFER_COUNT; i++) { - int ret = source_update(stream->src, buf, AUDIO_BUFFER_SIZE); - if(ret > 0) { - alBufferData(local->buffers[i], local->format, buf, ret, source_get_frequency(stream->src)); - alSourceQueueBuffers(local->source, 1, &local->buffers[i]); - } - } - - // Set volume etc. - openal_stream_apply(stream); - - // Start playback - alSourcePlay(local->source); - int err = alGetError(); - if(err != AL_NO_ERROR) { - PERROR("OpenAL Stream: Source playback error: %d.", err); - } -} - -void openal_stream_stop(audio_stream *stream) { - openal_stream *local = stream_get_userdata(stream); - alSourceStop(local->source); -} - -void openal_stream_update(audio_stream *stream) { - openal_stream *local = stream_get_userdata(stream); - - // See if we have any empty buffers to fill - int val; - alGetSourcei(local->source, AL_BUFFERS_PROCESSED, &val); - if(val <= 0) { - return; - } - - // Handle buffer filling and loading - char buf[AUDIO_BUFFER_SIZE]; - ALuint n; - while(val--) { - // Fill buffer & re-queue - int ret = source_update(stream->src, buf, AUDIO_BUFFER_SIZE); - if(ret > 0) { - alSourceUnqueueBuffers(local->source, 1, &n); - alBufferData(n, local->format, buf, ret, source_get_frequency(stream->src)); - alSourceQueueBuffers(local->source, 1, &n); - - // Check for any errors - int err = alGetError(); - if(err != AL_NO_ERROR) { - PERROR("OpenAL Stream: Error %d while buffering!", err); - } - } else { - stream_set_finished(stream); - break; - } - } - - // Make sure we are playing stream - if(stream_get_status(stream) == STREAM_STATUS_PLAYING) { - ALenum state; - alGetSourcei(local->source, AL_SOURCE_STATE, &state); - if(state != AL_PLAYING) { - alSourcePlay(local->source); - } - } -} - -void openal_stream_close(audio_stream *stream) { - openal_stream *local = stream_get_userdata(stream); - alSourceStop(local->source); - alDeleteSources(1, &local->source); - alDeleteBuffers(AUDIO_BUFFER_COUNT, local->buffers); - omf_free(local); - stream_set_userdata(stream, local); -} - -static int get_al_format(int bytes, int channels) { - if(bytes == 1) { - if(channels == 1) - return AL_FORMAT_MONO8; - if(channels == 2) - return AL_FORMAT_STEREO8; - } - if(bytes == 2) { - if(channels == 1) - return AL_FORMAT_MONO16; - if(channels == 2) - return AL_FORMAT_STEREO16; - } - return 0; -} - -int openal_stream_init(audio_stream *stream, audio_sink *sink) { - openal_stream *local = omf_calloc(1, sizeof(openal_stream)); - - // Dump old errors - while(alGetError() != AL_NO_ERROR) - ; - - // Pick format - local->format = get_al_format(source_get_bytes(stream->src), source_get_channels(stream->src)); - if(!local->format) { - PERROR("OpenAL Stream: Could not find suitable audio format!"); - goto exit_0; - } - - // Generate a source - alGenSources(1, &local->source); - if(alGetError() != AL_NO_ERROR) { - PERROR("OpenAL Stream: Could not create audio source!"); - goto exit_0; - } - - // Generate buffers - alGenBuffers(AUDIO_BUFFER_COUNT, local->buffers); - if(alGetError() != AL_NO_ERROR) { - PERROR("OpenAL Stream: Could not create audio buffers!"); - goto exit_1; - } - - // Set callbacks etc. - stream_set_userdata(stream, local); - stream_set_update_cb(stream, openal_stream_update); - stream_set_close_cb(stream, openal_stream_close); - stream_set_play_cb(stream, openal_stream_play); - stream_set_stop_cb(stream, openal_stream_stop); - stream_set_apply_cb(stream, openal_stream_apply); - - // All done - return 0; - - // Error exits -exit_1: - alDeleteSources(1, &local->source); -exit_0: - omf_free(local); - return 1; -} - -#endif // USE_OPENAL diff --git a/src/audio/sinks/openal_stream.h b/src/audio/sinks/openal_stream.h deleted file mode 100644 index 1c0d167a9..000000000 --- a/src/audio/sinks/openal_stream.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef OPENAL_STREAM_H -#define OPENAL_STREAM_H - -#ifdef USE_OPENAL - -#include "audio/sink.h" -#include "audio/stream.h" - -int openal_stream_init(audio_stream *stream, audio_sink *sink); - -#endif // USE_OPENAL - -#endif // OPENAL_STREAM_H diff --git a/src/audio/sound.c b/src/audio/sound.c deleted file mode 100644 index 8e00ae230..000000000 --- a/src/audio/sound.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "audio/sound.h" -#include "audio/audio.h" -#include "audio/sink.h" -#include "audio/source.h" -#include "audio/sources/raw_source.h" -#include "resources/sounds_loader.h" -#include "utils/allocator.h" - -static float _sound_volume = VOLUME_DEFAULT; - -void sound_play(int id, float volume, float panning, float pitch) { - audio_sink *sink = audio_get_sink(); - - // If there is no sink, do nothing - if(sink == NULL) { - return; - } - - // If the sound is already playing, stop it. - if(sink_is_playing(sink, id)) { - sink_stop(sink, id); - } - - // Get sample data - char *buf; - int len; - if(sounds_loader_get(id, &buf, &len) != 0) { - return; - } - - // Play - audio_source *src = omf_calloc(1, sizeof(audio_source)); - source_init(src); - raw_source_init(src, buf, len); - sink_play(sink, src, id, volume * _sound_volume, panning, pitch); -} - -int sound_playing(unsigned int id) { - audio_sink *sink = audio_get_sink(); - if(sink == NULL) { - return 0; - } - return sink_is_playing(sink, id); -} - -void sound_set_volume(float volume) { - _sound_volume = volume; -} diff --git a/src/audio/sound.h b/src/audio/sound.h deleted file mode 100644 index 076ab0ed4..000000000 --- a/src/audio/sound.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SOUND_H -#define SOUND_H - -void sound_play(int id, float volume, float panning, float pitch); -int sound_playing(unsigned int sound_id); -void sound_set_volume(float volume); - -#endif // SOUND_H diff --git a/src/audio/source.c b/src/audio/source.c deleted file mode 100644 index 389f13635..000000000 --- a/src/audio/source.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "audio/source.h" -#include -#include - -void source_init(audio_source *src) { - memset(src, 0, sizeof(audio_source)); -} - -int source_update(audio_source *src, char *buffer, int len) { - if(src->update != NULL) { - return src->update(src, buffer, len); - } - return 0; -} - -void source_free(audio_source *src) { - if(src->close != NULL) { - src->close(src); - } -} - -void source_set_channels(audio_source *src, int channels) { - src->channels = channels; -} -void source_set_bytes(audio_source *src, int bytes) { - src->bytes = bytes; -} -void source_set_frequency(audio_source *src, int frequency) { - src->frequency = frequency; -} -void source_set_loop(audio_source *src, int loop) { - src->loop = loop; -} -void source_set_resampler(audio_source *src, int resampler) { - src->resampler = resampler; -} - -int source_get_channels(audio_source *src) { - return src->channels; -} -int source_get_bytes(audio_source *src) { - return src->bytes; -} -int source_get_frequency(audio_source *src) { - return src->frequency; -} -int source_get_loop(audio_source *src) { - return src->loop; -} -int source_get_resampler(audio_source *src) { - return src->resampler; -} - -void source_set_userdata(audio_source *src, void *userdata) { - src->userdata = userdata; -} - -void *source_get_userdata(audio_source *src) { - return src->userdata; -} - -void source_set_update_cb(audio_source *src, source_update_cb cbfunc) { - src->update = cbfunc; -} - -void source_set_close_cb(audio_source *src, source_close_cb cbfunc) { - src->close = cbfunc; -} diff --git a/src/audio/source.h b/src/audio/source.h deleted file mode 100644 index 1854fcf21..000000000 --- a/src/audio/source.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef SOURCE_H -#define SOURCE_H - -typedef struct audio_source_t audio_source; - -typedef int (*source_update_cb)(audio_source *src, char *buffer, int len); -typedef void (*source_close_cb)(audio_source *src); - -struct audio_source_t { - int frequency; - int resampler; - int channels; - int bytes; - int loop; - void *userdata; - source_update_cb update; - source_close_cb close; -}; - -typedef struct { - int internal_id; - int is_default; - const char *name; -} audio_source_resampler; - -typedef struct { - int freq; - int is_default; - const char *name; -} audio_source_freq; - -void source_init(audio_source *src); -int source_update(audio_source *src, char *buffer, int len); -void source_free(audio_source *src); - -void source_set_channels(audio_source *src, int channels); -void source_set_bytes(audio_source *src, int bytes); -void source_set_frequency(audio_source *src, int frequency); -void source_set_loop(audio_source *src, int loop); -void source_set_resampler(audio_source *src, int resampler); - -int source_get_channels(audio_source *src); -int source_get_bytes(audio_source *src); -int source_get_frequency(audio_source *src); -int source_get_loop(audio_source *src); -int source_get_resampler(audio_source *src); - -void source_set_userdata(audio_source *src, void *userdata); -void *source_get_userdata(audio_source *src); -void source_set_update_cb(audio_source *src, source_update_cb cbfunc); -void source_set_close_cb(audio_source *src, source_close_cb cbfunc); - -#endif // SOURCE_H diff --git a/src/audio/sources/dumb_source.c b/src/audio/sources/dumb_source.c deleted file mode 100644 index 023bc22da..000000000 --- a/src/audio/sources/dumb_source.c +++ /dev/null @@ -1,140 +0,0 @@ -#ifdef USE_DUMB - -#include -#include -#ifdef __linux__ -#include // strcasecmp -#endif // __linux__ -#include "audio/sources/dumb_source.h" -#include "utils/allocator.h" -#include "utils/log.h" -#include - -typedef struct { - DUH_SIGRENDERER *renderer; - sample_t **sig_samples; - long sig_samples_size; - DUH *data; - long vpos; -} dumb_source; - -const audio_source_freq dumb_freqs[] = { - {11025, 0, "11025Hz"}, - {22050, 0, "22050Hz"}, - {44100, 1, "44100Hz"}, - {48000, 1, "48000Hz"}, - {0, 0, 0 } // Guard -}; - -const audio_source_resampler dumb_resamplers[] = { - {DUMB_RQ_ALIASING, 0, "Aliasing"}, - {DUMB_RQ_BLEP, 0, "BLEP" }, - {DUMB_RQ_LINEAR, 1, "Linear" }, - {DUMB_RQ_BLAM, 0, "BLIP" }, - {DUMB_RQ_CUBIC, 0, "Cubic" }, - {DUMB_RQ_FIR, 0, "FIR" }, - {0, 0, 0 } // Guard -}; - -const audio_source_freq *dumb_get_freqs() { - return dumb_freqs; -} - -const audio_source_resampler *dumb_get_resamplers() { - return dumb_resamplers; -} - -int dumb_source_update(audio_source *src, char *buffer, int len) { - dumb_source *local = source_get_userdata(src); - - // Get deltatime and bitrate - float delta = 65536.0f / source_get_frequency(src); - int bps = source_get_channels(src) * source_get_bytes(src); - - // If looping is off, and if we have played the whole file, stop here. - long pos = duh_sigrenderer_get_position(local->renderer); - if(pos < local->vpos && !src->loop) { - return 0; - } - local->vpos = pos; - - // ... otherwise get more data. - int ret = duh_render_int(local->renderer, &local->sig_samples, &local->sig_samples_size, - source_get_bytes(src) * 8, // Bits - 0, // Unsign - 1.0f, // Volume - delta, - len / bps, // Size - buffer) * - bps; - return ret; -} - -void dumb_source_close(audio_source *src) { - dumb_source *local = source_get_userdata(src); - duh_end_sigrenderer(local->renderer); - unload_duh(local->data); - destroy_sample_buffer(local->sig_samples); - omf_free(local); - source_set_userdata(src, local); - dumb_exit(); // Free libdumb memory - DEBUG("Libdumb Source: Closed."); -} - -int dumb_source_init(audio_source *src, const char *file, int channels, int freq, int resampler) { - dumb_source *local = omf_calloc(1, sizeof(dumb_source)); - - // Make sure libdumb is initialized - dumb_register_stdfiles(); - - // Load file and initialize renderer - char *ext = strrchr(file, '.') + 1; - if(strcasecmp(ext, "psm") == 0) { - local->data = dumb_load_psm(file, 0); - } else if(strcasecmp(ext, "s3m") == 0) { - local->data = dumb_load_s3m(file); - } else if(strcasecmp(ext, "mod") == 0) { - local->data = dumb_load_mod(file, 0); - } else if(strcasecmp(ext, "it") == 0) { - local->data = dumb_load_it(file); - } else if(strcasecmp(ext, "xm") == 0) { - local->data = dumb_load_xm(file); - } else { - PERROR("Libdumb Source: No suitable module decoder found."); - goto error_0; - } - if(!local->data) { - PERROR("Libdumb Source: Error while loading module file!"); - goto error_0; - } - local->renderer = duh_start_sigrenderer(local->data, 0, channels, 0); - local->vpos = 0; - local->sig_samples = NULL; - local->sig_samples_size = 0; - - // Set resampler here - dumb_it_set_resampling_quality(duh_get_it_sigrenderer(local->renderer), resampler); - - // Audio information - source_set_frequency(src, freq); - source_set_bytes(src, 2); - source_set_channels(src, channels); - source_set_resampler(src, resampler); - - // Set callbacks - source_set_userdata(src, local); - source_set_update_cb(src, dumb_source_update); - source_set_close_cb(src, dumb_source_close); - - // Some debug info - DEBUG("Libdumb Source: Loaded file '%s' succesfully.", file); - - // All done - return 0; - -error_0: - omf_free(local); - return 1; -} - -#endif // USE_DUMB diff --git a/src/audio/sources/dumb_source.h b/src/audio/sources/dumb_source.h deleted file mode 100644 index c47a59e55..000000000 --- a/src/audio/sources/dumb_source.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef DUMB_SOURCE_H -#define DUMB_SOURCE_H - -#ifdef USE_DUMB - -#include "audio/source.h" - -int dumb_source_init(audio_source *src, const char *file, int channels, int freq, int resampler); -const audio_source_freq *dumb_get_freqs(); -const audio_source_resampler *dumb_get_resamplers(); - -#endif // USE_DUMB - -#endif // DUMB_SOURCE_H diff --git a/src/audio/sources/raw_source.c b/src/audio/sources/raw_source.c deleted file mode 100644 index 4d7c7766d..000000000 --- a/src/audio/sources/raw_source.c +++ /dev/null @@ -1,50 +0,0 @@ -#include "audio/sources/raw_source.h" -#include "utils/allocator.h" -#include -#include - -typedef struct { - char *buf; - int len; - int pos; -} raw_source; - -int raw_source_update(audio_source *src, char *buffer, int len) { - raw_source *local = source_get_userdata(src); - int data_left = local->len - local->pos; - if(data_left == 0) { - return 0; - } - int real_len = (len > data_left) ? data_left : len; - memcpy(buffer, local->buf + local->pos, real_len); - local->pos += real_len; - return real_len; -} - -void raw_source_close(audio_source *src) { - raw_source *local = source_get_userdata(src); - omf_free(local); - source_set_userdata(src, local); -} - -int raw_source_init(audio_source *src, char *buffer, int len) { - raw_source *local = omf_calloc(1, sizeof(raw_source)); - - // Set data - local->pos = 0; - local->len = len; - local->buf = buffer; - - // Audio information - source_set_frequency(src, 8000); - source_set_bytes(src, 1); - source_set_channels(src, 1); - - // Set callbacks - source_set_userdata(src, local); - source_set_update_cb(src, raw_source_update); - source_set_close_cb(src, raw_source_close); - - // All done - return 0; -} diff --git a/src/audio/sources/raw_source.h b/src/audio/sources/raw_source.h deleted file mode 100644 index 2abe4db38..000000000 --- a/src/audio/sources/raw_source.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RAW_SOURCE_H -#define RAW_SOURCE_H - -#include "audio/source.h" - -int raw_source_init(audio_source *src, char *buffer, int len); - -#endif // RAW_SOURCE_H diff --git a/src/audio/sources/vorbis_source.c b/src/audio/sources/vorbis_source.c deleted file mode 100644 index 65ed737e1..000000000 --- a/src/audio/sources/vorbis_source.c +++ /dev/null @@ -1,119 +0,0 @@ -#ifdef USE_OGGVORBIS - -#include -#define OV_EXCLUDE_STATIC_CALLBACKS -#include "audio/sources/vorbis_source.h" -#include "utils/allocator.h" -#include "utils/log.h" -#include -#include - -typedef struct { - OggVorbis_File src_file; - int current_section; -} vorbis_source; - -const char *vorbis_text_error(int id) { - switch(id) { - case OV_EREAD: - return "OV_EREAD"; - case OV_ENOTVORBIS: - return "OV_ENOTVORBIS"; - case OV_EVERSION: - return "OV_EVERSION"; - case OV_EBADHEADER: - return "OV_EBADHEADER"; - case OV_EFAULT: - return "OV_EFAULT"; - case OV_HOLE: - return "OV_HOLE"; - case OV_EBADLINK: - return "OV_EBADLINK"; - case OV_EINVAL: - return "OV_EINVAL"; - default: - return "unknown error"; - } -} - -int vorbis_stream(audio_source *src, char *buffer, int len) { - vorbis_source *local = source_get_userdata(src); - - int read = 0; - int ret; - while(read < len) { - ret = ov_read(&local->src_file, buffer + read, len - read, // Output buffer & length - 0, 2, 1, // endian byte packing, word size (2), signedness (signed) - &local->current_section); // number of the current logical bitstream - read += ret; - if(ret < 0) { - DEBUG("Vorbis Source: Error %d while streaming: %s.", ret, vorbis_text_error(ret)); - return read; - } else if(ret == 0) { - return read; - } - } - return read; -} - -int vorbis_source_update(audio_source *src, char *buffer, int len) { - vorbis_source *local = source_get_userdata(src); - int got = vorbis_stream(src, buffer, len); - if(got == 0 && src->loop) { - ov_raw_seek(&local->src_file, 0); - return vorbis_stream(src, buffer, len); - } - return got; -} - -void vorbis_source_close(audio_source *src) { - vorbis_source *local = source_get_userdata(src); - ov_clear(&local->src_file); - omf_free(local); - source_set_userdata(src, local); - DEBUG("Vorbis Source: Closed."); -} - -int vorbis_source_init(audio_source *src, const char *file) { - vorbis_source *local; - int ret; - - // Init local struct - local = omf_calloc(1, sizeof(vorbis_source)); - - // Try to open up the audio file - ret = ov_fopen(file, &local->src_file); - if(ret != 0) { - PERROR("Vorbis Source: File '%s' could not be opened: ", file, vorbis_text_error(ret)); - goto error_1; - } - - // Get file information - vorbis_info *vi = ov_info(&local->src_file, -1); - char **comment_ptr = ov_comment(&local->src_file, -1)->user_comments; - - // Audio information - source_set_frequency(src, vi->rate); - source_set_bytes(src, 2); - source_set_channels(src, vi->channels); - - // Set callbacks - source_set_userdata(src, local); - source_set_update_cb(src, vorbis_source_update); - source_set_close_cb(src, vorbis_source_close); - - // Some debug info - DEBUG("Vorbis Source: Loaded file '%s' successfully (%d Hz, %d ch).", file, vi->rate, vi->channels); - while(*comment_ptr) { - DEBUG(" * Comment: %s", *comment_ptr); - ++comment_ptr; - } - - // All done - return 0; -error_1: - omf_free(local); - return 1; -} - -#endif // USE_OGGVORBIS diff --git a/src/audio/sources/vorbis_source.h b/src/audio/sources/vorbis_source.h deleted file mode 100644 index 91c73dc70..000000000 --- a/src/audio/sources/vorbis_source.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef VORBIS_SOURCE_H -#define VORBIS_SOURCE_H - -#ifdef USE_OGGVORBIS - -#include "audio/source.h" - -int vorbis_source_init(audio_source *src, const char *file); - -#endif // USE_OGGVORBIS - -#endif // VORBIS_SOURCE_H diff --git a/src/audio/sources/xmp_source.c b/src/audio/sources/xmp_source.c deleted file mode 100644 index 8cc504e98..000000000 --- a/src/audio/sources/xmp_source.c +++ /dev/null @@ -1,113 +0,0 @@ -#ifdef USE_XMP - -#include "audio/sources/xmp_source.h" -#include "utils/allocator.h" -#include "utils/log.h" -#include -#include - -typedef struct { - xmp_context ctx; -} xmp_source; - -const audio_source_freq xmp_freqs[] = { - {11025, 0, "11025Hz"}, - {22050, 0, "22050Hz"}, - {44100, 1, "44100Hz"}, - {48000, 1, "48000Hz"}, - {0, 0, 0 } // Guard -}; - -const audio_source_resampler xmp_resamplers[] = { - {XMP_INTERP_NEAREST, 0, "Nearest"}, - {XMP_INTERP_LINEAR, 1, "Linear" }, - {XMP_INTERP_SPLINE, 0, "Cubic" }, - {0, 0, 0 } -}; - -const audio_source_freq *xmp_get_freqs() { - return xmp_freqs; -} - -const audio_source_resampler *xmp_get_resamplers() { - return xmp_resamplers; -} - -int xmp_source_update(audio_source *src, char *buffer, int len) { - xmp_source *local = source_get_userdata(src); - int ret = xmp_play_buffer(local->ctx, buffer, len, (src->loop == 1) ? 999999 : 1); - return (ret != 0) ? 0 : len; -} - -void xmp_source_close(audio_source *src) { - xmp_source *local = source_get_userdata(src); - xmp_end_player(local->ctx); - xmp_release_module(local->ctx); - xmp_free_context(local->ctx); - omf_free(local); - source_set_userdata(src, local); - DEBUG("XMP Source: Closed."); -} - -int xmp_source_init(audio_source *src, const char *file, int channels, int freq, int resampler) { - xmp_source *local = omf_calloc(1, sizeof(xmp_source)); - - // Create a libxmp context - local->ctx = xmp_create_context(); - if(local->ctx == NULL) { - PERROR("XMP Source: Unable to initialize xmp context."); - goto error_0; - } - - // Load the module file - if(xmp_load_module(local->ctx, (char *)file) < 0) { - PERROR("XMP Source: Unable to open module file."); - goto error_1; - } - - // Show some information - struct xmp_module_info mi; - xmp_get_module_info(local->ctx, &mi); - DEBUG("XMP Source: Track is %s (%s)", mi.mod->name, mi.mod->type); - - // Start the player - int flags = 0; - if(channels == 1) { - flags |= XMP_FORMAT_MONO; - DEBUG("XMP Source: Setting to MONO."); - } - if(xmp_start_player(local->ctx, freq, flags) != 0) { - PERROR("XMP Source: Unable to open module file."); - goto error_1; - } - if(xmp_set_player(local->ctx, XMP_PLAYER_INTERP, resampler) != 0) { - PERROR("XMP Source: Unable to set resampler."); - goto error_1; - } - - // Audio information - source_set_frequency(src, freq); - source_set_bytes(src, 2); - source_set_channels(src, channels); - source_set_resampler(src, resampler); - - // Set callbacks - source_set_userdata(src, local); - source_set_update_cb(src, xmp_source_update); - source_set_close_cb(src, xmp_source_close); - - // Some debug info - DEBUG("XMP Source: Loaded file '%s' succesfully.", file); - - // All done - return 0; - -error_1: - xmp_free_context(local->ctx); - -error_0: - omf_free(local); - return 1; -} - -#endif // USE_XMP diff --git a/src/audio/sources/xmp_source.h b/src/audio/sources/xmp_source.h deleted file mode 100644 index 76faf3e2e..000000000 --- a/src/audio/sources/xmp_source.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef XMP_SOURCE_H -#define XMP_SOURCE_H - -#ifdef USE_XMP - -#include "audio/source.h" - -int xmp_source_init(audio_source *src, const char *file, int channels, int freq, int resampler); -const audio_source_freq *xmp_get_freqs(); -const audio_source_resampler *xmp_get_resamplers(); - -#endif // USE_XMP - -#endif // XMP_SOURCE_H diff --git a/src/audio/stream.c b/src/audio/stream.c deleted file mode 100644 index 87a0cfddb..000000000 --- a/src/audio/stream.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "audio/stream.h" -#include "audio/source.h" -#include "utils/allocator.h" -#include - -void stream_nullify(audio_stream *stream) { - stream->apply = NULL; - stream->close = NULL; - stream->play = NULL; - stream->stop = NULL; - stream->update = NULL; - stream->userdata = NULL; - stream->src = NULL; - stream->sink = NULL; -} - -void stream_init(audio_stream *stream, audio_sink *sink, audio_source *src) { - stream_nullify(stream); - stream->status = STREAM_STATUS_STOPPED; - stream->src = src; - stream->sink = sink; -} - -void stream_set_finished(audio_stream *stream) { - stream->status = STREAM_STATUS_FINISHED; -} - -void stream_render(audio_stream *stream) { - if(stream->update != NULL && stream->status == STREAM_STATUS_PLAYING) { - stream->update(stream); - } -} - -void stream_free(audio_stream *stream) { - if(stream->close != NULL) { - stream->close(stream); - } - if(stream->src != NULL) { - source_free(stream->src); - omf_free(stream->src); - } - stream_nullify(stream); -} - -void stream_play(audio_stream *stream) { - if(stream->play != NULL && stream->status == STREAM_STATUS_STOPPED) { - stream->play(stream); - stream->status = STREAM_STATUS_PLAYING; - } -} - -void stream_stop(audio_stream *stream) { - if(stream->stop != NULL && stream->status == STREAM_STATUS_PLAYING) { - stream->stop(stream); - stream->status = STREAM_STATUS_STOPPED; - } -} - -void stream_apply(audio_stream *stream) { - if(stream->apply != NULL) { - stream->apply(stream); - } -} - -int stream_get_status(audio_stream *stream) { - return stream->status; -} - -void stream_set_userdata(audio_stream *stream, void *userdata) { - stream->userdata = userdata; -} - -void *stream_get_userdata(audio_stream *stream) { - return stream->userdata; -} - -void stream_set_update_cb(audio_stream *stream, stream_update_cb cbfunc) { - stream->update = cbfunc; -} - -void stream_set_close_cb(audio_stream *stream, stream_close_cb cbfunc) { - stream->close = cbfunc; -} - -void stream_set_play_cb(audio_stream *stream, stream_play_cb cbfunc) { - stream->play = cbfunc; -} - -void stream_set_stop_cb(audio_stream *stream, stream_stop_cb cbfunc) { - stream->stop = cbfunc; -} - -void stream_set_apply_cb(audio_stream *stream, stream_apply_cb cbfunc) { - stream->apply = cbfunc; -} diff --git a/src/audio/stream.h b/src/audio/stream.h deleted file mode 100644 index 896692301..000000000 --- a/src/audio/stream.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef STREAM_H -#define STREAM_H - -typedef struct audio_stream_t audio_stream; -typedef struct audio_source_t audio_source; -typedef struct audio_sink_t audio_sink; - -typedef void (*stream_play_cb)(audio_stream *stream); -typedef void (*stream_stop_cb)(audio_stream *stream); -typedef void (*stream_update_cb)(audio_stream *stream); -typedef void (*stream_apply_cb)(audio_stream *stream); -typedef void (*stream_close_cb)(audio_stream *stream); - -enum -{ - STREAM_STATUS_PLAYING, - STREAM_STATUS_STOPPED, - STREAM_STATUS_FINISHED -}; - -struct audio_stream_t { - int status; - float panning; - float volume; - float pitch; - - void *userdata; - stream_update_cb update; - stream_close_cb close; - stream_play_cb play; - stream_stop_cb stop; - stream_apply_cb apply; - - audio_source *src; - audio_sink *sink; -}; - -void stream_init(audio_stream *stream, audio_sink *sink, audio_source *src); -void stream_render(audio_stream *stream); -void stream_free(audio_stream *stream); -void stream_play(audio_stream *stream); -void stream_stop(audio_stream *stream); -void stream_apply(audio_stream *stream); -void stream_set_finished(audio_stream *stream); -int stream_get_status(audio_stream *stream); - -void stream_set_userdata(audio_stream *stream, void *userdata); -void *stream_get_userdata(audio_stream *stream); -void stream_set_update_cb(audio_stream *stream, stream_update_cb cbfunc); -void stream_set_close_cb(audio_stream *stream, stream_close_cb cbfunc); -void stream_set_play_cb(audio_stream *stream, stream_play_cb cbfunc); -void stream_set_stop_cb(audio_stream *stream, stream_stop_cb cbfunc); -void stream_set_apply_cb(audio_stream *stream, stream_apply_cb cbfunc); - -#endif // STREAM_H diff --git a/src/console/console_cmd.c b/src/console/console_cmd.c index 661157dd7..a8a63994a 100644 --- a/src/console/console_cmd.c +++ b/src/console/console_cmd.c @@ -1,4 +1,4 @@ -#include "audio/music.h" +#include "audio/audio.h" #include "console/console.h" #include "console/console_type.h" #include "game/scenes/arena.h" @@ -228,7 +228,7 @@ int console_cmd_music(game_state *gs, int argc, char **argv) { if(argc == 2) { int i; if(strtoint(argv[1], &i)) { - music_play(PSM_END + i); + audio_play_music(PSM_END + i); } } return 0; diff --git a/src/controller/game_controller_db.c b/src/controller/game_controller_db.c index 1ac4e2a8d..a9a04bb39 100644 --- a/src/controller/game_controller_db.c +++ b/src/controller/game_controller_db.c @@ -1,9 +1,11 @@ -#include "controller/game_controller_db.h" +#include +#include + #include "controller/builtin_mappings.h" +#include "controller/game_controller_db.h" #include "resources/pathmanager.h" #include "utils/log.h" #include "utils/str.h" -#include void joystick_load_builtin_mappings() { SDL_RWops *rw = SDL_RWFromConstMem(builtin_controller_mappings, strlen(builtin_controller_mappings)); diff --git a/src/engine.c b/src/engine.c index c0a45f1ad..90aca2849 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,6 +1,5 @@ #include "engine.h" #include "audio/audio.h" -#include "audio/music.h" #include "console/console.h" #include "formats/altpal.h" #include "game/game_state.h" @@ -30,42 +29,27 @@ int engine_init() { int vsync = setting->video.vsync; int scale_factor = setting->video.scale_factor; char *scaler = setting->video.scaler; - const char *audiosink = setting->sound.sink; + int frequency = setting->sound.music_frequency; + int resampler = setting->sound.music_resampler; + bool mono = setting->sound.music_mono; + float music_volume = setting->sound.music_vol / 10.0; + float sound_volume = setting->sound.sound_vol / 10.0; // Initialize everything. - if(video_init(w, h, fs, vsync, scaler, scale_factor)) { + if(video_init(w, h, fs, vsync, scaler, scale_factor)) goto exit_0; - } - if(!audio_is_sink_available(audiosink)) { - const char *prev_sink = audiosink; - audiosink = audio_get_first_sink_name(); - if(audiosink == NULL) { - INFO("Could not find requested sink '%s'. No other sinks available; disabling audio.", prev_sink); - } else { - INFO("Could not find requested sink '%s'. Falling back to '%s'.", prev_sink, audiosink); - } - } - if(audio_init(audiosink)) { + if(!audio_init(frequency, mono, resampler, music_volume, sound_volume)) goto exit_1; - } - sound_set_volume(setting->sound.sound_vol / 10.0f); - music_set_volume(setting->sound.music_vol / 10.0f); - - if(sounds_loader_init()) { + if(sounds_loader_init()) goto exit_2; - } - if(lang_init()) { + if(lang_init()) goto exit_3; - } - if(fonts_init()) { + if(fonts_init()) goto exit_4; - } - if(altpals_init()) { + if(altpals_init()) goto exit_5; - } - if(console_init()) { + if(console_init()) goto exit_6; - } // Return successfully run = 1; @@ -118,7 +102,7 @@ void engine_run(engine_init_flags *init_flags) { } // apply volume settings - sound_set_volume(settings_get()->sound.sound_vol / 10.0f); + audio_set_sound_volume(settings_get()->sound.sound_vol / 10.0f); // Set up game game_state *gs = omf_calloc(1, sizeof(game_state)); @@ -253,11 +237,6 @@ void engine_run(engine_init_flags *init_flags) { dynamic_wait -= game_state_ms_per_dyntick(gs); } - // Handle audio - if(!visual_debugger) { - audio_render(); - } - // Do the actual video rendering jobs if(enable_screen_updates) { diff --git a/src/formats/chr.c b/src/formats/chr.c index 2d7cf3339..7481d6c2a 100644 --- a/src/formats/chr.c +++ b/src/formats/chr.c @@ -1,3 +1,4 @@ +#include #include #include @@ -11,7 +12,6 @@ #include "formats/tournament.h" #include "game/common_defines.h" #include "game/gui/pilotpic.h" -#include "resources/ids.h" #include "resources/pathmanager.h" #include "resources/trnmanager.h" #include "utils/allocator.h" diff --git a/src/formats/tournament.c b/src/formats/tournament.c index 9d17a313f..5c2b43ea3 100644 --- a/src/formats/tournament.c +++ b/src/formats/tournament.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/game/gui/menu.c b/src/game/gui/menu.c index c7db820b5..3416627de 100644 --- a/src/game/gui/menu.c +++ b/src/game/gui/menu.c @@ -1,5 +1,5 @@ #include "game/gui/menu.h" -#include "audio/sound.h" +#include "audio/audio.h" #include "game/gui/menu_background.h" #include "game/gui/sizer.h" #include "utils/allocator.h" @@ -158,7 +158,7 @@ static int menu_action(component *mc, int action) { } while(component_is_disabled(c)); // Play menu sound - sound_play(19, 0.5f, 0.0f, 2.0f); + audio_play_sound(19, 0.5f, 0.0f, 2.0f); component_select(c, 1); return 0; } diff --git a/src/game/gui/textbutton.c b/src/game/gui/textbutton.c index 5302953c4..8ac67e4b3 100644 --- a/src/game/gui/textbutton.c +++ b/src/game/gui/textbutton.c @@ -1,7 +1,7 @@ #include #include -#include "audio/sound.h" +#include "audio/audio.h" #include "game/gui/menu_background.h" #include "game/gui/textbutton.h" #include "game/gui/widget.h" @@ -81,7 +81,7 @@ static int textbutton_action(component *c, int action) { if(tb->click_cb) { tb->click_cb(c, tb->userdata); } - sound_play(20, 0.5f, 0.0f, 2.0f); + audio_play_sound(20, 0.5f, 0.0f, 2.0f); return 0; } return 1; diff --git a/src/game/gui/textselector.c b/src/game/gui/textselector.c index 679ab35f7..8e08a1370 100644 --- a/src/game/gui/textselector.c +++ b/src/game/gui/textselector.c @@ -2,7 +2,7 @@ #include #include -#include "audio/sound.h" +#include "audio/audio.h" #include "game/gui/textselector.h" #include "game/gui/widget.h" #include "utils/allocator.h" @@ -87,7 +87,7 @@ static int textselector_action(component *c, int action) { if(tb->toggle) { tb->toggle(c, tb->userdata, *tb->pos); } - sound_play(20, 0.5f, 0.5f, 2.0f); + audio_play_sound(20, 0.5f, 0.5f, 2.0f); // reset ticks so text is bright tb->ticks = 0; tb->dir = 0; @@ -103,7 +103,7 @@ static int textselector_action(component *c, int action) { if(tb->toggle) { tb->toggle(c, tb->userdata, *tb->pos); } - sound_play(20, 0.5f, -0.5f, 2.0f); + audio_play_sound(20, 0.5f, -0.5f, 2.0f); // reset ticks so text is bright tb->ticks = 0; tb->dir = 0; diff --git a/src/game/gui/textslider.c b/src/game/gui/textslider.c index 0808a9bf7..1a164f6ea 100644 --- a/src/game/gui/textslider.c +++ b/src/game/gui/textslider.c @@ -1,7 +1,7 @@ #include #include -#include "audio/sound.h" +#include "audio/audio.h" #include "game/gui/textslider.h" #include "game/gui/widget.h" #include "utils/allocator.h" @@ -57,7 +57,7 @@ static int textslider_action(component *c, int action) { *tb->pos = tb->positions; } else { // Play menu sound - sound_play(20, 0.5f, 0.5f, 2.0f); + audio_play_sound(20, 0.5f, 0.5f, 2.0f); } if(tb->slide) { tb->slide(c, tb->userdata, *tb->pos); @@ -72,7 +72,7 @@ static int textslider_action(component *c, int action) { *tb->pos = 0; } else { // Play menu sound - sound_play(20, 0.5f, -0.5f, 2.0f); + audio_play_sound(20, 0.5f, -0.5f, 2.0f); } if(tb->slide) { tb->slide(c, tb->userdata, *tb->pos); diff --git a/src/game/gui/trnselect.c b/src/game/gui/trnselect.c index 0693b897c..06f46f0c8 100644 --- a/src/game/gui/trnselect.c +++ b/src/game/gui/trnselect.c @@ -1,10 +1,11 @@ -#include "game/gui/trnselect.h" -#include "formats/error.h" +#include +#include + #include "formats/palette.h" #include "formats/tournament.h" #include "game/gui/label.h" +#include "game/gui/trnselect.h" #include "game/gui/widget.h" -#include "resources/pathmanager.h" #include "resources/sprite.h" #include "resources/trnmanager.h" #include "utils/allocator.h" diff --git a/src/game/objects/har.c b/src/game/objects/har.c index 91989872d..541ad4517 100644 --- a/src/game/objects/har.c +++ b/src/game/objects/har.c @@ -3,7 +3,7 @@ #include #include -#include "audio/sound.h" +#include "audio/audio.h" #include "controller/controller.h" #include "formats/af.h" #include "game/common_defines.h" @@ -452,7 +452,7 @@ void har_floor_landing_effects(object *obj) { // Landing sound float d = ((float)obj->pos.x) / 640.0f; float pos_pan = d - 0.25f; - sound_play(56, 0.3f, pos_pan, 2.2f); + audio_play_sound(56, 0.3f, pos_pan, 2.2f); } void har_move(object *obj) { @@ -780,7 +780,7 @@ void har_block(object *obj, vec2i hit_coord) { object_set_layers(scrape, LAYER_SCRAP); object_dynamic_tick(scrape); object_dynamic_tick(scrape); - sound_play(3, 0.7f, 0.5f, 1.0f); + audio_play_sound(3, 0.7f, 0.5f, 1.0f); game_state_add_object(obj->gs, scrape, RENDER_LAYER_MIDDLE, 0, 0); h->damage_received = 1; if(h->state == STATE_CROUCHBLOCK) { diff --git a/src/game/protos/player.c b/src/game/protos/player.c index 317f589cd..57d9ffd53 100644 --- a/src/game/protos/player.c +++ b/src/game/protos/player.c @@ -1,9 +1,7 @@ #include #include -#include "audio/music.h" -#include "audio/sink.h" -#include "audio/sound.h" +#include "audio/audio.h" #include "formats/error.h" #include "formats/script.h" #include "game/game_player.h" @@ -480,13 +478,13 @@ void player_run(object *obj) { // Music playback if(sd_script_isset(frame, "smo")) { if(sd_script_get(frame, "smo") == 0) { - music_stop(); + audio_stop_music(); return; } - music_play(PSM_END + (sd_script_get(frame, "smo") - 1)); + audio_play_music(PSM_END + (sd_script_get(frame, "smo") - 1)); } if(sd_script_isset(frame, "smf")) { - music_stop(); + audio_stop_music(); } // Sound playback @@ -507,7 +505,7 @@ void player_run(object *obj) { } if(obj->sound_translation_table) { int sound_id = obj->sound_translation_table[sd_script_get(frame, "s")] - 1; - sound_play(sound_id, volume, panning, pitch); + audio_play_sound(sound_id, volume, panning, pitch); } } diff --git a/src/game/scenes/arena.c b/src/game/scenes/arena.c index 6a4054a57..cb70b2b6b 100644 --- a/src/game/scenes/arena.c +++ b/src/game/scenes/arena.c @@ -2,11 +2,8 @@ #include #include #include -#include #include "audio/audio.h" -#include "audio/music.h" -#include "audio/stream.h" #include "controller/controller.h" #include "controller/net_controller.h" #include "formats/error.h" @@ -21,7 +18,6 @@ #include "game/gui/progressbar.h" #include "game/gui/text_render.h" #include "game/gui/textbutton.h" -#include "game/gui/textselector.h" #include "game/gui/textslider.h" #include "game/objects/arena_constraints.h" #include "game/objects/har.h" @@ -32,7 +28,6 @@ #include "game/utils/score.h" #include "game/utils/settings.h" #include "game/utils/ticktimer.h" -#include "resources/ids.h" #include "resources/languages.h" #include "utils/allocator.h" #include "utils/log.h" @@ -56,9 +51,6 @@ typedef struct arena_local_t { component *health_bars[2]; component *endurance_bars[2]; - chr_score player1_score; - chr_score player2_score; - object *player1_portrait; object *player2_portrait; @@ -105,11 +97,11 @@ void game_menu_return(component *c, void *userdata) { } void arena_music_slide(component *c, void *userdata, int pos) { - music_set_volume(pos / 10.0f); + audio_set_music_volume(pos / 10.0f); } void arena_sound_slide(component *c, void *userdata, int pos) { - sound_set_volume(pos / 10.0f); + audio_set_sound_volume(pos / 10.0f); } void arena_speed_slide(component *c, void *userdata, int pos) { @@ -490,7 +482,7 @@ void arena_har_hit_wall_hook(int player_id, int wall, scene *scene) { // Wallhit sound float d = ((float)o_har->pos.x) / 640.0f; float pos_pan = d - 0.25f; - sound_play(68, 1.0f, pos_pan, 2.0f); + audio_play_sound(68, 1.0f, pos_pan, 2.0f); } /** @@ -732,7 +724,7 @@ void arena_free(scene *scene) { guiframe_free(local->game_menu); surface_free(&local->sur); - music_stop(); + audio_stop_music(); // Free bar components for(int i = 0; i < 2; i++) { @@ -1081,8 +1073,8 @@ void arena_render_overlay(scene *scene) { } // Render HAR and pilot names - const char *player1_name; - const char *player2_name; + const char *player1_name = NULL; + const char *player2_name = NULL; if(player[0]->chr) { player1_name = player[0]->pilot->name; if(player[1]->pilot) { @@ -1188,19 +1180,19 @@ int arena_create(scene *scene) { // Handle music playback switch(scene->bk_data.file_id) { case 8: - music_play(PSM_ARENA0); + audio_play_music(PSM_ARENA0); break; case 16: - music_play(PSM_ARENA1); + audio_play_music(PSM_ARENA1); break; case 32: - music_play(PSM_ARENA2); + audio_play_music(PSM_ARENA2); break; case 64: - music_play(PSM_ARENA3); + audio_play_music(PSM_ARENA3); break; case 128: - music_play(PSM_ARENA4); + audio_play_music(PSM_ARENA4); break; } diff --git a/src/game/scenes/cutscene.c b/src/game/scenes/cutscene.c index 4db3220db..2989d9a8b 100644 --- a/src/game/scenes/cutscene.c +++ b/src/game/scenes/cutscene.c @@ -1,6 +1,6 @@ #include -#include "audio/music.h" +#include "audio/audio.h" #include "game/game_state.h" #include "game/gui/text_render.h" #include "game/scenes/cutscene.h" @@ -110,7 +110,7 @@ int cutscene_create(scene *scene) { const char *text = ""; switch(scene->id) { case SCENE_END: - music_play(PSM_END); + audio_play_music(PSM_END); text = lang_get(END_TEXT); local->text_x = 10; local->text_y = 5; @@ -153,7 +153,7 @@ int cutscene_create(scene *scene) { case SCENE_KATUSHAI: case SCENE_WAR: case SCENE_WORLD: - music_play(PSM_END); + audio_play_music(PSM_END); palette_load_player_cutscene_colors(mpal, &p1->pilot->palette); video_force_pal_refresh(); diff --git a/src/game/scenes/mainmenu.c b/src/game/scenes/mainmenu.c index 1e9ba638e..1a305b6a8 100644 --- a/src/game/scenes/mainmenu.c +++ b/src/game/scenes/mainmenu.c @@ -1,5 +1,5 @@ #include "game/scenes/mainmenu.h" -#include "audio/music.h" +#include "audio/audio.h" #include "game/gui/frame.h" #include "game/scenes/mainmenu/menu_main.h" #include "game/scenes/mainmenu/menu_widget_ids.h" @@ -152,7 +152,7 @@ int mainmenu_create(scene *scene) { local->prev_key[0] = local->prev_key[1] = ACT_PUNCH; // Music and renderer - music_play(PSM_MENU); + audio_play_music(PSM_MENU); // Don't render background on its own layer // Fix for some additive blending tricks. diff --git a/src/game/scenes/mainmenu/menu_audio.c b/src/game/scenes/mainmenu/menu_audio.c index dbfa47b95..6c367ee3e 100644 --- a/src/game/scenes/mainmenu/menu_audio.c +++ b/src/game/scenes/mainmenu/menu_audio.c @@ -1,8 +1,5 @@ #include "game/scenes/mainmenu/menu_audio.h" -#include "audio/music.h" -#include "audio/sound.h" -#include "audio/sources/dumb_source.h" -#include "audio/sources/xmp_source.h" +#include "audio/audio.h" #include "game/gui/gui.h" #include "game/utils/settings.h" #include "utils/allocator.h" @@ -19,11 +16,11 @@ typedef struct { static const char *mono_opts[] = {"OFF", "ON"}; void menu_audio_music_slide(component *c, void *userdata, int pos) { - music_set_volume(pos / 10.0f); + audio_set_music_volume(pos / 10.0f); } void menu_audio_sound_slide(component *c, void *userdata, int pos) { - sound_set_volume(pos / 10.0f); + audio_set_sound_volume(pos / 10.0f); } void menu_audio_done(component *c, void *userdata) { @@ -35,19 +32,19 @@ void menu_audio_done(component *c, void *userdata) { // Reload music if changes made settings_sound *s = &settings_get()->sound; - if(s->music_library != local->old_audio_settings.music_library || - s->music_frequency != local->old_audio_settings.music_frequency || + if(s->music_frequency != local->old_audio_settings.music_frequency || s->music_resampler != local->old_audio_settings.music_resampler || s->music_mono != local->old_audio_settings.music_mono) { - music_reload(); + audio_close(); + if(audio_init(s->music_frequency, s->music_mono, s->music_resampler, s->music_vol / 10.0f, + s->sound_vol / 10.0f)) { + audio_play_music(PSM_MENU); + } } } void menu_audio_reset_freqs(audio_menu_data *local, int use_settings) { - module_source *sources = music_get_module_sources(); - int id = sources[textselector_get_pos(local->lib_selector)].id; - const audio_source_freq *freqs = music_module_get_freqs(id); - + const audio_freq *freqs = audio_get_freqs(); textselector_clear_options(local->freq_selector); for(int i = 0; freqs[i].name != 0; i++) { textselector_add_option(local->freq_selector, freqs[i].name); @@ -59,10 +56,7 @@ void menu_audio_reset_freqs(audio_menu_data *local, int use_settings) { } void menu_audio_reset_resamplers(audio_menu_data *local, int use_settings) { - module_source *sources = music_get_module_sources(); - int id = sources[textselector_get_pos(local->lib_selector)].id; - const audio_source_resampler *resamplers = music_module_get_resamplers(id); - + const audio_mod_resampler *resamplers = audio_get_resamplers(); textselector_clear_options(local->resampler_selector); for(int i = 0; resamplers[i].name != 0; i++) { textselector_add_option(local->resampler_selector, resamplers[i].name); @@ -74,27 +68,13 @@ void menu_audio_reset_resamplers(audio_menu_data *local, int use_settings) { } } -void menu_audio_library_toggled(component *c, void *userdata, int pos) { - audio_menu_data *local = userdata; - module_source *sources = music_get_module_sources(); - settings_get()->sound.music_library = sources[pos].id; - menu_audio_reset_freqs(local, 0); - menu_audio_reset_resamplers(local, 0); -} - void menu_audio_freq_toggled(component *c, void *userdata, int pos) { - audio_menu_data *local = userdata; - module_source *sources = music_get_module_sources(); - int id = sources[textselector_get_pos(local->lib_selector)].id; - const audio_source_freq *freqs = music_module_get_freqs(id); + const audio_freq *freqs = audio_get_freqs(); settings_get()->sound.music_frequency = freqs[pos].freq; } void menu_audio_resampler_toggled(component *c, void *userdata, int pos) { - audio_menu_data *local = userdata; - module_source *sources = music_get_module_sources(); - int id = sources[textselector_get_pos(local->lib_selector)].id; - const audio_source_resampler *resamplers = music_module_get_resamplers(id); + const audio_mod_resampler *resamplers = audio_get_resamplers(); settings_get()->sound.music_resampler = resamplers[pos].internal_id; } @@ -126,17 +106,6 @@ component *menu_audio_create(scene *s) { &settings_get()->sound.music_vol)); menu_attach(menu, textselector_create_bind_opts(&tconf, "MONO", NULL, NULL, &settings_get()->sound.music_mono, mono_opts, 2)); - - local->lib_selector = textselector_create(&tconf, "PLAYBACK:", menu_audio_library_toggled, local); - module_source *sources = music_get_module_sources(); - for(int i = 0; sources[i].name != 0; i++) { - textselector_add_option(local->lib_selector, sources[i].name); - if(sources[i].id == settings_get()->sound.music_library) { - textselector_set_pos(local->lib_selector, i); - } - } - menu_attach(menu, local->lib_selector); - local->freq_selector = textselector_create(&tconf, "FREQUENCY:", menu_audio_freq_toggled, local); menu_audio_reset_freqs(local, 1); menu_attach(menu, local->freq_selector); diff --git a/src/game/scenes/mechlab.c b/src/game/scenes/mechlab.c index bb173c89a..5c5d5e75b 100644 --- a/src/game/scenes/mechlab.c +++ b/src/game/scenes/mechlab.c @@ -1,4 +1,5 @@ #include +#include #include #include "formats/error.h" diff --git a/src/game/scenes/mechlab/lab_menu_customize.c b/src/game/scenes/mechlab/lab_menu_customize.c index d3c573c3d..6ae07810c 100644 --- a/src/game/scenes/mechlab/lab_menu_customize.c +++ b/src/game/scenes/mechlab/lab_menu_customize.c @@ -1,6 +1,6 @@ -#include "game/scenes/mechlab/lab_menu_customize.h" +#include + #include "formats/pilot.h" -#include "game/common_defines.h" #include "game/gui/label.h" #include "game/gui/sizer.h" #include "game/gui/spritebutton.h" @@ -8,6 +8,7 @@ #include "game/gui/trn_menu.h" #include "game/scenes/mechlab.h" #include "game/scenes/mechlab/button_details.h" +#include "game/scenes/mechlab/lab_menu_customize.h" #include "game/scenes/mechlab/lab_menu_trade.h" #include "resources/bk.h" #include "resources/languages.h" diff --git a/src/game/scenes/mechlab/lab_menu_trade.c b/src/game/scenes/mechlab/lab_menu_trade.c index ec6730e99..75fa1fa85 100644 --- a/src/game/scenes/mechlab/lab_menu_trade.c +++ b/src/game/scenes/mechlab/lab_menu_trade.c @@ -1,6 +1,5 @@ -#include "game/scenes/mechlab/lab_menu_trade.h" -#include "game/common_defines.h" -#include "game/gui/label.h" +#include + #include "game/gui/sizer.h" #include "game/gui/spritebutton.h" #include "game/gui/text_render.h" @@ -9,6 +8,7 @@ #include "game/scenes/mechlab/button_details.h" #include "game/scenes/mechlab/lab_menu_confirm.h" #include "game/scenes/mechlab/lab_menu_customize.h" +#include "game/scenes/mechlab/lab_menu_trade.h" #include "resources/bk.h" #include "resources/languages.h" #include "utils/allocator.h" diff --git a/src/game/scenes/mechlab/lab_menu_training.c b/src/game/scenes/mechlab/lab_menu_training.c index be0924b4a..ae724899a 100644 --- a/src/game/scenes/mechlab/lab_menu_training.c +++ b/src/game/scenes/mechlab/lab_menu_training.c @@ -1,5 +1,5 @@ -#include "game/scenes/mechlab/lab_menu_training.h" -#include "game/common_defines.h" +#include + #include "game/gui/label.h" #include "game/gui/sizer.h" #include "game/gui/spritebutton.h" @@ -7,9 +7,9 @@ #include "game/gui/trn_menu.h" #include "game/scenes/mechlab.h" #include "game/scenes/mechlab/button_details.h" +#include "game/scenes/mechlab/lab_menu_training.h" #include "resources/bk.h" #include "resources/languages.h" -#include "utils/log.h" // I don't care anymore, sorry static component *label1; diff --git a/src/game/scenes/melee.c b/src/game/scenes/melee.c index 2cc537cb8..142371d25 100644 --- a/src/game/scenes/melee.c +++ b/src/game/scenes/melee.c @@ -1,8 +1,7 @@ +#include #include -#include -#include "audio/music.h" -#include "audio/sound.h" +#include "audio/audio.h" #include "formats/pilot.h" #include "game/game_state.h" #include "game/gui/menu_background.h" @@ -13,7 +12,6 @@ #include "game/scenes/melee.h" #include "resources/animation.h" #include "resources/bk.h" -#include "resources/ids.h" #include "resources/languages.h" #include "resources/pilots.h" #include "resources/sprite.h" @@ -24,7 +22,6 @@ #define MAX_STAT 20 typedef struct melee_local_t { - int selection; // 0 for player, 1 for HAR int row_a, row_b; // 0 or 1 int column_a, column_b; // 0-4 @@ -209,20 +206,20 @@ void handle_action(scene *scene, int player, int action) { if(*column < 0) { *column = 4; } - sound_play(19, 0.5f, 0.0f, 2.0f); + audio_play_sound(19, 0.5f, 0.0f, 2.0f); break; case ACT_RIGHT: (*column)++; if(*column > 4) { *column = 0; } - sound_play(19, 0.5f, 0.0f, 2.0f); + audio_play_sound(19, 0.5f, 0.0f, 2.0f); break; case ACT_UP: if(*row == 1) { *row = 0; } - sound_play(19, 0.5f, 0.0f, 2.0f); + audio_play_sound(19, 0.5f, 0.0f, 2.0f); break; case ACT_DOWN: if(*row == 0) { @@ -235,12 +232,12 @@ void handle_action(scene *scene, int player, int action) { local->katana_down_count[player - 1] = 11; } } - sound_play(19, 0.5f, 0.0f, 2.0f); + audio_play_sound(19, 0.5f, 0.0f, 2.0f); break; case ACT_KICK: case ACT_PUNCH: *done = 1; - sound_play(20, 0.5f, 0.0f, 2.0f); + audio_play_sound(20, 0.5f, 0.0f, 2.0f); if(local->done_a && (local->done_b || !player2->selectable)) { local->done_a = 0; local->done_b = 0; @@ -367,7 +364,7 @@ void melee_input_tick(scene *scene) { do { if(i->type == EVENT_TYPE_ACTION) { if(i->event_data.action == ACT_ESC) { - sound_play(20, 0.5f, 0.0f, 2.0f); + audio_play_sound(20, 0.5f, 0.0f, 2.0f); if(local->selection == 1) { // restore the player selection local->column_a = local->pilot_id_a % 5; @@ -699,7 +696,7 @@ int melee_create(scene *scene) { scene_set_dynamic_tick_cb(scene, melee_tick); // Play correct music - music_play(PSM_MENU); + audio_play_music(PSM_MENU); // Don't render background on its own layer // Fix for some additive blending tricks. diff --git a/src/game/scenes/newsroom.c b/src/game/scenes/newsroom.c index fdd9918c8..2118fb287 100644 --- a/src/game/scenes/newsroom.c +++ b/src/game/scenes/newsroom.c @@ -1,5 +1,5 @@ #include "game/scenes/newsroom.h" -#include "audio/music.h" +#include "audio/audio.h" #include "game/gui/dialog.h" #include "game/gui/menu_background.h" #include "game/gui/text_render.h" @@ -361,7 +361,7 @@ int newsroom_create(scene *scene) { scene_set_startup_cb(scene, newsroom_startup); // Start correct music - music_play(PSM_MENU); + audio_play_music(PSM_MENU); // Don't render background on its own layer // Fix for some additive blending tricks. diff --git a/src/game/utils/settings.c b/src/game/utils/settings.c index 2036ba36b..38f52d88b 100644 --- a/src/game/utils/settings.c +++ b/src/game/utils/settings.c @@ -60,18 +60,9 @@ const field f_video[] = { F_INT(settings_video, scale_factor, 1), }; -const field f_sound[] = {F_STRING(settings_sound, sink, "openal"), F_BOOL(settings_sound, music_mono, 0), - F_INT(settings_sound, sound_vol, 5), F_INT(settings_sound, music_vol, 5), - F_INT(settings_sound, music_frequency, 44100), -#if USE_DUMB - F_INT(settings_sound, music_library, 1), F_INT(settings_sound, music_resampler, 2), -#elif USE_XMP - F_INT(settings_sound, music_library, 2), F_INT(settings_sound, music_resampler, 1), -#endif - F_STRING(settings_sound, music_arena0, ""), F_STRING(settings_sound, music_arena1, ""), - F_STRING(settings_sound, music_arena2, ""), F_STRING(settings_sound, music_arena3, ""), - F_STRING(settings_sound, music_arena4, ""), F_STRING(settings_sound, music_end, ""), - F_STRING(settings_sound, music_menu, "")}; +const field f_sound[] = {F_BOOL(settings_sound, music_mono, 0), F_INT(settings_sound, sound_vol, 5), + F_INT(settings_sound, music_vol, 5), F_INT(settings_sound, music_frequency, 48000), + F_INT(settings_sound, music_resampler, 1)}; const field f_gameplay[] = {F_INT(settings_gameplay, speed, 5), F_INT(settings_gameplay, fight_mode, 0), F_INT(settings_gameplay, power1, 5), F_INT(settings_gameplay, power2, 5), diff --git a/src/game/utils/settings.h b/src/game/utils/settings.h index 83bbc123c..1e4cd20bf 100644 --- a/src/game/utils/settings.h +++ b/src/game/utils/settings.h @@ -27,20 +27,11 @@ typedef enum } difficulty; typedef struct { - char *sink; int music_mono; int music_frequency; int music_resampler; - int music_library; int sound_vol; int music_vol; - char *music_arena0; - char *music_arena1; - char *music_arena2; - char *music_arena3; - char *music_arena4; - char *music_end; - char *music_menu; } settings_sound; typedef struct { diff --git a/src/resources/ids.c b/src/resources/ids.c index 8eb209457..bc48b0a52 100644 --- a/src/resources/ids.c +++ b/src/resources/ids.c @@ -225,7 +225,17 @@ int is_har(unsigned int id) { } int is_music(unsigned int id) { - return (id >= PSM_MENU && id <= PSM_ARENA4); + switch(id) { + case PSM_MENU: + case PSM_END: + case PSM_ARENA0: + case PSM_ARENA1: + case PSM_ARENA2: + case PSM_ARENA3: + case PSM_ARENA4: + return 1; + } + return 0; } int is_pic(unsigned int id) { diff --git a/src/resources/ids.h b/src/resources/ids.h index 81d2ede2e..19a6dd400 100644 --- a/src/resources/ids.h +++ b/src/resources/ids.h @@ -1,7 +1,7 @@ #ifndef IDS_H #define IDS_H -enum RESOURCE_ID +typedef enum resource_id { BK_INTRO = 0, BK_OPENOMF, @@ -52,7 +52,7 @@ enum RESOURCE_ID PIC_WORLD, PIC_PLAYERS, NUMBER_OF_RESOURCES -}; +} resource_id; const char *get_resource_file(unsigned int id); const char *get_resource_name(unsigned int id);