summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/audiofile.h2
-rw-r--r--src/audioinputenginemidi.cc51
-rw-r--r--src/drumgizmo.cc37
-rw-r--r--src/drumgizmo.h2
-rw-r--r--src/drumkitloader.cc5
-rw-r--r--src/events_ds.cc19
-rw-r--r--src/events_ds.h9
-rw-r--r--src/inputprocessor.cc29
-rw-r--r--src/memory_heap.h8
-rw-r--r--src/midimapparser.cc3
-rw-r--r--src/midimapper.cc24
-rw-r--r--src/midimapper.h16
-rw-r--r--src/sample_selection.cc3
-rw-r--r--src/settings.h1
-rw-r--r--src/translation.h2
16 files changed, 156 insertions, 57 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b656f48..85b10fa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,7 +32,7 @@ libpugi_la_SOURCES = \
libdg_la_CPPFLAGS = \
$(DEBUG_FLAGS) \
-I$(top_srcdir)/hugin -I$(top_srcdir)/pugixml/src \
- $(SSEFLAGS) -I$(top_srcdir)/zita-resampler/libs
+ $(SSEFLAGS) -I$(top_srcdir)/zita-resampler/libs \
$(SNDFILE_CFLAGS) $(PTHREAD_CFLAGS)
libdg_la_LIBADD = \
diff --git a/src/audiofile.h b/src/audiofile.h
index e20d91f..504d0ae 100644
--- a/src/audiofile.h
+++ b/src/audiofile.h
@@ -32,8 +32,6 @@
#include <limits>
#include <mutex>
-#include <sndfile.h>
-
#include "audio.h"
#include "channel.h"
#include "logger.h"
diff --git a/src/audioinputenginemidi.cc b/src/audioinputenginemidi.cc
index ce3ce18..69aeeb6 100644
--- a/src/audioinputenginemidi.cc
+++ b/src/audioinputenginemidi.cc
@@ -117,32 +117,35 @@ void AudioInputEngineMidi::processNote(const std::uint8_t* midi_buffer,
auto key = midi_buffer[1];
auto velocity = midi_buffer[2];
auto instrument_idx = mmap.lookup(key);
-
- switch(midi_buffer[0] & NoteMask)
+ auto instruments = mmap.lookup(key);
+ for(const auto& instrument_idx : instruments)
{
- case NoteOff:
- // Ignore for now
- break;
-
- case NoteOn:
- if(velocity != 0 && instrument_idx != -1)
- {
- // maps velocities to [.5/127, 126.5/127]
- auto centered_velocity = (velocity-.5f)/127.0f;
- events.push_back({EventType::OnSet, (std::size_t)instrument_idx,
- offset, centered_velocity});
- }
- break;
-
- case NoteAftertouch:
- if(velocity == 0 && instrument_idx != -1)
+ switch(midi_buffer[0] & NoteMask)
{
- events.push_back({EventType::Choke, (std::size_t)instrument_idx,
- offset, .0f});
+ case NoteOff:
+ // Ignore for now
+ break;
+
+ case NoteOn:
+ if(velocity != 0)
+ {
+ // maps velocities to [.5/127, 126.5/127]
+ auto centered_velocity = (velocity-.5f)/127.0f;
+ events.push_back({EventType::OnSet, (std::size_t)instrument_idx,
+ offset, centered_velocity});
+ }
+ break;
+
+ case NoteAftertouch:
+ if(velocity > 0)
+ {
+ events.push_back({EventType::Choke, (std::size_t)instrument_idx,
+ offset, .0f});
+ }
+ break;
+
+ default:
+ break;
}
- break;
-
- default:
- break;
}
}
diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc
index ca91c12..abe57be 100644
--- a/src/drumgizmo.cc
+++ b/src/drumgizmo.cc
@@ -119,6 +119,12 @@ void DrumGizmo::setRandomSeed(unsigned int seed)
bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
{
+ if(settings_getter.drumkit_file.hasChanged())
+ {
+ // New kit loaded/loading - old events no longer makes sense.
+ events_ds.clear();
+ }
+
if(settings_getter.enable_resampling.hasChanged())
{
enable_resampling = settings_getter.enable_resampling.getValue();
@@ -191,6 +197,11 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
for(size_t c = 0; c < kit.channels.size(); ++c)
{
+ if(c >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ break;
+ }
+
sample_t *buf = samples;
bool internal = false;
if(oe.getBuffer(c))
@@ -218,6 +229,11 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples)
size_t kitpos = pos * ratio;
for(size_t c = 0; c < kit.channels.size(); ++c)
{
+ if(c >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ break;
+ }
+
sample_t *buf = samples;
bool internal = false;
if(oe.getBuffer(c))
@@ -333,6 +349,8 @@ repeat:
void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)
{
+ assert(ch < NUM_CHANNELS);
+
// Store local values of settings to ensure they don't change intra-iteration
const auto enable_bleed_control = settings.enable_bleed_control.load();
const auto master_bleed = settings.master_bleed.load();
@@ -346,8 +364,9 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz)
if(!af.isLoaded() || !af.isValid() || (s == nullptr))
{
- removeevent = true;
- break;
+ // This event cannot be played - schedule for deletion and continue.
+ to_remove.push_back(sample_event.id);
+ continue;
}
if(sample_event.offset > (pos + sz))
@@ -431,7 +450,7 @@ float DrumGizmo::samplerate()
void DrumGizmo::setSamplerate(float samplerate, float resampling_quality)
{
- DEBUG(dgeditor, "%s samplerate: %f\n", __PRETTY_FUNCTION__, samplerate);
+ DEBUG(engine, "%s samplerate: %f\n", __PRETTY_FUNCTION__, samplerate);
settings.samplerate.store(samplerate);
// Notify input engine of the samplerate change.
@@ -463,10 +482,14 @@ void DrumGizmo::setSamplerate(float samplerate, float resampling_quality)
zita[c].set_inp_data(nullptr);
zita[c].set_inp_count(null_size);
- constexpr auto sz = 4096 * 16;
- sample_t s[sz];
- zita[c].set_out_data(s);
- zita[c].set_out_count(sz);
+ std::size_t scratch_buffer_size = (null_size / ratio);
+
+ if(scratch_buffer.size() < scratch_buffer_size)
+ {
+ scratch_buffer.resize(scratch_buffer_size);
+ }
+ zita[c].set_out_data(scratch_buffer.data());
+ zita[c].set_out_count(scratch_buffer_size);
zita[c].process();
}
diff --git a/src/drumgizmo.h b/src/drumgizmo.h
index f08c9f7..89c2960 100644
--- a/src/drumgizmo.h
+++ b/src/drumgizmo.h
@@ -107,5 +107,5 @@ protected:
std::array<ZRWrapper, NUM_CHANNELS> zita;
std::array<std::unique_ptr<sample_t>, NUM_CHANNELS> resampler_input_buffer;
double ratio = 1.0;
-
+ std::vector<sample_t> scratch_buffer;
};
diff --git a/src/drumkitloader.cc b/src/drumkitloader.cc
index 6a4c9f4..9167201 100644
--- a/src/drumkitloader.cc
+++ b/src/drumkitloader.cc
@@ -138,7 +138,7 @@ bool DrumKitLoader::loadkit(const std::string& file)
settings.drumkit_samplerate.store(44100);
settings.load_status_text.store("");
- settings.drumkit_load_status.store(LoadStatus::Loading);
+ settings.drumkit_load_status.store(LoadStatus::Parsing);
// Parse drumkit and instrument xml
@@ -226,6 +226,9 @@ bool DrumKitLoader::loadkit(const std::string& file)
settings.midimap_file = drumkit_path + "/" + drumkitdom.metadata.default_midimap_file;
}
+ // Done parsing. Now start loading the audio
+ settings.midimap_load_status.store(LoadStatus::Loading);
+
loadKitAudio(kit);
DEBUG(loadkit, "loadkit: Success\n");
diff --git a/src/events_ds.cc b/src/events_ds.cc
index ee21f93..0195a89 100644
--- a/src/events_ds.cc
+++ b/src/events_ds.cc
@@ -99,6 +99,25 @@ void EventsDS::startAddingNewGroup(InstrumentID instrument_id)
}
}
+void EventsDS::clear()
+{
+ // *this = EventsDS();
+
+ id_to_info.clear();
+ id_to_group_data.clear();
+ for (auto& channel_data: channel_data_array)
+ {
+ channel_data.sample_events.clear();
+ }
+ for (auto& event_group_ids: instruments_sample_event_group_ids)
+ {
+ event_group_ids.clear();
+ }
+
+ current_group_id.invalidate();
+ current_groups_instrument_id.invalidate();
+}
+
void EventsDS::removeGroup(EventGroupID group_id, InstrumentID instrument_id)
{
// if we remove the current group, then invalidate it
diff --git a/src/events_ds.h b/src/events_ds.h
index 5855711..41287d1 100644
--- a/src/events_ds.h
+++ b/src/events_ds.h
@@ -96,6 +96,9 @@ public:
//! when startAddingNewGroup is again called.
void startAddingNewGroup(InstrumentID instrument_id = InstrumentID());
+ //! Clears the whole data structure to make it ready for a new drum kit.
+ void clear();
+
private:
struct ChannelData
{
@@ -146,6 +149,8 @@ private:
template <typename T, typename... Args>
T& EventsDS::emplace(channel_t ch, Args&&... args)
{
+ assert(ch < NUM_CHANNELS);
+
// add new event types here
static_assert(std::is_same<T, SampleEvent>::value, "Check event type");
@@ -177,6 +182,8 @@ T& EventsDS::get(EventID event_id)
template <typename T>
ContainerRange<std::vector<T>> EventsDS::iterateOver(channel_t ch)
{
+ assert(ch < NUM_CHANNELS);
+
// add new event types here
static_assert(std::is_same<T, SampleEvent>::value, "Check event type");
@@ -190,6 +197,8 @@ ContainerRange<std::vector<T>> EventsDS::iterateOver(channel_t ch)
template <typename T>
T& EventsDS::getSample(EventInfo const& info)
{
+ assert(info.ch < NUM_CHANNELS);
+
// add new event types here
static_assert(std::is_same<T, SampleEvent>::value, "Check event type");
diff --git a/src/inputprocessor.cc b/src/inputprocessor.cc
index fd6e5b9..7d12bdd 100644
--- a/src/inputprocessor.cc
+++ b/src/inputprocessor.cc
@@ -163,6 +163,11 @@ static void applyChokeGroup(Settings& settings, DrumKit& kit,
// Add event to ramp down all existing events with the same groupname.
for(const auto& ch : kit.channels)
{
+ if(ch.num >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ continue;
+ }
+
for(auto& event_sample : events_ds.iterateOver<SampleEvent>(ch.num))
{
if(event_sample.group == instr.getGroup() &&
@@ -186,13 +191,18 @@ static void applyDirectedChoke(Settings& settings, DrumKit& kit,
// Add event to ramp down all existing events with the same groupname.
for(const auto& ch : kit.channels)
{
+ if(ch.num >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ continue;
+ }
+
for(auto& event_sample : events_ds.iterateOver<SampleEvent>(ch.num))
{
if(choke.instrument_id == event_sample.instrument_id &&
event_sample.rampdown_count == -1) // Only if not already ramping.
{
// choke.choketime is in ms
- applyChoke(settings, event_sample, choke.choketime, event_sample.offset);
+ applyChoke(settings, event_sample, choke.choketime, event.offset);
}
}
}
@@ -264,6 +274,11 @@ bool InputProcessor::processOnset(event_t& event, std::size_t pos,
bool new_group_added = false;
for(Channel& ch: kit.channels)
{
+ if(ch.num >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ continue;
+ }
+
const auto af = sample->getAudioFile(ch);
if(af == nullptr || !af->isValid())
{
@@ -330,13 +345,18 @@ bool InputProcessor::processChoke(event_t& event,
// Add event to ramp down all existing events with the same groupname.
for(const auto& ch : kit.channels)
{
+ if(ch.num >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ continue;
+ }
+
for(auto& event_sample : events_ds.iterateOver<SampleEvent>(ch.num))
{
if(event_sample.instrument_id == instrument_id &&
event_sample.rampdown_count == -1) // Only if not already ramping.
{
// Fixed group rampdown time of 68ms, independent of samplerate
- applyChoke(settings, event_sample, 68, event_sample.offset);
+ applyChoke(settings, event_sample, 450, event.offset);
}
}
}
@@ -357,6 +377,11 @@ bool InputProcessor::processStop(event_t& event)
int num_active_events = 0;
for(auto& ch: kit.channels)
{
+ if(ch.num >= NUM_CHANNELS) // kit may have more channels than the engine
+ {
+ continue;
+ }
+
num_active_events += events_ds.numberOfEvents(ch.num);
}
diff --git a/src/memory_heap.h b/src/memory_heap.h
index 3f0105a..658598c 100644
--- a/src/memory_heap.h
+++ b/src/memory_heap.h
@@ -61,6 +61,7 @@ public:
T& get(Index index);
const T& get(Index index) const;
void remove(Index index);
+ void clear();
private:
std::vector<T> memory;
@@ -119,3 +120,10 @@ void MemoryHeap<T>::remove(Index index)
{
free_indices.push_back(index);
}
+
+template <typename T>
+void MemoryHeap<T>::clear()
+{
+ memory.clear();
+ free_indices.clear();
+}
diff --git a/src/midimapparser.cc b/src/midimapparser.cc
index 059dfec..363e1d5 100644
--- a/src/midimapparser.cc
+++ b/src/midimapparser.cc
@@ -50,7 +50,8 @@ bool MidiMapParser::parseFile(const std::string& filename)
continue;
}
- midimap[note] = instr;
+ MidimapEntry entry{note, instr};
+ midimap.push_back(entry);
}
return true;
diff --git a/src/midimapper.cc b/src/midimapper.cc
index 9593aae..b9316c5 100644
--- a/src/midimapper.cc
+++ b/src/midimapper.cc
@@ -26,23 +26,25 @@
*/
#include "midimapper.h"
-int MidiMapper::lookup(int note)
+std::vector<int> MidiMapper::lookup(int note_id)
{
- std::lock_guard<std::mutex> guard(mutex);
+ std::vector<int> instruments;
- auto midimap_it = midimap.find(note);
- if(midimap_it == midimap.end())
- {
- return -1;
- }
+ std::lock_guard<std::mutex> guard(mutex);
- auto instrmap_it = instrmap.find(midimap_it->second);
- if(instrmap_it == instrmap.end())
+ for(const auto& map_entry : midimap)
{
- return -1;
+ if(map_entry.note_id == note_id)
+ {
+ auto instrmap_it = instrmap.find(map_entry.instrument_name);
+ if(instrmap_it != instrmap.end())
+ {
+ instruments.push_back(instrmap_it->second);
+ }
+ }
}
- return instrmap_it->second;
+ return instruments;
}
void MidiMapper::swap(instrmap_t& instrmap, midimap_t& midimap)
diff --git a/src/midimapper.h b/src/midimapper.h
index 4673e33..94781d4 100644
--- a/src/midimapper.h
+++ b/src/midimapper.h
@@ -29,16 +29,22 @@
#include <map>
#include <string>
#include <mutex>
+#include <vector>
-typedef std::map<int, std::string> midimap_t;
-typedef std::map<std::string, int> instrmap_t;
+struct MidimapEntry
+{
+ int note_id;
+ std::string instrument_name;
+};
+
+using midimap_t = std::vector<MidimapEntry>;
+using instrmap_t = std::map<std::string, int>;
class MidiMapper
{
public:
- //! Lookup note in map and return its index.
- //! \returns -1 if not found or the note index.
- int lookup(int note);
+ //! Lookup note in map and returns the corresponding instrument index list.
+ std::vector<int> lookup(int note_id);
//! Set new map sets.
void swap(instrmap_t& instrmap, midimap_t& midimap);
diff --git a/src/sample_selection.cc b/src/sample_selection.cc
index 7267faf..31313bb 100644
--- a/src/sample_selection.cc
+++ b/src/sample_selection.cc
@@ -103,8 +103,7 @@ const Sample* SampleSelection::get(level_t level, std::size_t pos)
{
DEBUG(rand, "%d %d", (int)up_index, (int)down_index);
- // at least avoid infinite loops in case of a bug...
- if (up_index == samples.size()-1 && down_index == 0) { break; }
+ assert(down_index <= up_index);
std::size_t current_index;
if (up_value_lb < down_value_lb)
diff --git a/src/settings.h b/src/settings.h
index 7507827..fb93d79 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -38,6 +38,7 @@
enum class LoadStatus : unsigned int
{
Idle,
+ Parsing,
Loading,
Done,
Error
diff --git a/src/translation.h b/src/translation.h
index 7f506a6..d8a6072 100644
--- a/src/translation.h
+++ b/src/translation.h
@@ -26,6 +26,8 @@
*/
#pragma once
+#include <cstdint>
+
#include <config.h>
#ifdef WITH_NLS