Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add emulated Serial MIDI synthesizer support #305

Merged
merged 63 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
d5f4376
First iteration of MIDI synth support
mooinglemur Sep 19, 2024
a3dd97f
fix some autobuild issues
mooinglemur Sep 19, 2024
c232aeb
adding some debugging
mooinglemur Sep 19, 2024
a8d1a2b
more updates to try to resolve windows builds
mooinglemur Sep 19, 2024
9d847e7
more fixes
mooinglemur Sep 19, 2024
8008b79
more fixes
mooinglemur Sep 19, 2024
aa3249f
perhaps everything will build now
mooinglemur Sep 19, 2024
dac8989
typo of variable name
mooinglemur Sep 19, 2024
385fd47
attempt to fix windows runtime
mooinglemur Sep 19, 2024
3878486
missing semicolon
mooinglemur Sep 19, 2024
ed53b76
switch windows to bind to bundled DLL
mooinglemur Sep 19, 2024
4431b70
additional DLL dependency
mooinglemur Sep 19, 2024
8c49d27
more DLL deps
mooinglemur Sep 19, 2024
b8c6820
another DLL dep
mooinglemur Sep 19, 2024
516928b
go back to dynamic loading for DLL
mooinglemur Sep 19, 2024
dac597b
more DLL deps
mooinglemur Sep 19, 2024
0931369
fix typo
mooinglemur Sep 19, 2024
b7aeac5
more deep DLL deps
mooinglemur Sep 19, 2024
7c67153
macos fix
mooinglemur Sep 19, 2024
a20de95
Static link builds for fluidsynth
mooinglemur Sep 21, 2024
e3c07f3
test
mooinglemur Sep 22, 2024
f0fc780
static lib
mooinglemur Sep 22, 2024
31a8ae8
static lib
mooinglemur Sep 22, 2024
c5c33f5
more testing with custom ubuntu build
mooinglemur Sep 22, 2024
64be681
package name
mooinglemur Sep 22, 2024
a938d40
more testing
mooinglemur Sep 22, 2024
56ad845
test macos
mooinglemur Sep 22, 2024
3bf10e3
test fix macos
mooinglemur Sep 22, 2024
002927f
more static build tests on macos
mooinglemur Sep 22, 2024
b3fc57c
forgot doubled $
mooinglemur Sep 22, 2024
5d3e197
update shell expansion for static libs on mac
mooinglemur Sep 22, 2024
9341874
back to dynamic loading, lets see how this does in the actions
mooinglemur Sep 26, 2024
ad76f2b
full serial port behaviors
mooinglemur Sep 29, 2024
a7f27c8
fix some build problems
mooinglemur Sep 29, 2024
c98aea7
fluidsynth audio now routed into the x16emu mixer rather than creatin…
mooinglemur Sep 30, 2024
8e60973
make midi_synth_render an effective no-op unless the synth is initial…
mooinglemur Sep 30, 2024
00a7bac
external MIDI working, inbound serial working
mooinglemur Oct 1, 2024
5df577e
move handler functions so that wasm will build
mooinglemur Oct 1, 2024
d7b52ff
move handler prototype so that wasm will build
mooinglemur Oct 1, 2024
6214615
Make MIDI card address flexible, add interrupts
mooinglemur Oct 2, 2024
27ed6ac
fix for wasm
mooinglemur Oct 2, 2024
39a105e
adding debug
mooinglemur Oct 3, 2024
0cf6e02
fix interrupt logic
mooinglemur Oct 3, 2024
abd311b
add the ability to select specific MIDI IN, other fixes
mooinglemur Oct 3, 2024
6949905
revert device selection logic
mooinglemur Oct 3, 2024
3f8303b
add -midi-in option back as a toggle
mooinglemur Oct 3, 2024
d4b66a2
fix punctuation in usage
mooinglemur Oct 3, 2024
3e8783a
-midi-in now controls whether the midi driver gets instantiated
mooinglemur Oct 3, 2024
264ee12
Add SysEx handler for midi-in
mooinglemur Oct 4, 2024
8e64857
type fixup
mooinglemur Oct 4, 2024
64f1719
remove debugging, add a bit of error checking
mooinglemur Oct 5, 2024
af5155f
allow building without fluidsynth
mooinglemur Oct 5, 2024
9eaf32b
less lenient Makefile syntax
mooinglemur Oct 5, 2024
fb0cbc0
even less lenient Makefile syntax
mooinglemur Oct 5, 2024
95b81b8
even less lenient Makefile syntax
mooinglemur Oct 5, 2024
8eef604
test makefile on runners
mooinglemur Oct 5, 2024
7144ec1
trying it another way
mooinglemur Oct 5, 2024
c7c5ade
trying something else
mooinglemur Oct 5, 2024
07025ba
update builds for fluidsynth
mooinglemur Oct 5, 2024
ba8af95
fix MAC static SDL2 build
mooinglemur Oct 5, 2024
7263001
some changes for review
mooinglemur Oct 6, 2024
c4e286c
more updates via review, doubled FS level in audio mix
mooinglemur Oct 6, 2024
7ca6c8a
add master volume sysex handling
mooinglemur Oct 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 58 additions & 14 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:
with:
msystem: MINGW64
update: true
install: make git mingw-w64-x86_64-toolchain mingw-w64-x86_64-libelf mingw-w64-x86_64-SDL2
install: make git mingw-w64-x86_64-toolchain mingw-w64-x86_64-libelf mingw-w64-x86_64-SDL2 mingw-w64-x86_64-fluidsynth
- uses: actions/setup-python@v5
with:
python-version: '3.9'
Expand All @@ -65,11 +65,31 @@ jobs:
run: |
git reset --hard
git diff
TRACE=1 CROSS_COMPILE_WINDOWS=1 SDL2CONFIG=sdl2-config make V=1 -j2
TRACE=1 FLUIDSYNTH=1 CROSS_COMPILE_WINDOWS=1 SDL2CONFIG=sdl2-config make V=1 -j2
mkdir emu_binaries
cp $(which SDL2.dll) emu_binaries/.
cp $(which zlib1.dll) emu_binaries/.
cp $(which libwinpthread-1.dll) emu_binaries/.
cp $(which libfluidsynth-3.dll) emu_binaries/.
cp $(which libgcc_s_seh-1.dll) emu_binaries/.
cp $(which libglib-2.0-0.dll) emu_binaries/.
cp $(which libgmodule-2.0-0.dll) emu_binaries/.
cp $(which libportaudio.dll) emu_binaries/.
cp $(which libintl-8.dll) emu_binaries/.
cp $(which libstdc++-6.dll) emu_binaries/.
cp $(which libgomp-1.dll) emu_binaries/.
cp $(which libreadline8.dll) emu_binaries/.
cp $(which libsndfile-1.dll) emu_binaries/.
cp $(which libpcre2-8-0.dll) emu_binaries/.
cp $(which libiconv-2.dll) emu_binaries/.
cp $(which libtermcap-0.dll) emu_binaries/.
cp $(which libFLAC.dll) emu_binaries/.
cp $(which libmp3lame-0.dll) emu_binaries/.
cp $(which libmpg123-0.dll) emu_binaries/.
cp $(which libogg-0.dll) emu_binaries/.
cp $(which libopus-0.dll) emu_binaries/.
cp $(which libvorbis-0.dll) emu_binaries/.
cp $(which libvorbisenc-2.dll) emu_binaries/.
cp sdcard.img.zip emu_binaries/.
cp x16emu.exe emu_binaries/.
cp makecart.exe emu_binaries/.
Expand Down Expand Up @@ -103,7 +123,7 @@ jobs:
with:
msystem: MINGW64
update: true
install: make git mingw-w64-i686-toolchain mingw-w64-i686-libelf mingw-w64-i686-SDL2
install: make git mingw-w64-i686-toolchain mingw-w64-i686-libelf mingw-w64-i686-SDL2 mingw-w64-i686-fluidsynth
path-type: inherit
- uses: actions/setup-python@v5
with:
Expand Down Expand Up @@ -131,11 +151,31 @@ jobs:
run: |
git reset --hard
git diff
TRACE=1 WIN_SDL2=/mingw32 TARGET_CPU=x86 CROSS_COMPILE_WINDOWS=1 make V=1 -j2
TRACE=1 FLUIDSYNTH=1 WIN_SDL2=/mingw32 TARGET_CPU=x86 CROSS_COMPILE_WINDOWS=1 make V=1 -j2
mkdir emu_binaries
cp $(which SDL2.dll) emu_binaries/.
cp $(which zlib1.dll) emu_binaries/.
cp $(which libwinpthread-1.dll) emu_binaries/.
cp $(which libfluidsynth-3.dll) emu_binaries/.
cp $(which libgcc_s_seh-1.dll) emu_binaries/.
cp $(which libglib-2.0-0.dll) emu_binaries/.
cp $(which libgmodule-2.0-0.dll) emu_binaries/.
cp $(which libportaudio.dll) emu_binaries/.
cp $(which libintl-8.dll) emu_binaries/.
cp $(which libstdc++-6.dll) emu_binaries/.
cp $(which libgomp-1.dll) emu_binaries/.
cp $(which libreadline8.dll) emu_binaries/.
cp $(which libsndfile-1.dll) emu_binaries/.
cp $(which libpcre2-8-0.dll) emu_binaries/.
cp $(which libiconv-2.dll) emu_binaries/.
cp $(which libtermcap-0.dll) emu_binaries/.
cp $(which libFLAC.dll) emu_binaries/.
cp $(which libmp3lame-0.dll) emu_binaries/.
cp $(which libmpg123-0.dll) emu_binaries/.
cp $(which libogg-0.dll) emu_binaries/.
cp $(which libopus-0.dll) emu_binaries/.
cp $(which libvorbis-0.dll) emu_binaries/.
cp $(which libvorbisenc-2.dll) emu_binaries/.
cp sdcard.img.zip emu_binaries/.
cp x16emu.exe emu_binaries/.
cp makecart.exe emu_binaries/.
Expand Down Expand Up @@ -165,7 +205,11 @@ jobs:
with:
python-version: '3.9'
- name: Install Dependencies
run: sudo apt-get update && sudo apt-get install -y build-essential make libsdl2-dev
run: |
sudo cp /etc/apt/sources.list /etc/apt/sources.list~
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y build-essential make libsdl2-dev libfluidsynth-dev
- name: Fetch latest ROM
if: startsWith(github.ref, 'refs/tags/r') != true
run: |
Expand All @@ -183,7 +227,7 @@ jobs:
cp latest_rom/*.h src/.
- name: Build Emulator
run: |
TRACE=1 make V=1 -j3
TRACE=1 FLUIDSYNTH=1 make V=1 -j3
mkdir emu_binaries
cp sdcard.img.zip emu_binaries/.
cp x16emu emu_binaries/.
Expand Down Expand Up @@ -241,8 +285,8 @@ jobs:
copy_artifact_path: emu_binaries
commands: |
apt-get update
apt-get install -y build-essential make libsdl2-dev file git
TRACE=1 make V=1 -j3
apt-get install -y build-essential make libsdl2-dev file git libfluidsynth-dev
TRACE=1 FLUIDSYNTH=1 make V=1 -j3
mkdir emu_binaries
cp sdcard.img.zip emu_binaries/.
cp x16emu emu_binaries/.
Expand Down Expand Up @@ -301,8 +345,8 @@ jobs:
copy_artifact_path: emu_binaries
commands: |
apt-get update
apt-get install -y build-essential make libsdl2-dev file git
TRACE=1 make V=1 -j3
apt-get install -y build-essential make libsdl2-dev file git libfluidsynth-dev
TRACE=1 FLUIDSYNTH=1 make V=1 -j3
mkdir emu_binaries
cp sdcard.img.zip emu_binaries/.
cp x16emu emu_binaries/.
Expand Down Expand Up @@ -333,7 +377,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
brew install make sdl2
brew install make sdl2 fluid-synth
- uses: actions/setup-python@v5
with:
python-version: '3.9'
Expand All @@ -354,7 +398,7 @@ jobs:
cp latest_rom/*.h src/.
- name: Build Emulator
run: |
TRACE=1 MAC_STATIC=1 LIBSDL_FILE=/usr/local/Cellar/sdl2/*/lib/libSDL2.a make V=1 -j3
TRACE=1 MAC_STATIC=1 LIBSDL_FILE=/usr/local/Cellar/sdl2/*/lib/libSDL2.a HOMEBREW_LIB=/usr/local/lib make V=1 -j3
mkdir emu_binaries
cp sdcard.img.zip emu_binaries/.
cp x16emu emu_binaries/.
Expand Down Expand Up @@ -383,7 +427,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
brew install make sdl2
brew install make sdl2 fluid-synth
- uses: actions/setup-python@v5
with:
python-version: '3.10'
Expand All @@ -404,7 +448,7 @@ jobs:
cp latest_rom/*.h src/.
- name: Build Emulator
run: |
TRACE=1 MAC_STATIC=1 LIBSDL_FILE=/opt/homebrew/Cellar/sdl2/*/lib/libSDL2.a make V=1 -j3
TRACE=1 MAC_STATIC=1 LIBSDL_FILE=/opt/homebrew/Cellar/sdl2/*/lib/libSDL2.a ADDL_INCLUDE=/opt/homebrew/include HOMEBREW_LIB=/opt/homebrew/lib FLUIDSYNTH=1 make V=1 -j3
mkdir emu_binaries
cp sdcard.img.zip emu_binaries/.
cp x16emu emu_binaries/.
Expand Down
31 changes: 20 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ endif

CFLAGS=-std=c99 -O3 -Wall -Werror -g $(shell $(SDL2CONFIG) --cflags) -Isrc/extern/include
CXXFLAGS=-std=c++17 -O3 -Wall -Werror -Isrc/extern/ymfm/src
LDFLAGS=$(shell $(SDL2CONFIG) --libs) -lm -lz
LDFLAGS=$(shell $(SDL2CONFIG) --libs) -lm -lz -pthread

# build with link time optimization
ifndef NOLTO
CFLAGS+=-flto
LDFLAGS+=-flto
ifdef ADDL_INCLUDE
CFLAGS+=-I$(ADDL_INCLUDE)
endif

X16_ODIR = build/x16emu
Expand All @@ -44,10 +42,9 @@ GIT_REV=$(shell git diff --quiet && /bin/echo -n $$(git rev-parse --short=8 HEAD
CFLAGS+=-D GIT_REV='"$(GIT_REV)"'

ifeq ($(MAC_STATIC),1)
LDFLAGS=$(LIBSDL_FILE) -lm -liconv -lz -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,ForceFeedback -lobjc -Wl,-framework,CoreVideo -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,IOKit -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,Metal -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController
endif

ifeq ($(CROSS_COMPILE_WINDOWS),1)
LDFLAGS=$(LIBSDL_FILE) -lm -liconv -lz -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,ForceFeedback -lobjc -Wl,-framework,CoreVideo -Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,IOKit -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,Metal -Wl,-weak_framework,CoreHaptics -Wl,-weak_framework,GameController -pthread
LDEMU=-ldl -Wl,-rpath,$(HOMEBREW_LIB)
else ifeq ($(CROSS_COMPILE_WINDOWS),1)
LDFLAGS+=-L$(MINGW32)/lib
# this enables printf() to show, but also forces a console window
LDFLAGS+=-Wl,--subsystem,console
Expand All @@ -59,6 +56,14 @@ else
CC=x86_64-w64-mingw32-gcc
CXX=x86_64-w64-mingw32-g++
endif
else # Not Mac, not Windows, probably Linux
LDEMU=-ldl
endif

# build with link time optimization
ifndef NOLTO
CFLAGS+=-flto
LDFLAGS+=-flto
endif

ifdef TARGET_WIN32
Expand All @@ -74,7 +79,11 @@ ifdef EMSCRIPTEN
MAKECART_OUTPUT=makecart.html
endif

_X16_OBJS = cpu/fake6502.o memory.o disasm.o video.o i2c.o smc.o rtc.o via.o serial.o ieee.o vera_spi.o audio.o vera_pcm.o vera_psg.o sdcard.o main.o debugger.o javascript_interface.o joystick.o rendertext.o keyboard.o icon.o timing.o wav_recorder.o testbench.o files.o cartridge.o iso_8859_15.o ymglue.o
ifeq ($(FLUIDSYNTH),1)
CFLAGS+=-DHAS_FLUIDSYNTH
endif

_X16_OBJS = cpu/fake6502.o memory.o disasm.o video.o i2c.o smc.o rtc.o via.o serial.o ieee.o vera_spi.o audio.o vera_pcm.o vera_psg.o sdcard.o main.o debugger.o javascript_interface.o joystick.o rendertext.o keyboard.o icon.o timing.o wav_recorder.o testbench.o files.o cartridge.o iso_8859_15.o ymglue.o midi.o
_X16_OBJS += extern/ymfm/src/ymfm_opm.o

ifdef TARGET_WIN32
Expand All @@ -93,7 +102,7 @@ MAKECART_DEPS := $(MAKECART_OBJS:.o=.d)
all: x16emu makecart

x16emu: $(X16_OBJS)
$(CXX) -o $(X16_OUTPUT) $(X16_OBJS) $(LDFLAGS)
$(CXX) -o $(X16_OUTPUT) $(X16_OBJS) $(LDFLAGS) $(LDEMU)

$(X16_ODIR)/%.o: $(X16_SDIR)/%.c
@mkdir -p $$(dirname $@)
Expand Down
67 changes: 62 additions & 5 deletions src/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "vera_pcm.h"
#include "wav_recorder.h"
#include "ymglue.h"
#include "midi.h"
#include <stdint.h>
#include <stdio.h>
#include <string.h>
Expand All @@ -23,6 +24,7 @@

#define VERA_SAMP_CLKS_PER_CPU_CLK ((25000000ULL << SAMP_POS_FRAC_BITS) / 512 / MHZ / 1000000)
#define YM_SAMP_CLKS_PER_CPU_CLK ((3579545ULL << SAMP_POS_FRAC_BITS) / 64 / MHZ / 1000000)
#define FS_SAMP_CLKS_PER_CPU_CLK VERA_SAMP_CLKS_PER_CPU_CLK
#define SAMPLE_BYTES (2 * sizeof(int16_t))
#define SAMP_POS_MASK (SAMPLES_PER_BUFFER - 1)
#define SAMP_POS_MASK_FRAC (((uint32_t)SAMPLES_PER_BUFFER << SAMP_POS_FRAC_BITS) - 1)
Expand Down Expand Up @@ -75,13 +77,18 @@ static uint32_t vera_samp_pos_hd = 0;
static uint32_t ym_samp_pos_rd = 0;
static uint32_t ym_samp_pos_wr = 0;
static uint32_t ym_samp_pos_hd = 0;
static uint32_t fs_samp_pos_rd = 0;
static uint32_t fs_samp_pos_wr = 0;
static uint32_t fs_samp_pos_hd = 0;
static uint32_t vera_samps_per_host_samps = 0;
static uint32_t ym_samps_per_host_samps = 0;
static uint32_t fs_samps_per_host_samps = 0;
static uint32_t limiter_amp = 0;

static int16_t psg_buf[2 * SAMPLES_PER_BUFFER];
static int16_t pcm_buf[2 * SAMPLES_PER_BUFFER];
static int16_t ym_buf[2 * SAMPLES_PER_BUFFER];
static int16_t fs_buf[2 * SAMPLES_PER_BUFFER];

uint32_t host_sample_rate = 0;

Expand Down Expand Up @@ -181,17 +188,22 @@ audio_init(const char *dev_name, int num_audio_buffers)
host_sample_rate = obtained.freq;
vera_samps_per_host_samps = ((25000000ULL << SAMP_POS_FRAC_BITS) / 512 / host_sample_rate);
ym_samps_per_host_samps = ((3579545ULL << SAMP_POS_FRAC_BITS) / 64 / host_sample_rate);
fs_samps_per_host_samps = vera_samps_per_host_samps;
vera_samp_pos_rd = 0;
vera_samp_pos_wr = 0;
vera_samp_pos_hd = 0;
ym_samp_pos_rd = 0;
ym_samp_pos_wr = 0;
ym_samp_pos_hd = 0;
fs_samp_pos_rd = 0;
fs_samp_pos_wr = 0;
fs_samp_pos_hd = 0;
limiter_amp = (1 << 16);

psg_buf[0] = psg_buf[1] = 0;
pcm_buf[0] = pcm_buf[1] = 0;
ym_buf[0] = ym_buf[1] = 0;
fs_buf[0] = fs_buf[1] = 0;

// Start playback
SDL_PauseAudioDevice(audio_dev, 0);
Expand Down Expand Up @@ -228,6 +240,7 @@ audio_step(int cpu_clocks)
uint32_t max_cpu_clks = SDL_min(cpu_clocks, max_cpu_clks_ym);
vera_samp_pos_hd = (vera_samp_pos_hd + max_cpu_clks * VERA_SAMP_CLKS_PER_CPU_CLK) & SAMP_POS_MASK_FRAC;
ym_samp_pos_hd = (ym_samp_pos_hd + max_cpu_clks * YM_SAMP_CLKS_PER_CPU_CLK) & SAMP_POS_MASK_FRAC;
fs_samp_pos_hd = (fs_samp_pos_hd + max_cpu_clks * FS_SAMP_CLKS_PER_CPU_CLK) & SAMP_POS_MASK_FRAC;
cpu_clocks -= max_cpu_clks;
if (cpu_clocks > 0) audio_render();
}
Expand Down Expand Up @@ -271,16 +284,31 @@ audio_render()
YM_stream_update((uint16_t *)&ym_buf[pos * 2], len);
}

pos = (fs_samp_pos_wr + 1) & SAMP_POS_MASK;
len = ((fs_samp_pos_hd >> SAMP_POS_FRAC_BITS) - fs_samp_pos_wr) & SAMP_POS_MASK;
fs_samp_pos_wr = fs_samp_pos_hd >> SAMP_POS_FRAC_BITS;
if ((pos + len) > SAMPLES_PER_BUFFER) {
midi_synth_render(&fs_buf[pos * 2], SAMPLES_PER_BUFFER - pos);
len -= SAMPLES_PER_BUFFER - pos;
pos = 0;
}
if (len > 0) {
midi_synth_render(&fs_buf[pos * 2], len);
}

uint32_t wridx_old = wridx;
uint32_t len_vera = (vera_samp_pos_hd - vera_samp_pos_rd) & SAMP_POS_MASK_FRAC;
uint32_t len_ym = (ym_samp_pos_hd - ym_samp_pos_rd) & SAMP_POS_MASK_FRAC;
if (len_vera < (4 << SAMP_POS_FRAC_BITS) || len_ym < (4 << SAMP_POS_FRAC_BITS)) {
uint32_t len_fs = (fs_samp_pos_hd - fs_samp_pos_rd) & SAMP_POS_MASK_FRAC;
if (len_vera < (4 << SAMP_POS_FRAC_BITS) || len_ym < (4 << SAMP_POS_FRAC_BITS) || len_fs < (4 << SAMP_POS_FRAC_BITS)) {
// not enough samples yet, at least 4 are needed for the filter
return;
}
len_vera = (len_vera - (4 << SAMP_POS_FRAC_BITS)) / vera_samps_per_host_samps;
len_ym = (len_ym - (4 << SAMP_POS_FRAC_BITS)) / ym_samps_per_host_samps;
len_fs = (len_fs - (4 << SAMP_POS_FRAC_BITS)) / fs_samps_per_host_samps;
len = SDL_min(len_vera, len_ym);
len = SDL_min(len, len_fs);
SDL_LockAudioDevice(audio_dev);
for (int i = 0; i < len; i++) {
int32_t samp[8];
Expand All @@ -289,6 +317,8 @@ audio_render()
int32_t vera_out_r = 0;
int32_t ym_out_l = 0;
int32_t ym_out_r = 0;
int32_t fs_out_l = 0;
int32_t fs_out_r = 0;
// Don't resample VERA outputs if the host sample rate is as desired
if (host_sample_rate == AUDIO_SAMPLERATE) {
pos = (vera_samp_pos_rd >> SAMP_POS_FRAC_BITS) * 2;
Expand Down Expand Up @@ -326,11 +356,33 @@ audio_render()
ym_out_r += samp[5] * filter[255 - filter_idx];
ym_out_l += samp[6] * filter[511 - filter_idx];
ym_out_r += samp[7] * filter[511 - filter_idx];
// Mixing is according to the Developer Board
// Don't resample MIDI synth outputs if the host sample rate matches it
if (host_sample_rate == AUDIO_SAMPLERATE) {
pos = (fs_samp_pos_rd >> SAMP_POS_FRAC_BITS) * 2;
fs_out_l = (uint32_t)fs_buf[pos] << 14;
fs_out_r = (uint32_t)fs_buf[pos + 1] << 14;
} else {
filter_idx = (fs_samp_pos_rd >> (SAMP_POS_FRAC_BITS - 8)) & 0xff;
pos = (fs_samp_pos_rd >> SAMP_POS_FRAC_BITS) * 2;
for (int j = 0; j < 8; j += 2) {
samp[j] = fs_buf[pos];
samp[j + 1] = fs_buf[pos + 1];
pos = (pos + 2) & (SAMP_POS_MASK * 2);
}
fs_out_l += samp[0] * filter[256 + filter_idx];
fs_out_r += samp[1] * filter[256 + filter_idx];
fs_out_l += samp[2] * filter[ 0 + filter_idx];
fs_out_r += samp[3] * filter[ 0 + filter_idx];
fs_out_l += samp[4] * filter[255 - filter_idx];
fs_out_r += samp[5] * filter[255 - filter_idx];
fs_out_l += samp[6] * filter[511 - filter_idx];
fs_out_r += samp[7] * filter[511 - filter_idx];
}
// VERA+YM mixing is according to the Developer Board
// Loudest single PSG channel is 1/8 times the max output
// mix = (psg + pcm) * 2 + ym
int32_t mix_l = (vera_out_l >> 13) + (ym_out_l >> 15);
int32_t mix_r = (vera_out_r >> 13) + (ym_out_r >> 15);
// mix = (psg + pcm) * 2 + ym + fs * 4
int32_t mix_l = (vera_out_l >> 13) + (ym_out_l >> 15) + (fs_out_l >> 12);
int32_t mix_r = (vera_out_r >> 13) + (ym_out_r >> 15) + (fs_out_r >> 12);
uint32_t amp = SDL_max(SDL_abs(mix_l), SDL_abs(mix_r));
if (amp > 32767) {
uint32_t limiter_amp_new = (32767 << 16) / amp;
Expand All @@ -341,6 +393,7 @@ audio_render()
if (limiter_amp < (1 << 16)) limiter_amp++;
vera_samp_pos_rd = (vera_samp_pos_rd + vera_samps_per_host_samps) & SAMP_POS_MASK_FRAC;
ym_samp_pos_rd = (ym_samp_pos_rd + ym_samps_per_host_samps) & SAMP_POS_MASK_FRAC;
fs_samp_pos_rd = (fs_samp_pos_rd + fs_samps_per_host_samps) & SAMP_POS_MASK_FRAC;
if (wridx == buffer_size) {
wav_recorder_process(&buffer[wridx_old], (buffer_size - wridx_old) / 2);
wridx = 0;
Expand Down Expand Up @@ -368,6 +421,10 @@ audio_render()
if (skip > 1) {
ym_samp_pos_rd = (ym_samp_pos_rd + ym_samps_per_host_samps) & SAMP_POS_MASK_FRAC;
}
skip = len_fs - len;
if (skip > 1) {
fs_samp_pos_rd = (fs_samp_pos_rd + fs_samps_per_host_samps) & SAMP_POS_MASK_FRAC;
}
}

void
Expand Down
Loading
Loading