mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-08-03 20:57:55 -04:00
initial implementation of macOS native MIDI module (#1048)
* set CMAKE_FIND_FRAMEWORK to NEVER * use pkg-config * simplify FindOpenAL.cmake * try to fix build * integrate code from Odamex
This commit is contained in:
parent
69b4b5a81a
commit
b86a45f2a2
21
.github/workflows/main.yml
vendored
21
.github/workflows/main.yml
vendored
@ -26,8 +26,8 @@ jobs:
|
||||
shell: bash,
|
||||
}
|
||||
- {
|
||||
name: Linux Clang,
|
||||
os: ubuntu-latest,
|
||||
name: macOS Clang,
|
||||
os: macos-latest,
|
||||
compiler: clang,
|
||||
shell: bash,
|
||||
}
|
||||
@ -42,7 +42,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Install dependencies (Linux)
|
||||
if: matrix.config.os == 'ubuntu-latest'
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install \
|
||||
@ -54,6 +54,21 @@ jobs:
|
||||
libxmp-dev \
|
||||
ninja-build
|
||||
|
||||
- name: Install dependencies (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
brew update
|
||||
brew install \
|
||||
cmake \
|
||||
ninja \
|
||||
pkg-config \
|
||||
sdl2 \
|
||||
sdl2_net \
|
||||
openal-soft \
|
||||
libsndfile \
|
||||
fluid-synth \
|
||||
libxmp
|
||||
|
||||
- name: Install dependencies (MSYS2)
|
||||
if: matrix.config.shell == 'msys2 {0}'
|
||||
uses: msys2/setup-msys2@v2
|
||||
|
@ -61,6 +61,8 @@ check_symbol_exists(strncasecmp "strings.h" HAVE_DECL_STRNCASECMP)
|
||||
option(CMAKE_FIND_PACKAGE_PREFER_CONFIG
|
||||
"Lookup package config files before using find modules" ON)
|
||||
|
||||
set(CMAKE_FIND_FRAMEWORK NEVER)
|
||||
|
||||
# Library requirements.
|
||||
find_package(SDL2 2.0.18 REQUIRED)
|
||||
find_package(SDL2_net REQUIRED)
|
||||
|
@ -1,6 +1,3 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindOpenAL
|
||||
----------
|
||||
@ -12,23 +9,6 @@ header file, **not** ``#include <AL/al.h>``. The reason for this is that the
|
||||
latter is not entirely portable. Windows/Creative Labs does not by default put
|
||||
their headers in ``AL/`` and macOS uses the convention ``<OpenAL/al.h>``.
|
||||
|
||||
Hints
|
||||
^^^^^
|
||||
|
||||
Environment variable ``$OPENALDIR`` can be used to set the prefix of OpenAL
|
||||
installation to be found.
|
||||
|
||||
By default on macOS, system framework is search first. In other words,
|
||||
OpenAL is searched in the following order:
|
||||
|
||||
1. System framework: ``/System/Library/Frameworks``, whose priority can be
|
||||
changed via setting the :variable:`CMAKE_FIND_FRAMEWORK` variable.
|
||||
2. Environment variable ``$OPENALDIR``.
|
||||
3. System paths.
|
||||
4. User-compiled framework: ``~/Library/Frameworks``.
|
||||
5. Manually compiled framework: ``/Library/Frameworks``.
|
||||
6. Add-on package: ``/opt``.
|
||||
|
||||
IMPORTED Targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -50,27 +30,16 @@ This module defines the following variables:
|
||||
Human-readable string containing the version of OpenAL
|
||||
#]=======================================================================]
|
||||
|
||||
# For Windows, Creative Labs seems to have added a registry key for their
|
||||
# OpenAL 1.1 installer. I have added that key to the list of search paths,
|
||||
# however, the key looks like it could be a little fragile depending on
|
||||
# if they decide to change the 1.00.0000 number for bug fix releases.
|
||||
# Also, they seem to have laid down groundwork for multiple library platforms
|
||||
# which puts the library in an extra subdirectory. Currently there is only
|
||||
# Win32 and I have hardcoded that here. This may need to be adjusted as
|
||||
# platforms are introduced.
|
||||
# The OpenAL 1.0 installer doesn't seem to have a useful key I can use.
|
||||
# I do not know if the Nvidia OpenAL SDK has a registry key.
|
||||
if(APPLE)
|
||||
set(ENV{PKG_CONFIG_PATH} "/usr/local/opt/openal-soft/lib/pkgconfig")
|
||||
endif()
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_OpenAL QUIET OpenAL)
|
||||
|
||||
find_path(OPENAL_INCLUDE_DIR al.h
|
||||
HINTS
|
||||
ENV OPENALDIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/opt
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
|
||||
PATH_SUFFIXES include/AL include/OpenAL include AL OpenAL
|
||||
)
|
||||
HINTS "${PC_OpenAL_INCLUDEDIR}")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_OpenAL_ARCH_DIR libs/Win64)
|
||||
@ -80,37 +49,21 @@ endif()
|
||||
|
||||
find_library(OPENAL_LIBRARY
|
||||
NAMES OpenAL al openal OpenAL32
|
||||
HINTS
|
||||
ENV OPENALDIR
|
||||
PATHS
|
||||
~/Library/Frameworks
|
||||
/Library/Frameworks
|
||||
/opt
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Creative\ Labs\\OpenAL\ 1.1\ Software\ Development\ Kit\\1.00.0000;InstallDir]
|
||||
PATH_SUFFIXES libx32 lib64 lib libs64 libs ${_OpenAL_ARCH_DIR}
|
||||
)
|
||||
HINTS "${PC_OpenAL_LIBDIR}")
|
||||
|
||||
unset(_OpenAL_ARCH_DIR)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(
|
||||
OpenAL
|
||||
find_package_handle_standard_args(OpenAL
|
||||
REQUIRED_VARS OPENAL_LIBRARY OPENAL_INCLUDE_DIR
|
||||
VERSION_VAR OPENAL_VERSION_STRING
|
||||
)
|
||||
VERSION_VAR OPENAL_VERSION_STRING)
|
||||
|
||||
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
|
||||
|
||||
if(OPENAL_FOUND AND NOT TARGET OpenAL::OpenAL)
|
||||
if(OPENAL_LIBRARY MATCHES "/([^/]+)\\.framework$")
|
||||
add_library(OpenAL::OpenAL INTERFACE IMPORTED)
|
||||
set_target_properties(OpenAL::OpenAL PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES "${OPENAL_LIBRARY}")
|
||||
else()
|
||||
add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
|
||||
set_target_properties(OpenAL::OpenAL PROPERTIES
|
||||
IMPORTED_LOCATION "${OPENAL_LIBRARY}")
|
||||
endif()
|
||||
set_target_properties(OpenAL::OpenAL PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}")
|
||||
IMPORTED_LOCATION "${OPENAL_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
@ -124,30 +124,6 @@ set(WOOF_SOURCES
|
||||
z_zone.c z_zone.h
|
||||
../miniz/miniz.c ../miniz/miniz.h)
|
||||
|
||||
# Some platforms require standard libraries to be linked against.
|
||||
if(HAVE_LIBM)
|
||||
list(APPEND WOOF_LIBRARIES m)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND WOOF_SOURCES i_winmusic.c)
|
||||
list(APPEND WOOF_LIBRARIES winmm)
|
||||
if(MSVC)
|
||||
list(APPEND WOOF_SOURCES
|
||||
../win32/win_opendir.c ../win32/win_opendir.h)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FluidSynth_FOUND)
|
||||
list(APPEND WOOF_SOURCES i_flmusic.c)
|
||||
list(APPEND WOOF_LIBRARIES FluidSynth::libfluidsynth)
|
||||
endif()
|
||||
|
||||
if(libxmp_FOUND)
|
||||
list(APPEND WOOF_SOURCES i_xmp.c)
|
||||
list(APPEND WOOF_LIBRARIES libxmp::xmp)
|
||||
endif()
|
||||
|
||||
# Standard target definition
|
||||
if(WIN32)
|
||||
add_library(woof SHARED EXCLUDE_FROM_ALL ${WOOF_SOURCES})
|
||||
@ -194,6 +170,36 @@ target_link_libraries(woof PRIVATE ${WOOF_LIBRARIES}
|
||||
opl
|
||||
textscreen)
|
||||
|
||||
# Some platforms require standard libraries to be linked against.
|
||||
if(HAVE_LIBM)
|
||||
target_link_libraries(woof PRIVATE m)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_sources(woof PRIVATE i_winmusic.c)
|
||||
target_link_libraries(woof PRIVATE winmm)
|
||||
if(MSVC)
|
||||
target_sources(woof PRIVATE
|
||||
../win32/win_opendir.c ../win32/win_opendir.h)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
target_sources(woof PRIVATE i_macmusic.c)
|
||||
target_link_libraries(woof PRIVATE
|
||||
-Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit -Wl,-framework,CoreServices)
|
||||
endif()
|
||||
|
||||
if(FluidSynth_FOUND)
|
||||
target_sources(woof PRIVATE i_flmusic.c)
|
||||
target_link_libraries(woof PRIVATE FluidSynth::libfluidsynth)
|
||||
endif()
|
||||
|
||||
if(libxmp_FOUND)
|
||||
target_sources(woof PRIVATE i_xmp.c)
|
||||
target_link_libraries(woof PRIVATE libxmp::xmp)
|
||||
endif()
|
||||
|
||||
# Optional features.
|
||||
#
|
||||
# Our defines are not namespaced, so we pass them at compile-time instead of
|
||||
|
367
src/i_macmusic.c
Normal file
367
src/i_macmusic.c
Normal file
@ -0,0 +1,367 @@
|
||||
//
|
||||
// Copyright (C) 2006-2020 by The Odamex Team.
|
||||
// Copyright(C) 2023 Roman Fomin
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
|
||||
/*
|
||||
native_midi_macosx: Native Midi support on Mac OS X for the SDL_mixer library
|
||||
Copyright (C) 2009 Ryan C. Gordon <icculus@icculus.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "i_sound.h"
|
||||
#include "memio.h"
|
||||
#include "mus2mid.h"
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <AvailabilityMacros.h>
|
||||
|
||||
static MusicPlayer player;
|
||||
static MusicSequence sequence;
|
||||
static AudioUnit unit;
|
||||
static AUGraph graph;
|
||||
static AUNode synth;
|
||||
static AUNode output;
|
||||
|
||||
static boolean music_initialized;
|
||||
|
||||
static boolean I_MAC_InitMusic(int device)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||
ComponentDescription d;
|
||||
#else
|
||||
AudioComponentDescription d;
|
||||
#endif
|
||||
|
||||
d.componentType = kAudioUnitType_MusicDevice;
|
||||
d.componentSubType = kAudioUnitSubType_DLSSynth;
|
||||
d.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
d.componentFlags = 0;
|
||||
d.componentFlagsMask = 0;
|
||||
|
||||
NewAUGraph(&graph);
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||
AUGraphNewNode(graph, &d, 0, NULL, &synth);
|
||||
#else
|
||||
AUGraphAddNode(graph, &d, &synth);
|
||||
#endif
|
||||
|
||||
d.componentType = kAudioUnitType_Output;
|
||||
d.componentSubType = kAudioUnitSubType_DefaultOutput;
|
||||
d.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
d.componentFlags = 0;
|
||||
d.componentFlagsMask = 0;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||
AUGraphNewNode(graph, &d, 0, NULL, &output);
|
||||
#else
|
||||
AUGraphAddNode(graph, &d, &output);
|
||||
#endif
|
||||
|
||||
if (AUGraphConnectNodeInput(graph, synth, 0, output, 0) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_InitMusic: AUGraphConnectNodeInput failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AUGraphOpen(graph) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_InitMusic: AUGraphOpen failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AUGraphInitialize(graph) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_InitMusic: AUGraphInitialize failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 // this is deprecated, but works back to 10.0
|
||||
if (AUGraphGetNodeInfo(graph, output, NULL, NULL, NULL, &unit) != noErr)
|
||||
#else // not deprecated, but requires 10.5 or later
|
||||
if (AUGraphNodeInfo(graph, output, NULL, &unit) != noErr)
|
||||
#endif
|
||||
{
|
||||
fprintf(stderr, "I_MAC_InitMusic: AUGraphGetNodeInfo failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NewMusicPlayer(&player) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_InitMusic: Music player creation failed using AudioToolbox.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("I_MAC_InitMusic: Music playback enabled using AudioToolbox.\n");
|
||||
music_initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void I_MAC_SetMusicVolume(int volume)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
if (AudioUnitSetParameter(unit,
|
||||
kAudioUnitParameterUnit_LinearGain,
|
||||
kAudioUnitScope_Output,
|
||||
0, (float) volume / 15, 0) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_SetMusicVolume: AudioUnitSetParameter failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void I_MAC_PauseSong(void *handle)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
MusicPlayerStop(player);
|
||||
}
|
||||
|
||||
static void I_MAC_ResumeSong(void *handle)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
MusicPlayerStart(player);
|
||||
}
|
||||
|
||||
static void I_MAC_PlaySong(void *handle, boolean looping)
|
||||
{
|
||||
UInt32 i, ntracks;
|
||||
MusicTimeStamp maxtime = 0;
|
||||
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
if (MusicSequenceSetAUGraph(sequence, graph) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicSequenceSetAUGraph failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicPlayerSetSequence(player, sequence) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicPlayerSetSequence failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicPlayerPreroll(player) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicPlayerPreroll failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicSequenceGetTrackCount(sequence, &ntracks) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicSequenceGetTrackCount failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ntracks; i++)
|
||||
{
|
||||
MusicTrack track;
|
||||
MusicTimeStamp time;
|
||||
UInt32 size = sizeof(time);
|
||||
|
||||
if (MusicSequenceGetIndTrack(sequence, i, &track) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicSequenceGetIndTrack failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (MusicTrackGetProperty(track, kSequenceTrackProperty_TrackLength,
|
||||
&time, &size) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicTrackGetProperty failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (time > maxtime)
|
||||
{
|
||||
maxtime = time;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ntracks; i++)
|
||||
{
|
||||
MusicTrack track;
|
||||
MusicTrackLoopInfo info;
|
||||
|
||||
if (MusicSequenceGetIndTrack(sequence, i, &track) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicSequenceGetIndTrack failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
info.loopDuration = maxtime;
|
||||
info.numberOfLoops = (looping ? 0 : 1);
|
||||
|
||||
if (MusicTrackSetProperty(track, kSequenceTrackProperty_LoopInfo,
|
||||
&info, sizeof(info)) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicTrackSetProperty failed.\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (MusicPlayerStart(player) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_PlaySong: MusicPlayerStart failed.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void I_MAC_StopSong(void *handle)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
MusicPlayerStop(player);
|
||||
|
||||
// needed to prevent error and memory leak when disposing sequence
|
||||
MusicPlayerSetSequence(player, NULL);
|
||||
}
|
||||
|
||||
static void *I_MAC_RegisterSong(void *data, int len)
|
||||
{
|
||||
CFDataRef data_ref = NULL;
|
||||
|
||||
if (!music_initialized)
|
||||
return NULL;
|
||||
|
||||
if (NewMusicSequence(&sequence) != noErr)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_RegisterSong: Unable to create AudioUnit sequence.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (IsMid(data, len))
|
||||
{
|
||||
data_ref = CFDataCreate(NULL, (const UInt8 *)data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume a MUS file and try to convert
|
||||
MEMFILE *instream;
|
||||
MEMFILE *outstream;
|
||||
void *outbuf;
|
||||
size_t outbuf_len;
|
||||
|
||||
instream = mem_fopen_read(data, len);
|
||||
outstream = mem_fopen_write();
|
||||
|
||||
if (mus2mid(instream, outstream) == 0)
|
||||
{
|
||||
mem_get_buf(outstream, &outbuf, &outbuf_len);
|
||||
data_ref = CFDataCreate(NULL, (const UInt8 *)outbuf, outbuf_len);
|
||||
}
|
||||
|
||||
mem_fclose(instream);
|
||||
mem_fclose(outstream);
|
||||
}
|
||||
|
||||
if (data_ref == NULL)
|
||||
{
|
||||
fprintf(stderr, "I_MAC_RegisterSong: Failed to load MID.\n");
|
||||
DisposeMusicSequence(sequence);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
|
||||
// MusicSequenceLoadSMFData() (avail. in 10.2, no 64 bit) is equivalent to
|
||||
// calling MusicSequenceLoadSMFDataWithFlags() with a flags value of 0
|
||||
// (avail. in 10.3, avail. 64 bit). So, we use MusicSequenceLoadSMFData() for
|
||||
// powerpc versions but the *WithFlags() on intel which require 10.4 anyway.
|
||||
#if defined(__ppc__) || defined(__POWERPC__)
|
||||
if (MusicSequenceLoadSMFData(sequence, data_ref) != noErr)
|
||||
#else
|
||||
if (MusicSequenceLoadSMFDataWithFlags(sequence, data_ref, 0) != noErr)
|
||||
#endif
|
||||
#else // MusicSequenceFileLoadData() requires 10.5 or later.
|
||||
if (MusicSequenceFileLoadData(sequence, data_ref, 0, 0) != noErr)
|
||||
#endif
|
||||
{
|
||||
DisposeMusicSequence(sequence);
|
||||
CFRelease(data_ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CFRelease(data_ref);
|
||||
|
||||
return (void *)1;
|
||||
}
|
||||
|
||||
static void I_MAC_UnRegisterSong(void *handle)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
DisposeMusicSequence(sequence);
|
||||
}
|
||||
|
||||
static void I_MAC_ShutdownMusic(void)
|
||||
{
|
||||
if (!music_initialized)
|
||||
return;
|
||||
|
||||
I_MAC_StopSong(NULL);
|
||||
I_MAC_UnRegisterSong(NULL);
|
||||
|
||||
DisposeMusicPlayer(player);
|
||||
DisposeAUGraph(graph);
|
||||
|
||||
music_initialized = false;
|
||||
}
|
||||
|
||||
static int I_MAC_DeviceList(const char* devices[], int size, int *current_device)
|
||||
{
|
||||
*current_device = 0;
|
||||
if (size > 0)
|
||||
{
|
||||
devices[0] = "Native";
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
music_module_t music_mac_module =
|
||||
{
|
||||
I_MAC_InitMusic,
|
||||
I_MAC_ShutdownMusic,
|
||||
I_MAC_SetMusicVolume,
|
||||
I_MAC_PauseSong,
|
||||
I_MAC_ResumeSong,
|
||||
I_MAC_RegisterSong,
|
||||
I_MAC_PlaySong,
|
||||
I_MAC_StopSong,
|
||||
I_MAC_UnRegisterSong,
|
||||
I_MAC_DeviceList,
|
||||
};
|
@ -22,7 +22,6 @@
|
||||
|
||||
#include "SDL.h"
|
||||
#include "al.h"
|
||||
#include "alext.h"
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "i_sndfile.h"
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
// Music modules
|
||||
extern music_module_t music_win_module;
|
||||
extern music_module_t music_mac_module;
|
||||
extern music_module_t music_fl_module;
|
||||
extern music_module_t music_oal_module;
|
||||
extern music_module_t music_opl_module;
|
||||
@ -45,6 +46,8 @@ static music_modules_t music_modules[] =
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
{ &music_win_module, 1 },
|
||||
#elif defined(__APPLE__)
|
||||
{ &music_mac_module, 1 },
|
||||
#endif
|
||||
#if defined(HAVE_FLUIDSYNTH)
|
||||
{ &music_fl_module, 1 },
|
||||
|
Loading…
x
Reference in New Issue
Block a user