mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-30 19:30:17 +00:00
Eliminates potential race conditions on validity of delegate_
.
This commit is contained in:
parent
f43c31da1f
commit
a5e1765ce4
@ -124,7 +124,8 @@ template <typename SampleSource> class LowpassSpeaker: public Speaker {
|
|||||||
at construction, filtering it and passing it on to the speaker's delegate if there is one.
|
at construction, filtering it and passing it on to the speaker's delegate if there is one.
|
||||||
*/
|
*/
|
||||||
void run_for(const Cycles cycles) {
|
void run_for(const Cycles cycles) {
|
||||||
if(!delegate_) return;
|
const auto delegate = delegate_.load();
|
||||||
|
if(!delegate) return;
|
||||||
|
|
||||||
std::size_t cycles_remaining = size_t(cycles.as_integral());
|
std::size_t cycles_remaining = size_t(cycles.as_integral());
|
||||||
if(!cycles_remaining) return;
|
if(!cycles_remaining) return;
|
||||||
@ -138,7 +139,7 @@ template <typename SampleSource> class LowpassSpeaker: public Speaker {
|
|||||||
}
|
}
|
||||||
if(filter_parameters.parameters_are_dirty) update_filter_coefficients(filter_parameters);
|
if(filter_parameters.parameters_are_dirty) update_filter_coefficients(filter_parameters);
|
||||||
if(filter_parameters.input_rate_changed) {
|
if(filter_parameters.input_rate_changed) {
|
||||||
delegate_->speaker_did_change_input_clock(this);
|
delegate->speaker_did_change_input_clock(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(conversion_) {
|
switch(conversion_) {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#ifndef Speaker_hpp
|
#ifndef Speaker_hpp
|
||||||
#define Speaker_hpp
|
#define Speaker_hpp
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -82,12 +83,16 @@ class Speaker {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer, bool is_stereo) {
|
void did_complete_samples(Speaker *speaker, const std::vector<int16_t> &buffer, bool is_stereo) {
|
||||||
|
// Test the delegate for existence again, as it may have changed.
|
||||||
|
const auto delegate = delegate_.load();
|
||||||
|
if(!delegate) return;
|
||||||
|
|
||||||
++completed_sample_sets_;
|
++completed_sample_sets_;
|
||||||
|
|
||||||
// Hope for the fast path first: producer and consumer agree about
|
// Hope for the fast path first: producer and consumer agree about
|
||||||
// number of channels.
|
// number of channels.
|
||||||
if(is_stereo == stereo_output_) {
|
if(is_stereo == stereo_output_) {
|
||||||
delegate_->speaker_did_complete_samples(this, buffer);
|
delegate->speaker_did_complete_samples(this, buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,9 +111,9 @@ class Speaker {
|
|||||||
mix_buffer_[(c << 1) + 0] = mix_buffer_[(c << 1) + 1] = buffer[c];
|
mix_buffer_[(c << 1) + 0] = mix_buffer_[(c << 1) + 1] = buffer[c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delegate_->speaker_did_complete_samples(this, mix_buffer_);
|
delegate->speaker_did_complete_samples(this, mix_buffer_);
|
||||||
}
|
}
|
||||||
Delegate *delegate_ = nullptr;
|
std::atomic<Delegate *> delegate_ = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void compute_output_rate() {
|
void compute_output_rate() {
|
||||||
@ -121,7 +126,7 @@ class Speaker {
|
|||||||
float input_rate_multiplier_ = 1.0f;
|
float input_rate_multiplier_ = 1.0f;
|
||||||
float output_cycles_per_second_ = 1.0f;
|
float output_cycles_per_second_ = 1.0f;
|
||||||
int output_buffer_size_ = 1;
|
int output_buffer_size_ = 1;
|
||||||
bool stereo_output_ = false;
|
std::atomic<bool> stereo_output_ = false;
|
||||||
std::vector<int16_t> mix_buffer_;
|
std::vector<int16_t> mix_buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user