diff --git a/src/envelope_widget.cpp b/src/envelope_widget.cpp index 159981f..485fde8 100644 --- a/src/envelope_widget.cpp +++ b/src/envelope_widget.cpp @@ -42,12 +42,12 @@ RK_DECLARE_IMAGE_RC(layer3_env_active); EnvelopeWidget::EnvelopeWidget(GeonkickWidget *parent, GeonkickApi *api, const std::vector> &oscillators) - : GeonkickWidget(parent) - , drawArea{nullptr} - , layer1Button{nullptr} - , layer2Button{nullptr} - , layer3Button{nullptr} - , geonkickApi{api} + : GeonkickWidget(parent) + , drawArea{nullptr} + , layer1Button{nullptr} + , layer2Button{nullptr} + , layer3Button{nullptr} + , geonkickApi{api} { // Create drawing area. drawArea = new EnvelopeWidgetDrawingArea(this, geonkickApi); @@ -55,26 +55,30 @@ EnvelopeWidget::EnvelopeWidget(GeonkickWidget *parent, // Oscillator1 envelope auto oscillator = oscillators[static_cast(Oscillator::Type::Oscillator1)].get(); - auto envelope = std::dynamic_pointer_cast(std::make_shared(oscillator, rect)); - envelopes.insert({static_cast(Envelope::Category::Oscillator1), envelope}); + auto envelope = std::make_unique(oscillator, rect); envelope->setCategory(Envelope::Category::Oscillator1); + envelopes.insert({static_cast(Envelope::Category::Oscillator1), + std::move(envelope)}); // Oscillator2 envelope oscillator = oscillators[static_cast(Oscillator::Type::Oscillator2)].get(); - envelope = std::dynamic_pointer_cast(std::make_shared(oscillator, rect)); - envelopes.insert({static_cast(Envelope::Category::Oscillator2), envelope}); + envelope = std::make_unique(oscillator, rect); envelope->setCategory(Envelope::Category::Oscillator2); + envelopes.insert({static_cast(Envelope::Category::Oscillator2), + std::move(envelope)}); // Noise envelope oscillator = oscillators[static_cast(Oscillator::Type::Noise)].get(); - envelope = std::dynamic_pointer_cast(std::make_shared(oscillator, rect)); - envelopes.insert({static_cast(Envelope::Category::Noise), envelope}); + envelope = std::make_unique(oscillator, rect); envelope->setCategory(Envelope::Category::Noise); + envelopes.insert({static_cast(Envelope::Category::Noise), + std::move(envelope)}); // General envelope - envelope = std::dynamic_pointer_cast(std::make_shared(geonkickApi, rect)); - envelopes.insert({static_cast(Envelope::Category::General), envelope}); - envelope->setCategory(Envelope::Category::General); + auto generalEnvelope = std::make_unique(geonkickApi, rect); + generalEnvelope->setCategory(Envelope::Category::General); + envelopes.insert({static_cast(Envelope::Category::General), + std::move(generalEnvelope)}); createButtomMenu(); showEnvelope(Envelope::Category::General, Envelope::Type::Amplitude); RK_ACT_BIND(viewState(), envelopeChanged, diff --git a/src/envelope_widget.h b/src/envelope_widget.h index e4ef60d..2e0f430 100644 --- a/src/envelope_widget.h +++ b/src/envelope_widget.h @@ -61,7 +61,7 @@ class EnvelopeWidget : public GeonkickWidget void createPointInfoLabel(); private: - std::unordered_map> envelopes; + std::unordered_map> envelopes; EnvelopeWidgetDrawingArea *drawArea; GeonkickButton *layer1Button; GeonkickButton *layer2Button; diff --git a/src/geonkick_api.cpp b/src/geonkick_api.cpp index 8b51dcc..ecca17d 100755 --- a/src/geonkick_api.cpp +++ b/src/geonkick_api.cpp @@ -141,9 +141,9 @@ std::unique_ptr GeonkickApi::getDefaultKitState() return std::make_unique(); } -std::shared_ptr GeonkickApi::getDefaultPercussionState() +std::unique_ptr GeonkickApi::getDefaultPercussionState() { - std::shared_ptr state = std::make_shared(); + auto state = std::make_unique(); state->setName("Default"); state->setId(0); state->setPlayingKey(-1); @@ -240,7 +240,7 @@ std::shared_ptr GeonkickApi::getDefaultPercussionState() return state; } -void GeonkickApi::setPercussionState(const std::shared_ptr &state) +void GeonkickApi::setPercussionState(const std::unique_ptr &state) { if (!state) return; @@ -307,7 +307,7 @@ void GeonkickApi::setPercussionState(const std::string &data) setPercussionState(state); } -std::shared_ptr GeonkickApi::getPercussionState(size_t id) const +std::unique_ptr GeonkickApi::getPercussionState(size_t id) const { if (id == currentPercussion()) { return getPercussionState(); @@ -324,9 +324,9 @@ std::shared_ptr GeonkickApi::getPercussionState(size_t id) cons } } -std::shared_ptr GeonkickApi::getPercussionState() const +std::unique_ptr GeonkickApi::getPercussionState() const { - auto state = std::make_shared(); + auto state = std::make_unique(); state->setId(currentPercussion()); state->setName(getPercussionName(state->getId())); state->setLimiterValue(limiterValue()); @@ -381,7 +381,7 @@ std::shared_ptr GeonkickApi::getPercussionState() const void GeonkickApi::getOscillatorState(GeonkickApi::Layer layer, OscillatorType osc, - const std::shared_ptr &state) const + const std::unique_ptr &state) const { auto temp = currentLayer; currentLayer = layer; @@ -423,7 +423,7 @@ void GeonkickApi::getOscillatorState(GeonkickApi::Layer layer, void GeonkickApi::setOscillatorState(GeonkickApi::Layer layer, OscillatorType oscillator, - const std::shared_ptr &state) + const std::unique_ptr &state) { auto temp = currentLayer; currentLayer = layer; @@ -479,7 +479,7 @@ std::unique_ptr GeonkickApi::getKitState() const for (const auto &id : ordredPercussionIds()) { auto state = getPercussionState(id); state->setId(i); - kit->addPercussion(state); + kit->addPercussion(std::move(state)); GEONKICK_LOG_DEBUG("PER: " << state->getName() << ": id = " << state->getId()); i++; } @@ -1631,7 +1631,7 @@ void GeonkickApi::copyToClipboard() void GeonkickApi::pasteFromClipboard() { if (clipboardPercussion) { - auto state = std::make_shared(*clipboardPercussion); + auto state = std::make_unique(*clipboardPercussion); auto currId = currentPercussion(); state->setId(currId); state->setName(getPercussionName(currId)); diff --git a/src/geonkick_api.h b/src/geonkick_api.h index 94e2cd3..a523ba6 100755 --- a/src/geonkick_api.h +++ b/src/geonkick_api.h @@ -185,15 +185,15 @@ class GeonkickApi : public RkObject { double limiterValue() const; int getSampleRate() const; static std::unique_ptr getDefaultKitState(); - static std::shared_ptr getDefaultPercussionState(); + static std::unique_ptr getDefaultPercussionState(); // This function is called only from the audio thread. void setKeyPressed(bool b, int note, int velocity); // This function is called only from the audio thread. void process(float** out, size_t channel, size_t size); - std::shared_ptr getPercussionState(size_t id) const; - std::shared_ptr getPercussionState() const; + std::unique_ptr getPercussionState(size_t id) const; + std::unique_ptr getPercussionState() const; bool isCompressorEnabled() const; double getCompressorAttack() const; double getCompressorRelease() const; @@ -216,7 +216,7 @@ class GeonkickApi : public RkObject { void enableKickFilter(bool b); void setKickFilterType(FilterType type); void setPercussionState(const std::string &data); - void setPercussionState(const std::shared_ptr &state); + void setPercussionState(const std::unique_ptr &state); std::unique_ptr getKitState() const; bool setKitState(const std::string &data); bool setKitState(const std::unique_ptr &state); @@ -353,10 +353,10 @@ class GeonkickApi : public RkObject { void updateKickBuffer(const std::vector &&buffer, size_t id); void setOscillatorState(Layer layer, OscillatorType oscillator, - const std::shared_ptr &state); + const std::unique_ptr &state); void getOscillatorState(Layer layer, OscillatorType osc, - const std::shared_ptr &state) const; + const std::unique_ptr &state) const; void setLimiterLevelerValue(size_t index, double val); static std::vector loadSample(const std::string &file, double length = 4.0, @@ -376,7 +376,7 @@ class GeonkickApi : public RkObject { std::string kitName; std::string kitAuthor; std::string kitUrl; - std::shared_ptr clipboardPercussion; + std::unique_ptr clipboardPercussion; /** * Current working paths for entire application. diff --git a/src/kit_state.cpp b/src/kit_state.cpp index 0624286..0956efe 100755 --- a/src/kit_state.cpp +++ b/src/kit_state.cpp @@ -118,7 +118,7 @@ std::string KitState::getUrl() const return kitUrl; } -std::vector>& KitState::percussions() +const std::vector>& KitState::percussions() const { return percussionsList; } @@ -152,10 +152,10 @@ void KitState::parsePercussions(const rapidjson::Value &percussionsArray) { size_t i = 0; for (const auto &per: percussionsArray.GetArray()) { - auto state = std::make_shared(); + auto state = std::make_unique(); state->setId(i++); state->loadObject(per); - addPercussion(state); + addPercussion(std::move(state)); } } @@ -182,14 +182,14 @@ std::string KitState::toJson() const return jsonStream.str(); } -void KitState::addPercussion(const std::shared_ptr &percussion) +void KitState::addPercussion(std::unique_ptr percussion) { - percussionsList.push_back(percussion); + percussionsList.push_back(std::move(percussion)); } -std::shared_ptr KitState::getPercussion(size_t id) +const PercussionState* KitState::getPercussion(size_t id) const { if (id < percussionsList.size()) - return percussionsList[id]; + return percussionsList[id].get(); return nullptr; } diff --git a/src/kit_state.h b/src/kit_state.h index 952c605..72efad3 100644 --- a/src/kit_state.h +++ b/src/kit_state.h @@ -43,15 +43,15 @@ class KitState { void setUrl(const std::string &url); std::string getUrl() const; std::string toJson() const; - void addPercussion(const std::shared_ptr &percussion); - std::shared_ptr getPercussion(size_t id); - std::vector>& percussions(); + void addPercussion(std::unique_ptr percussion); + const PercussionState* getPercussion(size_t id) const; + const std::vector>& percussions() const; protected: void parsePercussions(const rapidjson::Value &percussionsArray); private: - std::vector> percussionsList; + std::vector> percussionsList; int kitAppVersion; std::string kitName; std::string kitAuthor; diff --git a/src/percussion_state.cpp b/src/percussion_state.cpp index 52b5c8b..b672ead 100755 --- a/src/percussion_state.cpp +++ b/src/percussion_state.cpp @@ -203,14 +203,14 @@ void PercussionState::initOscillators() { for (decltype(layers.size()) i = 0; i < layers.size(); i++) { oscillators.insert({static_cast(GeonkickApi::OscillatorType::Oscillator1) - + GKICK_OSC_GROUP_SIZE * i, - std::make_shared()}); + + GKICK_OSC_GROUP_SIZE * i, + OscillatorInfo()}); oscillators.insert({static_cast(GeonkickApi::OscillatorType::Oscillator2) - + GKICK_OSC_GROUP_SIZE * i, - std::make_shared()}); + + GKICK_OSC_GROUP_SIZE * i, + OscillatorInfo()}); oscillators.insert({static_cast(GeonkickApi::OscillatorType::Noise) - + GKICK_OSC_GROUP_SIZE * i, - std::make_shared()}); + + GKICK_OSC_GROUP_SIZE * i, + OscillatorInfo()}); } } @@ -563,13 +563,24 @@ PercussionState::getKickEnvelopePoints(GeonkickApi::EnvelopeType envelope) const } } -std::shared_ptr -PercussionState::getOscillator(int index) const +PercussionState::OscillatorInfo* +PercussionState::getOscillator(int index) { index += GKICK_OSC_GROUP_SIZE * static_cast(currentLayer); auto it = oscillators.find(index); if (it != oscillators.end()) - return it->second; + return &it->second; + + return nullptr; +} + +const PercussionState::OscillatorInfo* +PercussionState::getConstOscillator(int index) const +{ + index += GKICK_OSC_GROUP_SIZE * static_cast(currentLayer); + auto it = oscillators.find(index); + if (it != oscillators.end()) + return &it->second; return nullptr; } @@ -701,7 +712,7 @@ void PercussionState::setOscillatorEnvelopeApplyType(int index, GeonkickApi::EnvelopeApplyType PercussionState::getOscillatorEnvelopeApplyType(int index, GeonkickApi::EnvelopeType envelope) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (!oscillator) return GeonkickApi::EnvelopeApplyType::Linear; @@ -718,7 +729,7 @@ GeonkickApi::EnvelopeApplyType PercussionState::getOscillatorEnvelopeApplyType(i bool PercussionState::isOscillatorAsFm(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->isFm; return false; @@ -733,7 +744,7 @@ void PercussionState::setOscillatorAsFm(int index, bool b) bool PercussionState::isOscillatorEnabled(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->isEnabled; @@ -742,7 +753,7 @@ bool PercussionState::isOscillatorEnabled(int index) const GeonkickApi::FunctionType PercussionState::oscillatorFunction(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->function; @@ -751,7 +762,7 @@ GeonkickApi::FunctionType PercussionState::oscillatorFunction(int index) const double PercussionState::oscillatorPhase(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->phase; @@ -760,7 +771,7 @@ double PercussionState::oscillatorPhase(int index) const int PercussionState::oscillatorSeed(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->seed; @@ -769,35 +780,35 @@ int PercussionState::oscillatorSeed(int index) const double PercussionState::oscillatorAmplitue(int index) const { - if (auto oscillator = getOscillator(index); oscillator) + if (auto oscillator = getConstOscillator(index); oscillator) return oscillator->amplitude; return 0; } double PercussionState::oscillatorFrequency(int index) const { - if (auto oscillator = getOscillator(index); oscillator) + if (auto oscillator = getConstOscillator(index); oscillator) return oscillator->frequency; return 0; } double PercussionState::oscillatorPitchShift(int index) const { - if (auto oscillator = getOscillator(index); oscillator) + if (auto oscillator = getConstOscillator(index); oscillator) return oscillator->pitchShift; return 0; } bool PercussionState::isOscillatorFilterEnabled(int index) const { - if (auto oscillator = getOscillator(index); oscillator) + if (auto oscillator = getConstOscillator(index); oscillator) return oscillator->isFilterEnabled; return false; } GeonkickApi::FilterType PercussionState::oscillatorFilterType(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->filterType; return GeonkickApi::FilterType::LowPass; @@ -805,7 +816,7 @@ GeonkickApi::FilterType PercussionState::oscillatorFilterType(int index) const double PercussionState::oscillatorFilterCutOffFreq(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->filterFrequency; return 0; @@ -813,7 +824,7 @@ double PercussionState::oscillatorFilterCutOffFreq(int index) const double PercussionState::oscillatorFilterFactor(int index) const { - auto oscillator = getOscillator(index); + auto oscillator = getConstOscillator(index); if (oscillator) return oscillator->filterFactor; return 0; @@ -822,7 +833,7 @@ double PercussionState::oscillatorFilterFactor(int index) const std::vector PercussionState::oscillatorEnvelopePoints(int index, GeonkickApi::EnvelopeType type) const { - if (auto oscillator = getOscillator(index); oscillator) { + if (auto oscillator = getConstOscillator(index); oscillator) { switch (type) { case GeonkickApi::EnvelopeType::Amplitude: return oscillator->amplitudeEnvelope; @@ -988,41 +999,41 @@ void PercussionState::oscJson(std::ostringstream &jsonStream) const { for (const auto& val: oscillators) { jsonStream << "\"osc" << val.first << "\": {" << std::endl; - jsonStream << "\"enabled\": " << (val.second->isEnabled ? "true" : "false") << ", " << std::endl; - jsonStream << "\"is_fm\": " << (val.second->isFm ? "true" : "false") << ", " << std::endl; - if (val.second->function == GeonkickApi::FunctionType::Sample && !val.second->sample.empty()) - jsonStream << "\"sample\": \"" << toBase64F(val.second->sample) << "\"," << std::endl; - jsonStream << "\"function\": " << static_cast(val.second->function) << "," << std::endl; + jsonStream << "\"enabled\": " << (val.second.isEnabled ? "true" : "false") << ", " << std::endl; + jsonStream << "\"is_fm\": " << (val.second.isFm ? "true" : "false") << ", " << std::endl; + if (val.second.function == GeonkickApi::FunctionType::Sample && !val.second.sample.empty()) + jsonStream << "\"sample\": \"" << toBase64F(val.second.sample) << "\"," << std::endl; + jsonStream << "\"function\": " << static_cast(val.second.function) << "," << std::endl; jsonStream << "\"phase\": " - << val.second->phase << ", " << std::endl; - jsonStream << "\"seed\": " << val.second->seed << ", " << std::endl; + << val.second.phase << ", " << std::endl; + jsonStream << "\"seed\": " << val.second.seed << ", " << std::endl; envelopeToJson(jsonStream, "ampl_env", - val.second->amplitude, - val.second->amplitudeEnvelope); + val.second.amplitude, + val.second.amplitudeEnvelope); jsonStream << "," << std::endl; envelopeToJson(jsonStream, "freq_env", - val.second->frequency, - val.second->frequencyEnvelope, - val.second->frequencyEnvelopeApplyType); + val.second.frequency, + val.second.frequencyEnvelope, + val.second.frequencyEnvelopeApplyType); jsonStream << "," << std::endl; envelopeToJson(jsonStream, "pitchshift_env", - val.second->pitchShift, - val.second->pitchShiftEnvelope); + val.second.pitchShift, + val.second.pitchShiftEnvelope); jsonStream << "," << std::endl; jsonStream << "\"filter\": {" << std::endl; - jsonStream << "\"enabled\": " << (val.second->isFilterEnabled ? "true" : "false"); + jsonStream << "\"enabled\": " << (val.second.isFilterEnabled ? "true" : "false"); jsonStream << ", " << std::endl; - jsonStream << "\"type\": " << static_cast(val.second->filterType) << ", " << std::endl; + jsonStream << "\"type\": " << static_cast(val.second.filterType) << ", " << std::endl; jsonStream << "\"cutoff\": " - << val.second->filterFrequency << ", " << std::endl; + << val.second.filterFrequency << ", " << std::endl; jsonStream << "\"apply_type\": " - << static_cast(val.second->cutOffEnvelopeApplyType) << ", " << std::endl; + << static_cast(val.second.cutOffEnvelopeApplyType) << ", " << std::endl; jsonStream << "\"cutoff_env\": ["; bool first = true; - for (const auto &point: val.second->filterCutOffEnvelope) { + for (const auto &point: val.second.filterCutOffEnvelope) { if (first) first = false; else @@ -1032,10 +1043,10 @@ void PercussionState::oscJson(std::ostringstream &jsonStream) const } jsonStream << "], " << std::endl; jsonStream << "\"factor\": " - << val.second->filterFactor << "," << std::endl; + << val.second.filterFactor << "," << std::endl; jsonStream << "\"qfactor_env\": ["; first = true; - for (const auto &point: val.second->filterQFactorEnvelope) { + for (const auto &point: val.second.filterQFactorEnvelope) { if (first) first = false; else @@ -1279,7 +1290,7 @@ void PercussionState::setOscillatorSample(int oscillatorIndex, const std::vector std::vector PercussionState::getOscillatorSample(int oscillatorIndex) const { - auto oscillator = getOscillator(oscillatorIndex); + auto oscillator = getConstOscillator(oscillatorIndex); return oscillator->sample; } diff --git a/src/percussion_state.h b/src/percussion_state.h index 15cfebb..31e0203 100644 --- a/src/percussion_state.h +++ b/src/percussion_state.h @@ -199,7 +199,8 @@ class PercussionState std::vector pitchShiftEnvelope; }; - std::shared_ptr getOscillator(int index) const; + OscillatorInfo* getOscillator(int index); + const OscillatorInfo* getConstOscillator(int index) const; struct Compressor { bool enabled; @@ -240,7 +241,7 @@ class PercussionState std::vector kickEnvelopePoints; std::vector kickDistortionDriveEnvelope; std::vector kickDistortionVolumeEnvelope; - std::unordered_map> oscillators; + std::unordered_map oscillators; Compressor compressor; Distortion distortion; std::vector layers;