From e0c67124a621321ef20fbfd460e79a0fea063740 Mon Sep 17 00:00:00 2001 From: stonedDiscord Date: Fri, 25 Mar 2022 13:58:59 +0100 Subject: [PATCH] Midi music (#614) * add bassmidi everywhere but CI * hello CI please don't ban me from github * add lib and open midi files with the lib * overlooked windows CI * yes, overwrite everything * add tracker support * add file formats that bass supports * forgot .mid smh * load all plugins in one function --- .github/workflows/build.yml | 6 + .github/workflows/test.yml | 3 + .gitlab-ci.yml | 16 +- Attorney_Online.pro | 1 + CMakeLists.txt | 2 +- include/CMakeLists.txt | 1 + include/aoapplication.h | 3 +- include/aomusicplayer.h | 1 + include/bassmidi.h | 380 ++++++++++++++++++++++++++++++++++++ scripts/configure_macos.sh | 5 + scripts/configure_ubuntu.sh | 3 + scripts/macos_build.sh | 4 + src/aoapplication.cpp | 25 +-- src/aomusicplayer.cpp | 6 + src/text_file_functions.cpp | 2 +- test/CMakeLists.txt | 2 +- test/test_bass.cpp | 1 + 17 files changed, 441 insertions(+), 20 deletions(-) create mode 100644 include/bassmidi.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ca38b7..c1c2291 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,6 +38,11 @@ jobs: unzip bass.zip cp ./c/x64/bass.lib ./lib + # BASS MIDI + curl http://www.un4seen.com/files/bassmidi24.zip -o bassmidi.zip + unzip bassmidi.zip + cp ./c/x64/bassmidi.lib ./lib + # BASS Opus curl http://www.un4seen.com/files/bassopus24.zip -o bassopus.zip unzip bassopus.zip @@ -77,6 +82,7 @@ jobs: cp ../../msvc2017_64/plugins/imageformats/qapng.dll ./imageformats/ cp ../../discord-rpc/win64-dynamic/bin/discord-rpc.dll . cp ../../x64/bass.dll . + cp ../../x64/bassmidi.dll . cp ../../x64/bassopus.dll . - name: Upload Artifact diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4350a7c..0ef8695 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,14 +31,17 @@ jobs: run: | # Download curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip + curl http://www.un4seen.com/files/bassmidi24-linux.zip -o bassmidi_linux.zip curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip # Extract unzip bass_linux.zip + unzip bassmidi_linux.zip unzip bassopus_linux.zip unzip discord_rpc_linux.zip # Copy cp x64/libbass.so lib + cp x64/libbassmidi.so lib cp x64/libbassopus.so lib cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so lib diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0230d40..0aa9662 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,10 +35,13 @@ build linux x86_64: - mkdir bass - cd bass - curl http://www.un4seen.com/files/bass24-linux.zip -o bass.zip - - unzip bass.zip + - unzip -o bass.zip - cp x64/libbass.so ../lib + - curl http://www.un4seen.com/files/bassmidi24-linux.zip -o bassmidi.zip + - unzip -o bassmidi.zip + - cp x64/libbassmidi.so ../lib - curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus.zip - - unzip bassopus.zip + - unzip -o bassopus.zip - cp x64/libbassopus.so ../lib - cd .. @@ -46,7 +49,7 @@ build linux x86_64: - mkdir discord-rpc - cd discord-rpc - curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip - - unzip discord_rpc_linux.zip + - unzip -o discord_rpc_linux.zip - cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so ../lib - cd .. @@ -99,10 +102,13 @@ build windows i686: - mkdir bass - cd bass - curl http://www.un4seen.com/files/bass24.zip -o bass.zip - - unzip bass.zip + - unzip -o bass.zip - cp bass.dll ../lib + - curl http://www.un4seen.com/files/bassmidi24.zip -o bassmidi.zip + - unzip -o bassmidi.zip + - cp bassmidi.dll ../lib - curl http://www.un4seen.com/files/bassopus24.zip -o bassopus.zip - - unzip bassopus.zip + - unzip -o bassopus.zip - cp bassopus.dll ../lib - cd .. diff --git a/Attorney_Online.pro b/Attorney_Online.pro index c21c7de..3b4a0ee 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -38,6 +38,7 @@ contains(DEFINES, DISCORD) { DEFINES += BASSAUDIO LIBS += -lbass LIBS += -lbassopus +LIBS += -lbassmidi macx:LIBS += -framework CoreFoundation -framework Foundation -framework CoreServices diff --git a/CMakeLists.txt b/CMakeLists.txt index 31559ad..12a63c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ target_include_directories(Attorney_Online PRIVATE include) find_package(Qt5 COMPONENTS Core Gui Network Widgets Concurrent REQUIRED) target_link_directories(Attorney_Online PRIVATE lib) target_link_libraries(Attorney_Online PRIVATE Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets Qt5::Concurrent - bass bassopus discord-rpc) + bass bassmidi bassopus discord-rpc) target_compile_definitions(Attorney_Online PRIVATE DISCORD) # Subdirectories diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index e74a49b..a46afbc 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -16,6 +16,7 @@ aopacket.h aosfxplayer.h aotextarea.h bass.h +bassmidi.h bassopus.h chatlogpiece.h courtroom.h diff --git a/include/aoapplication.h b/include/aoapplication.h index ecd3180..2ee1120 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -7,6 +7,7 @@ #include "discord_rich_presence.h" #include "bass.h" +#include "bassmidi.h" #include "bassopus.h" #include @@ -543,7 +544,7 @@ public: QString asset_url; void initBASS(); - static void load_bass_opus_plugin(); + static void load_bass_plugins(); static void CALLBACK BASSreset(HSTREAM handle, DWORD channel, DWORD data, void *user); static void doBASSreset(); diff --git a/include/aomusicplayer.h b/include/aomusicplayer.h index 7c9bfb3..d00ab8e 100644 --- a/include/aomusicplayer.h +++ b/include/aomusicplayer.h @@ -3,6 +3,7 @@ #include "file_functions.h" #include "bass.h" +#include "bassmidi.h" #include "bassopus.h" #include "aoapplication.h" diff --git a/include/bassmidi.h b/include/bassmidi.h new file mode 100644 index 0000000..72ebe9c --- /dev/null +++ b/include/bassmidi.h @@ -0,0 +1,380 @@ +/* + BASSMIDI 2.4 C/C++ header file + Copyright (c) 2006-2020 Un4seen Developments Ltd. + + See the BASSMIDI.CHM file for more detailed documentation +*/ + +#ifndef BASSMIDI_H +#define BASSMIDI_H + +#include "bass.h" + +#if BASSVERSION!=0x204 +#error conflicting BASS and BASSMIDI versions +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef BASSMIDIDEF +#define BASSMIDIDEF(f) WINAPI f +#endif + +typedef DWORD HSOUNDFONT; // soundfont handle + +// Additional error codes returned by BASS_ErrorGetCode +#define BASS_ERROR_MIDI_INCLUDE 7000 // SFZ include file could not be opened + +// Additional BASS_SetConfig options +#define BASS_CONFIG_MIDI_COMPACT 0x10400 +#define BASS_CONFIG_MIDI_VOICES 0x10401 +#define BASS_CONFIG_MIDI_AUTOFONT 0x10402 +#define BASS_CONFIG_MIDI_IN_PORTS 0x10404 +#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406 +#define BASS_CONFIG_MIDI_SAMPLEMEM 0x10407 +#define BASS_CONFIG_MIDI_SAMPLEREAD 0x10408 + +// Additional BASS_SetConfigPtr options +#define BASS_CONFIG_MIDI_DEFFONT 0x10403 +#define BASS_CONFIG_MIDI_SFZHEAD 0x10408 + +// Additional sync types +#define BASS_SYNC_MIDI_MARK 0x10000 +#define BASS_SYNC_MIDI_MARKER 0x10000 +#define BASS_SYNC_MIDI_CUE 0x10001 +#define BASS_SYNC_MIDI_LYRIC 0x10002 +#define BASS_SYNC_MIDI_TEXT 0x10003 +#define BASS_SYNC_MIDI_EVENT 0x10004 +#define BASS_SYNC_MIDI_TICK 0x10005 +#define BASS_SYNC_MIDI_TIMESIG 0x10006 +#define BASS_SYNC_MIDI_KEYSIG 0x10007 + +// Additional BASS_MIDI_StreamCreateFile/etc flags +#define BASS_MIDI_NOSYSRESET 0x800 +#define BASS_MIDI_DECAYEND 0x1000 +#define BASS_MIDI_NOFX 0x2000 +#define BASS_MIDI_DECAYSEEK 0x4000 +#define BASS_MIDI_NOCROP 0x8000 +#define BASS_MIDI_NOTEOFF1 0x10000 +#define BASS_MIDI_SINCINTER 0x800000 + +// BASS_MIDI_FontInit flags +#define BASS_MIDI_FONT_MEM 0x10000 +#define BASS_MIDI_FONT_MMAP 0x20000 +#define BASS_MIDI_FONT_XGDRUMS 0x40000 +#define BASS_MIDI_FONT_NOFX 0x80000 +#define BASS_MIDI_FONT_LINATTMOD 0x100000 +#define BASS_MIDI_FONT_LINDECVOL 0x200000 +#define BASS_MIDI_FONT_NORAMPIN 0x400000 +#define BASS_MIDI_FONT_NOLIMITS 0x800000 + +typedef struct { + HSOUNDFONT font; // soundfont + int preset; // preset number (-1=all) + int bank; +} BASS_MIDI_FONT; + +typedef struct { + HSOUNDFONT font; // soundfont + int spreset; // source preset number + int sbank; // source bank number + int dpreset; // destination preset/program number + int dbank; // destination bank number + int dbanklsb; // destination bank number LSB +} BASS_MIDI_FONTEX; + +// BASS_MIDI_StreamSet/GetFonts flag +#define BASS_MIDI_FONT_EX 0x1000000 // BASS_MIDI_FONTEX + +typedef struct { + const char *name; + const char *copyright; + const char *comment; + DWORD presets; // number of presets/instruments + DWORD samsize; // total size (in bytes) of the sample data + DWORD samload; // amount of sample data currently loaded + DWORD samtype; // sample format (CTYPE) if packed +} BASS_MIDI_FONTINFO; + +typedef struct { + DWORD track; // track containing marker + DWORD pos; // marker position + const char *text; // marker text +} BASS_MIDI_MARK; + +// Marker types +#define BASS_MIDI_MARK_MARKER 0 // marker +#define BASS_MIDI_MARK_CUE 1 // cue point +#define BASS_MIDI_MARK_LYRIC 2 // lyric +#define BASS_MIDI_MARK_TEXT 3 // text +#define BASS_MIDI_MARK_TIMESIG 4 // time signature +#define BASS_MIDI_MARK_KEYSIG 5 // key signature +#define BASS_MIDI_MARK_COPY 6 // copyright notice +#define BASS_MIDI_MARK_TRACK 7 // track name +#define BASS_MIDI_MARK_INST 8 // instrument name +#define BASS_MIDI_MARK_TRACKSTART 9 // track start (SMF2) +#define BASS_MIDI_MARK_TICK 0x10000 // flag: get position in ticks (otherwise bytes) + +// MIDI events +#define MIDI_EVENT_NOTE 1 +#define MIDI_EVENT_PROGRAM 2 +#define MIDI_EVENT_CHANPRES 3 +#define MIDI_EVENT_PITCH 4 +#define MIDI_EVENT_PITCHRANGE 5 +#define MIDI_EVENT_DRUMS 6 +#define MIDI_EVENT_FINETUNE 7 +#define MIDI_EVENT_COARSETUNE 8 +#define MIDI_EVENT_MASTERVOL 9 +#define MIDI_EVENT_BANK 10 +#define MIDI_EVENT_MODULATION 11 +#define MIDI_EVENT_VOLUME 12 +#define MIDI_EVENT_PAN 13 +#define MIDI_EVENT_EXPRESSION 14 +#define MIDI_EVENT_SUSTAIN 15 +#define MIDI_EVENT_SOUNDOFF 16 +#define MIDI_EVENT_RESET 17 +#define MIDI_EVENT_NOTESOFF 18 +#define MIDI_EVENT_PORTAMENTO 19 +#define MIDI_EVENT_PORTATIME 20 +#define MIDI_EVENT_PORTANOTE 21 +#define MIDI_EVENT_MODE 22 +#define MIDI_EVENT_REVERB 23 +#define MIDI_EVENT_CHORUS 24 +#define MIDI_EVENT_CUTOFF 25 +#define MIDI_EVENT_RESONANCE 26 +#define MIDI_EVENT_RELEASE 27 +#define MIDI_EVENT_ATTACK 28 +#define MIDI_EVENT_DECAY 29 +#define MIDI_EVENT_REVERB_MACRO 30 +#define MIDI_EVENT_CHORUS_MACRO 31 +#define MIDI_EVENT_REVERB_TIME 32 +#define MIDI_EVENT_REVERB_DELAY 33 +#define MIDI_EVENT_REVERB_LOCUTOFF 34 +#define MIDI_EVENT_REVERB_HICUTOFF 35 +#define MIDI_EVENT_REVERB_LEVEL 36 +#define MIDI_EVENT_CHORUS_DELAY 37 +#define MIDI_EVENT_CHORUS_DEPTH 38 +#define MIDI_EVENT_CHORUS_RATE 39 +#define MIDI_EVENT_CHORUS_FEEDBACK 40 +#define MIDI_EVENT_CHORUS_LEVEL 41 +#define MIDI_EVENT_CHORUS_REVERB 42 +#define MIDI_EVENT_USERFX 43 +#define MIDI_EVENT_USERFX_LEVEL 44 +#define MIDI_EVENT_USERFX_REVERB 45 +#define MIDI_EVENT_USERFX_CHORUS 46 +#define MIDI_EVENT_DRUM_FINETUNE 50 +#define MIDI_EVENT_DRUM_COARSETUNE 51 +#define MIDI_EVENT_DRUM_PAN 52 +#define MIDI_EVENT_DRUM_REVERB 53 +#define MIDI_EVENT_DRUM_CHORUS 54 +#define MIDI_EVENT_DRUM_CUTOFF 55 +#define MIDI_EVENT_DRUM_RESONANCE 56 +#define MIDI_EVENT_DRUM_LEVEL 57 +#define MIDI_EVENT_DRUM_USERFX 58 +#define MIDI_EVENT_SOFT 60 +#define MIDI_EVENT_SYSTEM 61 +#define MIDI_EVENT_TEMPO 62 +#define MIDI_EVENT_SCALETUNING 63 +#define MIDI_EVENT_CONTROL 64 +#define MIDI_EVENT_CHANPRES_VIBRATO 65 +#define MIDI_EVENT_CHANPRES_PITCH 66 +#define MIDI_EVENT_CHANPRES_FILTER 67 +#define MIDI_EVENT_CHANPRES_VOLUME 68 +#define MIDI_EVENT_MOD_VIBRATO 69 +#define MIDI_EVENT_MODRANGE 69 +#define MIDI_EVENT_BANK_LSB 70 +#define MIDI_EVENT_KEYPRES 71 +#define MIDI_EVENT_KEYPRES_VIBRATO 72 +#define MIDI_EVENT_KEYPRES_PITCH 73 +#define MIDI_EVENT_KEYPRES_FILTER 74 +#define MIDI_EVENT_KEYPRES_VOLUME 75 +#define MIDI_EVENT_SOSTENUTO 76 +#define MIDI_EVENT_MOD_PITCH 77 +#define MIDI_EVENT_MOD_FILTER 78 +#define MIDI_EVENT_MOD_VOLUME 79 +#define MIDI_EVENT_VIBRATO_RATE 80 +#define MIDI_EVENT_VIBRATO_DEPTH 81 +#define MIDI_EVENT_VIBRATO_DELAY 82 +#define MIDI_EVENT_MIXLEVEL 0x10000 +#define MIDI_EVENT_TRANSPOSE 0x10001 +#define MIDI_EVENT_SYSTEMEX 0x10002 +#define MIDI_EVENT_SPEED 0x10004 + +#define MIDI_EVENT_END 0 +#define MIDI_EVENT_END_TRACK 0x10003 + +#define MIDI_EVENT_NOTES 0x20000 +#define MIDI_EVENT_VOICES 0x20001 + +#define MIDI_SYSTEM_DEFAULT 0 +#define MIDI_SYSTEM_GM1 1 +#define MIDI_SYSTEM_GM2 2 +#define MIDI_SYSTEM_XG 3 +#define MIDI_SYSTEM_GS 4 + +typedef struct { + DWORD event; // MIDI_EVENT_xxx + DWORD param; + DWORD chan; + DWORD tick; // event position (ticks) + DWORD pos; // event position (bytes) +} BASS_MIDI_EVENT; + +// BASS_MIDI_StreamEvents modes +#define BASS_MIDI_EVENTS_STRUCT 0 // BASS_MIDI_EVENT structures +#define BASS_MIDI_EVENTS_RAW 0x10000 // raw MIDI event data +#define BASS_MIDI_EVENTS_SYNC 0x1000000 // flag: trigger event syncs +#define BASS_MIDI_EVENTS_NORSTATUS 0x2000000 // flag: no running status +#define BASS_MIDI_EVENTS_CANCEL 0x4000000 // flag: cancel pending events +#define BASS_MIDI_EVENTS_TIME 0x8000000 // flag: delta-time info is present +#define BASS_MIDI_EVENTS_ABSTIME 0x10000000 // flag: absolute time info is present + +// BASS_MIDI_StreamGetChannel special channels +#define BASS_MIDI_CHAN_CHORUS (DWORD)-1 +#define BASS_MIDI_CHAN_REVERB (DWORD)-2 +#define BASS_MIDI_CHAN_USERFX (DWORD)-3 + +// BASS_CHANNELINFO type +#define BASS_CTYPE_STREAM_MIDI 0x10d00 + +// Additional attributes +#define BASS_ATTRIB_MIDI_PPQN 0x12000 +#define BASS_ATTRIB_MIDI_CPU 0x12001 +#define BASS_ATTRIB_MIDI_CHANS 0x12002 +#define BASS_ATTRIB_MIDI_VOICES 0x12003 +#define BASS_ATTRIB_MIDI_VOICES_ACTIVE 0x12004 +#define BASS_ATTRIB_MIDI_STATE 0x12005 +#define BASS_ATTRIB_MIDI_SRC 0x12006 +#define BASS_ATTRIB_MIDI_KILL 0x12007 +#define BASS_ATTRIB_MIDI_SPEED 0x12008 +#define BASS_ATTRIB_MIDI_REVERB 0x12009 +#define BASS_ATTRIB_MIDI_VOL 0x1200a +#define BASS_ATTRIB_MIDI_TRACK_VOL 0x12100 // + track # + +// Additional tag type +#define BASS_TAG_MIDI_TRACK 0x11000 // + track #, track text : array of null-terminated ANSI strings + +// BASS_ChannelGetLength/GetPosition/SetPosition mode +#define BASS_POS_MIDI_TICK 2 // tick position + +typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, DWORD track, BASS_MIDI_EVENT *event, BOOL seeking, void *user); +/* Event filtering callback function. +handle : MIDI stream handle +track : Track containing the event +event : The event +seeking: TRUE = the event is being processed while seeking, FALSE = it is being played +user : The 'user' parameter value given when calling BASS_MIDI_StreamSetFilter +RETURN : TRUE = process the event, FALSE = drop the event */ + +// BASS_MIDI_FontLoadEx flags +#define BASS_MIDI_FONTLOAD_NOWAIT 1 // don't want for the samples to load +#define BASS_MIDI_FONTLOAD_COMPACT 2 // compact samples +#define BASS_MIDI_FONTLOAD_NOLOAD 4 // don't load (only compact) +#define BASS_MIDI_FONTLOAD_TIME 8 // length is in milliseconds +#define BASS_MIDI_FONTLOAD_KEEPDEC 16 // keep decoders + +// BASS_MIDI_FontPack flags +#define BASS_MIDI_PACK_NOHEAD 1 // don't send a WAV header to the encoder +#define BASS_MIDI_PACK_16BIT 2 // discard low 8 bits of 24-bit sample data +#define BASS_MIDI_PACK_48KHZ 4 // set encoding rate to 48000 Hz (else 44100 Hz) + +typedef struct { + const char *name; // description + DWORD id; + DWORD flags; +} BASS_MIDI_DEVICEINFO; + +typedef void (CALLBACK MIDIINPROC)(DWORD device, double time, const BYTE *buffer, DWORD length, void *user); +/* MIDI input callback function. +device : MIDI input device +time : Timestamp +buffer : Buffer containing MIDI data +length : Number of bytes of data +user : The 'user' parameter value given when calling BASS_MIDI_InInit */ + +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreate)(DWORD channels, DWORD flags, DWORD freq); +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags, DWORD freq); +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq); +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *procs, void *user, DWORD freq); +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamCreateEvents)(const BASS_MIDI_EVENT *events, DWORD ppqn, DWORD flags, DWORD freq); +BOOL BASSMIDIDEF(BASS_MIDI_StreamGetMark)(HSTREAM handle, DWORD type, DWORD index, BASS_MIDI_MARK *mark); +DWORD BASSMIDIDEF(BASS_MIDI_StreamGetMarks)(HSTREAM handle, int track, DWORD type, BASS_MIDI_MARK *marks); +BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFonts)(HSTREAM handle, const void *fonts, DWORD count); +DWORD BASSMIDIDEF(BASS_MIDI_StreamGetFonts)(HSTREAM handle, void *fonts, DWORD count); +BOOL BASSMIDIDEF(BASS_MIDI_StreamLoadSamples)(HSTREAM handle); +BOOL BASSMIDIDEF(BASS_MIDI_StreamEvent)(HSTREAM handle, DWORD chan, DWORD event, DWORD param); +DWORD BASSMIDIDEF(BASS_MIDI_StreamEvents)(HSTREAM handle, DWORD mode, const void *events, DWORD length); +DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvent)(HSTREAM handle, DWORD chan, DWORD event); +DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEvents)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events); +DWORD BASSMIDIDEF(BASS_MIDI_StreamGetEventsEx)(HSTREAM handle, int track, DWORD filter, BASS_MIDI_EVENT *events, DWORD start, DWORD count); +BOOL BASSMIDIDEF(BASS_MIDI_StreamGetPreset)(HSTREAM handle, DWORD chan, BASS_MIDI_FONT *font); +HSTREAM BASSMIDIDEF(BASS_MIDI_StreamGetChannel)(HSTREAM handle, DWORD chan); +BOOL BASSMIDIDEF(BASS_MIDI_StreamSetFilter)(HSTREAM handle, BOOL seeking, MIDIFILTERPROC *proc, void *user); + +HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInit)(const void *file, DWORD flags); +HSOUNDFONT BASSMIDIDEF(BASS_MIDI_FontInitUser)(const BASS_FILEPROCS *procs, void *user, DWORD flags); +BOOL BASSMIDIDEF(BASS_MIDI_FontFree)(HSOUNDFONT handle); +BOOL BASSMIDIDEF(BASS_MIDI_FontGetInfo)(HSOUNDFONT handle, BASS_MIDI_FONTINFO *info); +BOOL BASSMIDIDEF(BASS_MIDI_FontGetPresets)(HSOUNDFONT handle, DWORD *presets); +const char *BASSMIDIDEF(BASS_MIDI_FontGetPreset)(HSOUNDFONT handle, int preset, int bank); +BOOL BASSMIDIDEF(BASS_MIDI_FontLoad)(HSOUNDFONT handle, int preset, int bank); +BOOL BASSMIDIDEF(BASS_MIDI_FontLoadEx)(HSOUNDFONT handle, int preset, int bank, DWORD length, DWORD flags); +BOOL BASSMIDIDEF(BASS_MIDI_FontUnload)(HSOUNDFONT handle, int preset, int bank); +BOOL BASSMIDIDEF(BASS_MIDI_FontCompact)(HSOUNDFONT handle); +BOOL BASSMIDIDEF(BASS_MIDI_FontPack)(HSOUNDFONT handle, const void *outfile, const void *encoder, DWORD flags); +BOOL BASSMIDIDEF(BASS_MIDI_FontUnpack)(HSOUNDFONT handle, const void *outfile, DWORD flags); +BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume); +float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle); + +DWORD BASSMIDIDEF(BASS_MIDI_ConvertEvents)(const BYTE *data, DWORD length, BASS_MIDI_EVENT *events, DWORD count, DWORD flags); + +BOOL BASSMIDIDEF(BASS_MIDI_InGetDeviceInfo)(DWORD device, BASS_MIDI_DEVICEINFO *info); +BOOL BASSMIDIDEF(BASS_MIDI_InInit)(DWORD device, MIDIINPROC *proc, void *user); +BOOL BASSMIDIDEF(BASS_MIDI_InFree)(DWORD device); +BOOL BASSMIDIDEF(BASS_MIDI_InStart)(DWORD device); +BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device); + +#ifdef __cplusplus +} + +static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count) +{ + return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count|BASS_MIDI_FONT_EX); +} + +static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX *fonts, DWORD count) +{ + return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count|BASS_MIDI_FONT_EX); +} + +#ifdef _WIN32 +static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq) +{ + return BASS_MIDI_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq); +} + +static inline HSTREAM BASS_MIDI_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user, DWORD freq) +{ + return BASS_MIDI_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user, freq); +} + +static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags) +{ + return BASS_MIDI_FontInit((const void*)file, flags|BASS_UNICODE); +} + +static inline BOOL BASS_MIDI_FontPack(HSOUNDFONT handle, const WCHAR *outfile, const WCHAR *encoder, DWORD flags) +{ + return BASS_MIDI_FontPack(handle, (const void*)outfile, (const void*)encoder, flags|BASS_UNICODE); +} + +static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, DWORD flags) +{ + return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags|BASS_UNICODE); +} +#endif +#endif + +#endif diff --git a/scripts/configure_macos.sh b/scripts/configure_macos.sh index af08966..ebf4ab9 100755 --- a/scripts/configure_macos.sh +++ b/scripts/configure_macos.sh @@ -13,6 +13,7 @@ cd ${ROOT_DIR} LIB_TARGET="../../lib" BASS_LINK="http://uk.un4seen.com/files/bass24-osx.zip" BASSOPUS_LINK="http://www.un4seen.com/files/bassopus24-osx.zip" +BASSMIDI_LINK="https://www.un4seen.com/files/bassmidi24.zip" DISCORD_RPC_LINK="https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-osx.zip" APNG_LINK="https://github.com/Skycoder42/QtApng/releases/download/1.1.2-2/qtapng_clang_64_5.13.0.tar.xz" @@ -30,6 +31,10 @@ curl -Ls ${BASSOPUS_LINK} -o bassopus.zip unzip -qq bassopus.zip cp libbassopus.dylib ${LIB_TARGET} +curl -Ls ${BASSMIDI_LINK} -o bassmidi.zip +unzip -qq bassmidi.zip +cp libbassmidi.dylib ${LIB_TARGET} + curl -Ls ${DISCORD_RPC_LINK} -o discord_rpc.zip unzip -qq discord_rpc.zip cp discord-rpc/osx-dynamic/lib/libdiscord-rpc.dylib ${LIB_TARGET} diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh index b010d36..5e14179 100755 --- a/scripts/configure_ubuntu.sh +++ b/scripts/configure_ubuntu.sh @@ -20,12 +20,15 @@ cd tmp #get the bass prebuilt curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip +curl http://www.un4seen.com/files/bassmidi24-linux.zip -o bassmidi_linux.zip curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip unzip bass_linux.zip +unzip bassmidi_linux.zip unzip bassopus_linux.zip cp x64/libbass.so ../../lib +cp x64/libbassmidi.so ../../lib cp x64/libbassopus.so ../../lib #get the discord-rpc prebuilt diff --git a/scripts/macos_build.sh b/scripts/macos_build.sh index fb631e9..533aaf1 100755 --- a/scripts/macos_build.sh +++ b/scripts/macos_build.sh @@ -11,6 +11,10 @@ curl http://www.un4seen.com/files/bass24-osx.zip -o bass.zip unzip bass.zip cp libbass.dylib ../lib +curl http://www.un4seen.com/files/bassmidi24-osx.zip -o bassmidi.zip +unzip bassmidi.zip +cp libbassmidi.dylib ../lib + curl http://www.un4seen.com/files/bassopus24-osx.zip -o bassopus.zip unzip bassopus.zip cp libbassopus.dylib ../lib diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index a20fe26..1e78ef5 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -196,7 +196,7 @@ void AOApplication::doBASSreset() { BASS_Free(); BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); + load_bass_plugins(); } void AOApplication::initBASS() @@ -210,7 +210,7 @@ void AOApplication::initBASS() if (get_audio_output_device() == "default") { BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); + load_bass_plugins(); } else { for (a = 0; BASS_GetDeviceInfo(a, &info); a++) { @@ -218,30 +218,33 @@ void AOApplication::initBASS() BASS_SetDevice(a); BASS_Init(static_cast(a), 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); + load_bass_plugins(); qInfo() << info.name << "was set as the default audio output device."; return; } } BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); + load_bass_plugins(); } } #if (defined(_WIN32) || defined(_WIN64)) -void AOApplication::load_bass_opus_plugin() +void AOApplication::load_bass_plugins() { BASS_PluginLoad("bassopus.dll", 0); -} -#elif (defined(LINUX) || defined(__linux__)) -void AOApplication::load_bass_opus_plugin() -{ - BASS_PluginLoad("libbassopus.so", 0); + BASS_PluginLoad("bassmidi.dll", 0); } #elif defined __APPLE__ -void AOApplication::load_bass_opus_plugin() +void AOApplication::load_bass_plugins() { BASS_PluginLoad("libbassopus.dylib", 0); + BASS_PluginLoad("libbassmidi.dylib", 0); +} +#elif (defined(LINUX) || defined(__linux__)) +void AOApplication::load_bass_plugins() +{ + BASS_PluginLoad("libbassopus.so", 0); + BASS_PluginLoad("libbassmidi.so", 0); } #else #error This operating system is unsupported for BASS plugins. diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 2b75baa..16db163 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -31,6 +31,8 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop, if (f_path.startsWith("http")) { if (f_path.endsWith(".opus")) newstream = BASS_OPUS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0); + else if (f_path.endsWith(".mid")) + newstream = BASS_MIDI_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0, 1); else newstream = BASS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0); @@ -38,6 +40,10 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop, f_path = ao_app->get_real_path(ao_app->get_music_path(p_song)); if (f_path.endsWith(".opus")) newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); + else if (f_path.endsWith(".mid")) + newstream = BASS_MIDI_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags, 1); + else if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx") ) + newstream = BASS_MusicLoad(FALSE,f_path.utf16(), 0, 0, flags, 1); else newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); } diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index e3a285d..b020941 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -515,7 +515,7 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc) QString AOApplication::get_sfx_suffix(VPath sound_to_check) { return get_real_suffixed_path(sound_to_check, - {".opus", ".ogg", ".mp3", ".wav" }); + {".opus", ".ogg", ".mp3", ".wav", ".mid", ".midi", ".xm", ".it", ".s3m", ".mod", ".mtm", ".umx" }); } QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e43b551..393a753 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -4,5 +4,5 @@ find_package(Catch2 REQUIRED) add_executable(test test_aopacket.cpp test_caseloading.cpp test_apng.cpp test_bass.cpp ../include/aopacket.h ../src/aopacket.cpp) target_include_directories(test PRIVATE ../include) target_link_directories(test PRIVATE ../lib) -target_link_libraries(test PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Catch2::Catch2 bass bassopus discord-rpc) +target_link_libraries(test PRIVATE Qt5::Core Qt5::Gui Qt5::Widgets Catch2::Catch2 bass bassmidi bassopus discord-rpc) target_compile_definitions(Attorney_Online PRIVATE DISCORD) diff --git a/test/test_bass.cpp b/test/test_bass.cpp index f5f9198..e48decd 100644 --- a/test/test_bass.cpp +++ b/test/test_bass.cpp @@ -5,6 +5,7 @@ #include #include "bass.h" +#include "bassmidi.h" #include "bassopus.h" TEST_CASE("BASS URL streaming", "[bass][noci]") {