mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
Extended to allow floating-point sampling rates. Which makes sense.
This commit is contained in:
parent
4190b42bbb
commit
fcf4b14344
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
- (void)runForNumberOfCycles:(int)numberOfCycles;
|
- (void)runForNumberOfCycles:(int)numberOfCycles;
|
||||||
|
|
||||||
- (int)idealSamplingRateFromRange:(NSRange)range;
|
- (float)idealSamplingRateFromRange:(NSRange)range;
|
||||||
- (void)setAudioSamplingRate:(int)samplingRate;
|
- (void)setAudioSamplingRate:(float)samplingRate;
|
||||||
|
|
||||||
- (void)setView:(CSOpenGLView *)view aspectRatio:(float)aspectRatio;
|
- (void)setView:(CSOpenGLView *)view aspectRatio:(float)aspectRatio;
|
||||||
- (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty;
|
- (void)drawViewForPixelSize:(CGSize)pixelSize onlyIfDirty:(BOOL)onlyIfDirty;
|
||||||
|
@ -36,25 +36,25 @@ struct SpeakerDelegate: public Outputs::Speaker::Delegate {
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (int)idealSamplingRateFromRange:(NSRange)range {
|
- (float)idealSamplingRateFromRange:(NSRange)range {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
Outputs::Speaker *speaker = self.machine->get_speaker();
|
Outputs::Speaker *speaker = self.machine->get_speaker();
|
||||||
if(speaker)
|
if(speaker)
|
||||||
{
|
{
|
||||||
return speaker->get_ideal_clock_rate_in_range((int)range.location, (int)(range.location + range.length));
|
return speaker->get_ideal_clock_rate_in_range((float)range.location, (float)(range.location + range.length));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAudioSamplingRate:(int)samplingRate {
|
- (void)setAudioSamplingRate:(float)samplingRate {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
_speakerDelegate.machine = self;
|
_speakerDelegate.machine = self;
|
||||||
[self setSpeakerDelegate:&_speakerDelegate sampleRate:samplingRate];
|
[self setSpeakerDelegate:&_speakerDelegate sampleRate:samplingRate];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(int)sampleRate {
|
- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(float)sampleRate {
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
Outputs::Speaker *speaker = self.machine->get_speaker();
|
Outputs::Speaker *speaker = self.machine->get_speaker();
|
||||||
if(speaker)
|
if(speaker)
|
||||||
|
@ -24,7 +24,7 @@ class Speaker {
|
|||||||
virtual void speaker_did_complete_samples(Speaker *speaker, const int16_t *buffer, int buffer_size) = 0;
|
virtual void speaker_did_complete_samples(Speaker *speaker, const int16_t *buffer, int buffer_size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
int get_ideal_clock_rate_in_range(int minimum, int maximum)
|
float get_ideal_clock_rate_in_range(float minimum, float maximum)
|
||||||
{
|
{
|
||||||
// return exactly the input rate if possible
|
// return exactly the input rate if possible
|
||||||
if(_input_cycles_per_second >= minimum && _input_cycles_per_second <= maximum) return _input_cycles_per_second;
|
if(_input_cycles_per_second >= minimum && _input_cycles_per_second <= maximum) return _input_cycles_per_second;
|
||||||
@ -36,7 +36,7 @@ class Speaker {
|
|||||||
return maximum;
|
return maximum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_output_rate(int cycles_per_second, int buffer_size)
|
void set_output_rate(float cycles_per_second, int buffer_size)
|
||||||
{
|
{
|
||||||
_output_cycles_per_second = cycles_per_second;
|
_output_cycles_per_second = cycles_per_second;
|
||||||
if(_buffer_size != buffer_size)
|
if(_buffer_size != buffer_size)
|
||||||
@ -58,7 +58,7 @@ class Speaker {
|
|||||||
_delegate = delegate;
|
_delegate = delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_input_rate(int cycles_per_second)
|
void set_input_rate(float cycles_per_second)
|
||||||
{
|
{
|
||||||
_input_cycles_per_second = cycles_per_second;
|
_input_cycles_per_second = cycles_per_second;
|
||||||
set_needs_updated_filter_coefficients();
|
set_needs_updated_filter_coefficients();
|
||||||
@ -74,7 +74,7 @@ class Speaker {
|
|||||||
bool _coefficients_are_dirty;
|
bool _coefficients_are_dirty;
|
||||||
Delegate *_delegate;
|
Delegate *_delegate;
|
||||||
|
|
||||||
int _input_cycles_per_second, _output_cycles_per_second;
|
float _input_cycles_per_second, _output_cycles_per_second;
|
||||||
|
|
||||||
void set_needs_updated_filter_coefficients()
|
void set_needs_updated_filter_coefficients()
|
||||||
{
|
{
|
||||||
@ -181,7 +181,7 @@ template <class T> class Filter: public Speaker {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_number_of_taps = (_input_cycles_per_second + _output_cycles_per_second) / _output_cycles_per_second;
|
_number_of_taps = (int)ceilf((_input_cycles_per_second + _output_cycles_per_second) / _output_cycles_per_second);
|
||||||
_number_of_taps *= 2;
|
_number_of_taps *= 2;
|
||||||
_number_of_taps |= 1;
|
_number_of_taps |= 1;
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ template <class T> class Filter: public Speaker {
|
|||||||
_buffer_in_progress_pointer = 0;
|
_buffer_in_progress_pointer = 0;
|
||||||
|
|
||||||
_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper((uint64_t)_input_cycles_per_second, (uint64_t)_output_cycles_per_second));
|
_stepper = std::unique_ptr<SignalProcessing::Stepper>(new SignalProcessing::Stepper((uint64_t)_input_cycles_per_second, (uint64_t)_output_cycles_per_second));
|
||||||
_filter = std::unique_ptr<SignalProcessing::FIRFilter>(new SignalProcessing::FIRFilter((unsigned int)_number_of_taps, (unsigned int)_input_cycles_per_second, 0.0, (float)_output_cycles_per_second / 2.0f, SignalProcessing::FIRFilter::DefaultAttenuation));
|
_filter = std::unique_ptr<SignalProcessing::FIRFilter>(new SignalProcessing::FIRFilter((unsigned int)_number_of_taps, (float)_input_cycles_per_second, 0.0, (float)_output_cycles_per_second / 2.0f, SignalProcessing::FIRFilter::DefaultAttenuation));
|
||||||
|
|
||||||
_input_buffer = std::unique_ptr<int16_t>(new int16_t[_number_of_taps]);
|
_input_buffer = std::unique_ptr<int16_t>(new int16_t[_number_of_taps]);
|
||||||
_input_buffer_depth = 0;
|
_input_buffer_depth = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user