This commit is contained in:
OBattler
2022-02-20 01:22:44 +01:00
8 changed files with 318 additions and 90 deletions

View File

@@ -32,3 +32,7 @@ indent_size = 4
[*.cmake] [*.cmake]
indent_style = space indent_style = space
indent_size = 4 indent_size = 4
[*.json]
indent_style = space
indent_size = 4

View File

@@ -35,10 +35,10 @@ jobs:
fail-fast: true fail-fast: true
matrix: matrix:
build: build:
- name: Regular ODR # - name: Regular ODR
slug: -ODR # slug: -ODR
preset: regular # preset: regular
target: install/strip # target: install/strip
- name: Debug ODR - name: Debug ODR
slug: -ODR-Debug slug: -ODR-Debug
preset: debug preset: debug
@@ -47,10 +47,10 @@ jobs:
slug: -ODR-Dev slug: -ODR-Dev
preset: experimental preset: experimental
target: install target: install
- name: Regular NDR # - name: Regular NDR
slug: -NDR # slug: -NDR
preset: regularndr # preset: regularndr
target: install/strip # target: install/strip
- name: Debug NDR - name: Debug NDR
slug: -NDR-Debug slug: -NDR-Debug
preset: debugndr preset: debugndr
@@ -114,12 +114,12 @@ jobs:
fail-fast: true fail-fast: true
matrix: matrix:
build: build:
- name: Regular ODR # - name: Regular ODR
slug: -ODR # slug: -ODR
type: Release # type: Release
dev-build: off # dev-build: off
new-dynarec: off # new-dynarec: off
strip: --strip # strip: --strip
- name: Debug ODR - name: Debug ODR
slug: -ODR-Debug slug: -ODR-Debug
type: Debug type: Debug
@@ -130,12 +130,12 @@ jobs:
type: Debug type: Debug
dev-build: on dev-build: on
new-dynarec: off new-dynarec: off
- name: Regular NDR # - name: Regular NDR
slug: -NDR # slug: -NDR
type: Release # type: Release
strip: --strip # strip: --strip
dev-build: off # dev-build: off
new-dynarec: on # new-dynarec: on
- name: Debug NDR - name: Debug NDR
slug: -NDR-Debug slug: -NDR-Debug
type: Debug type: Debug
@@ -210,18 +210,18 @@ jobs:
linux: linux:
name: "Linux GCC 11 (${{ matrix.build.name }} x86_64)" name: "Linux GCC 11 (${{ matrix.build.name }} x86_64)"
runs-on: ubuntu-2004 runs-on: ubuntu-20.04
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
build: build:
- name: Regular ODR # - name: Regular ODR
slug: -ODR # slug: -ODR
type: Release # type: Release
dev-build: off # dev-build: off
new-dynarec: off # new-dynarec: off
strip: --strip # strip: --strip
- name: Debug ODR - name: Debug ODR
slug: -ODR-Debug slug: -ODR-Debug
type: Debug type: Debug
@@ -232,12 +232,12 @@ jobs:
type: Debug type: Debug
dev-build: on dev-build: on
new-dynarec: off new-dynarec: off
- name: Regular NDR # - name: Regular NDR
slug: -NDR # slug: -NDR
type: Release # type: Release
strip: --strip # strip: --strip
dev-build: off # dev-build: off
new-dynarec: on # new-dynarec: on
- name: Debug NDR - name: Debug NDR
slug: -NDR-Debug slug: -NDR-Debug
type: Debug type: Debug
@@ -280,12 +280,12 @@ jobs:
fail-fast: true fail-fast: true
matrix: matrix:
build: build:
- name: Regular ODR # - name: Regular ODR
slug: -ODR # slug: -ODR
type: Release # type: Release
dev-build: off # dev-build: off
new-dynarec: off # new-dynarec: off
strip: --strip # strip: --strip
- name: Debug ODR - name: Debug ODR
slug: -ODR-Debug slug: -ODR-Debug
type: Debug type: Debug
@@ -296,12 +296,12 @@ jobs:
type: Debug type: Debug
dev-build: on dev-build: on
new-dynarec: off new-dynarec: off
- name: Regular NDR # - name: Regular NDR
slug: -NDR # slug: -NDR
type: Release # type: Release
strip: --strip # strip: --strip
dev-build: off # dev-build: off
new-dynarec: on # new-dynarec: on
- name: Debug NDR - name: Debug NDR
slug: -NDR-Debug slug: -NDR-Debug
type: Debug type: Debug

View File

@@ -115,6 +115,7 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
option(RELEASE "Release build" OFF) option(RELEASE "Release build" OFF)
option(DYNAREC "Dynamic recompiler" ON) option(DYNAREC "Dynamic recompiler" ON)
option(OPENAL "OpenAL" ON) option(OPENAL "OpenAL" ON)
option(FAUDIO "FAudio" OFF)
option(FLUIDSYNTH "FluidSynth" ON) option(FLUIDSYNTH "FluidSynth" ON)
option(MUNT "MUNT" ON) option(MUNT "MUNT" ON)
option(DINPUT "DirectInput" OFF) option(DINPUT "DirectInput" OFF)

View File

@@ -86,7 +86,12 @@ if(APPLE)
target_link_libraries(86Box Freetype::Freetype) target_link_libraries(86Box Freetype::Freetype)
endif() endif()
if(OPENAL) if(FAUDIO)
find_package(FAudio REQUIRED)
target_link_libraries(86Box FAudio::FAudio)
endif()
if(OPENAL AND NOT FAUDIO)
if(VCPKG_TOOLCHAIN) if(VCPKG_TOOLCHAIN)
find_package(OpenAL CONFIG REQUIRED) find_package(OpenAL CONFIG REQUIRED)
elseif(MINGW) elseif(MINGW)

View File

@@ -202,9 +202,8 @@ macro(install_qt5_plugin _qt_plugin_name _qt_plugins_var _prefix)
get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH) get_filename_component(_qt_plugin_type "${_qt_plugin_path}" PATH)
get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME) get_filename_component(_qt_plugin_type "${_qt_plugin_type}" NAME)
set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}") set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}")
install(FILES "${_qt_plugin_path}" install(FILES "${_qt_plugin_path}" DESTINATION "${_qt_plugin_dest}")
DESTINATION "${_qt_plugin_dest}") list(APPEND ${_qt_plugins_var} "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${_qt_plugin_dest}/${_qt_plugin_file}")
list(APPEND ${_qt_plugins_var} "${_qt_plugin_dest}/${_qt_plugin_file}")
else() else()
message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found") message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
endif() endif()
@@ -245,11 +244,7 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
install(CODE " install(CODE "
include(BundleUtilities) include(BundleUtilities)
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX} ABSOLUTE) get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX} ABSOLUTE)
foreach(PLUGIN ${QT_PLUGINS}) fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${QT_PLUGINS}\" \"${DIRS}\")")
get_filename_component(PLUGIN_ABSOLUTE \${PLUGIN} ABSOLUTE BASE_DIR \${CMAKE_INSTALL_PREFIX_ABSOLUTE})
list(APPEND QT_PLUGINS_ABSOLUTE \${PLUGIN_ABSOLUTE})
endforeach()
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${QT_PLUGINS_ABSOLUTE}\" \"${DIRS}\")")
endif() endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)

View File

@@ -19,10 +19,14 @@ add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_resid.cc
snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c snd_azt2316a.c snd_cms.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c
snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c) snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c)
if(OPENAL) if(OPENAL OR FAUDIO)
target_compile_definitions(snd PRIVATE USE_OPENAL) target_compile_definitions(snd PRIVATE USE_OPENAL)
if (FAUDIO)
target_sources(snd PRIVATE faudio.cpp)
else()
target_sources(snd PRIVATE openal.c) target_sources(snd PRIVATE openal.c)
endif() endif()
endif()
if(FLUIDSYNTH) if(FLUIDSYNTH)
target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH) target_compile_definitions(snd PRIVATE USE_FLUIDSYNTH)

219
src/sound/faudio.cpp Normal file
View File

@@ -0,0 +1,219 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Interface to the FAudio audio processing library.
*
*
*
* Authors: Cacodemon345
*
* Copyright 2022 Cacodemon345.
*/
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <FAudio.h>
extern "C"
{
#include <86box/86box.h>
#include <86box/sound.h>
#include <86box/midi.h>
static int midi_freq = 44100;
static int midi_buf_size = 4410;
static int initialized = 0;
static FAudio* faudio = nullptr;
static FAudioMasteringVoice* mastervoice = nullptr;
static FAudioSourceVoice* srcvoice = nullptr;
static FAudioSourceVoice* srcvoicemidi = nullptr;
static FAudioSourceVoice* srcvoicecd = nullptr;
#define FREQ 48000
#define BUFLEN SOUNDBUFLEN
static void FAUDIOCALL
onBufferFinished(
FAudioVoiceCallback *callback,
void *pBufferContext)
{
if (sound_is_float) delete[] (float*)(pBufferContext);
else delete[] (int16_t*)(pBufferContext);
}
static FAudioVoiceCallback callbacks =
{
onBufferFinished
};
void
inital()
{
if (FAudioCreate(&faudio, 0, FAUDIO_DEFAULT_PROCESSOR))
{
return;
}
if (FAudio_CreateMasteringVoice(faudio, &mastervoice, 2, FREQ, 0, 0, nullptr))
{
FAudio_Release(faudio);
faudio = nullptr;
return;
}
FAudioWaveFormatEx fmt;
fmt.nChannels = 2;
if (sound_is_float)
{
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
fmt.wBitsPerSample = 32;
}
else
{
fmt.wFormatTag = FAUDIO_FORMAT_PCM;
fmt.wBitsPerSample = 16;
}
fmt.nSamplesPerSec = FREQ;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
fmt.cbSize = 0;
if (FAudio_CreateSourceVoice(faudio, &srcvoice, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr))
{
FAudioVoice_DestroyVoice(mastervoice);
FAudio_Release(faudio);
faudio = nullptr;
mastervoice = nullptr;
return;
}
fmt.nSamplesPerSec = CD_FREQ;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
FAudio_CreateSourceVoice(faudio, &srcvoicecd, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
FAudioVoice_SetVolume(srcvoice, 1, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_Start(srcvoice, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_Start(srcvoicecd, 0, FAUDIO_COMMIT_NOW);
auto mdn = midi_device_get_internal_name(midi_device_current);
if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME))
{
fmt.nSamplesPerSec = midi_freq;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
}
initialized = 1;
}
void
closeal()
{
if (!initialized) return;
initialized = 0;
FAudioSourceVoice_Stop(srcvoice, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoice);
FAudioSourceVoice_Stop(srcvoicecd, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicecd);
if (srcvoicemidi)
{
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi);
FAudioVoice_DestroyVoice(srcvoicemidi);
}
FAudioVoice_DestroyVoice(srcvoice);
FAudioVoice_DestroyVoice(srcvoicecd);
FAudioVoice_DestroyVoice(mastervoice);
FAudio_Release(faudio);
srcvoice = srcvoicecd = srcvoicemidi = nullptr;
mastervoice = nullptr;
faudio = nullptr;
}
void
givealbuffer_common(void *buf, FAudioSourceVoice* sourcevoice, size_t buflen)
{
if (!initialized) return;
FAudioVoice_SetVolume(mastervoice, pow(10.0, (double)sound_gain / 20.0), FAUDIO_COMMIT_NOW);
FAudioBuffer buffer{};
buffer.Flags = 0;
if (sound_is_float)
{
buffer.pAudioData = (uint8_t*)new float[buflen];
buffer.AudioBytes = (buflen) * sizeof(float);
}
else
{
buffer.pAudioData = (uint8_t*)new int16_t[buflen];
buffer.AudioBytes = (buflen) * sizeof(int16_t);
}
if (buffer.pAudioData == nullptr)
{
fatal("faudio: Out Of Memory!");
}
memcpy((void*)buffer.pAudioData, buf, buffer.AudioBytes);
buffer.PlayBegin = buffer.PlayLength = 0;
buffer.PlayLength = buflen >> 1;
buffer.pContext = (void*)buffer.pAudioData;
FAudioSourceVoice_SubmitSourceBuffer(sourcevoice, &buffer, nullptr);
}
void
givealbuffer(void *buf)
{
givealbuffer_common(buf, srcvoice, BUFLEN << 1);
}
void
givealbuffer_cd(void *buf)
{
if (srcvoicecd) givealbuffer_common(buf, srcvoicecd, CD_BUFLEN << 1);
}
void
al_set_midi(int freq, int buf_size)
{
midi_freq = freq;
midi_buf_size = buf_size;
if (initialized && srcvoicemidi)
{
FAudioSourceVoice_Stop(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
FAudioSourceVoice_FlushSourceBuffers(srcvoicemidi);
FAudioVoice_DestroyVoice(srcvoicemidi);
srcvoicemidi = nullptr;
FAudioWaveFormatEx fmt;
fmt.nChannels = 2;
if (sound_is_float)
{
fmt.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
fmt.wBitsPerSample = 32;
}
else
{
fmt.wFormatTag = FAUDIO_FORMAT_PCM;
fmt.wBitsPerSample = 16;
}
fmt.nSamplesPerSec = midi_freq;
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
fmt.cbSize = 0;
FAudio_CreateSourceVoice(faudio, &srcvoicemidi, &fmt, 0, 2.0f, &callbacks, nullptr, nullptr);
FAudioSourceVoice_Start(srcvoicemidi, 0, FAUDIO_COMMIT_NOW);
}
}
void
givealbuffer_midi(void *buf, uint32_t size)
{
givealbuffer_common(buf, srcvoicemidi, size);
}
}