diff --git a/DEVELOPERS b/DEVELOPERS index 9f115d9f2f..42d08f7fc7 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -1747,6 +1747,8 @@ F: support/testing/tests/package/test_compressor_base.py F: support/testing/tests/package/test_ddrescue.py F: support/testing/tests/package/test_ddrescue/ F: support/testing/tests/package/test_dos2unix.py +F: support/testing/tests/package/test_fluidsynth.py +F: support/testing/tests/package/test_fluidsynth/ F: support/testing/tests/package/test_gawk.py F: support/testing/tests/package/test_glslsandbox_player.py F: support/testing/tests/package/test_glslsandbox_player/ diff --git a/support/testing/tests/package/test_fluidsynth.py b/support/testing/tests/package/test_fluidsynth.py new file mode 100644 index 0000000000..20d4da0c50 --- /dev/null +++ b/support/testing/tests/package/test_fluidsynth.py @@ -0,0 +1,61 @@ +import os + +import infra.basetest + + +class TestFluidsynth(infra.basetest.BRTest): + # infra.basetest.BASIC_TOOLCHAIN_CONFIG cannot be used as it is + # armv5 and based on qemu versatilepb which is limited to 256MB of + # RAM. The test needs 1GB of RAM (larger initrd and soundfont is + # loaded in memory). + config = \ + """ + BR2_aarch64=y + BR2_TOOLCHAIN_EXTERNAL=y + BR2_TARGET_GENERIC_GETTY_PORT="ttyAMA0" + BR2_LINUX_KERNEL=y + BR2_LINUX_KERNEL_CUSTOM_VERSION=y + BR2_LINUX_KERNEL_CUSTOM_VERSION_VALUE="5.15.86" + BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y + BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="board/qemu/aarch64-virt/linux.config" + BR2_LINUX_KERNEL_NEEDS_HOST_OPENSSL=y + BR2_PACKAGE_AUBIO=y + BR2_PACKAGE_FLUIDSYNTH=y + BR2_PACKAGE_FLUIDSYNTH_LIBSNDFILE=y + BR2_PACKAGE_FLUID_SOUNDFONT=y + BR2_PACKAGE_PYTHON3=y + BR2_PACKAGE_PYTHON_MIDIUTIL=y + BR2_ROOTFS_OVERLAY="{}" + BR2_TARGET_ROOTFS_CPIO=y + # BR2_TARGET_ROOTFS_TAR is not set + """.format( + # overlay to add helper test scripts + infra.filepath("tests/package/test_fluidsynth/rootfs-overlay")) + + def test_run(self): + img = os.path.join(self.builddir, "images", "rootfs.cpio") + kern = os.path.join(self.builddir, "images", "Image") + self.emulator.boot(arch="aarch64", + kernel=kern, + kernel_cmdline=["console=ttyAMA0"], + options=["-M", "virt", "-cpu", "cortex-a57", "-m", "1G", "-initrd", img]) + self.emulator.login() + + # Test the binary executes + self.assertRunOk("fluidsynth --version") + + # Create a simple MIDI file programmatically + self.assertRunOk("/root/gen_midi_file.py /tmp/output.mid") + + # Convert the MIDI file to a WAV file + cmd = "fluidsynth" + cmd += " -F /tmp/output.wav" + cmd += " /usr/share/soundfonts/FluidR3_GM.sf2" + cmd += " /tmp/output.mid" + self.assertRunOk(cmd) + + # Extract notes in the WAV file with Aubio + self.assertRunOk("aubionotes /tmp/output.wav > /tmp/notes.txt") + + # Check the extracted notes are the expected ones + self.assertRunOk("/root/check_notes.py < /tmp/notes.txt") diff --git a/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/check_notes.py b/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/check_notes.py new file mode 100755 index 0000000000..7301e14a9f --- /dev/null +++ b/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/check_notes.py @@ -0,0 +1,24 @@ +#! /usr/bin/env python3 +# +# This script reads the output of the "aubionotes" command and +# validates it contains three expected notes (A2, E3, A3) in the +# correct order. Silences or other notes are allowed in between those +# notes, to allow some flexibility. + +import sys + +found = 0 +notes = [57, 64, 69] + +for line in sys.stdin: + fields = line.split() + if len(fields) >= 1: + value = round(float(fields[0])) + if value == notes[found]: + found += 1 + if found == len(notes): + print("Found all notes") + sys.exit(0) + +print("Error: all notes not found") +sys.exit(1) diff --git a/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/gen_midi_file.py b/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/gen_midi_file.py new file mode 100755 index 0000000000..aa53a25af3 --- /dev/null +++ b/support/testing/tests/package/test_fluidsynth/rootfs-overlay/root/gen_midi_file.py @@ -0,0 +1,23 @@ +#! /usr/bin/env python3 +# +# This script generates a MIDI file with only 3 notes: A2, E3, A3 +# usage: gen_midi_file.py [output-filename] + +import sys + +from midiutil import MIDIFile + +output_filename = "output.mid" +if len(sys.argv) >= 2: + output_filename = sys.argv[1] + +notes = [57, 64, 69] # A2, E3, A3 + +midi = MIDIFile() +midi.addTempo(track=0, time=0, tempo=60) + +for i, p in enumerate(notes): + midi.addNote(track=0, channel=0, pitch=p, time=i, duration=1, volume=100) + +with open(output_filename, "wb") as output_file: + midi.writeFile(output_file)