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