aboutsummaryrefslogtreecommitdiff
path: root/platform/darwin-native.m
blob: 633d04bfe03c0556dafedc6fe3d447d135de3f5b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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];
}