1 /*************************************************************************/
2 /*  sample_editor_plugin.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 "sample_editor_plugin.h"
31 
32 #include "editor/editor_settings.h"
33 #include "globals.h"
34 #include "io/resource_loader.h"
35 
_input_event(InputEvent p_event)36 void SampleEditor::_input_event(InputEvent p_event) {
37 }
38 
_notification(int p_what)39 void SampleEditor::_notification(int p_what) {
40 
41 	if (p_what == NOTIFICATION_FIXED_PROCESS) {
42 	}
43 
44 	if (p_what == NOTIFICATION_ENTER_TREE) {
45 		play->set_icon(get_icon("Play", "EditorIcons"));
46 		stop->set_icon(get_icon("Stop", "EditorIcons"));
47 	}
48 
49 	if (p_what == NOTIFICATION_READY) {
50 
51 		//get_scene()->connect("node_removed",this,"_node_removed");
52 	}
53 
54 	if (p_what == NOTIFICATION_DRAW) {
55 	}
56 }
57 
_play_pressed()58 void SampleEditor::_play_pressed() {
59 
60 	player->play("default", true);
61 	stop->set_pressed(false);
62 	play->set_pressed(true);
63 }
_stop_pressed()64 void SampleEditor::_stop_pressed() {
65 
66 	player->stop_all();
67 	play->set_pressed(false);
68 }
69 
generate_preview_texture(const Ref<Sample> & p_sample,Ref<ImageTexture> & p_texture)70 void SampleEditor::generate_preview_texture(const Ref<Sample> &p_sample, Ref<ImageTexture> &p_texture) {
71 
72 	if (p_sample == NULL)
73 		return;
74 
75 	DVector<uint8_t> data = p_sample->get_data();
76 
77 	DVector<uint8_t> img;
78 	int w = p_texture->get_width();
79 	int h = p_texture->get_height();
80 	img.resize(w * h * 3);
81 	DVector<uint8_t>::Write imgdata = img.write();
82 	uint8_t *imgw = imgdata.ptr();
83 	DVector<uint8_t>::Read sampledata = data.read();
84 	const uint8_t *sdata = sampledata.ptr();
85 
86 	bool stereo = p_sample->is_stereo();
87 	bool _16 = p_sample->get_format() == Sample::FORMAT_PCM16;
88 	int len = p_sample->get_length();
89 
90 	if (len < 1)
91 		return;
92 
93 	if (p_sample->get_format() == Sample::FORMAT_IMA_ADPCM) {
94 
95 		struct IMA_ADPCM_State {
96 
97 			int16_t step_index;
98 			int32_t predictor;
99 			/* values at loop point */
100 			int16_t loop_step_index;
101 			int32_t loop_predictor;
102 			int32_t last_nibble;
103 			int32_t loop_pos;
104 			int32_t window_ofs;
105 			const uint8_t *ptr;
106 		} ima_adpcm;
107 
108 		ima_adpcm.step_index = 0;
109 		ima_adpcm.predictor = 0;
110 		ima_adpcm.loop_step_index = 0;
111 		ima_adpcm.loop_predictor = 0;
112 		ima_adpcm.last_nibble = -1;
113 		ima_adpcm.loop_pos = 0x7FFFFFFF;
114 		ima_adpcm.window_ofs = 0;
115 		ima_adpcm.ptr = NULL;
116 
117 		for (int i = 0; i < w; i++) {
118 
119 			float max[2] = { -1e10, -1e10 };
120 			float min[2] = { 1e10, 1e10 };
121 			int from = i * len / w;
122 			int to = (i + 1) * len / w;
123 			if (to >= len)
124 				to = len - 1;
125 
126 			for (int j = from; j < to; j++) {
127 
128 				while (j > ima_adpcm.last_nibble) {
129 
130 					static const int16_t _ima_adpcm_step_table[89] = {
131 						7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
132 						19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
133 						50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
134 						130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
135 						337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
136 						876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
137 						2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
138 						5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
139 						15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
140 					};
141 
142 					static const int8_t _ima_adpcm_index_table[16] = {
143 						-1, -1, -1, -1, 2, 4, 6, 8,
144 						-1, -1, -1, -1, 2, 4, 6, 8
145 					};
146 
147 					int16_t nibble, diff, step;
148 
149 					ima_adpcm.last_nibble++;
150 					const uint8_t *src_ptr = sdata;
151 
152 					int ofs = ima_adpcm.last_nibble >> 1;
153 
154 					if (stereo)
155 						ofs *= 2;
156 
157 					nibble = (ima_adpcm.last_nibble & 1) ?
158 									 (src_ptr[ofs] >> 4) :
159 									 (src_ptr[ofs] & 0xF);
160 
161 					step = _ima_adpcm_step_table[ima_adpcm.step_index];
162 
163 					ima_adpcm.step_index += _ima_adpcm_index_table[nibble];
164 					if (ima_adpcm.step_index < 0)
165 						ima_adpcm.step_index = 0;
166 					if (ima_adpcm.step_index > 88)
167 						ima_adpcm.step_index = 88;
168 
169 					diff = step >> 3;
170 					if (nibble & 1)
171 						diff += step >> 2;
172 					if (nibble & 2)
173 						diff += step >> 1;
174 					if (nibble & 4)
175 						diff += step;
176 					if (nibble & 8)
177 						diff = -diff;
178 
179 					ima_adpcm.predictor += diff;
180 					if (ima_adpcm.predictor < -0x8000)
181 						ima_adpcm.predictor = -0x8000;
182 					else if (ima_adpcm.predictor > 0x7FFF)
183 						ima_adpcm.predictor = 0x7FFF;
184 
185 					/* store loop if there */
186 					if (ima_adpcm.last_nibble == ima_adpcm.loop_pos) {
187 
188 						ima_adpcm.loop_step_index = ima_adpcm.step_index;
189 						ima_adpcm.loop_predictor = ima_adpcm.predictor;
190 					}
191 				}
192 
193 				float v = ima_adpcm.predictor / 32767.0;
194 				if (v > max[0])
195 					max[0] = v;
196 				if (v < min[0])
197 					min[0] = v;
198 			}
199 
200 			for (int j = 0; j < h; j++) {
201 				float v = (j / (float)h) * 2.0 - 1.0;
202 				uint8_t *imgofs = &imgw[(uint64_t(j) * w + i) * 3];
203 				if (v > min[0] && v < max[0]) {
204 					imgofs[0] = 255;
205 					imgofs[1] = 150;
206 					imgofs[2] = 80;
207 				} else {
208 					imgofs[0] = 0;
209 					imgofs[1] = 0;
210 					imgofs[2] = 0;
211 				}
212 			}
213 		}
214 	} else {
215 		for (int i = 0; i < w; i++) {
216 			// i trust gcc will optimize this loop
217 			float max[2] = { -1e10, -1e10 };
218 			float min[2] = { 1e10, 1e10 };
219 			int c = stereo ? 2 : 1;
220 			int from = uint64_t(i) * len / w;
221 			int to = (uint64_t(i) + 1) * len / w;
222 			if (to >= len)
223 				to = len - 1;
224 
225 			if (_16) {
226 				const int16_t *src = (const int16_t *)sdata;
227 
228 				for (int j = 0; j < c; j++) {
229 
230 					for (int k = from; k <= to; k++) {
231 
232 						float v = src[uint64_t(k) * c + j] / 32768.0;
233 						if (v > max[j])
234 							max[j] = v;
235 						if (v < min[j])
236 							min[j] = v;
237 					}
238 				}
239 			} else {
240 
241 				const int8_t *src = (const int8_t *)sdata;
242 
243 				for (int j = 0; j < c; j++) {
244 
245 					for (int k = from; k <= to; k++) {
246 
247 						float v = src[uint64_t(k) * c + j] / 128.0;
248 						if (v > max[j])
249 							max[j] = v;
250 						if (v < min[j])
251 							min[j] = v;
252 					}
253 				}
254 			}
255 
256 			if (!stereo) {
257 				for (int j = 0; j < h; j++) {
258 					float v = (j / (float)h) * 2.0 - 1.0;
259 					uint8_t *imgofs = &imgw[(uint64_t(j) * w + i) * 3];
260 					if (v > min[0] && v < max[0]) {
261 						imgofs[0] = 255;
262 						imgofs[1] = 150;
263 						imgofs[2] = 80;
264 					} else {
265 						imgofs[0] = 0;
266 						imgofs[1] = 0;
267 						imgofs[2] = 0;
268 					}
269 				}
270 			} else {
271 
272 				for (int j = 0; j < h; j++) {
273 
274 					int half;
275 					float v;
276 					if (j < (h / 2)) {
277 						half = 0;
278 						v = (j / (float)(h / 2)) * 2.0 - 1.0;
279 					} else {
280 						half = 1;
281 						v = ((j - (h / 2)) / (float)(h / 2)) * 2.0 - 1.0;
282 					}
283 
284 					uint8_t *imgofs = &imgw[(uint64_t(j) * w + i) * 3];
285 					if (v > min[half] && v < max[half]) {
286 						imgofs[0] = 255;
287 						imgofs[1] = 150;
288 						imgofs[2] = 80;
289 					} else {
290 						imgofs[0] = 0;
291 						imgofs[1] = 0;
292 						imgofs[2] = 0;
293 					}
294 				}
295 			}
296 		}
297 	}
298 
299 	imgdata = DVector<uint8_t>::Write();
300 
301 	p_texture->set_data(Image(w, h, 0, Image::FORMAT_RGB, img));
302 }
303 
_update_sample()304 void SampleEditor::_update_sample() {
305 
306 	player->stop_all();
307 
308 	generate_preview_texture(sample, peakdisplay);
309 	info_label->set_text(TTR("Length:") + " " + String::num(sample->get_length() / (float)sample->get_mix_rate(), 2) + "s");
310 
311 	if (library->has_sample("default"))
312 		library->remove_sample("default");
313 
314 	library->add_sample("default", sample);
315 }
316 
edit(Ref<Sample> p_sample)317 void SampleEditor::edit(Ref<Sample> p_sample) {
318 
319 	sample = p_sample;
320 
321 	if (!sample.is_null())
322 		_update_sample();
323 	else {
324 
325 		hide();
326 		set_fixed_process(false);
327 	}
328 }
329 
_bind_methods()330 void SampleEditor::_bind_methods() {
331 
332 	ObjectTypeDB::bind_method(_MD("_input_event"), &SampleEditor::_input_event);
333 	ObjectTypeDB::bind_method(_MD("_play_pressed"), &SampleEditor::_play_pressed);
334 	ObjectTypeDB::bind_method(_MD("_stop_pressed"), &SampleEditor::_stop_pressed);
335 }
336 
SampleEditor()337 SampleEditor::SampleEditor() {
338 
339 	player = memnew(SamplePlayer);
340 	add_child(player);
341 	add_style_override("panel", get_stylebox("panel", "Panel"));
342 	library = Ref<SampleLibrary>(memnew(SampleLibrary));
343 	player->set_sample_library(library);
344 	sample_texframe = memnew(TextureFrame);
345 	add_child(sample_texframe);
346 	sample_texframe->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_BEGIN, 5);
347 	sample_texframe->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 5);
348 	sample_texframe->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 30);
349 	sample_texframe->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 5);
350 
351 	info_label = memnew(Label);
352 	sample_texframe->add_child(info_label);
353 	info_label->set_area_as_parent_rect();
354 	info_label->set_anchor_and_margin(MARGIN_TOP, ANCHOR_END, 15);
355 	info_label->set_margin(MARGIN_BOTTOM, 4);
356 	info_label->set_margin(MARGIN_RIGHT, 4);
357 	info_label->set_align(Label::ALIGN_RIGHT);
358 
359 	play = memnew(Button);
360 
361 	play->set_pos(Point2(5, 5));
362 	play->set_size(Size2(1, 1));
363 	play->set_toggle_mode(true);
364 	add_child(play);
365 
366 	stop = memnew(Button);
367 
368 	stop->set_pos(Point2(35, 5));
369 	stop->set_size(Size2(1, 1));
370 	stop->set_toggle_mode(true);
371 	add_child(stop);
372 
373 	peakdisplay = Ref<ImageTexture>(memnew(ImageTexture));
374 	peakdisplay->create(EDITOR_DEF("audio/sample_editor_preview_width", 512), EDITOR_DEF("audio/sample_editor_preview_height", 128), Image::FORMAT_RGB);
375 	sample_texframe->set_expand(true);
376 	sample_texframe->set_texture(peakdisplay);
377 
378 	play->connect("pressed", this, "_play_pressed");
379 	stop->connect("pressed", this, "_stop_pressed");
380 
381 	set_custom_minimum_size(Size2(1, 150) * EDSCALE);
382 }
383 
edit(Object * p_object)384 void SampleEditorPlugin::edit(Object *p_object) {
385 
386 	Sample *s = p_object->cast_to<Sample>();
387 	if (!s)
388 		return;
389 
390 	sample_editor->edit(Ref<Sample>(s));
391 }
392 
handles(Object * p_object) const393 bool SampleEditorPlugin::handles(Object *p_object) const {
394 
395 	return p_object->is_type("Sample");
396 }
397 
make_visible(bool p_visible)398 void SampleEditorPlugin::make_visible(bool p_visible) {
399 
400 	if (p_visible) {
401 		sample_editor->show();
402 		//		sample_editor->set_process(true);
403 	} else {
404 
405 		sample_editor->hide();
406 		//		sample_editor->set_process(false);
407 	}
408 }
409 
SampleEditorPlugin(EditorNode * p_node)410 SampleEditorPlugin::SampleEditorPlugin(EditorNode *p_node) {
411 
412 	editor = p_node;
413 	sample_editor = memnew(SampleEditor);
414 	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, sample_editor);
415 	sample_editor->hide();
416 }
417 
~SampleEditorPlugin()418 SampleEditorPlugin::~SampleEditorPlugin() {
419 }
420