From 2565b0e28ff2c58dd3f34624a71c7a2acaac0a0a Mon Sep 17 00:00:00 2001 From: Nicholas Tay Date: Fri, 9 Dec 2022 11:43:18 +1100 Subject: Initial working Obj-C sound (leak) It seems to memory leak so needs to be fixed, but this was before I had to return my work MacBook - until I get my own! --- Makefile | 6 +++-- platform/darwin-native.bridging.h | 7 +++++ platform/darwin-native.m | 57 +++++++++++++++++++++++++++++++++++++++ platform/darwin.c | 19 +++++-------- 4 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 platform/darwin-native.bridging.h create mode 100644 platform/darwin-native.m diff --git a/Makefile b/Makefile index e21da87..ce7e806 100644 --- a/Makefile +++ b/Makefile @@ -17,13 +17,15 @@ else else ifeq ($(UNAME_S),Darwin) PLATFORM = darwin CFLAGS += -framework CoreFoundation -framework IOKit -framework AppKit + PLATFORM_C += platform/$(PLATFORM)-native.m endif endif +PLATFORM_C += platform/$(PLATFORM).c default: $(NAME) -$(NAME): $(NAME).c platform/$(PLATFORM).c - $(CC) $(CFLAGS) $(NAME).c platform/$(PLATFORM).c $(LDLIBS) -o $(NAME) +$(NAME): $(NAME).c $(PLATFORM_C) + $(CC) $(CFLAGS) $(NAME).c $(PLATFORM_C) $(LDLIBS) -o $(NAME) clean: rm -f *.o diff --git a/platform/darwin-native.bridging.h b/platform/darwin-native.bridging.h new file mode 100644 index 0000000..0dc9d72 --- /dev/null +++ b/platform/darwin-native.bridging.h @@ -0,0 +1,7 @@ +#ifndef CLAK_DARWIN_NATIVE_BRIDGING_H_ +#define CLAK_DARWIN_NATIVE_BRIDGING_H_ + +bool macos_sound_init(float volume); +void macos_sound_play(unsigned char *buffer, unsigned int buffer_len); + +#endif /* CLAK_DARWIN_NATIVE_BRIDGING_H_ */ 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 + +#import +#import + +/* 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 +@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]; +} + diff --git a/platform/darwin.c b/platform/darwin.c index 820c012..3189a5d 100644 --- a/platform/darwin.c +++ b/platform/darwin.c @@ -3,6 +3,7 @@ #include #include +#include "darwin-native.bridging.h" #include "platform.h" #include "../board/board.h" @@ -11,24 +12,18 @@ extern void keyboard_on_down(void); extern void keyboard_on_up(void); -static float volume = 0; static IOHIDManagerRef hid_manager = NULL; -bool sound_init(float _volume) +bool sound_init(float volume) { - volume = _volume; - - /* TODO: Init sound, NSCache probably too via bridge? */ - - return true; + /* Call Obj-C function */ + return macos_sound_init(volume); } void sound_play(unsigned char *buffer, unsigned int buffer_len) { - (void) buffer; - (void) buffer_len; - - /* TODO: Play the sound via obj-c for now */ + /* Call Obj-C function */ + macos_sound_play(buffer, buffer_len); } /* TODO: Maybe merge some of this stuff with linux, lots of overlap */ @@ -97,7 +92,7 @@ void hid_callback(void *context, IOReturn result, void *sender, IOHIDValueRef va /* seems like getting 'int value' is if it is key up or down * true(1) = down */ bool key_down = IOHIDValueGetIntegerValue(value) == 1; - printf(">>> value: %d, down: %d\n", scancode, key_down); + // printf(">>> value: %d, down: %d\n", scancode, key_down); if (key_down) keyboard_on_down(); else -- cgit