From 5fdd39289affe341151839a48e227d51b08c4a25 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Tue, 15 May 2018 18:09:04 +0200 Subject: specialized hash table for bank number mappings --- src/adlmidi_bankmap.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/adlmidi_bankmap.h (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h new file mode 100644 index 0000000..881b9b5 --- /dev/null +++ b/src/adlmidi_bankmap.h @@ -0,0 +1,114 @@ +/* + * libADLMIDI is a free MIDI to WAV conversion library with OPL3 emulation + * + * Original ADLMIDI code: Copyright (c) 2010-2014 Joel Yliluoma + * ADLMIDI Library API: Copyright (c) 2015-2018 Vitaly Novichkov + * + * Library is based on the ADLMIDI, a MIDI player for Linux and Windows with OPL3 emulation: + * http://iki.fi/bisqwit/source/adlmidi.html + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef ADLMIDI_BANKMAP_H +#define ADLMIDI_BANKMAP_H + +#include +#include +#include +#include + +/** + * A simple hash map which accepts bank numbers as keys, can be reserved to a + * fixed size, offers O(1) search and insertion, has a hash function to + * optimize for the worst case, and has some good cache locality properties. + */ +template +class BasicBankMap +{ +public: + typedef uint16_t key_type; /* the bank identifier */ + typedef T mapped_type; + typedef std::pair value_type; + + BasicBankMap(); + void reserve(size_t capacity); + + size_t size() const + { return m_size; } + size_t capacity() const + { return m_capacity; } + + class iterator; + iterator begin() const; + iterator end() const; + + struct do_not_expand_t {}; + + iterator find(key_type key); + void erase(iterator it); + std::pair insert(const value_type &value); + std::pair insert(const value_type &value, do_not_expand_t); + void clear(); + + T &operator[](key_type key); + +private: + struct Slot; + enum { minimum_allocation = 4 }; + enum + { + hash_bits = 8, /* worst case # of collisions: 128^2/2^hash_bits */ + hash_buckets = 1 << hash_bits, + }; + +public: + class iterator + { + public: + iterator() {} + value_type &operator*() const { return slot->value; } + value_type *operator->() const { return &slot->value; } + iterator &operator++(); + bool operator==(const iterator &o) const; + bool operator!=(const iterator &o) const; + private: + Slot **buckets = nullptr, *slot = nullptr; + size_t index = 0; + iterator(Slot **buckets, Slot *slot, size_t index); + friend BasicBankMap; + }; + +private: + struct Slot { + Slot *next = nullptr, *prev = nullptr; + value_type value; + }; + std::unique_ptr m_buckets; + std::list> m_allocations; + Slot *m_freeslots = nullptr; + size_t m_size = 0; + size_t m_capacity = 0; + static size_t hash(key_type key); + Slot *allocate_slot(); + Slot *ensure_allocate_slot(); + void free_slot(Slot *slot); + Slot *bucket_find(size_t index, key_type key); + void bucket_add(size_t index, Slot *slot); + void bucket_remove(size_t index, Slot *slot); +}; + +#include "adlmidi_bankmap.tcc" + +#endif // ADLMIDI_BANKMAP_H -- cgit v1.2.3 From af1926e8fe3627880290baad4e45335a5c627620 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Wed, 16 May 2018 03:40:24 +0300 Subject: BankMap: Added better friendly template declarison --- src/adlmidi_bankmap.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 881b9b5..123c8e1 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -29,6 +29,8 @@ #include #include +#include "adlmidi_ptr.hpp" + /** * A simple hash map which accepts bank numbers as keys, can be reserved to a * fixed size, offers O(1) search and insertion, has a hash function to @@ -87,7 +89,12 @@ public: Slot **buckets = nullptr, *slot = nullptr; size_t index = 0; iterator(Slot **buckets, Slot *slot, size_t index); - friend BasicBankMap; +#ifdef _MSC_VER + template + friend class BasicBankMap; + #else + friend class BasicBankMap; +#endif }; private: -- cgit v1.2.3 From 8cce88f8706ca6fb52592458aa12641c43469a6e Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 03:27:07 +0200 Subject: c++98 support for bank map --- src/adlmidi_bankmap.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 123c8e1..c249b55 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -25,9 +25,8 @@ #define ADLMIDI_BANKMAP_H #include -#include #include -#include +#include #include "adlmidi_ptr.hpp" @@ -79,15 +78,15 @@ public: class iterator { public: - iterator() {} + iterator(); value_type &operator*() const { return slot->value; } value_type *operator->() const { return &slot->value; } iterator &operator++(); bool operator==(const iterator &o) const; bool operator!=(const iterator &o) const; private: - Slot **buckets = nullptr, *slot = nullptr; - size_t index = 0; + Slot **buckets, *slot; + size_t index; iterator(Slot **buckets, Slot *slot, size_t index); #ifdef _MSC_VER template @@ -99,14 +98,15 @@ public: private: struct Slot { - Slot *next = nullptr, *prev = nullptr; + Slot *next, *prev; value_type value; + Slot() : next(NULL), prev(NULL) {} }; - std::unique_ptr m_buckets; - std::list> m_allocations; - Slot *m_freeslots = nullptr; - size_t m_size = 0; - size_t m_capacity = 0; + AdlMIDI_SPtrArray m_buckets; + std::list< AdlMIDI_SPtrArray > m_allocations; + Slot *m_freeslots; + size_t m_size; + size_t m_capacity; static size_t hash(key_type key); Slot *allocate_slot(); Slot *ensure_allocate_slot(); -- cgit v1.2.3 From bed6bcb220346c622a307bf405b9a1e87fd99db5 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 19 May 2018 19:55:47 +0300 Subject: OpenWatcom compilation fix --- src/adlmidi_bankmap.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index c249b55..84af6e9 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -85,7 +85,8 @@ public: bool operator==(const iterator &o) const; bool operator!=(const iterator &o) const; private: - Slot **buckets, *slot; + Slot **buckets; + Slot *slot; size_t index; iterator(Slot **buckets, Slot *slot, size_t index); #ifdef _MSC_VER -- cgit v1.2.3 From bb4797ee68c0f12018196d3ee8caddcdcad9fe38 Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Sat, 19 May 2018 22:33:37 +0300 Subject: Works and fixes - Fixed an incorrect calculation of 4-op channels and choosing 4-op channels for 2-op only banks - Resolved trouble with automatically chosen flags because of internal confusion --- src/adlmidi_bankmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 84af6e9..43921b8 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -92,7 +92,7 @@ public: #ifdef _MSC_VER template friend class BasicBankMap; - #else +#else friend class BasicBankMap; #endif }; -- cgit v1.2.3 From c4ed5cf15e64a84129865a58b5063ef0e73f0bcf Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Wed, 16 May 2018 14:27:04 +0200 Subject: bank storage inside dynamic map --- src/adlmidi_bankmap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 43921b8..9b71d8f 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -27,6 +27,7 @@ #include #include #include +#include #include "adlmidi_ptr.hpp" -- cgit v1.2.3 From d7b9439df5d09d121c55a15f2bc25c360deeebe0 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Thu, 17 May 2018 21:33:28 +0200 Subject: dynamic instrument API --- src/adlmidi_bankmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 9b71d8f..178a1c1 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -85,6 +85,8 @@ public: iterator &operator++(); bool operator==(const iterator &o) const; bool operator!=(const iterator &o) const; + void to_ptrs(void *ptrs[3]); + static iterator from_ptrs(void *const ptrs[3]); private: Slot **buckets; Slot *slot; -- cgit v1.2.3 From 611aac1271c2e76b0ca634f136d8a7102ba94fd6 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sun, 3 Jun 2018 12:43:43 +0200 Subject: fix build under dynamic bank map and embedded banks disabled --- src/adlmidi_bankmap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/adlmidi_bankmap.h') diff --git a/src/adlmidi_bankmap.h b/src/adlmidi_bankmap.h index 178a1c1..e4534cd 100644 --- a/src/adlmidi_bankmap.h +++ b/src/adlmidi_bankmap.h @@ -51,6 +51,8 @@ public: { return m_size; } size_t capacity() const { return m_capacity; } + bool empty() const + { return m_size == 0; } class iterator; iterator begin() const; -- cgit v1.2.3