diff options
Diffstat (limited to 'src')
47 files changed, 1314 insertions, 1046 deletions
diff --git a/src/Makefile.am.drumgizmo b/src/Makefile.am.drumgizmo index e41bacc..8f648d0 100644 --- a/src/Makefile.am.drumgizmo +++ b/src/Makefile.am.drumgizmo @@ -28,6 +28,7 @@ DRUMGIZMO_SOURCES = \ $(top_srcdir)/src/mutex.cc \ $(top_srcdir)/src/path.cc \ $(top_srcdir)/src/powerlist.cc \ + $(top_srcdir)/src/random.cc \ $(top_srcdir)/src/sample.cc \ $(top_srcdir)/src/semaphore.cc \ $(top_srcdir)/src/saxparser.cc \ diff --git a/src/audio.h b/src/audio.h index a5ef06d..d022147 100644 --- a/src/audio.h +++ b/src/audio.h @@ -24,9 +24,6 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_AUDIO_H__ -#define __DRUMGIZMO_AUDIO_H__ +#pragma once #include <audiotypes.h> - -#endif/*__DRUMGIZMO_AUDIO_H__*/ diff --git a/src/audiocache.cc b/src/audiocache.cc index 65ddef9..a5fb0db 100644 --- a/src/audiocache.cc +++ b/src/audiocache.cc @@ -271,7 +271,7 @@ void AudioCache::setFrameSize(size_t framesize) event_handler.setChunkSize(CHUNKSIZE(framesize)); } -size_t AudioCache::frameSize() const +size_t AudioCache::getFrameSize() const { return framesize; } @@ -281,7 +281,7 @@ void AudioCache::setAsyncMode(bool async) event_handler.setThreaded(async); } -bool AudioCache::asyncMode() const +bool AudioCache::isAsyncMode() const { return event_handler.isThreaded(); } diff --git a/src/audiocache.h b/src/audiocache.h index 5e27cc5..5a4577f 100644 --- a/src/audiocache.h +++ b/src/audiocache.h @@ -89,13 +89,13 @@ public: //! Set/get internal framesize used when iterating through cache buffers. void setFrameSize(size_t framesize); - size_t frameSize() const; + size_t getFrameSize() const; //! Control/get reader threaded mode. //! True means reading happening threaded, false means all reading done //! synchronious. void setAsyncMode(bool async); - bool asyncMode() const; + bool isAsyncMode() const; //! Return the number of chunks that were read too late. size_t getNumberOfUnderruns() const; diff --git a/src/audiocacheeventhandler.cc b/src/audiocacheeventhandler.cc index 8ceabc8..a0261a5 100644 --- a/src/audiocacheeventhandler.cc +++ b/src/audiocacheeventhandler.cc @@ -186,7 +186,7 @@ void AudioCacheEventHandler::setChunkSize(size_t chunksize) this->chunksize = chunksize; } -size_t AudioCacheEventHandler::chunkSize() +size_t AudioCacheEventHandler::getChunkSize() const { return chunksize; } diff --git a/src/audiocacheeventhandler.h b/src/audiocacheeventhandler.h index 87cb3eb..4c0e9d9 100644 --- a/src/audiocacheeventhandler.h +++ b/src/audiocacheeventhandler.h @@ -74,7 +74,7 @@ public: void pushCloseEvent(cacheid_t id); void setChunkSize(size_t chunksize); - size_t chunkSize(); + size_t getChunkSize() const; AudioCacheFile& openFile(const std::string& filename); diff --git a/src/audiocachefile.cc b/src/audiocachefile.cc index 41e9859..2c2888c 100644 --- a/src/audiocachefile.cc +++ b/src/audiocachefile.cc @@ -36,7 +36,8 @@ AudioCacheFile::AudioCacheFile(const std::string& filename, std::vector<sample_t>& read_buffer) - : filename(filename), read_buffer(read_buffer) + : filename(filename) + , read_buffer(read_buffer) { std::memset(&sf_info, 0, sizeof(SF_INFO)); @@ -73,7 +74,7 @@ const std::string& AudioCacheFile::getFilename() const return filename; } -size_t AudioCacheFile::getChannelCount() +size_t AudioCacheFile::getChannelCount() const { return sf_info.channels; } diff --git a/src/audiocachefile.h b/src/audiocachefile.h index 88f1df2..01625a7 100644 --- a/src/audiocachefile.h +++ b/src/audiocachefile.h @@ -69,7 +69,7 @@ public: const std::string& getFilename() const; //! Get number of channels in the file - size_t getChannelCount(); + size_t getChannelCount() const; //! Read audio data from the file into the supplied channel caches. void readChunk(const CacheChannels& channels, size_t pos, size_t num_samples); diff --git a/src/audioinputengine.h b/src/audioinputengine.h index b218086..1701864 100644 --- a/src/audioinputengine.h +++ b/src/audioinputengine.h @@ -38,11 +38,11 @@ class AudioInputEngine { public: virtual ~AudioInputEngine() {} - virtual bool isMidiEngine() { return false; } + virtual bool isMidiEngine() const { return false; } - virtual bool init(Instruments &instruments) = 0; + virtual bool init(const Instruments& instruments) = 0; - virtual void setParm(std::string parm, std::string value) = 0; + virtual void setParm(const std::string& parm, const std::string& value) = 0; virtual bool start() = 0; virtual void stop() = 0; diff --git a/src/audioinputenginemidi.cc b/src/audioinputenginemidi.cc index e3cb796..ea632fe 100644 --- a/src/audioinputenginemidi.cc +++ b/src/audioinputenginemidi.cc @@ -38,7 +38,7 @@ AudioInputEngineMidi::AudioInputEngineMidi() is_valid = false; } -bool AudioInputEngineMidi::loadMidiMap(std::string file, Instruments &instruments) +bool AudioInputEngineMidi::loadMidiMap(const std::string& file, const Instruments& instruments) { std::string f = file; @@ -67,7 +67,7 @@ bool AudioInputEngineMidi::loadMidiMap(std::string file, Instruments &instrument mmap.midimap = p.midimap; for(size_t i = 0; i < instruments.size(); i++) { - mmap.instrmap[instruments[i]->name()] = i; + mmap.instrmap[instruments[i]->getName()] = i; } midimap = file; @@ -76,12 +76,12 @@ bool AudioInputEngineMidi::loadMidiMap(std::string file, Instruments &instrument return true; } -std::string AudioInputEngineMidi::midimapFile() +std::string AudioInputEngineMidi::getMidimapFile() const { return midimap; } -bool AudioInputEngineMidi::isValid() +bool AudioInputEngineMidi::isValid() const { return is_valid; } diff --git a/src/audioinputenginemidi.h b/src/audioinputenginemidi.h index 3f96afe..b892750 100644 --- a/src/audioinputenginemidi.h +++ b/src/audioinputenginemidi.h @@ -41,11 +41,11 @@ public: AudioInputEngineMidi(); virtual ~AudioInputEngineMidi() {} - bool isMidiEngine() { return true; } + bool isMidiEngine() const { return true; } - virtual bool init(Instruments &instruments) = 0; + virtual bool init(const Instruments &instruments) = 0; - virtual void setParm(std::string parm, std::string value) = 0; + virtual void setParm(const std::string& parm, const std::string& value) = 0; virtual bool start() = 0; virtual void stop() = 0; @@ -54,11 +54,11 @@ public: virtual void run(size_t pos, size_t len, std::vector<event_t>& events) = 0; virtual void post() = 0; - bool loadMidiMap(std::string file, Instruments &i); + bool loadMidiMap(const std::string& file, const Instruments& i); - std::string midimapFile(); + std::string getMidimapFile() const; - bool isValid(); + bool isValid() const; protected: MidiMapper mmap; diff --git a/src/audiooutputengine.h b/src/audiooutputengine.h index 0a9d65b..df8b0ee 100644 --- a/src/audiooutputengine.h +++ b/src/audiooutputengine.h @@ -37,9 +37,9 @@ class AudioOutputEngine { public: virtual ~AudioOutputEngine() {} - virtual bool init(Channels channels) = 0; + virtual bool init(const Channels& channels) = 0; - virtual void setParm(std::string parm, std::string value) = 0; + virtual void setParm(const std::string& parm, const std::string& value) = 0; virtual bool start() = 0; virtual void stop() = 0; @@ -49,14 +49,14 @@ public: virtual void post(size_t nsamples) = 0; // Reimplement this if you wish to use internal buffer directly. - virtual sample_t *getBuffer(int ch) { return NULL; } + virtual sample_t *getBuffer(int ch) const { return NULL; } /* * Overload this method to force engine to use different buffer size. */ - virtual size_t getBufferSize() { return 1024; } + virtual size_t getBufferSize() const { return 1024; } - virtual size_t samplerate() { return 44100; } + virtual size_t getSamplerate() const { return 44100; } }; #endif/*__DRUMGIZMO_AUDIOOUTPUTENGINE_H__*/ diff --git a/src/beatmapper.cc b/src/beatmapper.cc index 78441cb..b61f0b5 100644 --- a/src/beatmapper.cc +++ b/src/beatmapper.cc @@ -30,48 +30,58 @@ #define DEF 2.0 -BeatMapper::BeatMapper(Instrument *instrument) +BeatMapper::BeatMapper(const Instrument& instrument) + : instrument{instrument} + , hist{} + , C{1.3} + , mindist{4} + , last{mindist} { - this->instrument = instrument; - for(size_t i = 0; i < HISTORY_SIZE; i++) hist[i] = DEF; - C = 1.3; - mindist = 4; - last = mindist; + for(size_t i = 0; i < HISTORY_SIZE; ++i) + { + hist[i] = DEF; + } } - -Sample *BeatMapper::map(jack_nframes_t nframes) +Sample* BeatMapper::map(jack_nframes_t nframes) { - return NULL; - Sample *sample = NULL; - - jack_default_audio_sample_t *buffer; - buffer = (jack_default_audio_sample_t *)jack_port_get_buffer(instrument->port, nframes); - - float e = 0.0; - for(size_t i = 0; i < nframes; i++) { - e += buffer[i] * buffer[i]; - } + return nullptr; + + // moved the following to comment by glocke since return makes this + // unreachable + /* + Sample *sample = nullptr; + + jack_default_audio_sample_t *buffer; + buffer = (jack_default_audio_sample_t + *)jack_port_get_buffer(instrument->port, nframes); + + float e = 0.0; + for(size_t i = 0; i < nframes; i++) { + e += buffer[i] * buffer[i]; + } - float E = 0.0; - for(size_t i = 0; i < HISTORY_SIZE; i++) E += hist[i] / (float)HISTORY_SIZE; - if(E == 0) E = DEF; // We do not have a connection + float E = 0.0; + for(size_t i = 0; i < HISTORY_SIZE; i++) E += hist[i] / (float)HISTORY_SIZE; + if(E == 0) E = DEF; // We do not have a connection - // printf("last: %d, E: %f, e: %f - threshold: %f\n", last, E, e, 1.3 * E); + // printf("last: %d, E: %f, e: %f - threshold: %f\n", last, E, e, 1.3 * + E); - // Shift history and save new value - for(size_t i = 0; i < HISTORY_SIZE - 1; i++) hist[i] = hist[i+1]; - hist[HISTORY_SIZE - 1] = e>DEF?e:DEF; + // Shift history and save new value + for(size_t i = 0; i < HISTORY_SIZE - 1; i++) hist[i] = hist[i+1]; + hist[HISTORY_SIZE - 1] = e>DEF?e:DEF; - if(instrument->name == "hihat" && e > 0) printf("e: %f\n", e); + if(instrument->name == "hihat" && e > 0) printf("e: %f\n", e); - if(e > C * E && last > mindist) { - Velocity *v = instrument->getVelocity(127); - if(v) sample = v->getSample(); - } + if(e > C * E && last > mindist) { + Velocity *v = instrument->getVelocity(127); + if(v) sample = v->getSample(); + } - last++; - if(sample) last = 0; + last++; + if(sample) last = 0; - return sample; + return sample; + */ } diff --git a/src/beatmapper.h b/src/beatmapper.h index fde1988..405b3d6 100644 --- a/src/beatmapper.h +++ b/src/beatmapper.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_BEATMAPPER_H__ -#define __DRUMGIZMO_BEATMAPPER_H__ +#pragma once #include <jack/jack.h> @@ -36,19 +35,18 @@ #define HISTORY_SIZE 200 -class BeatMapper { +class BeatMapper +{ public: - BeatMapper(Instrument *instrument); + BeatMapper(const Instrument& instrument); - Sample *map(jack_nframes_t nframes); + Sample* map(jack_nframes_t nframes); private: - Instrument *instrument; - float hist[HISTORY_SIZE]; - float C; + const Instrument& instrument; + float hist[HISTORY_SIZE]; + float C; - size_t mindist; - size_t last; + size_t mindist; + size_t last; }; - -#endif/*__DRUMGIZMO_BEATMAPPER_H__*/ diff --git a/src/channel.cc b/src/channel.cc index 6aece18..402a09a 100644 --- a/src/channel.cc +++ b/src/channel.cc @@ -26,16 +26,16 @@ */ #include "channel.h" -Channel::Channel(std::string name) +Channel::Channel(const std::string& name) + : name{name} + , num{NO_CHANNEL} { - this->name = name; - num = NO_CHANNEL; } #ifdef TEST_CHANNEL -//deps: -//cflags: -//libs: +// deps: +// cflags: +// libs: #include "test.h" TEST_BEGIN; @@ -54,4 +54,4 @@ channels.push_back(c2); TEST_END; -#endif/*TEST_CHANNEL*/ +#endif /*TEST_CHANNEL*/ diff --git a/src/channel.h b/src/channel.h index c031973..6cfee81 100644 --- a/src/channel.h +++ b/src/channel.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_CHANNEL_H__ -#define __DRUMGIZMO_CHANNEL_H__ +#pragma once #include <vector> #include <string> @@ -35,16 +34,15 @@ #define ALL_CHANNELS ((channel_t)0xffffffff) #define NO_CHANNEL ((channel_t)0xfffffffe) -class Channel { +class Channel +{ public: - Channel(std::string name = ""); + Channel(const std::string& name = ""); - std::string name; - channel_t num; + std::string name; + channel_t num; }; typedef Channel InstrumentChannel; -typedef std::vector< Channel > Channels; - -#endif/*__DRUMGIZMO_CHANNEL_H__*/ +typedef std::vector<Channel> Channels; diff --git a/src/channelmixer.cc b/src/channelmixer.cc index 76a25a6..510d9a8 100644 --- a/src/channelmixer.cc +++ b/src/channelmixer.cc @@ -26,40 +26,46 @@ */ #include "channelmixer.h" -ChannelMixer::ChannelMixer(Channels &c, Channel *defc, float defg) - : channels(c) +ChannelMixer::ChannelMixer(const Channels& c, const Channel* defc, float defg) + : mix{} + , defaultchannel{nullptr} + , defaultgain{1.f} + , channels(c) { - setDefaults(defc, defg); + setDefaults(defc, defg); } -void ChannelMixer::setDefaults(Channel *defc, float defg) +void ChannelMixer::setDefaults(const Channel* defc, float defg) { - defaultchannel = defc; - if(defc == NULL && channels.size() > 0) defaultchannel = &channels[0]; + defaultchannel = defc; + if(defc == nullptr && channels.size() > 0) + { + defaultchannel = &channels[0]; + } - defaultgain = defg; + defaultgain = defg; } -MixerSettings &ChannelMixer::lookup(InstrumentChannel *c) +MixerSettings& ChannelMixer::lookup(const InstrumentChannel& c) { - std::map<InstrumentChannel *, MixerSettings>::iterator mi = mix.find(c); - - if(mi == mix.end()) { - MixerSettings m; - m.gain = defaultgain; - m.output = defaultchannel; - mix[c] = m; - return mix[c]; - } - - return mi->second; + auto mi = mix.find(&c); + + if(mi == mix.end()) + { + MixerSettings m; + m.gain = defaultgain; + m.output = defaultchannel; + mix[&c] = m; + return mix[&c]; + } + + return mi->second; } - #ifdef TEST_CHANNELMIXER -//deps: channel.cc -//cflags: -//libs: +// deps: channel.cc +// cflags: +// libs: #include "test.h" TEST_BEGIN; @@ -71,40 +77,39 @@ channels.push_back(ch1); channels.push_back(ch2); { - ChannelMixer mixer(channels, NULL, 1.0); + ChannelMixer mixer(channels, nullptr, 1.0); - InstrumentChannel ich; - MixerSettings &m = mixer.lookup(&ich); - TEST_EQUAL(m.output, &channels[0], "Default channel?"); - TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); + InstrumentChannel ich; + MixerSettings& m = mixer.lookup(&ich); + TEST_EQUAL(m.output, &channels[0], "Default channel?"); + TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); } { - ChannelMixer mixer(channels, &channels[1]); + ChannelMixer mixer(channels, &channels[1]); - InstrumentChannel ich; - MixerSettings &m = mixer.lookup(&ich); - TEST_EQUAL(m.output, &channels[1], "Default channel?"); - TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); + InstrumentChannel ich; + MixerSettings& m = mixer.lookup(&ich); + TEST_EQUAL(m.output, &channels[1], "Default channel?"); + TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); } { - ChannelMixer mixer(channels, &channels[1]); + ChannelMixer mixer(channels, &channels[1]); - InstrumentChannel ich; - MixerSettings &m = mixer.lookup(&ich); - TEST_EQUAL(m.output, &channels[1], "Default channel?"); - TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); + InstrumentChannel ich; + MixerSettings& m = mixer.lookup(&ich); + TEST_EQUAL(m.output, &channels[1], "Default channel?"); + TEST_EQUAL_FLOAT(m.gain, 1.0, "Default gain?"); - m.output = &channels[0]; - m.gain = 0.5; + m.output = &channels[0]; + m.gain = 0.5; - MixerSettings &m2 = mixer.lookup(&ich); - TEST_EQUAL(m2.output, &channels[0], "Changed channel?"); - TEST_EQUAL_FLOAT(m2.gain, 0.5, "Changed gain?"); + MixerSettings& m2 = mixer.lookup(&ich); + TEST_EQUAL(m2.output, &channels[0], "Changed channel?"); + TEST_EQUAL_FLOAT(m2.gain, 0.5, "Changed gain?"); } - TEST_END; -#endif/*TEST_CHANNELMIXER*/ +#endif /*TEST_CHANNELMIXER*/ diff --git a/src/channelmixer.h b/src/channelmixer.h index fadf181..ec495ac 100644 --- a/src/channelmixer.h +++ b/src/channelmixer.h @@ -24,35 +24,34 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_CHANNELMIXER_H__ -#define __DRUMGIZMO_CHANNELMIXER_H__ +#pragma once #include <map> #include "channel.h" -class MixerSettings { +class MixerSettings +{ public: - float gain; - Channel *output; + float gain; + const Channel* output; }; -class ChannelMixer { +class ChannelMixer +{ public: - ChannelMixer(Channels &channels, - Channel *defaultchannel = NULL, float defaultgain = 1.0); + ChannelMixer(const Channels& channels, + const Channel* defaultchannel = nullptr, float defaultgain = 1.0); - MixerSettings &lookup(InstrumentChannel *channel); + MixerSettings& lookup(const InstrumentChannel& channel); - void setDefaults(Channel *defaultchannel, float defaultgain); + void setDefaults(const Channel* defaultchannel, float defaultgain); private: - std::map<InstrumentChannel *, MixerSettings> mix; + std::map<const InstrumentChannel*, MixerSettings> mix; - Channel *defaultchannel; - float defaultgain; + const Channel* defaultchannel; + float defaultgain; - Channels &channels; + const Channels& channels; }; - -#endif/*__DRUMGIZMO_CHANNELMIXER_H__*/ diff --git a/src/chresampler.cc b/src/chresampler.cc index 414efc3..4515e53 100644 --- a/src/chresampler.cc +++ b/src/chresampler.cc @@ -25,6 +25,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "chresampler.h" +#include "cpp11fix.h" #include <config.h> #include <hugin.hpp> @@ -33,57 +34,59 @@ #ifdef WITH_RESAMPLER #if defined(USE_ZITA) - #include <zita-resampler/resampler.h> +#include <zita-resampler/resampler.h> #elif defined(USE_SRC) - #include <samplerate.h> +#include <samplerate.h> #else - #error "No resampler selected" +#error "No resampler selected" #endif -class CHResampler::Prv { +class CHResampler::Prv +{ public: #if defined(USE_ZITA) - Resampler zita; + Resampler zita; #elif defined(USE_SRC) - SRC_STATE *state; - SRC_DATA data; + SRC_STATE* state; + SRC_DATA data; #endif }; CHResampler::CHResampler() + : prv{std::make_unique<Prv>()} + , input_fs{44100} + , output_fs{44100} { - input_fs = 44100; - output_fs = 44100; - - prv = new Prv(); #if defined(SRC) - prv->state = NULL; + prv->state = nullptr; #endif } void CHResampler::setup(double input_fs, double output_fs) { - int nchan = 1; // always mono + int nchan = 1; // always mono - this->input_fs = input_fs; - this->output_fs = output_fs; + this->input_fs = input_fs; + this->output_fs = output_fs; #if defined(USE_ZITA) - DEBUG(resampler, "Using zita-resampler (%d -> %d)", (int)input_fs, (int)output_fs); + DEBUG(resampler, "Using zita-resampler (%d -> %d)", (int)input_fs, + (int)output_fs); - int hlen = 72; // 16 ≤ hlen ≤ 96 - // delay is 2 * hlen, 72 corresponds to delay introduced by SRC. - prv->zita.setup(input_fs, output_fs, nchan, hlen); + int hlen = 72; // 16 ≤ hlen ≤ 96 + // delay is 2 * hlen, 72 corresponds to delay introduced by SRC. + prv->zita.setup(input_fs, output_fs, nchan, hlen); #elif defined(USE_SRC) - DEBUG(resampler, "Using libsamplerate (%d -> %d)", (int)input_fs, (int)output_fs); - - int err; - prv->state = src_new(SRC_SINC_BEST_QUALITY, nchan, &err); - (void)err; - // printf("err: %d\n", err); - src_set_ratio(prv->state, output_fs / input_fs); - prv->data.src_ratio = output_fs / input_fs; - prv->data.end_of_input = 0; + DEBUG(resampler, "Using libsamplerate (%d -> %d)", (int)input_fs, + (int)output_fs); + + int err; + prv->state = src_new(SRC_SINC_BEST_QUALITY, nchan, &err); + (void)err; + // printf("err: %d\n", err); + src_set_ratio(prv->state, output_fs / input_fs); + prv->data.src_ratio = output_fs / input_fs; + prv->data.end_of_input = 0; #endif } @@ -91,67 +94,69 @@ CHResampler::~CHResampler() { #if defined(USE_ZITA) #elif defined(USE_SRC) - if(prv->state) src_delete(prv->state); + if(prv->state) + { + src_delete(prv->state); + } #endif - delete prv; } -void CHResampler::setInputSamples(float *samples, size_t count) +void CHResampler::setInputSamples(float* samples, size_t count) { #if defined(USE_ZITA) - prv->zita.inp_data = samples; - prv->zita.inp_count = count; + prv->zita.inp_data = samples; + prv->zita.inp_count = count; #elif defined(USE_SRC) - prv->data.data_in = samples; - prv->data.input_frames = count; + prv->data.data_in = samples; + prv->data.input_frames = count; #endif } -void CHResampler::setOutputSamples(float *samples, size_t count) +void CHResampler::setOutputSamples(float* samples, size_t count) { #if defined(USE_ZITA) - prv->zita.out_data = samples; - prv->zita.out_count = count; + prv->zita.out_data = samples; + prv->zita.out_count = count; #elif defined(USE_SRC) - prv->data.data_out = samples; - prv->data.output_frames = count; + prv->data.data_out = samples; + prv->data.output_frames = count; #endif } void CHResampler::process() { #if defined(USE_ZITA) - prv->zita.process(); + prv->zita.process(); #elif defined(USE_SRC) - src_process(prv->state, &prv->data); - prv->data.output_frames -= prv->data.output_frames_gen; - prv->data.data_out += prv->data.output_frames_gen; - prv->data.input_frames -= prv->data.input_frames_used; - prv->data.data_in += prv->data.input_frames_used; + src_process(prv->state, &prv->data); + prv->data.output_frames -= prv->data.output_frames_gen; + prv->data.data_out += prv->data.output_frames_gen; + prv->data.input_frames -= prv->data.input_frames_used; + prv->data.data_in += prv->data.input_frames_used; #endif } -size_t CHResampler::getInputSampleCount() +size_t CHResampler::getInputSampleCount() const { #if defined(USE_ZITA) - return prv->zita.inp_count; + return prv->zita.inp_count; #elif defined(USE_SRC) - return prv->data.input_frames; + return prv->data.input_frames; #endif } -size_t CHResampler::getOutputSampleCount() +size_t CHResampler::getOutputSampleCount() const { #if defined(USE_ZITA) - return prv->zita.out_count; + return prv->zita.out_count; #elif defined(USE_SRC) - return prv->data.output_frames; + return prv->data.output_frames; #endif } -double CHResampler::ratio() +double CHResampler::getRatio() const { - return input_fs / output_fs; + return input_fs / output_fs; } #else @@ -160,11 +165,23 @@ double CHResampler::ratio() CHResampler::CHResampler() {} CHResampler::~CHResampler() {} void CHResampler::setup(double, double) {} -void CHResampler::setInputSamples(float *, size_t) {} -void CHResampler::setOutputSamples(float *, size_t) {} +void CHResampler::setInputSamples(float*, size_t) {} +void CHResampler::setOutputSamples(float*, size_t) {} void CHResampler::process() {} -size_t CHResampler::getInputSampleCount() { return 0; } -size_t CHResampler::getOutputSampleCount() { return 0; } -double CHResampler::ratio() { return 1; } -#endif/*WITH_RESAMPLER*/ +size_t CHResampler::getInputSampleCount() +{ + return 0; +} + +size_t CHResampler::getOutputSampleCount() +{ + return 0; +} + +double CHResampler::getRatio() const +{ + return 1; +} + +#endif /*WITH_RESAMPLER*/ diff --git a/src/chresampler.h b/src/chresampler.h index ae6cb3b..cd5d571 100644 --- a/src/chresampler.h +++ b/src/chresampler.h @@ -24,9 +24,9 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_CHRESAMPLER_H__ -#define __DRUMGIZMO_CHRESAMPLER_H__ +#pragma once +#include <memory> #include <stdlib.h> /** @@ -36,30 +36,28 @@ * If WITH_RESAMPLER=="zita" zita-resampler will be used. * If WITH_RESAMPLER=="src" Secret Rabbit Code will be used. */ -class CHResampler { +class CHResampler +{ public: - CHResampler(); - ~CHResampler(); + CHResampler(); + ~CHResampler(); - void setup(double input_fs, double output_fs); + void setup(double input_fs, double output_fs); - void setInputSamples(float *samples, size_t count); - void setOutputSamples(float *samples, size_t count); + void setInputSamples(float* samples, size_t count); + void setOutputSamples(float* samples, size_t count); - void process(); + void process(); - size_t getInputSampleCount(); - size_t getOutputSampleCount(); + size_t getInputSampleCount() const; + size_t getOutputSampleCount() const; - double ratio(); + double getRatio() const; private: - class Prv; - Prv *prv; + class Prv; + std::unique_ptr<Prv> prv; - double input_fs; - double output_fs; + double input_fs; + double output_fs; }; - - -#endif/*__DRUMGIZMO_CHRESAMPLER_H__*/ diff --git a/src/configfile.cc b/src/configfile.cc index fc1611e..24f9deb 100644 --- a/src/configfile.cc +++ b/src/configfile.cc @@ -44,11 +44,11 @@ #endif #include <hugin.hpp> - + #ifdef WIN32 - #define SEP "\\" +#define SEP "\\" #else - #define SEP "/" +#define SEP "/" #endif #define CONFIGDIRNAME ".drumgizmo" @@ -56,22 +56,23 @@ /** * Return the path containing the config files. */ -static std::string configPath() +static std::string getConfigPath() { #ifdef WIN32 - std::string configpath; - TCHAR szPath[256]; - if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, - NULL, 0, szPath))) { - configpath = szPath; - } + std::string configpath; + TCHAR szPath[256]; + if(SUCCEEDED(SHGetFolderPath( + NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath))) + { + configpath = szPath; + } #else - std::string configpath = getenv("HOME"); + std::string configpath = getenv("HOME"); #endif - configpath += SEP; - configpath += CONFIGDIRNAME; + configpath += SEP; + configpath += CONFIGDIRNAME; - return configpath; + return configpath; } /** @@ -79,270 +80,320 @@ static std::string configPath() */ static bool createConfigPath() { - std::string configpath = configPath(); + std::string configpath = getConfigPath(); - struct stat st; - if(stat(configpath.c_str(), &st) == 0) { - DEBUG(configfile, "No configuration exists, creating directory '%s'\n", - configpath.c_str()); + struct stat st; + if(stat(configpath.c_str(), &st) == 0) + { + DEBUG(configfile, "No configuration exists, creating directory '%s'\n", + configpath.c_str()); #ifdef WIN32 - if(mkdir(configpath.c_str()) < 0) { + if(mkdir(configpath.c_str()) < 0) + { #else - if(mkdir(configpath.c_str(), 0755) < 0) { + if(mkdir(configpath.c_str(), 0755) < 0) + { #endif - DEBUG(configfile, "Could not create config directory\n"); - } + DEBUG(configfile, "Could not create config directory\n"); + } - return false; - } + return false; + } - return true; + return true; } -ConfigFile::ConfigFile(std::string filename) - : filename(filename) - , fp(NULL) +ConfigFile::ConfigFile(std::string const& filename) + : filename(filename) + , fp(nullptr) { } ConfigFile::~ConfigFile() { + if (fp != nullptr) + { + DEBUG(configfile, "File has not been closed by the client...\n"); + } } bool ConfigFile::load() { - DEBUG(configfile, "Loading config file...\n"); - if(!open("r")) { - return false; - } + DEBUG(configfile, "Loading config file...\n"); + if(!open("r")) + { + return false; + } + + values.clear(); - values.clear(); + std::string line; + while(true) + { + line = readLine(); - std::string line; - while(true) { - line = readLine(); + if(line == "") + break; - if(line == "") break; - - if(!parseLine(line)) { - return false; - } - } + if(!parseLine(line)) + { + return false; + } + } - close(); + close(); - return true; + return true; } bool ConfigFile::save() { - DEBUG(configfile, "Saving configuration...\n"); + DEBUG(configfile, "Saving configuration...\n"); - createConfigPath(); + createConfigPath(); - if(!open("w")) { - return false; - } + if(!open("w")) + { + return false; + } - std::map<std::string, std::string>::iterator v = values.begin(); - for(; v != values.end(); ++v) { - fprintf(fp, "%s:%s\n", v->first.c_str(), v->second.c_str()); - } + std::map<std::string, std::string>::iterator v = values.begin(); + for(; v != values.end(); ++v) + { + fprintf(fp, "%s:%s\n", v->first.c_str(), v->second.c_str()); + } - close(); + close(); - return true; + return true; } -std::string ConfigFile::getValue(const std::string& key) +std::string ConfigFile::getValue(const std::string& key) const { - if(values.find(key) != values.end()) { - return values[key]; - } + auto i = values.find(key); + if (i != values.end()) + { + return i->second; + } - return ""; + return ""; } void ConfigFile::setValue(const std::string& key, const std::string& value) { - values[key] = value; + values[key] = value; } bool ConfigFile::open(std::string mode) { - if(fp) close(); + if(fp) + { + close(); + } - std::string configpath = configPath(); + std::string configpath = getConfigPath(); - std::string configfile = configpath; - configfile += SEP; - configfile += filename; + std::string configfile = configpath; + configfile += SEP; + configfile += filename; - DEBUG(configfile, "Opening config file '%s'\n", configfile.c_str()); - fp = fopen(configfile.c_str(), mode.c_str()); + DEBUG(configfile, "Opening config file '%s'\n", configfile.c_str()); + fp = fopen(configfile.c_str(), mode.c_str()); - if(!fp) return false; + if(!fp) + { + return false; + } - return true; + return true; } void ConfigFile::close() { - fclose(fp); - fp = NULL; + fclose(fp); + fp = nullptr; } std::string ConfigFile::readLine() { - if(!fp) return ""; - - std::string line; - - char buf[1024]; - while(!feof(fp)) { - char *s = fgets(buf, sizeof(buf), fp); - if(s) { - line += buf; - if(buf[strlen(buf) - 1] == '\n') break; - } - } - - return line; + if(!fp) + { + return ""; + } + + std::string line; + + char buf[1024]; + while(!feof(fp)) + { + char* s = fgets(buf, sizeof(buf), fp); + if(s) + { + line += buf; + if(buf[strlen(buf) - 1] == '\n') + break; + } + } + + return line; } bool ConfigFile::parseLine(const std::string& line) { - std::string key; - std::string value; - enum { - before_key, - in_key, - after_key, - before_value, - in_value, - in_value_single_quoted, - in_value_double_quoted, - after_value, - } state = before_key; - - for(std::size_t p = 0; p < line.size(); ++p) { - switch(state) { - case before_key: - if(line[p] == '#') { - // Comment: Ignore line. - p = line.size(); - continue; - } - if(std::isspace(line[p])) { - continue; - } - key += line[p]; - state = in_key; - break; - - case in_key: - if(std::isspace(line[p])) { - state = after_key; - continue; - } - if(line[p] == ':' || line[p] == '=') { - state = before_value; - continue; - } - key += line[p]; - break; - - case after_key: - if(std::isspace(line[p])) { - continue; - } - if(line[p] == ':' || line[p] == '=') { - state = before_value; - continue; - } - ERR(configfile, "Bad symbol." - " Expecting only whitespace or key/value seperator: '%s'", - line.c_str()); - return false; - - case before_value: - if(std::isspace(line[p])) { - continue; - } - if(line[p] == '\'') { - state = in_value_single_quoted; - continue; - } - if(line[p] == '"') { - state = in_value_double_quoted; - continue; - } - value += line[p]; - state = in_value; - break; - - case in_value: - if(std::isspace(line[p])) { - state = after_value; - continue; - } - if(line[p] == '#') { - // Comment: Ignore the rest of the line. - p = line.size(); - state = after_value; - continue; - } - value += line[p]; - break; - - case in_value_single_quoted: - if(line[p] == '\'') { - state = after_value; - continue; - } - value += line[p]; - break; - - case in_value_double_quoted: - if(line[p] == '"') { - state = after_value; - continue; - } - value += line[p]; - break; - - case after_value: - if(std::isspace(line[p])) { - continue; - } - if(line[p] == '#') { - // Comment: Ignore the rest of the line. - p = line.size(); - continue; - } - ERR(configfile, "Bad symbol." - " Expecting only whitespace or key/value seperator: '%s'", - line.c_str()); - return false; - } - } - - if(state == before_key) { - // Line did not contain any data (empty or comment) - return true; - } - - // If state == in_value_XXX_quoted here, the string was not terminated. - if(state != after_value && state != in_value) { - ERR(configfile,"Malformed line: '%s'", line.c_str()); - return false; - } - - DEBUG(configfile, "key['%s'] value['%s']\n", key.c_str(), value.c_str()); - - if(key != "") { - values[key] = value; - } - - return true; + std::string key; + std::string value; + enum + { + before_key, + in_key, + after_key, + before_value, + in_value, + in_value_single_quoted, + in_value_double_quoted, + after_value, + } state = before_key; + + for(std::size_t p = 0; p < line.size(); ++p) + { + switch(state) + { + case before_key: + if(line[p] == '#') + { + // Comment: Ignore line. + p = line.size(); + continue; + } + if(std::isspace(line[p])) + { + continue; + } + key += line[p]; + state = in_key; + break; + + case in_key: + if(std::isspace(line[p])) + { + state = after_key; + continue; + } + if(line[p] == ':' || line[p] == '=') + { + state = before_value; + continue; + } + key += line[p]; + break; + + case after_key: + if(std::isspace(line[p])) + { + continue; + } + if(line[p] == ':' || line[p] == '=') + { + state = before_value; + continue; + } + ERR(configfile, + "Bad symbol." + " Expecting only whitespace or key/value seperator: '%s'", + line.c_str()); + return false; + + case before_value: + if(std::isspace(line[p])) + { + continue; + } + if(line[p] == '\'') + { + state = in_value_single_quoted; + continue; + } + if(line[p] == '"') + { + state = in_value_double_quoted; + continue; + } + value += line[p]; + state = in_value; + break; + + case in_value: + if(std::isspace(line[p])) + { + state = after_value; + continue; + } + if(line[p] == '#') + { + // Comment: Ignore the rest of the line. + p = line.size(); + state = after_value; + continue; + } + value += line[p]; + break; + + case in_value_single_quoted: + if(line[p] == '\'') + { + state = after_value; + continue; + } + value += line[p]; + break; + + case in_value_double_quoted: + if(line[p] == '"') + { + state = after_value; + continue; + } + value += line[p]; + break; + + case after_value: + if(std::isspace(line[p])) + { + continue; + } + if(line[p] == '#') + { + // Comment: Ignore the rest of the line. + p = line.size(); + continue; + } + ERR(configfile, + "Bad symbol." + " Expecting only whitespace or key/value seperator: '%s'", + line.c_str()); + return false; + } + } + + if(state == before_key) + { + // Line did not contain any data (empty or comment) + return true; + } + + // If state == in_value_XXX_quoted here, the string was not terminated. + if(state != after_value && state != in_value) + { + ERR(configfile, "Malformed line: '%s'", line.c_str()); + return false; + } + + DEBUG(configfile, "key['%s'] value['%s']\n", key.c_str(), value.c_str()); + + if(key != "") + { + values[key] = value; + } + + return true; } diff --git a/src/configfile.h b/src/configfile.h index 3a781ec..47ae80b 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -24,34 +24,32 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_CONFIGFILE_H__ -#define __DRUMGIZMO_CONFIGFILE_H__ +#pragma once #include <string> #include <map> #include <stdio.h> -class ConfigFile { +class ConfigFile +{ public: - ConfigFile(std::string filename); - virtual ~ConfigFile(); + ConfigFile(std::string const& filename); + virtual ~ConfigFile(); - virtual bool load(); - virtual bool save(); + virtual bool load(); + virtual bool save(); - virtual std::string getValue(const std::string& key); - virtual void setValue(const std::string& key, const std::string& value); + virtual std::string getValue(const std::string& key) const; + virtual void setValue(const std::string& key, const std::string& value); protected: - std::map<std::string, std::string> values; - std::string filename; + std::map<std::string, std::string> values; + std::string filename; - virtual bool open(std::string mode); - void close(); - std::string readLine(); - bool parseLine(const std::string& line); + virtual bool open(std::string mode); + void close(); + std::string readLine(); + bool parseLine(const std::string& line); - FILE* fp; + FILE* fp; }; - -#endif/*__DRUMGIZMO_CONFIGFILE_H__*/ diff --git a/src/configparser.h b/src/configparser.h index 79f0cb1..29e47b0 100644 --- a/src/configparser.h +++ b/src/configparser.h @@ -26,7 +26,7 @@ */ #pragma once -#include <map> +#include <unordered_map> #include "saxparser.h" @@ -42,6 +42,6 @@ public: std::string value(const std::string& name, const std::string& def = ""); private: - std::map<std::string, std::string> values; + std::unordered_map<std::string, std::string> values; std::string* str; }; diff --git a/src/drumgizmo.cc b/src/drumgizmo.cc index 2658754..4109249 100644 --- a/src/drumgizmo.cc +++ b/src/drumgizmo.cc @@ -103,7 +103,7 @@ bool DrumGizmo::loadkit(std::string file) #ifdef WITH_RESAMPLER for(int i = 0; i < MAX_NUM_CHANNELS; ++i) { - resampler[i].setup(kit.samplerate(), Conf::samplerate); + resampler[i].setup(kit.getSamplerate(), Conf::samplerate); } #endif/*WITH_RESAMPLER*/ @@ -162,14 +162,14 @@ void DrumGizmo::handleMessage(Message *msg) if(ie->isMidiEngine()) { AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie; - mmapfile = aim->midimapFile(); + mmapfile = aim->getMidimapFile(); mmap_loaded = aim->isValid(); } EngineSettingsMessage *msg = new EngineSettingsMessage(); msg->midimapfile = mmapfile; msg->midimap_loaded = mmap_loaded; - msg->drumkitfile = kit.file(); + msg->drumkitfile = kit.getFile(); msg->drumkit_loaded = loader.isDone(); msg->enable_velocity_modifier = Conf::enable_velocity_modifier; msg->velocity_modifier_falloff = Conf::velocity_modifier_falloff; @@ -203,7 +203,7 @@ void DrumGizmo::handleMessage(Message *msg) void DrumGizmo::setFrameSize(size_t framesize) { // If we are resampling override the frame size. - if(resampler[0].ratio() != 1) + if(resampler[0].getRatio() != 1) { framesize = RESAMPLER_INPUT_BUFFER; } @@ -306,7 +306,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) continue; } - if(i->group() != "") + if(i->getGroup() != "") { // Add event to ramp down all existing events with the same groupname. Channels::iterator j = kit.channels.begin(); @@ -317,10 +317,10 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) while(evs != activeevents[ch.num].end()) { Event *ev = *evs; - if(ev->type() == Event::sample) + if(ev->getType() == Event::sample) { EventSample *sev = (EventSample*)ev; - if(sev->group == i->group() && sev->instrument != i) + if(sev->group == i->getGroup() && sev->instrument != i) { sev->rampdown = 3000; // Ramp down 3000 samples // TODO: This must be configurable at some point... @@ -360,8 +360,8 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) else { //DEBUG(drumgizmo, "Adding event %d.\n", event.offset); - Event *evt = new EventSample(ch.num, 1.0, af, i->group(), i); - evt->offset = (event.offset + pos) * resampler[0].ratio(); + Event *evt = new EventSample(ch.num, 1.0, af, i->getGroup(), i); + evt->offset = (event.offset + pos) * resampler[0].getRatio(); activeevents[ch.num].push_back(evt); } ++j; @@ -401,7 +401,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) // #ifdef WITH_RESAMPLER if((Conf::enable_resampling == false) || - (resampler[0].ratio() == 1.0)) // No resampling needed + (resampler[0].getRatio() == 1.0)) // No resampling needed { #endif for(size_t c = 0; c < kit.channels.size(); ++c) @@ -446,7 +446,7 @@ bool DrumGizmo::run(size_t pos, sample_t *samples, size_t nsamples) } // Process channel data - size_t kitpos = pos * resampler[0].ratio(); + size_t kitpos = pos * resampler[0].getRatio(); size_t insize = sizeof(resampler_input_buffer[0]) / sizeof(sample_t); while(resampler[0].getOutputSampleCount() > 0) @@ -500,7 +500,7 @@ void DrumGizmo::getSamples(int ch, int pos, sample_t* s, size_t sz) Event* event = *i; - Event::type_t type = event->type(); + Event::type_t type = event->getType(); switch(type) { case Event::sample: { @@ -648,9 +648,9 @@ void DrumGizmo::setSamplerate(int samplerate) #ifdef WITH_RESAMPLER for(int i = 0; i < MAX_NUM_CHANNELS; ++i) { - resampler[i].setup(kit.samplerate(), Conf::samplerate); + resampler[i].setup(kit.getSamplerate(), Conf::samplerate); } - if(resampler[0].ratio() != 1) + if(resampler[0].getRatio() != 1) { setFrameSize(RESAMPLER_INPUT_BUFFER); } @@ -685,12 +685,12 @@ std::string DrumGizmo::configString() if(ie->isMidiEngine()) { AudioInputEngineMidi *aim = (AudioInputEngineMidi*)ie; - mmapfile = aim->midimapFile(); + mmapfile = aim->getMidimapFile(); } return "<config>\n" - " <value name=\"drumkitfile\">" + kit.file() + "</value>\n" + " <value name=\"drumkitfile\">" + kit.getFile() + "</value>\n" " <value name=\"midimapfile\">" + mmapfile + "</value>\n" " <value name=\"enable_velocity_modifier\">" + bool2str(Conf::enable_velocity_modifier) + "</value>\n" @@ -754,7 +754,7 @@ bool DrumGizmo::setConfigString(std::string cfg) } std::string newkit = p.value("drumkitfile"); - if(newkit != "" && kit.file() != newkit) + if(newkit != "" && kit.getFile() != newkit) { /* if(!loadkit(p.values["drumkitfile"])) diff --git a/src/drumkit.cc b/src/drumkit.cc index e41bd49..f25a6ea 100644 --- a/src/drumkit.cc +++ b/src/drumkit.cc @@ -53,27 +53,27 @@ void DrumKit::clear() _samplerate = 44100; } -bool DrumKit::isValid() +bool DrumKit::isValid() const { return this == magic; } -std::string DrumKit::file() +std::string DrumKit::getFile() const { return _file; } -std::string DrumKit::name() +std::string DrumKit::getName() const { return _name; } -std::string DrumKit::description() +std::string DrumKit::getDescription() const { return _description; } -size_t DrumKit::samplerate() +size_t DrumKit::getSamplerate() const { return _samplerate; } diff --git a/src/drumkit.h b/src/drumkit.h index 26f2945..e3ae783 100644 --- a/src/drumkit.h +++ b/src/drumkit.h @@ -40,22 +40,22 @@ public: DrumKit(); ~DrumKit(); - std::string file(); + std::string getFile() const; - std::string name(); - std::string description(); + std::string getName() const; + std::string getDescription() const; Instruments instruments; Channels channels; void clear(); - bool isValid(); + bool isValid() const; - size_t samplerate(); + size_t getSamplerate() const; private: - void *magic{nullptr}; + void* magic{nullptr}; std::string _file; diff --git a/src/drumkitparser.cc b/src/drumkitparser.cc index 1210611..221e921 100644 --- a/src/drumkitparser.cc +++ b/src/drumkitparser.cc @@ -215,7 +215,7 @@ void DrumKitParser::endTag(const std::string& name) if(c->num == NO_CHANNEL) { ERR(kitparser, "Missing channel '%s' in instrument '%s'\n", - c->name.c_str(), instrument->name().c_str()); + c->name.c_str(), instrument->getName().c_str()); } else { diff --git a/src/drumkitparser.h b/src/drumkitparser.h index b3cf0a6..0adccb9 100644 --- a/src/drumkitparser.h +++ b/src/drumkitparser.h @@ -46,7 +46,7 @@ private: DrumKit& kit; std::string path; - std::map<std::string, std::string> channelmap; + std::unordered_map<std::string, std::string> channelmap; std::string instr_file; std::string instr_name; std::string instr_group; diff --git a/src/events.cc b/src/events.cc index 8149c08..a7ce715 100644 --- a/src/events.cc +++ b/src/events.cc @@ -26,25 +26,26 @@ */ #include "events.h" -void EventQueue::post(Event *event, timepos_t time) +void EventQueue::post(Event* event, timepos_t time) { - MutexAutolock lock(mutex); - event->offset = time; - queue.insert(std::pair<timepos_t, Event*>(time, event)); + MutexAutolock lock(mutex); + event->offset = time; + queue.insert(std::pair<timepos_t, Event*>(time, event)); } -Event *EventQueue::take(timepos_t time) +Event* EventQueue::take(timepos_t time) { - MutexAutolock lock(mutex); - std::multimap<timepos_t, Event*>::iterator i = queue.find(time); - if(i == queue.end()) return NULL; - Event *event = i->second; - queue.erase(i); - return event; + MutexAutolock lock(mutex); + std::multimap<timepos_t, Event*>::iterator i = queue.find(time); + if(i == queue.end()) + return NULL; + Event* event = i->second; + queue.erase(i); + return event; } bool EventQueue::hasEvent(timepos_t time) { - MutexAutolock lock(mutex); - return queue.find(time) != queue.end(); + MutexAutolock lock(mutex); + return queue.find(time) != queue.end(); } diff --git a/src/events.h b/src/events.h index a965bd3..bbbb7ea 100644 --- a/src/events.h +++ b/src/events.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_EVENTS_H__ -#define __DRUMGIZMO_EVENTS_H__ +#pragma once #include <map> #include <stdio.h> @@ -39,62 +38,73 @@ typedef unsigned int timepos_t; -class Event { +class Event +{ public: - virtual ~Event() {} + virtual ~Event() + { + } - typedef enum { - sample - } type_t; - - virtual type_t type() = 0; + typedef enum + { + sample + } type_t; - channel_t channel; - timepos_t offset; + virtual type_t getType() const = 0; + + channel_t channel; + timepos_t offset; }; #define NO_RAMPDOWN -1 -class EventSample : public Event { +class EventSample : public Event +{ public: - EventSample(channel_t c, float g, AudioFile *af, std::string grp, - void *instr) - { - cache_id = CACHE_NOID; - channel = c; - gain = g; - t = 0; - file = af; - group = grp; - instrument = instr; - rampdown = NO_RAMPDOWN; - ramp_start = 0; - } + EventSample(channel_t c, float g, AudioFile* af, + const std::string& grp, void* instr) + { + cache_id = CACHE_NOID; + 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; } + Event::type_t getType() const + { + return Event::sample; + } - cacheid_t cache_id; - sample_t *buffer; - size_t buffer_size; + cacheid_t cache_id; + sample_t* buffer; + size_t buffer_size; - float gain; - unsigned int t; - AudioFile *file; - std::string group; - void *instrument; - int rampdown; - int ramp_start; + float gain; + unsigned int t; + AudioFile* file; + std::string group; + void* instrument; + int rampdown; + int ramp_start; }; -class EventQueue { +class EventQueue +{ public: - void post(Event *event, timepos_t time); - Event *take(timepos_t time); - bool hasEvent(timepos_t time); - size_t size() { return queue.size(); } + void post(Event* event, timepos_t time); + Event* take(timepos_t time); + bool hasEvent(timepos_t time); + size_t getSize() const + { + return queue.size(); + } private: - std::multimap< timepos_t, Event* > queue; - Mutex mutex; + std::multimap<timepos_t, Event*> queue; + Mutex mutex; }; -#endif/*__DRUMGIZMO_EVENTS_H__*/ diff --git a/src/instrument.cc b/src/instrument.cc index eeaa956..d246c09 100644 --- a/src/instrument.cc +++ b/src/instrument.cc @@ -26,8 +26,8 @@ */ #include "instrument.h" -#include <stdlib.h> -#include <stdio.h> +#include <cstdlib> +//#include <stdio.h> #include <hugin.hpp> @@ -57,12 +57,12 @@ Instrument::~Instrument() } } -bool Instrument::isValid() +bool Instrument::isValid() const { return this == magic; } -Sample *Instrument::sample(level_t level, size_t pos) +Sample* Instrument::sample(level_t level, size_t pos) { Sample *sample = NULL; @@ -134,7 +134,7 @@ Sample *Instrument::sample(level_t level, size_t pos) return sample; } -void Instrument::addSample(level_t a, level_t b, Sample *s) +void Instrument::addSample(level_t a, level_t b, Sample* s) { samples.insert(a, b, s); } @@ -154,22 +154,22 @@ void Instrument::finalise() } } -std::string Instrument::name() +std::string Instrument::getName() const { return _name; } -std::string Instrument::description() +std::string Instrument::getDescription() const { return _description; } -std::string Instrument::group() +std::string Instrument::getGroup() const { return _group; } -void Instrument::setGroup(std::string g) +void Instrument::setGroup(const std::string& g) { _group = g; } diff --git a/src/instrument.h b/src/instrument.h index 549a5a4..a531aec 100644 --- a/src/instrument.h +++ b/src/instrument.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_INSTRUMENT_H__ -#define __DRUMGIZMO_INSTRUMENT_H__ +#pragma once #include <string> #include <vector> @@ -35,32 +34,33 @@ #include "sample.h" #include "versionstr.h" +#include "random.h" #include "settings.h" -class InstrumentParser; -class Instrument { +class Instrument +{ friend class InstrumentParser; public: Instrument(Settings& settings); ~Instrument(); - Sample *sample(level_t level, size_t pos); + Sample* sample(level_t level, size_t pos); - std::string name(); - std::string description(); - std::string group(); + std::string getName() const; + std::string getDescription() const; + std::string getGroup() const; - void setGroup(std::string group); + void setGroup(const std::string& group); // std::map<std::string, std::string> channelmap; std::vector<AudioFile*> audiofiles; - bool isValid(); + bool isValid() const; private: - void *magic; + void* magic; std::string _group; std::string _name; @@ -71,18 +71,16 @@ private: RangeMap<level_t, Sample*> samples; PowerList powerlist; - void addSample(level_t a, level_t b, Sample *s); + void addSample(level_t a, level_t b, Sample* s); void finalise(); ///< Signal instrument that no more samples will be added. std::vector<Sample*> samplelist; size_t lastpos; float mod; - Settings& settings; + Random rand; }; -//typedef std::map< std::string, Instrument > Instruments; -typedef std::vector< Instrument* > Instruments; - -#endif/*__DRUMGIZMO_INSTRUMENT_H__*/ +// typedef std::map< std::string, Instrument > Instruments; +typedef std::vector<Instrument*> Instruments; diff --git a/src/midimapper.cc b/src/midimapper.cc index 8df5901..05f69e5 100644 --- a/src/midimapper.cc +++ b/src/midimapper.cc @@ -28,14 +28,20 @@ int MidiMapper::lookup(int note) { - if(midimap.find(note) == midimap.end()) return -1; - std::string instr = midimap[note]; - if(instrmap.find(instr) == instrmap.end()) return -1; - return instrmap[instr]; + if(midimap.find(note) == midimap.end()) + { + return -1; + } + std::string instr = midimap[note]; + if(instrmap.find(instr) == instrmap.end()) + { + return -1; + } + return instrmap[instr]; } void MidiMapper::clear() { - midimap.clear(); - instrmap.clear(); + midimap.clear(); + instrmap.clear(); } diff --git a/src/midimapper.h b/src/midimapper.h index e8f7ab3..1887013 100644 --- a/src/midimapper.h +++ b/src/midimapper.h @@ -24,8 +24,7 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_MIDIMAPPER_H__ -#define __DRUMGIZMO_MIDIMAPPER_H__ +#pragma once #include <map> #include <string> @@ -33,14 +32,13 @@ typedef std::map<int, std::string> midimap_t; typedef std::map<std::string, int> instrmap_t; -class MidiMapper { +class MidiMapper +{ public: - void clear(); + void clear(); - int lookup(int note); + int lookup(int note); - instrmap_t instrmap; - midimap_t midimap; + instrmap_t instrmap; + midimap_t midimap; }; - -#endif/*__DRUMGIZMO_MIDIMAPPER_H__*/ diff --git a/src/nolocale.h b/src/nolocale.h index 4d6fc75..ec49ec6 100644 --- a/src/nolocale.h +++ b/src/nolocale.h @@ -24,55 +24,52 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_NOLOCALE_H__ -#define __DRUMGIZMO_NOLOCALE_H__ +#pragma once #include <locale.h> #include <stdarg.h> -static inline double atof_nol(const char *nptr) +static inline double atof_nol(const char* nptr) { double res; - const char *locale = setlocale(LC_NUMERIC, "C"); + const char* locale = setlocale(LC_NUMERIC, "C"); - res = atof(nptr); + res = atof(nptr); - setlocale(LC_NUMERIC, locale); + setlocale(LC_NUMERIC, locale); return res; } -static inline int sprintf_nol(char *str, const char *format, ...) +static inline int sprintf_nol(char* str, const char* format, ...) { - int ret; + int ret; - const char *locale = setlocale(LC_NUMERIC, "C"); + const char* locale = setlocale(LC_NUMERIC, "C"); - va_list vl; - va_start(vl, format); - ret = vsprintf(str, format, vl); - va_end(vl); + va_list vl; + va_start(vl, format); + ret = vsprintf(str, format, vl); + va_end(vl); - setlocale(LC_NUMERIC, locale); + setlocale(LC_NUMERIC, locale); - return ret; + return ret; } -static inline int snprintf_nol(char *str, size_t size, const char *format, ...) +static inline int snprintf_nol(char* str, size_t size, const char* format, ...) { - int ret; + int ret; - const char *locale = setlocale(LC_NUMERIC, "C"); + const char* locale = setlocale(LC_NUMERIC, "C"); - va_list vl; - va_start(vl, format); - ret = vsnprintf(str, size, format, vl); - va_end(vl); + va_list vl; + va_start(vl, format); + ret = vsnprintf(str, size, format, vl); + va_end(vl); - setlocale(LC_NUMERIC, locale); + setlocale(LC_NUMERIC, locale); - return ret; + return ret; } - -#endif/*__DRUMGIZMO_NOLOCALE_H__*/ diff --git a/src/powerlist.cc b/src/powerlist.cc index efb1f97..f94dbb2 100644 --- a/src/powerlist.cc +++ b/src/powerlist.cc @@ -51,230 +51,246 @@ #define SIZE 500 -// Box–Muller transform. -// See: http://en.wikipedia.org/wiki/Box%E2%80%93Muller_transform -static float box_muller_transform(float mean, float stddev) -{ - float U1 = (float)rand() / (float)RAND_MAX; - float U2 = (float)rand() / (float)RAND_MAX; - - float x = sqrt(-2.0 * log(U1)) * cos(2.0 * M_PI * U2); - - return mean + stddev * x; -} - PowerList::PowerList() { - power_max = 0; - power_min = 100000000; - lastsample = NULL; + power_max = 0; + power_min = 100000000; + lastsample = nullptr; } #define THRES 1.0 -void PowerList::add(Sample *sample) +void PowerList::add(Sample* sample) { - PowerListItem item; - item.power = -1; - item.sample = sample; + PowerListItem item; + item.power = -1; + item.sample = sample; - samples.push_back(item); + samples.push_back(item); } -Channel *PowerList::getMasterChannel() +Channel* PowerList::getMasterChannel() { - std::map<Channel *, int> count; - - std::vector<PowerListItem>::iterator si = samples.begin(); - while(si != samples.end()) { - PowerListItem &item = *si; - Sample *sample = item.sample; - - Channel *max_channel = NULL; - sample_t max_val = 0; - - // DEBUG(rand, "Sample: %s\n", sample->name.c_str()); - - size_t ci = 0; - AudioFiles::iterator ai = sample->audiofiles.begin(); - while(ai != sample->audiofiles.end()) { - Channel *c = ai->first; - AudioFile *af = ai->second; - - af->load(SIZE); - - float silence = 0; - size_t silence_length = 4; - for(size_t s = af->size; s > 0 && s > af->size - silence_length; s--) { - silence += af->data[s]; - } - silence /= silence_length; - - size_t s = 0; - for(; s < af->size; s++) { - float val = af->data[s] * af->data[s] * (1.0 / (float)(s+1)); - if(val > max_val) { - max_val = val; - max_channel = c; - break; - } - } - - af->unload(); - - ai++; - ci++; - } - - if(max_channel) { - if(count.find(max_channel) == count.end()) count[max_channel] = 0; - count[max_channel]++; - } - - si++; - } - - Channel *master = NULL; - int max_count = -1; - - std::map<Channel *, int>::iterator ci = count.begin(); - while(ci != count.end()) { - if(ci->second > max_count && - strstr(ci->first->name.c_str(), "Alesis") == 0) { - master = ci->first; - max_count = ci->second; - } - ci++; - } - - return master; + std::map<Channel*, int> count; + + std::vector<PowerListItem>::iterator si = samples.begin(); + while(si != samples.end()) + { + PowerListItem& item = *si; + Sample* sample = item.sample; + + Channel* max_channel = nullptr; + sample_t max_val = 0; + + // DEBUG(rand, "Sample: %s\n", sample->name.c_str()); + + size_t ci = 0; + AudioFiles::iterator ai = sample->audiofiles.begin(); + while(ai != sample->audiofiles.end()) + { + Channel* c = ai->first; + AudioFile* af = ai->second; + + af->load(SIZE); + + float silence = 0; + size_t silence_length = 4; + for(size_t s = af->size; s > 0 && s > af->size - silence_length; + s--) + { + silence += af->data[s]; + } + silence /= silence_length; + + size_t s = 0; + for(; s < af->size; s++) + { + float val = af->data[s] * af->data[s] * (1.0 / (float)(s + 1)); + if(val > max_val) + { + max_val = val; + max_channel = c; + break; + } + } + + af->unload(); + + ai++; + ci++; + } + + if(max_channel) + { + if(count.find(max_channel) == count.end()) + { + count[max_channel] = 0; + } + count[max_channel]++; + } + + si++; + } + + Channel* master = nullptr; + int max_count = -1; + + std::map<Channel*, int>::iterator ci = count.begin(); + while(ci != count.end()) + { + if(ci->second > max_count && + strstr(ci->first->name.c_str(), "Alesis") == 0) + { + master = ci->first; + max_count = ci->second; + } + ci++; + } + + return master; } void PowerList::finalise() { #ifdef AUTO_CALCULATE_POWER - Channel *master_channel = getMasterChannel(); - - if(master_channel == NULL) { - ERR(rand, "No master channel found!\n"); - return; // This should not happen... - } - - DEBUG(rand, "Master channel: %s\n", master_channel->name.c_str()); -#endif/*AUTO_CALCULATE_POWER*/ - - std::vector<PowerListItem>::iterator si = samples.begin(); - while(si != samples.end()) { - PowerListItem &item = *si; - Sample *sample = item.sample; - - #ifdef AUTO_CALCULATE_POWER - DEBUG(rand, "Sample: %s\n", sample->name.c_str()); + Channel* master_channel = getMasterChannel(); - AudioFile *master = NULL; + if(master_channel == nullptr) + { + ERR(rand, "No master channel found!\n"); + return; // This should not happen... + } - AudioFiles::iterator afi = sample->audiofiles.begin(); - while(afi != sample->audiofiles.end()) { - if(afi->first->name == master_channel->name) { - master = afi->second; - break; - } - afi++; - } + DEBUG(rand, "Master channel: %s\n", master_channel->name.c_str()); +#endif /*AUTO_CALCULATE_POWER*/ - if(master == NULL) { - si++; - continue; - } - - master->load(); -#endif/*AUTO_CALCULATE_POWER*/ + std::vector<PowerListItem>::iterator si = samples.begin(); + while(si != samples.end()) + { + PowerListItem& item = *si; + Sample* sample = item.sample; #ifdef AUTO_CALCULATE_POWER - if(sample->power == -1) { // Power not defined. Calculate it! - DEBUG(powerlist, "Calculating power\n"); - - float power = 0; - size_t s = 0; - for(; s < SIZE && s < master->size; s++) { - power += master->data[s] * master->data[s]; - } - - power = sqrt(power); - - sample->power = power; - } -#endif/*AUTO_CALCULATE_POWER*/ - - item.power = sample->power; - - if(item.power > power_max) power_max = item.power; - if(item.power < power_min) power_min = item.power; - - DEBUG(rand, " - power: %f\n", item.power); - - si++; - } -} + DEBUG(rand, "Sample: %s\n", sample->name.c_str()); + + AudioFile* master = nullptr; + + AudioFiles::iterator afi = sample->audiofiles.begin(); + while(afi != sample->audiofiles.end()) + { + if(afi->first->name == master_channel->name) + { + master = afi->second; + break; + } + afi++; + } + + if(master == nullptr) + { + si++; + continue; + } + + master->load(); +#endif /*AUTO_CALCULATE_POWER*/ -Sample *PowerList::get(level_t level) -{ - int retry = 3; // TODO: This must be user controllable via the UI. +#ifdef AUTO_CALCULATE_POWER + if(sample->power == -1) + { // Power not defined. Calculate it! + DEBUG(powerlist, "Calculating power\n"); - Sample *sample = NULL; + float power = 0; + size_t s = 0; + for(; s < SIZE && s < master->size; s++) + { + power += master->data[s] * master->data[s]; + } - if(!samples.size()) return NULL; // No samples to choose from. + power = sqrt(power); - float power_span = power_max - power_min; + sample->power = power; + } +#endif /*AUTO_CALCULATE_POWER*/ - // Width is limited to at least 10. Fioxes problem with instrument with a - // sample set smaller than MIN_SAMPLE_SET_SIZE. - float width = fmax(samples.size(), MIN_SAMPLE_SET_SIZE); + item.power = sample->power; - // Spread out at most ~2 samples away from center if all samples have a - // uniform distribution over the power spectrum (which they probably don't). - float stddev = power_span / width; + if(item.power > power_max) + power_max = item.power; + if(item.power < power_min) + power_min = item.power; - // Cut off mean value with stddev/2 in both ends in order to make room for - // downwards expansion on velocity 0 and upwards expansion on velocity 1. - float mean = level * (power_span - stddev) + (stddev / 2.0); + DEBUG(rand, " - power: %f\n", item.power); -again: - // Select normal distributed value between - // (stddev/2) and (power_span-stddev/2) - float lvl = box_muller_transform(mean, stddev); - - // Adjust this value to be in range - // (power_min+stddev/2) and (power_max-stddev/2) - lvl += power_min; + si++; + } +} - DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f)\n", - level, lvl, mean, stddev); +Sample* PowerList::get(level_t level) +{ + int retry = 3; // TODO: This must be user controllable via the UI. - float power = 0; - std::vector<PowerListItem>::iterator i = samples.begin(); - while(i != samples.end()) { - if(sample == NULL) { - sample = i->sample; - power = i->power; - } + Sample* sample = nullptr; - if(fabs(i->power - lvl) < fabs(power - lvl)) { - sample = i->sample; - power = i->power; - } + if(!samples.size()) + { + return nullptr; // No samples to choose from. + } - i++; - } + float power_span = power_max - power_min; - if(lastsample == sample && retry--) { - DEBUG(rand, "Retry [%d retries left]", retry); - goto again; - } + // Width is limited to at least 10. Fioxes problem with instrument with a + // sample set smaller than MIN_SAMPLE_SET_SIZE. + float width = fmax(samples.size(), MIN_SAMPLE_SET_SIZE); - DEBUG(rand, "Found sample with power %f\n", power); + // Spread out at most ~2 samples away from center if all samples have a + // uniform distribution over the power spectrum (which they probably don't). + float stddev = power_span / width; - lastsample = sample; + // Cut off mean value with stddev/2 in both ends in order to make room for + // downwards expansion on velocity 0 and upwards expansion on velocity 1. + float mean = level * (power_span - stddev) + (stddev / 2.0); - return sample; +again: + // Select normal distributed value between + // (stddev/2) and (power_span-stddev/2) + float lvl = rand.normalDistribution(mean, stddev); + + // Adjust this value to be in range + // (power_min+stddev/2) and (power_max-stddev/2) + lvl += power_min; + + DEBUG(rand, "level: %f, lvl: %f (mean: %.2f, stddev: %.2f)\n", level, lvl, + mean, stddev); + + float power = 0; + std::vector<PowerListItem>::iterator i = samples.begin(); + while(i != samples.end()) + { + if(sample == nullptr) + { + sample = i->sample; + power = i->power; + } + + if(fabs(i->power - lvl) < fabs(power - lvl)) + { + sample = i->sample; + power = i->power; + } + + i++; + } + + if(lastsample == sample && retry--) + { + DEBUG(rand, "Retry [%d retries left]", retry); + goto again; + } + + DEBUG(rand, "Found sample with power %f\n", power); + + lastsample = sample; + + return sample; } diff --git a/src/powerlist.h b/src/powerlist.h index 43f51d2..a3af475 100644 --- a/src/powerlist.h +++ b/src/powerlist.h @@ -24,35 +24,37 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_POWERLIST_H__ -#define __DRUMGIZMO_POWERLIST_H__ +#pragma once #include <vector> #include "sample.h" +#include "random.h" -class PowerList { +class PowerList +{ public: - PowerList(); + PowerList(); - void add(Sample *s); - void finalise(); ///< Call this when no more samples will be added. + void add(Sample* s); + void finalise(); ///< Call this when no more samples will be added. - Sample *get(level_t velocity); + Sample* get(level_t velocity); private: - class PowerListItem { - public: - Sample *sample; - float power; - }; - - std::vector<PowerListItem> samples; - float power_max; - float power_min; - - Channel *getMasterChannel(); - Sample *lastsample; -}; + class PowerListItem + { + public: + Sample* sample; + float power; + }; + + Random rand; -#endif/*__DRUMGIZMO_POWERLIST_H__*/ + std::vector<PowerListItem> samples; + float power_max; + float power_min; + + Channel* getMasterChannel(); + Sample* lastsample; +}; diff --git a/src/random.cc b/src/random.cc new file mode 100644 index 0000000..1df9a62 --- /dev/null +++ b/src/random.cc @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * random.cc + * + * Wed Mar 23 19:17:24 CET 2016 + * Copyright 2016 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "random.h" + +#include <chrono> + +Random::Random() + : Random(std::chrono::system_clock::now().time_since_epoch().count()) +{ + +} + +Random::Random(unsigned int seed) +{ + generator.seed(seed); +} + +int Random::intInRange(int lower_bound, int upper_bound) +{ + std::uniform_int_distribution<int> distribution(lower_bound, upper_bound); + return distribution(generator); +} + +float Random::floatInRange(float lower_bound, float upper_bound) +{ + std::uniform_real_distribution<float> distribution(lower_bound, upper_bound); + return distribution(generator); +} + +float Random::normalDistribution(float mean, float stddev) +{ + std::normal_distribution<float> distribution(mean, stddev); + return distribution(generator); +} diff --git a/src/random.h b/src/random.h new file mode 100644 index 0000000..9eaefad --- /dev/null +++ b/src/random.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * random.h + * + * Wed Mar 23 19:17:24 CET 2016 + * Copyright 2016 André Nusser + * andre.nusser@googlemail.com + ****************************************************************************/ + +/* + * This file is part of DrumGizmo. + * + * DrumGizmo is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * DrumGizmo 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with DrumGizmo; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#pragma once + +#include <random> +#include <vector> + +class Random +{ +public: + Random(); + Random(unsigned int seed); + + //! \return random int in range [<lower_bound>, <upper_bound>]. + int intInRange(int lower_bound, int upper_bound); + + //! \return random float in range [<lower_bound>, <upper_bound>]. + float floatInRange(float lower_bound, float upper_bound); + + //! \return random float drawn from a normal distribution with mean <mean> + //! and standard deviation <stddev>. + float normalDistribution(float mean, float stddev); + + //! \return uniformly at random chosen element from <vec>. + template <typename T> + T& choose(std::vector<T>& vec); + +private: + std::default_random_engine generator; +}; + +template <typename T> +T& Random::choose(std::vector<T>& vec) +{ + std::uniform_int_distribution<size_t> distribution(0, vec.size()-1); + size_t rand_index = distribution(generator); + return vec[rand_index]; +} diff --git a/src/rangemap.h b/src/rangemap.h index 34a50b1..4c427e7 100644 --- a/src/rangemap.h +++ b/src/rangemap.h @@ -24,68 +24,74 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_RANGEMAP_H__ -#define __DRUMGIZMO_RANGEMAP_H__ +#pragma once #include <vector> #include <map> -template<typename T1, typename T2> -class RangeMap { +template <typename T1, typename T2> class RangeMap +{ public: - void insert(T1 from, T1 to, T2 value); - std::vector<T2> get(T1 from, T1 to); - std::vector<T2> get(T1 at); + void insert(T1 from, T1 to, T2 value); + std::vector<T2> get(T1 from, T1 to); + std::vector<T2> get(T1 at); private: - std::multimap<std::pair<T1, T1>, T2> values; + std::multimap<std::pair<T1, T1>, T2> values; }; -template<typename T1, typename T2> +template <typename T1, typename T2> void RangeMap<T1, T2>::insert(T1 from, T1 to, T2 value) { - if(from < to) values.insert(std::make_pair(std::make_pair(from, to), value)); - else values.insert(std::make_pair(std::make_pair(to, from), value)); + if(from < to) + { + values.insert(std::make_pair(std::make_pair(from, to), value)); + } + else + { + values.insert(std::make_pair(std::make_pair(to, from), value)); + } } -template<typename T1, typename T2> +template <typename T1, typename T2> std::vector<T2> RangeMap<T1, T2>::get(T1 from, T1 to) { - std::vector<T2> res; + std::vector<T2> res; - typename std::multimap<std::pair<T1, T1>, T2>::iterator i = values.begin(); - while(i != values.end()) { - T1 a = i->first.first; - T1 b = i->first.second; - if( - (from >= a && to <= b) || // inside - (from <= a && to >= b) || // containing - (from <= a && to >= a && to <= b) || // overlapping lower - (from >= a && from <= b && to >= b) // overlapping upper - ) - res.push_back(i->second); - i++; - } + typename std::multimap<std::pair<T1, T1>, T2>::iterator i = values.begin(); + while(i != values.end()) + { + T1 a = i->first.first; + T1 b = i->first.second; + if((from >= a && to <= b) || // inside + (from <= a && to >= b) || // containing + (from <= a && to >= a && to <= b) || // overlapping lower + (from >= a && from <= b && to >= b) // overlapping upper + ) + { + res.push_back(i->second); + } + i++; + } - return res; + return res; } -template<typename T1, typename T2> -std::vector<T2> RangeMap<T1, T2>::get(T1 at) +template <typename T1, typename T2> std::vector<T2> RangeMap<T1, T2>::get(T1 at) { - std::vector<T2> res; + std::vector<T2> res; - typename std::multimap<std::pair<T1, T1>, T2>::iterator i = values.begin(); - while(i != values.end()) { - T1 a = i->first.first; - T1 b = i->first.second; - if(at >= a && at <= b) - res.push_back(i->second); - i++; - } + typename std::multimap<std::pair<T1, T1>, T2>::iterator i = values.begin(); + while(i != values.end()) + { + T1 a = i->first.first; + T1 b = i->first.second; + if(at >= a && at <= b) + { + res.push_back(i->second); + } + i++; + } - return res; + return res; } - - -#endif/*__DRUMGIZMO_RANGEMAP_H__*/ diff --git a/src/sample.cc b/src/sample.cc index 22bee14..ced8a47 100644 --- a/src/sample.cc +++ b/src/sample.cc @@ -26,9 +26,15 @@ */ #include "sample.h" +#include <stdlib.h> +#include <unistd.h> + +#include <sndfile.h> + Sample::Sample(const std::string& name, float power) - : name(name) - , power(power) + : name{name} + , power{power} + , audiofiles{} { } @@ -36,25 +42,24 @@ Sample::~Sample() { } -void Sample::addAudioFile(InstrumentChannel* instrument_channel, - AudioFile* audio_file) +void Sample::addAudioFile(Channel* c, AudioFile* a) { - audiofiles[instrument_channel] = audio_file; + audiofiles[c] = a; } -AudioFile *Sample::getAudioFile(InstrumentChannel* instrument_channel) +AudioFile* Sample::getAudioFile(Channel* c) { /* - if(audiofiles.find(c) == audiofiles.end()) return NULL; - return audiofiles[c]; + if(audiofiles.find(c) == audiofiles.end()) return nullptr; + return audiofiles[c]; */ - for(auto& audio_file : audiofiles) + // todo: std::find_if ?? + for (auto& pair: audiofiles) { - InstrumentChannel *ch = audio_file.first; - if(instrument_channel->num == ch->num) + if (pair.first->num == c->num) { - return audio_file.second; + return pair.second; } } diff --git a/src/saxparser.h b/src/saxparser.h index 8cfbdda..4b1a273 100644 --- a/src/saxparser.h +++ b/src/saxparser.h @@ -27,7 +27,7 @@ #pragma once #include <string> -#include <map> +#include <unordered_map> #include <expat.h> #include <fstream> @@ -45,7 +45,7 @@ public: const std::string& xml_source_name = ""); protected: - using attr_t = std::map<std::string, std::string>; + using attr_t = std::unordered_map<std::string, std::string>; virtual void characterData(const std::string& data) {} virtual void startTag(const std::string& name, const attr_t& attr) {} diff --git a/src/settings.h b/src/settings.h index eb18909..ed031b2 100644 --- a/src/settings.h +++ b/src/settings.h @@ -49,7 +49,6 @@ struct Settings Atomic<int> number_of_files; Atomic<int> number_of_files_loaded; Atomic<std::string> current_file; - }; //! Getter utility class. diff --git a/src/velocity.cc b/src/velocity.cc index 04d0475..c8faa32 100644 --- a/src/velocity.cc +++ b/src/velocity.cc @@ -29,33 +29,40 @@ #include <stdlib.h> Velocity::Velocity(unsigned int lower, unsigned int upper) + : lower{lower} + , upper{upper} + , samples{} { - this->lower = lower; - this->upper = upper; } -void Velocity::addSample(Sample *sample, float probability) +void Velocity::addSample(Sample* sample, float probability) { - if(samples.find(sample) != samples.end()) { - samples[sample] += probability; - } else { - samples[sample] = probability; - } + if(samples.find(sample) != samples.end()) + { + samples[sample] += probability; + } + else + { + samples[sample] = probability; + } } -Sample *Velocity::getSample() +Sample* Velocity::getSample() { - Sample *sample = NULL; - - float x = (float)rand() / (float)RAND_MAX; - float sum = 0.0; - - Samples::iterator i = samples.begin(); - while(i != samples.end() && x > sum) { - sum += i->second; - sample = i->first; - i++; - } - - return sample; + Sample* sample{nullptr}; + + float x = rand.floatInRange(0, 1); + float sum = 0.0; + + for (auto const & pair: samples) + { + if (x > sum) + { + break; + } + sum += pair.second; + sample = pair.first; + } + + return sample; } diff --git a/src/velocity.h b/src/velocity.h index 439ca68..19284a4 100644 --- a/src/velocity.h +++ b/src/velocity.h @@ -24,26 +24,27 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __DRUMGIZMO_VELOCITY_H__ -#define __DRUMGIZMO_VELOCITY_H__ +#pragma once #include <map> #include "sample.h" +#include "random.h" -class Velocity { +class Velocity +{ public: - Velocity(unsigned int lower, unsigned int upper); + Velocity(unsigned int lower, unsigned int upper); - void addSample(Sample *sample, float probability); - Sample *getSample(); + void addSample(Sample* sample, float probability); + Sample* getSample(); - unsigned int lower; - unsigned int upper; + unsigned int lower; + unsigned int upper; private: - typedef std::map< Sample *, float > Samples; - Samples samples; -}; + typedef std::map<Sample*, float> Samples; + Samples samples; -#endif/*__DRUMGIZMO_VELOCITY_H__*/ + Random rand; +}; diff --git a/src/versionstr.cc b/src/versionstr.cc index 48764ba..604d7c1 100644 --- a/src/versionstr.cc +++ b/src/versionstr.cc @@ -31,7 +31,8 @@ #include <stdlib.h> #include <stdio.h> -// Workaround - major, minor and patch are defined as macros when using _GNU_SOURCES +// Workaround - major, minor and patch are defined as macros when using +// _GNU_SOURCES #ifdef major #undef major #endif @@ -42,110 +43,138 @@ #undef patch #endif -VersionStr::VersionStr(std::string v) throw(const char *) +VersionStr::VersionStr(const std::string& v) throw(const char*) { - memset(version, 0, sizeof(version)); - set(v); + memset(version, 0, sizeof(version)); + set(v); } VersionStr::VersionStr(size_t major, size_t minor, size_t patch) { - version[0] = major; - version[1] = minor; - version[2] = patch; + version[0] = major; + version[1] = minor; + version[2] = patch; } -void VersionStr::set(std::string v) throw(const char *) +void VersionStr::set(const std::string& v) throw(const char*) { - std::string num; - size_t idx = 0; - for(size_t i = 0; i < v.length(); i++) { - if(v[i] == '.') { - if(idx > 2) throw "Version string is too long."; - version[idx] = atoi(num.c_str()); - idx++; - num = ""; - } else if(v[i] >= '0' && v[i] <= '9') { - num.append(1, v[i]); - } else { - throw "Version string contains illegal character."; - } - } - if(idx > 2) throw "Version string is too long."; - version[idx] = atoi(num.c_str()); + std::string num; + size_t idx = 0; + for(size_t i = 0; i < v.length(); i++) + { + if(v[i] == '.') + { + if(idx > 2) + { + throw "Version string is too long."; + } + version[idx] = atoi(num.c_str()); + idx++; + num = ""; + } + else if(v[i] >= '0' && v[i] <= '9') + { + num.append(1, v[i]); + } + else + { + throw "Version string contains illegal character."; + } + } + if(idx > 2) + { + throw "Version string is too long."; + } + version[idx] = atoi(num.c_str()); } VersionStr::operator std::string() const { - std::string v; - char buf[64]; - if(patch()) { - sprintf(buf, "%d.%d.%d", (int)major(), (int)minor(), (int)patch()); - } else { - sprintf(buf, "%d.%d", (int)major(), (int)minor()); - } - v = buf; - return v; + std::string v; + char buf[64]; + if(patch()) + { + sprintf(buf, "%d.%d.%d", (int)major(), (int)minor(), (int)patch()); + } + else + { + sprintf(buf, "%d.%d", (int)major(), (int)minor()); + } + v = buf; + return v; } - -void VersionStr::operator=(std::string v) throw(const char *) + +void VersionStr::operator=(const std::string& v) throw(const char*) { - set(v); + set(v); } // return a - b simplified as -1, 0 or 1 -static int vdiff(const VersionStr &a, const VersionStr &b) +static int vdiff(const VersionStr& a, const VersionStr& b) { - if(a.major() < b.major()) return -1; - if(a.major() > b.major()) return 1; - if(a.minor() < b.minor()) return -1; - if(a.minor() > b.minor()) return 1; - if(a.patch() < b.patch()) return -1; - if(a.patch() > b.patch()) return 1; - return 0; + if(a.major() < b.major()) + { + return -1; + } + if(a.major() > b.major()) + { + return 1; + } + if(a.minor() < b.minor()) + { + return -1; + } + if(a.minor() > b.minor()) + { + return 1; + } + if(a.patch() < b.patch()) + { + return -1; + } + if(a.patch() > b.patch()) + { + return 1; + } + return 0; } -bool VersionStr::operator<(const VersionStr &other) const +bool VersionStr::operator<(const VersionStr& other) const { - if(vdiff(*this, other) == -1) return true; - return false; + return vdiff(*this, other) == -1; } -bool VersionStr::operator>(const VersionStr &other) const +bool VersionStr::operator>(const VersionStr& other) const { - if(vdiff(*this, other) == 1) return true; - return false; + return vdiff(*this, other) == 1; } -bool VersionStr::operator==(const VersionStr &other) const +bool VersionStr::operator==(const VersionStr& other) const { - if(vdiff(*this, other) == 0) return true; - return false; + return vdiff(*this, other) == 0; } -bool VersionStr::operator<=(const VersionStr &other) const +bool VersionStr::operator<=(const VersionStr& other) const { - if(vdiff(*this, other) != 1) return true; - return false; + return vdiff(*this, other) != 1; } -bool VersionStr::operator>=(const VersionStr &other) const +bool VersionStr::operator>=(const VersionStr& other) const { - if(vdiff(*this, other) != -1) return true; - return false; + return vdiff(*this, other) != -1; } size_t VersionStr::major() const { - return version[0]; + return version[0]; } size_t VersionStr::minor() const { - return version[1]; + return version[1]; } size_t VersionStr::patch() const { - return version[2]; + return version[2]; } diff --git a/src/versionstr.h b/src/versionstr.h index 9cdd056..f168332 100644 --- a/src/versionstr.h +++ b/src/versionstr.h @@ -25,12 +25,12 @@ * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#ifndef __PRACRO_VERSIONSTR_H__ -#define __PRACRO_VERSIONSTR_H__ +#pragma once #include <string> -// Workaround - major, minor and patch are defined as macros when using _GNU_SOURCES +// Workaround - major, minor and patch are defined as macros when using +// _GNU_SOURCES #ifdef major #undef major #endif @@ -43,70 +43,70 @@ /** * VersionStr class. - * It hold a version number and is capable of correct sorting, as well as string + * It hold a version number and is capable of correct sorting, as well as string * conversion both ways. */ -class VersionStr { +class VersionStr +{ public: - /** - * Constructor. - * Throws an exeption if the string does not parse. - * @param v A std::string containing a version string on the form a.b or a.b.c - */ - VersionStr(std::string v) throw(const char *); + /** + * Constructor. + * Throws an exeption if the string does not parse. + * @param v A std::string containing a version string on the form a.b or + * a.b.c + */ + VersionStr(const std::string& v) throw(const char*); - /** - * Constructor. - * @param major A size_t containing the major version number. - * @param minor A size_t containing the minor version number. - * @param patch A size_t containing the patch level. - */ - VersionStr(size_t major = 0, size_t minor = 0, size_t patch = 0); + /** + * Constructor. + * @param major A size_t containing the major version number. + * @param minor A size_t containing the minor version number. + * @param patch A size_t containing the patch level. + */ + VersionStr(size_t major = 0, size_t minor = 0, size_t patch = 0); - /** - * Typecast to std::string operator. - * It simply converts the version numbers into a string of the form major.minor - * (if patch i 0) or major.minor.patch - */ - operator std::string() const; + /** + * Typecast to std::string operator. + * It simply converts the version numbers into a string of the form + * major.minor + * (if patch i 0) or major.minor.patch + */ + operator std::string() const; - /** - * Assignment from std::string operator. - * Same as in the VersionStr(std::string v) constructor. - * Throws an exeption if the string does not parse. - */ - void operator=(std::string v) throw(const char *); + /** + * Assignment from std::string operator. + * Same as in the VersionStr(std::string v) constructor. + * Throws an exeption if the string does not parse. + */ + void operator=(const std::string& v) throw(const char*); - /** - * Comparison operator. - * The version objects are sorted according to their major, minor and patch - * level numbers. - */ - bool operator<(const VersionStr &other) const; - bool operator==(const VersionStr &other) const; - bool operator>(const VersionStr &other) const; - bool operator>=(const VersionStr &other) const; - bool operator<=(const VersionStr &other) const; + /** + * Comparison operator. + * The version objects are sorted according to their major, minor and patch + * level numbers. + */ + bool operator<(const VersionStr& other) const; + bool operator==(const VersionStr& other) const; + bool operator>(const VersionStr& other) const; + bool operator>=(const VersionStr& other) const; + bool operator<=(const VersionStr& other) const; + /** + * @return Major version number. + */ + size_t major() const; - /** - * @return Major version number. - */ - size_t major() const; + /** + * @return Minor version number. + */ + size_t minor() const; - /** - * @return Minor version number. - */ - size_t minor() const; - - /** - * @return Patch level. - */ - size_t patch() const; + /** + * @return Patch level. + */ + size_t patch() const; private: - void set(std::string v) throw(const char *); - size_t version[3]; + void set(const std::string& v) throw(const char*); + size_t version[3]; }; - -#endif/*__PRACRO_VERSIONSTR_H__*/ |