1 /*************************************************************************/
2 /*  audio_driver_media_kit.cpp                                           */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 #include "audio_driver_media_kit.h"
31 
32 #ifdef MEDIA_KIT_ENABLED
33 
34 #include "globals.h"
35 
36 int32_t *AudioDriverMediaKit::samples_in = NULL;
37 
init()38 Error AudioDriverMediaKit::init() {
39 	active = false;
40 
41 	mix_rate = 44100;
42 	output_format = OUTPUT_STEREO;
43 	channels = 2;
44 
45 	int latency = GLOBAL_DEF("audio/output_latency", 25);
46 	buffer_size = closest_power_of_2(latency * mix_rate / 1000);
47 	samples_in = memnew_arr(int32_t, buffer_size * channels);
48 
49 	media_raw_audio_format format;
50 	format = media_raw_audio_format::wildcard;
51 	format.frame_rate = mix_rate;
52 	format.channel_count = channels;
53 	format.format = media_raw_audio_format::B_AUDIO_INT;
54 	format.byte_order = B_MEDIA_LITTLE_ENDIAN;
55 	format.buffer_size = buffer_size * sizeof(int32_t) * channels;
56 
57 	player = new BSoundPlayer(
58 			&format,
59 			"godot_sound_server",
60 			AudioDriverMediaKit::PlayBuffer,
61 			NULL,
62 			this);
63 
64 	if (player->InitCheck() != B_OK) {
65 		fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n");
66 		ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN);
67 	}
68 
69 	mutex = Mutex::create();
70 	player->Start();
71 
72 	return OK;
73 }
74 
PlayBuffer(void * cookie,void * buffer,size_t size,const media_raw_audio_format & format)75 void AudioDriverMediaKit::PlayBuffer(void *cookie, void *buffer, size_t size, const media_raw_audio_format &format) {
76 	AudioDriverMediaKit *ad = (AudioDriverMediaKit *)cookie;
77 	int32_t *buf = (int32_t *)buffer;
78 
79 	if (!ad->active) {
80 		for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
81 			AudioDriverMediaKit::samples_in[i] = 0;
82 		}
83 	} else {
84 		ad->lock();
85 		ad->audio_server_process(ad->buffer_size, AudioDriverMediaKit::samples_in);
86 		ad->unlock();
87 	}
88 
89 	for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
90 		buf[i] = AudioDriverMediaKit::samples_in[i];
91 	}
92 }
93 
start()94 void AudioDriverMediaKit::start() {
95 	active = true;
96 }
97 
get_mix_rate() const98 int AudioDriverMediaKit::get_mix_rate() const {
99 	return mix_rate;
100 }
101 
get_output_format() const102 AudioDriverSW::OutputFormat AudioDriverMediaKit::get_output_format() const {
103 	return output_format;
104 }
105 
lock()106 void AudioDriverMediaKit::lock() {
107 	if (!mutex)
108 		return;
109 
110 	mutex->lock();
111 }
112 
unlock()113 void AudioDriverMediaKit::unlock() {
114 	if (!mutex)
115 		return;
116 
117 	mutex->unlock();
118 }
119 
finish()120 void AudioDriverMediaKit::finish() {
121 	delete player;
122 
123 	if (samples_in) {
124 		memdelete_arr(samples_in);
125 	};
126 
127 	if (mutex) {
128 		memdelete(mutex);
129 		mutex = NULL;
130 	}
131 }
132 
AudioDriverMediaKit()133 AudioDriverMediaKit::AudioDriverMediaKit() {
134 	mutex = NULL;
135 	player = NULL;
136 }
137 
~AudioDriverMediaKit()138 AudioDriverMediaKit::~AudioDriverMediaKit() {
139 }
140 
141 #endif
142