# The MIT License (MIT)
#
# Copyright (C) 2026 Scott Duensing
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

# Sound library suite: audio.lib compiled from its sources (without its
# shell hooks, which the test replaces by calling audioIdle and
# audioAppEnded) plus the Sound Blaster driver's arithmetic.  The mixer
# is checked bit for bit against golden/mixer.txt (UPDATE_GOLDENS=1
# rewrites it), the WAV / VOC decoder against good and damaged files, and
# driver discovery against fake drivers (fakeDrv.c, and fakeSynth.c for
# the FM chip and the MIDI port) built as .drv shared objects into the
# work tree the test runs in.

include ../dvxtest/dvxtest.mk

.DEFAULT_GOAL := all

AUDIO_DIR  = $(DVXTEST_ROOT)/src/libs/kpunch/audio
BINDIR     = $(DVXTEST_BINDIR)/audio
AUDIO_TEST = $(BINDIR)/audioTest
WORKDIR    = $(BINDIR)/work
DRVDIR     = $(WORKDIR)/libs/kpunch/audio/drivers
GOLDEN     = $(abspath golden/mixer.txt)

AUDIO_SRCS = $(filter-out $(AUDIO_DIR)/audioShell.c,$(wildcard $(AUDIO_DIR)/*.c)) $(AUDIO_DIR)/drivers/sb/sbCalc.c
AUDIO_OBJS = $(patsubst $(AUDIO_DIR)/%.c,$(BINDIR)/lib/%.o,$(AUDIO_SRCS))
LIBS_A     = $(DVXTEST_ARCHIVES)

CFLAGS     = $(DVXTEST_CFLAGS) -I$(AUDIO_DIR) -I$(AUDIO_DIR)/drivers/sb -I$(DVXTEST_ROOT)/src/libs/kpunch -DAUDIO_GOLDEN='"$(GOLDEN)"' -DAUDIO_WORKDIR='"$(WORKDIR)"'

# The fake drivers: name, priority, open / play succeed, rate, bits,
# channels, DAC, tone generator, clocked
FAKE_DEFS  = -DFAKE_CLOCK=0 -DFAKE_TONE=0 -DFAKE_DAC=1 -DFAKE_RATE=22050 -DFAKE_BITS=16 -DFAKE_CHANNELS=2 -DFAKE_OPEN_OK=1 -DFAKE_PLAY_OK=1
FAKE_alpha  = -DFAKE_NAME='"alpha"' -DFAKE_PRIORITY=50 -UFAKE_OPEN_OK -DFAKE_OPEN_OK=0
FAKE_beta   = -DFAKE_NAME='"beta"' -DFAKE_PRIORITY=40 -UFAKE_PLAY_OK -DFAKE_PLAY_OK=0
FAKE_gamma  = -DFAKE_NAME='"gamma"' -DFAKE_PRIORITY=30
FAKE_delta  = -DFAKE_NAME='"delta"' -DFAKE_PRIORITY=20 -UFAKE_DAC -DFAKE_DAC=0 -UFAKE_TONE -DFAKE_TONE=1 -UFAKE_CLOCK -DFAKE_CLOCK=1 -UFAKE_RATE -DFAKE_RATE=11025 -UFAKE_BITS -DFAKE_BITS=8 -UFAKE_CHANNELS -DFAKE_CHANNELS=1
FAKE_mono8  = -DFAKE_NAME='"mono8"' -DFAKE_PRIORITY=10 -UFAKE_BITS -DFAKE_BITS=8 -UFAKE_CHANNELS -DFAKE_CHANNELS=1
FAKE_badabi = -DFAKE_NAME='"badabi"' -DFAKE_PRIORITY=90 -DFAKE_BAD_ABI
FAKE_nodesc = -DFAKE_NO_DESC
FAKES      = alpha beta gamma delta mono8 badabi nodesc
FAKE_DRVS  = $(patsubst %,$(DRVDIR)/%.drv,$(FAKES)) $(DRVDIR)/fmfake.drv $(DRVDIR)/midifake.drv

.PHONY: all run clean

all: run

$(BINDIR)/lib/%.o: $(AUDIO_DIR)/%.c $(DVX_MAKEFILES)
	@mkdir -p $(dir $@)
	$(HOSTCC) $(CFLAGS) -c -o $@ $<

$(DRVDIR)/%.drv: fakeDrv.c $(AUDIO_DIR)/audioDrv.h $(DVX_MAKEFILES)
	@mkdir -p $(DRVDIR)
	$(HOSTCC) $(CFLAGS) -shared $(FAKE_DEFS) $(FAKE_$*) -o $@ fakeDrv.c

# The fake synthesizers (fakeSynth.c): an FM chip and a MIDI port
$(DRVDIR)/fmfake.drv: fakeSynth.c $(AUDIO_DIR)/audioDrv.h $(DVX_MAKEFILES)
	@mkdir -p $(DRVDIR)
	$(HOSTCC) $(CFLAGS) -shared -DFAKE_SYN_FM -o $@ fakeSynth.c

$(DRVDIR)/midifake.drv: fakeSynth.c $(AUDIO_DIR)/audioDrv.h $(DVX_MAKEFILES)
	@mkdir -p $(DRVDIR)
	$(HOSTCC) $(CFLAGS) -shared -o $@ fakeSynth.c

$(AUDIO_TEST): audioTest.c $(AUDIO_OBJS) $(DVX_MAKEFILES) $(LIBS_A) | dvxtest-libs
	@mkdir -p $(BINDIR)
	$(HOSTCC) $(CFLAGS) -o $@ $< $(AUDIO_OBJS) $(DVXTEST_LINK)

-include $(AUDIO_OBJS:.o=.d) $(AUDIO_TEST).d $(FAKE_DRVS:.drv=.d)

run: $(AUDIO_TEST) $(FAKE_DRVS)
	cd $(BINDIR) && ASAN_OPTIONS=detect_leaks=1 ./audioTest

clean:
	rm -rf $(BINDIR)
