Skip to content

Commit

Permalink
Fix memory leak related to operators
Browse files Browse the repository at this point in the history
It was always there, but now it's also reported
because operators are now a Godot type.
  • Loading branch information
YuriSizov committed Oct 19, 2024
1 parent 3c84004 commit 14aea53
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 40 deletions.
77 changes: 40 additions & 37 deletions src/chip/channels/siopm_channel_fm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,28 @@
#include "chip/wave/siopm_wave_pcm_table.h"
#include "chip/wave/siopm_wave_table.h"

List<SiOPMOperator *> SiOPMChannelFM::_free_operators;
List<SiOPMOperator *> SiOPMChannelFM::_operator_pool;

SiOPMOperator *SiOPMChannelFM::_alloc_fm_operator() {
if (_free_operators.size() > 0) {
SiOPMOperator *op = _free_operators.back()->get();
_free_operators.pop_back();
void SiOPMChannelFM::finalize_pool() {
for (SiOPMOperator *op : _operator_pool) {
memdelete(op);
}
_operator_pool.clear();
}

SiOPMOperator *SiOPMChannelFM::_alloc_operator() {
if (_operator_pool.size() > 0) {
SiOPMOperator *op = _operator_pool.back()->get();
_operator_pool.pop_back();

return op;
} else {
return memnew(SiOPMOperator(_sound_chip));
}
}

void SiOPMChannelFM::_free_fm_operator(SiOPMOperator *p_operator) {
_free_operators.push_back(p_operator);
void SiOPMChannelFM::_release_operator(SiOPMOperator *p_operator) {
_operator_pool.push_back(p_operator);
}

//
Expand All @@ -40,12 +47,12 @@ void SiOPMChannelFM::_update_process_function() {
void SiOPMChannelFM::_update_operator_count(int p_count) {
if (_operator_count < p_count) {
for (int i = _operator_count; i < p_count; i++) {
_operators.write[i] = _alloc_fm_operator();
_operators.write[i] = _alloc_operator();
_operators[i]->initialize();
}
} else if (_operator_count > p_count) {
for (int i = p_count; i < _operator_count; i++) {
_free_fm_operator(_operators[i]);
_release_operator(_operators[i]);
_operators.write[i] = nullptr;
}
}
Expand Down Expand Up @@ -716,17 +723,10 @@ void SiOPMChannelFM::initialize_lfo(int p_waveform, Vector<int> p_custom_wave_ta
_amplitude_modulation_output_level = 0;
_pitch_modulation_output_level = 0;

if (_operators[0]) {
_operators[0]->set_detune2(0);
}
if (_operators[1]) {
_operators[1]->set_detune2(0);
}
if (_operators[2]) {
_operators[2]->set_detune2(0);
}
if (_operators[3]) {
_operators[3]->set_detune2(0);
for (SiOPMOperator *op : _operators) {
if (op) {
op->set_detune2(0);
}
}
}

Expand All @@ -744,17 +744,10 @@ void SiOPMChannelFM::set_pitch_modulation(int p_depth) {
_set_lfo_state(_pitch_modulation_depth != 0 || _amplitude_modulation_depth > 0);

if (_pitch_modulation_depth == 0) {
if (_operators[0]) {
_operators[0]->set_detune2(0);
}
if (_operators[1]) {
_operators[1]->set_detune2(0);
}
if (_operators[2]) {
_operators[2]->set_detune2(0);
}
if (_operators[3]) {
_operators[3]->set_detune2(0);
for (SiOPMOperator *op : _operators) {
if (op) {
op->set_detune2(0);
}
}
}
}
Expand Down Expand Up @@ -1532,14 +1525,10 @@ SiOPMChannelFM::SiOPMChannelFM(SiOPMSoundChip *p_chip) : SiOPMChannelBase(p_chip
}
};

_operator_count = 1;
_operators.resize_zeroed(4);
_operators.write[0] = _alloc_fm_operator();
_operators.write[1] = nullptr;
_operators.write[2] = nullptr;
_operators.write[3] = nullptr;

_operators.write[0] = _alloc_operator();
_active_operator = _operators[0];
_operator_count = 1;

_update_process_function();

Expand All @@ -1548,3 +1537,17 @@ SiOPMChannelFM::SiOPMChannelFM(SiOPMSoundChip *p_chip) : SiOPMChannelBase(p_chip

initialize(nullptr, 0);
}

SiOPMChannelFM::~SiOPMChannelFM() {
_active_operator = nullptr;

for (SiOPMOperator *op : _operators) {
if (op) {
_release_operator(op);
}
}
_operators.clear();

memdelete(_pipe0);
memdelete(_pipe1);
}
9 changes: 6 additions & 3 deletions src/chip/channels/siopm_channel_fm.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ class SiOPMChannelFM : public SiOPMChannelBase {

static const int IDLING_THRESHOLD = 5120; // = 256(resolution)*10(2^10=1024)*2(p/n) = volume<1/1024

static List<SiOPMOperator *> _free_operators;
static List<SiOPMOperator *> _operator_pool;

SiOPMOperator *_alloc_fm_operator();
void _free_fm_operator(SiOPMOperator *p_operator);
SiOPMOperator *_alloc_operator();
void _release_operator(SiOPMOperator *p_operator);

int _algorithm = 0;

Expand Down Expand Up @@ -120,6 +120,8 @@ class SiOPMChannelFM : public SiOPMChannelBase {
int _lfo_timer_initial = 0; // LFO_TIMER_INITIAL * freq_ratio

public:
static void finalize_pool();

virtual void get_channel_params(const Ref<SiOPMChannelParams> &p_params) const override;
virtual void set_channel_params(const Ref<SiOPMChannelParams> &p_params, bool p_with_volume, bool p_with_modulation = true) override;
void set_params_by_value(int p_ar, int p_dr, int p_sr, int p_rr, int p_sl, int p_tl, int p_ksr, int p_ksl, int p_mul, int p_dt1, int p_detune, int p_ams, int p_phase, int p_fix_note);
Expand Down Expand Up @@ -172,6 +174,7 @@ class SiOPMChannelFM : public SiOPMChannelBase {
virtual void reset() override;

SiOPMChannelFM(SiOPMSoundChip *p_chip = nullptr);
~SiOPMChannelFM();
};

#endif // SIOPM_CHANNEL_FM_H
5 changes: 5 additions & 0 deletions src/chip/channels/siopm_channel_pcm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,3 +603,8 @@ SiOPMChannelPCM::SiOPMChannelPCM(SiOPMSoundChip *p_chip) : SiOPMChannelBase(p_ch

initialize(nullptr, 0);
}

SiOPMChannelPCM::~SiOPMChannelPCM() {
memdelete(_operator);
_operator = nullptr;
}
1 change: 1 addition & 0 deletions src/chip/channels/siopm_channel_pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class SiOPMChannelPCM : public SiOPMChannelBase {
virtual void reset() override;

SiOPMChannelPCM(SiOPMSoundChip *p_chip = nullptr);
~SiOPMChannelPCM();
};

#endif // SIOPM_CHANNEL_PCM_H
1 change: 1 addition & 0 deletions src/register_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ void uninitialize_sion_module(ModuleInitializationLevel p_level) {
SinglyLinkedList<double>::finalize_pool();

// Finalize singletons and static members after the execution.
SiOPMChannelFM::finalize_pool();
SiMMLTrack::finalize();
SiMMLRefTable::finalize();
SiOPMRefTable::finalize();
Expand Down

0 comments on commit 14aea53

Please sign in to comment.