Redo musicplayer to use sdl2_mixer

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@7639 30fe4595-0a0c-4342-8851-515496e4dcbd
This commit is contained in:
beaglejoe 2021-08-31 15:49:49 +00:00
parent c3fa8c35d3
commit 7099707d41
13 changed files with 466 additions and 783 deletions

220
cmake/FindSDL2_mixer.cmake Normal file
View File

@ -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 <amine.benhassouna@gmail.com>
# 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()

View File

@ -252,6 +252,17 @@ MACRO(CHECK_LIBRARIES)
MESSAGE(STATUS "Looking for library SDL2 - NOT found")
ENDIF(SDL2_FOUND)
IF(NOT SDL2_MIXER_FOUND)
Find_Package(SDL2_mixer)
ENDIF()
IF(SDL2_MIXER_FOUND)
SET(HAVE_LIBSDL2 1)
MESSAGE(STATUS "Looking for library SDL2_mixer - found")
ELSE(SDL2_MIXER_FOUND)
MESSAGE(STATUS "Looking for library SDL2_mixer - NOT found")
ENDIF(SDL2_MIXER_FOUND)
ELSE(OPTION_SDL2)
# SDL 1.x
Find_Package(SDL)

View File

@ -91,6 +91,7 @@ MACRO(_FIND_3RDPARTY_DEPENDENCIES ROOT_DIR)
IF(OPTION_SDL2)
_FIND_3RDPARTY_DEPENDENCY(SDL2MAIN sdl_main.h "SDL2" "sdl2main" "${ROOT_DIR}" "")
_FIND_3RDPARTY_DEPENDENCY(SDL2 sdl.h "SDL2" "sdl2" "${ROOT_DIR}" "")
_FIND_3RDPARTY_DEPENDENCY(SDL2_MIXER SDL_mixer.h "" "SDL2_mixer" "${ROOT_DIR}" "")
#IF(SDL_FOUND) # Dirty hack to make FindPackage(SDL) work later.
# SET(SDL_LIBRARY_TEMP ${SDL_LIBRARY} CACHE FILEPATH "")
@ -322,6 +323,8 @@ MACRO(SD_INSTALL_CUSTOM_3RDPARTY TARGET_NAME)
IF(OPTION_SDL2)
_FIND_3RDPARTY_DLL("${SDL2_LIBRARY}" "SDL2" ";lib" _DLL_PATHNAME)
LIST(APPEND _THIRDPARTY_DLL_PATHNAMES "${_DLL_PATHNAME}")
_FIND_3RDPARTY_DLL("${SDL2_MIXER_LIBRARY}" "SDL2_mixer" ";lib" _DLL_PATHNAME)
LIST(APPEND _THIRDPARTY_DLL_PATHNAMES "${_DLL_PATHNAME}")
ELSE()
_FIND_3RDPARTY_DLL("${SDL_LIBRARY}" "SDL" ";lib" _DLL_PATHNAME)
LIST(APPEND _THIRDPARTY_DLL_PATHNAMES "${_DLL_PATHNAME}")

View File

@ -181,6 +181,31 @@ MACRO(ADD_SDL2_LIBRARY TARGET)
ENDMACRO(ADD_SDL2_LIBRARY TARGET)
MACRO(ADD_SDL2_MIXER_INCLUDEDIR)
FIND_PACKAGE(SDL2_mixer)
message(STATUS "SDL2_MIXER_INCLUDE_DIR = '${SDL2_MIXER_INCLUDE_DIR}'")
message(STATUS "SDL2_MIXER_LIBRARY = '${SDL2_MIXER_LIBRARY}'")
IF(SDL2_MIXER_FOUND)
INCLUDE_DIRECTORIES(${SDL2_MIXER_INCLUDE_DIR})
ELSE(SDL2_MIXER_FOUND)
MESSAGE(FATAL_ERROR "Cannot find SDL2_mixer header files")
ENDIF(SDL2_MIXER_FOUND)
ENDMACRO(ADD_SDL2_MIXER_INCLUDEDIR)
MACRO(ADD_SDL2_MIXER_LIBRARY TARGET)
FIND_PACKAGE(SDL2_mixer)
IF(SDL2_MIXER_FOUND)
TARGET_LINK_LIBRARIES(${TARGET} ${SDL2_MIXER_LIBRARY})
ELSE(SDL2_MIXER_FOUND)
MESSAGE(FATAL_ERROR "Cannot find SDL2_mixer library")
ENDIF(SDL2_MIXER_FOUND)
ENDMACRO(ADD_SDL2_MIXER_LIBRARY TARGET)
MACRO(ADD_OPENGL_INCLUDEDIR)
FIND_PACKAGE(OpenGL)

View File

@ -6,13 +6,12 @@ ADD_INTERFACE_INCLUDEDIR()
ADD_SDLIB_INCLUDEDIR(tgf math portability)
IF(OPTION_SDL2)
ADD_SDL2_INCLUDEDIR()
ADD_SDL2_MIXER_INCLUDEDIR()
ELSE(OPTION_SDL2)
ADD_SDL_INCLUDEDIR()
ENDIF(OPTION_SDL2)
ADD_JPEG_INCLUDEDIR()
ADD_PLIB_INCLUDEDIR()
ADD_OPENAL_INCLUDEDIR()
ADD_VORBIS_INCLUDEDIR()
IF(OPTION_WEBSERVER)
ADD_CURL_INCLUDEDIR()
ENDIF(OPTION_WEBSERVER)
@ -24,6 +23,7 @@ SET(_SOURCES control.cpp glfeatures.cpp guibutton.cpp guifont.cpp
guicombobox.cpp guicheckbox.cpp guiprogresbar.cpp
guiscreen.cpp guieventloop.cpp guiapplication.cpp
musicplayer.cpp musicplayer.h
sdl2musicplayer.cpp sdl2musicplayer.h
glfeatures.h gui.h guiscreen.h guimenu.h tgfclient.h guifont.h)
IF(OPTION_WEBSERVER)
@ -36,11 +36,6 @@ ENDIF(OPTION_SDL_FORCEFEEDBACK)
SET(_OTHER_SOURCES guimenutest.xml)
SET(_SOURCES ${_SOURCES}
soundstream.cpp soundstream.h
oggsoundstream.cpp oggsoundstream.h
openalmusicplayer.cpp openalmusicplayer.h )
#disable developer warning
IF (COMMAND CMAKE_POLICY)
CMAKE_POLICY(SET CMP0003 NEW)
@ -84,24 +79,11 @@ IF(OPENGL_FOUND)
TARGET_LINK_LIBRARIES(tgfclient ${OPENGL_LIBRARY})
ENDIF(OPENGL_FOUND)
IF(OPENAL_FOUND)
TARGET_LINK_LIBRARIES(tgfclient ${OPENAL_LIBRARY})
ENDIF(OPENAL_FOUND)
IF(VORBIS_FOUND)
TARGET_LINK_LIBRARIES(tgfclient ${VORBIS_LIBRARY})
ENDIF(VORBIS_FOUND)
IF(VORBISFILE_FOUND)
TARGET_LINK_LIBRARIES(tgfclient ${VORBISFILE_LIBRARY})
ENDIF(VORBISFILE_FOUND)
IF(OGG_FOUND)
TARGET_LINK_LIBRARIES(tgfclient ${OGG_LIBRARY})
ENDIF(OGG_FOUND)
ADD_PLIB_LIBRARY(tgfclient ul sg js)
IF(OPTION_SDL2)
ADD_SDL2_LIBRARY(tgfclient)
ADD_SDL2_MIXER_LIBRARY(tgfclient)
ELSE(OPTION_SDL2)
ADD_SDL_LIBRARY(tgfclient)
ENDIF(OPTION_SDL2)

View File

@ -26,11 +26,12 @@
#include "tgfclient.h"
#include <portability.h>
#include <sound.h>
#include <SDL_mixer.h>
#define MAX_MUSIC_PATH 1024
#define NOMUSIC "None"
#include "oggsoundstream.h"
#include "openalmusicplayer.h"
#include "sdl2musicplayer.h"
static const char *musicDisabledStr = SND_VAL_MUSIC_STATE_DISABLED;
@ -38,169 +39,126 @@ static bool enabled = true;
static char currentMusicfile[MAX_MUSIC_PATH] = {0};
static char defaultMusic[MAX_MUSIC_PATH] = {0}; //"data/music/main.ogg";
static float maxMusicVolume = 1.0;
#define NOMUSIC "None"
std::map<std::string,OpenALMusicPlayer*> mapOpenAlPlayers;
static SDL_mutex *mapMutex = NULL;
static void playMenuMusic();
static void pauseMenuMusic();
std::map<std::string,SDL2MusicPlayer*> mapSDL2Players;
static void readConfig();
static bool isEnabled()
{
{
return enabled;
}
// Path relative to CWD, e.g "data/music/main.ogg"
static SoundStream* getMenuSoundStream(char* oggFilePath)
static SDL2MusicPlayer* getMusicPlayer(char* oggFilePath)
{
OggSoundStream* stream = new OggSoundStream(oggFilePath);
return stream;
}
static OpenALMusicPlayer* getMusicPlayer(char* oggFilePath)
{
OpenALMusicPlayer* player = NULL;
SDL2MusicPlayer* player = NULL;
SDL_LockMutex(mapMutex);
const std::map<std::string, OpenALMusicPlayer*>::const_iterator itPlayers = mapOpenAlPlayers.find(oggFilePath);
const std::map<std::string, SDL2MusicPlayer*>::const_iterator itPlayers = mapSDL2Players.find(oggFilePath);
if (itPlayers == mapOpenAlPlayers.end()) {
player = new OpenALMusicPlayer(getMenuSoundStream(oggFilePath));
mapOpenAlPlayers[oggFilePath] = player;
if (itPlayers == mapSDL2Players.end()) {
player = new SDL2MusicPlayer(oggFilePath);
mapSDL2Players[oggFilePath] = player;
player->setvolume(maxMusicVolume);
player->start();
} else {
player = mapOpenAlPlayers[oggFilePath];
player = mapSDL2Players[oggFilePath];
}
SDL_UnlockMutex(mapMutex);
return player;
}
static Uint32 sdlTimerFunc(Uint32 interval, void* /* pEvLoopPriv */)
{
playMenuMusic();
return 1;
}
SDL_TimerID timerId = 0;
static void playMenuMusic()
{
const int nextcallinms = 100;
SDL_LockMutex(mapMutex);
std::map<std::string, OpenALMusicPlayer*>::const_iterator itPlayers = mapOpenAlPlayers.begin();
while(itPlayers != mapOpenAlPlayers.end()) {
OpenALMusicPlayer* player = itPlayers->second;
if (player) {
player->playAndManageBuffer();
}
++itPlayers;
}
SDL_UnlockMutex(mapMutex);
if(timerId == 0){
timerId = SDL_AddTimer(nextcallinms, sdlTimerFunc, (void*)NULL);
}
}
void initMusic()
{
readConfig();
if (isEnabled()) {
GfLogInfo("(Re-)Initializing music player \n");
mapMutex = SDL_CreateMutex();
(void)getMusicPlayer(defaultMusic);
strcpy(currentMusicfile,defaultMusic);
playMenuMusic();
if( Mix_OpenAudio( 44100, MIX_DEFAULT_FORMAT, 2, 2048 ) >= 0 ){
(void)getMusicPlayer(defaultMusic);
strcpy(currentMusicfile,defaultMusic);
SDL2MusicPlayer* player = getMusicPlayer(currentMusicfile);
if(player){
player->resume();
}
}
}
else {
GfLogInfo("Music player is disabled \n");
}
}
void shutdownMusic()
{
if(timerId != 0){
SDL_RemoveTimer(timerId);
timerId = 0;
}
SDL_LockMutex(mapMutex);
std::map<std::string, OpenALMusicPlayer*>::const_iterator itPlayers = mapOpenAlPlayers.begin();
while(itPlayers != mapOpenAlPlayers.end()) {
OpenALMusicPlayer* player = itPlayers->second;
std::map<std::string, SDL2MusicPlayer*>::const_iterator itPlayers = mapSDL2Players.begin();
while(itPlayers != mapSDL2Players.end()) {
SDL2MusicPlayer* player = itPlayers->second;
player->stop();
player->rewind();
++itPlayers;
}
itPlayers = mapOpenAlPlayers.begin();
while(itPlayers != mapOpenAlPlayers.end()) {
OpenALMusicPlayer* player = itPlayers->second;
itPlayers = mapSDL2Players.begin();
while(itPlayers != mapSDL2Players.end()) {
SDL2MusicPlayer* player = itPlayers->second;
delete player;
++itPlayers;
}
mapOpenAlPlayers.clear();
mapSDL2Players.clear();
SDL_UnlockMutex(mapMutex);
SDL_DestroyMutex(mapMutex);
mapMutex = NULL;
Mix_Quit();
}
void pauseMenuMusic()
{
if(timerId != 0){
SDL_RemoveTimer(timerId);
timerId = 0;
}
SDL_LockMutex(mapMutex);
std::map<std::string, OpenALMusicPlayer*>::const_iterator itPlayers = mapOpenAlPlayers.begin();
while(itPlayers != mapOpenAlPlayers.end()) {
OpenALMusicPlayer* player = itPlayers->second;
player->pause();
++itPlayers;
}
SDL_UnlockMutex(mapMutex);
}
void playMusic(char* filename)
{
if (isEnabled()) {
OpenALMusicPlayer* player = NULL;
if(filename != NULL) {
if(0 == strcmp(NOMUSIC,filename)){
SDL2MusicPlayer* player = NULL;
if(filename != NULL)
{
if(0 == strcmp(NOMUSIC,filename))
{
player = getMusicPlayer(currentMusicfile);
player->stop();
strcpy(currentMusicfile,filename);
GfLogInfo("Music changing to: %s \n", filename);
pauseMenuMusic();
return;
}
if(0 != strcmp(currentMusicfile,filename)){
if(0 != strcmp(currentMusicfile,filename))
{
if(0 != strcmp(NOMUSIC,currentMusicfile)){
player = getMusicPlayer(currentMusicfile);
player->fadeout();
player->stop();
}
strcpy(currentMusicfile,filename);
GfLogInfo("Music changing to: %s \n", filename);
player = getMusicPlayer(filename);
player->fadein();
player->resume();
}
} else {
if(0 != strcmp(currentMusicfile,defaultMusic)){
if(0 != strcmp(NOMUSIC,currentMusicfile)){
}
else
{
if(0 != strcmp(currentMusicfile,defaultMusic))
{
if(0 != strcmp(NOMUSIC,currentMusicfile))
{
player = getMusicPlayer(currentMusicfile);
player->fadeout();
player->stop();
}
strcpy(currentMusicfile,defaultMusic);
GfLogInfo("Music changing to: %s \n", defaultMusic);
player = getMusicPlayer(defaultMusic);
player->fadein();
player->resume();
}
else
{
player = getMusicPlayer(defaultMusic);
player->resume();
}
}
if(player) {
player->resume();
}
playMenuMusic();
}
}
@ -225,6 +183,8 @@ static void readConfig()
{
char fnbuf[1024];
sprintf(fnbuf, "%s%s", GfLocalDir(), SND_PARAM_FILE);
GfLogInfo("Reading music player config\n");
void *paramHandle = GfParmReadFile(fnbuf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
const char *musicenabled = GfParmGetStr(paramHandle, SND_SCT_MUSIC, SND_ATT_MUSIC_STATE, musicDisabledStr);
@ -249,12 +209,11 @@ static void readConfig()
// Using plib for the sound effects sometimes crashes when OpenAL already has the sound device
const char* isplib = GfParmGetStr(paramHandle, SND_SCT_SOUND, SND_ATT_SOUND_STATE, "");
if (!strcmp(isplib, "plib")) {
enabled = false;
GfLogInfo("Music player disabled for PLIB\n");
//enabled = false;
GfLogInfo("Music player disabled when using PLIB for sound effects\n");
}
//TODO end of section to Remove
GfLogInfo("(Re-)Initializing music player \n");
GfParmReleaseHandle(paramHandle);
paramHandle = NULL;
}
@ -268,5 +227,5 @@ void setMusicVolume(float vol)
maxMusicVolume = vol;
GfLogInfo("Music maximum volume set to %.2f\n", maxMusicVolume);
GfLogInfo("Music volume set to %.2f\n", maxMusicVolume);
}

View File

@ -1,160 +0,0 @@
/***************************************************************************
file : OggSoundStream.cpp
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* Concrete implementation for ogg sound streams */
#include "oggsoundstream.h"
#include <tgf.h>
OggSoundStream::OggSoundStream(char* path):
SoundStream(path),
_valid(false),
_rateInHz(0),
_format(FORMAT_INVALID)
{
int result;
if((result = ov_fopen(path, &_oggStream)) < 0) {
GfLogError("OggSoundStream: Could not open Ogg stream: %s\n", errorString(result));
return;
}
// fclose is not required here, the vorbis lib will take care of this on ov_clear.
vorbis_info* vorbisInfo = ov_info(&_oggStream, -1);
_rateInHz = vorbisInfo->rate;
if(vorbisInfo->channels == 1) {
_format = FORMAT_MONO16;
} else {
_format = FORMAT_STEREO16;
}
_valid = true;
}
OggSoundStream::~OggSoundStream()
{
if (isValid()) {
ov_clear(&_oggStream);
}
}
bool OggSoundStream::read(char* buffer, const int bufferSize, int* resultSize, const char*& error)
{
if (!isValid()) {
error = "OggSoundStream: Invalid, no data available.";
return false;
}
int section;
int result;
while(*resultSize < bufferSize) {
result = ov_read(&_oggStream, buffer + *resultSize, bufferSize - *resultSize, 0, 2, 1, &section);
if(result > 0) {
*resultSize += result;
} else {
if(result < 0) {
error = errorString(result);
return false;
} else {
// Loop to the beginning of the stream
ov_time_seek(&_oggStream, 0);
}
}
}
if(*resultSize == 0) {
error = "OggSoundStream: Read 0 bytes.";
return false;
}
return true;
}
void OggSoundStream::rewind()
{
if (!isValid()) {
GfLogError("OggSoundStream: Invalid, no info available.\n");
return;
}
ov_time_seek(&_oggStream, 0);
}
void OggSoundStream::display()
{
if (!isValid()) {
GfLogError("OggSoundStream: Invalid, no info available.\n");
return;
}
vorbis_info* vorbisInfo = ov_info(&_oggStream, -1);
vorbis_comment* vorbisComment = ov_comment(&_oggStream, -1);
GfLogInfo("version %d\n", vorbisInfo->version);
GfLogInfo("channels %d\n", vorbisInfo->channels);
GfLogInfo("rate (hz) %ld\n", vorbisInfo->rate);
GfLogInfo("bitrate upper %ld\n", vorbisInfo->bitrate_upper);
GfLogInfo("bitrate nominal %ld\n", vorbisInfo->bitrate_nominal);
GfLogInfo("bitrate lower %ld\n", vorbisInfo->bitrate_lower);
GfLogInfo("bitrate window %ld\n\n", vorbisInfo->bitrate_window);
GfLogInfo("vendor %s\n", vorbisComment->vendor);
int i;
for(i = 0; i < vorbisComment->comments; i++) {
GfLogInfo(" %s\n", vorbisComment->user_comments[i]);
}
}
const char* OggSoundStream::errorString(int code)
{
switch(code)
{
case OV_EREAD:
return "OggSoundStream: Read from media.";
case OV_ENOTVORBIS:
return "OggSoundStream: Not Vorbis data.";
case OV_EVERSION:
return "OggSoundStream: Vorbis version mismatch.";
case OV_EBADHEADER:
return "OggSoundStream: Invalid Vorbis header.";
case OV_EFAULT:
return "OggSoundStream: Internal logic fault (bug or heap/stack corruption.";
default:
return "OggSoundStream: Unknown Ogg error.";
}
}

View File

@ -1,55 +0,0 @@
#ifndef __OggSoundStream_h__
#define __OggSoundStream_h__
/***************************************************************************
file : OggSoundStream.h
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* Concrete implementation for ogg sound streams */
#define OV_EXCLUDE_STATIC_CALLBACKS
#include <vorbis/vorbisfile.h>
#include "soundstream.h"
class OggSoundStream : public SoundStream
{
public:
OggSoundStream(char* path);
virtual ~OggSoundStream();
virtual int getRateInHz() { return _rateInHz; }
virtual SoundFormat getSoundFormat() { return _format; }
virtual bool read(char* buffer, const int bufferSize, int* resultSize, const char*& error);
virtual void rewind();
virtual void display();
virtual bool isValid() { return _valid; }
protected:
private:
const char* errorString(int code);
OggVorbis_File _oggStream;
bool _valid;
int _rateInHz;
SoundFormat _format;
};
#endif // __OggSoundStream_h__

View File

@ -1,343 +0,0 @@
/***************************************************************************
file : OpenAlMusicPlayer.cpp
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <cstdio>
#include <tgf.h>
#include "openalmusicplayer.h"
const int OpenALMusicPlayer::BUFFERSIZE = 4096*64;
const ALfloat OpenALMusicPlayer::FADESTEP = 0.01f;
OpenALMusicPlayer::OpenALMusicPlayer(SoundStream* soundStream):
_device(NULL),
_context(NULL),
_originalcontext(NULL),
_source(0),
_maxVolume(1.0),
_fadestate(FADEIN),
_stream(soundStream),
_ready(false)
{
_buffers[0] = 0;
_buffers[1] = 0;
}
OpenALMusicPlayer::~OpenALMusicPlayer()
{
if (_ready) {
stop();
}
if(_originalcontext == NULL) {
alcMakeContextCurrent(0);
alcDestroyContext(_context);
alcCloseDevice(_device);
}
if(_stream) {
delete _stream;
_stream = NULL;
}
}
void OpenALMusicPlayer::stop()
{
if (!_ready) {
return;
}
alSourceStop(_source);
int queued = 0;
alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued);
while (queued--) {
ALuint buffer;
alSourceUnqueueBuffers(_source, 1, &buffer);
check();
}
alDeleteSources(1, &_source);
check();
alDeleteBuffers(2, _buffers);
check();
_ready = false;
}
bool OpenALMusicPlayer::initContext()
{
_originalcontext = alcGetCurrentContext();
if(_originalcontext == NULL) {
_device = alcOpenDevice(NULL);
if(_device == NULL ) {
GfLogError("OpenALMusicPlayer: OpenAL could not open device\n");
return false;
}
_context = alcCreateContext(_device, NULL);
if(_context == NULL) {
alcCloseDevice(_device);
GfLogError("OpenALMusicPlayer: OpenAL could not create contect for device\n");
return false;
}
alcMakeContextCurrent(_context);
alcGetError(_device);
}
return check();
}
bool OpenALMusicPlayer::initBuffers()
{
alGenBuffers(2, _buffers);
return check();
}
bool OpenALMusicPlayer::initSource()
{
alGenSources(1, &_source);
if (!check()) {
GfLogError("OpenALMusicPlayer: initSource failed to get sound source.\n");
return false;
};
alSource3f(_source, AL_POSITION, 0.0, 0.0, 0.0);
alSource3f(_source, AL_VELOCITY, 0.0, 0.0, 0.0);
alSource3f(_source, AL_DIRECTION, 0.0, 0.0, 0.0);
alSourcef (_source, AL_ROLLOFF_FACTOR, 0.0 );
alSourcei (_source, AL_SOURCE_RELATIVE, AL_TRUE );
return true;
}
bool OpenALMusicPlayer::check()
{
int error = alGetError();
if(error != AL_NO_ERROR) {
GfLogError("OpenALMusicPlayer: OpenAL error was raised: %d\n", error);
return false;
}
return true;
}
bool OpenALMusicPlayer::isPlaying()
{
ALenum state;
alGetSourcei(_source, AL_SOURCE_STATE, &state);
return (state == AL_PLAYING);
}
bool OpenALMusicPlayer::streamBuffer(ALuint buffer)
{
char pcm[BUFFERSIZE];
int size = 0;
const char* error = (char*)'\0';
if (!_stream->read(pcm, BUFFERSIZE, &size, error)) {
GfLogError("OpenALMusicPlayer: Stream read error: %s\n", error);
return false;
}
int format;
switch (_stream->getSoundFormat()) {
case SoundStream::FORMAT_MONO16:
format = AL_FORMAT_MONO16;
break;
case SoundStream::FORMAT_STEREO16:
format = AL_FORMAT_STEREO16;
break;
default:
GfLogError("OpenALMusicPlayer: Format error: \n");
return false;
}
alBufferData(buffer, format, pcm, size, _stream->getRateInHz());
return check();
}
void OpenALMusicPlayer::start()
{
if (!_ready) {
if (_stream->getSoundFormat() == SoundStream::FORMAT_INVALID) {
GfLogError("OpenALMusicPlayer: Sound stream has invalid format\n");
return;
}
if (initContext() && initBuffers() && initSource()) {
_ready = true;
startPlayback();
}
return;
}
}
void OpenALMusicPlayer::pause()
{
if(isPlaying()) {
alSourceStop(_source);
}
}
void OpenALMusicPlayer::resume()
{
if(!isPlaying()) {
alSourcePlay(_source);
}
}
void OpenALMusicPlayer::rewind()
{
_stream->rewind();
}
bool OpenALMusicPlayer::playAndManageBuffer()
{
if (!_ready) {
return false;
}
int processed = 0;
bool active = true;
doFade();
alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);
while(processed--) {
ALuint buffer;
alSourceUnqueueBuffers(_source, 1, &buffer);
check();
active = streamBuffer(buffer);
alSourceQueueBuffers(_source, 1, &buffer);
check();
}
if (!active && !isPlaying()) {
// Try to reanimate playback
if(!startPlayback()) {
GfLogError("OpenALMusicPlayer: Cannot play stream.\n");
}
}
return true;
}
bool OpenALMusicPlayer::startPlayback()
{
if(isPlaying()) {
return true;
}
if(!streamBuffer(_buffers[0])) {
return false;
}
if(!streamBuffer(_buffers[1])) {
return false;
}
alSourceQueueBuffers(_source, 2, _buffers);
alSourcePlay(_source);
return true;
}
void OpenALMusicPlayer::fadeout()
{
_fadestate = FADEOUT;
}
void OpenALMusicPlayer::fadein()
{
_fadestate = FADEIN;
alSourcef(_source, AL_GAIN, 0.0f);
}
void OpenALMusicPlayer::setvolume(float volume)
{
_maxVolume = volume;
}
float OpenALMusicPlayer::getvolume()
{
return _maxVolume;
}
void OpenALMusicPlayer::doFade()
{
ALfloat currentVol = 0.0;
switch(_fadestate){
case FADEIN:
alGetSourcef(_source, AL_GAIN, &currentVol);
currentVol += FADESTEP;
if(currentVol >= _maxVolume){
currentVol = _maxVolume;
_fadestate = NONE;
}
alSourcef(_source, AL_GAIN, currentVol);
break;
case FADEOUT:
alGetSourcef(_source, AL_GAIN, &currentVol);
currentVol -= FADESTEP;
if(currentVol <= 0.0){
currentVol = 0.0;
_fadestate = NONE;
}
alSourcef(_source, AL_GAIN, currentVol);
break;
case NONE:
break;
}
}

View File

@ -0,0 +1,125 @@
/***************************************************************************
file : SDL2MusicPlayer.cpp
created : Sat June 5 2021
copyright : (C) 2021
email :
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <cstdio>
#include <tgf.h>
#include "sdl2musicplayer.h"
SDL2MusicPlayer::SDL2MusicPlayer(char* oggFilePath):
music(NULL),
maxVolume(1.0),
fadestate(FADEIN),
started(false),
ready(false)
{
if(oggFilePath){
music = Mix_LoadMUS(oggFilePath);
}
}
SDL2MusicPlayer::~SDL2MusicPlayer()
{
stop();
if(music) {
Mix_FreeMusic( music );
music = NULL;
}
}
void SDL2MusicPlayer::stop()
{
Mix_HaltMusic();
if (!ready) {
return;
}
ready = false;
}
bool SDL2MusicPlayer::isPlaying()
{
return started;
}
void SDL2MusicPlayer::start()
{
if(music){
Mix_FadeInMusic(music, -1, 1000);
started = true;
}
}
void SDL2MusicPlayer::pause()
{
//Mix_PauseMusic();
Mix_FadeOutMusic(1000);
}
void SDL2MusicPlayer::resume()
{
if((Mix_PlayingMusic() == 0) || (!started))
{
start();
}
else
{
Mix_ResumeMusic();
}
}
void SDL2MusicPlayer::rewind()
{
//_stream->rewind();
}
bool SDL2MusicPlayer::startPlayback()
{
if(isPlaying()) {
return true;
}
return true;
}
void SDL2MusicPlayer::fadeout()
{
fadestate = FADEOUT;
}
void SDL2MusicPlayer::fadein()
{
fadestate = FADEIN;
}
void SDL2MusicPlayer::setvolume(float volume)
{
maxVolume = volume;
Mix_VolumeMusic(int(maxVolume * 100));
}
float SDL2MusicPlayer::getvolume()
{
return maxVolume;
}
void SDL2MusicPlayer::doFade()
{
}

View File

@ -1,12 +1,12 @@
#ifndef __OpenALMusicPlayer_h__
#define __OpenALMusicPlayer_h__
#ifndef __SDL2MusicPlayer_h__
#define __SDL2MusicPlayer_h__
/***************************************************************************
file : OpenAlMusicPlayer.h
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
file : SDL2MusicPlayer.h
created : Sat June 5 2021
copyright : (C) 2021
email :
version : $Id$
***************************************************************************/
@ -20,51 +20,37 @@
* *
***************************************************************************/
#include <AL/al.h>
#include <AL/alc.h>
#include "soundstream.h"
#include <SDL_mixer.h>
class OpenALMusicPlayer
class SDL2MusicPlayer
{
public:
OpenALMusicPlayer(SoundStream* soundStream);
virtual ~OpenALMusicPlayer();
SDL2MusicPlayer(char* oggFilePath);
virtual ~SDL2MusicPlayer();
virtual void start();
virtual void stop();
virtual void pause();
virtual void resume();
virtual void rewind();
virtual bool playAndManageBuffer();
virtual void setvolume(float volume);
virtual float getvolume();
virtual void fadeout();
virtual void fadein();
protected:
virtual bool initContext();
virtual bool initBuffers();
virtual bool initSource();
virtual bool check();
virtual bool startPlayback();
virtual bool isPlaying();
virtual bool streamBuffer(ALuint buffer);
virtual void doFade();
ALCdevice* _device;
ALCcontext* _context;
ALCcontext* _originalcontext;
ALuint _source; // audio source
ALuint _buffers[2]; // front and back buffers
ALfloat _maxVolume;
Mix_Music* music;
typedef enum { NONE, FADEIN, FADEOUT } eFadeState;
eFadeState _fadestate;
eFadeState fadestate;
SoundStream* _stream;
bool _ready; // initialization sucessful
static const int BUFFERSIZE;
static const ALfloat FADESTEP;
float maxVolume;
bool ready;
bool started;
};
#endif // __OpenALMusicPlayer_h__
#endif // __SDL2MusicPlayer_h__

View File

@ -1,22 +0,0 @@
/***************************************************************************
file : SoundStream.cpp
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* Interface for sound streams */
#include "soundstream.h"

View File

@ -1,48 +0,0 @@
#ifndef __SoundStream_h__
#define __SoundStream_h__
/***************************************************************************
file : SoundStream.h
created : Fri Dec 23 17:35:18 CET 2011
copyright : (C) 2011 Bernhard Wymann
email : berniw@bluewin.ch
version : $Id$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* Intherface for sound streams */
class SoundStream
{
public:
SoundStream(const char* path) {};
virtual ~SoundStream() {};
enum SoundFormat {
FORMAT_INVALID,
FORMAT_MONO16,
FORMAT_STEREO16
};
virtual int getRateInHz() = 0;
virtual SoundFormat getSoundFormat() = 0;
virtual bool read(char* buffer, const int bufferSize, int* resultSize, const char*& error) = 0;
virtual void rewind() = 0;
virtual void display() = 0;
// isValid is not nice, but I do not want to introduce exceptions at this time
virtual bool isValid() = 0;
};
#endif // __SoundStream_h__