aboutsummaryrefslogtreecommitdiff
path: root/platform/darwin-native.m
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin-native.m')
-rw-r--r--platform/darwin-native.m57
1 files changed, 57 insertions, 0 deletions
diff --git a/platform/darwin-native.m b/platform/darwin-native.m
new file mode 100644
index 0000000..633d04b
--- /dev/null
+++ b/platform/darwin-native.m
@@ -0,0 +1,57 @@
+#include <stdio.h>
+
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+
+/* TODO: Can we have even lower level API than AppKit? */
+
+static float volume = 0;
+static NSCache *audio_cache = nil;
+
+/* For sound finish delegate memory safety */
+@interface ClakMacSound : NSObject <NSSoundDelegate>
+@end
+
+@implementation ClakMacSound
+- (void)sound:(NSSound *)sound didFinishPlaying:(BOOL)flag {
+ [sound release];
+ [sound dealloc];
+}
+@end
+static ClakMacSound *clak_mac_sound = nil;
+
+bool macos_sound_init(float _volume)
+{
+ volume = _volume;
+
+ /* Bring up NSCache for storing NSData */
+ audio_cache = [[NSCache alloc] init];
+ if (audio_cache == nil) {
+ printf("ERROR: Could not initialise audio cache!\n");
+ return false;
+ }
+
+ /* Prepare sound delegate for memory safety */
+ clak_mac_sound = [[ClakMacSound alloc] init];
+
+ return true;
+}
+
+void macos_sound_play(unsigned char *buffer, unsigned int buffer_len)
+{
+ /* Get buffer's pointer for use as dictionary key in cache */
+ NSValue *ptr_key = [NSValue valueWithPointer:buffer];
+
+ /* If no cached, set up the data */
+ NSData *buffer_ns = [audio_cache objectForKey:ptr_key];
+ if (buffer_ns == nil) {
+ /* Set up data, reusing the static buffer */
+ buffer_ns = [NSData dataWithBytesNoCopy:(void *)buffer length:(NSUInteger)buffer_len freeWhenDone:NO];
+ /* Cache it */
+ [audio_cache setObject:buffer_ns forKey:ptr_key];
+ }
+
+ NSSound *sound = [[NSSound alloc] initWithData:buffer_ns];
+ [sound play];
+}
+