From c9200c25e02b2ab5c1fc4461a4621d109e798350 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 20 Apr 2013 20:13:52 +0200 Subject: New 'instrument group' feature added. --- src/drumgizmo.cc | 54 +++++++++++++++++++++++++++++++++++++++---------- src/drumkitparser.cc | 5 ++++- src/drumkitparser.h | 1 + src/events.h | 14 ++++++++++--- src/instrument.cc | 10 +++++++++ src/instrument.h | 4 ++++ src/instrumentparser.cc | 2 +- 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index c30147f..77d9b89 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -268,6 +268,29 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) continue; } + if(i->group() != "") { + // Add event to ramp down all existing events with the same groupname. + Channels::iterator j = kit.channels.begin(); + while(j != kit.channels.end()) { + Channel &ch = *j; + std::list< Event* >::iterator evs = activeevents[ch.num].begin(); + while(evs != activeevents[ch.num].end()) { + Event *ev = *evs; + if(ev->type() == Event::sample) { + EventSample *sev = (EventSample*)ev; + if(sev->group == i->group() && sev->instrument != i) { + sev->rampdown = 3000; // Ramp down 3000 samples + // TODO: This must be configurable at some point... + // ... perhaps even by instrument (ie. in the xml file) + sev->ramp_start = sev->rampdown; + } + } + evs++; + } + j++; + } + } + Sample *s = i->sample(evs[e].velocity, evs[e].offset + pos); if(s == NULL) { @@ -283,7 +306,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) //printf("Missing AudioFile.\n"); } else { DEBUG(drumgizmo, "Adding event %d.\n", evs[e].offset); - Event *evt = new EventSample(ch.num, 1.0, af); + Event *evt = new EventSample(ch.num, 1.0, af, i->group(), i); evt->offset = evs[e].offset + pos; activeevents[ch.num].push_back(evt); } @@ -361,7 +384,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz) { EventSample *evt = (EventSample *)event; AudioFile *af = evt->file; - //af->load(); // Make sure it is loaded. + if(!af->isLoaded() || s == NULL) { removeevent = true; break; @@ -372,17 +395,26 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t *s, size_t sz) size_t end = sz; if(evt->t + end - n > af->size) end = af->size - evt->t + n; + if(evt->rampdown == NO_RAMPDOWN) { #ifdef SSE - size_t optend = ((end - n) / N) * N + n; - for(; n < optend; n += N) { - *(vNsf*)&(s[n]) += *(vNsf*)&(af->data[evt->t]); - evt->t += N; - } + size_t optend = ((end - n) / N) * N + n; + for(; n < optend; n += N) { + *(vNsf*)&(s[n]) += *(vNsf*)&(af->data[evt->t]); + evt->t += N; + } #endif - //printf("n: %d end: %d, diff: %d", n, end, end - n); fflush(stdout); - for(; n < end; n++) { - s[n] += af->data[evt->t]; - evt->t++; + for(; n < end; n++) { + s[n] += af->data[evt->t]; + evt->t++; + } + } else { // Ramp down in progress. + for(; n < end && evt->rampdown; n++) { + float scale = (float)evt->rampdown/(float)evt->ramp_start; + s[n] += af->data[evt->t] * scale; + evt->t++; + evt->rampdown--; + } + } if(evt->t > af->size) removeevent = true; diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index 5d7ae92..99dc06e 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -51,7 +51,7 @@ DrumKitParser::~DrumKitParser() } void DrumKitParser::startTag(std::string name, - std::map< std::string, std::string> attr) + std::map attr) { if(name == "drumkit") { if(attr.find("name") != attr.end()) @@ -88,6 +88,8 @@ void DrumKitParser::startTag(std::string name, instr_name = attr["name"]; instr_file = attr["file"]; + if(attr.find("group") != attr.end()) instr_group = attr["group"]; + else instr_group = ""; } if(name == "channelmap") { @@ -109,6 +111,7 @@ void DrumKitParser::endTag(std::string name) { if(name == "instrument") { Instrument *i = new Instrument(); + i->setGroup(instr_group); // Instrument &i = kit.instruments[kit.instruments.size() - 1]; InstrumentParser parser(path + "/" + instr_file, *i); parser.parse(); diff --git a/src/drumkitparser.h b/src/drumkitparser.h index f02eece..907b09d 100644 --- a/src/drumkitparser.h +++ b/src/drumkitparser.h @@ -51,6 +51,7 @@ private: std::map channelmap; std::string instr_file; std::string instr_name; + std::string instr_group; }; #endif/*__DRUMGIZMO_DRUMKITPARSER_H__*/ diff --git a/src/events.h b/src/events.h index a4adcee..fa0147b 100644 --- a/src/events.h +++ b/src/events.h @@ -52,23 +52,31 @@ public: timepos_t offset; }; +#define NO_RAMPDOWN -1 class EventSample : public Event { public: - EventSample(channel_t c, float g, AudioFile *af) + EventSample(channel_t c, float g, AudioFile *af, std::string grp, + void *instr) { channel = c; gain = g; t = 0; file = af; + group = grp; + instrument = instr; + rampdown = NO_RAMPDOWN; + ramp_start = 0; } Event::type_t type() { return Event::sample; } float gain; - unsigned int t; - AudioFile *file; + std::string group; + void *instrument; + int rampdown; + int ramp_start; }; class EventQueue { diff --git a/src/instrument.cc b/src/instrument.cc index 22b6a90..7232431 100644 --- a/src/instrument.cc +++ b/src/instrument.cc @@ -109,6 +109,16 @@ std::string Instrument::description() return _description; } +std::string Instrument::group() +{ + return _group; +} + +void Instrument::setGroup(std::string g) +{ + _group = g; +} + #ifdef TEST_INSTRUMENT //deps: channel.cc sample.cc audiofile.cc //cflags: $(SNDFILE_CFLAGS) diff --git a/src/instrument.h b/src/instrument.h index b146cb2..a302412 100644 --- a/src/instrument.h +++ b/src/instrument.h @@ -45,6 +45,9 @@ public: std::string name(); std::string description(); + std::string group(); + + void setGroup(std::string group); // std::map channelmap; @@ -55,6 +58,7 @@ public: private: void *magic; + std::string _group; std::string _name; std::string _description; RangeMap samples; diff --git a/src/instrumentparser.cc b/src/instrumentparser.cc index fdeb934..1445cbe 100644 --- a/src/instrumentparser.cc +++ b/src/instrumentparser.cc @@ -47,7 +47,7 @@ InstrumentParser::~InstrumentParser() } void InstrumentParser::startTag(std::string name, - std::map< std::string, std::string> attr) + std::map attr) { if(name == "instrument") { if(attr.find("name") != attr.end()) -- cgit v1.2.3