Update libVGM and BASSMIDI, SF3 support
BASSMIDI now includes SF3 support, as well as several other changes. Signed-off-by: Christopher Snowhill <kode54@gmail.com>lastfm
parent
ee5b6be4bb
commit
608483ae60
|
@ -205,7 +205,7 @@ void AUPlayer::setComponent(OSType uSubType, OSType uManufacturer) {
|
|||
|
||||
void AUPlayer::setSoundFont(const char *in) {
|
||||
const char *ext = strrchr(in, '.');
|
||||
if(*ext && ((strncasecmp(ext + 1, "sf2", 3) == 0) || (strncasecmp(ext + 1, "dls", 3) == 0))) {
|
||||
if(ext && *ext && ((strncasecmp(ext + 1, "sf2", 3) == 0) || (strncasecmp(ext + 1, "dls", 3) == 0))) {
|
||||
sSoundFontName = in;
|
||||
shutdown();
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ static class Bass_Initializer {
|
|||
|
||||
BMPlayer::BMPlayer()
|
||||
: MIDIPlayer() {
|
||||
memset(_stream, 0, sizeof(_stream));
|
||||
_stream = NULL;
|
||||
bSincInterpolation = false;
|
||||
_presetList = 0;
|
||||
|
||||
|
@ -279,39 +279,19 @@ void BMPlayer::send_event(uint32_t b) {
|
|||
event[1] = static_cast<uint8_t>(b >> 8);
|
||||
event[2] = static_cast<uint8_t>(b >> 16);
|
||||
unsigned port = (b >> 24) & 0x7F;
|
||||
const unsigned channel = b & 0x0F;
|
||||
if(port > 2) port = 0;
|
||||
const unsigned channel = (b & 0x0F) + port * 16;
|
||||
const unsigned command = b & 0xF0;
|
||||
const unsigned event_length = (command >= 0xF8 && command <= 0xFF) ? 1 : ((command == 0xC0 || command == 0xD0) ? 2 : 3);
|
||||
if(port > 2) port = 0;
|
||||
if(bank_lsb_overridden && command == 0xB0 && event[1] == 0x20) return;
|
||||
BASS_MIDI_StreamEvents(_stream[port], BASS_MIDI_EVENTS_RAW + 1 + channel, event, event_length);
|
||||
BASS_MIDI_StreamEvents(_stream, BASS_MIDI_EVENTS_RAW + 1 + channel, event, event_length);
|
||||
}
|
||||
|
||||
void BMPlayer::send_sysex(const uint8_t *data, size_t size, size_t port) {
|
||||
if(port > 2) port = 0;
|
||||
BASS_MIDI_StreamEvents(_stream[port], BASS_MIDI_EVENTS_RAW, data, static_cast<unsigned int>(size));
|
||||
if(port == 0) {
|
||||
BASS_MIDI_StreamEvents(_stream[1], BASS_MIDI_EVENTS_RAW, data, static_cast<unsigned int>(size));
|
||||
BASS_MIDI_StreamEvents(_stream[2], BASS_MIDI_EVENTS_RAW, data, static_cast<unsigned int>(size));
|
||||
}
|
||||
BASS_MIDI_StreamEvents(_stream, BASS_MIDI_EVENTS_RAW, data, static_cast<unsigned int>(size));
|
||||
}
|
||||
|
||||
void BMPlayer::render(float *out, unsigned long count) {
|
||||
float buffer[1024];
|
||||
while(count) {
|
||||
unsigned long todo = count;
|
||||
if(todo > 512)
|
||||
todo = 512;
|
||||
memset(out, 0, todo * sizeof(float) * 2);
|
||||
for(unsigned long i = 0; i < 3; ++i) {
|
||||
BASS_ChannelGetData(_stream[i], buffer, BASS_DATA_FLOAT | (unsigned int)(todo * sizeof(float) * 2));
|
||||
for(unsigned long j = 0; j < todo * 2; ++j) {
|
||||
out[j] += buffer[j];
|
||||
}
|
||||
}
|
||||
out += todo * 2;
|
||||
count -= todo;
|
||||
}
|
||||
BASS_ChannelGetData(_stream, out, BASS_DATA_FLOAT | (unsigned int)(count * sizeof(float) * 2));
|
||||
}
|
||||
|
||||
void BMPlayer::setSoundFont(const char *in) {
|
||||
|
@ -325,10 +305,8 @@ void BMPlayer::setFileSoundFont(const char *in) {
|
|||
}
|
||||
|
||||
void BMPlayer::shutdown() {
|
||||
if(_stream[2]) BASS_StreamFree(_stream[2]);
|
||||
if(_stream[1]) BASS_StreamFree(_stream[1]);
|
||||
if(_stream[0]) BASS_StreamFree(_stream[0]);
|
||||
memset(_stream, 0, sizeof(_stream));
|
||||
if(_stream) BASS_StreamFree(_stream);
|
||||
_stream = NULL;
|
||||
for(unsigned long i = 0; i < _soundFonts.size(); ++i) {
|
||||
cache_close_font(_soundFonts[i]);
|
||||
}
|
||||
|
@ -339,37 +317,17 @@ void BMPlayer::shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
void BMPlayer::compound_presets(std::vector<BASS_MIDI_FONTEX> &out, std::vector<BASS_MIDI_FONTEX> &in, std::vector<long> &channels) {
|
||||
if(!in.size())
|
||||
in.push_back({ 0, -1, -1, -1, 0, 0 });
|
||||
if(channels.size()) {
|
||||
for(auto pit = in.begin(); pit != in.end(); ++pit) {
|
||||
for(auto it = channels.begin(); it != channels.end(); ++it) {
|
||||
bank_lsb_override[*it - 1] = *it;
|
||||
|
||||
int dbanklsb = (int)*it;
|
||||
pit->dbanklsb = dbanklsb;
|
||||
out.push_back(*pit);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(auto pit = in.begin(); pit != in.end(); ++pit) {
|
||||
out.push_back(*pit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BMPlayer::startup() {
|
||||
if(_stream[0] && _stream[1] && _stream[2]) return true;
|
||||
if(_stream) return true;
|
||||
|
||||
_stream[0] = BASS_MIDI_StreamCreate(16, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE | (bSincInterpolation ? BASS_MIDI_SINCINTER : 0), (unsigned int)uSampleRate);
|
||||
_stream[1] = BASS_MIDI_StreamCreate(16, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE | (bSincInterpolation ? BASS_MIDI_SINCINTER : 0), (unsigned int)uSampleRate);
|
||||
_stream[2] = BASS_MIDI_StreamCreate(16, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE | (bSincInterpolation ? BASS_MIDI_SINCINTER : 0), (unsigned int)uSampleRate);
|
||||
if(!_stream[0] || !_stream[1] || !_stream[2]) {
|
||||
_stream = BASS_MIDI_StreamCreate(48, BASS_SAMPLE_FLOAT | BASS_STREAM_DECODE | (bSincInterpolation ? BASS_MIDI_SINCINTER : 0), (unsigned int)uSampleRate);
|
||||
if(!_stream) {
|
||||
return false;
|
||||
}
|
||||
memset(bank_lsb_override, 0, sizeof(bank_lsb_override));
|
||||
std::vector<BASS_MIDI_FONTEX> presetList;
|
||||
BASS_MIDI_StreamEvent(_stream, 9, MIDI_EVENT_DEFDRUMS, 1);
|
||||
BASS_MIDI_StreamEvent(_stream, 9 + 16, MIDI_EVENT_DEFDRUMS, 1);
|
||||
BASS_MIDI_StreamEvent(_stream, 9 + 32, MIDI_EVENT_DEFDRUMS, 1);
|
||||
std::vector<BASS_MIDI_FONTEX2> presetList;
|
||||
if(sFileSoundFontName.length()) {
|
||||
HSOUNDFONT font = cache_open_font(sFileSoundFontName.c_str());
|
||||
if(!font) {
|
||||
|
@ -377,14 +335,14 @@ bool BMPlayer::startup() {
|
|||
return false;
|
||||
}
|
||||
_soundFonts.push_back(font);
|
||||
presetList.push_back({ font, -1, -1, -1, 0, 0 });
|
||||
presetList.push_back({ font, -1, -1, -1, 0, 0, 0, 48 });
|
||||
}
|
||||
|
||||
if(sSoundFontName.length()) {
|
||||
std::string ext;
|
||||
size_t dot = sSoundFontName.find_last_of('.');
|
||||
if(dot != std::string::npos) ext.assign(sSoundFontName.begin() + dot + 1, sSoundFontName.end());
|
||||
if(!strcasecmp(ext.c_str(), "sf2")
|
||||
if(!strcasecmp(ext.c_str(), "sf2") || !strcasecmp(ext.c_str(), "sf3")
|
||||
#ifdef SF2PACK
|
||||
|| !strcasecmp(ext.c_str(), "sf2pack")
|
||||
#endif
|
||||
|
@ -395,7 +353,7 @@ bool BMPlayer::startup() {
|
|||
return false;
|
||||
}
|
||||
_soundFonts.push_back(font);
|
||||
presetList.push_back({ font, -1, -1, -1, 0, 0 });
|
||||
presetList.push_back({ font, -1, -1, -1, 0, 0, 0, 48 });
|
||||
} else if(!strcasecmp(ext.c_str(), "sflist") || !strcasecmp(ext.c_str(), "json")) {
|
||||
_presetList = cache_open_list(sSoundFontName.c_str());
|
||||
if(!_presetList) {
|
||||
|
@ -408,20 +366,7 @@ bool BMPlayer::startup() {
|
|||
}
|
||||
}
|
||||
|
||||
BASS_MIDI_StreamSetFonts(_stream[0], &presetList[0], (unsigned int)presetList.size() | BASS_MIDI_FONT_EX);
|
||||
BASS_MIDI_StreamSetFonts(_stream[1], &presetList[0], (unsigned int)presetList.size() | BASS_MIDI_FONT_EX);
|
||||
BASS_MIDI_StreamSetFonts(_stream[2], &presetList[0], (unsigned int)presetList.size() | BASS_MIDI_FONT_EX);
|
||||
|
||||
reset_parameters();
|
||||
BASS_MIDI_StreamSetFonts(_stream, &presetList[0], (unsigned int)presetList.size() | BASS_MIDI_FONT_EX2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BMPlayer::reset_parameters() {
|
||||
bank_lsb_overridden = false;
|
||||
for(unsigned int i = 0; i < 48; ++i) {
|
||||
if(bank_lsb_override[i])
|
||||
bank_lsb_overridden = true;
|
||||
BASS_MIDI_StreamEvent(_stream[i / 16], i % 16, MIDI_EVENT_BANK_LSB, bank_lsb_override[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,6 @@ class BMPlayer : public MIDIPlayer {
|
|||
virtual void shutdown();
|
||||
virtual bool startup();
|
||||
|
||||
void compound_presets(std::vector<BASS_MIDI_FONTEX>& out, std::vector<BASS_MIDI_FONTEX>& in, std::vector<long>& channels);
|
||||
|
||||
void reset_parameters();
|
||||
|
||||
std::vector<HSOUNDFONT> _soundFonts;
|
||||
|
@ -37,12 +35,9 @@ class BMPlayer : public MIDIPlayer {
|
|||
std::string sSoundFontName;
|
||||
std::string sFileSoundFontName;
|
||||
|
||||
HSTREAM _stream[3];
|
||||
HSTREAM _stream;
|
||||
|
||||
bool bSincInterpolation;
|
||||
|
||||
bool bank_lsb_overridden;
|
||||
uint8_t bank_lsb_override[48];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -120,7 +120,7 @@ static OSType getOSType(const char *in_) {
|
|||
|
||||
if([[source url] isFileURL]) {
|
||||
// Let's check for a SoundFont
|
||||
NSArray *extensions = @[@"sflist", @"sf2pack", @"sf2"];
|
||||
NSArray *extensions = @[@"sflist", @"sf2pack", @"sf2", @"sf3"];
|
||||
NSString *filePath = [[source url] path];
|
||||
NSString *fileNameBase = [filePath lastPathComponent];
|
||||
filePath = [filePath stringByDeletingLastPathComponent];
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
}
|
||||
|
||||
- (IBAction)setSoundFont:(id)sender {
|
||||
NSArray *fileTypes = @[@"sf2", @"sf2pack", @"sflist"];
|
||||
NSArray *fileTypes = @[@"sf2", @"sf2pack", @"sflist", @"sf3"];
|
||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||
[panel setAllowsMultipleSelection:NO];
|
||||
[panel setCanChooseDirectories:NO];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
BASSMIDI 2.4 C/C++ header file
|
||||
Copyright (c) 2006-2020 Un4seen Developments Ltd.
|
||||
Copyright (c) 2006-2022 Un4seen Developments Ltd.
|
||||
|
||||
See the BASSMIDI.CHM file for more detailed documentation
|
||||
*/
|
||||
|
@ -14,6 +14,11 @@
|
|||
#error conflicting BASS and BASSMIDI versions
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
typedef int BOOL32;
|
||||
#define BOOL BOOL32 // override objc's BOOL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -35,10 +40,11 @@ typedef DWORD HSOUNDFONT; // soundfont handle
|
|||
#define BASS_CONFIG_MIDI_SAMPLETHREADS 0x10406
|
||||
#define BASS_CONFIG_MIDI_SAMPLEMEM 0x10407
|
||||
#define BASS_CONFIG_MIDI_SAMPLEREAD 0x10408
|
||||
#define BASS_CONFIG_MIDI_SAMPLELOADING 0x1040a
|
||||
|
||||
// Additional BASS_SetConfigPtr options
|
||||
#define BASS_CONFIG_MIDI_DEFFONT 0x10403
|
||||
#define BASS_CONFIG_MIDI_SFZHEAD 0x10408
|
||||
#define BASS_CONFIG_MIDI_SFZHEAD 0x10409
|
||||
|
||||
// Additional sync types
|
||||
#define BASS_SYNC_MIDI_MARK 0x10000
|
||||
|
@ -52,12 +58,14 @@ typedef DWORD HSOUNDFONT; // soundfont handle
|
|||
#define BASS_SYNC_MIDI_KEYSIG 0x10007
|
||||
|
||||
// Additional BASS_MIDI_StreamCreateFile/etc flags
|
||||
#define BASS_MIDI_NODRUMPARAM 0x400
|
||||
#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_ASYNC 0x400000
|
||||
#define BASS_MIDI_SINCINTER 0x800000
|
||||
|
||||
// BASS_MIDI_FontInit flags
|
||||
|
@ -69,6 +77,7 @@ typedef DWORD HSOUNDFONT; // soundfont handle
|
|||
#define BASS_MIDI_FONT_LINDECVOL 0x200000
|
||||
#define BASS_MIDI_FONT_NORAMPIN 0x400000
|
||||
#define BASS_MIDI_FONT_NOLIMITS 0x800000
|
||||
#define BASS_MIDI_FONT_MINFX 0x1000000
|
||||
|
||||
typedef struct {
|
||||
HSOUNDFONT font; // soundfont
|
||||
|
@ -85,8 +94,20 @@ typedef struct {
|
|||
int dbanklsb; // destination bank number LSB
|
||||
} BASS_MIDI_FONTEX;
|
||||
|
||||
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
|
||||
DWORD minchan; // minimum channel number
|
||||
DWORD numchan; // number of channels from minchan
|
||||
} BASS_MIDI_FONTEX2;
|
||||
|
||||
// BASS_MIDI_StreamSet/GetFonts flag
|
||||
#define BASS_MIDI_FONT_EX 0x1000000 // BASS_MIDI_FONTEX
|
||||
#define BASS_MIDI_FONT_EX2 0x2000000 // BASS_MIDI_FONTEX2
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
@ -197,10 +218,13 @@ typedef struct {
|
|||
#define MIDI_EVENT_VIBRATO_RATE 80
|
||||
#define MIDI_EVENT_VIBRATO_DEPTH 81
|
||||
#define MIDI_EVENT_VIBRATO_DELAY 82
|
||||
#define MIDI_EVENT_MASTER_FINETUNE 83
|
||||
#define MIDI_EVENT_MASTER_COARSETUNE 84
|
||||
#define MIDI_EVENT_MIXLEVEL 0x10000
|
||||
#define MIDI_EVENT_TRANSPOSE 0x10001
|
||||
#define MIDI_EVENT_SYSTEMEX 0x10002
|
||||
#define MIDI_EVENT_SPEED 0x10004
|
||||
#define MIDI_EVENT_DEFDRUMS 0x10006
|
||||
|
||||
#define MIDI_EVENT_END 0
|
||||
#define MIDI_EVENT_END_TRACK 0x10003
|
||||
|
@ -230,6 +254,9 @@ typedef struct {
|
|||
#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
|
||||
#define BASS_MIDI_EVENTS_ASYNC 0x20000000 // flag: process asynchronously
|
||||
#define BASS_MIDI_EVENTS_FILTER 0x40000000 // flag: apply filtering
|
||||
#define BASS_MIDI_EVENTS_FLUSH 0x80000000 // flag: flush async events
|
||||
|
||||
// BASS_MIDI_StreamGetChannel special channels
|
||||
#define BASS_MIDI_CHAN_CHORUS (DWORD)-1
|
||||
|
@ -259,7 +286,7 @@ typedef struct {
|
|||
// 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);
|
||||
typedef BOOL (CALLBACK MIDIFILTERPROC)(HSTREAM handle, int track, BASS_MIDI_EVENT *event, BOOL seeking, void *user);
|
||||
/* Event filtering callback function.
|
||||
handle : MIDI stream handle
|
||||
track : Track containing the event
|
||||
|
@ -294,6 +321,8 @@ buffer : Buffer containing MIDI data
|
|||
length : Number of bytes of data
|
||||
user : The 'user' parameter value given when calling BASS_MIDI_InInit */
|
||||
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_GetVersion)(void);
|
||||
|
||||
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);
|
||||
|
@ -325,6 +354,7 @@ 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);
|
||||
DWORD BASSMIDIDEF(BASS_MIDI_FontFlags)(HSOUNDFONT handle, DWORD flags, DWORD mask);
|
||||
BOOL BASSMIDIDEF(BASS_MIDI_FontSetVolume)(HSOUNDFONT handle, float volume);
|
||||
float BASSMIDIDEF(BASS_MIDI_FontGetVolume)(HSOUNDFONT handle);
|
||||
|
||||
|
@ -341,23 +371,33 @@ BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device);
|
|||
|
||||
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);
|
||||
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX);
|
||||
}
|
||||
|
||||
static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX2 *fonts, DWORD count)
|
||||
{
|
||||
return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX2);
|
||||
}
|
||||
|
||||
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);
|
||||
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX);
|
||||
}
|
||||
|
||||
static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX2 *fonts, DWORD count)
|
||||
{
|
||||
return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX2);
|
||||
}
|
||||
|
||||
#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);
|
||||
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);
|
||||
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)
|
||||
|
@ -367,14 +407,18 @@ static inline HSOUNDFONT BASS_MIDI_FontInit(const WCHAR *file, DWORD flags)
|
|||
|
||||
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);
|
||||
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);
|
||||
return BASS_MIDI_FontUnpack(handle, (const void*)outfile, flags | BASS_UNICODE);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
#undef BOOL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -457,7 +457,7 @@ static const json_value *json_object_item(const json_value *object, const char *
|
|||
return &json_value_none;
|
||||
}
|
||||
|
||||
static void sflist_process_patchmappings(BASS_MIDI_FONTEX *out, BASS_MIDI_FONTEX *fontex, const json_value *patchMappings, unsigned int channel) {
|
||||
static void sflist_process_patchmappings(BASS_MIDI_FONTEX2 *out, BASS_MIDI_FONTEX2 *fontex, const json_value *patchMappings, unsigned int channel, unsigned int channelCount) {
|
||||
unsigned int i, j;
|
||||
for(i = 0, j = patchMappings->u.array.length; i < j; ++i) {
|
||||
json_value *preset = patchMappings->u.array.values[i];
|
||||
|
@ -471,7 +471,8 @@ static void sflist_process_patchmappings(BASS_MIDI_FONTEX *out, BASS_MIDI_FONTEX
|
|||
fontex->sbank = (source_bank->type == json_none) ? -1 : (int)source_bank->u.integer;
|
||||
fontex->dpreset = (destination_program->type == json_none) ? -1 : (int)destination_program->u.integer;
|
||||
fontex->dbank = (destination_bank->type == json_none) ? 0 : (int)destination_bank->u.integer;
|
||||
fontex->dbanklsb = channel;
|
||||
fontex->minchan = channel;
|
||||
fontex->numchan = channelCount;
|
||||
*out++ = *fontex;
|
||||
}
|
||||
}
|
||||
|
@ -487,7 +488,7 @@ static sflist_presets *sflist_process(const json_value *sflist, const char *base
|
|||
json_value *arr;
|
||||
unsigned int i, j, k, l, preset_number;
|
||||
HSOUNDFONT hfont = 0;
|
||||
BASS_MIDI_FONTEX fontex;
|
||||
BASS_MIDI_FONTEX2 fontex;
|
||||
|
||||
if(!rval) {
|
||||
strcpy(error_buf, "Out of memory");
|
||||
|
@ -544,6 +545,8 @@ static sflist_presets *sflist_process(const json_value *sflist, const char *base
|
|||
sprintf(error_buf, "soundFont item #%u 'channels' is not an array", i + 1);
|
||||
goto error;
|
||||
}
|
||||
int prevchannel = -1;
|
||||
int contiguouschannelsets = 0;
|
||||
for(k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
json_value *channel = channels->u.array.values[k];
|
||||
if(channel->type != json_integer) {
|
||||
|
@ -554,8 +557,12 @@ static sflist_presets *sflist_process(const json_value *sflist, const char *base
|
|||
sprintf(error_buf, "soundFont item #%u 'channels' #%u is out of range (wanted 1-48, got %" PRId64 ")", i + 1, k + 1, channel->u.integer);
|
||||
goto error;
|
||||
}
|
||||
if(prevchannel < 0 || channel->u.integer > (prevchannel + 1)) {
|
||||
++contiguouschannelsets;
|
||||
}
|
||||
prevchannel = (int)channel->u.integer;
|
||||
}
|
||||
patches_needed = l;
|
||||
patches_needed = contiguouschannelsets;
|
||||
}
|
||||
if(patchMappings->type != json_none) {
|
||||
if(patchMappings->type != json_array) {
|
||||
|
@ -647,7 +654,7 @@ static sflist_presets *sflist_process(const json_value *sflist, const char *base
|
|||
}
|
||||
|
||||
rval->count = presets_to_allocate;
|
||||
rval->presets = calloc(sizeof(BASS_MIDI_FONTEX), rval->count);
|
||||
rval->presets = calloc(sizeof(BASS_MIDI_FONTEX2), rval->count);
|
||||
|
||||
if(!rval->presets) {
|
||||
strcpy(error_buf, "Out of memory");
|
||||
|
@ -725,22 +732,51 @@ static sflist_presets *sflist_process(const json_value *sflist, const char *base
|
|||
fontex.dpreset = -1;
|
||||
fontex.dbank = 0;
|
||||
fontex.dbanklsb = 0;
|
||||
fontex.minchan = 0;
|
||||
fontex.numchan = 48;
|
||||
/* Simplest case, whole bank loading */
|
||||
if(channels->type == json_none && patchMappings->type == json_none) {
|
||||
rval->presets[preset_number++] = fontex;
|
||||
} else if(patchMappings->type == json_none) {
|
||||
int prevchannel = -1;
|
||||
int firstchannel = -1;
|
||||
for(k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
fontex.dbanklsb = (int)channels->u.array.values[k]->u.integer;
|
||||
rval->presets[preset_number++] = fontex;
|
||||
int channel = (int)channels->u.array.values[k]->u.integer;
|
||||
if(firstchannel < 0) {
|
||||
firstchannel = channel;
|
||||
prevchannel = channel;
|
||||
}
|
||||
if(channel > (prevchannel + 1)) {
|
||||
fontex.minchan = firstchannel;
|
||||
fontex.numchan = prevchannel - firstchannel + 1;
|
||||
rval->presets[preset_number++] = fontex;
|
||||
firstchannel = channel;
|
||||
}
|
||||
prevchannel = channel;
|
||||
}
|
||||
fontex.minchan = firstchannel;
|
||||
fontex.numchan = prevchannel - firstchannel + 1;
|
||||
rval->presets[preset_number++] = fontex;
|
||||
} else if(channels->type == json_none) {
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, 0);
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, 0, 48);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
} else {
|
||||
int prevchannel = -1;
|
||||
int firstchannel = -1;
|
||||
for(k = 0, l = channels->u.array.length; k < l; ++k) {
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, (int)channels->u.array.values[k]->u.integer);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
int channel = (int)channels->u.array.values[k]->u.integer;
|
||||
if(firstchannel < 0) {
|
||||
firstchannel = channel;
|
||||
prevchannel = channel;
|
||||
}
|
||||
if(channel > (prevchannel + 1)) {
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, firstchannel, prevchannel - firstchannel + 1);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
}
|
||||
prevchannel = channel;
|
||||
}
|
||||
sflist_process_patchmappings(rval->presets + preset_number, &fontex, patchMappings, firstchannel, prevchannel - firstchannel + 1);
|
||||
preset_number += patchMappings->u.array.length;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
|
||||
typedef struct sflist_presets {
|
||||
unsigned int count;
|
||||
BASS_MIDI_FONTEX *presets;
|
||||
BASS_MIDI_FONTEX2 *presets;
|
||||
} sflist_presets;
|
||||
|
||||
#define sflist_max_error 1024
|
||||
|
|
Binary file not shown.
|
@ -6,6 +6,6 @@ Built on an M1 Mac mini, using CMake from Homebrew, with the following
|
|||
options:
|
||||
|
||||
```
|
||||
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.12" \
|
||||
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" -DCMAKE_OSX_DEPLOYMENT_TARGET="10.13" \
|
||||
-DBUILD_LIBAUDIO=NO -DBUILD_PLAYER=NO -DBUILD_VGM2WAV=NO
|
||||
```
|
||||
|
|
Loading…
Reference in New Issue