Merge branch '86Box:master' into nec-v20

This commit is contained in:
Jasmine Iwanek
2022-02-19 18:16:49 -05:00
committed by GitHub
7 changed files with 273 additions and 45 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

@@ -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,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_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)
target_sources(snd PRIVATE openal.c) if (FAUDIO)
target_sources(snd PRIVATE faudio.cpp)
else()
target_sources(snd PRIVATE openal.c)
endif()
endif() endif()
if(FLUIDSYNTH) if(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);
}
}

View File

@@ -1,35 +1,35 @@
{ {
"name": "86box", "name": "86box",
"version-string": "3.1", "version-string": "3.1",
"homepage": "https://86box.net/", "homepage": "https://86box.net/",
"documentation": "http://86box.readthedocs.io/", "documentation": "http://86box.readthedocs.io/",
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"dependencies": [ "dependencies": [
"freetype", "freetype",
"libpng", "libpng",
"openal-soft", "openal-soft",
"sdl2", "sdl2",
"rtmidi" "rtmidi"
], ],
"features": { "features": {
"qt-ui": { "qt-ui": {
"description": "Qt User Interface", "description": "Qt User Interface",
"dependencies": [ "dependencies": [
"qt5-base", "qt5-base",
"qt5-translations" "qt5-translations"
] ]
}, },
"munt": { "munt": {
"description": "Roland MT-32 emulation", "description": "Roland MT-32 emulation",
"dependencies": [ "dependencies": [
"libmt32emu" "libmt32emu"
] ]
}, },
"slirp": { "slirp": {
"description": "Slirp network support", "description": "Slirp network support",
"dependencies": [ "dependencies": [
"libslirp" "libslirp"
] ]
} }
} }
} }