Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -32,3 +32,7 @@ indent_size = 4
|
||||
[*.cmake]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
90
.github/workflows/cmake.yml
vendored
90
.github/workflows/cmake.yml
vendored
@@ -35,10 +35,10 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
- name: Regular ODR
|
||||
slug: -ODR
|
||||
preset: regular
|
||||
target: install/strip
|
||||
# - name: Regular ODR
|
||||
# slug: -ODR
|
||||
# preset: regular
|
||||
# target: install/strip
|
||||
- name: Debug ODR
|
||||
slug: -ODR-Debug
|
||||
preset: debug
|
||||
@@ -47,10 +47,10 @@ jobs:
|
||||
slug: -ODR-Dev
|
||||
preset: experimental
|
||||
target: install
|
||||
- name: Regular NDR
|
||||
slug: -NDR
|
||||
preset: regularndr
|
||||
target: install/strip
|
||||
# - name: Regular NDR
|
||||
# slug: -NDR
|
||||
# preset: regularndr
|
||||
# target: install/strip
|
||||
- name: Debug NDR
|
||||
slug: -NDR-Debug
|
||||
preset: debugndr
|
||||
@@ -114,12 +114,12 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
- name: Regular ODR
|
||||
slug: -ODR
|
||||
type: Release
|
||||
dev-build: off
|
||||
new-dynarec: off
|
||||
strip: --strip
|
||||
# - name: Regular ODR
|
||||
# slug: -ODR
|
||||
# type: Release
|
||||
# dev-build: off
|
||||
# new-dynarec: off
|
||||
# strip: --strip
|
||||
- name: Debug ODR
|
||||
slug: -ODR-Debug
|
||||
type: Debug
|
||||
@@ -130,12 +130,12 @@ jobs:
|
||||
type: Debug
|
||||
dev-build: on
|
||||
new-dynarec: off
|
||||
- name: Regular NDR
|
||||
slug: -NDR
|
||||
type: Release
|
||||
strip: --strip
|
||||
dev-build: off
|
||||
new-dynarec: on
|
||||
# - name: Regular NDR
|
||||
# slug: -NDR
|
||||
# type: Release
|
||||
# strip: --strip
|
||||
# dev-build: off
|
||||
# new-dynarec: on
|
||||
- name: Debug NDR
|
||||
slug: -NDR-Debug
|
||||
type: Debug
|
||||
@@ -210,18 +210,18 @@ jobs:
|
||||
linux:
|
||||
name: "Linux GCC 11 (${{ matrix.build.name }} x86_64)"
|
||||
|
||||
runs-on: ubuntu-2004
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
strategy:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
- name: Regular ODR
|
||||
slug: -ODR
|
||||
type: Release
|
||||
dev-build: off
|
||||
new-dynarec: off
|
||||
strip: --strip
|
||||
# - name: Regular ODR
|
||||
# slug: -ODR
|
||||
# type: Release
|
||||
# dev-build: off
|
||||
# new-dynarec: off
|
||||
# strip: --strip
|
||||
- name: Debug ODR
|
||||
slug: -ODR-Debug
|
||||
type: Debug
|
||||
@@ -232,12 +232,12 @@ jobs:
|
||||
type: Debug
|
||||
dev-build: on
|
||||
new-dynarec: off
|
||||
- name: Regular NDR
|
||||
slug: -NDR
|
||||
type: Release
|
||||
strip: --strip
|
||||
dev-build: off
|
||||
new-dynarec: on
|
||||
# - name: Regular NDR
|
||||
# slug: -NDR
|
||||
# type: Release
|
||||
# strip: --strip
|
||||
# dev-build: off
|
||||
# new-dynarec: on
|
||||
- name: Debug NDR
|
||||
slug: -NDR-Debug
|
||||
type: Debug
|
||||
@@ -280,12 +280,12 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
build:
|
||||
- name: Regular ODR
|
||||
slug: -ODR
|
||||
type: Release
|
||||
dev-build: off
|
||||
new-dynarec: off
|
||||
strip: --strip
|
||||
# - name: Regular ODR
|
||||
# slug: -ODR
|
||||
# type: Release
|
||||
# dev-build: off
|
||||
# new-dynarec: off
|
||||
# strip: --strip
|
||||
- name: Debug ODR
|
||||
slug: -ODR-Debug
|
||||
type: Debug
|
||||
@@ -296,12 +296,12 @@ jobs:
|
||||
type: Debug
|
||||
dev-build: on
|
||||
new-dynarec: off
|
||||
- name: Regular NDR
|
||||
slug: -NDR
|
||||
type: Release
|
||||
strip: --strip
|
||||
dev-build: off
|
||||
new-dynarec: on
|
||||
# - name: Regular NDR
|
||||
# slug: -NDR
|
||||
# type: Release
|
||||
# strip: --strip
|
||||
# dev-build: off
|
||||
# new-dynarec: on
|
||||
- name: Debug NDR
|
||||
slug: -NDR-Debug
|
||||
type: Debug
|
||||
|
@@ -115,6 +115,7 @@ set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
|
||||
option(RELEASE "Release build" OFF)
|
||||
option(DYNAREC "Dynamic recompiler" ON)
|
||||
option(OPENAL "OpenAL" ON)
|
||||
option(FAUDIO "FAudio" OFF)
|
||||
option(FLUIDSYNTH "FluidSynth" ON)
|
||||
option(MUNT "MUNT" ON)
|
||||
option(DINPUT "DirectInput" OFF)
|
||||
|
@@ -86,7 +86,12 @@ if(APPLE)
|
||||
target_link_libraries(86Box Freetype::Freetype)
|
||||
endif()
|
||||
|
||||
if(OPENAL)
|
||||
if(FAUDIO)
|
||||
find_package(FAudio REQUIRED)
|
||||
target_link_libraries(86Box FAudio::FAudio)
|
||||
endif()
|
||||
|
||||
if(OPENAL AND NOT FAUDIO)
|
||||
if(VCPKG_TOOLCHAIN)
|
||||
find_package(OpenAL CONFIG REQUIRED)
|
||||
elseif(MINGW)
|
||||
|
@@ -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_type}" NAME)
|
||||
set(_qt_plugin_dest "${_prefix}/PlugIns/${_qt_plugin_type}")
|
||||
install(FILES "${_qt_plugin_path}"
|
||||
DESTINATION "${_qt_plugin_dest}")
|
||||
list(APPEND ${_qt_plugins_var} "${_qt_plugin_dest}/${_qt_plugin_file}")
|
||||
install(FILES "${_qt_plugin_path}" DESTINATION "${_qt_plugin_dest}")
|
||||
list(APPEND ${_qt_plugins_var} "\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/${_qt_plugin_dest}/${_qt_plugin_file}")
|
||||
else()
|
||||
message(FATAL_ERROR "QT plugin ${_qt_plugin_name} not found")
|
||||
endif()
|
||||
@@ -245,11 +244,7 @@ if (APPLE AND CMAKE_MACOSX_BUNDLE)
|
||||
install(CODE "
|
||||
include(BundleUtilities)
|
||||
get_filename_component(CMAKE_INSTALL_PREFIX_ABSOLUTE \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX} ABSOLUTE)
|
||||
foreach(PLUGIN ${QT_PLUGINS})
|
||||
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}\")")
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX_ABSOLUTE}/86Box.app\" \"${QT_PLUGINS}\" \"${DIRS}\")")
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
|
@@ -19,9 +19,13 @@ 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_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_sources(snd PRIVATE openal.c)
|
||||
if (FAUDIO)
|
||||
target_sources(snd PRIVATE faudio.cpp)
|
||||
else()
|
||||
target_sources(snd PRIVATE openal.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FLUIDSYNTH)
|
||||
@@ -60,4 +64,4 @@ if(TANDY_ISA)
|
||||
endif()
|
||||
|
||||
add_subdirectory(resid-fp)
|
||||
target_link_libraries(86Box resid-fp)
|
||||
target_link_libraries(86Box resid-fp)
|
||||
|
219
src/sound/faudio.cpp
Normal file
219
src/sound/faudio.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
66
vcpkg.json
66
vcpkg.json
@@ -1,35 +1,35 @@
|
||||
{
|
||||
"name": "86box",
|
||||
"version-string": "3.1",
|
||||
"homepage": "https://86box.net/",
|
||||
"documentation": "http://86box.readthedocs.io/",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"dependencies": [
|
||||
"freetype",
|
||||
"libpng",
|
||||
"openal-soft",
|
||||
"sdl2",
|
||||
"rtmidi"
|
||||
],
|
||||
"features": {
|
||||
"qt-ui": {
|
||||
"description": "Qt User Interface",
|
||||
"dependencies": [
|
||||
"qt5-base",
|
||||
"qt5-translations"
|
||||
]
|
||||
},
|
||||
"munt": {
|
||||
"description": "Roland MT-32 emulation",
|
||||
"dependencies": [
|
||||
"libmt32emu"
|
||||
]
|
||||
},
|
||||
"slirp": {
|
||||
"description": "Slirp network support",
|
||||
"dependencies": [
|
||||
"libslirp"
|
||||
]
|
||||
}
|
||||
}
|
||||
"name": "86box",
|
||||
"version-string": "3.1",
|
||||
"homepage": "https://86box.net/",
|
||||
"documentation": "http://86box.readthedocs.io/",
|
||||
"license": "GPL-2.0-or-later",
|
||||
"dependencies": [
|
||||
"freetype",
|
||||
"libpng",
|
||||
"openal-soft",
|
||||
"sdl2",
|
||||
"rtmidi"
|
||||
],
|
||||
"features": {
|
||||
"qt-ui": {
|
||||
"description": "Qt User Interface",
|
||||
"dependencies": [
|
||||
"qt5-base",
|
||||
"qt5-translations"
|
||||
]
|
||||
},
|
||||
"munt": {
|
||||
"description": "Roland MT-32 emulation",
|
||||
"dependencies": [
|
||||
"libmt32emu"
|
||||
]
|
||||
},
|
||||
"slirp": {
|
||||
"description": "Slirp network support",
|
||||
"dependencies": [
|
||||
"libslirp"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user