diff --git a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift index 06e494000..cd1adc6cd 100644 --- a/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift +++ b/OSBindings/Mac/Clock Signal/Documents/ElectronDocument.swift @@ -7,6 +7,7 @@ // import Foundation +import AudioToolbox class ElectronDocument: MachineDocument { diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm index 3f0efb63c..90477f081 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm @@ -35,9 +35,11 @@ _electron.get_crt()->set_delegate(delegate); } -- (void)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate { - _electron.get_speaker()->set_output_rate(44100, 512); +- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(int)sampleRate { + _electron.get_speaker()->set_output_rate(sampleRate, 512); _electron.get_speaker()->set_output_quality(15); + _electron.get_speaker()->set_delegate(delegate); + return YES; } - (void)setView:(CSCathodeRayView *)view { diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSMachine+Subclassing.h b/OSBindings/Mac/Clock Signal/Wrappers/CSMachine+Subclassing.h index 61c3460f6..64c00b6fa 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSMachine+Subclassing.h +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSMachine+Subclassing.h @@ -12,12 +12,13 @@ @interface CSMachine (Subclassing) -- (void)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate; +- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(int)sampleRate; - (void)setCRTDelegate:(Outputs::CRT::Delegate *)delegate; - (void)doRunForNumberOfCycles:(int)numberOfCycles; - (void)perform:(dispatch_block_t)action; - (void)crt:(Outputs::CRT *)crt didEndFrame:(CRTFrame *)frame didDetectVSync:(BOOL)didDetectVSync; +- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const uint16_t *)samples length:(int)length; @end diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSMachine.mm b/OSBindings/Mac/Clock Signal/Wrappers/CSMachine.mm index e3d656f9c..f6ce615dc 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSMachine.mm @@ -16,6 +16,13 @@ struct CRTDelegate: public Outputs::CRT::Delegate { } }; +struct SpeakerDelegate: public Outputs::Speaker::Delegate { + __weak CSMachine *machine; + void speaker_did_complete_samples(Outputs::Speaker *speaker, const uint16_t *buffer, int buffer_size) { + [machine speaker:speaker didCompleteSamples:buffer length:buffer_size]; + } +}; + typedef NS_ENUM(NSInteger, CSAtari2600RunningState) { CSMachineRunningStateRunning, CSMachineRunningStateStopped @@ -23,6 +30,7 @@ typedef NS_ENUM(NSInteger, CSAtari2600RunningState) { @implementation CSMachine { CRTDelegate _crtDelegate; + SpeakerDelegate _speakerDelegate; dispatch_queue_t _serialDispatchQueue; NSConditionLock *_runningLock; @@ -36,6 +44,9 @@ typedef NS_ENUM(NSInteger, CSAtari2600RunningState) { if([self.view pushFrame:frame]) crt->return_frame(); } +- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const uint16_t *)samples length:(int)length { +} + - (void)runForNumberOfCycles:(int)cycles { if([_runningLock tryLockWhenCondition:CSMachineRunningStateStopped]) { [_runningLock unlockWithCondition:CSMachineRunningStateRunning]; @@ -51,18 +62,22 @@ typedef NS_ENUM(NSInteger, CSAtari2600RunningState) { self = [super init]; if (self) { - _crtDelegate.machine = self; - [self setCRTDelegate:&_crtDelegate]; - [self setSpeakerDelegate:nil]; _serialDispatchQueue = dispatch_queue_create("Machine queue", DISPATCH_QUEUE_SERIAL); _runningLock = [[NSConditionLock alloc] initWithCondition:CSMachineRunningStateStopped]; + + _crtDelegate.machine = self; + _speakerDelegate.machine = self; + [self setCRTDelegate:&_crtDelegate]; + [self setSpeakerDelegate:&_speakerDelegate sampleRate:44100]; } return self; } - (void)setCRTDelegate:(Outputs::CRT::Delegate *)delegate {} -- (void)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate {} +- (BOOL)setSpeakerDelegate:(Outputs::Speaker::Delegate *)delegate sampleRate:(int)sampleRate { + return NO; +} - (void)doRunForNumberOfCycles:(int)numberOfCycles {} @end diff --git a/Outputs/Speaker.hpp b/Outputs/Speaker.hpp index 8dfcd6dc1..a0085c755 100644 --- a/Outputs/Speaker.hpp +++ b/Outputs/Speaker.hpp @@ -19,7 +19,7 @@ class Speaker { public: class Delegate { public: - virtual void speaker_did_complete_samples(Speaker *speaker, const uint16_t *buffer, int buffer_size); + virtual void speaker_did_complete_samples(Speaker *speaker, const uint16_t *buffer, int buffer_size) = 0; }; void set_output_rate(int cycles_per_second, int buffer_size)